diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 875f4fb67b8..c232ca6e3d3 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -9,3 +9,9 @@ # reorder and reformat GTFS GraphQL API schema file with graphql-java 14051fab312a67cae9a460aaf0bbc77223bec624 + +# Make OTP a multi-module project +ead33ffe280dd7caf72cae5ff7a41542e8427636 + +# json file reformatting with prettier +c287575df6798810a69fafc54c8c4e1867b71367 diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 89bc77b2b97..212c3934dc2 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -14,6 +14,12 @@ on: - master - dev-1.x - dev-2.x +env: + # Since version 3.9.0 of Maven it will automatically understand this environment variable. + # However, as of 2024-11 the latest versions of Ubuntu and Debian were on 3.8.8 so it will take some + # time until we can remove the $MAVEN_ARGS below. + MAVEN_ARGS: "--no-transfer-progress -Dstyle.color=always" + jobs: build-linux: runs-on: ubuntu-latest @@ -46,22 +52,29 @@ jobs: # https://github.com/actions/runner-images/issues/1499 # we set nodePath and npmPath to skip downloading the node binary, which frequently times out run: | - mvn --batch-mode jacoco:prepare-agent test jacoco:report -P prettierCheck -Dprettier.nodePath=node -Dprettier.npmPath=npm - mvn --batch-mode package -Dmaven.test.skip -P prettierSkip + mvn $MAVEN_ARGS jacoco:prepare-agent test jacoco:report -P prettierCheck -Dprettier.nodePath=node -Dprettier.npmPath=npm + mvn $MAVEN_ARGS package -Dmaven.test.skip -P prettierSkip - name: Send coverage data to codecov.io if: github.repository_owner == 'opentripplanner' uses: codecov/codecov-action@v4 with: - files: target/site/jacoco/jacoco.xml token: ${{ secrets.CODECOV_TOKEN }} verbose: true + - name: Upload test results to Codecov + # always upload test results, even when failed + if: ${{ !cancelled() }} + uses: codecov/test-results-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: "*TEST-*.xml" + - name: Deploy to Github Package Registry if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/dev-1.x' || github.ref == 'refs/heads/dev-2.x') env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: mvn --batch-mode deploy --settings maven-settings.xml -DskipTests -DGITHUB_REPOSITORY=$GITHUB_REPOSITORY -P prettierSkip -P deployGitHub + run: mvn $MAVEN_ARGS deploy --settings maven-settings.xml -DskipTests -DGITHUB_REPOSITORY=$GITHUB_REPOSITORY -P prettierSkip -P deployGitHub build-windows: timeout-minutes: 20 @@ -79,7 +92,7 @@ jobs: - name: Configure Windows Pagefile uses: al-cheb/configure-pagefile-action@v1.4 - name: Run tests - run: mvn --batch-mode test -P prettierSkip + run: mvn $MAVEN_ARGS test -P prettierSkip docs: if: github.repository_owner == 'opentripplanner' @@ -89,7 +102,7 @@ jobs: LOCAL_BRANCH: local-pages REMOTE_BRANCH: main TOKEN: ${{ secrets.CHANGELOG_TOKEN }} - MASTER_BRANCH_VERSION: 2.5.0 + MASTER_BRANCH_VERSION: 2.6.0 steps: @@ -121,7 +134,7 @@ jobs: - name: Build GTFS GraphQL API documentation run: | - npm install -g @magidoc/cli@6.0.0 + npm install -g @magidoc/cli@6.1.0 magidoc generate --stacktrace - name: Deploy compiled HTML to Github pages @@ -154,7 +167,7 @@ jobs: # schema hasn't changed. # example commit: https://github.com/opentripplanner/docs/commit/45e6ddf8e4a4 - SCHEMA_FILE_MODIFIED=`git log -n 1 --pretty=format:%ct src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls` + SCHEMA_FILE_MODIFIED=`git log -n 1 --pretty=format:%ct application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls` echo "schema modified at ${SCHEMA_FILE_MODIFIED}" git checkout $LOCAL_BRANCH DOCS_MODIFIED=`git log -n 1 --pretty=format:%ct api/dev-2.x/graphql-gtfs/introduction.html` @@ -179,9 +192,9 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 16 + node-version: 22 - name: Run code generator - working-directory: src/main/java/org/opentripplanner/apis/gtfs/generated + working-directory: application/src/main/java/org/opentripplanner/apis/gtfs/generated run: | yarn install yarn generate @@ -192,7 +205,7 @@ jobs: distribution: temurin cache: maven - name: Compile Java code - run: mvn --batch-mode compile -DskipTests -P prettierSkip + run: mvn $MAVEN_ARGS compile -DskipTests -P prettierSkip container-image: if: github.repository_owner == 'opentripplanner' && github.event_name == 'push' && (github.ref == 'refs/heads/dev-2.x' || github.ref == 'refs/heads/master') @@ -235,4 +248,6 @@ jobs: echo "Maven version ${version_with_snapshot} contains SNAPSHOT, adding date to container image tag" fi - mvn --batch-mode -P prettierSkip compile com.google.cloud.tools:jib-maven-plugin:build -Djib.to.tags=latest,$image_version + MAVEN_SKIP_ARGS="-P prettierSkip -Dmaven.test.skip=true -Dmaven.source.skip=true" + + mvn $MAVEN_ARGS $MAVEN_SKIP_ARGS package com.google.cloud.tools:jib-maven-plugin:build -Djib.to.tags=latest,$image_version diff --git a/.github/workflows/debug-client.yml b/.github/workflows/debug-client.yml index 6857b56b161..3c87e1c1b5c 100644 --- a/.github/workflows/debug-client.yml +++ b/.github/workflows/debug-client.yml @@ -76,8 +76,8 @@ jobs: git checkout dev-2.x git pull --rebase - CLIENT_HTML_OUTPUT=src/client/index.html - mkdir -p src/client/ + CLIENT_HTML_OUTPUT=application/src/client/index.html + mkdir -p application/src/client/ cp client/output/index.html ${CLIENT_HTML_OUTPUT} # just to debug diff --git a/.github/workflows/performance-test.yml b/.github/workflows/performance-test.yml index bfddea1b408..1ec537a0b4f 100644 --- a/.github/workflows/performance-test.yml +++ b/.github/workflows/performance-test.yml @@ -83,12 +83,12 @@ jobs: if: matrix.profile == 'core' || github.ref == 'refs/heads/dev-2.x' env: MAVEN_OPTS: "-Dmaven.repo.local=/home/lenni/.m2/repository/" - run: mvn -DskipTests --batch-mode package -P prettierSkip + run: mvn -DskipTests --batch-mode install -P prettierSkip - name: Build graph if: matrix.profile == 'core' || github.ref == 'refs/heads/dev-2.x' run: | - cp target/otp-*-SNAPSHOT-shaded.jar otp.jar + cp shaded-jar/target/otp-*-SNAPSHOT-shaded.jar otp.jar java -Xmx32G -jar otp.jar --build --save test/performance/${{ matrix.location }}/ - name: Run speed test @@ -98,18 +98,18 @@ jobs: SPEEDTEST_LOCATION: ${{ matrix.location }} MAVEN_OPTS: "-Xmx50g -XX:StartFlightRecording=delay=${{ matrix.jfr-delay }},duration=30m,filename=${{ matrix.location}}-speed-test.jfr -Dmaven.repo.local=/home/lenni/.m2/repository/" run: | - mvn exec:java -Dexec.mainClass="org.opentripplanner.transit.speed_test.SpeedTest" -Dexec.classpathScope=test -Dexec.args="--dir=test/performance/${{ matrix.location }} -p md -n ${{ matrix.iterations }} -i 3 -0" -P prettierSkip + mvn --projects application exec:java -Dexec.mainClass="org.opentripplanner.transit.speed_test.SpeedTest" -Dexec.classpathScope=test -Dexec.args="--dir=test/performance/${{ matrix.location }} -p md -n ${{ matrix.iterations }} -i 3 -0" - name: Archive travel results file if: matrix.profile == 'core' || github.ref == 'refs/heads/dev-2.x' uses: actions/upload-artifact@v4 with: name: ${{ matrix.location }}-travelSearch-results.csv - path: test/performance/${{ matrix.location }}/travelSearch-results.csv + path: test/performance/${{ matrix.location }}/travelSearch-results-md.csv - name: Archive Flight Recorder instrumentation file if: matrix.profile == 'core' || github.ref == 'refs/heads/dev-2.x' uses: actions/upload-artifact@v4 with: name: ${{ matrix.location }}-flight-recorder - path: ${{ matrix.location}}-speed-test.jfr + path: application/${{ matrix.location }}-speed-test.jfr diff --git a/.gitignore b/.gitignore index 6fac28d2178..d67b620f7b1 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ o_o_standalone_config_IncludeFileDirectiveTest_part.json .venv/ _site/ build/ +!/application/src/build/ dist/ doc/user/_build/ gen-java/ diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 4bd313c7a06..36ab454789a 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -40,22 +40,22 @@ examples. The Transit model is more complex than the VehiclePosition model. Below is a list of documented components in OTP. Not every component is documented at a high level, but this is a start and we would like to expand this list in the future. -### [OTP Configuration design](src/main/java/org/opentripplanner/standalone/config/package.md) +### [OTP Configuration design](application/src/main/java/org/opentripplanner/standalone/config/package.md) The Configuration module is responsible for loading and parsing OTP configuration files and map them into Plan Old Java Objects (POJOs). These POJOs are injected into the other components. -### [GTFS import module](src/main/java/org/opentripplanner/gtfs/package.md) +### [GTFS import module](application/src/main/java/org/opentripplanner/gtfs/package.md) Used to import GTFS transit data files. -### [NeTEx import module](src/main/java/org/opentripplanner/netex/package.md) +### [NeTEx import module](application/src/main/java/org/opentripplanner/netex/package.md) Used to import NeTEx transit data files. ### Transit Routing -#### [Raptor transit routing](src/main/java/org/opentripplanner/raptor/package.md) +#### [Raptor transit routing](raptor/src/main/java/org/opentripplanner/raptor/package.md) This is the OTP2 new transit routing engine implemented using the Raptor algorithm. It explains how Raptor works, the important concepts and the design. It might be worth reading even if you are not a @@ -68,35 +68,35 @@ dependencies from Raptor to other parts of OTP code, only to utility classes not Also, the code follows a stricter object-oriented design, than most other parts of OTP. The Raptor implementation is highly critical code, hence we set the bar higher with respect to code quality. -OTP provides transit data to Raptor by implementing the _raptor/api/transit_ model. The -[RoutingService](src/main/java/org/opentripplanner/routing/RoutingService.java) +OTP provides transit data to Raptor by implementing the _raptor/spi_. The +[RoutingService](application/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java) is responsible for mapping from the OTP context to a -[RaptorRequest](src/main/java/org/opentripplanner/raptor/api/request/RaptorRequest.java) +[RaptorRequest](raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorRequest.java) and then map the -result, [Raptor Path](src/main/java/org/opentripplanner/raptor/api/path/Path.java), back to +result, [Raptor Path](raptor/src/main/java/org/opentripplanner/raptor/api/path/RaptorPath.java), back to the OTP internal domain. This might seem like a lot of unnecessary mapping, but mapping is simple - routing is not. The performance of Raptor is important, and we care about every millisecond. All changes to the existing Raptor coded should be tested with the -[SpeedTest](src/test/java/org/opentripplanner/transit/raptor/speed_test/package.md) and compared +[SpeedTest](application/src/test/java/org/opentripplanner/transit/speed_test/package.md) and compared with an earlier version of the code to make sure the performance is NOT degraded. -#### [Transfer path optimization](src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/package.md) +#### [Transfer path optimization](application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/package.md) Describes the transfer functionality, the design and the implementation. The logic for finding the best transfer is distributed to the Raptor and -the [OptimizeTransferService](src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/OptimizeTransferService.java) +the [OptimizeTransferService](application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/OptimizeTransferService.java) . -#### [Itinerary list filter chain](src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md) +#### [Itinerary list filter chain](application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md) Describes the itinerary list filter chain, used to post-process the itineraries returned from the -routers in [RoutingWorker](src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java), +routers in [RoutingWorker](application/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java), in order to sort and reduce the number of returned itineraries. It can also be used to decorate the returned itineraries, especially if it requires more complex calculations, which would be unfeasible to do during the routing process. -### [Service](src/main/java/org/opentripplanner/service/package.md) +### [Service](application/src/main/java/org/opentripplanner/service/package.md) The service package contains small services usually specific to one or a few use-cases. In contrast -to a domain model they may use one or many domain models and other services. \ No newline at end of file +to a domain model they may use one or many domain models and other services. diff --git a/DEVELOPMENT_DECISION_RECORDS.md b/DEVELOPMENT_DECISION_RECORDS.md index a0e0554d4de..333ac88e1db 100644 --- a/DEVELOPMENT_DECISION_RECORDS.md +++ b/DEVELOPMENT_DECISION_RECORDS.md @@ -16,7 +16,13 @@ tests. Expect to include some code cleanup as part of all PRs. ## Follow-Naming-Conventions Use established terminology from GTFS, NeTEx or the existing OTP code. Make sure the code is easy -to read and understand. [Follow naming conventions](CODE_CONVENTIONS.md#naming-conventions) . +to read and understand. [Follow naming conventions](doc/dev/decisionrecords/NamingConventions.md#naming-conventions) . + + +## Do Analysis-and-design if needed + +Be prepared to provide [analyses and/or design documentation](doc/dev/decisionrecords/AnalysesAndDesign.md) +if a task is complex, changes the core model and/or the main APIs. ## Write-Code-Documentation - Use JavaDoc @@ -32,7 +38,7 @@ notes on `private` members and as inline comments. **See also** - [Developers-Guide > Code comments](doc/user/Developers-Guide.md#code-comments). - - [Codestyle > Javadoc Guidlines](doc/dev/decisionrecords/Codestyle.md#javadoc-guidlines) - JavaDoc checklist + - [Codestyle > Javadoc Guidelines](doc/dev/decisionrecords/Codestyle.md#javadoc-guidlines) - JavaDoc checklist ## Document-Config-and-APIs diff --git a/README.md b/README.md index 129771f9bdf..ec66e694e8c 100644 --- a/README.md +++ b/README.md @@ -31,11 +31,10 @@ We run a speed test (included in the code) to measure the performance for every ## Repository layout -The main Java server code is in `src/main/`. OTP also includes a Javascript client based on the -Leaflet mapping library in `src/client/`. This client is now primarily used for testing, with most -major deployments building custom clients from reusable components. The Maven build produces a -unified ("shaded") JAR file at `target/otp-VERSION.jar` containing all necessary code and -dependencies to run OpenTripPlanner. +The main Java server code is in `application/src/main/`. OTP also includes a Javascript client based on the +MapLibre mapping library in `client/src/`. This client is now used for testing, with most major +deployments building custom clients from reusable components. The Maven build produces a unified ("shaded") +JAR file at `shaded-jar/target/otp-VERSION.jar` containing all necessary code and dependencies to run OpenTripPlanner. Additional information and instructions are available in the [main documentation](http://docs.opentripplanner.org/en/dev-2.x/), including a diff --git a/application/pom.xml b/application/pom.xml new file mode 100644 index 00000000000..c3b4a6ee582 --- /dev/null +++ b/application/pom.xml @@ -0,0 +1,484 @@ + + + 4.0.0 + + org.opentripplanner + otp-root + 2.7.0-SNAPSHOT + + application + OpenTripPlanner - Application + + + + + ${project.groupId} + gtfs-realtime-protobuf + ${project.version} + + + ${project.groupId} + utils + ${project.version} + + + ${project.groupId} + raptor + ${project.version} + + + + + net.sf.trove4j + trove4j + + + + org.slf4j + slf4j-api + + + + org.slf4j + jul-to-slf4j + ${slf4j.version} + + + + ch.qos.logback + logback-classic + ${logback.version} + + + + net.logstash.logback + logstash-logback-encoder + 8.0 + + + + + com.google.dagger + dagger + ${google.dagger.version} + + + + + + org.geotools + gt-coverage + + + org.geotools + gt-geotiff + + + org.geotools + gt-api + + + org.geotools + gt-geojson-core + + + + + org.apache.lucene + lucene-core + ${lucene.version} + + + org.apache.lucene + lucene-queryparser + ${lucene.version} + + + org.apache.lucene + lucene-suggest + ${lucene.version} + + + + io.micrometer + micrometer-registry-prometheus + ${micrometer.version} + + + io.micrometer + micrometer-registry-influx + ${micrometer.version} + test + + + + + + edu.ucar + netcdf4 + ${netcdf4.version} + + + + org.entur + netex-java-model + ${netex-java-model.version} + + + + + org.entur + siri-java-model + ${siri-java-model.version} + + + + + org.entur + siri-protobuf-mapper + 1.0.3 + + + + org.mobilitydata + gbfs-java-model + 1.0.9 + + + + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + test + + + org.junit.jupiter + junit-jupiter-params + ${junit.version} + test + + + com.google.truth + truth + 1.4.4 + test + + + com.tngtech.archunit + archunit + 1.3.0 + test + + + org.mockito + mockito-core + 5.14.2 + test + + + io.github.origin-energy + java-snapshot-testing-junit5 + 2.3.0 + test + + + + + com.conveyal + kryo-tools + 1.6.0 + + + + de.javakaffee + kryo-serializers + 0.45 + + + + com.google.guava + guava + + + + org.glassfish.jersey.core + jersey-server + ${jersey.version} + + + + org.glassfish.jersey.containers + jersey-container-grizzly2-http + ${jersey.version} + + + + org.glassfish.jersey.media + jersey-media-json-jackson + ${jersey.version} + + + + org.glassfish.jersey.inject + jersey-hk2 + ${jersey.version} + + + + + org.glassfish.jaxb + jaxb-runtime + ${jaxb-runtime.version} + + + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + ${jackson.version} + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson.version} + + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + + + + + + com.google.cloud + google-cloud-storage + + + + + com.google.cloud + google-cloud-pubsub + + + + + com.google.protobuf + protobuf-java + + + + + org.onebusaway + onebusaway-gtfs + 4.3.0 + + + + org.processing + core + 2.2.1 + + + + net.java.dev.jets3t + jets3t + 0.9.4 + + + + org.openstreetmap.osmosis + osmosis-osm-binary + 0.48.3 + + + + com.beust + jcommander + 1.82 + + + com.graphql-java + graphql-java + 22.3 + + + com.graphql-java + graphql-java-extended-scalars + 22.0 + + + org.apache.httpcomponents.client5 + httpclient5 + 5.4.1 + + + commons-cli + commons-cli + 1.5.0 + test + + + net.sourceforge.javacsv + javacsv + 2.0 + + + org.eclipse.paho + org.eclipse.paho.client.mqttv3 + 1.2.5 + + + io.github.ci-cmg + mapbox-vector-tile + 4.0.6 + + + net.objecthunter + exp4j + 0.4.8 + + + com.azure + azure-core + 1.46.0 + + + com.azure + azure-messaging-servicebus + 7.15.0 + + + com.azure + azure-identity + 1.11.2 + compile + + + ch.poole + OpeningHoursParser + 0.28.2 + + + + + org.apache.commons + commons-compress + 1.27.1 + test + + + + + + + + src/main/resources + true + + + src/ext/resources + true + + + src/client + client + false + + + + + src/test/resources + + + src/ext-test/resources + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.6.0 + + + build-helper-generate-sources + generate-sources + + add-source + + + + src/main/java + src/ext/java + + + + + build-helper-generate-test-sources + generate-test-sources + + add-test-source + + + + src/test/java + src/ext-test/java + + + + + + + com.github.bohnman + package-info-maven-plugin + 1.1.0 + + + ${project.basedir}/src/main/java + ${project.basedir}/target/generated-sources + + + ** + + + + + + + + generate + + + + + + + diff --git a/application/src/build/templates/package-info-template.java b/application/src/build/templates/package-info-template.java new file mode 100644 index 00000000000..7cbb693f540 --- /dev/null +++ b/application/src/build/templates/package-info-template.java @@ -0,0 +1,4 @@ +@ParametersAreNonnullByDefault +package org.opentripplanner; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/client/META-INF/MANIFEST.MF b/application/src/client/META-INF/MANIFEST.MF similarity index 100% rename from src/client/META-INF/MANIFEST.MF rename to application/src/client/META-INF/MANIFEST.MF diff --git a/src/client/WEB-INF/web_client.xml b/application/src/client/WEB-INF/web_client.xml similarity index 100% rename from src/client/WEB-INF/web_client.xml rename to application/src/client/WEB-INF/web_client.xml diff --git a/src/client/classic-debug/i18n/babel.cfg b/application/src/client/classic-debug/i18n/babel.cfg similarity index 100% rename from src/client/classic-debug/i18n/babel.cfg rename to application/src/client/classic-debug/i18n/babel.cfg diff --git a/src/client/classic-debug/i18n/ca_ES.po b/application/src/client/classic-debug/i18n/ca_ES.po similarity index 100% rename from src/client/classic-debug/i18n/ca_ES.po rename to application/src/client/classic-debug/i18n/ca_ES.po diff --git a/src/client/classic-debug/i18n/de.po b/application/src/client/classic-debug/i18n/de.po similarity index 100% rename from src/client/classic-debug/i18n/de.po rename to application/src/client/classic-debug/i18n/de.po diff --git a/src/client/classic-debug/i18n/en.po b/application/src/client/classic-debug/i18n/en.po similarity index 100% rename from src/client/classic-debug/i18n/en.po rename to application/src/client/classic-debug/i18n/en.po diff --git a/src/client/classic-debug/i18n/es.po b/application/src/client/classic-debug/i18n/es.po similarity index 100% rename from src/client/classic-debug/i18n/es.po rename to application/src/client/classic-debug/i18n/es.po diff --git a/src/client/classic-debug/i18n/fr.po b/application/src/client/classic-debug/i18n/fr.po similarity index 100% rename from src/client/classic-debug/i18n/fr.po rename to application/src/client/classic-debug/i18n/fr.po diff --git a/src/client/classic-debug/i18n/hu.po b/application/src/client/classic-debug/i18n/hu.po similarity index 100% rename from src/client/classic-debug/i18n/hu.po rename to application/src/client/classic-debug/i18n/hu.po diff --git a/src/client/classic-debug/i18n/it.po b/application/src/client/classic-debug/i18n/it.po similarity index 100% rename from src/client/classic-debug/i18n/it.po rename to application/src/client/classic-debug/i18n/it.po diff --git a/src/client/classic-debug/i18n/messages.pot b/application/src/client/classic-debug/i18n/messages.pot similarity index 100% rename from src/client/classic-debug/i18n/messages.pot rename to application/src/client/classic-debug/i18n/messages.pot diff --git a/src/client/classic-debug/i18n/no.po b/application/src/client/classic-debug/i18n/no.po similarity index 100% rename from src/client/classic-debug/i18n/no.po rename to application/src/client/classic-debug/i18n/no.po diff --git a/src/client/classic-debug/i18n/pl.po b/application/src/client/classic-debug/i18n/pl.po similarity index 100% rename from src/client/classic-debug/i18n/pl.po rename to application/src/client/classic-debug/i18n/pl.po diff --git a/src/client/classic-debug/i18n/pt.po b/application/src/client/classic-debug/i18n/pt.po similarity index 100% rename from src/client/classic-debug/i18n/pt.po rename to application/src/client/classic-debug/i18n/pt.po diff --git a/src/client/classic-debug/i18n/sl.po b/application/src/client/classic-debug/i18n/sl.po similarity index 100% rename from src/client/classic-debug/i18n/sl.po rename to application/src/client/classic-debug/i18n/sl.po diff --git a/src/client/classic-debug/images/agency_logo.png b/application/src/client/classic-debug/images/agency_logo.png similarity index 100% rename from src/client/classic-debug/images/agency_logo.png rename to application/src/client/classic-debug/images/agency_logo.png diff --git a/src/client/classic-debug/images/alert.png b/application/src/client/classic-debug/images/alert.png similarity index 100% rename from src/client/classic-debug/images/alert.png rename to application/src/client/classic-debug/images/alert.png diff --git a/src/client/classic-debug/images/bicycle_green.png b/application/src/client/classic-debug/images/bicycle_green.png similarity index 100% rename from src/client/classic-debug/images/bicycle_green.png rename to application/src/client/classic-debug/images/bicycle_green.png diff --git a/src/client/classic-debug/images/bicycle_green_small.png b/application/src/client/classic-debug/images/bicycle_green_small.png similarity index 100% rename from src/client/classic-debug/images/bicycle_green_small.png rename to application/src/client/classic-debug/images/bicycle_green_small.png diff --git a/src/client/classic-debug/images/bicycle_red.png b/application/src/client/classic-debug/images/bicycle_red.png similarity index 100% rename from src/client/classic-debug/images/bicycle_red.png rename to application/src/client/classic-debug/images/bicycle_red.png diff --git a/src/client/classic-debug/images/bicycle_red_small.png b/application/src/client/classic-debug/images/bicycle_red_small.png similarity index 100% rename from src/client/classic-debug/images/bicycle_red_small.png rename to application/src/client/classic-debug/images/bicycle_red_small.png diff --git a/src/client/classic-debug/images/directions/circle_clockwise.png b/application/src/client/classic-debug/images/directions/circle_clockwise.png similarity index 100% rename from src/client/classic-debug/images/directions/circle_clockwise.png rename to application/src/client/classic-debug/images/directions/circle_clockwise.png diff --git a/src/client/classic-debug/images/directions/circle_counterclockwise.png b/application/src/client/classic-debug/images/directions/circle_counterclockwise.png similarity index 100% rename from src/client/classic-debug/images/directions/circle_counterclockwise.png rename to application/src/client/classic-debug/images/directions/circle_counterclockwise.png diff --git a/src/client/classic-debug/images/directions/clear.png b/application/src/client/classic-debug/images/directions/clear.png similarity index 100% rename from src/client/classic-debug/images/directions/clear.png rename to application/src/client/classic-debug/images/directions/clear.png diff --git a/src/client/classic-debug/images/directions/continue.png b/application/src/client/classic-debug/images/directions/continue.png similarity index 100% rename from src/client/classic-debug/images/directions/continue.png rename to application/src/client/classic-debug/images/directions/continue.png diff --git a/src/client/classic-debug/images/directions/depart.png b/application/src/client/classic-debug/images/directions/depart.png similarity index 100% rename from src/client/classic-debug/images/directions/depart.png rename to application/src/client/classic-debug/images/directions/depart.png diff --git a/src/client/classic-debug/images/directions/direction_icons.svg b/application/src/client/classic-debug/images/directions/direction_icons.svg similarity index 100% rename from src/client/classic-debug/images/directions/direction_icons.svg rename to application/src/client/classic-debug/images/directions/direction_icons.svg diff --git a/src/client/classic-debug/images/directions/elevator.png b/application/src/client/classic-debug/images/directions/elevator.png similarity index 100% rename from src/client/classic-debug/images/directions/elevator.png rename to application/src/client/classic-debug/images/directions/elevator.png diff --git a/src/client/classic-debug/images/directions/enter_station.png b/application/src/client/classic-debug/images/directions/enter_station.png similarity index 100% rename from src/client/classic-debug/images/directions/enter_station.png rename to application/src/client/classic-debug/images/directions/enter_station.png diff --git a/src/client/classic-debug/images/directions/exit_left.png b/application/src/client/classic-debug/images/directions/exit_left.png similarity index 100% rename from src/client/classic-debug/images/directions/exit_left.png rename to application/src/client/classic-debug/images/directions/exit_left.png diff --git a/src/client/classic-debug/images/directions/exit_right.png b/application/src/client/classic-debug/images/directions/exit_right.png similarity index 100% rename from src/client/classic-debug/images/directions/exit_right.png rename to application/src/client/classic-debug/images/directions/exit_right.png diff --git a/src/client/classic-debug/images/directions/exit_station.png b/application/src/client/classic-debug/images/directions/exit_station.png similarity index 100% rename from src/client/classic-debug/images/directions/exit_station.png rename to application/src/client/classic-debug/images/directions/exit_station.png diff --git a/src/client/classic-debug/images/directions/follow_signs.png b/application/src/client/classic-debug/images/directions/follow_signs.png similarity index 100% rename from src/client/classic-debug/images/directions/follow_signs.png rename to application/src/client/classic-debug/images/directions/follow_signs.png diff --git a/src/client/classic-debug/images/directions/hard_left.png b/application/src/client/classic-debug/images/directions/hard_left.png similarity index 100% rename from src/client/classic-debug/images/directions/hard_left.png rename to application/src/client/classic-debug/images/directions/hard_left.png diff --git a/src/client/classic-debug/images/directions/hard_right.png b/application/src/client/classic-debug/images/directions/hard_right.png similarity index 100% rename from src/client/classic-debug/images/directions/hard_right.png rename to application/src/client/classic-debug/images/directions/hard_right.png diff --git a/src/client/classic-debug/images/directions/left.png b/application/src/client/classic-debug/images/directions/left.png similarity index 100% rename from src/client/classic-debug/images/directions/left.png rename to application/src/client/classic-debug/images/directions/left.png diff --git a/src/client/classic-debug/images/directions/merge.png b/application/src/client/classic-debug/images/directions/merge.png similarity index 100% rename from src/client/classic-debug/images/directions/merge.png rename to application/src/client/classic-debug/images/directions/merge.png diff --git a/src/client/classic-debug/images/directions/right.png b/application/src/client/classic-debug/images/directions/right.png similarity index 100% rename from src/client/classic-debug/images/directions/right.png rename to application/src/client/classic-debug/images/directions/right.png diff --git a/src/client/classic-debug/images/directions/slightly_left.png b/application/src/client/classic-debug/images/directions/slightly_left.png similarity index 100% rename from src/client/classic-debug/images/directions/slightly_left.png rename to application/src/client/classic-debug/images/directions/slightly_left.png diff --git a/src/client/classic-debug/images/directions/slightly_right.png b/application/src/client/classic-debug/images/directions/slightly_right.png similarity index 100% rename from src/client/classic-debug/images/directions/slightly_right.png rename to application/src/client/classic-debug/images/directions/slightly_right.png diff --git a/src/client/classic-debug/images/directions/turn_left.png b/application/src/client/classic-debug/images/directions/turn_left.png similarity index 100% rename from src/client/classic-debug/images/directions/turn_left.png rename to application/src/client/classic-debug/images/directions/turn_left.png diff --git a/src/client/classic-debug/images/directions/turn_right.png b/application/src/client/classic-debug/images/directions/turn_right.png similarity index 100% rename from src/client/classic-debug/images/directions/turn_right.png rename to application/src/client/classic-debug/images/directions/turn_right.png diff --git a/src/client/classic-debug/images/directions/uturn_left.png b/application/src/client/classic-debug/images/directions/uturn_left.png similarity index 100% rename from src/client/classic-debug/images/directions/uturn_left.png rename to application/src/client/classic-debug/images/directions/uturn_left.png diff --git a/src/client/classic-debug/images/directions/uturn_right.png b/application/src/client/classic-debug/images/directions/uturn_right.png similarity index 100% rename from src/client/classic-debug/images/directions/uturn_right.png rename to application/src/client/classic-debug/images/directions/uturn_right.png diff --git a/src/client/classic-debug/images/flag_marker_green.png b/application/src/client/classic-debug/images/flag_marker_green.png similarity index 100% rename from src/client/classic-debug/images/flag_marker_green.png rename to application/src/client/classic-debug/images/flag_marker_green.png diff --git a/src/client/classic-debug/images/flag_marker_red.png b/application/src/client/classic-debug/images/flag_marker_red.png similarity index 100% rename from src/client/classic-debug/images/flag_marker_red.png rename to application/src/client/classic-debug/images/flag_marker_red.png diff --git a/src/client/classic-debug/images/gear.svg b/application/src/client/classic-debug/images/gear.svg similarity index 100% rename from src/client/classic-debug/images/gear.svg rename to application/src/client/classic-debug/images/gear.svg diff --git a/src/client/classic-debug/images/language_icon.png b/application/src/client/classic-debug/images/language_icon.png similarity index 100% rename from src/client/classic-debug/images/language_icon.png rename to application/src/client/classic-debug/images/language_icon.png diff --git a/src/client/classic-debug/images/language_icon.svg b/application/src/client/classic-debug/images/language_icon.svg similarity index 100% rename from src/client/classic-debug/images/language_icon.svg rename to application/src/client/classic-debug/images/language_icon.svg diff --git a/src/client/classic-debug/images/marker-0pct.png b/application/src/client/classic-debug/images/marker-0pct.png similarity index 100% rename from src/client/classic-debug/images/marker-0pct.png rename to application/src/client/classic-debug/images/marker-0pct.png diff --git a/src/client/classic-debug/images/marker-100pct.png b/application/src/client/classic-debug/images/marker-100pct.png similarity index 100% rename from src/client/classic-debug/images/marker-100pct.png rename to application/src/client/classic-debug/images/marker-100pct.png diff --git a/src/client/classic-debug/images/marker-25pct.png b/application/src/client/classic-debug/images/marker-25pct.png similarity index 100% rename from src/client/classic-debug/images/marker-25pct.png rename to application/src/client/classic-debug/images/marker-25pct.png diff --git a/src/client/classic-debug/images/marker-50pct.png b/application/src/client/classic-debug/images/marker-50pct.png similarity index 100% rename from src/client/classic-debug/images/marker-50pct.png rename to application/src/client/classic-debug/images/marker-50pct.png diff --git a/src/client/classic-debug/images/marker-75pct.png b/application/src/client/classic-debug/images/marker-75pct.png similarity index 100% rename from src/client/classic-debug/images/marker-75pct.png rename to application/src/client/classic-debug/images/marker-75pct.png diff --git a/src/client/classic-debug/images/marker-bike-green-shadowed.png b/application/src/client/classic-debug/images/marker-bike-green-shadowed.png similarity index 100% rename from src/client/classic-debug/images/marker-bike-green-shadowed.png rename to application/src/client/classic-debug/images/marker-bike-green-shadowed.png diff --git a/src/client/classic-debug/images/marker-bike-green.png b/application/src/client/classic-debug/images/marker-bike-green.png similarity index 100% rename from src/client/classic-debug/images/marker-bike-green.png rename to application/src/client/classic-debug/images/marker-bike-green.png diff --git a/src/client/classic-debug/images/marker-bike-red-shadowed.png b/application/src/client/classic-debug/images/marker-bike-red-shadowed.png similarity index 100% rename from src/client/classic-debug/images/marker-bike-red-shadowed.png rename to application/src/client/classic-debug/images/marker-bike-red-shadowed.png diff --git a/src/client/classic-debug/images/marker-bike-red.png b/application/src/client/classic-debug/images/marker-bike-red.png similarity index 100% rename from src/client/classic-debug/images/marker-bike-red.png rename to application/src/client/classic-debug/images/marker-bike-red.png diff --git a/src/client/classic-debug/images/marker-bike-shadow.png b/application/src/client/classic-debug/images/marker-bike-shadow.png similarity index 100% rename from src/client/classic-debug/images/marker-bike-shadow.png rename to application/src/client/classic-debug/images/marker-bike-shadow.png diff --git a/src/client/classic-debug/images/marker-blue-med.png b/application/src/client/classic-debug/images/marker-blue-med.png similarity index 100% rename from src/client/classic-debug/images/marker-blue-med.png rename to application/src/client/classic-debug/images/marker-blue-med.png diff --git a/src/client/classic-debug/images/marker-blue-nub.png b/application/src/client/classic-debug/images/marker-blue-nub.png similarity index 100% rename from src/client/classic-debug/images/marker-blue-nub.png rename to application/src/client/classic-debug/images/marker-blue-nub.png diff --git a/src/client/classic-debug/images/marker-blue-sm.png b/application/src/client/classic-debug/images/marker-blue-sm.png similarity index 100% rename from src/client/classic-debug/images/marker-blue-sm.png rename to application/src/client/classic-debug/images/marker-blue-sm.png diff --git a/src/client/classic-debug/images/marker-flag-end-shadowed.png b/application/src/client/classic-debug/images/marker-flag-end-shadowed.png similarity index 100% rename from src/client/classic-debug/images/marker-flag-end-shadowed.png rename to application/src/client/classic-debug/images/marker-flag-end-shadowed.png diff --git a/src/client/classic-debug/images/marker-flag-end.png b/application/src/client/classic-debug/images/marker-flag-end.png similarity index 100% rename from src/client/classic-debug/images/marker-flag-end.png rename to application/src/client/classic-debug/images/marker-flag-end.png diff --git a/src/client/classic-debug/images/marker-flag-shadow.png b/application/src/client/classic-debug/images/marker-flag-shadow.png similarity index 100% rename from src/client/classic-debug/images/marker-flag-shadow.png rename to application/src/client/classic-debug/images/marker-flag-shadow.png diff --git a/src/client/classic-debug/images/marker-flag-start-shadowed.png b/application/src/client/classic-debug/images/marker-flag-start-shadowed.png similarity index 100% rename from src/client/classic-debug/images/marker-flag-start-shadowed.png rename to application/src/client/classic-debug/images/marker-flag-start-shadowed.png diff --git a/src/client/classic-debug/images/marker-flag-start.png b/application/src/client/classic-debug/images/marker-flag-start.png similarity index 100% rename from src/client/classic-debug/images/marker-flag-start.png rename to application/src/client/classic-debug/images/marker-flag-start.png diff --git a/src/client/classic-debug/images/marker-med-0pct.png b/application/src/client/classic-debug/images/marker-med-0pct.png similarity index 100% rename from src/client/classic-debug/images/marker-med-0pct.png rename to application/src/client/classic-debug/images/marker-med-0pct.png diff --git a/src/client/classic-debug/images/marker-med-100pct.png b/application/src/client/classic-debug/images/marker-med-100pct.png similarity index 100% rename from src/client/classic-debug/images/marker-med-100pct.png rename to application/src/client/classic-debug/images/marker-med-100pct.png diff --git a/src/client/classic-debug/images/marker-med-25pct.png b/application/src/client/classic-debug/images/marker-med-25pct.png similarity index 100% rename from src/client/classic-debug/images/marker-med-25pct.png rename to application/src/client/classic-debug/images/marker-med-25pct.png diff --git a/src/client/classic-debug/images/marker-med-50pct.png b/application/src/client/classic-debug/images/marker-med-50pct.png similarity index 100% rename from src/client/classic-debug/images/marker-med-50pct.png rename to application/src/client/classic-debug/images/marker-med-50pct.png diff --git a/src/client/classic-debug/images/marker-med-75pct.png b/application/src/client/classic-debug/images/marker-med-75pct.png similarity index 100% rename from src/client/classic-debug/images/marker-med-75pct.png rename to application/src/client/classic-debug/images/marker-med-75pct.png diff --git a/src/client/classic-debug/images/marker-sm-0pct.png b/application/src/client/classic-debug/images/marker-sm-0pct.png similarity index 100% rename from src/client/classic-debug/images/marker-sm-0pct.png rename to application/src/client/classic-debug/images/marker-sm-0pct.png diff --git a/src/client/classic-debug/images/marker-sm-100pct.png b/application/src/client/classic-debug/images/marker-sm-100pct.png similarity index 100% rename from src/client/classic-debug/images/marker-sm-100pct.png rename to application/src/client/classic-debug/images/marker-sm-100pct.png diff --git a/src/client/classic-debug/images/marker-sm-25pct.png b/application/src/client/classic-debug/images/marker-sm-25pct.png similarity index 100% rename from src/client/classic-debug/images/marker-sm-25pct.png rename to application/src/client/classic-debug/images/marker-sm-25pct.png diff --git a/src/client/classic-debug/images/marker-sm-50pct.png b/application/src/client/classic-debug/images/marker-sm-50pct.png similarity index 100% rename from src/client/classic-debug/images/marker-sm-50pct.png rename to application/src/client/classic-debug/images/marker-sm-50pct.png diff --git a/src/client/classic-debug/images/marker-sm-75pct.png b/application/src/client/classic-debug/images/marker-sm-75pct.png similarity index 100% rename from src/client/classic-debug/images/marker-sm-75pct.png rename to application/src/client/classic-debug/images/marker-sm-75pct.png diff --git a/src/client/classic-debug/images/mode/airplane.png b/application/src/client/classic-debug/images/mode/airplane.png similarity index 100% rename from src/client/classic-debug/images/mode/airplane.png rename to application/src/client/classic-debug/images/mode/airplane.png diff --git a/src/client/classic-debug/images/mode/arrow-left.png b/application/src/client/classic-debug/images/mode/arrow-left.png similarity index 100% rename from src/client/classic-debug/images/mode/arrow-left.png rename to application/src/client/classic-debug/images/mode/arrow-left.png diff --git a/src/client/classic-debug/images/mode/arrow.png b/application/src/client/classic-debug/images/mode/arrow.png similarity index 100% rename from src/client/classic-debug/images/mode/arrow.png rename to application/src/client/classic-debug/images/mode/arrow.png diff --git a/src/client/classic-debug/images/mode/bicycle.png b/application/src/client/classic-debug/images/mode/bicycle.png similarity index 100% rename from src/client/classic-debug/images/mode/bicycle.png rename to application/src/client/classic-debug/images/mode/bicycle.png diff --git a/src/client/classic-debug/images/mode/bicycle_darkbg.png b/application/src/client/classic-debug/images/mode/bicycle_darkbg.png similarity index 100% rename from src/client/classic-debug/images/mode/bicycle_darkbg.png rename to application/src/client/classic-debug/images/mode/bicycle_darkbg.png diff --git a/src/client/classic-debug/images/mode/bus.png b/application/src/client/classic-debug/images/mode/bus.png similarity index 100% rename from src/client/classic-debug/images/mode/bus.png rename to application/src/client/classic-debug/images/mode/bus.png diff --git a/src/client/classic-debug/images/mode/bus_darkbg.png b/application/src/client/classic-debug/images/mode/bus_darkbg.png similarity index 100% rename from src/client/classic-debug/images/mode/bus_darkbg.png rename to application/src/client/classic-debug/images/mode/bus_darkbg.png diff --git a/src/client/classic-debug/images/mode/cable_car.png b/application/src/client/classic-debug/images/mode/cable_car.png similarity index 100% rename from src/client/classic-debug/images/mode/cable_car.png rename to application/src/client/classic-debug/images/mode/cable_car.png diff --git a/src/client/classic-debug/images/mode/car.png b/application/src/client/classic-debug/images/mode/car.png similarity index 100% rename from src/client/classic-debug/images/mode/car.png rename to application/src/client/classic-debug/images/mode/car.png diff --git a/src/client/classic-debug/images/mode/car_darkbg.png b/application/src/client/classic-debug/images/mode/car_darkbg.png similarity index 100% rename from src/client/classic-debug/images/mode/car_darkbg.png rename to application/src/client/classic-debug/images/mode/car_darkbg.png diff --git a/src/client/classic-debug/images/mode/carpool.png b/application/src/client/classic-debug/images/mode/carpool.png similarity index 100% rename from src/client/classic-debug/images/mode/carpool.png rename to application/src/client/classic-debug/images/mode/carpool.png diff --git a/src/client/classic-debug/images/mode/carpool_darkbg.png b/application/src/client/classic-debug/images/mode/carpool_darkbg.png similarity index 100% rename from src/client/classic-debug/images/mode/carpool_darkbg.png rename to application/src/client/classic-debug/images/mode/carpool_darkbg.png diff --git a/src/client/classic-debug/images/mode/coach.png b/application/src/client/classic-debug/images/mode/coach.png similarity index 100% rename from src/client/classic-debug/images/mode/coach.png rename to application/src/client/classic-debug/images/mode/coach.png diff --git a/src/client/classic-debug/images/mode/ferry.png b/application/src/client/classic-debug/images/mode/ferry.png similarity index 100% rename from src/client/classic-debug/images/mode/ferry.png rename to application/src/client/classic-debug/images/mode/ferry.png diff --git a/src/client/classic-debug/images/mode/ferry_darkbg.png b/application/src/client/classic-debug/images/mode/ferry_darkbg.png similarity index 100% rename from src/client/classic-debug/images/mode/ferry_darkbg.png rename to application/src/client/classic-debug/images/mode/ferry_darkbg.png diff --git a/src/client/classic-debug/images/mode/funicular.png b/application/src/client/classic-debug/images/mode/funicular.png similarity index 100% rename from src/client/classic-debug/images/mode/funicular.png rename to application/src/client/classic-debug/images/mode/funicular.png diff --git a/src/client/classic-debug/images/mode/gondola.png b/application/src/client/classic-debug/images/mode/gondola.png similarity index 100% rename from src/client/classic-debug/images/mode/gondola.png rename to application/src/client/classic-debug/images/mode/gondola.png diff --git a/src/client/classic-debug/images/mode/gondola_darkbg.png b/application/src/client/classic-debug/images/mode/gondola_darkbg.png similarity index 100% rename from src/client/classic-debug/images/mode/gondola_darkbg.png rename to application/src/client/classic-debug/images/mode/gondola_darkbg.png diff --git a/src/client/classic-debug/images/mode/mode_bubble.psd b/application/src/client/classic-debug/images/mode/mode_bubble.psd similarity index 100% rename from src/client/classic-debug/images/mode/mode_bubble.psd rename to application/src/client/classic-debug/images/mode/mode_bubble.psd diff --git a/src/client/classic-debug/images/mode/mode_bubble_ne.png b/application/src/client/classic-debug/images/mode/mode_bubble_ne.png similarity index 100% rename from src/client/classic-debug/images/mode/mode_bubble_ne.png rename to application/src/client/classic-debug/images/mode/mode_bubble_ne.png diff --git a/src/client/classic-debug/images/mode/mode_bubble_ne_highlight.png b/application/src/client/classic-debug/images/mode/mode_bubble_ne_highlight.png similarity index 100% rename from src/client/classic-debug/images/mode/mode_bubble_ne_highlight.png rename to application/src/client/classic-debug/images/mode/mode_bubble_ne_highlight.png diff --git a/src/client/classic-debug/images/mode/mode_bubble_nw.png b/application/src/client/classic-debug/images/mode/mode_bubble_nw.png similarity index 100% rename from src/client/classic-debug/images/mode/mode_bubble_nw.png rename to application/src/client/classic-debug/images/mode/mode_bubble_nw.png diff --git a/src/client/classic-debug/images/mode/mode_bubble_nw_highlight.png b/application/src/client/classic-debug/images/mode/mode_bubble_nw_highlight.png similarity index 100% rename from src/client/classic-debug/images/mode/mode_bubble_nw_highlight.png rename to application/src/client/classic-debug/images/mode/mode_bubble_nw_highlight.png diff --git a/src/client/classic-debug/images/mode/mode_bubble_se.png b/application/src/client/classic-debug/images/mode/mode_bubble_se.png similarity index 100% rename from src/client/classic-debug/images/mode/mode_bubble_se.png rename to application/src/client/classic-debug/images/mode/mode_bubble_se.png diff --git a/src/client/classic-debug/images/mode/mode_bubble_se_highlight.png b/application/src/client/classic-debug/images/mode/mode_bubble_se_highlight.png similarity index 100% rename from src/client/classic-debug/images/mode/mode_bubble_se_highlight.png rename to application/src/client/classic-debug/images/mode/mode_bubble_se_highlight.png diff --git a/src/client/classic-debug/images/mode/mode_bubble_sw.png b/application/src/client/classic-debug/images/mode/mode_bubble_sw.png similarity index 100% rename from src/client/classic-debug/images/mode/mode_bubble_sw.png rename to application/src/client/classic-debug/images/mode/mode_bubble_sw.png diff --git a/src/client/classic-debug/images/mode/mode_bubble_sw_highlight.png b/application/src/client/classic-debug/images/mode/mode_bubble_sw_highlight.png similarity index 100% rename from src/client/classic-debug/images/mode/mode_bubble_sw_highlight.png rename to application/src/client/classic-debug/images/mode/mode_bubble_sw_highlight.png diff --git a/src/client/classic-debug/images/mode/monorail.png b/application/src/client/classic-debug/images/mode/monorail.png similarity index 100% rename from src/client/classic-debug/images/mode/monorail.png rename to application/src/client/classic-debug/images/mode/monorail.png diff --git a/src/client/classic-debug/images/mode/rail.png b/application/src/client/classic-debug/images/mode/rail.png similarity index 100% rename from src/client/classic-debug/images/mode/rail.png rename to application/src/client/classic-debug/images/mode/rail.png diff --git a/src/client/classic-debug/images/mode/rail_darkbg.png b/application/src/client/classic-debug/images/mode/rail_darkbg.png similarity index 100% rename from src/client/classic-debug/images/mode/rail_darkbg.png rename to application/src/client/classic-debug/images/mode/rail_darkbg.png diff --git a/src/client/classic-debug/images/mode/scooter.png b/application/src/client/classic-debug/images/mode/scooter.png similarity index 100% rename from src/client/classic-debug/images/mode/scooter.png rename to application/src/client/classic-debug/images/mode/scooter.png diff --git a/src/client/classic-debug/images/mode/subway.png b/application/src/client/classic-debug/images/mode/subway.png similarity index 100% rename from src/client/classic-debug/images/mode/subway.png rename to application/src/client/classic-debug/images/mode/subway.png diff --git a/src/client/classic-debug/images/mode/subway_darkbg.png b/application/src/client/classic-debug/images/mode/subway_darkbg.png similarity index 100% rename from src/client/classic-debug/images/mode/subway_darkbg.png rename to application/src/client/classic-debug/images/mode/subway_darkbg.png diff --git a/src/client/classic-debug/images/mode/taxi.png b/application/src/client/classic-debug/images/mode/taxi.png similarity index 100% rename from src/client/classic-debug/images/mode/taxi.png rename to application/src/client/classic-debug/images/mode/taxi.png diff --git a/src/client/classic-debug/images/mode/tram.png b/application/src/client/classic-debug/images/mode/tram.png similarity index 100% rename from src/client/classic-debug/images/mode/tram.png rename to application/src/client/classic-debug/images/mode/tram.png diff --git a/src/client/classic-debug/images/mode/tram_darkbg.png b/application/src/client/classic-debug/images/mode/tram_darkbg.png similarity index 100% rename from src/client/classic-debug/images/mode/tram_darkbg.png rename to application/src/client/classic-debug/images/mode/tram_darkbg.png diff --git a/src/client/classic-debug/images/mode/trolleybus.png b/application/src/client/classic-debug/images/mode/trolleybus.png similarity index 100% rename from src/client/classic-debug/images/mode/trolleybus.png rename to application/src/client/classic-debug/images/mode/trolleybus.png diff --git a/src/client/classic-debug/images/mode/walk.png b/application/src/client/classic-debug/images/mode/walk.png similarity index 100% rename from src/client/classic-debug/images/mode/walk.png rename to application/src/client/classic-debug/images/mode/walk.png diff --git a/src/client/classic-debug/images/mode/walk_darkbg.png b/application/src/client/classic-debug/images/mode/walk_darkbg.png similarity index 100% rename from src/client/classic-debug/images/mode/walk_darkbg.png rename to application/src/client/classic-debug/images/mode/walk_darkbg.png diff --git a/src/client/classic-debug/images/openplans-logo-20x20.png b/application/src/client/classic-debug/images/openplans-logo-20x20.png similarity index 100% rename from src/client/classic-debug/images/openplans-logo-20x20.png rename to application/src/client/classic-debug/images/openplans-logo-20x20.png diff --git a/src/client/classic-debug/images/openplans-logo-40x40.png b/application/src/client/classic-debug/images/openplans-logo-40x40.png similarity index 100% rename from src/client/classic-debug/images/openplans-logo-40x40.png rename to application/src/client/classic-debug/images/openplans-logo-40x40.png diff --git a/src/client/classic-debug/images/openplans-logo-gray.gif b/application/src/client/classic-debug/images/openplans-logo-gray.gif similarity index 100% rename from src/client/classic-debug/images/openplans-logo-gray.gif rename to application/src/client/classic-debug/images/openplans-logo-gray.gif diff --git a/src/client/classic-debug/images/otp_logo_40px.png b/application/src/client/classic-debug/images/otp_logo_40px.png similarity index 100% rename from src/client/classic-debug/images/otp_logo_40px.png rename to application/src/client/classic-debug/images/otp_logo_40px.png diff --git a/src/client/classic-debug/images/otp_logo_darkbg_40px.png b/application/src/client/classic-debug/images/otp_logo_darkbg_40px.png similarity index 100% rename from src/client/classic-debug/images/otp_logo_darkbg_40px.png rename to application/src/client/classic-debug/images/otp_logo_darkbg_40px.png diff --git a/src/client/classic-debug/images/reverse.png b/application/src/client/classic-debug/images/reverse.png similarity index 100% rename from src/client/classic-debug/images/reverse.png rename to application/src/client/classic-debug/images/reverse.png diff --git a/src/client/classic-debug/images/shadow.png b/application/src/client/classic-debug/images/shadow.png similarity index 100% rename from src/client/classic-debug/images/shadow.png rename to application/src/client/classic-debug/images/shadow.png diff --git a/src/client/classic-debug/images/spinner.gif b/application/src/client/classic-debug/images/spinner.gif similarity index 100% rename from src/client/classic-debug/images/spinner.gif rename to application/src/client/classic-debug/images/spinner.gif diff --git a/src/client/classic-debug/images/stop20.png b/application/src/client/classic-debug/images/stop20.png similarity index 100% rename from src/client/classic-debug/images/stop20.png rename to application/src/client/classic-debug/images/stop20.png diff --git a/src/client/classic-debug/images/widget-trip-stop-first.png b/application/src/client/classic-debug/images/widget-trip-stop-first.png similarity index 100% rename from src/client/classic-debug/images/widget-trip-stop-first.png rename to application/src/client/classic-debug/images/widget-trip-stop-first.png diff --git a/src/client/classic-debug/images/widget-trip-stop-last.png b/application/src/client/classic-debug/images/widget-trip-stop-last.png similarity index 100% rename from src/client/classic-debug/images/widget-trip-stop-last.png rename to application/src/client/classic-debug/images/widget-trip-stop-last.png diff --git a/src/client/classic-debug/images/widget-trip-stop-middle.png b/application/src/client/classic-debug/images/widget-trip-stop-middle.png similarity index 100% rename from src/client/classic-debug/images/widget-trip-stop-middle.png rename to application/src/client/classic-debug/images/widget-trip-stop-middle.png diff --git a/src/client/classic-debug/index.html b/application/src/client/classic-debug/index.html similarity index 100% rename from src/client/classic-debug/index.html rename to application/src/client/classic-debug/index.html diff --git a/src/client/classic-debug/js/lib/ICanHaz.js b/application/src/client/classic-debug/js/lib/ICanHaz.js similarity index 100% rename from src/client/classic-debug/js/lib/ICanHaz.js rename to application/src/client/classic-debug/js/lib/ICanHaz.js diff --git a/src/client/classic-debug/js/lib/backbone-min.js b/application/src/client/classic-debug/js/lib/backbone-min.js similarity index 100% rename from src/client/classic-debug/js/lib/backbone-min.js rename to application/src/client/classic-debug/js/lib/backbone-min.js diff --git a/src/client/classic-debug/js/lib/backbone.js b/application/src/client/classic-debug/js/lib/backbone.js similarity index 100% rename from src/client/classic-debug/js/lib/backbone.js rename to application/src/client/classic-debug/js/lib/backbone.js diff --git a/src/client/classic-debug/js/lib/i18next-1.7.3.min.js b/application/src/client/classic-debug/js/lib/i18next-1.7.3.min.js similarity index 100% rename from src/client/classic-debug/js/lib/i18next-1.7.3.min.js rename to application/src/client/classic-debug/js/lib/i18next-1.7.3.min.js diff --git a/src/client/classic-debug/js/lib/jquery-ui/addons/jquery-ui-timepicker.css b/application/src/client/classic-debug/js/lib/jquery-ui/addons/jquery-ui-timepicker.css similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/addons/jquery-ui-timepicker.css rename to application/src/client/classic-debug/js/lib/jquery-ui/addons/jquery-ui-timepicker.css diff --git a/src/client/classic-debug/js/lib/jquery-ui/addons/jquery-ui-timepicker.js b/application/src/client/classic-debug/js/lib/jquery-ui/addons/jquery-ui-timepicker.js similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/addons/jquery-ui-timepicker.js rename to application/src/client/classic-debug/js/lib/jquery-ui/addons/jquery-ui-timepicker.js diff --git a/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png b/application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png rename to application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png diff --git a/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png b/application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png rename to application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png diff --git a/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png b/application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png rename to application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png diff --git a/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png b/application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png rename to application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png diff --git a/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png b/application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png rename to application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png diff --git a/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png b/application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png rename to application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png diff --git a/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png b/application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png rename to application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png diff --git a/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png rename to application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png diff --git a/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_222222_256x240.png b/application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_222222_256x240.png similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_222222_256x240.png rename to application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_222222_256x240.png diff --git a/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_2e83ff_256x240.png b/application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_2e83ff_256x240.png similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_2e83ff_256x240.png rename to application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_2e83ff_256x240.png diff --git a/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_454545_256x240.png b/application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_454545_256x240.png similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_454545_256x240.png rename to application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_454545_256x240.png diff --git a/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_888888_256x240.png b/application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_888888_256x240.png similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_888888_256x240.png rename to application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_888888_256x240.png diff --git a/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_cd0a0a_256x240.png b/application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_cd0a0a_256x240.png similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_cd0a0a_256x240.png rename to application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/images/ui-icons_cd0a0a_256x240.png diff --git a/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/jquery-ui-1.9.1.custom.css b/application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/jquery-ui-1.9.1.custom.css similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/css/smoothness/jquery-ui-1.9.1.custom.css rename to application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/jquery-ui-1.9.1.custom.css diff --git a/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/jquery-ui-1.9.1.custom.min.css b/application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/jquery-ui-1.9.1.custom.min.css similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/css/smoothness/jquery-ui-1.9.1.custom.min.css rename to application/src/client/classic-debug/js/lib/jquery-ui/css/smoothness/jquery-ui-1.9.1.custom.min.css diff --git a/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-ca.js b/application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-ca.js similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-ca.js rename to application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-ca.js diff --git a/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-de.js b/application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-de.js similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-de.js rename to application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-de.js diff --git a/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-es.js b/application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-es.js similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-es.js rename to application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-es.js diff --git a/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-fr.js b/application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-fr.js similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-fr.js rename to application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-fr.js diff --git a/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-hu.js b/application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-hu.js similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-hu.js rename to application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-hu.js diff --git a/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-it.js b/application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-it.js similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-it.js rename to application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-it.js diff --git a/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-no.js b/application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-no.js similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-no.js rename to application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-no.js diff --git a/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-pl.js b/application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-pl.js similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-pl.js rename to application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-pl.js diff --git a/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-pt.js b/application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-pt.js similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-pt.js rename to application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-pt.js diff --git a/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-sl.js b/application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-sl.js similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-sl.js rename to application/src/client/classic-debug/js/lib/jquery-ui/i18n/jquery.ui.datepicker-sl.js diff --git a/src/client/classic-debug/js/lib/jquery-ui/js/jquery-1.8.2.js b/application/src/client/classic-debug/js/lib/jquery-ui/js/jquery-1.8.2.js similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/js/jquery-1.8.2.js rename to application/src/client/classic-debug/js/lib/jquery-ui/js/jquery-1.8.2.js diff --git a/src/client/classic-debug/js/lib/jquery-ui/js/jquery-ui-1.9.1.custom.js b/application/src/client/classic-debug/js/lib/jquery-ui/js/jquery-ui-1.9.1.custom.js similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/js/jquery-ui-1.9.1.custom.js rename to application/src/client/classic-debug/js/lib/jquery-ui/js/jquery-ui-1.9.1.custom.js diff --git a/src/client/classic-debug/js/lib/jquery-ui/js/jquery-ui-1.9.1.custom.min.js b/application/src/client/classic-debug/js/lib/jquery-ui/js/jquery-ui-1.9.1.custom.min.js similarity index 100% rename from src/client/classic-debug/js/lib/jquery-ui/js/jquery-ui-1.9.1.custom.min.js rename to application/src/client/classic-debug/js/lib/jquery-ui/js/jquery-ui-1.9.1.custom.min.js diff --git a/src/client/classic-debug/js/otp/config.js b/application/src/client/classic-debug/js/otp/config.js similarity index 100% rename from src/client/classic-debug/js/otp/config.js rename to application/src/client/classic-debug/js/otp/config.js diff --git a/src/client/classic-debug/js/otp/core/ContextMenu.js b/application/src/client/classic-debug/js/otp/core/ContextMenu.js similarity index 100% rename from src/client/classic-debug/js/otp/core/ContextMenu.js rename to application/src/client/classic-debug/js/otp/core/ContextMenu.js diff --git a/src/client/classic-debug/js/otp/core/Geocoder.js b/application/src/client/classic-debug/js/otp/core/Geocoder.js similarity index 100% rename from src/client/classic-debug/js/otp/core/Geocoder.js rename to application/src/client/classic-debug/js/otp/core/Geocoder.js diff --git a/src/client/classic-debug/js/otp/core/GeocoderBag.js b/application/src/client/classic-debug/js/otp/core/GeocoderBag.js similarity index 100% rename from src/client/classic-debug/js/otp/core/GeocoderBag.js rename to application/src/client/classic-debug/js/otp/core/GeocoderBag.js diff --git a/src/client/classic-debug/js/otp/core/GeocoderBuiltin.js b/application/src/client/classic-debug/js/otp/core/GeocoderBuiltin.js similarity index 100% rename from src/client/classic-debug/js/otp/core/GeocoderBuiltin.js rename to application/src/client/classic-debug/js/otp/core/GeocoderBuiltin.js diff --git a/src/client/classic-debug/js/otp/core/IndexApi.js b/application/src/client/classic-debug/js/otp/core/IndexApi.js similarity index 100% rename from src/client/classic-debug/js/otp/core/IndexApi.js rename to application/src/client/classic-debug/js/otp/core/IndexApi.js diff --git a/src/client/classic-debug/js/otp/core/Map.js b/application/src/client/classic-debug/js/otp/core/Map.js similarity index 100% rename from src/client/classic-debug/js/otp/core/Map.js rename to application/src/client/classic-debug/js/otp/core/Map.js diff --git a/src/client/classic-debug/js/otp/core/MapContextMenu.js b/application/src/client/classic-debug/js/otp/core/MapContextMenu.js similarity index 100% rename from src/client/classic-debug/js/otp/core/MapContextMenu.js rename to application/src/client/classic-debug/js/otp/core/MapContextMenu.js diff --git a/src/client/classic-debug/js/otp/core/PopupMenu.js b/application/src/client/classic-debug/js/otp/core/PopupMenu.js similarity index 100% rename from src/client/classic-debug/js/otp/core/PopupMenu.js rename to application/src/client/classic-debug/js/otp/core/PopupMenu.js diff --git a/src/client/classic-debug/js/otp/core/QueryLogger.js b/application/src/client/classic-debug/js/otp/core/QueryLogger.js similarity index 100% rename from src/client/classic-debug/js/otp/core/QueryLogger.js rename to application/src/client/classic-debug/js/otp/core/QueryLogger.js diff --git a/src/client/classic-debug/js/otp/core/SOLRGeocoder.js b/application/src/client/classic-debug/js/otp/core/SOLRGeocoder.js similarity index 100% rename from src/client/classic-debug/js/otp/core/SOLRGeocoder.js rename to application/src/client/classic-debug/js/otp/core/SOLRGeocoder.js diff --git a/src/client/classic-debug/js/otp/core/TransitIndex.js b/application/src/client/classic-debug/js/otp/core/TransitIndex.js similarity index 100% rename from src/client/classic-debug/js/otp/core/TransitIndex.js rename to application/src/client/classic-debug/js/otp/core/TransitIndex.js diff --git a/src/client/classic-debug/js/otp/core/TripPlan.js b/application/src/client/classic-debug/js/otp/core/TripPlan.js similarity index 100% rename from src/client/classic-debug/js/otp/core/TripPlan.js rename to application/src/client/classic-debug/js/otp/core/TripPlan.js diff --git a/src/client/classic-debug/js/otp/core/Webapp.js b/application/src/client/classic-debug/js/otp/core/Webapp.js similarity index 100% rename from src/client/classic-debug/js/otp/core/Webapp.js rename to application/src/client/classic-debug/js/otp/core/Webapp.js diff --git a/src/client/classic-debug/js/otp/core/WidgetManagerMenu.js b/application/src/client/classic-debug/js/otp/core/WidgetManagerMenu.js similarity index 100% rename from src/client/classic-debug/js/otp/core/WidgetManagerMenu.js rename to application/src/client/classic-debug/js/otp/core/WidgetManagerMenu.js diff --git a/src/client/classic-debug/js/otp/debug.js b/application/src/client/classic-debug/js/otp/debug.js similarity index 100% rename from src/client/classic-debug/js/otp/debug.js rename to application/src/client/classic-debug/js/otp/debug.js diff --git a/src/client/classic-debug/js/otp/layers/AreaStopsLayer.js b/application/src/client/classic-debug/js/otp/layers/AreaStopsLayer.js similarity index 100% rename from src/client/classic-debug/js/otp/layers/AreaStopsLayer.js rename to application/src/client/classic-debug/js/otp/layers/AreaStopsLayer.js diff --git a/src/client/classic-debug/js/otp/layers/GeofencingZonesLayer.js b/application/src/client/classic-debug/js/otp/layers/GeofencingZonesLayer.js similarity index 100% rename from src/client/classic-debug/js/otp/layers/GeofencingZonesLayer.js rename to application/src/client/classic-debug/js/otp/layers/GeofencingZonesLayer.js diff --git a/src/client/classic-debug/js/otp/layers/StopsLayer.js b/application/src/client/classic-debug/js/otp/layers/StopsLayer.js similarity index 100% rename from src/client/classic-debug/js/otp/layers/StopsLayer.js rename to application/src/client/classic-debug/js/otp/layers/StopsLayer.js diff --git a/src/client/classic-debug/js/otp/layers/layers-templates.html b/application/src/client/classic-debug/js/otp/layers/layers-templates.html similarity index 100% rename from src/client/classic-debug/js/otp/layers/layers-templates.html rename to application/src/client/classic-debug/js/otp/layers/layers-templates.html diff --git a/src/client/classic-debug/js/otp/locale/Catalan.js b/application/src/client/classic-debug/js/otp/locale/Catalan.js similarity index 100% rename from src/client/classic-debug/js/otp/locale/Catalan.js rename to application/src/client/classic-debug/js/otp/locale/Catalan.js diff --git a/src/client/classic-debug/js/otp/locale/English.js b/application/src/client/classic-debug/js/otp/locale/English.js similarity index 100% rename from src/client/classic-debug/js/otp/locale/English.js rename to application/src/client/classic-debug/js/otp/locale/English.js diff --git a/src/client/classic-debug/js/otp/locale/French.js b/application/src/client/classic-debug/js/otp/locale/French.js similarity index 100% rename from src/client/classic-debug/js/otp/locale/French.js rename to application/src/client/classic-debug/js/otp/locale/French.js diff --git a/src/client/classic-debug/js/otp/locale/German.js b/application/src/client/classic-debug/js/otp/locale/German.js similarity index 100% rename from src/client/classic-debug/js/otp/locale/German.js rename to application/src/client/classic-debug/js/otp/locale/German.js diff --git a/src/client/classic-debug/js/otp/locale/Hungarian.js b/application/src/client/classic-debug/js/otp/locale/Hungarian.js similarity index 100% rename from src/client/classic-debug/js/otp/locale/Hungarian.js rename to application/src/client/classic-debug/js/otp/locale/Hungarian.js diff --git a/src/client/classic-debug/js/otp/locale/Italian.js b/application/src/client/classic-debug/js/otp/locale/Italian.js similarity index 100% rename from src/client/classic-debug/js/otp/locale/Italian.js rename to application/src/client/classic-debug/js/otp/locale/Italian.js diff --git a/src/client/classic-debug/js/otp/locale/Norwegian.js b/application/src/client/classic-debug/js/otp/locale/Norwegian.js similarity index 100% rename from src/client/classic-debug/js/otp/locale/Norwegian.js rename to application/src/client/classic-debug/js/otp/locale/Norwegian.js diff --git a/src/client/classic-debug/js/otp/locale/Polish.js b/application/src/client/classic-debug/js/otp/locale/Polish.js similarity index 100% rename from src/client/classic-debug/js/otp/locale/Polish.js rename to application/src/client/classic-debug/js/otp/locale/Polish.js diff --git a/src/client/classic-debug/js/otp/locale/Portuguese.js b/application/src/client/classic-debug/js/otp/locale/Portuguese.js similarity index 100% rename from src/client/classic-debug/js/otp/locale/Portuguese.js rename to application/src/client/classic-debug/js/otp/locale/Portuguese.js diff --git a/src/client/classic-debug/js/otp/locale/Slovenian.js b/application/src/client/classic-debug/js/otp/locale/Slovenian.js similarity index 100% rename from src/client/classic-debug/js/otp/locale/Slovenian.js rename to application/src/client/classic-debug/js/otp/locale/Slovenian.js diff --git a/src/client/classic-debug/js/otp/locale/Spanish.js b/application/src/client/classic-debug/js/otp/locale/Spanish.js similarity index 100% rename from src/client/classic-debug/js/otp/locale/Spanish.js rename to application/src/client/classic-debug/js/otp/locale/Spanish.js diff --git a/application/src/client/classic-debug/js/otp/locale/ca_ES.json b/application/src/client/classic-debug/js/otp/locale/ca_ES.json new file mode 100644 index 00000000000..e730a986359 --- /dev/null +++ b/application/src/client/classic-debug/js/otp/locale/ca_ES.json @@ -0,0 +1,238 @@ +{ + "Transit": "Transport públic", + "Bus Only": "Només bus", + "Rail Only": "Només tren", + "Airplane Only": "", + "Transit, No Airplane": "", + "Bicycle Only": "Bicicleta", + "Bicycle & Transit": "Transport públic i bicicleta", + "Walk Only": "Només a peu", + "Car Only": "", + "Taxi": "", + "Park and Ride": "", + "Ride and Kiss (Car Pickup)": "", + "Kiss and Ride (Car Dropoff)": "", + "Bike and Ride": "", + "Rented Bicycle": "", + "Transit & Rented Bicycle": "", + "Rented Scooter": "", + "Transit & Rented Scooter": "", + "Transit with flex access": "", + "Transit with flex egress": "", + "Transit with flex access and egress": "", + "Direct flex search": "", + "Recenter Map Here": "Centrar mapa aquí", + "Zoom In": "Apropar", + "Zoom Out": "Allunyar", + "Minimize all": "", + "Unminimize all": "", + "Stop Viewer": "", + "Plan Trip": "", + "From Stop": "", + "To Stop": "", + "Routes Serving Stop": "", + "Bike Share Planner": "", + "Trip Options": "", + "PICK UP BIKE": "", + "ALTERNATE PICKUP": "", + "DROP OFF BIKE": "", + "ALTERNATE DROP OFF": "", + "BIKE STATION": "", + "Station:": "", + "%d bike available": "", + "%d bike available_plural": "", + "%d dock available": "", + "%d dock available_plural": "", + "Recommended Pick Up:": "", + "Bicycle rental": "", + "Recommended Drop Off:": "", + "Multimodal Trip Planner": "", + "Itineraries": "", + "This itinerary departs on a different day from the previous one": "", + "%d Itinerary Returned": "", + "%d Itinerary Returned_plural": "", + "Link to search": "", + "Previous Page": "", + "Next Page": "", + "CONTINUES AS": "", + "%d min late": "", + "%d min late_plural": "", + "%d min early": "", + "%d min early_plural": "", + "on time": "", + "This itinerary departs on a different day than the one searched for": "", + "Arrived at destination with a rented bicycle!": "", + "End": "", + "Trip Summary": "", + "Travel": "Hora de sortida", + "Time": "Temps", + "GenCost": "", + "Total Walk": "", + "Total Bike": "", + "Total drive": "", + "Elevation Gained": "", + "Elevation Lost": "", + "Transfers": "transbords", + "Fare": "Tarifa", + "Valid": "Hora actual", + "Link to Itinerary": "", + "Print": "Imprimir", + "Your Trip": "", + "Email": "", + "every %d min": "", + "every %d min_plural": "", + "Board at ": "", + "Stop": "", + "Time in transit": "", + "Route ID": "", + "Trip ID": "", + "Service Date": "", + "Trip Viewer": "", + "late as": "", + "Stay on board": "stay on board", + "Alight": "", + "at": "a", + "%(currency)s %(price)s": "", + "Start: %(location)s at %(time_date)s": "", + "Board": "", + "(%(agency_id)s Stop ID #%(stop_id)s),": "", + "End: %(location)s at %(time_date)s": "", + "(%(agencyId)s Stop ID #%(id)s),": "", + "\nView itinerary online:\n%(itinerary_link)s\n": "", + "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "", + "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", + "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", + "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "", + "The trip planner is taking way too long to process your request. Please try again later.": "", + "The request has errors that the server is not willing or able to process.": "", + "Origin is unknown. Can you be a bit more descriptive?": "", + "Destination is unknown. Can you be a bit more descriptive?": "", + "Both origin and destination are unknown. Can you be a bit more descriptive?": "", + "Both origin and destination are not wheelchair accessible": "", + "Origin is within a trivial distance of the destination.": "", + "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "", + "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "", + "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "", + "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "", + "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "", + "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "", + "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "", + "Set as Start Location": "", + "Set as End Location": "", + "Destination": "", + "Error %(error_id)d": "", + "No Trip Found": "", + "Your %(bike_share_name)s route": "", + "Your bike route": "", + "Walk to the %(bike_share_name)s dock.": "", + "Walk from the %(bike_share_name)s dock to your destination.": "", + "Your walk route": "", + "Your route using the scooter": "", + "Your driving route": "", + "north": "nord", + "northeast": "nord-est", + "east": "est", + "southeast": "sud-est", + "south": "sud", + "southwest": "sud-oest", + "west": "oest", + "northwest": "nord-oest", + "hard left": "gira completament a la esquerra", + "left": "gira a la esquerra", + "slight left": "gira lleugerament a la esquerra", + "continue": "", + "slight right": "gira lleugerament a la dreta", + "right": "gira a la dreta", + "hard right": "gira completament a la dreta", + "elevator": "", + "U-turn left": "", + "U-turn right": "", + "Walk": "A peu", + "Cycle": "Bicicleta", + "Car": "Cotxe", + "Bus": "AUTOBÚS", + "Subway": "METRO", + "Train": "Tren", + "Ferry": "BOT", + "Light Rail": "", + "Cable Car": "PONT PENJANT", + "Funicular": "FUNICULAR", + "Aerial Tram": "", + "Airplane": "", + "Bicycle rental station": "", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", + "Start on": "", + " heading ": "", + "to continue on": "per a continuar a", + "on to": "", + "first": "", + "second": "", + "third": "", + "fourth": "", + "fifth": "", + "sixth": "", + "seventh": "", + "eight": "", + "ninth": "", + "tenth": "", + "%d hr": "", + "%d hr_plural": "", + "%d min": "", + "%d min_plural": "", + "%d sec": "", + "%d sec_plural": "", + "OK": "OK", + "Minimize": "", + "Bring to front": "", + "Send to back": "", + "Route:": "", + "Variant:": "", + "Stop Finder": "", + "Feed": "Agency", + "By ID": "", + "By Name": "", + "Search": "", + "No Stops Found": "", + "Date": "Data", + "Find Stops": "", + "(No Stop Selected)": "", + "Block": "", + "Recenter": "", + "Viewer": "", + "Quick": "", + "Flat": "", + "Bike Friendly": "", + "B": "", + "F": "", + "Q": "", + "All Routes": "", + "Save": "", + "Close": "", + "Travel Options": "", + "Geocoder": "", + "Arrive": "Arribada a", + "Now": "", + "Wheelchair accessible trip:": "Viatge amb accessibilitat:", + "Show Filtered Itineraries:": "", + "Travel by": "Mode de viatge", + "Preferred Routes": "", + "Edit": "Editar", + "None": "", + "Weight": "", + "Banned routes": "", + "Use": "", + "My Own Bike": "", + "A Shared Bike": "", + "Plan Your Trip": "Planificar el viatge", + "Additional parameters": "", + " to _direction": "", + " to _bus_direction": "", + "Start_template": "", + "Depart_itinerary": "Sortida des de", + "depart_itinerary": "Sortida des de", + "Start_popup": "", + "Depart_tripoptions": "Sortida des de" +} diff --git a/application/src/client/classic-debug/js/otp/locale/de.json b/application/src/client/classic-debug/js/otp/locale/de.json new file mode 100644 index 00000000000..56d08ab778a --- /dev/null +++ b/application/src/client/classic-debug/js/otp/locale/de.json @@ -0,0 +1,238 @@ +{ + "Transit": "ÖPNV", + "Bus Only": "nur Bus", + "Rail Only": "nur Bahn", + "Airplane Only": "", + "Transit, No Airplane": "", + "Bicycle Only": "Fahrrad", + "Bicycle & Transit": "ÖPNV und Fahrrad", + "Walk Only": "zu Fuß", + "Car Only": "", + "Taxi": "", + "Park and Ride": "Parken und Reisen", + "Ride and Kiss (Car Pickup)": "", + "Kiss and Ride (Car Dropoff)": "", + "Bike and Ride": "", + "Rented Bicycle": "Fahrradverleih", + "Transit & Rented Bicycle": "ÖPNV und Fahrradverleih", + "Rented Scooter": "", + "Transit & Rented Scooter": "ÖPNV und Fahrradverleih", + "Transit with flex access": "", + "Transit with flex egress": "", + "Transit with flex access and egress": "", + "Direct flex search": "", + "Recenter Map Here": "Karte hier zentrieren", + "Zoom In": "hineinzoomen", + "Zoom Out": "herauszoomen", + "Minimize all": "Alle Dialoge minimieren", + "Unminimize all": "Dialoge wiederanzeigen", + "Stop Viewer": "", + "Plan Trip": "", + "From Stop": "", + "To Stop": "", + "Routes Serving Stop": "", + "Bike Share Planner": "", + "Trip Options": "Einstellungen für Routensuche", + "PICK UP BIKE": "", + "ALTERNATE PICKUP": "", + "DROP OFF BIKE": "", + "ALTERNATE DROP OFF": "", + "BIKE STATION": "", + "Station:": "", + "%d bike available": "", + "%d bike available_plural": "", + "%d dock available": "", + "%d dock available_plural": "", + "Recommended Pick Up:": "", + "Bicycle rental": "Fahrradverleih", + "Recommended Drop Off:": "", + "Multimodal Trip Planner": "Multimodaler Routenplaner", + "Itineraries": "Routenvorschläge", + "This itinerary departs on a different day from the previous one": "", + "%d Itinerary Returned": "", + "%d Itinerary Returned_plural": "", + "Link to search": "Link für diese Suche erstellen", + "Previous Page": "Vorheriger", + "Next Page": "", + "CONTINUES AS": "Weiterfahren", + "%d min late": "%d min Verspätung", + "%d min late_plural": "%d min Verspätung", + "%d min early": "%d min zu früh", + "%d min early_plural": "%d min zu früh", + "on time": "pünktlich", + "This itinerary departs on a different day than the one searched for": "", + "Arrived at destination with a rented bicycle!": "", + "End": "Ankunft", + "Trip Summary": "", + "Travel": "Reise", + "Time": "Dauer", + "GenCost": "", + "Total Walk": "", + "Total Bike": "", + "Total drive": "", + "Elevation Gained": "", + "Elevation Lost": "", + "Transfers": "Umsteigepunkt", + "Fare": "Tarif", + "Valid": "Gültig bis", + "Link to Itinerary": "", + "Print": "drucken", + "Your Trip": "", + "Email": "", + "every %d min": "", + "every %d min_plural": "", + "Board at ": "", + "Stop": "", + "Time in transit": "", + "Route ID": "", + "Trip ID": "", + "Service Date": "", + "Trip Viewer": "", + "late as": "", + "Stay on board": "an Bord bleiben", + "Alight": "", + "at": "um", + "%(currency)s %(price)s": "", + "Start: %(location)s at %(time_date)s": "", + "Board": "", + "(%(agency_id)s Stop ID #%(stop_id)s),": "", + "End: %(location)s at %(time_date)s": "", + "(%(agencyId)s Stop ID #%(id)s),": "", + "\nView itinerary online:\n%(itinerary_link)s\n": "", + "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "", + "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", + "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", + "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "", + "The trip planner is taking way too long to process your request. Please try again later.": "", + "The request has errors that the server is not willing or able to process.": "", + "Origin is unknown. Can you be a bit more descriptive?": "", + "Destination is unknown. Can you be a bit more descriptive?": "", + "Both origin and destination are unknown. Can you be a bit more descriptive?": "", + "Both origin and destination are not wheelchair accessible": "", + "Origin is within a trivial distance of the destination.": "", + "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "", + "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "", + "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "", + "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "", + "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "", + "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "", + "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "", + "Set as Start Location": "", + "Set as End Location": "", + "Destination": "", + "Error %(error_id)d": "", + "No Trip Found": "", + "Your %(bike_share_name)s route": "", + "Your bike route": "", + "Walk to the %(bike_share_name)s dock.": "", + "Walk from the %(bike_share_name)s dock to your destination.": "", + "Your walk route": "", + "Your route using the scooter": "", + "Your driving route": "", + "north": "nord", + "northeast": "nordost", + "east": "ost", + "southeast": "südost", + "south": "süd", + "southwest": "südwest", + "west": "west", + "northwest": "nordwest", + "hard left": "scharf links", + "left": "links", + "slight left": "links halten", + "continue": "", + "slight right": "rechts halten", + "right": "rechts", + "hard right": "scharf rechts", + "elevator": "", + "U-turn left": "", + "U-turn right": "", + "Walk": "zu Fuß gehen", + "Cycle": "Fahrrad", + "Car": "Auto", + "Bus": "Bus", + "Subway": "U-Bahn", + "Train": "Bahn", + "Ferry": "Fähre", + "Light Rail": "", + "Cable Car": "Standseilbahn", + "Funicular": "Seilbahn", + "Aerial Tram": "", + "Airplane": "", + "Bicycle rental station": "Fahrradverleihstation", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", + "Start on": "", + " heading ": "", + "to continue on": "weiter auf", + "on to": "", + "first": "Erster", + "second": "", + "third": "", + "fourth": "", + "fifth": "", + "sixth": "", + "seventh": "", + "eight": "", + "ninth": "", + "tenth": "", + "%d hr": "", + "%d hr_plural": "", + "%d min": "", + "%d min_plural": "", + "%d sec": "", + "%d sec_plural": "", + "OK": "OK", + "Minimize": "Minimieren", + "Bring to front": "in den Vordergrund", + "Send to back": "in den Hintergrund", + "Route:": "", + "Variant:": "", + "Stop Finder": "", + "Feed": "Agency", + "By ID": "", + "By Name": "", + "Search": "", + "No Stops Found": "", + "Date": "Datum", + "Find Stops": "", + "(No Stop Selected)": "", + "Block": "", + "Recenter": "", + "Viewer": "", + "Quick": "Schnellste", + "Flat": "Flach", + "Bike Friendly": "Fahrradgeeignet", + "B": "F", + "F": "Fl", + "Q": "S", + "All Routes": "alle Routen", + "Save": "Speichern", + "Close": "Schließen", + "Travel Options": "Routeneinstellungen", + "Geocoder": "Geocoder", + "Arrive": "Ankunft", + "Now": "Jetzt", + "Wheelchair accessible trip:": "barrierefreie Route:", + "Show Filtered Itineraries:": "", + "Travel by": "Fortbewegungsart/Verkehrsmittel", + "Preferred Routes": "bevorzugte Routen", + "Edit": "anpassen", + "None": "keine", + "Weight": "Gewichtung", + "Banned routes": "ausgeschlossene Routen", + "Use": "", + "My Own Bike": "", + "A Shared Bike": "", + "Plan Your Trip": "Route berechnen", + "Additional parameters": "", + " to _direction": "", + " to _bus_direction": "", + "Start_template": "Abfahrt", + "Depart_itinerary": "Abfahrt", + "depart_itinerary": "Abfahrt", + "Start_popup": "Abfahrt", + "Depart_tripoptions": "Abfahrt" +} diff --git a/application/src/client/classic-debug/js/otp/locale/en.json b/application/src/client/classic-debug/js/otp/locale/en.json new file mode 100644 index 00000000000..a4d3f1efa9d --- /dev/null +++ b/application/src/client/classic-debug/js/otp/locale/en.json @@ -0,0 +1,238 @@ +{ + "Transit": "Transit", + "Bus Only": "Bus Only", + "Rail Only": "Rail Only", + "Airplane Only": "Airplane Only", + "Transit, No Airplane": "", + "Bicycle Only": "Bicycle Only", + "Bicycle & Transit": "Bicycle & Transit", + "Walk Only": "Walk Only", + "Car Only": "Car Only", + "Taxi": "", + "Park and Ride": "Park and Ride", + "Ride and Kiss (Car Pickup)": "", + "Kiss and Ride (Car Dropoff)": "", + "Bike and Ride": "Bike and Ride", + "Rented Bicycle": "Rented Bicycle", + "Transit & Rented Bicycle": "Transit & Rented Bicycle", + "Rented Scooter": "", + "Transit & Rented Scooter": "Transit & Rented Bicycle", + "Transit with flex access": "", + "Transit with flex egress": "", + "Transit with flex access and egress": "", + "Direct flex search": "", + "Recenter Map Here": "Recenter Map Here", + "Zoom In": "Zoom In", + "Zoom Out": "Zoom Out", + "Minimize all": "Minimize all", + "Unminimize all": "Unminimize all", + "Stop Viewer": "Stop Viewer", + "Plan Trip": "Plan Trip", + "From Stop": "From Stop", + "To Stop": "To Stop", + "Routes Serving Stop": "Routes Serving Stop", + "Bike Share Planner": "Bike Share Planner", + "Trip Options": "Trip Options", + "PICK UP BIKE": "PICK UP BIKE", + "ALTERNATE PICKUP": "ALTERNATE PICKUP", + "DROP OFF BIKE": "DROP OFF BIKE", + "ALTERNATE DROP OFF": "ALTERNATE DROP OFF", + "BIKE STATION": "BIKE STATION", + "Station:": "Station:", + "%d bike available": "%d bike available", + "%d bike available_plural": "%d bikes available", + "%d dock available": "%d dock available", + "%d dock available_plural": "%d docks available", + "Recommended Pick Up:": "Recommended Pick Up:", + "Bicycle rental": "Bicycle rental", + "Recommended Drop Off:": "Recommended Drop Off:", + "Multimodal Trip Planner": "Multimodal Trip Planner", + "Itineraries": "Itineraries", + "This itinerary departs on a different day from the previous one": "", + "%d Itinerary Returned": "%d Itinerary Returned", + "%d Itinerary Returned_plural": "%d Itineraries Returned", + "Link to search": "Link to search", + "Previous Page": "Previous", + "Next Page": "", + "CONTINUES AS": "CONTINUES AS", + "%d min late": "%d min late", + "%d min late_plural": "%d mins late", + "%d min early": "%d min early", + "%d min early_plural": "%d mins early", + "on time": "on time", + "This itinerary departs on a different day than the one searched for": "", + "Arrived at destination with a rented bicycle!": "", + "End": "End", + "Trip Summary": "Trip Summary", + "Travel": "Travel", + "Time": "Time", + "GenCost": "Weight/Cost", + "Total Walk": "Total Walk", + "Total Bike": "Total Bike", + "Total drive": "Total drive", + "Elevation Gained": "", + "Elevation Lost": "Elevation Lost", + "Transfers": "Transfers", + "Fare": "Fare", + "Valid": "Valid", + "Link to Itinerary": "Link to Itinerary", + "Print": "Print", + "Your Trip": "Your Trip", + "Email": "Email", + "every %d min": "every %d min", + "every %d min_plural": "every %d mins", + "Board at ": "Board at ", + "Stop": "Stop", + "Time in transit": "Time in transit", + "Route ID": "", + "Trip ID": "", + "Service Date": "", + "Trip Viewer": "Trip Viewer", + "late as": "late as", + "Stay on board": "Stay on board", + "Alight": "Alight", + "at": "at", + "%(currency)s %(price)s": "%(currency)s %(price)s", + "Start: %(location)s at %(time_date)s": "Start: %(location)s at %(time_date)s", + "Board": "Board", + "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s Stop ID #%(stop_id)s),", + "End: %(location)s at %(time_date)s": "End: %(location)s at %(time_date)s", + "(%(agencyId)s Stop ID #%(id)s),": "", + "\nView itinerary online:\n%(itinerary_link)s\n": "\nView itinerary online:\n%(itinerary_link)s\n", + "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "We're sorry. The trip planner is temporarily unavailable. Please try again later.", + "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "Trip is not possible. You might be trying to plan a trip outside the map data boundary.", + "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", + "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.", + "The trip planner is taking way too long to process your request. Please try again later.": "The trip planner is taking way too long to process your request. Please try again later.", + "The request has errors that the server is not willing or able to process.": "The request has errors that the server is not willing or able to process.", + "Origin is unknown. Can you be a bit more descriptive?": "Origin is unknown. Can you be a bit more descriptive?", + "Destination is unknown. Can you be a bit more descriptive?": "Destination is unknown. Can you be a bit more descriptive?", + "Both origin and destination are unknown. Can you be a bit more descriptive?": "Both origin and destination are unknown. Can you be a bit more descriptive?", + "Both origin and destination are not wheelchair accessible": "Both origin and destination are not wheelchair accessible", + "Origin is within a trivial distance of the destination.": "Origin is within a trivial distance of the destination.", + "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.", + "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.", + "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "Both origin and destination are ambiguous. Please select from the following options, or be more specific.", + "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are", + "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1", + "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE", + "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set", + "Set as Start Location": "Set as Start Location", + "Set as End Location": "Set as End Location", + "Destination": "Destination", + "Error %(error_id)d": "Error %(error_id)d", + "No Trip Found": "No Trip Found", + "Your %(bike_share_name)s route": "Your %(bike_share_name)s route", + "Your bike route": "Your bike route", + "Walk to the %(bike_share_name)s dock.": "Walk to the %(bike_share_name)s dock.", + "Walk from the %(bike_share_name)s dock to your destination.": "Walk from the %(bike_share_name)s dock to your destination.", + "Your walk route": "Your walk route", + "Your route using the scooter": "", + "Your driving route": "Your bike route", + "north": "north", + "northeast": "northeast", + "east": "east", + "southeast": "southeast", + "south": "south", + "southwest": "southwest", + "west": "west", + "northwest": "northwest", + "hard left": "hard left", + "left": "left", + "slight left": "slight left", + "continue": "continue", + "slight right": "slight right", + "right": "right", + "hard right": "hard right", + "elevator": "elevator", + "U-turn left": "U-turn left", + "U-turn right": "U-turn right", + "Walk": "Walk", + "Cycle": "Cycle", + "Car": "Car", + "Bus": "Bus", + "Subway": "Subway", + "Train": "Train", + "Ferry": "Ferry", + "Light Rail": "Light Rail", + "Cable Car": "Cable Car", + "Funicular": "Funicular", + "Aerial Tram": "Aerial Tram", + "Airplane": "", + "Bicycle rental station": "Bicycle rental station", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s", + "Start on": "Start on", + " heading ": " heading ", + "to continue on": "to continue on", + "on to": "on to", + "first": "first", + "second": "second", + "third": "third", + "fourth": "fourth", + "fifth": "fifth", + "sixth": "sixth", + "seventh": "seventh", + "eight": "eight", + "ninth": "ninth", + "tenth": "tenth", + "%d hr": "%d hr", + "%d hr_plural": "%d hrs", + "%d min": "%d min", + "%d min_plural": "%d mins", + "%d sec": "%d sec", + "%d sec_plural": "%d secs", + "OK": "OK", + "Minimize": "Minimize", + "Bring to front": "Bring to front", + "Send to back": "Send to back", + "Route:": "Route:", + "Variant:": "Variant:", + "Stop Finder": "Stop Finder", + "Feed": "Agency", + "By ID": "By ID", + "By Name": "By Name", + "Search": "Search", + "No Stops Found": "No Stops Found", + "Date": "Date", + "Find Stops": "Find Stops", + "(No Stop Selected)": "(No Stop Selected)", + "Block": "Block", + "Recenter": "Recenter", + "Viewer": "Viewer", + "Quick": "Quick", + "Flat": "Flat", + "Bike Friendly": "Bike Friendly", + "B": "B", + "F": "F", + "Q": "Q", + "All Routes": "All Routes", + "Save": "Save", + "Close": "Close", + "Travel Options": "Travel Options", + "Geocoder": "Geocoder", + "Arrive": "Arrive", + "Now": "Now", + "Wheelchair accessible trip:": "Wheelchair accessible trip:", + "Show Filtered Itineraries:": "", + "Travel by": "Travel by", + "Preferred Routes": "Preferred Routes", + "Edit": "Edit", + "None": "None", + "Weight": "Weight", + "Banned routes": "Banned routes", + "Use": "Use", + "My Own Bike": "My Own Bike", + "A Shared Bike": "A Shared Bike", + "Plan Your Trip": "Plan Your Trip", + "Additional parameters": "", + " to _direction": " to ", + " to _bus_direction": " to ", + "Start_template": "Start", + "Depart_itinerary": "Depart", + "depart_itinerary": "depart", + "Start_popup": "Start", + "Depart_tripoptions": "Depart" +} diff --git a/application/src/client/classic-debug/js/otp/locale/es.json b/application/src/client/classic-debug/js/otp/locale/es.json new file mode 100644 index 00000000000..7909780d938 --- /dev/null +++ b/application/src/client/classic-debug/js/otp/locale/es.json @@ -0,0 +1,238 @@ +{ + "Transit": "Transporte Público", + "Bus Only": "Sólo autobús", + "Rail Only": "Sólo tren", + "Airplane Only": "", + "Transit, No Airplane": "", + "Bicycle Only": "Sólo bicicletas", + "Bicycle & Transit": "Bicicleta y Transporte Público", + "Walk Only": "Sólo a pie", + "Car Only": "Comienza en", + "Taxi": "", + "Park and Ride": "Aparcar y Transporte Público", + "Ride and Kiss (Car Pickup)": "", + "Kiss and Ride (Car Dropoff)": "", + "Bike and Ride": "Bicicleta y Transporte Público", + "Rented Bicycle": "Alquiler bicicleta", + "Transit & Rented Bicycle": "Transporte Público y Alquiler de bicicleta", + "Rented Scooter": "", + "Transit & Rented Scooter": "Transporte Público y Alquiler de bicicleta", + "Transit with flex access": "", + "Transit with flex egress": "", + "Transit with flex access and egress": "", + "Direct flex search": "", + "Recenter Map Here": "Centrar Mapa Aquí", + "Zoom In": "Acercar", + "Zoom Out": "Alejar", + "Minimize all": "Minimizar todo", + "Unminimize all": "Ampliar todo", + "Stop Viewer": "Visor de parada", + "Plan Trip": "Calcular viaje", + "From Stop": "Desde parada", + "To Stop": "Hasta parada", + "Routes Serving Stop": "Rutas por la parada", + "Bike Share Planner": "Planificador de Bicicleta Compartida", + "Trip Options": "Opciones de viaje", + "PICK UP BIKE": "Recogida de bicicleta", + "ALTERNATE PICKUP": "Recogida alternativa", + "DROP OFF BIKE": "DEVOLUCIÓN DE BICICLETA", + "ALTERNATE DROP OFF": "DEVOLUCIÓN DE BICICLETA ALTERNATIVA", + "BIKE STATION": "Estación de bicicleta", + "Station:": "Estación:", + "%d bike available": "%d bike available", + "%d bike available_plural": "%d bikes available", + "%d dock available": "%d dock available", + "%d dock available_plural": "%d docks available", + "Recommended Pick Up:": "Recogida recomendada:", + "Bicycle rental": "alquiler de bicicleta", + "Recommended Drop Off:": "Devolución recomendada:", + "Multimodal Trip Planner": "Planificador multimodo", + "Itineraries": "Rutas", + "This itinerary departs on a different day from the previous one": "", + "%d Itinerary Returned": "%d Ruta encontrada", + "%d Itinerary Returned_plural": "%d Rutas encontradas", + "Link to search": "Enlace a búsqueda", + "Previous Page": "Anterior", + "Next Page": "", + "CONTINUES AS": "CONTINÚA COMO", + "%d min late": "%d min tarde", + "%d min late_plural": "%d mins tarde", + "%d min early": "%d min early", + "%d min early_plural": "%d mins early", + "on time": "puntual", + "This itinerary departs on a different day than the one searched for": "", + "Arrived at destination with a rented bicycle!": "", + "End": "Fin", + "Trip Summary": "Resumen de la ruta", + "Travel": "Viaje", + "Time": "Duración", + "GenCost": "", + "Total Walk": "Total a pie", + "Total Bike": "Total en bicicleta", + "Total drive": "", + "Elevation Gained": "", + "Elevation Lost": "", + "Transfers": "Transbordos", + "Fare": "Ticket", + "Valid": "Válido", + "Link to Itinerary": "Enlace a ruta", + "Print": "Imprimir", + "Your Trip": "Tu Viaje", + "Email": "Email", + "every %d min": "cada %d min", + "every %d min_plural": "cada %d mins", + "Board at ": "Desde ", + "Stop": "Parada", + "Time in transit": "Durante", + "Route ID": "", + "Trip ID": "", + "Service Date": "", + "Trip Viewer": "Visor de ruta", + "late as": "no más tarde que", + "Stay on board": "mantente montado", + "Alight": "hasta ", + "at": "en", + "%(currency)s %(price)s": "%(currency)s %(price)s", + "Start: %(location)s at %(time_date)s": "Comienza: %(location)s a las %(time_date)s", + "Board": "Toma", + "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s ID Parada #%(stop_id)s),", + "End: %(location)s at %(time_date)s": "Finaliza: %(location)s a las %(time_date)s", + "(%(agencyId)s Stop ID #%(id)s),": "", + "\nView itinerary online:\n%(itinerary_link)s\n": "\nVer ruta online:\n%(itinerary_link)s\n", + "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Lo sentimos. El planificador de ruta está fuera de servicio temporalmente. Inténtelo más tarde.", + "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", + "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", + "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Tiempos no disponibles. La información disponible podría no ser válida para la fecha actual o no hay rutas disponibles para tu viaje.", + "The trip planner is taking way too long to process your request. Please try again later.": "El planificador de rutas está tardando demasiado. Por favor, inténtalo más tarde.", + "The request has errors that the server is not willing or able to process.": "Error en la petición, el server no puede procesar la información.", + "Origin is unknown. Can you be a bit more descriptive?": "Origen desconocido. ¿Puedes ser un poco más descriptivo?", + "Destination is unknown. Can you be a bit more descriptive?": "Destino desconocido. ¿Puedes ser un poco más descriptivo?", + "Both origin and destination are unknown. Can you be a bit more descriptive?": "Origen y destino desconocidos ¿Puedes ser un poco más descriptivo?", + "Both origin and destination are not wheelchair accessible": "Origen y destino no son accesibles a silla de ruedas.", + "Origin is within a trivial distance of the destination.": "Origen y destino están demasiado cerca.", + "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "El planificador de rutas no está seguro de tu origen. Por favor, seleccione una de las siguientes opciones o introduzca un origen más exacto.", + "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "El planificador de rutas no está seguro de tu destino. Por favor, seleccione una de las siguientes opciones o introduzca un destino más exacto.", + "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "Origen y destino son ambiguos. Por favor, seleccione una de las siguientes opciones o introduzca un destino más exacto.", + "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "El triángulo de Seguridad, Llano y Tiempo debe ser seleccionado si está disponible.", + "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "El valor del triángulo de Seguridad, Llano y Tiempo debe sumar 1.", + "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "Si el triángulo de Seguridad, Llano y Tiempo está disponible, debe ser un TRIÁNGULO.", + "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "Si el tipo de optimización es triángulo, los factores de Seguridad, Llano y Tiempo tienen que estar seleccionados.", + "Set as Start Location": "Ruta desde aquí", + "Set as End Location": "Ruta hacia aquí", + "Destination": "Fin", + "Error %(error_id)d": "Error %(error_id)d", + "No Trip Found": "Viaje no encontrado", + "Your %(bike_share_name)s route": "Tu ruta %(bike_share_name)s", + "Your bike route": "Tu ruta en bicicleta", + "Walk to the %(bike_share_name)s dock.": "Camina hacia la estación %(bike_share_name)s.", + "Walk from the %(bike_share_name)s dock to your destination.": "Camina desde la estación %(bike_share_name)s hacia tu destino.", + "Your walk route": "Tu ruta a pie", + "Your route using the scooter": "", + "Your driving route": "Tu ruta en bicicleta", + "north": "Norte", + "northeast": "Nordeste", + "east": "Este", + "southeast": "Sureste", + "south": "Sur", + "southwest": "Suroeste", + "west": "Oeste", + "northwest": "Noroeste", + "hard left": "Izquierda fuerte", + "left": "izquierda", + "slight left": "Izquierda suave", + "continue": "continúa", + "slight right": "Derecha suave", + "right": "derecha", + "hard right": "Derecha fuerte", + "elevator": "ascensor", + "U-turn left": "Gira a la izquierda", + "U-turn right": "Gira a la derecha", + "Walk": "Camina", + "Cycle": "Bicicleta", + "Car": "Coche", + "Bus": "Autobús", + "Subway": "Metro", + "Train": "Tren", + "Ferry": "Barco", + "Light Rail": "Tranvía", + "Cable Car": "Bus Tranvía", + "Funicular": "Funicular", + "Aerial Tram": "Funicular", + "Airplane": "", + "Bicycle rental station": "estación de alquiler de bicicleta", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Toma la rotonda sentido contrario a las agujas del reloj hasta la %(ordinal_exit_number)s salida dirección %(street_name)s", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Toma la rotonda sentido contrario a las agujas del reloj hasta la %(ordinal_exit_number)s salida hacia %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Toma la rotonda sentido a las agujas del reloj hasta la %(ordinal_exit_number)s salida dirección %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Toma la rotonda sentido a las agujas del reloj hasta la %(ordinal_exit_number)s salida hacia %(street_name)s", + "Start on": "Comienza en", + " heading ": " dirección ", + "to continue on": "hacia", + "on to": "dirección", + "first": "primera", + "second": "segunda", + "third": "tercera", + "fourth": "cuarta", + "fifth": "quinta", + "sixth": "sexta", + "seventh": "séptima", + "eight": "octava", + "ninth": "novena", + "tenth": "décima", + "%d hr": "%d hr", + "%d hr_plural": "%d hrs", + "%d min": "%d min", + "%d min_plural": "%d mins", + "%d sec": "%d seg", + "%d sec_plural": "%d segs", + "OK": "Vale", + "Minimize": "Minimizar", + "Bring to front": "Traer al frente", + "Send to back": "Mandar al fondo", + "Route:": "Línea:", + "Variant:": "Variante:", + "Stop Finder": "Buscador de paradas", + "Feed": "Compañía", + "By ID": "Número:", + "By Name": "Nombre:", + "Search": "Buscar", + "No Stops Found": "Paradas no encontradas", + "Date": "Fecha", + "Find Stops": "Buscar paradas", + "(No Stop Selected)": "(Sin parada seleccionada)", + "Block": "Transbordo sin cambio de vehículo", + "Recenter": "Centrar", + "Viewer": "Visor", + "Quick": "Rápido", + "Flat": "Sin cuestas", + "Bike Friendly": "Adaptado a bicicleta", + "B": "B", + "F": "P", + "Q": "R", + "All Routes": "Todas las líneas", + "Save": "Guardar", + "Close": "Cerrar", + "Travel Options": "Opciones de viaje", + "Geocoder": "Geocoder", + "Arrive": "Llegar a las", + "Now": "Ahora", + "Wheelchair accessible trip:": "Ruta accesible a silla de ruedas:", + "Show Filtered Itineraries:": "", + "Travel by": "Viajar en", + "Preferred Routes": "Líneas favoritas", + "Edit": "Editar", + "None": "Niguna", + "Weight": "Prioridad", + "Banned routes": "Líneas prohibidas", + "Use": "Usar", + "My Own Bike": "Mi propia bicileta", + "A Shared Bike": "Una bicicleta compartida", + "Plan Your Trip": "Calcular Viaje", + "Additional parameters": "", + " to _direction": " dirección ", + " to _bus_direction": " dirección ", + "Start_template": "Inicio", + "Depart_itinerary": "Comienza", + "depart_itinerary": "Comienza", + "Start_popup": "Inicio", + "Depart_tripoptions": "Salir a las" +} diff --git a/application/src/client/classic-debug/js/otp/locale/fr.json b/application/src/client/classic-debug/js/otp/locale/fr.json new file mode 100644 index 00000000000..ced9f30440d --- /dev/null +++ b/application/src/client/classic-debug/js/otp/locale/fr.json @@ -0,0 +1,238 @@ +{ + "Transit": "Transports en commun", + "Bus Only": "Bus uniquement", + "Rail Only": "Ferré uniquement", + "Airplane Only": "", + "Transit, No Airplane": "", + "Bicycle Only": "Vélo uniquement", + "Bicycle & Transit": "Transports en commun + Vélo", + "Walk Only": "Marche seulement", + "Car Only": "Partir de", + "Taxi": "", + "Park and Ride": "Parc Relais", + "Ride and Kiss (Car Pickup)": "", + "Kiss and Ride (Car Dropoff)": "", + "Bike and Ride": "Parc Relais Vélo", + "Rented Bicycle": "Vélo Libre Service", + "Transit & Rented Bicycle": "Transports en commun et Vélo Libre Service", + "Rented Scooter": "", + "Transit & Rented Scooter": "Transports en commun et Vélo Libre Service", + "Transit with flex access": "", + "Transit with flex egress": "", + "Transit with flex access and egress": "", + "Direct flex search": "", + "Recenter Map Here": "Centrer la carte ici", + "Zoom In": "Zoomer", + "Zoom Out": "Dézoomer", + "Minimize all": "Tout minimiser", + "Unminimize all": "Tout restaurer", + "Stop Viewer": "Visualisateur d'arrêt", + "Plan Trip": "Organiser un voyage", + "From Stop": "De l'arrêt", + "To Stop": "À l'arrêt", + "Routes Serving Stop": "Lignes desservant l'arrêt", + "Bike Share Planner": "Organisation en Vélo Libre Service", + "Trip Options": "Paramètres de l'itinéraire", + "PICK UP BIKE": "Récupérer un vélo", + "ALTERNATE PICKUP": "Alternative de récupération de vélo", + "DROP OFF BIKE": "Déposer le vélo", + "ALTERNATE DROP OFF": "Alternative de dépôt de vélo", + "BIKE STATION": "Station de vélos", + "Station:": "Station :", + "%d bike available": "%d vélo disponible", + "%d bike available_plural": "%d vélos disponibles", + "%d dock available": "%d emplacements disponibles", + "%d dock available_plural": "%d emplacements disponibles", + "Recommended Pick Up:": "Station de récupération de vélo recommandée :", + "Bicycle rental": "Station de vélo libre service", + "Recommended Drop Off:": "Station de dépôt de vélo recommandée", + "Multimodal Trip Planner": "Planificateur d'itinéraires multimodal", + "Itineraries": "Itinéraires", + "This itinerary departs on a different day from the previous one": "", + "%d Itinerary Returned": "%d itinéraire trouvé", + "%d Itinerary Returned_plural": "%d itinéraires trouvés", + "Link to search": "Lien vers cette recherche", + "Previous Page": "Précédent", + "Next Page": "", + "CONTINUES AS": "Continue comme", + "%d min late": "en retard de %d min", + "%d min late_plural": "en retard de %d mins", + "%d min early": "en avance de %d min", + "%d min early_plural": "en avance de %d mins", + "on time": "à l'heure", + "This itinerary departs on a different day than the one searched for": "", + "Arrived at destination with a rented bicycle!": "", + "End": "Arrivée", + "Trip Summary": "Résumé du voyage", + "Travel": "Voyage", + "Time": "Durée", + "GenCost": "", + "Total Walk": "Total de marche", + "Total Bike": "Total de vélo", + "Total drive": "", + "Elevation Gained": "", + "Elevation Lost": "", + "Transfers": "correspondances", + "Fare": "Tarif", + "Valid": "Valide le", + "Link to Itinerary": "Lien vers l'itinéraire", + "Print": "Imprimer", + "Your Trip": "Votre voyage", + "Email": "Courriel", + "every %d min": "toutes les %d min", + "every %d min_plural": "toutes les %d mins", + "Board at ": "Montez à ", + "Stop": "Arrêt", + "Time in transit": "Temps de correspondance", + "Route ID": "", + "Trip ID": "", + "Service Date": "", + "Trip Viewer": "Visualisateur de voyage", + "late as": "en retard à", + "Stay on board": "rester à bord", + "Alight": "Descendre", + "at": "à", + "%(currency)s %(price)s": "%(price)s %(currency)s", + "Start: %(location)s at %(time_date)s": "Départ : %(location)s à %(time_date)s", + "Board": "Monter", + "(%(agency_id)s Stop ID #%(stop_id)s),": "arrêt #%(stop_id)s) de (%(agency_id)s,", + "End: %(location)s at %(time_date)s": "Arrivée : %(location)s à %(time_date)s", + "(%(agencyId)s Stop ID #%(id)s),": "", + "\nView itinerary online:\n%(itinerary_link)s\n": "\nVoir l'itinéraire en ligne :\n%(itinerary_link)s\n", + "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Nous sommes désolé. Le planificateur de voyage est temporairement indisponible. Merci de réessayer plus tard.", + "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", + "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", + "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Aucune durée de voyage disponible. La date est peut être passée ou trop loin dans le futur, ou il n'y a peut être pas de transports en service pour votre trajet à l'heure choisie.", + "The trip planner is taking way too long to process your request. Please try again later.": "Le planificateur de voyage prend largement trop de temps à étudier votre demande. Merci de réessayer plus tard.", + "The request has errors that the server is not willing or able to process.": "La requête renvoie des erreurs que le serveur ne souhaite ou ne peut pas traiter.", + "Origin is unknown. Can you be a bit more descriptive?": "L'origine est inconnue. Pouvez-vous être plus précis ?", + "Destination is unknown. Can you be a bit more descriptive?": "La destination est inconnue. Pouvez-vous être plus précis ?", + "Both origin and destination are unknown. Can you be a bit more descriptive?": "L'origine et la destination sont toutes deux inconnues. Pouvez-vous être plus précis ?", + "Both origin and destination are not wheelchair accessible": "Ni l'origine ni la destination ne sont accessibles en fauteuil roulant", + "Origin is within a trivial distance of the destination.": "L'origine est à une distance trop courte de la destination.", + "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "Le planificateur de voyage n'est pas sûr du lieu d'où vous voulez partir. Merci de le sélectionner parmi les options suivantes, ou d'être plus précis.", + "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "Le planificateur de voyage n'est pas sûr du lieu où vous désirez vous rendre. Merci de le sélectionner parmi les options suivantes, ou d'être plus précis.", + "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "L'origine et la destination sont toutes deux ambigües. Merci de les sélectionner parmi les options suivantes, ou d'être plus précis.", + "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "Toutes les options triangleSafetyFactor, triangleSlopeFactor, et triangleTimeFactor doivent être paramétrées si l'une d'elles l'est", + "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "Les valeurs de triangleSafetyFactor, triangleSlopeFactor, et triangleTimeFactor doivent avoir pour addition 1", + "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "Si triangleSafetyFactor, triangleSlopeFactor, et triangleTimeFactor sont fournis, OptimizeType doit être TRIANGLE", + "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "Si OptimizeType est TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, et triangleTimeFactor doivent être paramétrées", + "Set as Start Location": "Définir comme point de départ", + "Set as End Location": "Définir comme point d'arrivée", + "Destination": "Destination", + "Error %(error_id)d": "Erreur %(error_id)d", + "No Trip Found": "Aucun voyage trouvé", + "Your %(bike_share_name)s route": "Votre itinéraire en %(bike_share_name)s", + "Your bike route": "Votre itinéraire en vélo", + "Walk to the %(bike_share_name)s dock.": "Marcher jusqu'à l'emplacement %(bike_share_name)s.", + "Walk from the %(bike_share_name)s dock to your destination.": "Marcher de l'emplacement %(bike_share_name)s jusqu'à votre destination", + "Your walk route": "Votre itinéraire à pieds", + "Your route using the scooter": "", + "Your driving route": "Votre itinéraire en vélo", + "north": "nord", + "northeast": "nord-est", + "east": "est", + "southeast": "sud-est", + "south": "sud", + "southwest": "sud-ouest", + "west": "ouest", + "northwest": "nord-ouest", + "hard left": "complètement à gauche", + "left": "à gauche", + "slight left": "légèrement à gauche", + "continue": "continuer", + "slight right": "légèrement à droite", + "right": "à droite", + "hard right": "complètement à droite", + "elevator": "ascenseur", + "U-turn left": "virage en U à gauche", + "U-turn right": "virage en U à droite", + "Walk": "Marche à pied", + "Cycle": "Vélo", + "Car": "Voiture", + "Bus": "Bus", + "Subway": "Métro", + "Train": "Train", + "Ferry": "Ferry", + "Light Rail": "Tram ou Trolley", + "Cable Car": "Tramway funiculaire", + "Funicular": "Funiculaire", + "Aerial Tram": "Téléphérique", + "Airplane": "", + "Bicycle rental station": "Station de vélo libre service", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendre le rond-point dans le sens contraire des aiguilles d'une montre jusqu'à la %(ordinal_exit_number)s sortie sur %(street_name)s", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendre le rond-point dans le sens contraire des aiguilles d'une montre jusqu'à la %(ordinal_exit_number)s sortie sur %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendre le rond-point dans le sens des aiguilles d'une montre jusqu'à la %(ordinal_exit_number)s sortie sur %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendre le rond-point dans le sens des aiguilles d'une montre jusqu'à la %(ordinal_exit_number)s sortie sur %(street_name)s", + "Start on": "Partir de", + " heading ": " vers le ", + "to continue on": "pour continuer sur", + "on to": "sur", + "first": "première", + "second": "seconde", + "third": "troisième", + "fourth": "quatrième", + "fifth": "cinquième", + "sixth": "sixième", + "seventh": "septième", + "eight": "huitième", + "ninth": "neuvième", + "tenth": "dixième", + "%d hr": "%d h", + "%d hr_plural": "%d h", + "%d min": "%d min", + "%d min_plural": "%d mins", + "%d sec": "%d s", + "%d sec_plural": "%d s", + "OK": "OK", + "Minimize": "Minimiser", + "Bring to front": "Placer au dessus", + "Send to back": "Placer en dessous", + "Route:": "Ligne :", + "Variant:": "Variante :", + "Stop Finder": "Recherche d'arrêt", + "Feed": "Transporteur", + "By ID": "Par identifiant", + "By Name": "Par nom", + "Search": "Recherche", + "No Stops Found": "Aucun arrêt trouvé", + "Date": "Date", + "Find Stops": "Trouver les arrêts", + "(No Stop Selected)": "(Aucun arrêt sélectionné)", + "Block": "Bloc", + "Recenter": "Recentrer", + "Viewer": "Visualisateur", + "Quick": "Le plus Rapide", + "Flat": "Le plus Plat", + "Bike Friendly": "Adapté au vélo", + "B": "A", + "F": "P", + "Q": "R", + "All Routes": "Tous les itinéraires", + "Save": "Sauvegarder", + "Close": "Fermer", + "Travel Options": "Paramètres de voyage", + "Geocoder": "Géocodeur", + "Arrive": "Arrivée", + "Now": "Maintenant", + "Wheelchair accessible trip:": "Accessible aux fauteuils roulants:", + "Show Filtered Itineraries:": "", + "Travel by": "Voyager par", + "Preferred Routes": "Itinéraires préférés", + "Edit": "Modifier", + "None": "Aucune", + "Weight": "Pondération", + "Banned routes": "Itinéraires à éviter", + "Use": "Utiliser", + "My Own Bike": "mon propre vélo", + "A Shared Bike": "un Vélo Libre Service", + "Plan Your Trip": "Calculer votre itinéraire", + "Additional parameters": "", + " to _direction": " jusqu'à ", + " to _bus_direction": " vers ", + "Start_template": "Départ", + "Depart_itinerary": "Départ", + "depart_itinerary": "Départ", + "Start_popup": "Départ", + "Depart_tripoptions": "Départ" +} diff --git a/application/src/client/classic-debug/js/otp/locale/hu.json b/application/src/client/classic-debug/js/otp/locale/hu.json new file mode 100644 index 00000000000..518dc407bc2 --- /dev/null +++ b/application/src/client/classic-debug/js/otp/locale/hu.json @@ -0,0 +1,238 @@ +{ + "Transit": "Tömegközlekedés", + "Bus Only": "Csak busz", + "Rail Only": "Csak vasút", + "Airplane Only": "Csak repülőgép", + "Transit, No Airplane": "Tömegközlekedés, repülés nélkül", + "Bicycle Only": "Csak kerékpár", + "Bicycle & Transit": "Kerékpár & tömegközlekedés", + "Walk Only": "Csak séta", + "Car Only": "Csak autó", + "Taxi": "Taxi", + "Park and Ride": "P+R (Park & Ride)", + "Ride and Kiss (Car Pickup)": "", + "Kiss and Ride (Car Dropoff)": "", + "Bike and Ride": "B+R (Bike & Ride)", + "Rented Bicycle": "Bérelt kerékpár", + "Transit & Rented Bicycle": "Tömegközlekedés és bérelt kerékpár", + "Rented Scooter": "", + "Transit & Rented Scooter": "Tömegközlekedés és bérelt kerékpár", + "Transit with flex access": "Tömegközlekedés rugalmas indulással", + "Transit with flex egress": "Tömegközlekedés rugalmas érkezéssel", + "Transit with flex access and egress": "Tömegközlekedés rugalmas indulással és érkezéssel", + "Direct flex search": "Közvetlen rugalmas keresés", + "Recenter Map Here": "Legyen itt a térkép középpontja", + "Zoom In": "Közelítés", + "Zoom Out": "Távolítás", + "Minimize all": "Minden kis méretűvé tétele", + "Unminimize all": "Minden kis méretűvé tételének megszüntetése", + "Stop Viewer": "Megállómegjelenítő", + "Plan Trip": "Utazás tervezése", + "From Stop": "Ettől a megállótól", + "To Stop": "Eddig a megállóig", + "Routes Serving Stop": "A megállót érintő járatok", + "Bike Share Planner": "Kerékpármegosztó-tervező", + "Trip Options": "Utazási beállítások", + "PICK UP BIKE": "KERÉKPÁR FELVÉTELE", + "ALTERNATE PICKUP": "MÁSIK FELVÉTELI HELY", + "DROP OFF BIKE": "KERÉKPÁR LEADÁSA", + "ALTERNATE DROP OFF": "MÁSIK LEADÁSI HELY", + "BIKE STATION": "KERÉKPÁRÁLLOMÁS", + "Station:": "Gyűjtőállomás:", + "%d bike available": "%d kerékpár elérhető", + "%d bike available_plural": "%d kerékpár elérhető", + "%d dock available": "%d dokkolóállás", + "%d dock available_plural": "%d dokkolállás", + "Recommended Pick Up:": "Ajánlott felvétel:", + "Bicycle rental": "Kerékpárbérlési hely", + "Recommended Drop Off:": "Ajánlott leadás:", + "Multimodal Trip Planner": "Multimodális utazástervező", + "Itineraries": "Útvonaltervek", + "This itinerary departs on a different day from the previous one": "Ez a útvonalterv az előző naptól eltérő napon kezdődik", + "%d Itinerary Returned": "%d útvonalatervet találtunk", + "%d Itinerary Returned_plural": "%d útvonaltervet találtunk", + "Link to search": "Link a kereséshez", + "Previous Page": "Előző", + "Next Page": "Következő", + "CONTINUES AS": "FOLYTATÁS MINT", + "%d min late": "%d perc késés", + "%d min late_plural": "%d perc késés", + "%d min early": "%d perccel korábban", + "%d min early_plural": "%d perccel korábban", + "on time": "pontos", + "This itinerary departs on a different day than the one searched for": "Ez az útvonalterv a tervezési naptól eltérő napon kezdődik", + "Arrived at destination with a rented bicycle!": "Bérelt kerékpárral való érkezés a célba!", + "End": "Érkezés", + "Trip Summary": "Utazás összefoglalója", + "Travel": "Utazás", + "Time": "Idő", + "GenCost": "Súly/Költség", + "Total Walk": "Séta összesen", + "Total Bike": "Kerékpárral összesen", + "Total drive": "Autóval összesen", + "Elevation Gained": "", + "Elevation Lost": "", + "Transfers": "Átszállások", + "Fare": "Viteldíj", + "Valid": "Érvényesség", + "Link to Itinerary": "Link az útvonaltervhez", + "Print": "Nyomtatás", + "Your Trip": "Az Ön utazása", + "Email": "E-mail", + "every %d min": "%d percenként", + "every %d min_plural": "%d percenként", + "Board at ": "Felszállás: ", + "Stop": "Megálló", + "Time in transit": "Közlekedési idő", + "Route ID": "", + "Trip ID": "", + "Service Date": "", + "Trip Viewer": "Utazásmegjelenítő", + "late as": "", + "Stay on board": "Maradjon a járművön", + "Alight": "Leszállás", + "at": "itt:", + "%(currency)s %(price)s": "%(currency)s %(price)s", + "Start: %(location)s at %(time_date)s": "Indulás: %(location)s (%(time_date)s)", + "Board": "Felszállás", + "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s megállóazonosító: #%(stop_id)s),", + "End: %(location)s at %(time_date)s": "Érkezés: %(location)s (%(time_date)s)", + "(%(agencyId)s Stop ID #%(id)s),": "(%(agencyId)s megállóazonosító: #%(id)s),", + "\nView itinerary online:\n%(itinerary_link)s\n": "\nOnline útvonalterv megtekintése:\n%(itinerary_link)s\n", + "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Sajnáljuk, az útvonaltervező átmenetileg nem elérhető. Kérjük, próbálja újra később.", + "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "Az utazás nem lehetséges. Lehet, hogy a térképadatok határain kívüli utat próbál tervezni.", + "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "Nem található ilyen utazás. Előfordulhat, hogy nincs tömegközlekedési szolgáltatás a megadott legnagyobb távolságon belül vagy a megadott időpontban, vagy a kezdő- vagy végpont nem érhető el biztonságosan.", + "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Nem áll rendelkezésre közlekedési idő. Előfordulhat, hogy a dátum elmúlt vagy túl messze van a jövőben, vagy az Ön által választott időpontban nincs tömegközlekedési szolgáltatás.", + "The trip planner is taking way too long to process your request. Please try again later.": "Az utazástervezőnek túl sokáig tart a kérés feldolgozása. Kérjük, próbálja újra később.", + "The request has errors that the server is not willing or able to process.": "A kérés olyan hibát tartalmaz, amelyet a szerver nem hajlandó vagy nem képes feldolgozni.", + "Origin is unknown. Can you be a bit more descriptive?": "A kiindulás pont ismeretlen. Le tudná írni egy kicsit gondosabban?", + "Destination is unknown. Can you be a bit more descriptive?": "Az úti cél ismeretlen. Le tudná írni egy kicsit gondosabban?", + "Both origin and destination are unknown. Can you be a bit more descriptive?": "A kiindulási és a célpont egyaránt ismeretlen. Le tudná-e írni egy kicsit gondosabban?", + "Both origin and destination are not wheelchair accessible": "Sem a kiindulási, sem a célpont nem akadálymentes", + "Origin is within a trivial distance of the destination.": "A kiindulási hely túl közel van a célponthoz.", + "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "Az útvonaltervező bizonytalan abban, hogy honnan szeretne indulni. Kérjük, válasszon az alábbi lehetőségek közül, vagy legyen pontosabb.", + "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "Az útvonaltervező bizonytalan abban, hogy hová szeretne érkezni. Kérjük, válasszon az alábbi lehetőségek közül, vagy legyen pontosabb.", + "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "Sem a kiindulási, sem a célpont nem egyértelmű. Kérjük, válasszon az alábbi lehetőségek közül, vagy legyen pontosabb.", + "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "A triangleSafetyFactor, a triangleSlopeFactor és a triangleTimeFactor értékeit egyaránt be kell állítani, ha vannak ilyenek", + "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "A triangleSafetyFactor, triangleSlopeFactor és triangleTimeFactor értékei összegének 1-nek kell lennie", + "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "Ha a triangleSafetyFactor, a triangleSlopeFactor és a triangleTimeFactor meg van adva, akkor az OptimizeType értékének TRIANGLE-nek kell lennie", + "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "Ha az OptimizeType értéke TRIANGLE, akkor be kell állítani a triangleSafetyFactor, a triangleSlopeFactor és a triangleTimeFactor értékeit", + "Set as Start Location": "Beállítás kiindulási helyként", + "Set as End Location": "Beállítás érkezési helyként", + "Destination": "Célpont", + "Error %(error_id)d": "Hiba: %(error_id)d", + "No Trip Found": "Nem található utazás", + "Your %(bike_share_name)s route": "Az Ön %(bike_share_name)s-útvonala", + "Your bike route": "Az Ön kerékpáros útvonala", + "Walk to the %(bike_share_name)s dock.": "Séta a dokkolóálláshoz (%(bike_share_name)s)", + "Walk from the %(bike_share_name)s dock to your destination.": "Séta a dokkolóállástól (%(bike_share_name)s) a célponthoz.", + "Your walk route": "Az Ön gyalogos útvonala", + "Your route using the scooter": "", + "Your driving route": "Az Ön kerékpáros útvonala", + "north": "észak", + "northeast": "északkelet", + "east": "kelet", + "southeast": "délkelet", + "south": "dél", + "southwest": "délnyugat", + "west": "nyugat", + "northwest": "északnyugat", + "hard left": "élesen balra", + "left": "balra", + "slight left": "enyhén balra", + "continue": "tovább", + "slight right": "enyhén jobbra", + "right": "jobbra", + "hard right": "élesen jobbra", + "elevator": "lift", + "U-turn left": "megfordulás balra", + "U-turn right": "megfordulás jobbra", + "Walk": "Séta", + "Cycle": "Kerékpározás", + "Car": "Autós útvonal", + "Bus": "Busz", + "Subway": "Metró", + "Train": "Vonat", + "Ferry": "Komp", + "Light Rail": "Villamos, könnyűvasút", + "Cable Car": "", + "Funicular": "Sikló", + "Aerial Tram": "Libegő", + "Airplane": "Repülőgép", + "Bicycle rental station": "Kerékpárkölcsönző állomás", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Hajtson be a körforgalomba az óramutató járásával ellentétesen, majd hajtson ki a(z) %(ordinal_exit_number)s kijáraton erre: %(street_name)s", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Hajtson be a körforgalomba az óramutató járásával ellentétesen, majd hajtson ki a(z) %(ordinal_exit_number)s kijáraton erre: %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Hajtson be a körforgalomba az óramutató járása szerinti irányba, majd hajtson ki a(z) %(ordinal_exit_number)s kijáraton erre: %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Hajtson be a körforgalomba az óramutató járása szerinti irányba, majd hajtson ki a(z) %(ordinal_exit_number)s kijáraton erre: %(street_name)s", + "Start on": "Induljon ezen:", + " heading ": " erre: ", + "to continue on": "menjen tovább ezen:", + "on to": "ezen:", + "first": "első", + "second": "második", + "third": "harmadik", + "fourth": "negyedik", + "fifth": "ötödik", + "sixth": "hatodik", + "seventh": "hetedik", + "eight": "nyolcadik", + "ninth": "kilencedik", + "tenth": "tizedik", + "%d hr": "%d óra", + "%d hr_plural": "%d óra", + "%d min": "%d perc", + "%d min_plural": "%d perc", + "%d sec": "%d másodperc", + "%d sec_plural": "%d másodperc", + "OK": "OK", + "Minimize": "Kis méretűvé tétel", + "Bring to front": "Előrehozás", + "Send to back": "Hátraküldés", + "Route:": "Útvonal:", + "Variant:": "Változat:", + "Stop Finder": "Megállókereső", + "Feed": "Feed", + "By ID": "Azonosító alapján", + "By Name": "Név alapján", + "Search": "Keresés", + "No Stops Found": "Nem található megálló", + "Date": "Dátum", + "Find Stops": "Megállóhelyek keresése", + "(No Stop Selected)": "(Nincs megálló kijelölve)", + "Block": "Blokk", + "Recenter": "Legyen ez a térkép középpontja", + "Viewer": "Megállómegtekintő", + "Quick": "Gyors", + "Flat": "Lapos", + "Bike Friendly": "Kerékpárosbarát", + "B": "K", + "F": "L", + "Q": "G", + "All Routes": "Minden útvonal", + "Save": "Mentés", + "Close": "Bezárás", + "Travel Options": "Utazás beállításai", + "Geocoder": "Geokóder", + "Arrive": "Érkezés", + "Now": "Most", + "Wheelchair accessible trip:": "Akadálymentes utazás:", + "Show Filtered Itineraries:": "Szűrt útvonaltervek megjelenítése:", + "Travel by": "Közlekedési eszköz:", + "Preferred Routes": "Előnyben részesített útvonalak", + "Edit": "Szerkesztés", + "None": "Nincs", + "Weight": "Súly", + "Banned routes": "Kerülendő útvonalak", + "Use": "Használt kerékpár:", + "My Own Bike": "saját", + "A Shared Bike": "bérelt", + "Plan Your Trip": "Tervezze meg utazását", + "Additional parameters": "További beállítások", + " to _direction": " eddig: ", + " to _bus_direction": " ide: ", + "Start_template": "Indulás", + "Depart_itinerary": "Indulás", + "depart_itinerary": "indulás", + "Start_popup": "Indulás", + "Depart_tripoptions": "Indulás" +} diff --git a/application/src/client/classic-debug/js/otp/locale/it.json b/application/src/client/classic-debug/js/otp/locale/it.json new file mode 100644 index 00000000000..81489b8d82c --- /dev/null +++ b/application/src/client/classic-debug/js/otp/locale/it.json @@ -0,0 +1,238 @@ +{ + "Transit": "Mezzi pubblici", + "Bus Only": "Solo Bus", + "Rail Only": "Solo Treno", + "Airplane Only": "", + "Transit, No Airplane": "", + "Bicycle Only": "In bici", + "Bicycle & Transit": "Bici & mezzi pubblici", + "Walk Only": "A piedi", + "Car Only": "Partenza su", + "Taxi": "", + "Park and Ride": "Park & Ride", + "Ride and Kiss (Car Pickup)": "", + "Kiss and Ride (Car Dropoff)": "", + "Bike and Ride": "Bike & Ride", + "Rented Bicycle": "Bike sharing", + "Transit & Rented Bicycle": "Bike sharing & Ride", + "Rented Scooter": "", + "Transit & Rented Scooter": "Bike sharing & Ride", + "Transit with flex access": "", + "Transit with flex egress": "", + "Transit with flex access and egress": "", + "Direct flex search": "", + "Recenter Map Here": "Centra", + "Zoom In": "Zoom in", + "Zoom Out": "Zoom out", + "Minimize all": "Minimizza tutto", + "Unminimize all": "Ripristina tutto", + "Stop Viewer": "Orari", + "Plan Trip": "Calcola percorso", + "From Stop": "Da questa fermata", + "To Stop": "A questa fermata", + "Routes Serving Stop": "Linee", + "Bike Share Planner": "Bike Sharing", + "Trip Options": "Opzioni di viaggio", + "PICK UP BIKE": "Prendi la bici qui", + "ALTERNATE PICKUP": "Puoi prendere la bici anche qui", + "DROP OFF BIKE": "Lascia la bici qui", + "ALTERNATE DROP OFF": "Puoi lasciare la bici anche qui", + "BIKE STATION": "Stazione di Bike Sharing", + "Station:": "Stazione:", + "%d bike available": "%d bici disponibile", + "%d bike available_plural": "%d bici disponibili", + "%d dock available": "%d posto disponibile", + "%d dock available_plural": "%d posti disponibili", + "Recommended Pick Up:": "Prendi la bici:", + "Bicycle rental": "", + "Recommended Drop Off:": "Lascia la bici:", + "Multimodal Trip Planner": "Calcolo percorso multimodale", + "Itineraries": "Percorsi", + "This itinerary departs on a different day from the previous one": "", + "%d Itinerary Returned": "%d percorso trovato", + "%d Itinerary Returned_plural": "%d percorsi trovati", + "Link to search": "Link a questa ricerca", + "Previous Page": "Precedente", + "Next Page": "", + "CONTINUES AS": "Rimani a bordo", + "%d min late": "%d minuto di ritardo", + "%d min late_plural": "%d minuti di ritardo", + "%d min early": "%d minuto in anticipo", + "%d min early_plural": "%d minuti in anticipo", + "on time": "in orario", + "This itinerary departs on a different day than the one searched for": "", + "Arrived at destination with a rented bicycle!": "", + "End": "Arrivo", + "Trip Summary": "Riepilogo", + "Travel": "Partenza", + "Time": "Durata", + "GenCost": "", + "Total Walk": "A piedi", + "Total Bike": "In bici", + "Total drive": "", + "Elevation Gained": "", + "Elevation Lost": "", + "Transfers": "Cambi", + "Fare": "Costo", + "Valid": "Calcolato il ", + "Link to Itinerary": "Link a questo percorso", + "Print": "Stampa", + "Your Trip": "Il tuo percorso", + "Email": "Invia mail", + "every %d min": "ogni minuto", + "every %d min_plural": "ogni %d minuti", + "Board at ": "Parti da ", + "Stop": "Fermata", + "Time in transit": "Tempo a bordo", + "Route ID": "", + "Trip ID": "", + "Service Date": "", + "Trip Viewer": "Percorso", + "late as": "al più", + "Stay on board": "Rimani a bordo", + "Alight": "Scendi", + "at": "a", + "%(currency)s %(price)s": "%(currency)s %(price)s", + "Start: %(location)s at %(time_date)s": "Partenza: %(location)s alle %(time_date)s", + "Board": "Sali a bordo", + "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s fermata n.%(stop_id)s),", + "End: %(location)s at %(time_date)s": "Arrivo: %(location)s alle %(time_date)s", + "(%(agencyId)s Stop ID #%(id)s),": "", + "\nView itinerary online:\n%(itinerary_link)s\n": "\nConsulta il percorso online:\n%(itinerary_link)s\n", + "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Siamo spiacenti. Il servizio è momentaneamente indisponibile.Riprova più tardi.", + "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", + "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", + "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Nessun servizio di Trasporto Pubblico trovato. La data indicata potrebbe essere al di fuori del periodo preso in considerazione dal Calcolo Percorso.", + "The trip planner is taking way too long to process your request. Please try again later.": "Il servizio di Calcolo percorsi sta impiegando troppo tempo per processare la tua richiesta. Riprova più tardi.", + "The request has errors that the server is not willing or able to process.": "La richiesta contiene errori che il server non è in grado di trattare.", + "Origin is unknown. Can you be a bit more descriptive?": "Origine non riconosciuta. Puoi essere più esplicito?", + "Destination is unknown. Can you be a bit more descriptive?": "Destinazione non riconosciuta. Puoi essere più esplicito?", + "Both origin and destination are unknown. Can you be a bit more descriptive?": "Origine e destinazione non riconosciute. Puoi essere più esplicito?", + "Both origin and destination are not wheelchair accessible": "Origine e destinazione non accessibili in carrozzina", + "Origin is within a trivial distance of the destination.": "Origine troppo vicina alla destinazione.", + "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "Origine non riconosciuta. Seleziona fra le seguenti opzioni o specifica meglio l'origine.", + "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "Destinazione non riconosciuta. Seleziona fra le seguenti opzioni o specifica meglio la destinazione.", + "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "Origine e destinazione non riconosciute. Seleziona fra le seguenti opzioni o specifica meglio l'origine e la destinazione.", + "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "Specificare tutti e 3 i fattori: triangleSafetyFactor, triangleSlopeFactor e triangleTimeFactor", + "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "La somma dai fattori triangleSafetyFactor, triangleSlopeFactor e triangleTimeFactor dev'essere pari a 1", + "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "Se si forniscono i fattori triangleSafetyFactor, triangleSlopeFactor e triangleTimeFactor il parametro OptimizeType dev'essere settato a TRIANGLE", + "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "Se il parametro OptimizeType è settato a TRIANGLE, si devono fornire i fattori triangleSafetyFactor, triangleSlopeFactor e triangleTimeFactor ", + "Set as Start Location": "Imposta Partenza", + "Set as End Location": "Imposta Arrivo", + "Destination": "Destinazione", + "Error %(error_id)d": "Errore %(error_id)d", + "No Trip Found": "nessun percoro trovato", + "Your %(bike_share_name)s route": "Percorso con %(bike_share_name)s ", + "Your bike route": "Percorso in bici", + "Walk to the %(bike_share_name)s dock.": "A piedi verso la stazione %(bike_share_name)s", + "Walk from the %(bike_share_name)s dock to your destination.": "A piedi dalla stazione %(bike_share_name)s a destinazione", + "Your walk route": "Percorso a piedi", + "Your route using the scooter": "", + "Your driving route": "Percorso in bici", + "north": "nord", + "northeast": "nord-est", + "east": "est", + "southeast": "sud-est", + "south": "sud", + "southwest": "sud-ovest", + "west": "ovest", + "northwest": "nod-ovest", + "hard left": "a sinistra", + "left": "a sinistra", + "slight left": "tenere la sinistra", + "continue": "continuare", + "slight right": "tenere la destra", + "right": "a destra", + "hard right": "a destra", + "elevator": "ascensore", + "U-turn left": "inversione di marcia", + "U-turn right": "inversione di marcia", + "Walk": "A piedi", + "Cycle": "bici", + "Car": "auto", + "Bus": "bus", + "Subway": "metro", + "Train": "treno", + "Ferry": "Ferry", + "Light Rail": "tram", + "Cable Car": "tram", + "Funicular": "funivia", + "Aerial Tram": "tram", + "Airplane": "", + "Bicycle rental station": "", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendere la rotonda in senso antiorario, %(ordinal_exit_number)s uscita, %(street_name)s", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendere la rotonda in senso antiorario, %(ordinal_exit_number)s uscita, %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendere la rotonda in senso orario, %(ordinal_exit_number)s uscita, %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendere la rotonda in senso orario, %(ordinal_exit_number)s uscita, %(street_name)s", + "Start on": "Partenza su", + " heading ": " in direzione ", + "to continue on": "continua su", + "on to": "su", + "first": "prima", + "second": "seconda", + "third": "terza", + "fourth": "quarta", + "fifth": "quinta", + "sixth": "sesta", + "seventh": "settima", + "eight": "ottava", + "ninth": "nona", + "tenth": "decima", + "%d hr": "%d h", + "%d hr_plural": "%d h", + "%d min": "%d m", + "%d min_plural": "%d m", + "%d sec": "%d s", + "%d sec_plural": "%d s", + "OK": "OK", + "Minimize": "Riduci a icona", + "Bring to front": "Porta in primo piano", + "Send to back": "Porta in secondo piano", + "Route:": "Linea:", + "Variant:": "Percorso:", + "Stop Finder": "Ricerca Fermata", + "Feed": "Azienda TPL", + "By ID": "Numero", + "By Name": "Nome", + "Search": "Cerca", + "No Stops Found": "Nessuna fermata trovata", + "Date": "Data", + "Find Stops": "Cerca fermata", + "(No Stop Selected)": "(nessuna fermata selezionata)", + "Block": "Turno", + "Recenter": "Centra", + "Viewer": "Passaggi", + "Quick": "Veloce", + "Flat": "Pianeggiante", + "Bike Friendly": "Sicuro", + "B": "S", + "F": "P", + "Q": "V", + "All Routes": "Linee", + "Save": "Salva", + "Close": "Chiudi", + "Travel Options": "Opzioni di viaggio", + "Geocoder": "Geocoder", + "Arrive": "Arrivo", + "Now": "Ora", + "Wheelchair accessible trip:": "Percorso accessibile:", + "Show Filtered Itineraries:": "", + "Travel by": "Modalità", + "Preferred Routes": "Linee preferite", + "Edit": "Modifica", + "None": "Nessuna", + "Weight": "Peso", + "Banned routes": "Linee da evitare", + "Use": "Usa", + "My Own Bike": "bici propria", + "A Shared Bike": "bike sharing", + "Plan Your Trip": "Calcola", + "Additional parameters": "", + " to _direction": " fino a ", + " to _bus_direction": " in direzione ", + "Start_template": "Partenza", + "Depart_itinerary": "Parti da", + "depart_itinerary": "Partenza", + "Start_popup": "Partenza", + "Depart_tripoptions": "Partenza" +} diff --git a/application/src/client/classic-debug/js/otp/locale/no.json b/application/src/client/classic-debug/js/otp/locale/no.json new file mode 100644 index 00000000000..e26b87d5e22 --- /dev/null +++ b/application/src/client/classic-debug/js/otp/locale/no.json @@ -0,0 +1,238 @@ +{ + "Transit": "Kollektivtransport", + "Bus Only": "Buss", + "Rail Only": "Tog", + "Airplane Only": "Fly", + "Transit, No Airplane": "", + "Bicycle Only": "Sykkel", + "Bicycle & Transit": "Sykkel & Kollektivtransport", + "Walk Only": "Gå", + "Car Only": "Start fra", + "Taxi": "", + "Park and Ride": "Park and Ride", + "Ride and Kiss (Car Pickup)": "", + "Kiss and Ride (Car Dropoff)": "", + "Bike and Ride": "Bike and Ride", + "Rented Bicycle": "Bysykkel", + "Transit & Rented Bicycle": "Kollektivtransport & Bysykkel", + "Rented Scooter": "", + "Transit & Rented Scooter": "Kollektivtransport & Bysykkel", + "Transit with flex access": "", + "Transit with flex egress": "", + "Transit with flex access and egress": "", + "Direct flex search": "", + "Recenter Map Here": "Sentrer kart her", + "Zoom In": "Zoom inn", + "Zoom Out": "Zoom ut", + "Minimize all": "Minimer vinduer", + "Unminimize all": "Vis vinduer", + "Stop Viewer": "Vis Stoppested", + "Plan Trip": "Reiseplanlegger", + "From Stop": "Fra stoppested", + "To Stop": "Til stoppested", + "Routes Serving Stop": "Ruter fra stoppested", + "Bike Share Planner": "Bike Share Planner", + "Trip Options": "Reise søk", + "PICK UP BIKE": "PICK UP BIKE", + "ALTERNATE PICKUP": "ALTERNATE PICKUP", + "DROP OFF BIKE": "DROP OFF BIKE", + "ALTERNATE DROP OFF": "ALTERNATE DROP OFF", + "BIKE STATION": "BIKE STATION", + "Station:": "Stasjon:", + "%d bike available": "%d sykkel tilgjengelig", + "%d bike available_plural": "%d sykler tilgjengelig", + "%d dock available": "%d plass ledig", + "%d dock available_plural": "%d plasser ledig", + "Recommended Pick Up:": "Anbefalt Pick Up:", + "Bicycle rental": "Bysykkel", + "Recommended Drop Off:": "Anbefalt Drop Off:", + "Multimodal Trip Planner": "Reiseplanlegger", + "Itineraries": "Vis Reiseplaner", + "This itinerary departs on a different day from the previous one": "", + "%d Itinerary Returned": "%d Reise alternativ", + "%d Itinerary Returned_plural": "%d Reise alternativer", + "Link to search": "Link til søk", + "Previous Page": "Forrige", + "Next Page": "", + "CONTINUES AS": "FORTSETTER SOM", + "%d min late": "%d minutt forsinket", + "%d min late_plural": "%d minutter forsinket", + "%d min early": "%d minutt fortidlig", + "%d min early_plural": "%d minutter fortidlig", + "on time": "i rute", + "This itinerary departs on a different day than the one searched for": "", + "Arrived at destination with a rented bicycle!": "", + "End": "Til", + "Trip Summary": "Reise oversikt", + "Travel": "Start", + "Time": "Reisetid", + "GenCost": "Kost", + "Total Walk": "Gangeavstand", + "Total Bike": "Sykkel distanse", + "Total drive": "Bil distanse", + "Elevation Gained": "", + "Elevation Lost": "", + "Transfers": "Bytter", + "Fare": "Pris", + "Valid": "Gyldig", + "Link to Itinerary": "Link til reise", + "Print": "Skriv ut", + "Your Trip": "Din reise", + "Email": "e-post", + "every %d min": "hvert minutt", + "every %d min_plural": "hvert %d minutt", + "Board at ": "Påstigning ", + "Stop": "Stoppested", + "Time in transit": "Tid kollektivtransport", + "Route ID": "", + "Trip ID": "", + "Service Date": "", + "Trip Viewer": "Vis Rute", + "late as": "sent som", + "Stay on board": "Bli om bord", + "Alight": "Avstigning", + "at": "på", + "%(currency)s %(price)s": "%(currency)s %(price)s", + "Start: %(location)s at %(time_date)s": "Fra: %(location)s klokka %(time_date)s", + "Board": "Påstigning", + "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s Stoppested ID #%(stop_id)s),", + "End: %(location)s at %(time_date)s": "Ankomst: %(location)s klokka %(time_date)s", + "(%(agencyId)s Stop ID #%(id)s),": "", + "\nView itinerary online:\n%(itinerary_link)s\n": "\nVis reiseplan:\n%(itinerary_link)s\n", + "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Beklager. Reiseplanleggeren er midlertidig utilgjengelig. Venligst forsøk igjen senere.", + "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", + "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "Ingen reise funnet. Sjekk at fra/til sted er innenfor angitt gangavstand til destinasjon, stopested, bysykkel-stativ og/eller påstigningspunkt for bil.", + "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Ingen kolektivreiser funnet for denne dagen.", + "The trip planner is taking way too long to process your request. Please try again later.": "Reiseplanleggeren svarer ikke på forspørsel. Prøv igjen senere.", + "The request has errors that the server is not willing or able to process.": "Ugyldig input data. Server er ikke i stand til å behandle 'RouteRequest'.", + "Origin is unknown. Can you be a bit more descriptive?": "Avreisested er ukjent. Kan du spesifisere nærmere?", + "Destination is unknown. Can you be a bit more descriptive?": "Reisemålet er ukjent. Kan du spesifisere nærmere?", + "Both origin and destination are unknown. Can you be a bit more descriptive?": "Både fra/til sted er ukjent. Kan du spesifisere nærmere?", + "Both origin and destination are not wheelchair accessible": "Både fra/til sted er utilgjengelig for rullestolukjent.", + "Origin is within a trivial distance of the destination.": "Du kan klare å gå? Det er bare noen få meter.", + "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.", + "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.", + "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "Both origin and destination are ambiguous. Please select from the following options, or be more specific.", + "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are", + "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1", + "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE", + "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set", + "Set as Start Location": "Reis herfra", + "Set as End Location": "Reis hit", + "Destination": "Destinasjon", + "Error %(error_id)d": "Feil %(error_id)d", + "No Trip Found": "Ingen tur tilgjenglig", + "Your %(bike_share_name)s route": "Din %(bike_share_name)s rute", + "Your bike route": "Din sykkel rute", + "Walk to the %(bike_share_name)s dock.": "Gå til %(bike_share_name)s sykkelstativ.", + "Walk from the %(bike_share_name)s dock to your destination.": "Walk from the %(bike_share_name)s dock to your destination.", + "Your walk route": "Your walk route", + "Your route using the scooter": "", + "Your driving route": "Din sykkel rute", + "north": "nord", + "northeast": "nordøst", + "east": "øst", + "southeast": "sørøst", + "south": "sør", + "southwest": "sørvest", + "west": "vest", + "northwest": "nordvest", + "hard left": "skart venstre", + "left": "venstre", + "slight left": "svakt venstre", + "continue": "fortsett", + "slight right": "svakt høyre", + "right": "høyre", + "hard right": "skart høyre", + "elevator": "heis", + "U-turn left": "U-sving venstre", + "U-turn right": "U-sving høyre", + "Walk": "Gå", + "Cycle": "Sykkel", + "Car": "Bil", + "Bus": "Buss", + "Subway": "T-bane", + "Train": "Tog", + "Ferry": "Ferje", + "Light Rail": "Trikk", + "Cable Car": "Cable Car", + "Funicular": "Kabelbane", + "Aerial Tram": "Tau bane", + "Airplane": "Fly", + "Bicycle rental station": "Bysykkelstativ", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Følg rundkjøringen mot klokka ta %(ordinal_exit_number)s avkjøring til %(street_name)s", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Følg rundkjøring mot klokka, ta %(ordinal_exit_number)s avkjøring til %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Følg rundkjøring med klokka, ta %(ordinal_exit_number)s avkjøring til %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Følg rundkjøring med klokka, ta %(ordinal_exit_number)s avkjøring til %(street_name)s", + "Start on": "Start fra", + " heading ": " mot ", + "to continue on": "fortsett på", + "on to": "på", + "first": "første", + "second": "andre", + "third": "tredje", + "fourth": "fjerde", + "fifth": "femte", + "sixth": "sjette", + "seventh": "syvende", + "eight": "åttende", + "ninth": "niende", + "tenth": "tidende", + "%d hr": "%d time", + "%d hr_plural": "%d timer", + "%d min": "%d minutt", + "%d min_plural": "%d minutter", + "%d sec": "%d sekund", + "%d sec_plural": "%d sekunder", + "OK": "OK", + "Minimize": "Minimer vinduer", + "Bring to front": "Flytt fremst", + "Send to back": "Flytt bakerst", + "Route:": "Rute:", + "Variant:": "Alternativ:", + "Stop Finder": "Søk Stoppested", + "Feed": "Agency", + "By ID": "Med ID", + "By Name": "Med Navn", + "Search": "Søk", + "No Stops Found": "Stoppested ikke funnet", + "Date": "Date", + "Find Stops": "Søk Stoppested", + "(No Stop Selected)": "(Ingen Stoppested valgt)", + "Block": "Block", + "Recenter": "Sentrer", + "Viewer": "Vis", + "Quick": "Rask", + "Flat": "Flat", + "Bike Friendly": "Sykkel vennlig", + "B": "B", + "F": "F", + "Q": "R", + "All Routes": "Alle Ruter", + "Save": "Lagre", + "Close": "Lukk", + "Travel Options": "Reise Resultater", + "Geocoder": "Geocoder", + "Arrive": "Ankomst", + "Now": "Nå", + "Wheelchair accessible trip:": "Tilgjenelig for rullestol:", + "Show Filtered Itineraries:": "", + "Travel by": "Reis med", + "Preferred Routes": "Foretrukket rute", + "Edit": "Endre", + "None": "Ingen", + "Weight": "Weight", + "Banned routes": "Untatt rute", + "Use": "Bruk", + "My Own Bike": "Egen Sykkel", + "A Shared Bike": "Bysykkel", + "Plan Your Trip": "Planlegg Reise", + "Additional parameters": "", + " to _direction": " til ", + " to _bus_direction": " til ", + "Start_template": "Fra", + "Depart_itinerary": "Avgang", + "depart_itinerary": "Avreise", + "Start_popup": "Start", + "Depart_tripoptions": "Avgang" +} diff --git a/application/src/client/classic-debug/js/otp/locale/pl.json b/application/src/client/classic-debug/js/otp/locale/pl.json new file mode 100644 index 00000000000..33cf622f930 --- /dev/null +++ b/application/src/client/classic-debug/js/otp/locale/pl.json @@ -0,0 +1,247 @@ +{ + "Transit": "komunikacją publiczną", + "Bus Only": "wyłącznie autobusami", + "Rail Only": "wyłącznie koleją", + "Airplane Only": "", + "Transit, No Airplane": "", + "Bicycle Only": "wyłącznie rowerem", + "Bicycle & Transit": "rowerem & komunikacją publiczną", + "Walk Only": "wyłącznie pieszo", + "Car Only": "Rozpocznij na ulicy", + "Taxi": "", + "Park and Ride": "schemat P+R (Park and Ride)", + "Ride and Kiss (Car Pickup)": "", + "Kiss and Ride (Car Dropoff)": "", + "Bike and Ride": "schemat B+R (Bike and Ride)", + "Rented Bicycle": "wypożyczonym rowerem", + "Transit & Rented Bicycle": "kom. publiczną & wypoż. rowerem", + "Rented Scooter": "", + "Transit & Rented Scooter": "kom. publiczną & wypoż. rowerem", + "Transit with flex access": "", + "Transit with flex egress": "", + "Transit with flex access and egress": "", + "Direct flex search": "", + "Recenter Map Here": "Wyśrodkuj mapę w tym miejscu", + "Zoom In": "Przybliż", + "Zoom Out": "Oddal", + "Minimize all": "Minimalizuj wszystko", + "Unminimize all": "Maskymalizuj wszystko", + "Stop Viewer": "Zatrzymaj podgląd", + "Plan Trip": "Zaplanuj podróż", + "From Stop": "Z przystanku", + "To Stop": "Do przystanku", + "Routes Serving Stop": "Trasy obsługujące dany przystanek", + "Bike Share Planner": "Planner wypożyczenia roweru", + "Trip Options": "Trasa", + "PICK UP BIKE": "WYPOŻYCZ ROWER", + "ALTERNATE PICKUP": "ALTERNATYWNY PUNKT WYPOŻYCZENIA", + "DROP OFF BIKE": "ODDAJ ROWER", + "ALTERNATE DROP OFF": "ALTERNATYWNY PUNKT ODDANIA ROWERU", + "BIKE STATION": "STACJA ROWEROWA", + "Station:": "Stacja:", + "%d bike available_0": "%d dostępny rower", + "%d bike available_1": "%d dostępne rowery", + "%d bike available_2": "%d dostępnych rowerów", + "%d dock available_0": "%d dostępna stacja", + "%d dock available_1": "%d dostępne stacje", + "%d dock available_2": "%d dostępnych stacji", + "Recommended Pick Up:": "Rekomendowane miejsce wypożyczenia roweru:", + "Bicycle rental": "Wypożyczalnia rowerów", + "Recommended Drop Off:": "Rekomendowane miejsce oddania roweru:", + "Multimodal Trip Planner": "Planner Podróży", + "Itineraries": "Trasy", + "This itinerary departs on a different day from the previous one": "", + "%d Itinerary Returned_0": "%d zwrócona trasa", + "%d Itinerary Returned_1": "%d zwrócone trasy", + "%d Itinerary Returned_2": "%d zwróconych tras", + "Link to search": "Link do wyszukiwania", + "Previous Page": "Poprzednia", + "Next Page": "", + "CONTINUES AS": "POZOSTAŃ", + "%d min late_0": "%d minuta opóźnienia", + "%d min late_1": "%d minuty opóźnienia", + "%d min late_2": "%d minut opóźnienia", + "%d min early_0": "%d minuta przed czasem", + "%d min early_1": "%d minuty przed czasem", + "%d min early_2": "%d minut przed czasem", + "on time": "na czas", + "This itinerary departs on a different day than the one searched for": "", + "Arrived at destination with a rented bicycle!": "", + "End": "Koniec", + "Trip Summary": "Podsumowanie podróży", + "Travel": "Podróż", + "Time": "Czas trwania podróży", + "GenCost": "", + "Total Walk": "Długość trasy do pokonania pieszo", + "Total Bike": "Długośc trasy do pokonania rowerem", + "Total drive": "", + "Elevation Gained": "", + "Elevation Lost": "", + "Transfers": "Przesiadki", + "Fare": "Koszt", + "Valid": "Aktualna", + "Link to Itinerary": "Link do trasy", + "Print": "Drukuj", + "Your Trip": "Zaplanowana podróż", + "Email": "Adres e-mail", + "every %d min_0": "co %d minutę", + "every %d min_1": "co %d minuty", + "every %d min_2": "co %d minut", + "Board at ": "Wyjazd o", + "Stop": "Przystanek", + "Time in transit": "Czas spędzony w komunikacji publicznej", + "Route ID": "", + "Trip ID": "", + "Service Date": "", + "Trip Viewer": "Podgląd podróży", + "late as": "dopiero jak", + "Stay on board": "Kontynuuj podróż", + "Alight": "Wysiądź", + "at": "na przystanku", + "%(currency)s %(price)s": "%(currency)s %(price)s", + "Start: %(location)s at %(time_date)s": "Początek: %(location)s o %(time_date)s", + "Board": "Wyjazd", + "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s ID przystanku #%(stop_id)s),", + "End: %(location)s at %(time_date)s": "Koniec: %(location)s o %(time_date)s", + "(%(agencyId)s Stop ID #%(id)s),": "", + "\nView itinerary online:\n%(itinerary_link)s\n": "\nWyświetl trasę w trybie online:\n%(itinerary_link)s\n", + "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Przepraszamy. Planer podróży jest obecnie niedostępny. Prosimy o ponowienie próby w późniejszym czasie.", + "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", + "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", + "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Brak informacji o rozkładzie komunikacji publicznej. Obowiązujące dane mogą być nieaktualne, bądź niekompatybilne w wybranym czasie z zaplanowaną trasą.", + "The trip planner is taking way too long to process your request. Please try again later.": "Planer podróży nie jest w stanie przetwożyć powierzonego mu zadania. Prosimy o ponowienie próby w późniejszym czasie.", + "The request has errors that the server is not willing or able to process.": "Wybrane zapytanie posiada błędy, których serwer nie jest w stanie obsłużyć.", + "Origin is unknown. Can you be a bit more descriptive?": "Wystąpił problem z określeniem lokalizacji startowej. Czy mógłbyś sprecyzować zapytanie?", + "Destination is unknown. Can you be a bit more descriptive?": "Wystąpił problem z określeniem lokalizacji końcowej. Czy mógłbyś sprecyzować zapytanie?", + "Both origin and destination are unknown. Can you be a bit more descriptive?": "Wystąpił problem z określeniem lokalizacji startowej oraz końcowej. Czy mógłbyś sprecyzować zapytanie?", + "Both origin and destination are not wheelchair accessible": "Zarówno lokalizacja startowa, jak i końcowa, nie oferuje udogodnień dla osób niepełnosprawnych.", + "Origin is within a trivial distance of the destination.": "Lokalizacja początkowa jest zlokalizowana w nieznacznej odległości od miejsca docelowego.", + "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "Planer podróży nie może zinterpretować lokalizacji początkowej. Prosimy o wybranie jednej z poniższych opcji, bądź sprecyzować zapytanie.", + "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "Planer podróży nie może zinterpretować lokalizacji końcowej. Prosimy o wybranie jednej z poniższych opcji, bądź sprecyzować zapytanie.", + "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "Zarówno lokalizacja początkowa, jak i końcowa nie została poprawnie ziterpretowana przez planer podróży. Prosimy o wybranie pozycji dostępnych na liście poniżej, bądź sprecyzować zapytanie.", + "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "Każdy z parametrów triangleSafetyFactor (bezpieczeństwo), triangleSlopeFactor (nachylenie) i triangleTimeFactor (czas) musi zostać ustawiony, jeśli na trasie znajdują się dane punkty.", + "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "Suma wartości w parametrach triangleSafetyFactor, triangleSlopeFactor i triangleTimeFactor musi wynieśc równo 1.", + "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "Jeśli zostały wprowadzone parametry triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor, wartość OptimizeType musi wskazywać na TRIANGLE (TRÓJKĄT)", + "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "Jeśli wartość pola OptimizeType wskazuje na TRIANGLE (TRÓJKĄT), należy podać parametry zmiennych triangleSafetyFactor, triangleSlopeFactor oraz triangleTimeFactor.", + "Set as Start Location": "Wybierz jako punkt początkowy", + "Set as End Location": "Wybierz jako punkt końcowy", + "Destination": "Cel", + "Error %(error_id)d": "Błąd %(error_id)d", + "No Trip Found": "Trasa nie została wyznaczona", + "Your %(bike_share_name)s route": "Twoja trasa : %(bike_share_name)s", + "Your bike route": "Trasa pokonana rowerem", + "Walk to the %(bike_share_name)s dock.": "Przejdź do doku %(bike_share_name)s", + "Walk from the %(bike_share_name)s dock to your destination.": "Przejdź z doku %(bike_share_name)s do punktu docelowego", + "Your walk route": "Trasa pokonana pieszo", + "Your route using the scooter": "", + "Your driving route": "Trasa pokonana rowerem", + "north": "północ", + "northeast": "północny wschód", + "east": "wschód", + "southeast": "południowy wschód", + "south": "południe", + "southwest": "południowy zachód", + "west": "zachód", + "northwest": "północny zachód", + "hard left": "ostro w lewo", + "left": "lewo", + "slight left": "łagodnie w lewo", + "continue": "utrzymuj kierunek", + "slight right": "łagodnie w prawo", + "right": "prawo", + "hard right": "ostro w prawo", + "elevator": "wzniesienie", + "U-turn left": "nawrót w lewo", + "U-turn right": "nawrót w prawo", + "Walk": "Spacer", + "Cycle": "Rower", + "Car": "Samochód", + "Bus": "Autobus", + "Subway": "Metro", + "Train": "Pociąg", + "Ferry": "Prom", + "Light Rail": "Light Rail", + "Cable Car": "Kolejka linowa", + "Funicular": "Kolej linowo-terenowa", + "Aerial Tram": "Kolej linowa", + "Airplane": "", + "Bicycle rental station": "Stacja wypożyczalni rowerów", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Przejedź przez rondo przeciwnie do ruchów wskazówki zegara do %(ordinal_exit_number)s wyjazdu na ulicę %(street_name)s", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Przejedź przez rondo przeciwnie do ruchów wskazówki zegara do %(ordinal_exit_number)s wyjazdu na ulicę %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Przejedź przez rondo zgodnie z ruchem wskazówki zegara do %(ordinal_exit_number)s wyjazdu na ulicę %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Przejedź przez rondo zgodnie z ruchem wskazówki zegara do %(ordinal_exit_number)s wyjazdu na ulicę %(street_name)s", + "Start on": "Rozpocznij na ulicy", + " heading ": "kierując się na", + "to continue on": "kieruj się w stronę", + "on to": "ulicy", + "first": "pierwszego", + "second": "drugiego", + "third": "trzeciego", + "fourth": "czwartego", + "fifth": "piątego", + "sixth": "szóstego", + "seventh": "siódmego", + "eight": "ósmego", + "ninth": "dziewiątego", + "tenth": "dziesiątego", + "%d hr_0": "%d h", + "%d hr_1": "%d h", + "%d hr_2": "%d h", + "%d min_0": "%d min", + "%d min_1": "%d min", + "%d min_2": "%d min", + "%d sec_0": "%d sek", + "%d sec_1": "%d sek", + "%d sec_2": "%d sek", + "OK": "OK", + "Minimize": "Minimalizuj", + "Bring to front": "Przenieś na wierzch", + "Send to back": "Przesuń na spód", + "Route:": "Trasa przejazdu:", + "Variant:": "Wariant:", + "Stop Finder": "Wyszukiwarka przystanków", + "Feed": "Agencja", + "By ID": "ID", + "By Name": "Nazwa", + "Search": "Szukaj", + "No Stops Found": "Nie znaleziono przystanków", + "Date": "Data", + "Find Stops": "Wyszukaj przystanki", + "(No Stop Selected)": "Nie wybrano przystanków", + "Block": "Zablokuj", + "Recenter": "Wyśrodkuj", + "Viewer": "Podgląd", + "Quick": "Szybki", + "Flat": "Równy teren", + "Bike Friendly": "Przyjazny dla rowerzystów", + "B": "B", + "F": "F", + "Q": "Q", + "All Routes": "Wszystkie trasy", + "Save": "Zapisz", + "Close": "Zamknij", + "Travel Options": "Opcje podróży", + "Geocoder": "Geocoder", + "Arrive": "Czas przyjazdu", + "Now": "Teraz", + "Wheelchair accessible trip:": "Wycieczka zawierająca udogodnienia dla osób niepełnosprawnych", + "Show Filtered Itineraries:": "", + "Travel by": "Podróżuj", + "Preferred Routes": "Preferowane trasy", + "Edit": "Edytuj", + "None": "Brak", + "Weight": "Waga", + "Banned routes": "Wyłączone trasy", + "Use": "Użyj", + "My Own Bike": "własnego roweru", + "A Shared Bike": "wypożyczonego roweru", + "Plan Your Trip": "Zaplanuj swoją podróż", + "Additional parameters": "", + " to _direction": "w kierunku", + " to _bus_direction": "w kierunku", + "Start_template": "Start", + "Depart_itinerary": "Wyjazd ze stacji", + "depart_itinerary": "odjazd", + "Start_popup": "Początek", + "Depart_tripoptions": "Czas wyjazdu" +} diff --git a/application/src/client/classic-debug/js/otp/locale/pt.json b/application/src/client/classic-debug/js/otp/locale/pt.json new file mode 100644 index 00000000000..bf2e4a78732 --- /dev/null +++ b/application/src/client/classic-debug/js/otp/locale/pt.json @@ -0,0 +1,238 @@ +{ + "Transit": "Vários", + "Bus Only": "Autocarro apenas", + "Rail Only": "Só ferroviário", + "Airplane Only": "", + "Transit, No Airplane": "", + "Bicycle Only": "Bicicleta apenas", + "Bicycle & Transit": "Bicicleta & vários", + "Walk Only": "Só a pé", + "Car Only": "Origem em", + "Taxi": "", + "Park and Ride": "Estacionar e conduzir", + "Ride and Kiss (Car Pickup)": "", + "Kiss and Ride (Car Dropoff)": "", + "Bike and Ride": "Bicicleta e conduzir", + "Rented Bicycle": "Bicicleta alugada", + "Transit & Rented Bicycle": "Vários & bicicletas alugadas", + "Rented Scooter": "", + "Transit & Rented Scooter": "Vários & bicicletas alugadas", + "Transit with flex access": "", + "Transit with flex egress": "", + "Transit with flex access and egress": "", + "Direct flex search": "", + "Recenter Map Here": "Mapa mais recente aqui", + "Zoom In": "Zoom In", + "Zoom Out": "Zoom Out", + "Minimize all": "Minimizar tudo", + "Unminimize all": "Maximizar tudo", + "Stop Viewer": "Visualizardor de paragens", + "Plan Trip": "Planear rota", + "From Stop": "Da paragem", + "To Stop": "Para a paragem", + "Routes Serving Stop": "Paragens servindo as linhas", + "Bike Share Planner": "Planeador de partilha de bicicletas", + "Trip Options": "Opções de viagem", + "PICK UP BIKE": "APANHAR UMA BICICLETA", + "ALTERNATE PICKUP": "APANHAR DE BICICLETA ALTERNATIVO", + "DROP OFF BIKE": "LARGAR A BICICLETA", + "ALTERNATE DROP OFF": "LARGAR DE BICICLETA ALTERNATIVO", + "BIKE STATION": "ESTAÇÃO DE BICICLETAS", + "Station:": "Estação:", + "%d bike available": "%d bicicleta disponível", + "%d bike available_plural": "%d bicicletas disponíveis", + "%d dock available": "%d dock disponível", + "%d dock available_plural": "%d docks disponíveis", + "Recommended Pick Up:": "Apanhar de bicicleta recomendado:", + "Bicycle rental": "Aluguer de bicicletas", + "Recommended Drop Off:": "Largar de bicicleta recomendado:", + "Multimodal Trip Planner": "Planeador de rotas multi-modal", + "Itineraries": "Itinerários", + "This itinerary departs on a different day from the previous one": "", + "%d Itinerary Returned": "%d Itinerário devolvido", + "%d Itinerary Returned_plural": "%d Itinerários devolvidos", + "Link to search": "Link para pesquisa", + "Previous Page": "Anterior", + "Next Page": "", + "CONTINUES AS": "CONTINUAR COMO", + "%d min late": "%d min mais tarde", + "%d min late_plural": "%d mins mais tarde", + "%d min early": "%d min mais cedo", + "%d min early_plural": "%d mins mais cedo", + "on time": "a tempo", + "This itinerary departs on a different day than the one searched for": "", + "Arrived at destination with a rented bicycle!": "", + "End": "Destino", + "Trip Summary": "Sumário da rota", + "Travel": "Viagem", + "Time": "Tempo", + "GenCost": "", + "Total Walk": "Total a pé", + "Total Bike": "Total de bicicleta", + "Total drive": "", + "Elevation Gained": "", + "Elevation Lost": "", + "Transfers": "Transferências", + "Fare": "Tarifa", + "Valid": "Válido", + "Link to Itinerary": "Link para o itenerário", + "Print": "Imprimir", + "Your Trip": "A tua rota", + "Email": "Email", + "every %d min": "A cada %d min", + "every %d min_plural": " A cada %d mins", + "Board at ": "Entrar às", + "Stop": "Paragem", + "Time in transit": "Tempo em viagem", + "Route ID": "", + "Trip ID": "", + "Service Date": "", + "Trip Viewer": "Visualizador de rotas", + "late as": "tão tarde como", + "Stay on board": "Mantenha-se em viagem", + "Alight": "Iluminado", + "at": "às", + "%(currency)s %(price)s": "%(currency)s %(price)s", + "Start: %(location)s at %(time_date)s": "Partida: %(location)s às %(time_date)s", + "Board": "Entrar", + "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s ID Paragem #%(stop_id)s),", + "End: %(location)s at %(time_date)s": "Destino: %(location)s at %(time_date)s", + "(%(agencyId)s Stop ID #%(id)s),": "", + "\nView itinerary online:\n%(itinerary_link)s\n": "\nVer itinerário online:\n%(itinerary_link)s\n", + "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Pedimos desculpa. O planeador de rotas está temporariamente indisponível. Tente mais tarde.", + "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", + "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", + "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Não há tempos de trânsito disponíveis. Não há informação acerca dos transportes para esta data.", + "The trip planner is taking way too long to process your request. Please try again later.": "O planeador de rotas está a demorar demasiado tempo para processar o seu pedido. Tente mais tarde.", + "The request has errors that the server is not willing or able to process.": "O seu pedido tem erros e o servidor não está a conseguir processá-lo.", + "Origin is unknown. Can you be a bit more descriptive?": "Origem desconhecida. Pode ser mais descritivo?", + "Destination is unknown. Can you be a bit more descriptive?": "Destino indisponível. Pode ser mais descritivo?", + "Both origin and destination are unknown. Can you be a bit more descriptive?": "Origem e destino desconhecidos. Pode ser mais descritivo?", + "Both origin and destination are not wheelchair accessible": "Origem e destino não acessível a cadeiras de rodas.", + "Origin is within a trivial distance of the destination.": "Origem a uma distância demasiado pequena do destino.", + "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "O planeador de rotas está inseguro em relação à localização da sua origem. Selecione uma das seguintes opções ou seja mais específico.", + "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "O planeador de rotas está inseguro em relação à localização do seu destino. Selecione uma das seguintes opções ou seja mais específico.", + "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "Origem e destino ambíguos. Selecione uma das seguintes opções ou seja mais específico.", + "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "Todo o triangleSafetyFactor, triangleSlopeFactor, e triangleTimeFactor deve ser definido se algum for", + "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "Os valores de triangleSafetyFactor, triangleSlopeFactor, e triangleTimeFactor devem somar com valor 1", + "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "Se o triangleSafetyFactor, triangleSlopeFactor, e triangleTimeFactor forem fornecidos, OptimizeType deve ser um TRIANGLE", + "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "Se OptimizeType é TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, e triangleTimeFactor devem ser definidos", + "Set as Start Location": "Definir como local de origem", + "Set as End Location": "Definir como local de destino", + "Destination": "Destino", + "Error %(error_id)d": "Erro %(error_id)d", + "No Trip Found": "Nenhuma rota encontrada", + "Your %(bike_share_name)s route": "A sua rota %(bike_share_name)s ", + "Your bike route": "A sua rota de bicicleta", + "Walk to the %(bike_share_name)s dock.": "Andar para a dock %(bike_share_name)s .", + "Walk from the %(bike_share_name)s dock to your destination.": "Andar da dock %(bike_share_name)s para o seu destino.", + "Your walk route": "A sua rota a pé", + "Your route using the scooter": "", + "Your driving route": "A sua rota de bicicleta", + "north": "norte", + "northeast": "nordeste", + "east": "este", + "southeast": "sudeste", + "south": "sul", + "southwest": "sudoeste", + "west": "oeste", + "northwest": "nordeste", + "hard left": "esquerda apertada", + "left": "esquerda", + "slight left": "esquerda ligeira", + "continue": "continuar", + "slight right": "direita ligeira", + "right": "direita", + "hard right": "direita apertada", + "elevator": "elevador", + "U-turn left": "cotovelo à esquerda", + "U-turn right": "cotovelo à direita", + "Walk": "A pé", + "Cycle": "Bicicleta", + "Car": "Carro", + "Bus": "Autocarro", + "Subway": "Metro", + "Train": "Comboio", + "Ferry": "Ferry", + "Light Rail": "Ferroviário leve", + "Cable Car": "Eléctrico", + "Funicular": "Teleférico", + "Aerial Tram": "Teleférico", + "Airplane": "", + "Bicycle rental station": "Estação de aluguer de bicicletas", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Entrar na rotuda no sentido contrário aos ponteiros do relógio na %(ordinal_exit_number)s saída em direção a %(street_name)s", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Entrar na rotunda no sentido contrário aos ponteiros do relógio, na %(ordinal_exit_number)s saída em direcção a %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Entrar na rotuda no sentido dos ponteiros do relógio na %(ordinal_exit_number)s saída em direção a %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Entrar na rotunda no sentido dos ponteiros do relógio, na %(ordinal_exit_number)s saída em direcção a %(street_name)s", + "Start on": "Origem em", + " heading ": "em direcção a", + "to continue on": "a continuar em", + "on to": "para", + "first": "primeiro", + "second": "segundo", + "third": "terceiro", + "fourth": "quarto", + "fifth": "quinto", + "sixth": "sexto", + "seventh": "sétimo", + "eight": "oitavo", + "ninth": "nono", + "tenth": "décimo", + "%d hr": "%d hr", + "%d hr_plural": "%d hrs", + "%d min": "%d min", + "%d min_plural": "%d mins", + "%d sec": "%d sec", + "%d sec_plural": "%d secs", + "OK": "OK", + "Minimize": "Minimzar", + "Bring to front": "Trazer prá frente", + "Send to back": "Mandar para trás", + "Route:": "Rota:", + "Variant:": "Variante:", + "Stop Finder": "Pesquisar paragem", + "Feed": "Companhia", + "By ID": "Por ID", + "By Name": "Por Nome", + "Search": "Pesquisar", + "No Stops Found": "Nenhuma paragem encontrada", + "Date": "Data", + "Find Stops": "Procurar paragens", + "(No Stop Selected)": "(Nenhuma paragem selecionada)", + "Block": "Bloquear", + "Recenter": "Mais recente", + "Viewer": "Visualizador", + "Quick": "Rápido", + "Flat": "Plano", + "Bike Friendly": "Amigo às bicicletas", + "B": "B", + "F": "F", + "Q": "Q", + "All Routes": "Todas as rotas", + "Save": "Guardar", + "Close": "Fechar", + "Travel Options": "Opções de viagem", + "Geocoder": "Geocoder", + "Arrive": "Chegada", + "Now": "Agora", + "Wheelchair accessible trip:": "Rota acessível a cadeira de rodas", + "Show Filtered Itineraries:": "", + "Travel by": "Viagem por", + "Preferred Routes": "Rotas favoritas", + "Edit": "Editar", + "None": "Nenhum", + "Weight": "Peso", + "Banned routes": "Rotas banidas", + "Use": "Utilizar", + "My Own Bike": "A minha bicicleta", + "A Shared Bike": "Uma bicicleta partilhada", + "Plan Your Trip": "Planear a sua viagem", + "Additional parameters": "", + " to _direction": "Para", + " to _bus_direction": "Para", + "Start_template": "Começar", + "Depart_itinerary": "Partida", + "depart_itinerary": "partida", + "Start_popup": "Origem", + "Depart_tripoptions": "Partir" +} diff --git a/application/src/client/classic-debug/js/otp/locale/sl.json b/application/src/client/classic-debug/js/otp/locale/sl.json new file mode 100644 index 00000000000..8991e9451d8 --- /dev/null +++ b/application/src/client/classic-debug/js/otp/locale/sl.json @@ -0,0 +1,256 @@ +{ + "Transit": "Javni prevoz", + "Bus Only": "Avtobus", + "Rail Only": "Vlak", + "Airplane Only": "", + "Transit, No Airplane": "", + "Bicycle Only": "Kolo", + "Bicycle & Transit": "Kolo & Javni prevoz", + "Walk Only": "Pešačenje", + "Car Only": "Začnite na", + "Taxi": "", + "Park and Ride": "Parkiraj in se pelji", + "Ride and Kiss (Car Pickup)": "", + "Kiss and Ride (Car Dropoff)": "", + "Bike and Ride": "", + "Rented Bicycle": "Izposojeno kolo", + "Transit & Rented Bicycle": "Izposojeno kolo & Javni prevoz", + "Rented Scooter": "", + "Transit & Rented Scooter": "Izposojeno kolo & Javni prevoz", + "Transit with flex access": "", + "Transit with flex egress": "", + "Transit with flex access and egress": "", + "Direct flex search": "", + "Recenter Map Here": "Prikaži karto tukaj", + "Zoom In": "Približaj", + "Zoom Out": "Oddalji", + "Minimize all": "Skrči vse", + "Unminimize all": "Razširi vse", + "Stop Viewer": "Pregledovalnik postaj", + "Plan Trip": "Načrtuj pot", + "From Stop": "Začetna postaja", + "To Stop": "Končna postaja", + "Routes Serving Stop": "Avtobusi, ki ustavljajo na postaji", + "Bike Share Planner": "Planer za izposojena kolesa", + "Trip Options": "Nastavitve poti", + "PICK UP BIKE": "IZPOSOJA KOLESA", + "ALTERNATE PICKUP": "ALTERNATIVNO MESTO IZPOSOJE", + "DROP OFF BIKE": "VRNITEV KOLESA", + "ALTERNATE DROP OFF": "ALTERNATIVNO MESTO VRNITVE KOLESA", + "BIKE STATION": "IZPOSOJEVALNA POSTAJA", + "Station:": "Postaja:", + "%d bike available_0": "%d koles na voljo", + "%d bike available_1": "%d kolo na voljo", + "%d bike available_2": "%d kolesi na voljo", + "%d bike available_3": "%d kolesa na voljo", + "%d dock available_0": "%d prostorov na voljo", + "%d dock available_1": "%d prostor na voljo", + "%d dock available_2": "%d prostora na voljo", + "%d dock available_3": "%d prostori na voljo", + "Recommended Pick Up:": "Predlagana postaja za izposojo kolesa:", + "Bicycle rental": "postaje za izposojo koles", + "Recommended Drop Off:": "Predlagana postaja za vrnitev kolesa:", + "Multimodal Trip Planner": "Načrtovalnik poti", + "Itineraries": "Načrti poti", + "This itinerary departs on a different day from the previous one": "", + "%d Itinerary Returned_0": "%d vrnjenih načrtov poti", + "%d Itinerary Returned_1": "%d vrnjen načrt poti", + "%d Itinerary Returned_2": "%d vrnjena načrta poti", + "%d Itinerary Returned_3": "%d vrnjeni načrti poti", + "Link to search": "Iskanje", + "Previous Page": "Prejšnja", + "Next Page": "", + "CONTINUES AS": "SE NADALJUJE KOT", + "%d min late_0": "%d min. zamude", + "%d min late_1": "%d min. zamude", + "%d min late_2": "%d min. zamude", + "%d min late_3": "%d min. zamude", + "%d min early_0": "%d min. prehitro", + "%d min early_1": "%d min. prehitro", + "%d min early_2": "%d min. prehitro", + "%d min early_3": "%d min. prehitro", + "on time": "pravočasno", + "This itinerary departs on a different day than the one searched for": "", + "Arrived at destination with a rented bicycle!": "", + "End": "Konec", + "Trip Summary": "Povzetek poti", + "Travel": "Potuj ob", + "Time": "Trajanje", + "GenCost": "", + "Total Walk": "Skupno hoje", + "Total Bike": "Skupno kolesarjenja", + "Total drive": "", + "Elevation Gained": "", + "Elevation Lost": "", + "Transfers": "Št. prestopov", + "Fare": "Cena", + "Valid": "Veljavno", + "Link to Itinerary": "Načrt poti", + "Print": "Natisni", + "Your Trip": "Vaša pot", + "Email": "E-pošta", + "every %d min_0": "vsakih %d min", + "every %d min_1": "vsako %d min", + "every %d min_2": "vsaki %d min", + "every %d min_3": "vsake %d min", + "Board at ": "Vstop na ", + "Stop": "Postaja", + "Time in transit": "Časa na vožnji", + "Route ID": "", + "Trip ID": "", + "Service Date": "", + "Trip Viewer": "Pregledovalnik poti", + "late as": "", + "Stay on board": "Ostanite v vozilu", + "Alight": "Izstop", + "at": "na", + "%(currency)s %(price)s": "%(price)s %(currency)s", + "Start: %(location)s at %(time_date)s": "Začetek: %(location)s ob %(time_date)s", + "Board": "Vstop", + "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s),", + "End: %(location)s at %(time_date)s": "Konec: %(location)s ob %(time_date)s", + "(%(agencyId)s Stop ID #%(id)s),": "", + "\nView itinerary online:\n%(itinerary_link)s\n": "\nOglejte si načrt poti na spletu:\n%(itinerary_link)s\n", + "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Opravičujemo se. Daljinar trenutno ni na voljo. Prosimo poskusite kasneje.", + "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", + "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", + "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Podatki o voznih redih niso na voljo. Mogoče je datum preveč v preteklosti ali prihodnosti ali pa javni prevoz ne obstaja za pot, ki jo načrtujete.", + "The trip planner is taking way too long to process your request. Please try again later.": "Daljinar potrebuje preveč časa za obdelavo vašega zahtevka. Prosimo poskusite znova kasneje.", + "The request has errors that the server is not willing or able to process.": "Zahtevek ima napake, ki jih strežnik ne more obdelati.", + "Origin is unknown. Can you be a bit more descriptive?": "Začetek poti ni znan. Prosimo bodite bolj natančni.", + "Destination is unknown. Can you be a bit more descriptive?": "Konec poti ni znan. Prosimo bodite bolj natančni.", + "Both origin and destination are unknown. Can you be a bit more descriptive?": "Začetek in konec sta neznana. Prosimo bodite bolj natančni.", + "Both origin and destination are not wheelchair accessible": "Do začetka in konca ni mogoče priti z vozičkom.", + "Origin is within a trivial distance of the destination.": "Začetek je trivialno oddaljen od konec.", + "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "", + "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "", + "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "", + "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "", + "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "", + "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "", + "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "", + "Set as Start Location": "Začetek poti", + "Set as End Location": "Konec poti", + "Destination": "Konec", + "Error %(error_id)d": "Napaka %(error_id)d", + "No Trip Found": "Ne najdemo poti", + "Your %(bike_share_name)s route": "Kolesarjenje s kolesom izposojenim pri %(bike_share_name)s", + "Your bike route": "Kolesarska pot", + "Walk to the %(bike_share_name)s dock.": "Hodite do postaje podjetja %(bike_share_name)s.", + "Walk from the %(bike_share_name)s dock to your destination.": "Hodite od postaje podjetja %(bike_share_name)s do vašega cilja.", + "Your walk route": "Pot peš", + "Your route using the scooter": "", + "Your driving route": "Kolesarska pot", + "north": "sever", + "northeast": "severovzhod", + "east": "vzhod", + "southeast": "jugovzhod", + "south": "jug", + "southwest": "jugozahod", + "west": "zahod", + "northwest": "severozahod", + "hard left": "ostro levo", + "left": "levo", + "slight left": "rahlo levo", + "continue": "nadaljujte", + "slight right": "rahlo desno", + "right": "desno", + "hard right": "ostro desno", + "elevator": "pojdite z dvigalom", + "U-turn left": "Polkrožno obrnite v levo", + "U-turn right": "Polkrožno obrnite v desno", + "Walk": "Pešačite", + "Cycle": "Kolesarite", + "Car": "Avto", + "Bus": "Avtobus", + "Subway": "Podzemna železnica", + "Train": "Vlak", + "Ferry": "", + "Light Rail": "Tramvaj", + "Cable Car": "", + "Funicular": "", + "Aerial Tram": "Gondola", + "Airplane": "", + "Bicycle rental station": "postaje za izposojo koles", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "V krožišču vozite v nasprotni smeri urinega kazalca in pri %(ordinal_exit_number)s izvozu zavijte na %(street_name)s", + "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "V krožišču vozite v nasprotni smeri urinega kazalca in pri %(ordinal_exit_number)s izvozu zavijte na %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "V krožišču vozite v smeri urinega kazalca in pri %(ordinal_exit_number)s izvozu zavijte na %(street_name)s", + "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "V krožišču vozite v smeri urinega kazalca in pri %(ordinal_exit_number)s izvozu zavijte na %(street_name)s", + "Start on": "Začnite na", + " heading ": " v smeri ", + "to continue on": "nadaljujte na", + "on to": "na", + "first": "prvem", + "second": "drugem", + "third": "tretjem", + "fourth": "četrtem", + "fifth": "petem", + "sixth": "šestem", + "seventh": "sedmem", + "eight": "osmem", + "ninth": "devetem", + "tenth": "desetem", + "%d hr_0": "%d ur", + "%d hr_1": "%d ura", + "%d hr_2": "%d uri", + "%d hr_3": "%d ure", + "%d min_0": "%d min.", + "%d min_1": "%d min.", + "%d min_2": "%d min.", + "%d min_3": "%d min.", + "%d sec_0": "%d sek.", + "%d sec_1": "%d sek.", + "%d sec_2": "%d sek.", + "%d sec_3": "%d sek.", + "OK": "V redu", + "Minimize": "Skrči", + "Bring to front": "Postavi v ospredje", + "Send to back": "Pošlji v ozadje", + "Route:": "Linija:", + "Variant:": "Različica:", + "Stop Finder": "Iskalnik postaj", + "Feed": "", + "By ID": "Po ID-ju", + "By Name": "Po imenu", + "Search": "Poišči", + "No Stops Found": "Ni najdenih postaj", + "Date": "Datum", + "Find Stops": "Poišči postaje", + "(No Stop Selected)": "(Nobena postaja ni bila izbrana)", + "Block": "Blok", + "Recenter": "Prikaži na karti", + "Viewer": "Pregledovalnik", + "Quick": "Hitro", + "Flat": "Položno", + "Bike Friendly": "Kolesarju prijazno", + "B": "K", + "F": "P", + "Q": "H", + "All Routes": "Vse linije", + "Save": "Shrani", + "Close": "Zapri", + "Travel Options": "Možnosti potovanja", + "Geocoder": "", + "Arrive": "Prihod do", + "Now": "Zdaj", + "Wheelchair accessible trip:": "Primerno za invalidske vozičke:", + "Show Filtered Itineraries:": "", + "Travel by": "Način potovanja ", + "Preferred Routes": "Priljubljene linije", + "Edit": "Uredi", + "None": "Brez", + "Weight": "Utež", + "Banned routes": "Neželene linije", + "Use": "Uporabi", + "My Own Bike": "Lastno kolo", + "A Shared Bike": "Izposojeno kolo", + "Plan Your Trip": "Načrtuj pot", + "Additional parameters": "", + " to _direction": " do ", + " to _bus_direction": " smer ", + "Start_template": "Začetek", + "Depart_itinerary": "Odhod", + "depart_itinerary": "začni pot", + "Start_popup": "Začetek", + "Depart_tripoptions": "Odhod ob" +} diff --git a/src/client/classic-debug/js/otp/modules/Module.js b/application/src/client/classic-debug/js/otp/modules/Module.js similarity index 100% rename from src/client/classic-debug/js/otp/modules/Module.js rename to application/src/client/classic-debug/js/otp/modules/Module.js diff --git a/src/client/classic-debug/js/otp/modules/bikeshare/BikeShareModule.js b/application/src/client/classic-debug/js/otp/modules/bikeshare/BikeShareModule.js similarity index 100% rename from src/client/classic-debug/js/otp/modules/bikeshare/BikeShareModule.js rename to application/src/client/classic-debug/js/otp/modules/bikeshare/BikeShareModule.js diff --git a/src/client/classic-debug/js/otp/modules/bikeshare/BikeStationsWidget.js b/application/src/client/classic-debug/js/otp/modules/bikeshare/BikeStationsWidget.js similarity index 100% rename from src/client/classic-debug/js/otp/modules/bikeshare/BikeStationsWidget.js rename to application/src/client/classic-debug/js/otp/modules/bikeshare/BikeStationsWidget.js diff --git a/src/client/classic-debug/js/otp/modules/bikeshare/bikeshare-style.css b/application/src/client/classic-debug/js/otp/modules/bikeshare/bikeshare-style.css similarity index 100% rename from src/client/classic-debug/js/otp/modules/bikeshare/bikeshare-style.css rename to application/src/client/classic-debug/js/otp/modules/bikeshare/bikeshare-style.css diff --git a/src/client/classic-debug/js/otp/modules/multimodal/MultimodalPlannerModule.js b/application/src/client/classic-debug/js/otp/modules/multimodal/MultimodalPlannerModule.js similarity index 100% rename from src/client/classic-debug/js/otp/modules/multimodal/MultimodalPlannerModule.js rename to application/src/client/classic-debug/js/otp/modules/multimodal/MultimodalPlannerModule.js diff --git a/src/client/classic-debug/js/otp/modules/multimodal/multimodal-style.css b/application/src/client/classic-debug/js/otp/modules/multimodal/multimodal-style.css similarity index 100% rename from src/client/classic-debug/js/otp/modules/multimodal/multimodal-style.css rename to application/src/client/classic-debug/js/otp/modules/multimodal/multimodal-style.css diff --git a/src/client/classic-debug/js/otp/modules/planner/IconFactory.js b/application/src/client/classic-debug/js/otp/modules/planner/IconFactory.js similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/IconFactory.js rename to application/src/client/classic-debug/js/otp/modules/planner/IconFactory.js diff --git a/src/client/classic-debug/js/otp/modules/planner/ItinerariesWidget.js b/application/src/client/classic-debug/js/otp/modules/planner/ItinerariesWidget.js similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/ItinerariesWidget.js rename to application/src/client/classic-debug/js/otp/modules/planner/ItinerariesWidget.js diff --git a/src/client/classic-debug/js/otp/modules/planner/Itinerary.js b/application/src/client/classic-debug/js/otp/modules/planner/Itinerary.js similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/Itinerary.js rename to application/src/client/classic-debug/js/otp/modules/planner/Itinerary.js diff --git a/src/client/classic-debug/js/otp/modules/planner/PlannerModule.js b/application/src/client/classic-debug/js/otp/modules/planner/PlannerModule.js similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/PlannerModule.js rename to application/src/client/classic-debug/js/otp/modules/planner/PlannerModule.js diff --git a/src/client/classic-debug/js/otp/modules/planner/TripPlan.js b/application/src/client/classic-debug/js/otp/modules/planner/TripPlan.js similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/TripPlan.js rename to application/src/client/classic-debug/js/otp/modules/planner/TripPlan.js diff --git a/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble.psd b/application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble.psd similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble.psd rename to application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble.psd diff --git a/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_ne.png b/application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_ne.png similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_ne.png rename to application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_ne.png diff --git a/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_ne_highlight.png b/application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_ne_highlight.png similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_ne_highlight.png rename to application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_ne_highlight.png diff --git a/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_nw.png b/application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_nw.png similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_nw.png rename to application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_nw.png diff --git a/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_nw_highlight.png b/application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_nw_highlight.png similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_nw_highlight.png rename to application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_nw_highlight.png diff --git a/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_se.png b/application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_se.png similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_se.png rename to application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_se.png diff --git a/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_se_highlight.png b/application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_se_highlight.png similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_se_highlight.png rename to application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_se_highlight.png diff --git a/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_sw.png b/application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_sw.png similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_sw.png rename to application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_sw.png diff --git a/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_sw_highlight.png b/application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_sw_highlight.png similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_sw_highlight.png rename to application/src/client/classic-debug/js/otp/modules/planner/images/mode/mode_bubble_sw_highlight.png diff --git a/src/client/classic-debug/js/otp/modules/planner/images/user_icon.png b/application/src/client/classic-debug/js/otp/modules/planner/images/user_icon.png similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/images/user_icon.png rename to application/src/client/classic-debug/js/otp/modules/planner/images/user_icon.png diff --git a/src/client/classic-debug/js/otp/modules/planner/planner-style.css b/application/src/client/classic-debug/js/otp/modules/planner/planner-style.css similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/planner-style.css rename to application/src/client/classic-debug/js/otp/modules/planner/planner-style.css diff --git a/src/client/classic-debug/js/otp/modules/planner/planner-templates.html b/application/src/client/classic-debug/js/otp/modules/planner/planner-templates.html similarity index 100% rename from src/client/classic-debug/js/otp/modules/planner/planner-templates.html rename to application/src/client/classic-debug/js/otp/modules/planner/planner-templates.html diff --git a/src/client/classic-debug/js/otp/otp.js b/application/src/client/classic-debug/js/otp/otp.js similarity index 100% rename from src/client/classic-debug/js/otp/otp.js rename to application/src/client/classic-debug/js/otp/otp.js diff --git a/src/client/classic-debug/js/otp/templates.js b/application/src/client/classic-debug/js/otp/templates.js similarity index 100% rename from src/client/classic-debug/js/otp/templates.js rename to application/src/client/classic-debug/js/otp/templates.js diff --git a/src/client/classic-debug/js/otp/util/DataStorage.js b/application/src/client/classic-debug/js/otp/util/DataStorage.js similarity index 100% rename from src/client/classic-debug/js/otp/util/DataStorage.js rename to application/src/client/classic-debug/js/otp/util/DataStorage.js diff --git a/src/client/classic-debug/js/otp/util/Geo.js b/application/src/client/classic-debug/js/otp/util/Geo.js similarity index 100% rename from src/client/classic-debug/js/otp/util/Geo.js rename to application/src/client/classic-debug/js/otp/util/Geo.js diff --git a/src/client/classic-debug/js/otp/util/Imperial.js b/application/src/client/classic-debug/js/otp/util/Imperial.js similarity index 100% rename from src/client/classic-debug/js/otp/util/Imperial.js rename to application/src/client/classic-debug/js/otp/util/Imperial.js diff --git a/src/client/classic-debug/js/otp/util/Itin.js b/application/src/client/classic-debug/js/otp/util/Itin.js similarity index 100% rename from src/client/classic-debug/js/otp/util/Itin.js rename to application/src/client/classic-debug/js/otp/util/Itin.js diff --git a/src/client/classic-debug/js/otp/util/Logger.js b/application/src/client/classic-debug/js/otp/util/Logger.js similarity index 100% rename from src/client/classic-debug/js/otp/util/Logger.js rename to application/src/client/classic-debug/js/otp/util/Logger.js diff --git a/src/client/classic-debug/js/otp/util/Text.js b/application/src/client/classic-debug/js/otp/util/Text.js similarity index 100% rename from src/client/classic-debug/js/otp/util/Text.js rename to application/src/client/classic-debug/js/otp/util/Text.js diff --git a/src/client/classic-debug/js/otp/util/Time.js b/application/src/client/classic-debug/js/otp/util/Time.js similarity index 100% rename from src/client/classic-debug/js/otp/util/Time.js rename to application/src/client/classic-debug/js/otp/util/Time.js diff --git a/src/client/classic-debug/js/otp/widgets/Dialogs.js b/application/src/client/classic-debug/js/otp/widgets/Dialogs.js similarity index 100% rename from src/client/classic-debug/js/otp/widgets/Dialogs.js rename to application/src/client/classic-debug/js/otp/widgets/Dialogs.js diff --git a/src/client/classic-debug/js/otp/widgets/InfoWidget.js b/application/src/client/classic-debug/js/otp/widgets/InfoWidget.js similarity index 100% rename from src/client/classic-debug/js/otp/widgets/InfoWidget.js rename to application/src/client/classic-debug/js/otp/widgets/InfoWidget.js diff --git a/src/client/classic-debug/js/otp/widgets/Widget.js b/application/src/client/classic-debug/js/otp/widgets/Widget.js similarity index 100% rename from src/client/classic-debug/js/otp/widgets/Widget.js rename to application/src/client/classic-debug/js/otp/widgets/Widget.js diff --git a/src/client/classic-debug/js/otp/widgets/WidgetManager.js b/application/src/client/classic-debug/js/otp/widgets/WidgetManager.js similarity index 100% rename from src/client/classic-debug/js/otp/widgets/WidgetManager.js rename to application/src/client/classic-debug/js/otp/widgets/WidgetManager.js diff --git a/src/client/classic-debug/js/otp/widgets/transit/RouteBasedWidget.js b/application/src/client/classic-debug/js/otp/widgets/transit/RouteBasedWidget.js similarity index 100% rename from src/client/classic-debug/js/otp/widgets/transit/RouteBasedWidget.js rename to application/src/client/classic-debug/js/otp/widgets/transit/RouteBasedWidget.js diff --git a/src/client/classic-debug/js/otp/widgets/transit/StopFinderWidget.js b/application/src/client/classic-debug/js/otp/widgets/transit/StopFinderWidget.js similarity index 100% rename from src/client/classic-debug/js/otp/widgets/transit/StopFinderWidget.js rename to application/src/client/classic-debug/js/otp/widgets/transit/StopFinderWidget.js diff --git a/src/client/classic-debug/js/otp/widgets/transit/StopViewerWidget.js b/application/src/client/classic-debug/js/otp/widgets/transit/StopViewerWidget.js similarity index 100% rename from src/client/classic-debug/js/otp/widgets/transit/StopViewerWidget.js rename to application/src/client/classic-debug/js/otp/widgets/transit/StopViewerWidget.js diff --git a/src/client/classic-debug/js/otp/widgets/transit/TripViewerWidget.js b/application/src/client/classic-debug/js/otp/widgets/transit/TripViewerWidget.js similarity index 100% rename from src/client/classic-debug/js/otp/widgets/transit/TripViewerWidget.js rename to application/src/client/classic-debug/js/otp/widgets/transit/TripViewerWidget.js diff --git a/src/client/classic-debug/js/otp/widgets/transit/widgets-transit-style.css b/application/src/client/classic-debug/js/otp/widgets/transit/widgets-transit-style.css similarity index 100% rename from src/client/classic-debug/js/otp/widgets/transit/widgets-transit-style.css rename to application/src/client/classic-debug/js/otp/widgets/transit/widgets-transit-style.css diff --git a/src/client/classic-debug/js/otp/widgets/transit/widgets-transit-templates.html b/application/src/client/classic-debug/js/otp/widgets/transit/widgets-transit-templates.html similarity index 100% rename from src/client/classic-debug/js/otp/widgets/transit/widgets-transit-templates.html rename to application/src/client/classic-debug/js/otp/widgets/transit/widgets-transit-templates.html diff --git a/src/client/classic-debug/js/otp/widgets/tripoptions/BikeTrianglePanel.js b/application/src/client/classic-debug/js/otp/widgets/tripoptions/BikeTrianglePanel.js similarity index 100% rename from src/client/classic-debug/js/otp/widgets/tripoptions/BikeTrianglePanel.js rename to application/src/client/classic-debug/js/otp/widgets/tripoptions/BikeTrianglePanel.js diff --git a/src/client/classic-debug/js/otp/widgets/tripoptions/RoutesSelectorWidget.js b/application/src/client/classic-debug/js/otp/widgets/tripoptions/RoutesSelectorWidget.js similarity index 100% rename from src/client/classic-debug/js/otp/widgets/tripoptions/RoutesSelectorWidget.js rename to application/src/client/classic-debug/js/otp/widgets/tripoptions/RoutesSelectorWidget.js diff --git a/src/client/classic-debug/js/otp/widgets/tripoptions/TripOptionsWidget.js b/application/src/client/classic-debug/js/otp/widgets/tripoptions/TripOptionsWidget.js similarity index 100% rename from src/client/classic-debug/js/otp/widgets/tripoptions/TripOptionsWidget.js rename to application/src/client/classic-debug/js/otp/widgets/tripoptions/TripOptionsWidget.js diff --git a/src/client/classic-debug/js/otp/widgets/tripoptions/tripoptions-style.css b/application/src/client/classic-debug/js/otp/widgets/tripoptions/tripoptions-style.css similarity index 100% rename from src/client/classic-debug/js/otp/widgets/tripoptions/tripoptions-style.css rename to application/src/client/classic-debug/js/otp/widgets/tripoptions/tripoptions-style.css diff --git a/src/client/classic-debug/js/otp/widgets/tripoptions/tripoptions-templates.html b/application/src/client/classic-debug/js/otp/widgets/tripoptions/tripoptions-templates.html similarity index 100% rename from src/client/classic-debug/js/otp/widgets/tripoptions/tripoptions-templates.html rename to application/src/client/classic-debug/js/otp/widgets/tripoptions/tripoptions-templates.html diff --git a/src/client/classic-debug/js/otp/widgets/widget-style.css b/application/src/client/classic-debug/js/otp/widgets/widget-style.css similarity index 100% rename from src/client/classic-debug/js/otp/widgets/widget-style.css rename to application/src/client/classic-debug/js/otp/widgets/widget-style.css diff --git a/src/client/classic-debug/js/otp/widgets/widget-templates.html b/application/src/client/classic-debug/js/otp/widgets/widget-templates.html similarity index 100% rename from src/client/classic-debug/js/otp/widgets/widget-templates.html rename to application/src/client/classic-debug/js/otp/widgets/widget-templates.html diff --git a/src/client/classic-debug/style.css b/application/src/client/classic-debug/style.css similarity index 100% rename from src/client/classic-debug/style.css rename to application/src/client/classic-debug/style.css diff --git a/src/client/graphiql/index.html b/application/src/client/graphiql/index.html similarity index 100% rename from src/client/graphiql/index.html rename to application/src/client/graphiql/index.html diff --git a/src/client/index.html b/application/src/client/index.html similarity index 62% rename from src/client/index.html rename to application/src/client/index.html index 5b969aed83e..b34591918d8 100644 --- a/src/client/index.html +++ b/application/src/client/index.html @@ -4,9 +4,9 @@ - OTP Debug Client - - + OTP Debug + +
diff --git a/src/client/legacygraphql/graphiql/index.html b/application/src/client/legacygraphql/graphiql/index.html similarity index 100% rename from src/client/legacygraphql/graphiql/index.html rename to application/src/client/legacygraphql/graphiql/index.html diff --git a/src/ext-test/java/org/opentripplanner/ext/SandboxExtensionResourceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/SandboxExtensionResourceTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/SandboxExtensionResourceTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/SandboxExtensionResourceTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java b/application/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/datastore/gs/GsDataSourceRepositoryTest.java b/application/src/ext-test/java/org/opentripplanner/ext/datastore/gs/GsDataSourceRepositoryTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/datastore/gs/GsDataSourceRepositoryTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/datastore/gs/GsDataSourceRepositoryTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/datastore/gs/GsHelperTest.java b/application/src/ext-test/java/org/opentripplanner/ext/datastore/gs/GsHelperTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/datastore/gs/GsHelperTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/datastore/gs/GsHelperTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/datastore/gs/GsIntegrationTest.java b/application/src/ext-test/java/org/opentripplanner/ext/datastore/gs/GsIntegrationTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/datastore/gs/GsIntegrationTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/datastore/gs/GsIntegrationTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/emissions/Co2EmissionsDataReaderTest.java b/application/src/ext-test/java/org/opentripplanner/ext/emissions/Co2EmissionsDataReaderTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/emissions/Co2EmissionsDataReaderTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/emissions/Co2EmissionsDataReaderTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsModuleTest.java b/application/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsModuleTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsModuleTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsModuleTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsTest.java b/application/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsTest.java similarity index 75% rename from src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsTest.java index ff8a65ab494..c26ec7c636a 100644 --- a/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsTest.java @@ -2,7 +2,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.model.plan.Itinerary.createScheduledTransitItinerary; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.time.OffsetDateTime; import java.time.ZonedDateTime; @@ -20,7 +21,7 @@ import org.opentripplanner.model.plan.ScheduledTransitLegBuilder; import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.street.search.TraverseMode; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -45,9 +46,13 @@ class EmissionsTest { .withEndTime(TIME.plusHours(1)) .build(); - private static final Route ROUTE_WITH_EMISSIONS = TransitModelForTest.route(id("1")).build(); - private static final Route ROUTE_WITH_ZERO_EMISSIONS = TransitModelForTest.route(id("2")).build(); - private static final Route ROUTE_WITHOUT_EMISSIONS_CONFIGURED = TransitModelForTest + private static final Route ROUTE_WITH_EMISSIONS = TimetableRepositoryForTest + .route(id("1")) + .build(); + private static final Route ROUTE_WITH_ZERO_EMISSIONS = TimetableRepositoryForTest + .route(id("2")) + .build(); + private static final Route ROUTE_WITHOUT_EMISSIONS_CONFIGURED = TimetableRepositoryForTest .route(id("3")) .build(); @@ -63,42 +68,48 @@ static void SetUp() { @Test void testGetEmissionsForItinerary() { - Itinerary i = new Itinerary(List.of(createTransitLeg(ROUTE_WITH_EMISSIONS))); + Itinerary i = createScheduledTransitItinerary(List.of(createTransitLeg(ROUTE_WITH_EMISSIONS))); decorateWithEmission.decorate(i); assertEquals(new Grams(2223.902), i.getEmissionsPerPerson().getCo2()); } @Test void testGetEmissionsForCarRoute() { - Itinerary i = new Itinerary(List.of(STREET_LEG)); + Itinerary i = createScheduledTransitItinerary(List.of(STREET_LEG)); decorateWithEmission.decorate(i); assertEquals(new Grams(28.0864), i.getEmissionsPerPerson().getCo2()); } @Test void testNoEmissionsForFeedWithoutEmissionsConfigured() { - Itinerary i = new Itinerary(List.of(createTransitLeg(ROUTE_WITHOUT_EMISSIONS_CONFIGURED))); + Itinerary i = createScheduledTransitItinerary( + List.of(createTransitLeg(ROUTE_WITHOUT_EMISSIONS_CONFIGURED)) + ); decorateWithEmission.decorate(i); assertNull(i.getEmissionsPerPerson()); } @Test void testZeroEmissionsForItineraryWithZeroEmissions() { - Itinerary i = new Itinerary(List.of(createTransitLeg(ROUTE_WITH_ZERO_EMISSIONS))); + Itinerary i = createScheduledTransitItinerary( + List.of(createTransitLeg(ROUTE_WITH_ZERO_EMISSIONS)) + ); decorateWithEmission.decorate(i); assertEquals(new Grams(0.0), i.getEmissionsPerPerson().getCo2()); } @Test void testGetEmissionsForCombinedRoute() { - Itinerary i = new Itinerary(List.of(createTransitLeg(ROUTE_WITH_EMISSIONS), STREET_LEG)); + Itinerary i = createScheduledTransitItinerary( + List.of(createTransitLeg(ROUTE_WITH_EMISSIONS), STREET_LEG) + ); decorateWithEmission.decorate(i); assertEquals(new Grams(2251.9884), i.getEmissionsPerPerson().getCo2()); } @Test void testNoEmissionsForCombinedRouteWithoutTransitEmissions() { - Itinerary i = new Itinerary( + Itinerary i = createScheduledTransitItinerary( List.of(createTransitLeg(ROUTE_WITHOUT_EMISSIONS_CONFIGURED), STREET_LEG) ); decorateWithEmission.decorate(i); @@ -112,12 +123,15 @@ private ScheduledTransitLeg createTransitLeg(Route route) { var stoptime = new StopTime(); var stopTimes = new ArrayList(); stopTimes.add(stoptime); - var testModel = TransitModelForTest.of(); + var testModel = TimetableRepositoryForTest.of(); var stopOne = testModel.stop("1:stop1", 60, 25).build(); var stopTwo = testModel.stop("1:stop1", 61, 25).build(); var stopThree = testModel.stop("1:stop1", 62, 25).build(); - var stopPattern = TransitModelForTest.stopPattern(stopOne, stopTwo, stopThree); - var pattern = TransitModelForTest.tripPattern("1", route).withStopPattern(stopPattern).build(); + var stopPattern = TimetableRepositoryForTest.stopPattern(stopOne, stopTwo, stopThree); + var pattern = TimetableRepositoryForTest + .tripPattern("1", route) + .withStopPattern(stopPattern) + .build(); var trip = Trip .of(FeedScopedId.parse("FOO:BAR")) .withMode(TransitMode.BUS) diff --git a/application/src/ext-test/java/org/opentripplanner/ext/fares/FareRuleSetTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/FareRuleSetTest.java new file mode 100644 index 00000000000..13d4f713634 --- /dev/null +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/FareRuleSetTest.java @@ -0,0 +1,222 @@ +package org.opentripplanner.ext.fares; + +import static org.junit.jupiter.api.Assertions.*; + +import java.time.Duration; +import java.util.HashSet; +import java.util.Set; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.opentripplanner.ext.fares.model.FareAttribute; +import org.opentripplanner.ext.fares.model.FareRuleSet; +import org.opentripplanner.transit.model.basic.Money; +import org.opentripplanner.transit.model.framework.FeedScopedId; + +class FareRuleSetTest { + + private FareRuleSet fareRuleSet; + static final Money TWO_FIFTY = Money.usDollars(2.50f); + + @BeforeEach + void setUp() { + FeedScopedId id = new FeedScopedId("feed", "fare1"); + FareAttribute fareAttribute = FareAttribute + .of(id) + .setPrice(TWO_FIFTY) + .setPaymentMethod(1) + .setTransfers(1) + .setTransferDuration(7200) + .build(); + fareRuleSet = new FareRuleSet(fareAttribute); + } + + @Test + void testHasNoRules() { + assertFalse(fareRuleSet.hasRules()); + } + + @Test + void testAddOriginDestination() { + fareRuleSet.addOriginDestination("A", "B"); + assertTrue(fareRuleSet.hasRules()); + } + + @Test + void testAddRouteOriginDestination() { + fareRuleSet.addRouteOriginDestination("Route1", "A", "B"); + assertTrue(fareRuleSet.hasRules()); + assertEquals(1, fareRuleSet.getRouteOriginDestinations().size()); + } + + @Test + void testAddContains() { + fareRuleSet.addContains("Zone1"); + assertTrue(fareRuleSet.hasRules()); + assertEquals(1, fareRuleSet.getContains().size()); + } + + @Test + void testAddRoute() { + FeedScopedId routeId = new FeedScopedId("feed", "route1"); + fareRuleSet.addRoute(routeId); + assertTrue(fareRuleSet.hasRules()); + assertEquals(1, fareRuleSet.getRoutes().size()); + } + + @Test + void testMatchesWithNoRules() { + var routes = Set.of(new FeedScopedId("feed", "route1")); + var trips = Set.of(new FeedScopedId("feed", "trip1")); + var zones = Set.of("zone1"); + assertTrue( + fareRuleSet.matches("A", "B", Set.of(), Set.of(), Set.of(), 0, Duration.ZERO, Duration.ZERO) + ); + assertTrue( + fareRuleSet.matches( + "A", + "B", + zones, + routes, + trips, + 0, + Duration.ofMinutes(100), + Duration.ofMinutes(100) + ) + ); + } + + @Test + void testMatchesWithOriginDestination() { + fareRuleSet.addOriginDestination("A", "B"); + assertTrue( + fareRuleSet.matches("A", "B", Set.of(), Set.of(), Set.of(), 0, Duration.ZERO, Duration.ZERO) + ); + assertFalse( + fareRuleSet.matches("B", "C", Set.of(), Set.of(), Set.of(), 0, Duration.ZERO, Duration.ZERO) + ); + } + + @Test + void testMatchesWithContains() { + Set zones = new HashSet<>(); + zones.add("Zone1"); + zones.add("Zone2"); + fareRuleSet.addContains("Zone1"); + fareRuleSet.addContains("Zone2"); + assertTrue( + fareRuleSet.matches("A", "B", zones, Set.of(), Set.of(), 0, Duration.ZERO, Duration.ZERO) + ); + assertFalse( + fareRuleSet.matches("A", "B", Set.of(), Set.of(), Set.of(), 0, Duration.ZERO, Duration.ZERO) + ); + } + + @Test + void testMatchesWithRoutes() { + Set routes = new HashSet<>(); + FeedScopedId routeId = new FeedScopedId("feed", "route1"); + FeedScopedId otherRouteId = new FeedScopedId("feed", "route2"); + routes.add(routeId); + fareRuleSet.addRoute(routeId); + assertTrue( + fareRuleSet.matches("A", "B", Set.of(), routes, Set.of(), 0, Duration.ZERO, Duration.ZERO) + ); + assertFalse( + fareRuleSet.matches( + "A", + "B", + Set.of(), + Set.of(otherRouteId), + Set.of(), + 0, + Duration.ZERO, + Duration.ZERO + ) + ); + } + + @Test + void testMatchesWithTransfers() { + assertTrue( + fareRuleSet.matches("A", "B", Set.of(), Set.of(), Set.of(), 1, Duration.ZERO, Duration.ZERO) + ); + assertFalse( + fareRuleSet.matches("A", "B", Set.of(), Set.of(), Set.of(), 2, Duration.ZERO, Duration.ZERO) + ); + } + + @Test + void testMatchesWithTransferDuration() { + assertTrue( + fareRuleSet.matches( + "A", + "B", + Set.of(), + Set.of(), + Set.of(), + 0, + Duration.ofSeconds(7000), + Duration.ZERO + ) + ); + assertFalse( + fareRuleSet.matches( + "A", + "B", + Set.of(), + Set.of(), + Set.of(), + 0, + Duration.ofSeconds(8000), + Duration.ZERO + ) + ); + } + + @Test + void testMatchesWithJourneyDuration() { + FareAttribute journeyFare = FareAttribute + .of(new FeedScopedId("feed", "journey")) + .setPrice(Money.usDollars(3.00f)) + .setPaymentMethod(1) + .setJourneyDuration(7200) + .build(); + FareRuleSet journeyRuleSet = new FareRuleSet(journeyFare); + + assertTrue( + journeyRuleSet.matches( + "A", + "B", + Set.of(), + Set.of(), + Set.of(), + 0, + Duration.ZERO, + Duration.ofSeconds(7000) + ) + ); + assertFalse( + journeyRuleSet.matches( + "A", + "B", + Set.of(), + Set.of(), + Set.of(), + 0, + Duration.ZERO, + Duration.ofSeconds(8000) + ) + ); + } + + @Test + void testAgencyMethods() { + assertFalse(fareRuleSet.hasAgencyDefined()); + assertNull(fareRuleSet.getAgency()); + + FeedScopedId agencyId = new FeedScopedId("feed", "agency1"); + fareRuleSet.setAgency(agencyId); + assertTrue(fareRuleSet.hasAgencyDefined()); + assertEquals(agencyId, fareRuleSet.getAgency()); + } +} diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/FaresConfigurationTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/FaresConfigurationTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/fares/FaresConfigurationTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/fares/FaresConfigurationTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java similarity index 86% rename from src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java index ac11886c208..b897f3aa78f 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java @@ -2,7 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.util.List; import org.junit.jupiter.api.Test; @@ -13,12 +13,12 @@ import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.fares.FareService; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Money; public class FaresFilterTest implements PlanTestConstants { - private final TransitModelForTest testModel = TransitModelForTest.of(); + private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of(); @Test void shouldAddFare() { diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java similarity index 98% rename from src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java index 3662d45affa..177a74a58db 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java @@ -32,7 +32,7 @@ import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; public class AtlantaFareServiceTest implements PlanTestConstants { @@ -262,7 +262,7 @@ private static Leg createLeg(String agencyId, String shortName, long startTimeMi } private static Itinerary createItinerary(String agencyId, String shortName, long startTimeMins) { - var stopModelBuilder = StopModel.of(); + var siteRepositoryBuilder = SiteRepository.of(); Agency agency = Agency .of(new FeedScopedId(FEED_ID, agencyId)) .withName(agencyId) @@ -270,12 +270,12 @@ private static Itinerary createItinerary(String agencyId, String shortName, long .build(); // Set up stops - RegularStop firstStop = stopModelBuilder + RegularStop firstStop = siteRepositoryBuilder .regularStop(new FeedScopedId(FEED_ID, "1")) .withCoordinate(new WgsCoordinate(1, 1)) .withName(new NonLocalizedString("first stop")) .build(); - RegularStop lastStop = stopModelBuilder + RegularStop lastStop = siteRepositoryBuilder .regularStop(new FeedScopedId(FEED_ID, "2")) .withCoordinate(new WgsCoordinate(1, 2)) .withName(new NonLocalizedString("last stop")) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java similarity index 96% rename from src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java index 407cd0f11e9..f1dabd0948c 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java @@ -22,13 +22,13 @@ import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.core.FareType; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.network.Route; class CombinedInterlinedLegsFareServiceTest implements PlanTestConstants { - static final Route route = TransitModelForTest.route("route-1").build(); + static final Route route = TimetableRepositoryForTest.route("route-1").build(); static final Itinerary interlinedWithDifferentRoute = newItinerary( Place.forStop(AIRPORT_STOP), T11_00 diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java similarity index 98% rename from src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java index cae23f60800..788c1c9b6d6 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java @@ -24,7 +24,7 @@ import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.core.FareType; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Money; class DefaultFareServiceTest implements PlanTestConstants { @@ -116,7 +116,7 @@ void shouldNotCombineInterlinedLegs() { var itin = newItinerary(Place.forStop(AIRPORT_STOP), T11_00) .bus(1, T11_05, T11_12, Place.forStop(CITY_CENTER_A_STOP)) .staySeatedBus( - TransitModelForTest.route("123").build(), + TimetableRepositoryForTest.route("123").build(), 2, T11_12, T11_16, diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FareModelForTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/FareModelForTest.java similarity index 81% rename from src/ext-test/java/org/opentripplanner/ext/fares/impl/FareModelForTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/fares/impl/FareModelForTest.java index e498588d00f..ccd2303f366 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FareModelForTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/FareModelForTest.java @@ -1,21 +1,20 @@ package org.opentripplanner.ext.fares.impl; -import static org.opentripplanner.transit.model._data.TransitModelForTest.OTHER_FEED_AGENCY; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.OTHER_FEED_AGENCY; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import org.opentripplanner.ext.fares.model.FareAttribute; import org.opentripplanner.ext.fares.model.FareRuleSet; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.site.FareZone; import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.StopModelBuilder; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; public class FareModelForTest { @@ -26,40 +25,40 @@ public class FareModelForTest { .of(FeedScopedId.ofNullable("F2", "other-feed-zone")) .build(); - private static final StopModelBuilder STOP_MODEL_BUILDER = StopModel.of(); + private static final SiteRepositoryBuilder SITE_REPOSITORY_BUILDER = SiteRepository.of(); - static final RegularStop AIRPORT_STOP = STOP_MODEL_BUILDER + static final RegularStop AIRPORT_STOP = SITE_REPOSITORY_BUILDER .regularStop(id("airport")) .withCoordinate(new WgsCoordinate(1, 1)) .addFareZones(AIRPORT_ZONE) .withName(I18NString.of("Airport")) .build(); - static final RegularStop CITY_CENTER_A_STOP = STOP_MODEL_BUILDER + static final RegularStop CITY_CENTER_A_STOP = SITE_REPOSITORY_BUILDER .regularStop(id("city-center-a")) .withCoordinate(new WgsCoordinate(1, 2)) .addFareZones(CITY_CENTER_ZONE) .withName(I18NString.of("City center: stop A")) .build(); - static final RegularStop CITY_CENTER_B_STOP = STOP_MODEL_BUILDER + static final RegularStop CITY_CENTER_B_STOP = SITE_REPOSITORY_BUILDER .regularStop(id("city-center-b")) .withCoordinate(new WgsCoordinate(1, 3)) .addFareZones(CITY_CENTER_ZONE) .withName(I18NString.of("City center: stop B")) .build(); - static final RegularStop CITY_CENTER_C_STOP = STOP_MODEL_BUILDER + static final RegularStop CITY_CENTER_C_STOP = SITE_REPOSITORY_BUILDER .regularStop(id("city-center-c")) .withCoordinate(new WgsCoordinate(1, 4)) .addFareZones(CITY_CENTER_ZONE) .withName(I18NString.of("City center: stop C")) .build(); - static final RegularStop SUBURB_STOP = STOP_MODEL_BUILDER + static final RegularStop SUBURB_STOP = SITE_REPOSITORY_BUILDER .regularStop(id("suburb")) .withCoordinate(new WgsCoordinate(1, 4)) .withName(I18NString.of("Suburb")) .build(); - static final RegularStop OTHER_FEED_STOP = STOP_MODEL_BUILDER + static final RegularStop OTHER_FEED_STOP = SITE_REPOSITORY_BUILDER .regularStop(FeedScopedId.ofNullable("F2", "other-feed-stop")) .withCoordinate(new WgsCoordinate(1, 5)) .withName(I18NString.of("Other feed stop")) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java similarity index 92% rename from src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java index 7b822b03059..f5ad2b471ab 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java @@ -22,7 +22,7 @@ import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.transit.model.basic.Money; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; public class FaresIntegrationTest { @@ -30,11 +30,11 @@ public class FaresIntegrationTest { public void testBasic() { TestOtpModel model = ConstantsForTests.buildGtfsGraph(ConstantsForTests.CALTRAIN_GTFS); var graph = model.graph(); - var transitModel = model.transitModel(); + var timetableRepository = model.timetableRepository(); - var feedId = transitModel.getFeedIds().iterator().next(); + var feedId = timetableRepository.getFeedIds().iterator().next(); - var serverContext = TestServerContext.createServerContext(graph, transitModel); + var serverContext = TestServerContext.createServerContext(graph, timetableRepository); var start = LocalDateTime .of(2009, Month.AUGUST, 7, 12, 0, 0) @@ -53,10 +53,10 @@ public void testBasic() { public void testPortland() { TestOtpModel model = ConstantsForTests.getInstance().getCachedPortlandGraph(); Graph graph = model.graph(); - TransitModel transitModel = model.transitModel(); - var portlandId = transitModel.getFeedIds().iterator().next(); + TimetableRepository timetableRepository = model.timetableRepository(); + var portlandId = timetableRepository.getFeedIds().iterator().next(); - var serverContext = TestServerContext.createServerContext(graph, transitModel); + var serverContext = TestServerContext.createServerContext(graph, timetableRepository); // from zone 3 to zone 2 var from = GenericLocation.fromStopId( diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/GtfsFaresV2ServiceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/GtfsFaresV2ServiceTest.java similarity index 97% rename from src/ext-test/java/org/opentripplanner/ext/fares/impl/GtfsFaresV2ServiceTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/fares/impl/GtfsFaresV2ServiceTest.java index c209bc22192..19b55489778 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/GtfsFaresV2ServiceTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/GtfsFaresV2ServiceTest.java @@ -2,8 +2,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; -import static org.opentripplanner.transit.model._data.TransitModelForTest.FEED_ID; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.FEED_ID; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import com.google.common.collect.Multimaps; import java.time.Duration; @@ -22,13 +22,13 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.framework.FeedScopedId; class GtfsFaresV2ServiceTest implements PlanTestConstants { - private final TransitModelForTest testModel = TransitModelForTest.of(); + private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of(); FeedScopedId LEG_GROUP1 = id("leg-group1"); FeedScopedId LEG_GROUP2 = id("leg-group2"); diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java similarity index 98% rename from src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java index 17c381f1bd6..072e8a5a4fe 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java @@ -1,10 +1,9 @@ package org.opentripplanner.ext.fares.impl; import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; -import static org.opentripplanner.transit.model._data.TransitModelForTest.FEED_ID; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.FEED_ID; import static org.opentripplanner.transit.model.basic.Money.euros; import java.util.LinkedList; @@ -21,7 +20,7 @@ import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.core.FareType; import org.opentripplanner.routing.fares.FareService; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -76,7 +75,7 @@ private static List createTestCases() { FareZone C = FareZone.of(new FeedScopedId(FEED_ID, "C")).build(); FareZone D = FareZone.of(new FeedScopedId(FEED_ID, "D")).build(); - var testModel = TransitModelForTest.of(); + var testModel = TimetableRepositoryForTest.of(); Place A1 = testModel.place("A1", sb -> sb.withCoordinate(10.0, 12.0).addFareZones(A)); Place A2 = testModel.place("A2", sb -> sb.withCoordinate(10.0, 12.0).addFareZones(A)); diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java similarity index 98% rename from src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java index e9aa17ba35f..c65db6c3a9f 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java @@ -3,8 +3,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; -import static org.opentripplanner.transit.model._data.TransitModelForTest.FEED_ID; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.FEED_ID; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.time.Duration; import java.util.LinkedList; diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java similarity index 98% rename from src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java index e7a2610b42f..d1e3bd4837c 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java @@ -48,7 +48,7 @@ import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; public class OrcaFareServiceTest { @@ -79,7 +79,7 @@ public static void setUpClass() { * types. */ private static void calculateFare(List legs, FareType fareType, Money expectedPrice) { - var itinerary = new Itinerary(legs); + var itinerary = Itinerary.createScheduledTransitItinerary(legs); var itineraryFares = orcaFareService.calculateFares(itinerary); assertEquals( expectedPrice, @@ -662,15 +662,15 @@ private static Itinerary createItinerary( .withTimezone(ZoneIds.NEW_YORK.getId()) .build(); - var stopModelBuilder = StopModel.of(); + var siteRepositoryBuilder = SiteRepository.of(); // Set up stops - RegularStop firstStop = stopModelBuilder + RegularStop firstStop = siteRepositoryBuilder .regularStop(new FeedScopedId(agencyId, "1")) .withCoordinate(new WgsCoordinate(1, 1)) .withName(new NonLocalizedString(firstStopName)) .build(); - RegularStop lastStop = stopModelBuilder + RegularStop lastStop = siteRepositoryBuilder .regularStop(new FeedScopedId(agencyId, "2")) .withCoordinate(new WgsCoordinate(1, 2)) .withName(new NonLocalizedString(lastStopName)) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/model/FareProductTest.java b/application/src/ext-test/java/org/opentripplanner/ext/fares/model/FareProductTest.java similarity index 97% rename from src/ext-test/java/org/opentripplanner/ext/fares/model/FareProductTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/fares/model/FareProductTest.java index 089bac64c11..65f10db6f85 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/model/FareProductTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/fares/model/FareProductTest.java @@ -6,7 +6,6 @@ import java.time.OffsetDateTime; import java.time.ZonedDateTime; import java.util.stream.Stream; -import javax.annotation.Nonnull; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -57,7 +56,6 @@ void instanceId(FareProduct fareProduct, ZonedDateTime startTime, String expecte assertEquals(expectedInstanceId, instanceId); } - @Nonnull private static FareProduct fareProduct(Duration duration, RiderCategory cat, FareMedium medium) { return new FareProduct( new FeedScopedId("fares", "daypass"), diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapperTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapperTest.java similarity index 84% rename from src/ext-test/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapperTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapperTest.java index 67eb7e3ed93..979db157268 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapperTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapperTest.java @@ -19,26 +19,29 @@ import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model._data.StreetModelForTest; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.site.AreaStop; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; class AreaStopsToVerticesMapperTest { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final AreaStop BERLIN_AREA_STOP = TEST_MODEL .areaStop("berlin") .withGeometry(Polygons.BERLIN) .build(); - public static final StopModel STOP_MODEL = TEST_MODEL - .stopModelBuilder() + public static final SiteRepository SITE_REPOSITORY = TEST_MODEL + .siteRepositoryBuilder() .withAreaStop(AreaStopsToVerticesMapperTest.BERLIN_AREA_STOP) .build(); - public static final TransitModel TRANSIT_MODEL = new TransitModel(STOP_MODEL, new Deduplicator()); + public static final TimetableRepository TRANSIT_MODEL = new TimetableRepository( + SITE_REPOSITORY, + new Deduplicator() + ); static List testCases() { return List.of( diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTest.java similarity index 91% rename from src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTest.java index c88439a9e3f..fb19f1dff36 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTest.java @@ -13,7 +13,6 @@ import java.time.ZonedDateTime; import java.util.List; import java.util.Map; -import javax.annotation.Nonnull; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -34,7 +33,7 @@ import org.opentripplanner.routing.api.request.framework.TimeAndCostPenalty; import org.opentripplanner.routing.api.request.request.filter.AllowAllTransitFilter; import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; /** * This test checks the combination of transit and flex works. @@ -49,7 +48,7 @@ public class FlexIntegrationTest { static Graph graph; - static TransitModel transitModel; + static TimetableRepository timetableRepository; static RoutingService service; @@ -58,23 +57,23 @@ static void setup() { OTPFeature.enableFeatures(Map.of(OTPFeature.FlexRouting, true)); TestOtpModel model = FlexIntegrationTestData.cobbOsm(); graph = model.graph(); - transitModel = model.transitModel(); + timetableRepository = model.timetableRepository(); addGtfsToGraph( graph, - transitModel, + timetableRepository, List.of( FlexIntegrationTestData.COBB_BUS_30_GTFS, FlexIntegrationTestData.MARTA_BUS_856_GTFS, FlexIntegrationTestData.COBB_FLEX_GTFS ) ); - service = TestServerContext.createServerContext(graph, transitModel).routingService(); + service = TestServerContext.createServerContext(graph, timetableRepository).routingService(); } @Test void addFlexTripsAndPatternsToGraph() { - assertFalse(transitModel.getAllTripPatterns().isEmpty()); + assertFalse(timetableRepository.getAllTripPatterns().isEmpty()); } @Test @@ -177,22 +176,26 @@ static void teardown() { OTPFeature.enableFeatures(Map.of(OTPFeature.FlexRouting, false)); } - private static void addGtfsToGraph(Graph graph, TransitModel transitModel, List gtfsFiles) { + private static void addGtfsToGraph( + Graph graph, + TimetableRepository timetableRepository, + List gtfsFiles + ) { // GTFS var gtfsBundles = gtfsFiles.stream().map(GtfsBundle::new).toList(); GtfsModule gtfsModule = new GtfsModule( gtfsBundles, - transitModel, + timetableRepository, graph, ServiceDateInterval.unbounded() ); gtfsModule.buildGraph(); // link stations to streets - TestStreetLinkerModule.link(graph, transitModel); + TestStreetLinkerModule.link(graph, timetableRepository); // link flex locations to streets - new AreaStopsToVerticesMapper(graph, transitModel).buildGraph(); + new AreaStopsToVerticesMapper(graph, timetableRepository).buildGraph(); // generate direct transfers var req = new RouteRequest(); @@ -200,15 +203,15 @@ private static void addGtfsToGraph(Graph graph, TransitModel transitModel, List< // we don't have a complete coverage of the entire area so use straight lines for transfers new DirectTransferGenerator( graph, - transitModel, + timetableRepository, DataImportIssueStore.NOOP, Duration.ofMinutes(10), List.of(req) ) .buildGraph(); - transitModel.index(); - graph.index(transitModel.getStopModel()); + timetableRepository.index(); + graph.index(timetableRepository.getSiteRepository()); } private Itinerary getItinerary(GenericLocation from, GenericLocation to, int index) { @@ -216,7 +219,6 @@ private Itinerary getItinerary(GenericLocation from, GenericLocation to, int ind return itineraries.get(index); } - @Nonnull private static List getItineraries( GenericLocation from, GenericLocation to, diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTestData.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTestData.java similarity index 82% rename from src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTestData.java rename to application/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTestData.java index d3f4f7a62e8..87106394708 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTestData.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTestData.java @@ -15,8 +15,8 @@ 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; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; public final class FlexIntegrationTestData { @@ -43,20 +43,20 @@ public static TestOtpModel cobbOsm() { private static TestOtpModel buildFlexGraph(File file) { var deduplicator = new Deduplicator(); var graph = new Graph(deduplicator); - var transitModel = new TransitModel(new StopModel(), deduplicator); + var timetableRepository = new TimetableRepository(new SiteRepository(), deduplicator); GtfsBundle gtfsBundle = new GtfsBundle(file); GtfsModule module = new GtfsModule( List.of(gtfsBundle), - transitModel, + timetableRepository, graph, new ServiceDateInterval(LocalDate.of(2021, 1, 1), LocalDate.of(2022, 1, 1)) ); OTPFeature.enableFeatures(Map.of(OTPFeature.FlexRouting, true)); module.buildGraph(); - transitModel.index(); - graph.index(transitModel.getStopModel()); + timetableRepository.index(); + graph.index(timetableRepository.getSiteRepository()); OTPFeature.enableFeatures(Map.of(OTPFeature.FlexRouting, false)); - assertTrue(transitModel.hasFlexTrips()); - return new TestOtpModel(graph, transitModel); + assertTrue(timetableRepository.hasFlexTrips()); + return new TestOtpModel(graph, timetableRepository); } } diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/FlexPathDurationsTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexPathDurationsTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/flex/FlexPathDurationsTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/flex/FlexPathDurationsTest.java diff --git a/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexStopTimesForTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexStopTimesForTest.java new file mode 100644 index 00000000000..b67ae85a434 --- /dev/null +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/FlexStopTimesForTest.java @@ -0,0 +1,102 @@ +package org.opentripplanner.ext.flex; + +import org.opentripplanner._support.geometry.Polygons; +import org.opentripplanner.model.PickDrop; +import org.opentripplanner.model.StopTime; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.utils.time.TimeUtils; + +public class FlexStopTimesForTest { + + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); + private static final StopLocation AREA_STOP = TEST_MODEL + .areaStop("area") + .withGeometry(Polygons.BERLIN) + .build(); + private static final RegularStop REGULAR_STOP = TEST_MODEL.stop("stop").build(); + + private static final Trip TRIP = TimetableRepositoryForTest.trip("flex").build(); + + public static StopTime area(String startTime, String endTime) { + return area(AREA_STOP, endTime, startTime); + } + + public static StopTime area(StopLocation areaStop, String endTime, String startTime) { + var stopTime = new StopTime(); + stopTime.setStop(areaStop); + stopTime.setFlexWindowStart(TimeUtils.time(startTime)); + stopTime.setFlexWindowEnd(TimeUtils.time(endTime)); + stopTime.setTrip(TRIP); + return stopTime; + } + + /** + * Returns an invalid combination of a flex area and continuous stopping. + */ + public static StopTime areaWithContinuousStopping(String time) { + var st = area(time, time); + st.setFlexContinuousPickup(PickDrop.COORDINATE_WITH_DRIVER); + st.setFlexContinuousDropOff(PickDrop.COORDINATE_WITH_DRIVER); + return st; + } + + /** + * Returns an invalid combination of a flex area and continuous pick up. + */ + public static StopTime areaWithContinuousPickup(String time) { + var st = area(time, time); + st.setFlexContinuousPickup(PickDrop.COORDINATE_WITH_DRIVER); + return st; + } + + /** + * Returns an invalid combination of a flex area and continuous drop off. + */ + public static StopTime areaWithContinuousDropOff(String time) { + var st = area(time, time); + st.setFlexContinuousDropOff(PickDrop.COORDINATE_WITH_DRIVER); + return st; + } + + public static StopTime regularStop(String arrivalTime, String departureTime) { + return regularStop(TimeUtils.time(arrivalTime), TimeUtils.time(departureTime)); + } + + public static StopTime regularStop(String time) { + return regularStop(TimeUtils.time(time), TimeUtils.time(time)); + } + + public static StopTime regularStopWithContinuousStopping(String time) { + var st = regularStop(TimeUtils.time(time), TimeUtils.time(time)); + st.setFlexContinuousPickup(PickDrop.COORDINATE_WITH_DRIVER); + st.setFlexContinuousDropOff(PickDrop.COORDINATE_WITH_DRIVER); + return st; + } + + public static StopTime regularStopWithContinuousPickup(String time) { + var st = regularStop(TimeUtils.time(time), TimeUtils.time(time)); + st.setFlexContinuousPickup(PickDrop.COORDINATE_WITH_DRIVER); + return st; + } + + public static StopTime regularStopWithContinuousDropOff(String time) { + var st = regularStop(TimeUtils.time(time), TimeUtils.time(time)); + st.setFlexContinuousDropOff(PickDrop.COORDINATE_WITH_DRIVER); + return st; + } + + public static StopTime regularStop(int arrivalTime, int departureTime) { + var stopTime = new StopTime(); + stopTime.setStop(REGULAR_STOP); + stopTime.setArrivalTime(arrivalTime); + stopTime.setDepartureTime(departureTime); + stopTime.setTrip(TRIP); + return stopTime; + } + + + +} diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/GtfsFlexTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/GtfsFlexTest.java similarity index 82% rename from src/ext-test/java/org/opentripplanner/ext/flex/GtfsFlexTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/flex/GtfsFlexTest.java index e116831e2d3..4bd042d332c 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/GtfsFlexTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/GtfsFlexTest.java @@ -11,7 +11,7 @@ import org.opentripplanner.ext.flex.trip.FlexTrip; import org.opentripplanner.ext.flex.trip.UnscheduledTrip; import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; /** * This test makes sure that one of the example feeds in the GTFS-Flex repo works. It's the City of @@ -23,17 +23,17 @@ */ class GtfsFlexTest { - private static TransitModel transitModel; + private static TimetableRepository timetableRepository; @BeforeAll static void setup() { TestOtpModel model = FlexIntegrationTestData.aspenGtfs(); - transitModel = model.transitModel(); + timetableRepository = model.timetableRepository(); } @Test void parseAspenTaxiAsUnscheduledTrip() { - var flexTrips = transitModel.getAllFlexTrips(); + var flexTrips = timetableRepository.getAllFlexTrips(); assertFalse(flexTrips.isEmpty()); assertEquals( Set.of("t_1289262_b_29084_tn_0", "t_1289257_b_28352_tn_0"), @@ -48,6 +48,6 @@ void parseAspenTaxiAsUnscheduledTrip() { @Test void shouldGeneratePatternForFlexTripWithSingleStop() { - assertFalse(transitModel.getAllTripPatterns().isEmpty()); + assertFalse(timetableRepository.getAllTripPatterns().isEmpty()); } } diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/ScheduledFlexPathCalculatorTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/ScheduledFlexPathCalculatorTest.java similarity index 87% rename from src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/ScheduledFlexPathCalculatorTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/ScheduledFlexPathCalculatorTest.java index 985ca5a9898..23827b9503b 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/ScheduledFlexPathCalculatorTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/ScheduledFlexPathCalculatorTest.java @@ -2,10 +2,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.ext.flex.FlexStopTimesForTest.area; -import static org.opentripplanner.ext.flex.FlexStopTimesForTest.regularStopTime; +import static org.opentripplanner.ext.flex.FlexStopTimesForTest.regularStop; import static org.opentripplanner.street.model._data.StreetModelForTest.V1; import static org.opentripplanner.street.model._data.StreetModelForTest.V2; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.time.Duration; import java.util.List; @@ -19,9 +19,9 @@ class ScheduledFlexPathCalculatorTest { .of(id("123")) .withStopTimes( List.of( - regularStopTime("10:00", "10:01"), + regularStop("10:00", "10:01"), area("10:10", "10:20"), - regularStopTime("10:25", "10:26"), + regularStop("10:25", "10:26"), area("10:40", "10:50") ) ) diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculatorTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculatorTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculatorTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculatorTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/template/BoardAlight.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/template/BoardAlight.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/flex/template/BoardAlight.java rename to application/src/ext-test/java/org/opentripplanner/ext/flex/template/BoardAlight.java diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/template/FlexTemplateFactoryTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/template/FlexTemplateFactoryTest.java similarity index 97% rename from src/ext-test/java/org/opentripplanner/ext/flex/template/FlexTemplateFactoryTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/flex/template/FlexTemplateFactoryTest.java index 8c73d0901ff..159e25ff113 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/template/FlexTemplateFactoryTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/template/FlexTemplateFactoryTest.java @@ -6,7 +6,7 @@ import static org.opentripplanner.ext.flex.template.BoardAlight.ALIGHT_ONLY; import static org.opentripplanner.ext.flex.template.BoardAlight.BOARD_AND_ALIGHT; import static org.opentripplanner.ext.flex.template.BoardAlight.BOARD_ONLY; -import static org.opentripplanner.framework.time.TimeUtils.time; +import static org.opentripplanner.utils.time.TimeUtils.time; import gnu.trove.set.hash.TIntHashSet; import java.time.Duration; @@ -30,7 +30,7 @@ import org.opentripplanner.street.model.vertex.StreetLocation; import org.opentripplanner.street.search.request.StreetSearchRequest; import org.opentripplanner.street.search.state.State; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.Trip; @@ -38,7 +38,7 @@ class FlexTemplateFactoryTest { - private static final TransitModelForTest MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest MODEL = TimetableRepositoryForTest.of(); /** * This is pass-through information @@ -78,7 +78,7 @@ class FlexTemplateFactoryTest { private static final StopLocation GROUP_STOP_12 = MODEL.groupStop("G", STOP_G1, STOP_G2); private static final StopLocation GROUP_STOP_34 = MODEL.groupStop("G", STOP_G3, STOP_G4); - private static final Trip TRIP = TransitModelForTest.trip("Trip").build(); + private static final Trip TRIP = TimetableRepositoryForTest.trip("Trip").build(); private static final int T_10_00 = time("10:00"); private static final int T_10_10 = time("10:10"); private static final int T_10_20 = time("10:20"); diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/trip/FlexTripsMapperTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/FlexTripsMapperTest.java similarity index 82% rename from src/ext-test/java/org/opentripplanner/ext/flex/trip/FlexTripsMapperTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/flex/trip/FlexTripsMapperTest.java index fad9e98e254..664bd5ed4bc 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/trip/FlexTripsMapperTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/FlexTripsMapperTest.java @@ -11,14 +11,14 @@ import org.opentripplanner.ext.flex.flexpathcalculator.DirectFlexPathCalculator; import org.opentripplanner.model.StopTime; import org.opentripplanner.model.impl.OtpTransitServiceBuilder; -import org.opentripplanner.transit.model._data.TransitModelForTest; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.transit.service.SiteRepository; class FlexTripsMapperTest { @Test void defaultTimePenalty() { - var builder = new OtpTransitServiceBuilder(StopModel.of().build(), NOOP); + var builder = new OtpTransitServiceBuilder(SiteRepository.of().build(), NOOP); var stopTimes = List.of(stopTime(0), stopTime(1)); builder.getStopTimesSortedByTrip().addAll(stopTimes); var trips = FlexTripsMapper.createFlexTrips(builder, NOOP); @@ -30,7 +30,7 @@ void defaultTimePenalty() { private static StopTime stopTime(int seq) { var st = FlexStopTimesForTest.area("08:00", "18:00"); - st.setTrip(TransitModelForTest.trip("flex-1").build()); + st.setTrip(TimetableRepositoryForTest.trip("flex-1").build()); st.setStopSequence(seq); return st; } diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripIntegrationTest.java similarity index 90% rename from src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripIntegrationTest.java index 6466d7bf6d6..3a8e33cfbf2 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripIntegrationTest.java @@ -24,7 +24,6 @@ import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.geometry.EncodedPolyline; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.graph_builder.module.ValidateAndInterpolateStopTimesForEachTrip; import org.opentripplanner.model.GenericLocation; import org.opentripplanner.model.StopTime; @@ -44,25 +43,27 @@ import org.opentripplanner.transit.model.network.grouppriority.TransitGroupPriorityService; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; +import org.opentripplanner.utils.time.ServiceDateUtils; /** * This tests that the feed for the Cobb County Flex service is processed correctly. This service * contains both flex zones but also scheduled stops. Inside the zone, passengers can get on or off * anywhere, so there it works more like a taxi. *

- * Read about the details at: https://www.cobbcounty.org/transportation/cobblinc/routes-and-schedules/flex + * This service is not being offered anymore, but we keep the test because others of the same + * type still exist. */ -class ScheduledDeviatedTripTest { +class ScheduledDeviatedTripIntegrationTest { static Graph graph; - static TransitModel transitModel; + static TimetableRepository timetableRepository; float delta = 0.01f; @Test void parseCobbCountyAsScheduledDeviatedTrip() { - var flexTrips = transitModel.getAllFlexTrips(); + var flexTrips = timetableRepository.getAllFlexTrips(); assertFalse(flexTrips.isEmpty()); assertEquals(72, flexTrips.size()); @@ -101,7 +102,7 @@ void calculateDirectFare() { var router = new FlexRouter( graph, - new DefaultTransitService(transitModel), + new DefaultTransitService(timetableRepository), FlexParameters.defaultValues(), OffsetDateTime.parse("2021-11-12T10:15:24-05:00").toInstant(), null, @@ -134,9 +135,9 @@ void calculateDirectFare() { */ @Test void flexTripInTransitMode() { - var feedId = transitModel.getFeedIds().iterator().next(); + var feedId = timetableRepository.getFeedIds().iterator().next(); - var serverContext = TestServerContext.createServerContext(graph, transitModel); + var serverContext = TestServerContext.createServerContext(graph, timetableRepository); // from zone 3 to zone 2 var from = GenericLocation.fromStopId("Transfer Point for Route 30", feedId, "cujv"); @@ -177,8 +178,8 @@ void flexTripInTransitMode() { */ @Test void shouldNotInterpolateFlexTimes() { - var feedId = transitModel.getFeedIds().iterator().next(); - var pattern = transitModel.getTripPatternForId(new FeedScopedId(feedId, "090z:0:01")); + var feedId = timetableRepository.getFeedIds().iterator().next(); + var pattern = timetableRepository.getTripPatternForId(new FeedScopedId(feedId, "090z:0:01")); assertEquals(3, pattern.numberOfStops()); @@ -192,7 +193,7 @@ void shouldNotInterpolateFlexTimes() { static void setup() { TestOtpModel model = FlexIntegrationTestData.cobbFlexGtfs(); graph = model.graph(); - transitModel = model.transitModel(); + timetableRepository = model.timetableRepository(); } private static List getItineraries( @@ -222,10 +223,6 @@ private static List getItineraries( return result.getItineraries(); } - private static NearbyStop getNearbyStop(FlexTrip trip) { - return getNearbyStop(trip, "nearby-stop"); - } - private static NearbyStop getNearbyStop(FlexTrip trip, String id) { // getStops() returns a set of stops and the order doesn't correspond to the stop times // of the trip @@ -248,8 +245,8 @@ private static NearbyStop getNearbyStop(FlexTrip trip, String id) { } private static FlexTrip getFlexTrip() { - var feedId = transitModel.getFeedIds().iterator().next(); + var feedId = timetableRepository.getFeedIds().iterator().next(); var tripId = new FeedScopedId(feedId, "a326c618-d42c-4bd1-9624-c314fbf8ecd8"); - return transitModel.getFlexTrip(tripId); + return timetableRepository.getFlexTrip(tripId); } } diff --git a/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java new file mode 100644 index 00000000000..4beefeb271e --- /dev/null +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java @@ -0,0 +1,62 @@ +package org.opentripplanner.ext.flex.trip; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.ext.flex.FlexStopTimesForTest.area; +import static org.opentripplanner.ext.flex.FlexStopTimesForTest.areaWithContinuousStopping; +import static org.opentripplanner.ext.flex.FlexStopTimesForTest.regularStop; +import static org.opentripplanner.ext.flex.FlexStopTimesForTest.regularStopWithContinuousStopping; + +import java.util.List; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.opentripplanner.model.StopTime; + +class ScheduledDeviatedTripTest { + + private static List> isScheduledDeviatedTripCases() { + return List.of( + List.of( + regularStop("10:10"), + area("10:20", "10:30"), + regularStop("10:40"), + area("10:50", "11:00") + ), + List.of( + regularStopWithContinuousStopping("10:10"), + area("10:20", "10:30"), + regularStopWithContinuousStopping("10:40"), + area("10:50", "11:00") + ) + ); + } + + @ParameterizedTest + @MethodSource("isScheduledDeviatedTripCases") + void isScheduledDeviatedTrip(List stopTimes) { + assertTrue(ScheduledDeviatedTrip.isScheduledDeviatedFlexTrip(stopTimes)); + } + + private static List> isNotScheduledDeviatedTripCases() { + return List.of( + List.of( + areaWithContinuousStopping("10:10"), + regularStop("10:20", "10:30"), + areaWithContinuousStopping("10:40"), + regularStop("10:50", "11:00") + ), + List.of( + regularStop("10:10"), + regularStop("10:20") + ) + ); + } + + @ParameterizedTest + @MethodSource("isNotScheduledDeviatedTripCases") + void isNotScheduledDeviatedTrip(List stopTimes) { + assertFalse(ScheduledDeviatedTrip.isScheduledDeviatedFlexTrip(stopTimes)); + } + + +} \ No newline at end of file diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledDrivingDurationTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledDrivingDurationTest.java similarity index 95% rename from src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledDrivingDurationTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledDrivingDurationTest.java index f19478af629..f6fd43595a9 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledDrivingDurationTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledDrivingDurationTest.java @@ -3,7 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.street.model._data.StreetModelForTest.V1; import static org.opentripplanner.street.model._data.StreetModelForTest.V2; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.time.Duration; import java.util.List; diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledTripTest.java b/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledTripTest.java similarity index 90% rename from src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledTripTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledTripTest.java index 8bc9d7c8919..b7f2706d25a 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledTripTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/flex/trip/UnscheduledTripTest.java @@ -3,34 +3,29 @@ 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.ext.flex.FlexStopTimesForTest.area; -import static org.opentripplanner.ext.flex.FlexStopTimesForTest.regularArrival; -import static org.opentripplanner.ext.flex.FlexStopTimesForTest.regularDeparture; import static org.opentripplanner.ext.flex.trip.UnscheduledTrip.isUnscheduledTrip; import static org.opentripplanner.ext.flex.trip.UnscheduledTripTest.TestCase.tc; import static org.opentripplanner.model.PickDrop.NONE; import static org.opentripplanner.model.StopTime.MISSING_VALUE; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.stream.Stream; -import javax.annotation.Nonnull; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.ext.flex.FlexStopTimesForTest; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.StopTime; -import org.opentripplanner.routing.graphfinder.NearbyStop; -import org.opentripplanner.transit.model._data.TransitModelForTest; -import org.opentripplanner.transit.model.site.AreaStop; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; class UnscheduledTripTest { @@ -42,7 +37,7 @@ class UnscheduledTripTest { private static final int T14_00 = TimeUtils.hm2time(14, 0); private static final int T15_00 = TimeUtils.hm2time(15, 0); - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final RegularStop REGULAR_STOP = TEST_MODEL.stop("stop").build(); @@ -51,35 +46,14 @@ class UnscheduledTripTest { @Nested class IsUnscheduledTrip { - private static final StopTime SCHEDULED_STOP = new StopTime(); - private static final StopTime UNSCHEDULED_STOP = new StopTime(); - private static final StopTime CONTINUOUS_PICKUP_STOP = new StopTime(); - private static final StopTime CONTINUOUS_DROP_OFF_STOP = new StopTime(); - - static { - var trip = TransitModelForTest.trip("flex").build(); - SCHEDULED_STOP.setArrivalTime(30); - SCHEDULED_STOP.setDepartureTime(60); - SCHEDULED_STOP.setStop(AREA_STOP); - SCHEDULED_STOP.setTrip(trip); - - UNSCHEDULED_STOP.setFlexWindowStart(30); - UNSCHEDULED_STOP.setFlexWindowEnd(300); - UNSCHEDULED_STOP.setStop(AREA_STOP); - UNSCHEDULED_STOP.setTrip(trip); - - CONTINUOUS_PICKUP_STOP.setFlexContinuousPickup(PickDrop.COORDINATE_WITH_DRIVER); - CONTINUOUS_PICKUP_STOP.setFlexWindowStart(30); - CONTINUOUS_PICKUP_STOP.setFlexWindowEnd(300); - CONTINUOUS_PICKUP_STOP.setStop(AREA_STOP); - CONTINUOUS_PICKUP_STOP.setTrip(trip); - - CONTINUOUS_DROP_OFF_STOP.setFlexContinuousDropOff(PickDrop.COORDINATE_WITH_DRIVER); - CONTINUOUS_DROP_OFF_STOP.setFlexWindowStart(100); - CONTINUOUS_DROP_OFF_STOP.setFlexWindowEnd(200); - CONTINUOUS_DROP_OFF_STOP.setStop(AREA_STOP); - CONTINUOUS_DROP_OFF_STOP.setTrip(trip); - } + private static final StopTime SCHEDULED_STOP = FlexStopTimesForTest.regularStop("10:00"); + private static final StopTime UNSCHEDULED_STOP = FlexStopTimesForTest.area("10:10", "10:20"); + private static final StopTime CONTINUOUS_PICKUP_STOP = FlexStopTimesForTest.regularStopWithContinuousPickup("10:30"); + private static final StopTime CONTINUOUS_DROP_OFF_STOP = FlexStopTimesForTest.regularStopWithContinuousDropOff("10:40"); + + // disallowed by the GTFS spec + private static final StopTime FLEX_AND_CONTINUOUS_PICKUP_STOP = FlexStopTimesForTest.areaWithContinuousPickup("10:50"); + private static final StopTime FLEX_AND_CONTINUOUS_DROP_OFF_STOP = FlexStopTimesForTest.areaWithContinuousDropOff("11:00"); static List> notUnscheduled() { return List.of( @@ -88,9 +62,9 @@ static List> notUnscheduled() { List.of(SCHEDULED_STOP, SCHEDULED_STOP), List.of(SCHEDULED_STOP, SCHEDULED_STOP, SCHEDULED_STOP), List.of(UNSCHEDULED_STOP, SCHEDULED_STOP, UNSCHEDULED_STOP), - List.of(UNSCHEDULED_STOP, CONTINUOUS_PICKUP_STOP), - List.of(UNSCHEDULED_STOP, CONTINUOUS_DROP_OFF_STOP), - List.of(CONTINUOUS_PICKUP_STOP, CONTINUOUS_DROP_OFF_STOP) + List.of(UNSCHEDULED_STOP, FLEX_AND_CONTINUOUS_PICKUP_STOP), + List.of(UNSCHEDULED_STOP, FLEX_AND_CONTINUOUS_DROP_OFF_STOP), + List.of(FLEX_AND_CONTINUOUS_PICKUP_STOP, FLEX_AND_CONTINUOUS_DROP_OFF_STOP) ); } @@ -107,7 +81,11 @@ static List> unscheduled() { List.of(SCHEDULED_STOP, UNSCHEDULED_STOP), List.of(UNSCHEDULED_STOP, UNSCHEDULED_STOP), List.of(UNSCHEDULED_STOP, UNSCHEDULED_STOP, UNSCHEDULED_STOP), - Collections.nCopies(10, UNSCHEDULED_STOP) + Collections.nCopies(10, UNSCHEDULED_STOP), + List.of(UNSCHEDULED_STOP, CONTINUOUS_PICKUP_STOP), + List.of(CONTINUOUS_PICKUP_STOP, UNSCHEDULED_STOP), + List.of(UNSCHEDULED_STOP, CONTINUOUS_DROP_OFF_STOP), + List.of(CONTINUOUS_DROP_OFF_STOP, UNSCHEDULED_STOP) ); } diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java b/application/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/application/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java similarity index 90% rename from src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index de6e600037c..b1468444076 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -1,7 +1,7 @@ package org.opentripplanner.ext.geocoder; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import static org.opentripplanner.transit.model.basic.TransitMode.BUS; import static org.opentripplanner.transit.model.basic.TransitMode.FERRY; @@ -21,7 +21,7 @@ import org.opentripplanner.ext.stopconsolidation.internal.DefaultStopConsolidationRepository; import org.opentripplanner.ext.stopconsolidation.internal.DefaultStopConsolidationService; import org.opentripplanner.model.FeedInfo; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -31,11 +31,11 @@ import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; class LuceneIndexTest { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); static final Agency BVG = Agency .of(id("bvg")) @@ -108,7 +108,7 @@ class LuceneIndexTest { @BeforeAll static void setup() { - var stopModel = TEST_MODEL.stopModelBuilder(); + var siteRepository = TEST_MODEL.siteRepositoryBuilder(); List .of( ALEXANDERPLATZ_BUS, @@ -122,29 +122,29 @@ static void setup() { MERIDIAN_N2, MERIDIAN_AVE ) - .forEach(stopModel::withRegularStop); + .forEach(siteRepository::withRegularStop); List .of(ALEXANDERPLATZ_STATION, BERLIN_HAUPTBAHNHOF_STATION, FIVE_POINTS_STATION) - .forEach(stopModel::withStation); - var transitModel = new TransitModel(stopModel.build(), new Deduplicator()); - transitModel.index(); - var transitService = new DefaultTransitService(transitModel) { + .forEach(siteRepository::withStation); + var timetableRepository = new TimetableRepository(siteRepository.build(), new Deduplicator()); + timetableRepository.index(); + var transitService = new DefaultTransitService(timetableRepository) { private final Multimap modes = ImmutableMultimap .builder() .putAll(WESTHAFEN, FERRY, BUS) .build(); @Override - public List getModesOfStopLocation(StopLocation stop) { - if (stop.getGtfsVehicleType() != null) { - return List.of(stop.getGtfsVehicleType()); + public List findTransitModes(StopLocation stop) { + if (stop.getVehicleType() != null) { + return List.of(stop.getVehicleType()); } else { return List.copyOf(modes.get(stop)); } } @Override - public Agency getAgencyForId(FeedScopedId id) { + public Agency getAgency(FeedScopedId id) { if (id.equals(BVG.getId())) { return BVG; } @@ -152,8 +152,8 @@ public Agency getAgencyForId(FeedScopedId id) { } @Override - public Set getRoutesForStop(StopLocation stop) { - return Set.of(TransitModelForTest.route("route1").withAgency(BVG).build()); + public Set findRoutes(StopLocation stop) { + return Set.of(TimetableRepositoryForTest.route("route1").withAgency(BVG).build()); } @Override @@ -171,7 +171,7 @@ public FeedInfo getFeedInfo(String feedId) { }; var stopConsolidationService = new DefaultStopConsolidationService( new DefaultStopConsolidationRepository(), - transitModel + timetableRepository ); index = new LuceneIndex(transitService, stopConsolidationService); mapper = new StopClusterMapper(transitService, stopConsolidationService); diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/StopClusterMapperTest.java b/application/src/ext-test/java/org/opentripplanner/ext/geocoder/StopClusterMapperTest.java similarity index 80% rename from src/ext-test/java/org/opentripplanner/ext/geocoder/StopClusterMapperTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/geocoder/StopClusterMapperTest.java index 578f7d4118f..fdff7787fb5 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/StopClusterMapperTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/geocoder/StopClusterMapperTest.java @@ -7,27 +7,27 @@ import org.opentripplanner.ext.stopconsolidation.internal.DefaultStopConsolidationRepository; import org.opentripplanner.ext.stopconsolidation.internal.DefaultStopConsolidationService; import org.opentripplanner.ext.stopconsolidation.model.ConsolidatedStopGroup; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; class StopClusterMapperTest { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final RegularStop STOP_A = TEST_MODEL.stop("A").build(); private static final RegularStop STOP_B = TEST_MODEL.stop("B").build(); private static final RegularStop STOP_C = TEST_MODEL.stop("C").build(); private static final List STOPS = List.of(STOP_A, STOP_B, STOP_C); - private static final StopModel STOP_MODEL = TEST_MODEL - .stopModelBuilder() + private static final SiteRepository SITE_REPOSITORY = TEST_MODEL + .siteRepositoryBuilder() .withRegularStops(STOPS) .build(); - private static final TransitModel TRANSIT_MODEL = new TransitModel( - STOP_MODEL, + private static final TimetableRepository TRANSIT_MODEL = new TimetableRepository( + SITE_REPOSITORY, new Deduplicator() ); private static final List LOCATIONS = STOPS diff --git a/src/ext-test/java/org/opentripplanner/ext/mapping/TransmodelMappingUtilTest.java b/application/src/ext-test/java/org/opentripplanner/ext/mapping/TransmodelMappingUtilTest.java similarity index 92% rename from src/ext-test/java/org/opentripplanner/ext/mapping/TransmodelMappingUtilTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/mapping/TransmodelMappingUtilTest.java index ce841be54a7..82023904f0f 100644 --- a/src/ext-test/java/org/opentripplanner/ext/mapping/TransmodelMappingUtilTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/mapping/TransmodelMappingUtilTest.java @@ -6,7 +6,7 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner.apis.transmodel.mapping.TransitIdMapper; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.organization.Agency; @@ -33,7 +33,7 @@ public void resolveFixedFeedIdTest() { Agency agency(String feedScope, int id) { // We use the test builder to make sure we get back an agency with all required fields - return TransitModelForTest + return TimetableRepositoryForTest .agency("Agency " + id) .copy() .withId(new FeedScopedId(feedScope, Integer.toString(id))) diff --git a/src/ext-test/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolverTest.java b/application/src/ext-test/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolverTest.java similarity index 85% rename from src/ext-test/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolverTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolverTest.java index 21d5a7f1696..80e5d1b153b 100644 --- a/src/ext-test/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolverTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolverTest.java @@ -3,8 +3,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.opentripplanner.framework.time.TimeUtils.time; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; +import static org.opentripplanner.utils.time.TimeUtils.time; import java.time.LocalDate; import java.util.List; @@ -23,21 +23,21 @@ import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.impl.TransitAlertServiceImpl; import org.opentripplanner.routing.services.TransitAlertService; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.transit.service.TransitService; class RealtimeResolverTest { - private final TransitModelForTest testModel = TransitModelForTest.of(); + private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of(); - private final Route route1 = TransitModelForTest.route("route1").build(); - private final Route route2 = TransitModelForTest.route("route2").build(); + private final Route route1 = TimetableRepositoryForTest.route("route1").build(); + private final Route route2 = TimetableRepositoryForTest.route("route2").build(); private final RegularStop stop1 = testModel.stop("stop1", 1, 1).build(); private final RegularStop stop2 = testModel.stop("stop2", 2, 1).build(); @@ -90,7 +90,7 @@ void testPopulateLegsWithRealtimeNonTransit() { .bus(route1, 1, time("11:20"), time("11:40"), Place.forStop(stop3)) .build(); - var model = new TransitModel(); + var model = new TimetableRepository(); model.index(); var transitService = new DefaultTransitService(model); @@ -129,9 +129,12 @@ void testPopulateLegsWithRealtimeKeepStaySeated() { private static TripPattern delay(TripPattern pattern1, int seconds) { var originalTimeTable = pattern1.getScheduledTimetable(); - var delayedTimetable = new Timetable(pattern1); var delayedTripTimes = delay(originalTimeTable.getTripTimes(0), seconds); - delayedTimetable.addTripTimes(delayedTripTimes); + var delayedTimetable = Timetable + .of() + .withTripPattern(pattern1) + .addTripTimes(delayedTripTimes) + .build(); return pattern1.copy().withScheduledTimeTable(delayedTimetable).build(); } @@ -161,23 +164,27 @@ private static TransitService makeTransitService( List patterns, LocalDate serviceDate ) { - var transitModel = new TransitModel(); + var timetableRepository = new TimetableRepository(); CalendarServiceData calendarServiceData = new CalendarServiceData(); patterns.forEach(pattern -> { - transitModel.addTripPattern(pattern.getId(), pattern); + timetableRepository.addTripPattern(pattern.getId(), pattern); var serviceCode = pattern.getScheduledTimetable().getTripTimes(0).getServiceCode(); - transitModel.getServiceCodes().put(pattern.getId(), serviceCode); + timetableRepository.getServiceCodes().put(pattern.getId(), serviceCode); calendarServiceData.putServiceDatesForServiceId(pattern.getId(), List.of(serviceDate)); }); - transitModel.updateCalendarServiceData(true, calendarServiceData, DataImportIssueStore.NOOP); - transitModel.index(); + timetableRepository.updateCalendarServiceData( + true, + calendarServiceData, + DataImportIssueStore.NOOP + ); + timetableRepository.index(); - return new DefaultTransitService(transitModel) { - final TransitAlertService alertService = new TransitAlertServiceImpl(transitModel); + return new DefaultTransitService(timetableRepository) { + final TransitAlertService alertService = new TransitAlertServiceImpl(timetableRepository); @Override public TransitAlertService getTransitAlertService() { diff --git a/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/EnumMapperTest.java b/application/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/EnumMapperTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/restapi/mapping/EnumMapperTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/EnumMapperTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMakerTest.java b/application/src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMakerTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMakerTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMakerTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiWalkStepTest.java b/application/src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiWalkStepTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiWalkStepTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiWalkStepTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/ApiRequestModeTest.java b/application/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/ApiRequestModeTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/restapi/parameter/ApiRequestModeTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/ApiRequestModeTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeSetTest.java b/application/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeSetTest.java similarity index 98% rename from src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeSetTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeSetTest.java index ad344713a74..7c3bf410192 100644 --- a/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeSetTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeSetTest.java @@ -231,7 +231,7 @@ void carHail() { @Test void carHailWithTransit() { var modeSet = new QualifiedModeSet("CAR_HAIL,BUS,RAIL"); - assertEquals(Set.of(COACH, BUS, RAIL), Set.copyOf(modeSet.getTransitModes())); + assertEquals(Set.of(BUS, RAIL), Set.copyOf(modeSet.getTransitModes())); assertEquals(WALK, modeSet.getRequestModes().directMode); assertEquals(CAR_HAILING, modeSet.getRequestModes().accessMode); diff --git a/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeTest.java b/application/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailingTest.java b/application/src/ext-test/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailingTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailingTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailingTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/ridehailing/FailingRideHailingService.java b/application/src/ext-test/java/org/opentripplanner/ext/ridehailing/FailingRideHailingService.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/ridehailing/FailingRideHailingService.java rename to application/src/ext-test/java/org/opentripplanner/ext/ridehailing/FailingRideHailingService.java diff --git a/src/ext-test/java/org/opentripplanner/ext/ridehailing/RideHailingAccessAdapterTest.java b/application/src/ext-test/java/org/opentripplanner/ext/ridehailing/RideHailingAccessAdapterTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/ridehailing/RideHailingAccessAdapterTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/ridehailing/RideHailingAccessAdapterTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/ridehailing/RideHailingAccessShifterTest.java b/application/src/ext-test/java/org/opentripplanner/ext/ridehailing/RideHailingAccessShifterTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/ridehailing/RideHailingAccessShifterTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/ridehailing/RideHailingAccessShifterTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/ridehailing/TestRideHailingService.java b/application/src/ext-test/java/org/opentripplanner/ext/ridehailing/TestRideHailingService.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/ridehailing/TestRideHailingService.java rename to application/src/ext-test/java/org/opentripplanner/ext/ridehailing/TestRideHailingService.java diff --git a/src/ext-test/java/org/opentripplanner/ext/ridehailing/configure/RideHailingServicesModuleTest.java b/application/src/ext-test/java/org/opentripplanner/ext/ridehailing/configure/RideHailingServicesModuleTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/ridehailing/configure/RideHailingServicesModuleTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/ridehailing/configure/RideHailingServicesModuleTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/ridehailing/service/uber/UberServiceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/ridehailing/service/uber/UberServiceTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/ridehailing/service/uber/UberServiceTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/ridehailing/service/uber/UberServiceTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceTest.java similarity index 95% rename from src/ext-test/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceTest.java index 761971bc56f..84161c00484 100644 --- a/src/ext-test/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceTest.java @@ -7,6 +7,7 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; +import org.opentripplanner.updater.vehicle_rental.datasources.params.RentalPickupType; import org.opentripplanner.updater.spi.HttpHeaders; class SmooveBikeRentalDataSourceTest { @@ -18,7 +19,8 @@ void makeStation() { "file:src/ext-test/resources/smoovebikerental/smoove.json", null, true, - HttpHeaders.empty() + HttpHeaders.empty(), + RentalPickupType.ALL ) ); assertTrue(source.update()); @@ -84,7 +86,8 @@ void makeStationWithoutOverloading() { "file:src/ext-test/resources/smoovebikerental/smoove.json", null, false, - HttpHeaders.empty() + HttpHeaders.empty(), + RentalPickupType.ALL ) ); assertTrue(source.update()); diff --git a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java b/application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java similarity index 51% rename from src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java index 7f389bc41ec..bcbc84fc4b8 100644 --- a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java @@ -5,17 +5,21 @@ import static org.opentripplanner.ext.stopconsolidation.TestStopConsolidationModel.STOP_D; import static org.opentripplanner.model.plan.PlanTestConstants.T11_05; import static org.opentripplanner.model.plan.PlanTestConstants.T11_12; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner.ext.stopconsolidation.internal.DefaultStopConsolidationRepository; import org.opentripplanner.ext.stopconsolidation.internal.DefaultStopConsolidationService; import org.opentripplanner.ext.stopconsolidation.model.ConsolidatedStopGroup; +import org.opentripplanner.ext.stopconsolidation.model.ConsolidatedStopLeg; import org.opentripplanner.model.fare.FareProduct; import org.opentripplanner.model.fare.FareProductUse; +import org.opentripplanner.model.plan.Leg; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; +import org.opentripplanner.model.plan.ScheduledTransitLeg; +import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.model.plan.TestItineraryBuilder; import org.opentripplanner.transit.model.basic.Money; @@ -32,21 +36,18 @@ class DecorateConsolidatedStopNamesTest { private static final List fpu = List.of( new FareProductUse("c1a04702-1fb6-32d4-ba02-483bf68111ed", fp) ); + private static final List GROUPS = List.of( + new ConsolidatedStopGroup(STOP_C.getId(), List.of(STOP_D.getId())) + ); + private static final Place PLACE_C = Place.forStop(STOP_C); @Test void changeNames() { - var transitModel = TestStopConsolidationModel.buildTransitModel(); - - var groups = List.of(new ConsolidatedStopGroup(STOP_C.getId(), List.of(STOP_D.getId()))); - var repo = new DefaultStopConsolidationRepository(); - repo.addGroups(groups); - - var service = new DefaultStopConsolidationService(repo, transitModel); - var filter = new DecorateConsolidatedStopNames(service); + var filter = defaultFilter(); var itinerary = TestItineraryBuilder - .newItinerary(Place.forStop(STOP_C)) - .bus(TestStopConsolidationModel.ROUTE, 1, T11_05, T11_12, Place.forStop(STOP_C)) + .newItinerary(PLACE_C) + .bus(TestStopConsolidationModel.ROUTE, 1, T11_05, T11_12, PLACE_C) .bus(1, T11_05, T11_12, PlanTestConstants.E) .bus(1, T11_05, T11_12, PlanTestConstants.F) .build(); @@ -62,4 +63,51 @@ void changeNames() { // Check that the fares were carried over assertEquals(fpu, updatedLeg.fareProducts()); } + + @Test + void removeTransferAtConsolidatedStop() { + final var filter = defaultFilter(); + + var itinerary = TestItineraryBuilder + .newItinerary(PLACE_C) + .bus(TestStopConsolidationModel.ROUTE, 1, T11_05, T11_12, PLACE_C) + .walk(1, PLACE_C) + .bus(1, T11_05, T11_12, PlanTestConstants.F) + .build(); + + filter.decorate(itinerary); + + var legs = itinerary.getLegs().stream().map(Leg::getClass).toList(); + assertEquals(List.of(ConsolidatedStopLeg.class, ScheduledTransitLeg.class), legs); + } + + @Test + void keepRegularTransfer() { + final var filter = defaultFilter(); + + var itinerary = TestItineraryBuilder + .newItinerary(PLACE_C) + .bus(TestStopConsolidationModel.ROUTE, 1, T11_05, T11_12, PLACE_C) + .walk(1, PlanTestConstants.E) + .bus(1, T11_05, T11_12, PlanTestConstants.F) + .build(); + + filter.decorate(itinerary); + + var legs = itinerary.getLegs().stream().map(Leg::getClass).toList(); + assertEquals( + List.of(ConsolidatedStopLeg.class, StreetLeg.class, ScheduledTransitLeg.class), + legs + ); + } + + private static DecorateConsolidatedStopNames defaultFilter() { + var timetableRepository = TestStopConsolidationModel.buildTimetableRepository(); + + var repo = new DefaultStopConsolidationRepository(); + repo.addGroups(GROUPS); + + var service = new DefaultStopConsolidationService(repo, timetableRepository); + return new DecorateConsolidatedStopNames(service); + } } diff --git a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationModuleTest.java b/application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationModuleTest.java similarity index 80% rename from src/ext-test/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationModuleTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationModuleTest.java index 0df495d63d0..91f62c319f6 100644 --- a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationModuleTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationModuleTest.java @@ -20,13 +20,13 @@ class StopConsolidationModuleTest { void replacePatterns() { var groups = List.of(new ConsolidatedStopGroup(STOP_D.getId(), List.of(STOP_B.getId()))); - var transitModel = TestStopConsolidationModel.buildTransitModel(); - transitModel.addTripPattern(PATTERN.getId(), PATTERN); + var timetableRepository = TestStopConsolidationModel.buildTimetableRepository(); + timetableRepository.addTripPattern(PATTERN.getId(), PATTERN); var repo = new DefaultStopConsolidationRepository(); - var module = new StopConsolidationModule(transitModel, repo, groups); + var module = new StopConsolidationModule(timetableRepository, repo, groups); module.buildGraph(); - var modifiedPattern = transitModel.getTripPatternForId(PATTERN.getId()); + var modifiedPattern = timetableRepository.getTripPatternForId(PATTERN.getId()); assertFalse(modifiedPattern.getRoutingTripPattern().getPattern().sameAs(PATTERN)); assertFalse(modifiedPattern.sameAs(PATTERN)); @@ -37,7 +37,7 @@ void replacePatterns() { .getStop(1); assertEquals(modifiedStop, STOP_D); - var patterns = List.copyOf(transitModel.getAllTripPatterns()); + var patterns = List.copyOf(timetableRepository.getAllTripPatterns()); var stops = patterns.stream().map(TripPattern::getStops).toList(); assertEquals(List.of(List.of(STOP_A, STOP_D, STOP_C)), stops); diff --git a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationParserTest.java b/application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationParserTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationParserTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationParserTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/TestStopConsolidationModel.java b/application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/TestStopConsolidationModel.java similarity index 63% rename from src/ext-test/java/org/opentripplanner/ext/stopconsolidation/TestStopConsolidationModel.java rename to application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/TestStopConsolidationModel.java index da0c1d6f61d..f763b520f5b 100644 --- a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/TestStopConsolidationModel.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/TestStopConsolidationModel.java @@ -1,9 +1,9 @@ package org.opentripplanner.ext.stopconsolidation; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.util.List; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; @@ -11,26 +11,26 @@ import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; class TestStopConsolidationModel { - private static final TransitModelForTest testModel = TransitModelForTest.of(); + private static final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of(); public static final RegularStop STOP_A = testModel.stop("A").withCoordinate(1, 1).build(); public static final RegularStop STOP_B = testModel.stop("B").withCoordinate(1.1, 1.1).build(); public static final RegularStop STOP_C = testModel.stop("C").withCoordinate(1.2, 1.2).build(); - public static final StopPattern STOP_PATTERN = TransitModelForTest.stopPattern( + public static final StopPattern STOP_PATTERN = TimetableRepositoryForTest.stopPattern( STOP_A, STOP_B, STOP_C ); static final String SECONDARY_FEED_ID = "secondary"; - static final Agency AGENCY = TransitModelForTest + static final Agency AGENCY = TimetableRepositoryForTest .agency("agency") .copy() .withId(new FeedScopedId(SECONDARY_FEED_ID, "agency")) .build(); - static final Route ROUTE = TransitModelForTest + static final Route ROUTE = TimetableRepositoryForTest .route(new FeedScopedId(SECONDARY_FEED_ID, "route-33")) .withAgency(AGENCY) .build(); @@ -45,9 +45,9 @@ class TestStopConsolidationModel { .withStopPattern(STOP_PATTERN) .build(); - static TransitModel buildTransitModel() { - var stopModelBuilder = testModel.stopModelBuilder(); - List.of(STOP_A, STOP_B, STOP_C, STOP_D).forEach(stopModelBuilder::withRegularStop); - return new TransitModel(stopModelBuilder.build(), new Deduplicator()); + static TimetableRepository buildTimetableRepository() { + var siteRepositoryBuilder = testModel.siteRepositoryBuilder(); + List.of(STOP_A, STOP_B, STOP_C, STOP_D).forEach(siteRepositoryBuilder::withRegularStop); + return new TimetableRepository(siteRepositoryBuilder.build(), new Deduplicator()); } } diff --git a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationRepositoryTest.java b/application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationRepositoryTest.java similarity index 91% rename from src/ext-test/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationRepositoryTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationRepositoryTest.java index ac5eb6d66e4..7bf87b4c89c 100644 --- a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationRepositoryTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationRepositoryTest.java @@ -2,7 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.util.List; import org.junit.jupiter.api.Test; diff --git a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationServiceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationServiceTest.java similarity index 80% rename from src/ext-test/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationServiceTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationServiceTest.java index b2fc356d111..1dd07a075ed 100644 --- a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationServiceTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationServiceTest.java @@ -3,7 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; class DefaultStopConsolidationServiceTest { @@ -11,7 +11,7 @@ class DefaultStopConsolidationServiceTest { void isActive() { var service = new DefaultStopConsolidationService( new DefaultStopConsolidationRepository(), - new TransitModel() + new TimetableRepository() ); assertFalse(service.isActive()); } diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java similarity index 97% rename from src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java index 51e1738ff6c..3a057182a67 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java @@ -3,11 +3,11 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromPath; +import static org.opentripplanner.utils.text.MarkdownFormatter.HEADER_4; import java.io.File; import org.junit.jupiter.api.Test; diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesResourceTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesResourceTest.java similarity index 85% rename from src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesResourceTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesResourceTest.java index ff9509a8474..be379fb6fa6 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesResourceTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesResourceTest.java @@ -8,7 +8,7 @@ import org.opentripplanner.TestServerContext; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.test.support.HttpForTest; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; class VectorTilesResourceTest { @@ -17,7 +17,7 @@ void tileJson() { // the Grizzly request is awful to instantiate, using Mockito var grizzlyRequest = Mockito.mock(Request.class); var resource = new VectorTilesResource( - TestServerContext.createServerContext(new Graph(), new TransitModel()), + TestServerContext.createServerContext(new Graph(), new TimetableRepository()), grizzlyRequest, "default" ); diff --git a/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/LayerFiltersTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/LayerFiltersTest.java new file mode 100644 index 00000000000..871a4b4c7da --- /dev/null +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/LayerFiltersTest.java @@ -0,0 +1,42 @@ +package org.opentripplanner.ext.vectortiles.layers; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.time.LocalDate; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.opentripplanner.transit.model._data.PatternTestModel; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.site.RegularStop; + +class LayerFiltersTest { + + private static final RegularStop STOP = TimetableRepositoryForTest.of().stop("1").build(); + private static final LocalDate DATE = LocalDate.of(2024, 9, 5); + private static final TripPattern PATTERN = PatternTestModel.pattern(); + + @Test + void includeStopWithinServiceWeek() { + var predicate = LayerFilters.buildCurrentServiceWeekPredicate( + s -> List.of(PATTERN), + trip -> List.of(DATE), + () -> DATE + ); + + assertTrue(predicate.test(STOP)); + } + + @Test + void excludeOutsideServiceWeek() { + var inThreeWeeks = DATE.plusDays(21); + var predicate = LayerFilters.buildCurrentServiceWeekPredicate( + s -> List.of(PATTERN), + trip -> List.of(inThreeWeeks), + () -> DATE + ); + + assertFalse(predicate.test(STOP)); + } +} diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/TestTransitService.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/TestTransitService.java similarity index 52% rename from src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/TestTransitService.java rename to application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/TestTransitService.java index d187b611ef3..37ea737626f 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/TestTransitService.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/TestTransitService.java @@ -1,23 +1,23 @@ package org.opentripplanner.ext.vectortiles.layers; import java.util.Set; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; public class TestTransitService extends DefaultTransitService { - public TestTransitService(TransitModel transitModel) { - super(transitModel); + public TestTransitService(TimetableRepository timetableRepository) { + super(timetableRepository); } @Override - public Set getRoutesForStop(StopLocation stop) { + public Set findRoutes(StopLocation stop) { return Set.of( - TransitModelForTest.route("1").withMode(TransitMode.RAIL).withGtfsType(100).build() + TimetableRepositoryForTest.route("1").withMode(TransitMode.RAIL).withGtfsType(100).build() ); } } diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapperTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapperTest.java similarity index 68% rename from src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapperTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapperTest.java index 5387df91bca..a33a8b55286 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapperTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapperTest.java @@ -6,20 +6,22 @@ import java.util.List; import java.util.Locale; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.site.AreaStop; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; class AreaStopPropertyMapperTest { - private static final TransitModelForTest MODEL = new TransitModelForTest(StopModel.of()); + private static final TimetableRepositoryForTest MODEL = new TimetableRepositoryForTest( + SiteRepository.of() + ); private static final AreaStop STOP = MODEL.areaStop("123").build(); - private static final Route ROUTE_WITH_COLOR = TransitModelForTest + private static final Route ROUTE_WITH_COLOR = TimetableRepositoryForTest .route("123") .withColor("ffffff") .build(); - private static final Route ROUTE_WITHOUT_COLOR = TransitModelForTest.route("456").build(); + private static final Route ROUTE_WITHOUT_COLOR = TimetableRepositoryForTest.route("456").build(); @Test void map() { diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopsLayerBuilderTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopsLayerBuilderTest.java similarity index 78% rename from src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopsLayerBuilderTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopsLayerBuilderTest.java index 2e6c4e16c40..cf5683b49b5 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopsLayerBuilderTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopsLayerBuilderTest.java @@ -15,9 +15,9 @@ import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.StopModelBuilder; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; +import org.opentripplanner.transit.service.TimetableRepository; class AreaStopsLayerBuilderTest { @@ -46,25 +46,25 @@ class AreaStopsLayerBuilderTest { .layers() .getFirst(); - private final StopModelBuilder stopModelBuilder = StopModel.of(); + private final SiteRepositoryBuilder siteRepositoryBuilder = SiteRepository.of(); - private final AreaStop AREA_STOP = stopModelBuilder + private final AreaStop AREA_STOP = siteRepositoryBuilder .areaStop(ID) .withName(NAME) .withGeometry(Polygons.BERLIN) .build(); - private final TransitModel transitModel = new TransitModel( - stopModelBuilder.withAreaStop(AREA_STOP).build(), + private final TimetableRepository timetableRepository = new TimetableRepository( + siteRepositoryBuilder.withAreaStop(AREA_STOP).build(), new Deduplicator() ); @Test void getAreaStops() { - transitModel.index(); + timetableRepository.index(); var subject = new AreaStopsLayerBuilder( - new DefaultTransitService(transitModel), + new DefaultTransitService(timetableRepository), LAYER_CONFIG, Locale.ENGLISH ); diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapperTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapperTest.java similarity index 68% rename from src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapperTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapperTest.java index da85285954d..f3b1c9e2126 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapperTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapperTest.java @@ -1,7 +1,7 @@ package org.opentripplanner.ext.vectortiles.layers.stations; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.util.HashMap; import java.util.Locale; @@ -9,20 +9,20 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.ext.vectortiles.layers.TestTransitService; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.site.Station; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; public class DigitransitStationPropertyMapperTest { @Test void map() { var deduplicator = new Deduplicator(); - var transitModel = new TransitModel(new StopModel(), deduplicator); - transitModel.index(); - var transitService = new TestTransitService(transitModel); + var timetableRepository = new TimetableRepository(new SiteRepository(), deduplicator); + timetableRepository.index(); + var transitService = new TestTransitService(timetableRepository); var mapper = DigitransitStationPropertyMapper.create(transitService, Locale.US); @@ -32,7 +32,7 @@ void map() { .withName(I18NString.of("A station")) .build(); - TransitModelForTest.of().stop("stop-1").withParentStation(station).build(); + TimetableRepositoryForTest.of().stop("stop-1").withParentStation(station).build(); Map map = new HashMap<>(); mapper.map(station).forEach(o -> map.put(o.key(), o.value())); diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/RealtimeStopsLayerTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/RealtimeStopsLayerTest.java similarity index 84% rename from src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/RealtimeStopsLayerTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/RealtimeStopsLayerTest.java index 796b2a204da..0db19baf6e5 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/RealtimeStopsLayerTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/RealtimeStopsLayerTest.java @@ -1,8 +1,8 @@ package org.opentripplanner.ext.vectortiles.layers.stops; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.time.TimeUtils.time; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; +import static org.opentripplanner.utils.time.TimeUtils.time; import java.time.ZonedDateTime; import java.util.HashMap; @@ -21,14 +21,14 @@ import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.impl.TransitAlertServiceImpl; import org.opentripplanner.routing.services.TransitAlertService; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; public class RealtimeStopsLayerTest { @@ -40,7 +40,7 @@ public void setUp() { var name = I18NString.of("name"); var desc = I18NString.of("desc"); stop = - StopModel + SiteRepository .of() .regularStop(new FeedScopedId("F", "name")) .withName(name) @@ -49,7 +49,7 @@ public void setUp() { .withTimeZone(ZoneIds.HELSINKI) .build(); stop2 = - StopModel + SiteRepository .of() .regularStop(new FeedScopedId("F", "name")) .withName(name) @@ -62,11 +62,11 @@ public void setUp() { @Test void realtimeStopLayer() { var deduplicator = new Deduplicator(); - var transitModel = new TransitModel(new StopModel(), deduplicator); - transitModel.initTimeZone(ZoneIds.HELSINKI); - transitModel.index(); - var transitService = new DefaultTransitService(transitModel) { - final TransitAlertService alertService = new TransitAlertServiceImpl(transitModel); + var timetableRepository = new TimetableRepository(new SiteRepository(), deduplicator); + timetableRepository.initTimeZone(ZoneIds.HELSINKI); + timetableRepository.index(); + var transitService = new DefaultTransitService(timetableRepository) { + final TransitAlertService alertService = new TransitAlertServiceImpl(timetableRepository); @Override public TransitAlertService getTransitAlertService() { @@ -74,7 +74,7 @@ public TransitAlertService getTransitAlertService() { } }; - Route route = TransitModelForTest.route("route").build(); + Route route = TimetableRepositoryForTest.route("route").build(); var itinerary = newItinerary(Place.forStop(stop), time("11:00")) .bus(route, 1, time("11:05"), time("11:20"), Place.forStop(stop2)) .build(); diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerTest.java similarity index 80% rename from src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerTest.java index 7760eee13b8..d5d12576a1a 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerTest.java @@ -1,7 +1,7 @@ package org.opentripplanner.ext.vectortiles.layers.stops; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.util.HashMap; import java.util.Locale; @@ -16,8 +16,8 @@ import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; public class StopsLayerTest { @@ -47,7 +47,7 @@ public class StopsLayerTest { .withCoordinate(WgsCoordinate.GREENWICH) .withName(I18NString.of("A Station")) .build(); - private static final RegularStop STOP = StopModel + private static final RegularStop STOP = SiteRepository .of() .regularStop(new FeedScopedId("F", "name")) .withName(NAME_TRANSLATIONS) @@ -59,9 +59,9 @@ public class StopsLayerTest { @Test public void digitransitStopPropertyMapperTest() { var deduplicator = new Deduplicator(); - var transitModel = new TransitModel(new StopModel(), deduplicator); - transitModel.index(); - var transitService = new TestTransitService(transitModel); + var timetableRepository = new TimetableRepository(new SiteRepository(), deduplicator); + timetableRepository.index(); + var transitService = new TestTransitService(timetableRepository); DigitransitStopPropertyMapper mapper = DigitransitStopPropertyMapper.create( transitService, @@ -81,9 +81,9 @@ public void digitransitStopPropertyMapperTest() { @Test public void digitransitStopPropertyMapperTranslationTest() { var deduplicator = new Deduplicator(); - var transitModel = new TransitModel(new StopModel(), deduplicator); - transitModel.index(); - var transitService = new DefaultTransitService(transitModel); + var timetableRepository = new TimetableRepository(new SiteRepository(), deduplicator); + timetableRepository.index(); + var transitService = new DefaultTransitService(timetableRepository); DigitransitStopPropertyMapper mapper = DigitransitStopPropertyMapper.create( transitService, diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java similarity index 85% rename from src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java index 1beca037457..b8a88c11703 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java @@ -19,19 +19,20 @@ import org.opentripplanner.framework.i18n.TranslatedString; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.inspector.vector.LayerParameters; -import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingGroup; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingState; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingService; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingGroup; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingState; import org.opentripplanner.standalone.config.routerconfig.VectorTileConfig; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; public class VehicleParkingGroupsLayerTest { - private static final FeedScopedId ID = TransitModelForTest.id("id"); + private static final FeedScopedId ID = TimetableRepositoryForTest.id("id"); private VehicleParkingGroup vehicleParkingGroup; private VehicleParking vehicleParking; @@ -90,9 +91,8 @@ public void setUp() { @Test public void vehicleParkingGroupGeometryTest() { - Graph graph = new Graph(); - VehicleParkingService service = graph.getVehicleParkingService(); - service.updateVehicleParking(List.of(vehicleParking), List.of()); + var repository = new DefaultVehicleParkingRepository(); + repository.updateVehicleParking(List.of(vehicleParking), List.of()); var config = """ @@ -116,7 +116,7 @@ public void vehicleParkingGroupGeometryTest() { var tiles = VectorTileConfig.mapVectorTilesParameters(nodeAdapter, "vectorTiles"); assertEquals(1, tiles.layers().size()); var builder = new VehicleParkingGroupsLayerBuilderWithPublicGeometry( - graph, + new DefaultVehicleParkingService(repository), tiles.layers().get(0), Locale.US ); @@ -171,11 +171,11 @@ private static class VehicleParkingGroupsLayerBuilderWithPublicGeometry extends VehicleParkingGroupsLayerBuilder { public VehicleParkingGroupsLayerBuilderWithPublicGeometry( - Graph graph, + VehicleParkingService service, LayerParameters layerParameters, Locale locale ) { - super(graph, layerParameters, locale); + super(service, layerParameters, locale); } @Override diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerTest.java similarity index 89% rename from src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerTest.java index 14e96e2aa28..ae4386e9dd6 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerTest.java @@ -23,19 +23,19 @@ import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.TranslatedString; import org.opentripplanner.model.calendar.openinghours.OpeningHoursCalendarService; -import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingState; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingService; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingState; import org.opentripplanner.standalone.config.routerconfig.VectorTileConfig; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; public class VehicleParkingsLayerTest { - private static final FeedScopedId ID = TransitModelForTest.id("id"); + private static final FeedScopedId ID = TimetableRepositoryForTest.id("id"); private VehicleParking vehicleParking; @@ -86,9 +86,8 @@ public void setUp() { @Test public void vehicleParkingGeometryTest() { - Graph graph = new Graph(); - VehicleParkingService service = graph.getVehicleParkingService(); - service.updateVehicleParking(List.of(vehicleParking), List.of()); + var repo = new DefaultVehicleParkingRepository(); + repo.updateVehicleParking(List.of(vehicleParking), List.of()); var config = """ @@ -111,7 +110,7 @@ public void vehicleParkingGeometryTest() { var nodeAdapter = newNodeAdapterForTest(config); var tiles = VectorTileConfig.mapVectorTilesParameters(nodeAdapter, "vectorTiles"); assertEquals(1, tiles.layers().size()); - var builder = new VehicleParkingsLayerBuilder(graph, tiles.layers().getFirst(), Locale.US); + var builder = new VehicleParkingsLayerBuilder(new DefaultVehicleParkingService(repo), tiles.layers().getFirst(), Locale.US); List geometries = builder.getGeometries(new Envelope(0.99, 1.01, 1.99, 2.01)); diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/VehicleRentalLayerTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/VehicleRentalLayerTest.java similarity index 99% rename from src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/VehicleRentalLayerTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/VehicleRentalLayerTest.java index 984d4927041..45a4ab30744 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/VehicleRentalLayerTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/VehicleRentalLayerTest.java @@ -8,7 +8,6 @@ import java.util.HashMap; import java.util.Locale; import java.util.Map; -import javax.annotation.Nonnull; import org.junit.jupiter.api.Test; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.framework.i18n.TranslatedString; @@ -114,7 +113,6 @@ public void realtimeStation() { assertEquals(3, map.get("spacesAvailable")); } - @Nonnull private static RentalVehicleType vehicleType(RentalFormFactor formFactor) { return new RentalVehicleType( new FeedScopedId("1", formFactor.name()), diff --git a/src/ext-test/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdaterTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdaterTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdaterTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdaterTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdaterTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdaterTest.java similarity index 96% rename from src/ext-test/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdaterTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdaterTest.java index 569db85f33b..66e0a0fda9a 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdaterTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdaterTest.java @@ -8,7 +8,7 @@ import java.time.Duration; import java.util.Locale; import org.junit.jupiter.api.Test; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingState; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingState; import org.opentripplanner.test.support.ResourceLoader; import org.opentripplanner.transit.model.basic.Locales; import org.opentripplanner.transit.model.framework.FeedScopedId; diff --git a/src/ext-test/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdaterTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdaterTest.java similarity index 98% rename from src/ext-test/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdaterTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdaterTest.java index 2226a988d20..fd584951586 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdaterTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdaterTest.java @@ -14,7 +14,7 @@ import org.opentripplanner._support.time.ZoneIds; import org.opentripplanner.model.calendar.openinghours.OpeningHoursCalendarService; import org.opentripplanner.model.calendar.openinghours.OsmOpeningHoursSupport; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingState; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingState; import org.opentripplanner.test.support.ResourceLoader; import org.opentripplanner.transit.model.framework.Deduplicator; diff --git a/src/ext-test/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdaterTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdaterTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdaterTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdaterTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterTest.java similarity index 100% rename from src/ext-test/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/VehicleRentalServiceDirectoryConfigDocTest.java b/application/src/ext-test/java/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/VehicleRentalServiceDirectoryConfigDocTest.java similarity index 97% rename from src/ext-test/java/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/VehicleRentalServiceDirectoryConfigDocTest.java rename to application/src/ext-test/java/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/VehicleRentalServiceDirectoryConfigDocTest.java index 2afcd95949c..06d75073029 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/VehicleRentalServiceDirectoryConfigDocTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/VehicleRentalServiceDirectoryConfigDocTest.java @@ -4,13 +4,13 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceJsonExample; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersDetails; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersTable; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; +import static org.opentripplanner.utils.text.MarkdownFormatter.HEADER_4; import java.io.File; import org.junit.jupiter.api.Test; diff --git a/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-invalid-test-gtfs/emissions.txt b/application/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-invalid-test-gtfs/emissions.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-invalid-test-gtfs/emissions.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-invalid-test-gtfs/emissions.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-invalid-test-gtfs/feed_info.txt b/application/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-invalid-test-gtfs/feed_info.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-invalid-test-gtfs/feed_info.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-invalid-test-gtfs/feed_info.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-missing-test-gtfs.zip b/application/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-missing-test-gtfs.zip similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-missing-test-gtfs.zip rename to application/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-missing-test-gtfs.zip diff --git a/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-missing-test-gtfs/feed_info.txt b/application/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-missing-test-gtfs/feed_info.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-missing-test-gtfs/feed_info.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-missing-test-gtfs/feed_info.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-test-gtfs.zip b/application/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-test-gtfs.zip similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-test-gtfs.zip rename to application/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-test-gtfs.zip diff --git a/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-test-gtfs/emissions.txt b/application/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-test-gtfs/emissions.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-test-gtfs/emissions.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-test-gtfs/emissions.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-test-gtfs/feed_info.txt b/application/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-test-gtfs/feed_info.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-test-gtfs/feed_info.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/emissions/emissions-test-gtfs/feed_info.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/agency.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/agency.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/agency.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/agency.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/booking_rules.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/booking_rules.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/booking_rules.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/booking_rules.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/calendar.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/calendar.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/calendar.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/calendar.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/calendar_attributes.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/calendar_attributes.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/calendar_attributes.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/calendar_attributes.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/calendar_dates.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/calendar_dates.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/calendar_dates.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/calendar_dates.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/feed_info.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/feed_info.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/feed_info.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/feed_info.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/location_groups.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/location_groups.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/location_groups.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/location_groups.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/locations.geojson b/application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/locations.geojson similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/locations.geojson rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/locations.geojson diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/routes.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/routes.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/routes.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/routes.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/shapes.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/shapes.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/shapes.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/shapes.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/stop_times.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/stop_times.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/stop_times.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/stop_times.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/stops.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/stops.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/stops.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/stops.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/trips.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/trips.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/trips.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/aspen-flex-on-demand.gtfs/trips.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/cobb-county.filtered.osm.pbf b/application/src/ext-test/resources/org/opentripplanner/ext/flex/cobb-county.filtered.osm.pbf similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/cobb-county.filtered.osm.pbf rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/cobb-county.filtered.osm.pbf diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-bus-30-only.gtfs.zip b/application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-bus-30-only.gtfs.zip similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-bus-30-only.gtfs.zip rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-bus-30-only.gtfs.zip diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/agency.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/agency.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/agency.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/agency.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/booking_rules.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/booking_rules.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/booking_rules.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/booking_rules.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/calendar.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/calendar.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/calendar.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/calendar.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/fare_attributes.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/fare_attributes.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/fare_attributes.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/fare_attributes.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/fare_rules.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/fare_rules.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/fare_rules.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/fare_rules.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/feed_info.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/feed_info.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/feed_info.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/feed_info.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/location_groups.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/location_groups.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/location_groups.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/location_groups.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/locations.geojson b/application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/locations.geojson similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/locations.geojson rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/locations.geojson diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/routes.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/routes.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/routes.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/routes.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/shapes.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/shapes.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/shapes.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/shapes.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/stop_times.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/stop_times.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/stop_times.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/stop_times.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/stops.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/stops.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/stops.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/stops.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/trips.txt b/application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/trips.txt similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/trips.txt rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/trips.txt diff --git a/src/ext-test/resources/org/opentripplanner/ext/flex/marta-bus-856-only.gtfs.zip b/application/src/ext-test/resources/org/opentripplanner/ext/flex/marta-bus-856-only.gtfs.zip similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/flex/marta-bus-856-only.gtfs.zip rename to application/src/ext-test/resources/org/opentripplanner/ext/flex/marta-bus-856-only.gtfs.zip diff --git a/src/ext-test/resources/org/opentripplanner/ext/stopconsolidation/consolidated-stops.csv b/application/src/ext-test/resources/org/opentripplanner/ext/stopconsolidation/consolidated-stops.csv similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/stopconsolidation/consolidated-stops.csv rename to application/src/ext-test/resources/org/opentripplanner/ext/stopconsolidation/consolidated-stops.csv diff --git a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/bikeep/bikeep.json b/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/bikeep/bikeep.json similarity index 73% rename from src/ext-test/resources/org/opentripplanner/ext/vehicleparking/bikeep/bikeep.json rename to application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/bikeep/bikeep.json index 6f164077ee1..0ffa202bd11 100644 --- a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/bikeep/bikeep.json +++ b/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/bikeep/bikeep.json @@ -5,22 +5,14 @@ "type": "Feature", "geometry": { "type": "Point", - "coordinates": [ - 4.996344, - 60.405932 - ] + "coordinates": [4.996344, 60.405932] }, "properties": { "code": "224121", "label": "Ågotnes Terminal", "name": "#224121 Ågotnes Terminal", "address": "Ågotnes", - "tags": [ - "FREE", - "BIKE", - "PRIVATE", - "BOOKABLE" - ], + "tags": ["FREE", "BIKE", "PRIVATE", "BOOKABLE"], "icon": { "png": "", "png2x": "", @@ -38,22 +30,14 @@ "type": "Feature", "geometry": { "type": "Point", - "coordinates": [ - 10.666802, - 59.436443 - ] + "coordinates": [10.666802, 59.436443] }, "properties": { "code": "226261", "label": "Gågata Østre", "name": "#226261 Gågata Østre", "address": "Dronningens gate, Moss", - "tags": [ - "FREE", - "PRIVATE", - "BOOKABLE", - "BIKE" - ], + "tags": ["FREE", "PRIVATE", "BOOKABLE", "BIKE"], "icon": { "png": "", "png2x": "", @@ -71,22 +55,14 @@ "type": "Feature", "geometry": { "type": "Point", - "coordinates": [ - 10.661444, - 59.435401 - ] + "coordinates": [10.661444, 59.435401] }, "properties": { "code": "226259", "label": "Gågata Vestre", "name": "#226259 Gågata Vestre", "address": "Dronningens gate, Moss", - "tags": [ - "BIKE", - "FREE", - "PRIVATE", - "BOOKABLE" - ], + "tags": ["BIKE", "FREE", "PRIVATE", "BOOKABLE"], "icon": { "png": "", "png2x": "", @@ -104,22 +80,14 @@ "type": "Feature", "geometry": { "type": "Point", - "coordinates": [ - 10.774958, - 59.946535 - ] + "coordinates": [10.774958, 59.946535] }, "properties": { "code": "223443", "label": "Storo Storsenter", "name": "#223443 Storo Storsenter", "address": "Norway", - "tags": [ - "BIKE", - "PRIVATE", - "BOOKABLE", - "FREE" - ], + "tags": ["BIKE", "PRIVATE", "BOOKABLE", "FREE"], "icon": { "png": "https://assets.bikeep.com/locations/icons/bikeep.png", "png2x": "https://assets.bikeep.com/locations/icons/bikeep@2x.png", @@ -137,23 +105,14 @@ "type": "Feature", "geometry": { "type": "Point", - "coordinates": [ - 10.501222, - 59.914578 - ] + "coordinates": [10.501222, 59.914578] }, "properties": { "code": "224519", "label": "Kolsås Sykkelhotell", "name": "#224519 Kolsås Sykkelhotell", "address": "Norway", - "tags": [ - "PRIVATE", - "FREE", - "BOOKABLE", - "BIKE_HOUSE", - "BIKE" - ], + "tags": ["PRIVATE", "FREE", "BOOKABLE", "BIKE_HOUSE", "BIKE"], "icon": { "png": "https://assets.bikeep.com/locations/icons/bikeep.png", "png2x": "https://assets.bikeep.com/locations/icons/bikeep@2x.png", @@ -171,22 +130,14 @@ "type": "Feature", "geometry": { "type": "Point", - "coordinates": [ - 10.663716, - 59.435539 - ] + "coordinates": [10.663716, 59.435539] }, "properties": { "code": "226260", "label": "Gågata Midtre", "name": "#226260 Gågata Midtre", "address": "Dronningens gate, Moss", - "tags": [ - "FREE", - "BOOKABLE", - "PRIVATE", - "BIKE" - ], + "tags": ["FREE", "BOOKABLE", "PRIVATE", "BIKE"], "icon": { "png": "", "png2x": "", @@ -204,22 +155,14 @@ "type": "Feature", "geometry": { "type": "Point", - "coordinates": [ - 5.320344, - 60.463246 - ] + "coordinates": [5.320344, 60.463246] }, "properties": { "code": "226266", "label": "Åsane Sykkelhus", "name": "#226266 Åsane Sykkelhus", "address": "Åsane terminal", - "tags": [ - "BOOKABLE", - "BIKE", - "FREE", - "PRIVATE" - ], + "tags": ["BOOKABLE", "BIKE", "FREE", "PRIVATE"], "icon": { "png": "", "png2x": "", @@ -237,22 +180,14 @@ "type": "Feature", "geometry": { "type": "Point", - "coordinates": [ - 10.521137, - 59.889181 - ] + "coordinates": [10.521137, 59.889181] }, "properties": { "code": "224112", "label": "Sandvika Storsenter Kjørbokollen", "name": "#224112 Sandvika Storsenter Kjørbokollen", "address": "Brodtkorbsgate 7, Sandvika", - "tags": [ - "PRIVATE", - "FREE", - "BIKE", - "BOOKABLE" - ], + "tags": ["PRIVATE", "FREE", "BIKE", "BOOKABLE"], "icon": { "png": "", "png2x": "", @@ -270,22 +205,14 @@ "type": "Feature", "geometry": { "type": "Point", - "coordinates": [ - 10.520496, - 59.887412 - ] + "coordinates": [10.520496, 59.887412] }, "properties": { "code": "224111", "label": "Sandvika Storsenter Nytorget", "name": "#224111 Sandvika Storsenter Nytorget", "address": "Sandviksveien 176, Sandvika", - "tags": [ - "BIKE", - "BOOKABLE", - "PRIVATE", - "FREE" - ], + "tags": ["BIKE", "BOOKABLE", "PRIVATE", "FREE"], "icon": { "png": "", "png2x": "", @@ -300,4 +227,4 @@ } } ] -} \ No newline at end of file +} diff --git a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/bikely/bikely.json b/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/bikely/bikely.json similarity index 99% rename from src/ext-test/resources/org/opentripplanner/ext/vehicleparking/bikely/bikely.json rename to application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/bikely/bikely.json index a3e1e9e2e57..172220650aa 100644 --- a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/bikely/bikely.json +++ b/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/bikely/bikely.json @@ -321,4 +321,4 @@ "id": 26 } ] -} \ No newline at end of file +} diff --git a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/facilities.json b/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/facilities.json similarity index 77% rename from src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/facilities.json rename to application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/facilities.json index 0bca41f3bf6..c9305c556c3 100644 --- a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/facilities.json +++ b/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/facilities.json @@ -15,66 +15,25 @@ } }, "bbox": [ - 24.80034603935215, - 60.17480881241633, - 24.80808017426278, + 24.80034603935215, 60.17480881241633, 24.80808017426278, 60.17714686717807 ], "type": "Polygon", "coordinates": [ [ - [ - 24.805922082319398, - 60.17671175792864 - ], - [ - 24.80745024472255, - 60.176920611087695 - ], - [ - 24.80808017426278, - 60.17588213365369 - ], - [ - 24.800591011951123, - 60.17480881241633 - ], - [ - 24.80034603935215, - 60.17519753280732 - ], - [ - 24.80281909606564, - 60.17555724011572 - ], - [ - 24.802492465933668, - 60.17611419849894 - ], - [ - 24.803798986461572, - 60.176299849194635 - ], - [ - 24.803460690967746, - 60.176874199389374 - ], - [ - 24.805478798568853, - 60.17714686717807 - ], - [ - 24.805805428700822, - 60.17661313236411 - ], - [ - 24.805945413043094, - 60.17663633840593 - ], - [ - 24.805922082319398, - 60.17671175792864 - ] + [24.805922082319398, 60.17671175792864], + [24.80745024472255, 60.176920611087695], + [24.80808017426278, 60.17588213365369], + [24.800591011951123, 60.17480881241633], + [24.80034603935215, 60.17519753280732], + [24.80281909606564, 60.17555724011572], + [24.802492465933668, 60.17611419849894], + [24.803798986461572, 60.176299849194635], + [24.803460690967746, 60.176874199389374], + [24.805478798568853, 60.17714686717807], + [24.805805428700822, 60.17661313236411], + [24.805945413043094, 60.17663633840593], + [24.805922082319398, 60.17671175792864] ] ] }, @@ -87,9 +46,7 @@ "builtCapacity": { "CAR": 1365 }, - "usages": [ - "PARK_AND_RIDE" - ], + "usages": ["PARK_AND_RIDE"], "services": [ "LIGHTING", "COVERED", @@ -97,9 +54,7 @@ "PAYMENT_AT_GATE", "ENGINE_IGNITION_AID" ], - "authenticationMethods": [ - "HSL_TICKET" - ], + "authenticationMethods": ["HSL_TICKET"], "pricing": [ { "usage": "PARK_AND_RIDE", @@ -211,9 +166,7 @@ "en": "1. tunti 2 € / 60 min, seuraavat tunnit 1 € / 30 min" }, "url": null, - "paymentMethods": [ - "DEBIT_CARD" - ] + "paymentMethods": ["DEBIT_CARD"] }, "openingHours": { "openNow": true, @@ -264,38 +217,18 @@ } }, "bbox": [ - 24.977034456273202, - 60.186015498799264, - 24.981894619008195, + 24.977034456273202, 60.186015498799264, 24.981894619008195, 60.18802910674705 ], "type": "Polygon", "coordinates": [ [ - [ - 24.977731830617074, - 60.18802910674705 - ], - [ - 24.977034456273202, - 60.186674268899424 - ], - [ - 24.979169494649057, - 60.186015498799264 - ], - [ - 24.981894619008195, - 60.187397033842615 - ], - [ - 24.98158348276247, - 60.187589057277705 - ], - [ - 24.977731830617074, - 60.18802910674705 - ] + [24.977731830617074, 60.18802910674705], + [24.977034456273202, 60.186674268899424], + [24.979169494649057, 60.186015498799264], + [24.981894619008195, 60.187397033842615], + [24.98158348276247, 60.187589057277705], + [24.977731830617074, 60.18802910674705] ] ] }, @@ -310,9 +243,7 @@ "CAR": 300, "ELECTRIC_CAR": 200 }, - "usages": [ - "PARK_AND_RIDE" - ], + "usages": ["PARK_AND_RIDE"], "services": [ "LIGHTING", "COVERED", @@ -320,9 +251,7 @@ "PAYMENT_AT_GATE", "ENGINE_IGNITION_AID" ], - "authenticationMethods": [ - "HSL_TICKET" - ], + "authenticationMethods": ["HSL_TICKET"], "pricing": [ { "usage": "PARK_AND_RIDE", @@ -383,12 +312,7 @@ "en": "Electric car parking 2 € + 0,15€ / kWh" }, "url": null, - "paymentMethods": [ - "COINS", - "NOTES", - "DEBIT_CARD", - "OTHER" - ] + "paymentMethods": ["COINS", "NOTES", "DEBIT_CARD", "OTHER"] }, "openingHours": { "openNow": false, @@ -423,34 +347,17 @@ } }, "bbox": [ - 24.81405168771744, - 60.21851030940037, - 24.81410264968872, + 24.81405168771744, 60.21851030940037, 24.81410264968872, 60.21875543991248 ], "type": "Polygon", "coordinates": [ [ - [ - 24.81406778097153, - 60.21875543991248 - ], - [ - 24.81405168771744, - 60.21851030940037 - ], - [ - 24.81408387422562, - 60.21851030940037 - ], - [ - 24.81410264968872, - 60.21875543991248 - ], - [ - 24.81406778097153, - 60.21875543991248 - ] + [24.81406778097153, 60.21875543991248], + [24.81405168771744, 60.21851030940037], + [24.81408387422562, 60.21851030940037], + [24.81410264968872, 60.21875543991248], + [24.81406778097153, 60.21875543991248] ] ] }, @@ -463,13 +370,8 @@ "builtCapacity": { "BICYCLE": 80 }, - "usages": [ - "PARK_AND_RIDE" - ], - "services": [ - "LIGHTING", - "BICYCLE_FRAME_LOCK" - ], + "usages": ["PARK_AND_RIDE"], + "services": ["LIGHTING", "BICYCLE_FRAME_LOCK"], "authenticationMethods": [], "pricing": [ { @@ -565,39 +467,16 @@ "name": "EPSG:4326" } }, - "bbox": [ - 25.11001, - 60.237897, - 25.110917, - 60.238254 - ], + "bbox": [25.11001, 60.237897, 25.110917, 60.238254], "type": "Polygon", "coordinates": [ [ - [ - 25.110053, - 60.238253 - ], - [ - 25.11001, - 60.237953 - ], - [ - 25.110106, - 60.237905 - ], - [ - 25.110917, - 60.237897 - ], - [ - 25.110912, - 60.238254 - ], - [ - 25.110053, - 60.238253 - ] + [25.110053, 60.238253], + [25.11001, 60.237953], + [25.110106, 60.237905], + [25.110917, 60.237897], + [25.110912, 60.238254], + [25.110053, 60.238253] ] ] }, @@ -610,9 +489,7 @@ "DISABLED": 2, "CAR": 80 }, - "usages": [ - "PARK_AND_RIDE" - ], + "usages": ["PARK_AND_RIDE"], "pricing": [ { "usage": "PARK_AND_RIDE", diff --git a/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/hubs.json b/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/hubs.json new file mode 100644 index 00000000000..a05886513df --- /dev/null +++ b/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/hubs.json @@ -0,0 +1,65 @@ +{ + "results": [ + { + "id": 321, + "name": { + "fi": "HubYksi", + "sv": "HubEn", + "en": "HubOne" + }, + "location": { + "crs": { + "type": "name", + "properties": { + "name": "EPSG:4326" + } + }, + "type": "Point", + "coordinates": [24.804913, 60.176064] + }, + "facilityIds": [990, 1037], + "address": { + "streetAddress": null, + "postalCode": null, + "city": { + "fi": "Espoo", + "sv": "Esbo", + "en": "Espoo" + } + }, + "modifiedAt": null, + "modifiedBy": null + }, + { + "id": 129, + "name": { + "fi": "HubKaksi", + "sv": "HubTvå", + "en": "HubTwo" + }, + "location": { + "crs": { + "type": "name", + "properties": { + "name": "EPSG:4326" + } + }, + "type": "Point", + "coordinates": [25.101168, 60.45744] + }, + "facilityIds": [894], + "address": { + "streetAddress": null, + "postalCode": null, + "city": { + "fi": "Järvenpää", + "sv": "Träskända", + "en": "Järvenpää" + } + }, + "modifiedAt": null, + "modifiedBy": null + } + ], + "hasMore": false +} diff --git a/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/utilizations.json b/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/utilizations.json new file mode 100644 index 00000000000..dc9772682c4 --- /dev/null +++ b/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/utilizations.json @@ -0,0 +1,20 @@ +[ + { + "facilityId": 990, + "capacityType": "CAR", + "usage": "PARK_AND_RIDE", + "timestamp": "2021-12-21T08:42:39.000+02:00", + "spacesAvailable": 600, + "capacity": 1365, + "openNow": true + }, + { + "facilityId": 894, + "capacityType": "BICYCLE", + "usage": "PARK_AND_RIDE", + "timestamp": "2019-12-31T11:58:13.000+02:00", + "spacesAvailable": 43, + "capacity": 80, + "openNow": true + } +] diff --git a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/parkapi/herrenberg.json b/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/parkapi/herrenberg.json similarity index 99% rename from src/ext-test/resources/org/opentripplanner/ext/vehicleparking/parkapi/herrenberg.json rename to application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/parkapi/herrenberg.json index e351bdc7fd0..b21ca985af1 100644 --- a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/parkapi/herrenberg.json +++ b/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/parkapi/herrenberg.json @@ -394,4 +394,4 @@ } } ] -} \ No newline at end of file +} diff --git a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/parkapi/parkapi-reutlingen.json b/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/parkapi/parkapi-reutlingen.json similarity index 99% rename from src/ext-test/resources/org/opentripplanner/ext/vehicleparking/parkapi/parkapi-reutlingen.json rename to application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/parkapi/parkapi-reutlingen.json index 946ec007ba9..23a39f17920 100644 --- a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/parkapi/parkapi-reutlingen.json +++ b/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/parkapi/parkapi-reutlingen.json @@ -424,4 +424,4 @@ "notes": {} } ] -} \ No newline at end of file +} diff --git a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/sirifm/siri-fm.xml b/application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/sirifm/siri-fm.xml similarity index 100% rename from src/ext-test/resources/org/opentripplanner/ext/vehicleparking/sirifm/siri-fm.xml rename to application/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/sirifm/siri-fm.xml diff --git a/src/ext-test/resources/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/router-config.json b/application/src/ext-test/resources/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/router-config.json similarity index 78% rename from src/ext-test/resources/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/router-config.json rename to application/src/ext-test/resources/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/router-config.json index 0c772551549..e2dc7e202d2 100644 --- a/src/ext-test/resources/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/router-config.json +++ b/application/src/ext-test/resources/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/router-config.json @@ -9,8 +9,8 @@ }, "networks": [ { - "network" : "oslo-by-sykkel", - "geofencingZones" : true + "network": "oslo-by-sykkel", + "geofencingZones": true } ] } diff --git a/src/ext-test/resources/ridehailing/uber-arrival-estimates.json b/application/src/ext-test/resources/ridehailing/uber-arrival-estimates.json similarity index 99% rename from src/ext-test/resources/ridehailing/uber-arrival-estimates.json rename to application/src/ext-test/resources/ridehailing/uber-arrival-estimates.json index 624d49d41e0..0126158daf7 100644 --- a/src/ext-test/resources/ridehailing/uber-arrival-estimates.json +++ b/application/src/ext-test/resources/ridehailing/uber-arrival-estimates.json @@ -49,4 +49,4 @@ "product_id": "3ab64887-4842-4c8e-9780-ccecd3a0391d" } ] -} \ No newline at end of file +} diff --git a/src/ext-test/resources/ridehailing/uber-price-estimates.json b/application/src/ext-test/resources/ridehailing/uber-price-estimates.json similarity index 99% rename from src/ext-test/resources/ridehailing/uber-price-estimates.json rename to application/src/ext-test/resources/ridehailing/uber-price-estimates.json index d9f8540229e..a6c39c7f10a 100644 --- a/src/ext-test/resources/ridehailing/uber-price-estimates.json +++ b/application/src/ext-test/resources/ridehailing/uber-price-estimates.json @@ -89,4 +89,4 @@ "currency_code": "USD" } ] -} \ No newline at end of file +} diff --git a/application/src/ext-test/resources/smoovebikerental/smoove.json b/application/src/ext-test/resources/smoovebikerental/smoove.json new file mode 100644 index 00000000000..9091a493a7c --- /dev/null +++ b/application/src/ext-test/resources/smoovebikerental/smoove.json @@ -0,0 +1,49 @@ +{ + "result": [ + { + "name": "A04 Hamn", + "operative": true, + "coordinates": "60.167913, 24.952269", + "style": "Station on", + "avl_bikes": 1, + "free_slots": 11, + "total_slots": 12 + }, + { + "name": "B05 Fake", + "operative": false, + "coordinates": "60, 24", + "style": "Station off", + "avl_bikes": 5, + "free_slots": 5, + "total_slots": 5 + }, + { + "name": "B06 Foo", + "operative": true, + "coordinates": "61,25", + "style": "Station on", + "avl_bikes": 5, + "free_slots": 5, + "total_slots": 5 + }, + { + "name": "B08 Invalid", + "operative": true, + "coordinates": "", + "style": "Station on", + "avl_bikes": 5, + "free_slots": 5, + "total_slots": 5 + }, + { + "name": "B09 Full", + "operative": true, + "coordinates": "60.168913, 24.953269", + "style": "Station on", + "avl_bikes": 12, + "free_slots": 0, + "total_slots": 12 + } + ] +} diff --git a/src/ext-test/resources/test.txt b/application/src/ext-test/resources/test.txt similarity index 100% rename from src/ext-test/resources/test.txt rename to application/src/ext-test/resources/test.txt diff --git a/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java b/application/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java rename to application/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java diff --git a/src/ext/java/org/opentripplanner/ext/actuator/ActuatorAPI.java b/application/src/ext/java/org/opentripplanner/ext/actuator/ActuatorAPI.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/actuator/ActuatorAPI.java rename to application/src/ext/java/org/opentripplanner/ext/actuator/ActuatorAPI.java diff --git a/src/ext/java/org/opentripplanner/ext/actuator/MicrometerGraphQLInstrumentation.java b/application/src/ext/java/org/opentripplanner/ext/actuator/MicrometerGraphQLInstrumentation.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/actuator/MicrometerGraphQLInstrumentation.java rename to application/src/ext/java/org/opentripplanner/ext/actuator/MicrometerGraphQLInstrumentation.java diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/DataOverlayStreetEdgeCostExtension.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/DataOverlayStreetEdgeCostExtension.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/DataOverlayStreetEdgeCostExtension.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/DataOverlayStreetEdgeCostExtension.java diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/EdgeGenQuality.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/EdgeGenQuality.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/EdgeGenQuality.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/EdgeGenQuality.java diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/EdgeUpdaterModule.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/EdgeUpdaterModule.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/EdgeUpdaterModule.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/EdgeUpdaterModule.java diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/GenericDataFile.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/GenericDataFile.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/GenericDataFile.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/GenericDataFile.java diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/GenericEdgeUpdater.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/GenericEdgeUpdater.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/GenericEdgeUpdater.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/GenericEdgeUpdater.java diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/api/DataOverlayParameters.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/api/DataOverlayParameters.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/api/DataOverlayParameters.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/api/DataOverlayParameters.java index 5e18a914d34..42a0209ba94 100644 --- a/src/ext/java/org/opentripplanner/ext/dataoverlay/api/DataOverlayParameters.java +++ b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/api/DataOverlayParameters.java @@ -6,7 +6,7 @@ import java.util.Map; import java.util.stream.Collectors; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * The purpose of this class is to hold all parameters and their value in a map. It also contains diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/api/DataOverlayParametersBuilder.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/api/DataOverlayParametersBuilder.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/api/DataOverlayParametersBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/api/DataOverlayParametersBuilder.java diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/api/Parameter.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/api/Parameter.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/api/Parameter.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/api/Parameter.java diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/api/ParameterName.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/api/ParameterName.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/api/ParameterName.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/api/ParameterName.java diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/api/ParameterType.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/api/ParameterType.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/api/ParameterType.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/api/ParameterType.java diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/DataOverlayConfig.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/DataOverlayConfig.java similarity index 97% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/DataOverlayConfig.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/DataOverlayConfig.java index c650bdf8a3c..858ac97d8ce 100644 --- a/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/DataOverlayConfig.java +++ b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/DataOverlayConfig.java @@ -2,7 +2,7 @@ import java.io.Serializable; import java.util.List; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * POJO class describing expected data-overlay-config.json structure diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/DataOverlayParameterBindings.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/DataOverlayParameterBindings.java similarity index 92% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/DataOverlayParameterBindings.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/DataOverlayParameterBindings.java index c86cf24bb79..7b3d1f19bac 100644 --- a/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/DataOverlayParameterBindings.java +++ b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/DataOverlayParameterBindings.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.Optional; import org.opentripplanner.ext.dataoverlay.api.ParameterName; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; public class DataOverlayParameterBindings implements Serializable { diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/IndexVariable.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/IndexVariable.java similarity index 93% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/IndexVariable.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/IndexVariable.java index 56b55b3a6b0..720ded65f89 100644 --- a/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/IndexVariable.java +++ b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/IndexVariable.java @@ -1,7 +1,7 @@ package org.opentripplanner.ext.dataoverlay.configuration; import java.io.Serializable; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This class describes the variables for the incoming .nc data file diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/ParameterBinding.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/ParameterBinding.java similarity index 95% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/ParameterBinding.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/ParameterBinding.java index 94a992eb552..07a29d4c4c1 100644 --- a/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/ParameterBinding.java +++ b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/ParameterBinding.java @@ -3,7 +3,7 @@ import java.io.Serializable; import org.opentripplanner.ext.dataoverlay.api.ParameterName; import org.opentripplanner.ext.dataoverlay.routing.Parameter; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This class describes the expected routing request parameter for the generic data diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/TimeUnit.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/TimeUnit.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/TimeUnit.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/configuration/TimeUnit.java diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/configure/DataOverlayFactory.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/configure/DataOverlayFactory.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/configure/DataOverlayFactory.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/configure/DataOverlayFactory.java diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/routing/DataOverlayContext.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/routing/DataOverlayContext.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/routing/DataOverlayContext.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/routing/DataOverlayContext.java diff --git a/src/ext/java/org/opentripplanner/ext/dataoverlay/routing/Parameter.java b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/routing/Parameter.java similarity index 94% rename from src/ext/java/org/opentripplanner/ext/dataoverlay/routing/Parameter.java rename to application/src/ext/java/org/opentripplanner/ext/dataoverlay/routing/Parameter.java index 7b6078bb04f..542f7ee26dc 100644 --- a/src/ext/java/org/opentripplanner/ext/dataoverlay/routing/Parameter.java +++ b/application/src/ext/java/org/opentripplanner/ext/dataoverlay/routing/Parameter.java @@ -2,7 +2,7 @@ import org.opentripplanner.ext.dataoverlay.api.ParameterName; import org.opentripplanner.ext.dataoverlay.configuration.ParameterBinding; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; public class Parameter { diff --git a/src/ext/java/org/opentripplanner/ext/datastore/gs/AbstractGsDataSource.java b/application/src/ext/java/org/opentripplanner/ext/datastore/gs/AbstractGsDataSource.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/datastore/gs/AbstractGsDataSource.java rename to application/src/ext/java/org/opentripplanner/ext/datastore/gs/AbstractGsDataSource.java diff --git a/src/ext/java/org/opentripplanner/ext/datastore/gs/GsDataSourceModule.java b/application/src/ext/java/org/opentripplanner/ext/datastore/gs/GsDataSourceModule.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/datastore/gs/GsDataSourceModule.java rename to application/src/ext/java/org/opentripplanner/ext/datastore/gs/GsDataSourceModule.java diff --git a/src/ext/java/org/opentripplanner/ext/datastore/gs/GsDataSourceRepository.java b/application/src/ext/java/org/opentripplanner/ext/datastore/gs/GsDataSourceRepository.java similarity index 94% rename from src/ext/java/org/opentripplanner/ext/datastore/gs/GsDataSourceRepository.java rename to application/src/ext/java/org/opentripplanner/ext/datastore/gs/GsDataSourceRepository.java index ee7e4614ee7..f049beef0b8 100644 --- a/src/ext/java/org/opentripplanner/ext/datastore/gs/GsDataSourceRepository.java +++ b/application/src/ext/java/org/opentripplanner/ext/datastore/gs/GsDataSourceRepository.java @@ -9,7 +9,6 @@ import java.io.IOException; import java.net.URI; import java.util.Collections; -import javax.annotation.Nonnull; import org.opentripplanner.datastore.api.CompositeDataSource; import org.opentripplanner.datastore.api.DataSource; import org.opentripplanner.datastore.api.FileType; @@ -39,7 +38,7 @@ public void open() { } @Override - public DataSource findSource(@Nonnull URI uri, @Nonnull FileType type) { + public DataSource findSource(URI uri, FileType type) { if (skipUri(uri)) { return null; } @@ -48,7 +47,7 @@ public DataSource findSource(@Nonnull URI uri, @Nonnull FileType type) { } @Override - public CompositeDataSource findCompositeSource(@Nonnull URI uri, @Nonnull FileType type) { + public CompositeDataSource findCompositeSource(URI uri, FileType type) { if (skipUri(uri)) { return null; } diff --git a/src/ext/java/org/opentripplanner/ext/datastore/gs/GsDirectoryDataSource.java b/application/src/ext/java/org/opentripplanner/ext/datastore/gs/GsDirectoryDataSource.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/datastore/gs/GsDirectoryDataSource.java rename to application/src/ext/java/org/opentripplanner/ext/datastore/gs/GsDirectoryDataSource.java diff --git a/src/ext/java/org/opentripplanner/ext/datastore/gs/GsFileDataSource.java b/application/src/ext/java/org/opentripplanner/ext/datastore/gs/GsFileDataSource.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/datastore/gs/GsFileDataSource.java rename to application/src/ext/java/org/opentripplanner/ext/datastore/gs/GsFileDataSource.java diff --git a/src/ext/java/org/opentripplanner/ext/datastore/gs/GsHelper.java b/application/src/ext/java/org/opentripplanner/ext/datastore/gs/GsHelper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/datastore/gs/GsHelper.java rename to application/src/ext/java/org/opentripplanner/ext/datastore/gs/GsHelper.java diff --git a/src/ext/java/org/opentripplanner/ext/datastore/gs/GsOutFileDataSource.java b/application/src/ext/java/org/opentripplanner/ext/datastore/gs/GsOutFileDataSource.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/datastore/gs/GsOutFileDataSource.java rename to application/src/ext/java/org/opentripplanner/ext/datastore/gs/GsOutFileDataSource.java diff --git a/application/src/ext/java/org/opentripplanner/ext/datastore/gs/package-info.md b/application/src/ext/java/org/opentripplanner/ext/datastore/gs/package-info.md new file mode 100644 index 00000000000..22ae44bb3e3 --- /dev/null +++ b/application/src/ext/java/org/opentripplanner/ext/datastore/gs/package-info.md @@ -0,0 +1,6 @@ +# Google cloud storage integration + +Add support for Google Cloud Storage, getting all input files and storing the graph.obj in the +cloud. + +This implementation will use the existing OtpConfigLoader to load config from the local disk. diff --git a/src/ext/java/org/opentripplanner/ext/emissions/Co2EmissionsDataReader.java b/application/src/ext/java/org/opentripplanner/ext/emissions/Co2EmissionsDataReader.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/emissions/Co2EmissionsDataReader.java rename to application/src/ext/java/org/opentripplanner/ext/emissions/Co2EmissionsDataReader.java index 597a7d89380..f3988265085 100644 --- a/src/ext/java/org/opentripplanner/ext/emissions/Co2EmissionsDataReader.java +++ b/application/src/ext/java/org/opentripplanner/ext/emissions/Co2EmissionsDataReader.java @@ -11,10 +11,10 @@ import java.util.Optional; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import org.opentripplanner.framework.lang.Sandbox; -import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.lang.Sandbox; +import org.opentripplanner.utils.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/ext/java/org/opentripplanner/ext/emissions/DecorateWithEmission.java b/application/src/ext/java/org/opentripplanner/ext/emissions/DecorateWithEmission.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/emissions/DecorateWithEmission.java rename to application/src/ext/java/org/opentripplanner/ext/emissions/DecorateWithEmission.java index 1f6e79fc4df..9657e053cb9 100644 --- a/src/ext/java/org/opentripplanner/ext/emissions/DecorateWithEmission.java +++ b/application/src/ext/java/org/opentripplanner/ext/emissions/DecorateWithEmission.java @@ -3,7 +3,6 @@ import java.util.List; import java.util.Optional; import org.opentripplanner.ext.flex.FlexibleTransitLeg; -import org.opentripplanner.framework.lang.Sandbox; import org.opentripplanner.framework.model.Grams; import org.opentripplanner.model.plan.Emissions; import org.opentripplanner.model.plan.Itinerary; @@ -13,6 +12,7 @@ import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.lang.Sandbox; /** * Calculates the emissions for the itineraries and adds them. diff --git a/src/ext/java/org/opentripplanner/ext/emissions/DefaultEmissionsService.java b/application/src/ext/java/org/opentripplanner/ext/emissions/DefaultEmissionsService.java similarity index 95% rename from src/ext/java/org/opentripplanner/ext/emissions/DefaultEmissionsService.java rename to application/src/ext/java/org/opentripplanner/ext/emissions/DefaultEmissionsService.java index 5df2ca17f26..4aaefd5a7a3 100644 --- a/src/ext/java/org/opentripplanner/ext/emissions/DefaultEmissionsService.java +++ b/application/src/ext/java/org/opentripplanner/ext/emissions/DefaultEmissionsService.java @@ -2,10 +2,10 @@ import jakarta.inject.Inject; import java.util.Optional; -import org.opentripplanner.framework.lang.Sandbox; import org.opentripplanner.framework.model.Grams; import org.opentripplanner.model.plan.Emissions; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.lang.Sandbox; @Sandbox public class DefaultEmissionsService implements EmissionsService { diff --git a/src/ext/java/org/opentripplanner/ext/emissions/EmissionsConfig.java b/application/src/ext/java/org/opentripplanner/ext/emissions/EmissionsConfig.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/emissions/EmissionsConfig.java rename to application/src/ext/java/org/opentripplanner/ext/emissions/EmissionsConfig.java diff --git a/src/ext/java/org/opentripplanner/ext/emissions/EmissionsDataModel.java b/application/src/ext/java/org/opentripplanner/ext/emissions/EmissionsDataModel.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/emissions/EmissionsDataModel.java rename to application/src/ext/java/org/opentripplanner/ext/emissions/EmissionsDataModel.java diff --git a/src/ext/java/org/opentripplanner/ext/emissions/EmissionsModule.java b/application/src/ext/java/org/opentripplanner/ext/emissions/EmissionsModule.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/emissions/EmissionsModule.java rename to application/src/ext/java/org/opentripplanner/ext/emissions/EmissionsModule.java diff --git a/src/ext/java/org/opentripplanner/ext/emissions/EmissionsService.java b/application/src/ext/java/org/opentripplanner/ext/emissions/EmissionsService.java similarity index 92% rename from src/ext/java/org/opentripplanner/ext/emissions/EmissionsService.java rename to application/src/ext/java/org/opentripplanner/ext/emissions/EmissionsService.java index 6f69ac60d06..18712bb590c 100644 --- a/src/ext/java/org/opentripplanner/ext/emissions/EmissionsService.java +++ b/application/src/ext/java/org/opentripplanner/ext/emissions/EmissionsService.java @@ -1,9 +1,9 @@ package org.opentripplanner.ext.emissions; import java.util.Optional; -import org.opentripplanner.framework.lang.Sandbox; import org.opentripplanner.model.plan.Emissions; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.lang.Sandbox; /** * A service for getting emissions information for routes. diff --git a/src/ext/java/org/opentripplanner/ext/emissions/EmissionsServiceModule.java b/application/src/ext/java/org/opentripplanner/ext/emissions/EmissionsServiceModule.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/emissions/EmissionsServiceModule.java rename to application/src/ext/java/org/opentripplanner/ext/emissions/EmissionsServiceModule.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/DecorateWithFare.java b/application/src/ext/java/org/opentripplanner/ext/fares/DecorateWithFare.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/DecorateWithFare.java rename to application/src/ext/java/org/opentripplanner/ext/fares/DecorateWithFare.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/FaresConfiguration.java b/application/src/ext/java/org/opentripplanner/ext/fares/FaresConfiguration.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/FaresConfiguration.java rename to application/src/ext/java/org/opentripplanner/ext/fares/FaresConfiguration.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/FaresToItineraryMapper.java b/application/src/ext/java/org/opentripplanner/ext/fares/FaresToItineraryMapper.java similarity index 93% rename from src/ext/java/org/opentripplanner/ext/fares/FaresToItineraryMapper.java rename to application/src/ext/java/org/opentripplanner/ext/fares/FaresToItineraryMapper.java index c545cbbb858..b936e458c00 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/FaresToItineraryMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/FaresToItineraryMapper.java @@ -1,9 +1,9 @@ package org.opentripplanner.ext.fares; -import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.model.fare.FareProductUse; import org.opentripplanner.model.fare.ItineraryFares; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.utils.collection.ListUtils; /** * Takes fares and applies them to the legs of an itinerary. diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceFactory.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceFactory.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceFactory.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceFactory.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/CombineInterlinedLegsFactory.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/CombineInterlinedLegsFactory.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/impl/CombineInterlinedLegsFactory.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/CombineInterlinedLegsFactory.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareService.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareService.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareService.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareService.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedTransitLeg.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedTransitLeg.java similarity index 96% rename from src/ext/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedTransitLeg.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedTransitLeg.java index 9d10b87bbd6..85aa1a25004 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedTransitLeg.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedTransitLeg.java @@ -5,9 +5,8 @@ import java.time.ZonedDateTime; import java.util.List; import java.util.Set; -import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.locationtech.jts.geom.LineString; -import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.model.fare.FareProductUse; import org.opentripplanner.model.plan.Leg; import org.opentripplanner.model.plan.LegTime; @@ -19,6 +18,7 @@ import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.FareZone; import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.utils.collection.ListUtils; /** * This is a fake leg that combines two interlined legs for the purpose of fare calculation. @@ -39,19 +39,16 @@ public Agency getAgency() { return first.getAgency(); } - @Nonnull @Override public TransitMode getMode() { return first.getMode(); } - @Nonnull @Override public Route getRoute() { return first.getRoute(); } - @Nonnull @Override public Trip getTrip() { return first.getTrip(); @@ -98,6 +95,7 @@ public List getIntermediateStops() { } @Override + @Nullable public LineString getLegGeometry() { return null; } diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceFactory.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceFactory.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceFactory.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceFactory.java index ee4c87924ea..d7a3a0425ec 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceFactory.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceFactory.java @@ -92,7 +92,7 @@ protected void fillFareRules( FareRuleSet fareRule = fareRuleSet.get(id); if (fareRule == null) { // Should never happen by design - LOG.error("Inexistant fare ID in fare rule: " + id); + LOG.error("Nonexistent fare ID in fare rule: " + id); continue; } String contains = rule.getContainsId(); diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/GtfsFaresService.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/GtfsFaresService.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/impl/GtfsFaresService.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/GtfsFaresService.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/GtfsFaresV2Service.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/GtfsFaresV2Service.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/fares/impl/GtfsFaresV2Service.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/GtfsFaresV2Service.java index 6aad14179b4..5bff64f05e0 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/GtfsFaresV2Service.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/impl/GtfsFaresV2Service.java @@ -13,7 +13,6 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.opentripplanner.ext.fares.model.FareDistance; import org.opentripplanner.ext.fares.model.FareLegRule; import org.opentripplanner.ext.fares.model.FareTransferRule; @@ -210,7 +209,7 @@ private boolean transferRuleMatchesNextLeg( .orElse(false); } - private Optional getFareLegRuleByGroupId(@Nonnull FeedScopedId groupId) { + private Optional getFareLegRuleByGroupId(FeedScopedId groupId) { return legRules.stream().filter(lr -> groupId.equals(lr.legGroupId())).findAny(); } diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/HSLFareService.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/HSLFareService.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/impl/HSLFareService.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/HSLFareService.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/HSLFareServiceFactory.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/HSLFareServiceFactory.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/impl/HSLFareServiceFactory.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/HSLFareServiceFactory.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceFactory.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceFactory.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceFactory.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceFactory.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/NoopFareServiceFactory.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/NoopFareServiceFactory.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/impl/NoopFareServiceFactory.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/NoopFareServiceFactory.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareFactory.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareFactory.java similarity index 88% rename from src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareFactory.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareFactory.java index 34a03c1fc06..d48cad48450 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareFactory.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareFactory.java @@ -24,6 +24,8 @@ public FareService makeFareService() { @Override public void processGtfs(FareRulesData fareRuleService, OtpTransitService transitService) { fillFareRules(fareRuleService.fareAttributes(), fareRuleService.fareRules(), regularFareRules); + // ORCA agencies don't rely on fare attributes without rules, so let's remove them. + regularFareRules.entrySet().removeIf(entry -> !entry.getValue().hasRules()); } /** diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFaresData.java b/application/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFaresData.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFaresData.java rename to application/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFaresData.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/model/Distance.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/Distance.java similarity index 94% rename from src/ext/java/org/opentripplanner/ext/fares/model/Distance.java rename to application/src/ext/java/org/opentripplanner/ext/fares/model/Distance.java index e29282fb4b8..f30712d4cad 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/model/Distance.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/model/Distance.java @@ -1,6 +1,6 @@ package org.opentripplanner.ext.fares.model; -import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; +import org.opentripplanner.utils.tostring.ValueObjectToStringBuilder; public class Distance { diff --git a/src/ext/java/org/opentripplanner/ext/fares/model/FareAttribute.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareAttribute.java similarity index 96% rename from src/ext/java/org/opentripplanner/ext/fares/model/FareAttribute.java rename to application/src/ext/java/org/opentripplanner/ext/fares/model/FareAttribute.java index 2c93fb016fa..39a6c0bd1d0 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/model/FareAttribute.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareAttribute.java @@ -2,7 +2,6 @@ package org.opentripplanner.ext.fares.model; import java.util.Objects; -import javax.annotation.Nonnull; import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -77,7 +76,7 @@ public Integer getJourneyDuration() { } @Override - public boolean sameAs(@Nonnull FareAttribute other) { + public boolean sameAs(FareAttribute other) { return ( getId().equals(other.getId()) && getPrice().equals(other.getPrice()) && @@ -88,7 +87,6 @@ public boolean sameAs(@Nonnull FareAttribute other) { ); } - @Nonnull @Override public FareAttributeBuilder copy() { return new FareAttributeBuilder(this); diff --git a/src/ext/java/org/opentripplanner/ext/fares/model/FareAttributeBuilder.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareAttributeBuilder.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/model/FareAttributeBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/fares/model/FareAttributeBuilder.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/model/FareDistance.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareDistance.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/model/FareDistance.java rename to application/src/ext/java/org/opentripplanner/ext/fares/model/FareDistance.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/model/FareLegRule.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareLegRule.java similarity index 90% rename from src/ext/java/org/opentripplanner/ext/fares/model/FareLegRule.java rename to application/src/ext/java/org/opentripplanner/ext/fares/model/FareLegRule.java index 28ef5dcab6c..984dcb0291a 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/model/FareLegRule.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareLegRule.java @@ -3,19 +3,18 @@ import java.util.Collection; import java.util.List; import java.util.Objects; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.model.fare.FareProduct; import org.opentripplanner.transit.model.framework.FeedScopedId; public record FareLegRule( - @Nonnull FeedScopedId id, + FeedScopedId id, @Nullable FeedScopedId legGroupId, @Nullable String networkId, @Nullable String fromAreaId, @Nullable String toAreaId, @Nullable FareDistance fareDistance, - @Nonnull Collection fareProducts + Collection fareProducts ) { public FareLegRule { Objects.requireNonNull(id); diff --git a/src/ext/java/org/opentripplanner/ext/fares/model/FareLegRuleBuilder.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareLegRuleBuilder.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/model/FareLegRuleBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/fares/model/FareLegRuleBuilder.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/model/FareRule.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareRule.java similarity index 95% rename from src/ext/java/org/opentripplanner/ext/fares/model/FareRule.java rename to application/src/ext/java/org/opentripplanner/ext/fares/model/FareRule.java index 3e70ef1cf2e..3b416ec2a6d 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/model/FareRule.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareRule.java @@ -2,9 +2,9 @@ package org.opentripplanner.ext.fares.model; import java.io.Serializable; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.utils.tostring.ToStringBuilder; public final class FareRule implements Serializable { diff --git a/src/ext/java/org/opentripplanner/ext/fares/model/FareRuleSet.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareRuleSet.java similarity index 77% rename from src/ext/java/org/opentripplanner/ext/fares/model/FareRuleSet.java rename to application/src/ext/java/org/opentripplanner/ext/fares/model/FareRuleSet.java index 30119631216..b8fbb0f1fe9 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/model/FareRuleSet.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareRuleSet.java @@ -40,6 +40,19 @@ public Set getRouteOriginDestinations() { return routeOriginDestinations; } + /** + * Determine whether the FareRuleSet has any rules added. + * @return True if any rules have been added. + */ + public boolean hasRules() { + return ( + !routes.isEmpty() || + !originDestinations.isEmpty() || + !routeOriginDestinations.isEmpty() || + !contains.isEmpty() + ); + } + public void addContains(String containsId) { contains.add(containsId); } @@ -60,6 +73,19 @@ public FareAttribute getFareAttribute() { return fareAttribute; } + /** + * Determines whether the FareRuleSet matches against a set of itinerary parameters + * based on the added rules and fare attribute + * @param startZone Origin zone + * @param endZone End zone + * @param zonesVisited A set containing the names of zones visited on the fare + * @param routesVisited A set containing the route IDs visited + * @param tripsVisited [Not implemented] A set containing the trip IDs visited + * @param transfersUsed Number of transfers already used + * @param tripTime Time from beginning of first leg to beginning of current leg to be evaluated + * @param journeyTime Total journey time from beginning of first leg to end of current leg + * @return True if this FareAttribute should apply to this leg + */ public boolean matches( String startZone, String endZone, diff --git a/src/ext/java/org/opentripplanner/ext/fares/model/FareRulesData.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareRulesData.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/model/FareRulesData.java rename to application/src/ext/java/org/opentripplanner/ext/fares/model/FareRulesData.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/model/FareTransferRule.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareTransferRule.java similarity index 81% rename from src/ext/java/org/opentripplanner/ext/fares/model/FareTransferRule.java rename to application/src/ext/java/org/opentripplanner/ext/fares/model/FareTransferRule.java index d3b2020771f..87917bc819c 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/model/FareTransferRule.java +++ b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareTransferRule.java @@ -2,18 +2,17 @@ import java.time.Duration; import java.util.Collection; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.model.fare.FareProduct; import org.opentripplanner.transit.model.framework.FeedScopedId; public record FareTransferRule( - @Nonnull FeedScopedId id, + FeedScopedId id, @Nullable FeedScopedId fromLegGroup, @Nullable FeedScopedId toLegGroup, int transferCount, @Nullable Duration timeLimit, - @Nonnull Collection fareProducts + Collection fareProducts ) { public String feedId() { return id.getFeedId(); diff --git a/src/ext/java/org/opentripplanner/ext/fares/model/FareTransferType.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/FareTransferType.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/model/FareTransferType.java rename to application/src/ext/java/org/opentripplanner/ext/fares/model/FareTransferType.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/model/LegProducts.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/LegProducts.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/model/LegProducts.java rename to application/src/ext/java/org/opentripplanner/ext/fares/model/LegProducts.java diff --git a/src/ext/java/org/opentripplanner/ext/fares/model/RouteOriginDestination.java b/application/src/ext/java/org/opentripplanner/ext/fares/model/RouteOriginDestination.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/fares/model/RouteOriginDestination.java rename to application/src/ext/java/org/opentripplanner/ext/fares/model/RouteOriginDestination.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapper.java b/application/src/ext/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapper.java similarity index 79% rename from src/ext/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapper.java rename to application/src/ext/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapper.java index 612fb7a1d29..85a4f749b16 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/AreaStopsToVerticesMapper.java @@ -4,21 +4,20 @@ import com.google.common.collect.ImmutableMultimap; import jakarta.inject.Inject; import java.util.stream.Stream; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.Point; import org.opentripplanner.framework.geometry.GeometryUtils; -import org.opentripplanner.framework.logging.ProgressTracker; import org.opentripplanner.graph_builder.model.GraphBuilderModule; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.graph.index.StreetIndex; import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.transit.model.site.AreaStop; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; +import org.opentripplanner.utils.logging.ProgressTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Iterates over all area stops in the stop model and adds them to vertices that are suitable for + * Iterates over all area stops in the stop and adds them to vertices that are suitable for * boarding flex trips. */ public class AreaStopsToVerticesMapper implements GraphBuilderModule { @@ -26,32 +25,32 @@ public class AreaStopsToVerticesMapper implements GraphBuilderModule { private static final Logger LOG = LoggerFactory.getLogger(AreaStopsToVerticesMapper.class); private final Graph graph; - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; @Inject - public AreaStopsToVerticesMapper(Graph graph, TransitModel transitModel) { + public AreaStopsToVerticesMapper(Graph graph, TimetableRepository timetableRepository) { this.graph = graph; - this.transitModel = transitModel; + this.timetableRepository = timetableRepository; } @Override @SuppressWarnings("Convert2MethodRef") public void buildGraph() { - if (!transitModel.getStopModel().hasAreaStops()) { + if (!timetableRepository.getSiteRepository().hasAreaStops()) { return; } - StreetIndex streetIndex = graph.getStreetIndexSafe(transitModel.getStopModel()); + StreetIndex streetIndex = graph.getStreetIndexSafe(timetableRepository.getSiteRepository()); ProgressTracker progress = ProgressTracker.track( "Add flex locations to street vertices", 1, - transitModel.getStopModel().listAreaStops().size() + timetableRepository.getSiteRepository().listAreaStops().size() ); LOG.info(progress.startMessage()); - var results = transitModel - .getStopModel() + var results = timetableRepository + .getSiteRepository() .listAreaStops() .parallelStream() .flatMap(areaStop -> { @@ -77,7 +76,6 @@ public void buildGraph() { LOG.info(progress.completeMessage()); } - @Nonnull private static Stream matchingVerticesForStop( StreetIndex streetIndex, AreaStop areaStop diff --git a/src/ext/java/org/opentripplanner/ext/flex/Flex.svg b/application/src/ext/java/org/opentripplanner/ext/flex/Flex.svg similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/Flex.svg rename to application/src/ext/java/org/opentripplanner/ext/flex/Flex.svg diff --git a/src/ext/java/org/opentripplanner/ext/flex/FlexAccessEgress.java b/application/src/ext/java/org/opentripplanner/ext/flex/FlexAccessEgress.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/flex/FlexAccessEgress.java rename to application/src/ext/java/org/opentripplanner/ext/flex/FlexAccessEgress.java index f464f1e1907..9ff2b3f67be 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/FlexAccessEgress.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/FlexAccessEgress.java @@ -4,10 +4,10 @@ import java.util.Objects; import org.opentripplanner.ext.flex.trip.FlexTrip; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.street.search.state.State; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.timetable.booking.RoutingBookingInfo; +import org.opentripplanner.utils.tostring.ToStringBuilder; public final class FlexAccessEgress { diff --git a/src/ext/java/org/opentripplanner/ext/flex/FlexIndex.java b/application/src/ext/java/org/opentripplanner/ext/flex/FlexIndex.java similarity index 88% rename from src/ext/java/org/opentripplanner/ext/flex/FlexIndex.java rename to application/src/ext/java/org/opentripplanner/ext/flex/FlexIndex.java index a875ba0f516..cd047de6d04 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/FlexIndex.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/FlexIndex.java @@ -12,7 +12,7 @@ import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.site.GroupStop; import org.opentripplanner.transit.model.site.StopLocation; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; public class FlexIndex { @@ -24,11 +24,11 @@ public class FlexIndex { private final Map> tripById = new HashMap<>(); - public FlexIndex(TransitModel transitModel) { - for (PathTransfer transfer : transitModel.getAllPathTransfers()) { + public FlexIndex(TimetableRepository timetableRepository) { + for (PathTransfer transfer : timetableRepository.getAllPathTransfers()) { transfersToStop.put(transfer.to, transfer); } - for (FlexTrip flexTrip : transitModel.getAllFlexTrips()) { + for (FlexTrip flexTrip : timetableRepository.getAllFlexTrips()) { routeById.put(flexTrip.getTrip().getRoute().getId(), flexTrip.getTrip().getRoute()); tripById.put(flexTrip.getTrip().getId(), flexTrip); for (StopLocation stop : flexTrip.getStops()) { diff --git a/src/ext/java/org/opentripplanner/ext/flex/FlexParameters.java b/application/src/ext/java/org/opentripplanner/ext/flex/FlexParameters.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/FlexParameters.java rename to application/src/ext/java/org/opentripplanner/ext/flex/FlexParameters.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/FlexPathDurations.java b/application/src/ext/java/org/opentripplanner/ext/flex/FlexPathDurations.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/flex/FlexPathDurations.java rename to application/src/ext/java/org/opentripplanner/ext/flex/FlexPathDurations.java index a77d72185d0..258435a6d6b 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/FlexPathDurations.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/FlexPathDurations.java @@ -1,6 +1,6 @@ package org.opentripplanner.ext.flex; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.utils.time.DurationUtils; /** * This value-object contains the durations for a Flex access or egress path. The path may also diff --git a/src/ext/java/org/opentripplanner/ext/flex/FlexRouter.java b/application/src/ext/java/org/opentripplanner/ext/flex/FlexRouter.java similarity index 97% rename from src/ext/java/org/opentripplanner/ext/flex/FlexRouter.java rename to application/src/ext/java/org/opentripplanner/ext/flex/FlexRouter.java index 84098db9dc9..46d9e527980 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/FlexRouter.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/FlexRouter.java @@ -20,7 +20,6 @@ import org.opentripplanner.ext.flex.template.FlexServiceDate; import org.opentripplanner.ext.flex.trip.FlexTrip; import org.opentripplanner.framework.application.OTPRequestTimeoutException; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.PathTransfer; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.routing.algorithm.mapping.GraphPathToItineraryMapper; @@ -31,6 +30,7 @@ import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.booking.RoutingBookingInfo; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.time.ServiceDateUtils; public class FlexRouter { @@ -192,7 +192,7 @@ public TransitStopVertex getStopVertexForStopId(FeedScopedId stopId) { @Override public Collection getTransfersFromStop(StopLocation stop) { - return transitService.getTransfersByStop(stop); + return transitService.findPathTransfers(stop); } @Override @@ -207,7 +207,7 @@ public Collection getTransfersToStop(StopLocation stop) { @Override public boolean isDateActive(FlexServiceDate date, FlexTrip trip) { - int serviceCode = transitService.getServiceCodeForId(trip.getTrip().getServiceId()); + int serviceCode = transitService.getServiceCode(trip.getTrip().getServiceId()); return date.isTripServiceRunning(serviceCode); } } diff --git a/src/ext/java/org/opentripplanner/ext/flex/FlexTripsMapper.java b/application/src/ext/java/org/opentripplanner/ext/flex/FlexTripsMapper.java similarity index 81% rename from src/ext/java/org/opentripplanner/ext/flex/FlexTripsMapper.java rename to application/src/ext/java/org/opentripplanner/ext/flex/FlexTripsMapper.java index c4167f2f9e1..17ce735a447 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/FlexTripsMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/FlexTripsMapper.java @@ -7,13 +7,13 @@ import org.opentripplanner.ext.flex.trip.FlexTrip; import org.opentripplanner.ext.flex.trip.ScheduledDeviatedTrip; import org.opentripplanner.ext.flex.trip.UnscheduledTrip; -import org.opentripplanner.framework.logging.ProgressTracker; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.model.StopTime; import org.opentripplanner.model.TripStopTimes; import org.opentripplanner.model.impl.OtpTransitServiceBuilder; import org.opentripplanner.routing.api.request.framework.TimePenalty; import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.utils.logging.ProgressTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,20 +44,20 @@ public class FlexTripsMapper { .withTimePenalty(timePenalty) .build() ); - } else if (ScheduledDeviatedTrip.isScheduledFlexTrip(stopTimes)) { + } else if (ScheduledDeviatedTrip.isScheduledDeviatedFlexTrip(stopTimes)) { result.add( ScheduledDeviatedTrip.of(trip.getId()).withTrip(trip).withStopTimes(stopTimes).build() ); - } else if (hasContinuousStops(stopTimes) && FlexTrip.containsFlexStops(stopTimes)) { + } else if (stopTimes.stream().anyMatch(StopTime::combinesContinuousStoppingWithFlexWindow)) { store.add( - "ContinuousFlexTrip", - "Trip %s contains both flex stops and continuous pick up/drop off. This is an invalid combination: https://github.com/MobilityData/gtfs-flex/issues/70", + "ContinuousFlexStopTime", + "Trip %s contains a stop time which combines flex with continuous pick up/drop off. This is an invalid combination: https://github.com/MobilityData/gtfs-flex/issues/70", trip.getId() ); // result.add(new ContinuousPickupDropOffTrip(trip, stopTimes)); } - //Keep lambda! A method-ref would causes incorrect class and line number to be logged + //Keep lambda! A method-ref would cause incorrect class and line number to be logged //noinspection Convert2MethodRef progress.step(m -> LOG.info(m)); } diff --git a/src/ext/java/org/opentripplanner/ext/flex/FlexibleTransitLeg.java b/application/src/ext/java/org/opentripplanner/ext/flex/FlexibleTransitLeg.java similarity index 97% rename from src/ext/java/org/opentripplanner/ext/flex/FlexibleTransitLeg.java rename to application/src/ext/java/org/opentripplanner/ext/flex/FlexibleTransitLeg.java index 0544a46da72..25c4abee12e 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/FlexibleTransitLeg.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/FlexibleTransitLeg.java @@ -6,12 +6,10 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.locationtech.jts.geom.LineString; import org.opentripplanner.ext.flex.edgetype.FlexTripEdge; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.lang.DoubleUtils; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.fare.FareProductUse; import org.opentripplanner.model.plan.Leg; @@ -28,6 +26,8 @@ import org.opentripplanner.transit.model.organization.Operator; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.booking.BookingInfo; +import org.opentripplanner.utils.lang.DoubleUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * One leg of a trip -- that is, a temporally continuous piece of the journey that takes place on a @@ -66,6 +66,7 @@ public Agency getAgency() { } @Override + @Nullable public Operator getOperator() { return getTrip().getOperator(); } @@ -96,7 +97,6 @@ public LegTime end() { } @Override - @Nonnull public TransitMode getMode() { return getTrip().getMode(); } diff --git a/src/ext/java/org/opentripplanner/ext/flex/README.md b/application/src/ext/java/org/opentripplanner/ext/flex/README.md similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/README.md rename to application/src/ext/java/org/opentripplanner/ext/flex/README.md diff --git a/src/ext/java/org/opentripplanner/ext/flex/edgetype/FlexTripEdge.java b/application/src/ext/java/org/opentripplanner/ext/flex/edgetype/FlexTripEdge.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/flex/edgetype/FlexTripEdge.java rename to application/src/ext/java/org/opentripplanner/ext/flex/edgetype/FlexTripEdge.java index 40201295d7b..70b0fcdcb3c 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/edgetype/FlexTripEdge.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/edgetype/FlexTripEdge.java @@ -2,7 +2,6 @@ import java.time.LocalDate; import java.util.Objects; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.LineString; import org.opentripplanner.ext.flex.flexpathcalculator.FlexPath; import org.opentripplanner.ext.flex.trip.FlexTrip; @@ -92,7 +91,6 @@ public double getDistanceMeters() { } @Override - @Nonnull public State[] traverse(State s0) { StateEditor editor = s0.edit(this); editor.setBackMode(TraverseMode.FLEX); diff --git a/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/DirectFlexPathCalculator.java b/application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/DirectFlexPathCalculator.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/DirectFlexPathCalculator.java rename to application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/DirectFlexPathCalculator.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPath.java b/application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPath.java similarity index 97% rename from src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPath.java rename to application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPath.java index 4a494286313..86934a22310 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPath.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPath.java @@ -4,8 +4,8 @@ import java.util.function.Supplier; import javax.annotation.concurrent.Immutable; import org.locationtech.jts.geom.LineString; -import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.routing.api.request.framework.TimePenalty; +import org.opentripplanner.utils.lang.IntUtils; /** * This class contains the results from a FlexPathCalculator. diff --git a/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathCalculator.java b/application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathCalculator.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathCalculator.java rename to application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathCalculator.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/ScheduledFlexPathCalculator.java b/application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/ScheduledFlexPathCalculator.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/ScheduledFlexPathCalculator.java rename to application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/ScheduledFlexPathCalculator.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/StreetFlexPathCalculator.java b/application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/StreetFlexPathCalculator.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/StreetFlexPathCalculator.java rename to application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/StreetFlexPathCalculator.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculator.java b/application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculator.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculator.java rename to application/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculator.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/template/AbstractFlexTemplate.java b/application/src/ext/java/org/opentripplanner/ext/flex/template/AbstractFlexTemplate.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/flex/template/AbstractFlexTemplate.java rename to application/src/ext/java/org/opentripplanner/ext/flex/template/AbstractFlexTemplate.java index 9ce9cf8a4c4..aeeab84259c 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/template/AbstractFlexTemplate.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/template/AbstractFlexTemplate.java @@ -13,7 +13,6 @@ import org.opentripplanner.ext.flex.edgetype.FlexTripEdge; import org.opentripplanner.ext.flex.flexpathcalculator.FlexPathCalculator; import org.opentripplanner.ext.flex.trip.FlexTrip; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.PathTransfer; import org.opentripplanner.routing.graphfinder.NearbyStop; import org.opentripplanner.street.model.edge.Edge; @@ -22,6 +21,7 @@ import org.opentripplanner.street.search.state.State; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A container for a few pieces of information that can be used to calculate flex accesses, egresses, @@ -199,7 +199,7 @@ private FlexAccessEgress createFlexAccessEgress( return null; } - final var finalStateOpt = EdgeTraverser.traverseEdges(afterFlexState[0], transferEdges); + final var finalStateOpt = EdgeTraverser.traverseEdges(afterFlexState, transferEdges); return finalStateOpt .map(finalState -> { diff --git a/src/ext/java/org/opentripplanner/ext/flex/template/ClosestTrip.java b/application/src/ext/java/org/opentripplanner/ext/flex/template/ClosestTrip.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/flex/template/ClosestTrip.java rename to application/src/ext/java/org/opentripplanner/ext/flex/template/ClosestTrip.java index a30ebacc497..553c8aee6c0 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/template/ClosestTrip.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/template/ClosestTrip.java @@ -7,9 +7,9 @@ import java.util.Map; import java.util.Objects; import org.opentripplanner.ext.flex.trip.FlexTrip; -import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.routing.graphfinder.NearbyStop; import org.opentripplanner.transit.model.timetable.booking.RoutingBookingInfo; +import org.opentripplanner.utils.lang.IntUtils; /** * The combination of the closest stop, trip and trip active date. diff --git a/src/ext/java/org/opentripplanner/ext/flex/template/DirectFlexPath.java b/application/src/ext/java/org/opentripplanner/ext/flex/template/DirectFlexPath.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/template/DirectFlexPath.java rename to application/src/ext/java/org/opentripplanner/ext/flex/template/DirectFlexPath.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/template/FlexAccessEgressCallbackAdapter.java b/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexAccessEgressCallbackAdapter.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/template/FlexAccessEgressCallbackAdapter.java rename to application/src/ext/java/org/opentripplanner/ext/flex/template/FlexAccessEgressCallbackAdapter.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/template/FlexAccessFactory.java b/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexAccessFactory.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/template/FlexAccessFactory.java rename to application/src/ext/java/org/opentripplanner/ext/flex/template/FlexAccessFactory.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/template/FlexAccessTemplate.java b/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexAccessTemplate.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/template/FlexAccessTemplate.java rename to application/src/ext/java/org/opentripplanner/ext/flex/template/FlexAccessTemplate.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/template/FlexDirectPathFactory.java b/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexDirectPathFactory.java similarity index 99% rename from src/ext/java/org/opentripplanner/ext/flex/template/FlexDirectPathFactory.java rename to application/src/ext/java/org/opentripplanner/ext/flex/template/FlexDirectPathFactory.java index f27a502911f..ae35c262a1e 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/template/FlexDirectPathFactory.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexDirectPathFactory.java @@ -113,7 +113,7 @@ private Optional createDirectGraphPath( final State[] afterFlexState = flexEdge.traverse(accessNearbyStop.state); - var finalStateOpt = EdgeTraverser.traverseEdges(afterFlexState[0], egress.edges); + var finalStateOpt = EdgeTraverser.traverseEdges(afterFlexState, egress.edges); if (finalStateOpt.isEmpty()) { return Optional.empty(); diff --git a/src/ext/java/org/opentripplanner/ext/flex/template/FlexEgressFactory.java b/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexEgressFactory.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/template/FlexEgressFactory.java rename to application/src/ext/java/org/opentripplanner/ext/flex/template/FlexEgressFactory.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/template/FlexEgressTemplate.java b/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexEgressTemplate.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/template/FlexEgressTemplate.java rename to application/src/ext/java/org/opentripplanner/ext/flex/template/FlexEgressTemplate.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/template/FlexServiceDate.java b/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexServiceDate.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/template/FlexServiceDate.java rename to application/src/ext/java/org/opentripplanner/ext/flex/template/FlexServiceDate.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/template/FlexTemplateFactory.java b/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexTemplateFactory.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/template/FlexTemplateFactory.java rename to application/src/ext/java/org/opentripplanner/ext/flex/template/FlexTemplateFactory.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTrip.java b/application/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTrip.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/flex/trip/FlexTrip.java rename to application/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTrip.java index 8fdb1b8fd5c..caceab676ce 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTrip.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTrip.java @@ -3,7 +3,6 @@ import java.util.List; import java.util.Objects; import java.util.Set; -import javax.annotation.Nonnull; import org.opentripplanner.ext.flex.flexpathcalculator.FlexPathCalculator; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.StopTime; @@ -140,7 +139,7 @@ public abstract FlexPathCalculator decorateFlexPathCalculator( ); @Override - public boolean sameAs(@Nonnull T other) { + public boolean sameAs(T other) { return getId().equals(other.getId()) && Objects.equals(trip, other.getTrip()); } } diff --git a/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTripBuilder.java b/application/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTripBuilder.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/trip/FlexTripBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/flex/trip/FlexTripBuilder.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTrip.java b/application/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTrip.java similarity index 91% rename from src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTrip.java rename to application/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTrip.java index 5ea0cb9fb91..25eac71ebb6 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTrip.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTrip.java @@ -1,6 +1,5 @@ package org.opentripplanner.ext.flex.trip; -import static org.opentripplanner.model.PickDrop.NONE; import static org.opentripplanner.model.StopTime.MISSING_VALUE; import java.io.Serializable; @@ -9,7 +8,6 @@ import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.opentripplanner.ext.flex.flexpathcalculator.FlexPathCalculator; import org.opentripplanner.ext.flex.flexpathcalculator.ScheduledFlexPathCalculator; import org.opentripplanner.model.PickDrop; @@ -36,7 +34,7 @@ public class ScheduledDeviatedTrip ScheduledDeviatedTrip(ScheduledDeviatedTripBuilder builder) { super(builder); List stopTimes = builder.stopTimes(); - if (!isScheduledFlexTrip(stopTimes)) { + if (!isScheduledDeviatedFlexTrip(stopTimes)) { throw new IllegalArgumentException("Incompatible stopTimes for scheduled flex trip"); } @@ -56,12 +54,10 @@ public static ScheduledDeviatedTripBuilder of(FeedScopedId id) { return new ScheduledDeviatedTripBuilder(id); } - public static boolean isScheduledFlexTrip(List stopTimes) { - Predicate notStopType = Predicate.not(st -> st.getStop() instanceof RegularStop); - Predicate notContinuousStop = stopTime -> - stopTime.getFlexContinuousDropOff() == NONE && stopTime.getFlexContinuousPickup() == NONE; + public static boolean isScheduledDeviatedFlexTrip(List stopTimes) { + Predicate notFixedStop = Predicate.not(st -> st.getStop() instanceof RegularStop); return ( - stopTimes.stream().anyMatch(notStopType) && stopTimes.stream().allMatch(notContinuousStop) + stopTimes.stream().anyMatch(notFixedStop) && stopTimes.stream().noneMatch(StopTime::combinesContinuousStoppingWithFlexWindow) ); } @@ -152,7 +148,7 @@ public boolean isAlightingPossible(StopLocation toStop) { } @Override - public boolean sameAs(@Nonnull ScheduledDeviatedTrip other) { + public boolean sameAs(ScheduledDeviatedTrip other) { return ( super.sameAs(other) && Arrays.equals(stopTimes, other.stopTimes) && @@ -161,7 +157,6 @@ public boolean sameAs(@Nonnull ScheduledDeviatedTrip other) { ); } - @Nonnull @Override public TransitBuilder copy() { return new ScheduledDeviatedTripBuilder(this); diff --git a/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripBuilder.java b/application/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripBuilder.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripBuilder.java diff --git a/src/ext/java/org/opentripplanner/ext/flex/trip/StopTimeWindow.java b/application/src/ext/java/org/opentripplanner/ext/flex/trip/StopTimeWindow.java similarity index 97% rename from src/ext/java/org/opentripplanner/ext/flex/trip/StopTimeWindow.java rename to application/src/ext/java/org/opentripplanner/ext/flex/trip/StopTimeWindow.java index 5b7ebbbc575..24b33360fce 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/trip/StopTimeWindow.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/trip/StopTimeWindow.java @@ -3,10 +3,10 @@ import static org.opentripplanner.model.StopTime.MISSING_VALUE; import java.io.Serializable; -import org.opentripplanner.framework.lang.IntRange; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.StopTime; import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.utils.lang.IntRange; class StopTimeWindow implements Serializable { diff --git a/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java b/application/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java similarity index 94% rename from src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java rename to application/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java index 20a77bb94ed..83fc22c9975 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java @@ -1,6 +1,5 @@ package org.opentripplanner.ext.flex.trip; -import static org.opentripplanner.model.PickDrop.NONE; import static org.opentripplanner.model.StopTime.MISSING_VALUE; import java.util.Arrays; @@ -8,14 +7,9 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.function.Predicate; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.opentripplanner.ext.flex.flexpathcalculator.FlexPathCalculator; import org.opentripplanner.ext.flex.flexpathcalculator.TimePenaltyCalculator; -import org.opentripplanner.framework.lang.DoubleUtils; -import org.opentripplanner.framework.lang.IntRange; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.StopTime; import org.opentripplanner.routing.api.request.framework.TimePenalty; @@ -24,6 +18,9 @@ import org.opentripplanner.transit.model.site.GroupStop; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.booking.BookingInfo; +import org.opentripplanner.utils.lang.DoubleUtils; +import org.opentripplanner.utils.lang.IntRange; +import org.opentripplanner.utils.time.DurationUtils; /** * This type of FlexTrip is used when a taxi-type service is modeled, which operates in any number @@ -82,11 +79,9 @@ public static UnscheduledTripBuilder of(FeedScopedId id) { * - One or more stop times with a flexible time window but no fixed stop in between them */ public static boolean isUnscheduledTrip(List stopTimes) { - Predicate hasContinuousStops = stopTime -> - stopTime.getFlexContinuousDropOff() != NONE || stopTime.getFlexContinuousPickup() != NONE; if (stopTimes.isEmpty()) { return false; - } else if (stopTimes.stream().anyMatch(hasContinuousStops)) { + } else if (stopTimes.stream().anyMatch(StopTime::combinesContinuousStoppingWithFlexWindow)) { return false; } else if (N_STOPS.contains(stopTimes.size())) { return stopTimes.stream().anyMatch(StopTime::hasFlexWindow); @@ -197,7 +192,7 @@ public boolean isAlightingPossible(StopLocation stop) { } @Override - public boolean sameAs(@Nonnull UnscheduledTrip other) { + public boolean sameAs(UnscheduledTrip other) { return ( super.sameAs(other) && Arrays.equals(stopTimes, other.stopTimes) && @@ -206,7 +201,6 @@ public boolean sameAs(@Nonnull UnscheduledTrip other) { ); } - @Nonnull @Override public TransitBuilder copy() { return new UnscheduledTripBuilder(this); diff --git a/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTripBuilder.java b/application/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTripBuilder.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTripBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTripBuilder.java diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java b/application/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java rename to application/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java b/application/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java rename to application/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/application/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java similarity index 95% rename from src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java rename to application/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index 71b80ac58a6..f742ddb131a 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/application/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -18,7 +18,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.lucene99.Lucene99Codec; +import org.apache.lucene.codecs.lucene912.Lucene912Codec; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field.Store; import org.apache.lucene.document.StoredField; @@ -34,7 +34,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.Completion99PostingsFormat; +import org.apache.lucene.search.suggest.document.Completion912PostingsFormat; import org.apache.lucene.search.suggest.document.CompletionAnalyzer; import org.apache.lucene.search.suggest.document.ContextQuery; import org.apache.lucene.search.suggest.document.ContextSuggestField; @@ -42,14 +42,14 @@ import org.apache.lucene.search.suggest.document.SuggestIndexSearcher; import org.apache.lucene.store.ByteBuffersDirectory; import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; -import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.site.StopLocationsGroup; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.collection.ListUtils; public class LuceneIndex implements Serializable { @@ -73,8 +73,11 @@ public class LuceneIndex implements Serializable { * However, we do need some methods in the service and that's why we instantiate it manually in this * constructor. */ - public LuceneIndex(TransitModel transitModel, StopConsolidationService stopConsolidationService) { - this(new DefaultTransitService(transitModel), stopConsolidationService); + public LuceneIndex( + TimetableRepository timetableRepository, + StopConsolidationService stopConsolidationService + ) { + this(new DefaultTransitService(timetableRepository), stopConsolidationService); } /** @@ -200,8 +203,8 @@ private StopCluster toStopCluster(Document document) { static IndexWriterConfig iwcWithSuggestField(Analyzer analyzer, final Set suggestFields) { IndexWriterConfig iwc = new IndexWriterConfig(analyzer); - Codec filterCodec = new Lucene99Codec() { - final PostingsFormat postingsFormat = new Completion99PostingsFormat(); + Codec filterCodec = new Lucene912Codec() { + final PostingsFormat postingsFormat = new Completion912PostingsFormat(); @Override public PostingsFormat getPostingsFormatForField(String field) { diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java b/application/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java rename to application/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java b/application/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java rename to application/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/application/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java similarity index 96% rename from src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java rename to application/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index 98a617b809f..daecb7f6a4e 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -13,7 +13,6 @@ import javax.annotation.Nullable; import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; import org.opentripplanner.ext.stopconsolidation.model.StopReplacement; -import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.model.FeedInfo; @@ -24,6 +23,7 @@ import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.site.StopLocationsGroup; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.collection.ListUtils; /** * Mappers for generating {@link LuceneStopCluster} from the transit model. @@ -174,7 +174,7 @@ private static Optional map(List stopLocations) } private List agenciesForStopLocation(StopLocation stop) { - return transitService.getRoutesForStop(stop).stream().map(Route::getAgency).distinct().toList(); + return transitService.findRoutes(stop).stream().map(Route::getAgency).distinct().toList(); } private List agenciesForStopLocationsGroup(StopLocationsGroup group) { @@ -190,7 +190,7 @@ StopCluster.Location toLocation(FeedScopedId id) { var loc = transitService.getStopLocation(id); if (loc != null) { var feedPublisher = toFeedPublisher(transitService.getFeedInfo(id.getFeedId())); - var modes = transitService.getModesOfStopLocation(loc).stream().map(Enum::name).toList(); + var modes = transitService.findTransitModes(loc).stream().map(Enum::name).toList(); var agencies = agenciesForStopLocation(loc) .stream() .map(StopClusterMapper::toAgency) @@ -209,7 +209,7 @@ StopCluster.Location toLocation(FeedScopedId id) { var group = transitService.getStopLocationsGroup(id); var feedPublisher = toFeedPublisher(transitService.getFeedInfo(id.getFeedId())); var modes = transitService - .getModesOfStopLocationsGroup(group) + .findTransitModes(group) .stream() .map(Enum::name) .toList(); diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/configure/GeocoderModule.java b/application/src/ext/java/org/opentripplanner/ext/geocoder/configure/GeocoderModule.java similarity index 79% rename from src/ext/java/org/opentripplanner/ext/geocoder/configure/GeocoderModule.java rename to application/src/ext/java/org/opentripplanner/ext/geocoder/configure/GeocoderModule.java index 9eaf6ade8e5..666ff5d7eaf 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/configure/GeocoderModule.java +++ b/application/src/ext/java/org/opentripplanner/ext/geocoder/configure/GeocoderModule.java @@ -7,7 +7,7 @@ import org.opentripplanner.ext.geocoder.LuceneIndex; import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; /** * This module builds the Lucene geocoder based on whether the feature flag is on or off. @@ -19,11 +19,11 @@ public class GeocoderModule { @Singleton @Nullable LuceneIndex luceneIndex( - TransitModel transitModel, + TimetableRepository timetableRepository, @Nullable StopConsolidationService stopConsolidationService ) { if (OTPFeature.SandboxAPIGeocoder.isOn()) { - return new LuceneIndex(transitModel, stopConsolidationService); + return new LuceneIndex(timetableRepository, stopConsolidationService); } else { return null; } diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/api/LauncherRequestDecorator.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/api/LauncherRequestDecorator.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/api/LauncherRequestDecorator.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/api/LauncherRequestDecorator.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/configuration/InteractiveLauncherModule.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/configuration/InteractiveLauncherModule.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/configuration/InteractiveLauncherModule.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/configuration/InteractiveLauncherModule.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/OtpDebugController.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/OtpDebugController.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/OtpDebugController.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/OtpDebugController.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggers.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggers.java similarity index 89% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggers.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggers.java index 48f87abf2ab..5880a6969fe 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggers.java +++ b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggers.java @@ -10,7 +10,8 @@ static List list() { of("All OTP debuggers", "org.opentripplanner"), of("OTP request/response", "org.opentripplanner.routing.service.DefaultRoutingService"), of("Raptor request/response", "org.opentripplanner.raptor.RaptorService"), - of("Transfer Optimization", "org.opentripplanner.routing.algorithm.transferoptimization") + of("Transfer Optimization", "org.opentripplanner.routing.algorithm.transferoptimization"), + of("Trip Updates", "org.opentripplanner.updater.trip") ); } diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggingSupport.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggingSupport.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggingSupport.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggingSupport.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogModel.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogModel.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogModel.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogModel.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugModel.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugModel.java similarity index 97% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugModel.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugModel.java index 41d6ed6be1a..71fb682581c 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugModel.java +++ b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugModel.java @@ -7,9 +7,9 @@ import java.util.Set; import javax.annotation.Nullable; import org.opentripplanner.ext.interactivelauncher.api.LauncherRequestDecorator; -import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.routing.api.request.DebugEventType; import org.opentripplanner.routing.api.request.RouteRequest; +import org.opentripplanner.utils.lang.StringUtils; public class RaptorDebugModel implements LauncherRequestDecorator { diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugView.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugView.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugView.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugView.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourceRootView.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourceRootView.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourceRootView.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourceRootView.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/MainView.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/MainView.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/MainView.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/MainView.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/OptionsView.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/OptionsView.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/OptionsView.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/OptionsView.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StartOtpButtonView.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StartOtpButtonView.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StartOtpButtonView.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StartOtpButtonView.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StartupModel.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StartupModel.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StartupModel.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StartupModel.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StatusBar.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StatusBar.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StatusBar.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StatusBar.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/support/SearchForOtpConfig.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/support/SearchForOtpConfig.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/support/SearchForOtpConfig.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/support/SearchForOtpConfig.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/support/ViewUtils.java b/application/src/ext/java/org/opentripplanner/ext/interactivelauncher/support/ViewUtils.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/support/ViewUtils.java rename to application/src/ext/java/org/opentripplanner/ext/interactivelauncher/support/ViewUtils.java diff --git a/src/ext/java/org/opentripplanner/ext/parkAndRideApi/ParkAndRideResource.java b/application/src/ext/java/org/opentripplanner/ext/parkAndRideApi/ParkAndRideResource.java similarity index 92% rename from src/ext/java/org/opentripplanner/ext/parkAndRideApi/ParkAndRideResource.java rename to application/src/ext/java/org/opentripplanner/ext/parkAndRideApi/ParkAndRideResource.java index 4a577433bfe..747ba0617ec 100644 --- a/src/ext/java/org/opentripplanner/ext/parkAndRideApi/ParkAndRideResource.java +++ b/application/src/ext/java/org/opentripplanner/ext/parkAndRideApi/ParkAndRideResource.java @@ -14,8 +14,8 @@ import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.routing.graphfinder.DirectGraphFinder; import org.opentripplanner.routing.graphfinder.GraphFinder; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; import org.opentripplanner.standalone.api.OtpServerRequestContext; /** @@ -36,11 +36,11 @@ public ParkAndRideResource( */ @Deprecated @PathParam("ignoreRouterId") String ignoreRouterId ) { - this.vehicleParkingService = serverContext.graph().getVehicleParkingService(); + this.vehicleParkingService = serverContext.vehicleParkingService(); // TODO OTP2 - Why are we using the DirectGraphFinder here, not just // - serverContext.graphFinder(). This needs at least a comment! - // - This can be replaced with a search done with the StopModel + // - This can be replaced with a search done with the SiteRepository // - if we have a radius search there. this.graphFinder = new DirectGraphFinder(serverContext.transitService()::findRegularStops); } @@ -73,7 +73,8 @@ public Response getParkAndRide( } var prs = vehicleParkingService - .getCarParks() + .listCarParks() + .stream() .filter(lot -> envelope.contains(lot.getCoordinate().asJtsCoordinate())) .filter(lot -> hasTransitStopsNearby(maxTransitDistance, lot)) .map(ParkAndRideInfo::ofVehicleParking) diff --git a/src/ext/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolver.java b/application/src/ext/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolver.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolver.java rename to application/src/ext/java/org/opentripplanner/ext/realtimeresolver/RealtimeResolver.java diff --git a/src/ext/java/org/opentripplanner/ext/reportapi/model/CachedValue.java b/application/src/ext/java/org/opentripplanner/ext/reportapi/model/CachedValue.java similarity index 87% rename from src/ext/java/org/opentripplanner/ext/reportapi/model/CachedValue.java rename to application/src/ext/java/org/opentripplanner/ext/reportapi/model/CachedValue.java index 6a7dac61b23..acf5758fa66 100644 --- a/src/ext/java/org/opentripplanner/ext/reportapi/model/CachedValue.java +++ b/application/src/ext/java/org/opentripplanner/ext/reportapi/model/CachedValue.java @@ -3,7 +3,6 @@ import java.time.Duration; import java.time.Instant; import java.util.function.Supplier; -import javax.annotation.Nonnull; /** * The purpose of this class is to be a generic container for caching expensive computations. @@ -16,7 +15,7 @@ public class CachedValue { private T value; private Instant timeout; - public CachedValue(@Nonnull Duration cacheInterval) { + public CachedValue(Duration cacheInterval) { this.value = null; this.cacheInterval = cacheInterval; this.timeout = calculateTimeout(); @@ -27,7 +26,7 @@ public CachedValue(@Nonnull Duration cacheInterval) { *

* Otherwise, recompute and return it. */ - public T get(@Nonnull Supplier supplier) { + public T get(Supplier supplier) { synchronized (this) { if (hasExpired()) { this.value = supplier.get(); diff --git a/src/ext/java/org/opentripplanner/ext/reportapi/model/CsvReportBuilder.java b/application/src/ext/java/org/opentripplanner/ext/reportapi/model/CsvReportBuilder.java similarity index 93% rename from src/ext/java/org/opentripplanner/ext/reportapi/model/CsvReportBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/reportapi/model/CsvReportBuilder.java index f2513159fa6..087ed028a23 100644 --- a/src/ext/java/org/opentripplanner/ext/reportapi/model/CsvReportBuilder.java +++ b/application/src/ext/java/org/opentripplanner/ext/reportapi/model/CsvReportBuilder.java @@ -1,7 +1,7 @@ package org.opentripplanner.ext.reportapi.model; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; /** * A very simple CSV builder to create CSV reports. diff --git a/src/ext/java/org/opentripplanner/ext/reportapi/model/GraphReportBuilder.java b/application/src/ext/java/org/opentripplanner/ext/reportapi/model/GraphReportBuilder.java similarity index 92% rename from src/ext/java/org/opentripplanner/ext/reportapi/model/GraphReportBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/reportapi/model/GraphReportBuilder.java index 57d0872b9bd..338d425db9a 100644 --- a/src/ext/java/org/opentripplanner/ext/reportapi/model/GraphReportBuilder.java +++ b/application/src/ext/java/org/opentripplanner/ext/reportapi/model/GraphReportBuilder.java @@ -4,7 +4,6 @@ import java.util.HashMap; import java.util.Map; import java.util.function.Function; -import javax.annotation.Nonnull; import org.opentripplanner.standalone.api.OtpServerRequestContext; public class GraphReportBuilder { @@ -42,21 +41,19 @@ public static GraphStats build(OtpServerRequestContext context) { new StreetStats(edgeTypes, vertexTypes), new TransitStats( stopCounts, - transitService.getAllTrips().size(), - transitService.getAllTripPatterns().size(), - transitService.getAllRoutes().size(), + transitService.listTrips().size(), + transitService.listTripPatterns().size(), + transitService.listRoutes().size(), constrainedTransferCounts ) ); } - @Nonnull private static String firstLetterToLowerCase(Object instance) { var className = instance.getClass().getSimpleName(); return Character.toLowerCase(className.charAt(0)) + className.substring(1); } - @Nonnull private static TypeStats countValues(Collection input, Function classify) { Map result = new HashMap<>(); input.forEach(item -> { diff --git a/src/ext/java/org/opentripplanner/ext/reportapi/model/TransfersReport.java b/application/src/ext/java/org/opentripplanner/ext/reportapi/model/TransfersReport.java similarity index 96% rename from src/ext/java/org/opentripplanner/ext/reportapi/model/TransfersReport.java rename to application/src/ext/java/org/opentripplanner/ext/reportapi/model/TransfersReport.java index 2cfe1b19c1c..e9b5ac8a236 100644 --- a/src/ext/java/org/opentripplanner/ext/reportapi/model/TransfersReport.java +++ b/application/src/ext/java/org/opentripplanner/ext/reportapi/model/TransfersReport.java @@ -1,10 +1,9 @@ package org.opentripplanner.ext.reportapi.model; -import static org.opentripplanner.framework.time.DurationUtils.durationToStr; +import static org.opentripplanner.utils.time.DurationUtils.durationToStr; import java.util.List; import java.util.Optional; -import javax.annotation.Nonnull; import org.opentripplanner.framework.geometry.SphericalDistanceLibrary; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; @@ -153,7 +152,7 @@ private TxPoint pointInfo(TransferPoint p, boolean boarding) { if (p instanceof TripTransferPoint tp) { var trip = tp.getTrip(); var route = trip.getRoute(); - var ptn = transitService.getPatternForTrip(trip); + var ptn = transitService.findPattern(trip); r.operator = getName(trip.getOperator()); r.type = "Trip"; r.entityId = trip.getId().getId(); @@ -163,7 +162,7 @@ private TxPoint pointInfo(TransferPoint p, boolean boarding) { addLocation(r, ptn, stop, trip, boarding); } else if (p instanceof RouteStopTransferPoint rp) { var route = rp.getRoute(); - var ptn = transitService.getPatternsForRoute(route).stream().findFirst().orElse(null); + var ptn = transitService.findPatterns(route).stream().findFirst().orElse(null); r.operator = getName(route.getOperator()); r.type = "Route"; r.entityId = route.getId().getId(); @@ -196,7 +195,6 @@ private TxPoint pointInfo(TransferPoint p, boolean boarding) { return r; } - @Nonnull private static String getName(Operator operator) { return Optional.ofNullable(operator).map(o -> o.getId().getId()).orElse(""); } diff --git a/src/ext/java/org/opentripplanner/ext/reportapi/model/TransitGroupPriorityReport.java b/application/src/ext/java/org/opentripplanner/ext/reportapi/model/TransitGroupPriorityReport.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/reportapi/model/TransitGroupPriorityReport.java rename to application/src/ext/java/org/opentripplanner/ext/reportapi/model/TransitGroupPriorityReport.java diff --git a/src/ext/java/org/opentripplanner/ext/reportapi/resource/ReportResource.java b/application/src/ext/java/org/opentripplanner/ext/reportapi/resource/ReportResource.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/reportapi/resource/ReportResource.java rename to application/src/ext/java/org/opentripplanner/ext/reportapi/resource/ReportResource.java index e06aec71b53..56a224d3d68 100644 --- a/src/ext/java/org/opentripplanner/ext/reportapi/resource/ReportResource.java +++ b/application/src/ext/java/org/opentripplanner/ext/reportapi/resource/ReportResource.java @@ -49,7 +49,7 @@ public String getTransfersAsCsv() { @Produces(MediaType.TEXT_PLAIN) public String getTransitGroupPriorities() { return TransitGroupPriorityReport.build( - transitService.getAllTripPatterns(), + transitService.listTripPatterns(), defaultRequest.journey().transit() ); } diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/AbsoluteDirectionMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/AbsoluteDirectionMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/AbsoluteDirectionMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/AbsoluteDirectionMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/AgencyMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/AgencyMapper.java similarity index 95% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/AgencyMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/AgencyMapper.java index 4ea3ebb5209..5a86968153a 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/AgencyMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/AgencyMapper.java @@ -28,7 +28,6 @@ public static ApiAgency mapToApi(Agency domain) { api.lang = domain.getLang(); api.phone = domain.getPhone(); api.fareUrl = domain.getFareUrl(); - api.brandingUrl = domain.getBrandingUrl(); return api; } diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/AlertMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/AlertMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/AlertMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/AlertMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/BikeAccessMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/BikeAccessMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/BikeAccessMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/BikeAccessMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingInfoMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingInfoMapper.java similarity index 92% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingInfoMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingInfoMapper.java index b4e3292b435..eafa81195b5 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingInfoMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingInfoMapper.java @@ -27,8 +27,8 @@ private static ApiBookingInfo mapBookingInfo(BookingInfo info, boolean isPickup) BookingMethodMapper.mapBookingMethods(info.bookingMethods()), BookingTimeMapper.mapBookingTime(info.getEarliestBookingTime()), BookingTimeMapper.mapBookingTime(info.getLatestBookingTime()), - info.getMinimumBookingNotice(), - info.getMaximumBookingNotice(), + info.getMinimumBookingNotice().orElse(null), + info.getMaximumBookingNotice().orElse(null), info.getMessage(), isPickup ? info.getPickupMessage() : null, !isPickup ? info.getDropOffMessage() : null diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingMethodMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingMethodMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingMethodMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingMethodMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingTimeMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingTimeMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingTimeMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingTimeMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/ContactInfoMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/ContactInfoMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/ContactInfoMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/ContactInfoMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/DirectionMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/DirectionMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/DirectionMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/DirectionMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/ElevationMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/ElevationMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/ElevationMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/ElevationMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedInfoMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedInfoMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedInfoMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedInfoMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedScopedIdMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedScopedIdMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedScopedIdMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedScopedIdMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/ItineraryMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/ItineraryMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/ItineraryMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/ItineraryMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java similarity index 99% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java index b642426cd6d..ce9ceeb7f46 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java @@ -100,7 +100,6 @@ public ApiLeg mapLeg( api.agencyId = FeedScopedIdMapper.mapToApi(agency.getId()); api.agencyName = agency.getName(); api.agencyUrl = agency.getUrl(); - api.agencyBrandingUrl = agency.getBrandingUrl(); api.mode = ModeMapper.mapToApi(trLeg.getMode()); var route = domain.getRoute(); diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyVehicleRoutingOptimizeType.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyVehicleRoutingOptimizeType.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyVehicleRoutingOptimizeType.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyVehicleRoutingOptimizeType.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/LocalDateMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/LocalDateMapper.java similarity index 87% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/LocalDateMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/LocalDateMapper.java index 940bcc13d54..09ff79ef9fd 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/LocalDateMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/LocalDateMapper.java @@ -1,7 +1,7 @@ package org.opentripplanner.ext.restapi.mapping; import java.time.LocalDate; -import org.opentripplanner.framework.time.ServiceDateUtils; +import org.opentripplanner.utils.time.ServiceDateUtils; public class LocalDateMapper { diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/ModeMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/ModeMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/ModeMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/ModeMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java index 28ceb0b84e3..059b0f93812 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java @@ -15,7 +15,7 @@ import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.StopArrival; import org.opentripplanner.model.plan.VehicleParkingWithEntrance; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; import org.opentripplanner.transit.model.site.RegularStop; public class PlaceMapper { diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteTypeMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteTypeMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteTypeMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteTypeMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/StopMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopTimesInPatternMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopTimesInPatternMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/StopTimesInPatternMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopTimesInPatternMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/SystemNoticeMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/SystemNoticeMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/SystemNoticeMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/SystemNoticeMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TransferMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/TransferMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/TransferMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/TransferMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/TripMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPatternMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPatternMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPatternMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPatternMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPlanMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPlanMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPlanMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPlanMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripSearchMetadataMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripSearchMetadataMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/TripSearchMetadataMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripSearchMetadataMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/VehicleRentalStationMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/VehicleRentalStationMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/VehicleRentalStationMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/VehicleRentalStationMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/VertexTypeMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/VertexTypeMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/VertexTypeMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/VertexTypeMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/WheelchairAccessibilityMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WheelchairAccessibilityMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/WheelchairAccessibilityMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WheelchairAccessibilityMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAbsoluteDirection.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAbsoluteDirection.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiAbsoluteDirection.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAbsoluteDirection.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAgency.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAgency.java similarity index 96% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiAgency.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAgency.java index ada6739a795..d1c15b7f6f6 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAgency.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAgency.java @@ -12,7 +12,6 @@ public class ApiAgency implements Serializable { public String lang; public String phone; public String fareUrl; - public String brandingUrl; @Override public int hashCode() { diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAlert.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAlert.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiAlert.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAlert.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingInfo.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingInfo.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingInfo.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingInfo.java index c89d6429caa..1fd4566a9b8 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingInfo.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingInfo.java @@ -3,7 +3,7 @@ import java.io.Serializable; import java.time.Duration; import java.util.Set; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Info about how a trip might be booked at a particular stop. All of this is pass-through diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingTime.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingTime.java similarity index 92% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingTime.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingTime.java index 08eee69a3cf..f2a8d5767ff 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingTime.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingTime.java @@ -1,7 +1,7 @@ package org.opentripplanner.ext.restapi.model; import java.io.Serializable; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Represents either an earliest or latest time a trip can be booked relative to the departure day diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiContactInfo.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiContactInfo.java similarity index 96% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiContactInfo.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiContactInfo.java index b7c2ec90166..cc7e6d069f1 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiContactInfo.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiContactInfo.java @@ -1,7 +1,7 @@ package org.opentripplanner.ext.restapi.model; import java.io.Serializable; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * How to contact the agency to book a trip or requests information. diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiCurrency.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiCurrency.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiCurrency.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiCurrency.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareComponent.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareComponent.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareComponent.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareComponent.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareProduct.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareProduct.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareProduct.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareProduct.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareQualifier.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareQualifier.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareQualifier.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareQualifier.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFeedInfo.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFeedInfo.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiFeedInfo.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFeedInfo.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiItinerary.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiItinerary.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiItinerary.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiItinerary.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiItineraryFares.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiItineraryFares.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiItineraryFares.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiItineraryFares.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLeg.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLeg.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiLeg.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLeg.java index 7bbd83f7c2d..2a434dfe92f 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLeg.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLeg.java @@ -87,8 +87,6 @@ public class ApiLeg { public String agencyUrl; - public String agencyBrandingUrl; - public int agencyTimeZoneOffset; /** @@ -98,7 +96,7 @@ public class ApiLeg { /** * For transit legs, the type of the route. Non transit -1 When 0-7: 0 Tram, 1 Subway, 2 Train, 3 - * Bus, 4 Ferry, 5 Cable Car, 6 Gondola, 7 Funicular When equal or highter than 100, it is coded + * Bus, 4 Ferry, 5 Cable Tram, 6 Gondola, 7 Funicular When equal or highter than 100, it is coded * using the Hierarchical Vehicle Type (HVT) codes from the European TPEG standard Also see * http://groups.google.com/group/gtfs-changes/msg/ed917a69cf8c5bef */ diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLegProducts.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLegProducts.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiLegProducts.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLegProducts.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiMoney.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiMoney.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiMoney.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiMoney.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternDetail.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternDetail.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternDetail.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternDetail.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternShort.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternShort.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternShort.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternShort.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPlace.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPlace.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiPlace.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPlace.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRealTimeState.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRealTimeState.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiRealTimeState.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRealTimeState.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRoute.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRoute.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiRoute.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRoute.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouteShort.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouteShort.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouteShort.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouteShort.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterInfo.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterInfo.java similarity index 87% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterInfo.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterInfo.java index a0bbb1116b3..95317d40057 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterInfo.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterInfo.java @@ -5,7 +5,7 @@ import org.locationtech.jts.geom.Geometry; import org.opentripplanner.ext.restapi.mapping.ModeMapper; import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; import org.opentripplanner.service.vehiclerental.VehicleRentalService; import org.opentripplanner.service.worldenvelope.model.WorldEnvelope; import org.opentripplanner.transit.service.TransitService; @@ -34,16 +34,15 @@ public ApiRouterInfo( Graph graph, TransitService transitService, VehicleRentalService vehicleRentalService, + VehicleParkingService vehicleParkingService, WorldEnvelope envelope ) { - VehicleParkingService vehicleParkingService = graph.getVehicleParkingService(); - this.routerId = routerId; this.polygon = graph.getConvexHull(); this.buildTime = Date.from(graph.buildTime); this.transitServiceStarts = transitService.getTransitServiceStarts().toEpochSecond(); this.transitServiceEnds = transitService.getTransitServiceEnds().toEpochSecond(); - this.transitModes = ModeMapper.mapToApi(transitService.getTransitModes()); + this.transitModes = ModeMapper.mapToApi(transitService.listTransitModes()); this.envelope = envelope; this.hasBikeSharing = mapHasBikeSharing(vehicleRentalService); this.hasBikePark = mapHasBikePark(vehicleParkingService); @@ -51,7 +50,7 @@ public ApiRouterInfo( this.hasParkRide = this.hasCarPark; this.hasVehicleParking = mapHasVehicleParking(vehicleParkingService); this.travelOptions = - ApiTravelOptionsMaker.makeOptions(graph, vehicleRentalService, transitService); + ApiTravelOptionsMaker.makeOptions(graph, vehicleRentalService, vehicleParkingService, transitService); } public boolean mapHasBikeSharing(VehicleRentalService service) { @@ -67,21 +66,21 @@ public boolean mapHasBikePark(VehicleParkingService service) { if (service == null) { return false; } - return service.getBikeParks().findAny().isPresent(); + return service.listBikeParks().stream().findAny().isPresent(); } public boolean mapHasCarPark(VehicleParkingService service) { if (service == null) { return false; } - return service.getCarParks().findAny().isPresent(); + return service.listCarParks().stream().findAny().isPresent(); } public boolean mapHasVehicleParking(VehicleParkingService service) { if (service == null) { return false; } - return service.getVehicleParkings().findAny().isPresent(); + return service.listVehicleParkings().stream().findAny().isPresent(); } public double getLowerLeftLatitude() { diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterList.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterList.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterList.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterList.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStop.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStop.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiStop.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStop.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopShort.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopShort.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopShort.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopShort.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopTimesInPattern.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopTimesInPattern.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopTimesInPattern.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopTimesInPattern.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiSystemNotice.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiSystemNotice.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiSystemNotice.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiSystemNotice.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTransfer.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTransfer.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiTransfer.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTransfer.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOption.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOption.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOption.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOption.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMaker.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMaker.java similarity index 94% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMaker.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMaker.java index cf424392d70..65fec7867cb 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMaker.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMaker.java @@ -5,6 +5,7 @@ import java.util.Set; import org.opentripplanner.api.parameter.ApiRequestMode; import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; import org.opentripplanner.service.vehiclerental.VehicleRentalService; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.service.TransitService; @@ -29,14 +30,14 @@ public final class ApiTravelOptionsMaker { public static List makeOptions( Graph graph, VehicleRentalService vehicleRentalService, + VehicleParkingService vehicleParkingService, TransitService transitService ) { - var service = graph.getVehicleParkingService(); return makeOptions( - transitService.getTransitModes(), + transitService.listTransitModes(), vehicleRentalService.hasRentalBikes(), - service.hasBikeParking(), - service.hasCarParking() + vehicleParkingService.hasBikeParking(), + vehicleParkingService.hasCarParking() ); } diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTrip.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTrip.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiTrip.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTrip.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripPlan.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripPlan.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripPlan.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripPlan.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripSearchMetadata.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripSearchMetadata.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripSearchMetadata.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripSearchMetadata.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripShort.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripShort.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripShort.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripShort.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingSpaces.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingSpaces.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingSpaces.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingSpaces.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStation.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStation.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStation.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStation.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStationList.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStationList.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStationList.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStationList.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVertexType.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVertexType.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiVertexType.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVertexType.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiWalkStep.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiWalkStep.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ApiWalkStep.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiWalkStep.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ElevationMetadata.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ElevationMetadata.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/ElevationMetadata.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/ElevationMetadata.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/TripPlannerResponse.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/TripPlannerResponse.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/TripPlannerResponse.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/model/TripPlannerResponse.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/BikeRental.java b/application/src/ext/java/org/opentripplanner/ext/restapi/resources/BikeRental.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/resources/BikeRental.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/resources/BikeRental.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java b/application/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java similarity index 94% rename from src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java index cab2be13ad0..7dbfabed156 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java @@ -51,7 +51,6 @@ 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; import org.opentripplanner.model.TripTimeOnDate; import org.opentripplanner.routing.graphfinder.DirectGraphFinder; @@ -64,6 +63,7 @@ import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.time.ServiceDateUtils; // TODO move to org.opentripplanner.api.resource, this is a Jersey resource class @@ -93,7 +93,7 @@ public IndexAPI( @GET @Path("/feeds") public Collection getFeeds() { - return transitService().getFeedIds(); + return transitService().listFeedIds(); } @GET @@ -108,7 +108,7 @@ public ApiFeedInfo getFeedInfo(@PathParam("feedId") String feedId) { @Path("/agencies/{feedId}") public Collection getAgencies(@PathParam("feedId") String feedId) { Collection agencies = transitService() - .getAgencies() + .listAgencies() .stream() .filter(agency -> agency.getId().getFeedId().equals(feedId)) .collect(Collectors.toList()); @@ -138,7 +138,7 @@ public Response getAgencyRoutes( var agency = agency(feedId, agencyId); Collection routes = transitService() - .getAllRoutes() + .listRoutes() .stream() .filter(r -> r.getAgency() == agency) .collect(Collectors.toList()); @@ -235,7 +235,7 @@ public List getStopsInRadius( public List getRoutesForStop(@PathParam("stopId") String stopId) { var stop = stop(stopId); return transitService() - .getPatternsForStop(stop) + .findPatterns(stop) .stream() .map(TripPattern::getRoute) .map(RouteMapper::mapToApiShort) @@ -247,7 +247,7 @@ public List getRoutesForStop(@PathParam("stopId") String stopId) public List getPatternsForStop(@PathParam("stopId") String stopId) { var stop = stop(stopId); return transitService() - .getPatternsForStop(stop) + .findPatterns(stop) .stream() .map(TripPatternMapper::mapToApiShort) .collect(Collectors.toList()); @@ -275,7 +275,7 @@ public Collection getStopTimesForStop( : Instant.ofEpochSecond(startTimeSeconds); return transitService() - .stopTimesForStop( + .findStopTimesInPattern( stop(stopIdString), startTime, Duration.ofSeconds(timeRange), @@ -303,7 +303,7 @@ public List getStoptimesForStopAndDate( var stop = stop(stopId); var serviceDate = parseServiceDate("date", date); List stopTimes = transitService() - .getStopTimesForStop( + .findStopTimesInPattern( stop, serviceDate, omitNonPickups ? ArrivalDeparture.DEPARTURES : ArrivalDeparture.BOTH, @@ -322,7 +322,7 @@ public Collection getTransfers(@PathParam("stopId") String stopId) // get the transfers for the stop return transitService() - .getTransfersByStop(stop) + .findPathTransfers(stop) .stream() .map(TransferMapper::mapToApi) .collect(Collectors.toList()); @@ -344,7 +344,7 @@ public Collection getAlertsForStop(@PathParam("stopId") String stopId) @GET @Path("/routes") public List getRoutes(@QueryParam("hasStop") List stopIds) { - Collection routes = transitService().getAllRoutes(); + Collection routes = transitService().listRoutes(); // Filter routes to include only those that pass through all given stops if (stopIds != null) { // Protective copy, we are going to calculate the intersection destructively @@ -352,7 +352,7 @@ public List getRoutes(@QueryParam("hasStop") List stopIds for (String stopId : stopIds) { var stop = stop(stopId); Set routesHere = new HashSet<>(); - for (TripPattern pattern : transitService().getPatternsForStop(stop)) { + for (TripPattern pattern : transitService().findPatterns(stop)) { routesHere.add(pattern.getRoute()); } routes.retainAll(routesHere); @@ -372,7 +372,7 @@ public ApiRoute getRoute(@PathParam("routeId") String routeId) { @GET @Path("/routes/{routeId}/patterns") public List getPatternsForRoute(@PathParam("routeId") String routeId) { - Collection patterns = transitService().getPatternsForRoute(route(routeId)); + Collection patterns = transitService().findPatterns(route(routeId)); return TripPatternMapper.mapToApiShort(patterns); } @@ -383,7 +383,7 @@ public List getStopsForRoute(@PathParam("routeId") String routeId) var route = route(routeId); Set stops = new HashSet<>(); - Collection patterns = transitService().getPatternsForRoute(route); + Collection patterns = transitService().findPatterns(route); for (TripPattern pattern : patterns) { stops.addAll(pattern.getStops()); } @@ -396,7 +396,7 @@ public List getStopsForRoute(@PathParam("routeId") String routeId) public List getTripsForRoute(@PathParam("routeId") String routeId) { var route = route(routeId); - var patterns = transitService().getPatternsForRoute(route); + var patterns = transitService().findPatterns(route); return patterns .stream() .flatMap(TripPattern::scheduledTripsAsStream) @@ -445,7 +445,7 @@ public List getStoptimesForTrip(@PathParam("tripId") String tr var pattern = tripPattern(trip); // Note, we need the updated timetable not the scheduled one (which contains no real-time updates). var table = transitService() - .getTimetableForTripPattern(pattern, LocalDate.now(transitService().getTimeZone())); + .findTimetable(pattern, LocalDate.now(transitService().getTimeZone())); var tripTimesOnDate = TripTimeOnDate.fromTripTimes(table, trip); return TripTimeMapper.mapToApi(tripTimesOnDate); } @@ -472,7 +472,7 @@ public Collection getAlertsForTrip(@PathParam("tripId") String tripId) @GET @Path("/patterns") public List getPatterns() { - Collection patterns = transitService().getAllTripPatterns(); + Collection patterns = transitService().listTripPatterns(); return TripPatternMapper.mapToApiShort(patterns); } @@ -589,7 +589,7 @@ private static NotFoundException notFoundException(String entity, String details } private Agency agency(String feedId, String agencyId) { - var agency = transitService().getAgencyForId(new FeedScopedId(feedId, agencyId)); + var agency = transitService().getAgency(new FeedScopedId(feedId, agencyId)); if (agency == null) { throw notFoundException("Agency", "feedId: " + feedId + ", agencyId: " + agencyId); } @@ -602,18 +602,18 @@ private StopLocation stop(String stopId) { } private Route route(String routeId) { - var route = transitService().getRouteForId(createId("routeId", routeId)); + var route = transitService().getRoute(createId("routeId", routeId)); return validateExist("Route", route, "routeId", routeId); } private Trip trip(String tripId) { - var trip = transitService().getTripForId(createId("tripId", tripId)); + var trip = transitService().getTrip(createId("tripId", tripId)); return validateExist("Trip", trip, "tripId", tripId); } private TripPattern tripPattern(String tripPatternId) { var id = createId("patternId", tripPatternId); - var pattern = transitService().getTripPatternForId(id); + var pattern = transitService().getTripPattern(id); return validateExist("TripPattern", pattern, "patternId", tripPatternId); } @@ -622,7 +622,7 @@ private TripPattern tripPatternForTripId(String tripId) { } private TripPattern tripPattern(Trip trip) { - var pattern = transitService().getPatternForTrip(trip); + var pattern = transitService().findPattern(trip); return validateExist("TripPattern", pattern, "trip", trip.getId()); } diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java b/application/src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java similarity index 99% rename from src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java index 51b2fae86b5..22aa194d4bb 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java @@ -3,7 +3,6 @@ import jakarta.validation.constraints.NotNull; import java.util.function.Consumer; import org.opentripplanner.ext.restapi.mapping.LegacyVehicleRoutingOptimizeType; -import org.opentripplanner.framework.lang.ObjectUtils; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.preference.ItineraryFilterPreferences; @@ -11,6 +10,7 @@ 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.utils.lang.ObjectUtils; class RequestToPreferencesMapper { diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/Routers.java b/application/src/ext/java/org/opentripplanner/ext/restapi/resources/Routers.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/restapi/resources/Routers.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/resources/Routers.java index 9cfab49017c..6c805560b8b 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/Routers.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/resources/Routers.java @@ -66,6 +66,7 @@ private ApiRouterInfo getRouterInfo() { serverContext.graph(), serverContext.transitService(), serverContext.vehicleRentalService(), + serverContext.vehicleParkingService(), serverContext.worldEnvelopeService().envelope().orElseThrow() ); } catch (GraphNotFoundException e) { diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java b/application/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java similarity index 99% rename from src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java index 3ae029fdb2d..9a0f030a807 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java @@ -23,8 +23,6 @@ import org.opentripplanner.ext.dataoverlay.api.DataOverlayParameters; import org.opentripplanner.ext.restapi.mapping.LegacyVehicleRoutingOptimizeType; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.framework.lang.StringUtils; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.framework.time.ZoneIdFallback; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; @@ -35,6 +33,8 @@ import org.opentripplanner.standalone.config.framework.json.NodeAdapter; import org.opentripplanner.standalone.config.routerequest.RouteRequestConfig; import org.opentripplanner.transit.model.basic.MainAndSubMode; +import org.opentripplanner.utils.lang.StringUtils; +import org.opentripplanner.utils.time.DurationUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/ValidateParameters.java b/application/src/ext/java/org/opentripplanner/ext/restapi/resources/ValidateParameters.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/resources/ValidateParameters.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/resources/ValidateParameters.java diff --git a/application/src/ext/java/org/opentripplanner/ext/restapi/resources/package-info.md b/application/src/ext/java/org/opentripplanner/ext/restapi/resources/package-info.md new file mode 100644 index 00000000000..a4bb7eb6f4f --- /dev/null +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/resources/package-info.md @@ -0,0 +1,4 @@ +# JAX-RS-annotated REST resource classes + +This package contains the JAX-RS-annotated REST resource classes for the OpenTripPlanner public +API, i.e. the Jersey REST endpoints. diff --git a/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdDeserializer.java b/application/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdDeserializer.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdDeserializer.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdDeserializer.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdKeyDeserializer.java b/application/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdKeyDeserializer.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdKeyDeserializer.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdKeyDeserializer.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdSerializer.java b/application/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdSerializer.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdSerializer.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdSerializer.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/serialization/JSONObjectMapperProvider.java b/application/src/ext/java/org/opentripplanner/ext/restapi/serialization/JSONObjectMapperProvider.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/serialization/JSONObjectMapperProvider.java rename to application/src/ext/java/org/opentripplanner/ext/restapi/serialization/JSONObjectMapperProvider.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/CachingRideHailingService.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/CachingRideHailingService.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/CachingRideHailingService.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/CachingRideHailingService.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailing.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailing.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailing.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailing.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingAccessAdapter.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingAccessAdapter.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingAccessAdapter.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingAccessAdapter.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingAccessShifter.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingAccessShifter.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingAccessShifter.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingAccessShifter.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingService.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingService.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingService.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingService.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingServiceParameters.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingServiceParameters.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingServiceParameters.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingServiceParameters.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/configure/RideHailingServicesModule.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/configure/RideHailingServicesModule.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/configure/RideHailingServicesModule.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/configure/RideHailingServicesModule.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/model/ArrivalTime.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/model/ArrivalTime.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/model/ArrivalTime.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/model/ArrivalTime.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/model/Ride.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/model/Ride.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/model/Ride.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/model/Ride.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/model/RideEstimate.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/model/RideEstimate.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/model/RideEstimate.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/model/RideEstimate.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/model/RideEstimateRequest.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/model/RideEstimateRequest.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/model/RideEstimateRequest.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/model/RideEstimateRequest.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/model/RideHailingLeg.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/model/RideHailingLeg.java similarity index 95% rename from src/ext/java/org/opentripplanner/ext/ridehailing/model/RideHailingLeg.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/model/RideHailingLeg.java index 91a7a1fbf6f..94587333c4e 100644 --- a/src/ext/java/org/opentripplanner/ext/ridehailing/model/RideHailingLeg.java +++ b/application/src/ext/java/org/opentripplanner/ext/ridehailing/model/RideHailingLeg.java @@ -1,6 +1,5 @@ package org.opentripplanner.ext.ridehailing.model; -import javax.annotation.Nonnull; import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.model.plan.StreetLegBuilder; @@ -27,7 +26,6 @@ public RideHailingProvider provider() { return provider; } - @Nonnull public RideEstimate rideEstimate() { return estimate; } diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/model/RideHailingProvider.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/model/RideHailingProvider.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/model/RideHailingProvider.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/model/RideHailingProvider.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/CachedOAuthToken.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/CachedOAuthToken.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/CachedOAuthToken.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/CachedOAuthToken.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/CachingOAuthService.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/CachingOAuthService.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/CachingOAuthService.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/CachingOAuthService.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/ClientCredentialsRequest.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/ClientCredentialsRequest.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/ClientCredentialsRequest.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/ClientCredentialsRequest.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/OAuthService.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/OAuthService.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/OAuthService.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/OAuthService.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/UrlEncodedOAuthService.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/UrlEncodedOAuthService.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/UrlEncodedOAuthService.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/service/oauth/UrlEncodedOAuthService.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberArrivalEstimateResponse.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberArrivalEstimateResponse.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberArrivalEstimateResponse.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberArrivalEstimateResponse.java diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberService.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberService.java similarity index 99% rename from src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberService.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberService.java index 9b276fc053e..d5ab1e8c5fa 100644 --- a/src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberService.java +++ b/application/src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberService.java @@ -13,7 +13,6 @@ import java.util.Currency; import java.util.List; import java.util.Map; -import javax.annotation.Nonnull; import org.opentripplanner.ext.ridehailing.CachingRideHailingService; import org.opentripplanner.ext.ridehailing.RideHailingServiceParameters; import org.opentripplanner.ext.ridehailing.model.ArrivalTime; @@ -191,7 +190,6 @@ private boolean filterRides(Ride a, boolean wheelchairAccessible) { } } - @Nonnull private Map headers() throws IOException { return Map.ofEntries( entry(AUTHORIZATION, "Bearer %s".formatted(oauthService.getToken())), diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberTripTimeEstimateResponse.java b/application/src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberTripTimeEstimateResponse.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberTripTimeEstimateResponse.java rename to application/src/ext/java/org/opentripplanner/ext/ridehailing/service/uber/UberTripTimeEstimateResponse.java diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/AbstractAzureSiriUpdater.java b/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/AbstractAzureSiriUpdater.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/siri/updater/azure/AbstractAzureSiriUpdater.java rename to application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/AbstractAzureSiriUpdater.java diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/AuthenticationType.java b/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/AuthenticationType.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/siri/updater/azure/AuthenticationType.java rename to application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/AuthenticationType.java diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdater.java b/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdater.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdater.java rename to application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdater.java index 009bc3a7f0e..a2fe5b71f36 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdater.java +++ b/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdater.java @@ -15,7 +15,7 @@ import java.util.function.Consumer; import javax.xml.stream.XMLStreamException; import org.apache.hc.core5.net.URIBuilder; -import org.opentripplanner.ext.siri.SiriTimetableSnapshotSource; +import org.opentripplanner.updater.siri.SiriTimetableSnapshotSource; import org.opentripplanner.updater.spi.ResultLogger; import org.opentripplanner.updater.spi.UpdateResult; import org.opentripplanner.updater.trip.UpdateIncrementality; diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdaterParameters.java b/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdaterParameters.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdaterParameters.java rename to application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdaterParameters.java diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureInitializationException.java b/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureInitializationException.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureInitializationException.java rename to application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureInitializationException.java diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureSXUpdater.java b/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureSXUpdater.java similarity index 93% rename from src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureSXUpdater.java rename to application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureSXUpdater.java index bcd2c500c40..0f3e2afe1ea 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureSXUpdater.java +++ b/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureSXUpdater.java @@ -15,11 +15,11 @@ import java.util.function.Consumer; import javax.xml.stream.XMLStreamException; import org.apache.hc.core5.net.URIBuilder; -import org.opentripplanner.ext.siri.SiriAlertsUpdateHandler; import org.opentripplanner.routing.impl.TransitAlertServiceImpl; import org.opentripplanner.routing.services.TransitAlertService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.updater.alert.TransitAlertProvider; +import org.opentripplanner.updater.siri.SiriAlertsUpdateHandler; import org.rutebanken.siri20.util.SiriXml; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,11 +35,14 @@ public class SiriAzureSXUpdater extends AbstractAzureSiriUpdater implements Tran private final LocalDate fromDateTime; private final LocalDate toDateTime; - public SiriAzureSXUpdater(SiriAzureSXUpdaterParameters config, TransitModel transitModel) { + public SiriAzureSXUpdater( + SiriAzureSXUpdaterParameters config, + TimetableRepository timetableRepository + ) { super(config); this.fromDateTime = config.getFromDateTime(); this.toDateTime = config.getToDateTime(); - this.transitAlertService = new TransitAlertServiceImpl(transitModel); + this.transitAlertService = new TransitAlertServiceImpl(timetableRepository); this.updateHandler = new SiriAlertsUpdateHandler(feedId, transitAlertService, Duration.ZERO); } diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureSXUpdaterParameters.java b/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureSXUpdaterParameters.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureSXUpdaterParameters.java rename to application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureSXUpdaterParameters.java diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureUpdaterParameters.java b/application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureUpdaterParameters.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureUpdaterParameters.java rename to application/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureUpdaterParameters.java diff --git a/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSource.java b/application/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSource.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSource.java rename to application/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSource.java diff --git a/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceParameters.java b/application/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceParameters.java similarity index 76% rename from src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceParameters.java rename to application/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceParameters.java index ca0f5497601..a04ea004bf0 100644 --- a/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceParameters.java +++ b/application/src/ext/java/org/opentripplanner/ext/smoovebikerental/SmooveBikeRentalDataSourceParameters.java @@ -1,7 +1,8 @@ package org.opentripplanner.ext.smoovebikerental; -import javax.annotation.Nonnull; +import java.util.Set; import javax.annotation.Nullable; +import org.opentripplanner.updater.vehicle_rental.datasources.params.RentalPickupType; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.vehicle_rental.VehicleRentalSourceType; import org.opentripplanner.updater.vehicle_rental.datasources.params.VehicleRentalDataSourceParameters; @@ -13,7 +14,8 @@ public record SmooveBikeRentalDataSourceParameters( String url, String network, boolean overloadingAllowed, - HttpHeaders httpHeaders + HttpHeaders httpHeaders, + Set rentalPickupTypes ) implements VehicleRentalDataSourceParameters { /** @@ -26,9 +28,13 @@ public String getNetwork(String defaultValue) { return network == null || network.isEmpty() ? defaultValue : network; } - @Nonnull @Override public VehicleRentalSourceType sourceType() { return VehicleRentalSourceType.SMOOVE; } + + @Override + public boolean allowRentalType(RentalPickupType rentalPickupType) { + return rentalPickupTypes.contains(rentalPickupType); + } } diff --git a/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/CoachCostCalculator.java b/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/CoachCostCalculator.java new file mode 100644 index 00000000000..ba4830f29cf --- /dev/null +++ b/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/CoachCostCalculator.java @@ -0,0 +1,82 @@ +package org.opentripplanner.ext.sorlandsbanen; + +import org.opentripplanner.raptor.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; +import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; +import org.opentripplanner.raptor.spi.RaptorCostCalculator; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripSchedule; +import org.opentripplanner.transit.model.basic.TransitMode; + + +/** + * This cost calculator increases the cost on mode coach by adding an extra reluctance. The + * reluctance is hardcoded in this class and cannot be configured. + */ +class CoachCostCalculator implements RaptorCostCalculator { + + private static final int EXTRA_RELUCTANCE_ON_COACH = RaptorCostConverter.toRaptorCost(0.6); + + private final RaptorCostCalculator delegate; + + CoachCostCalculator(RaptorCostCalculator delegate) { + this.delegate = delegate; + } + + @Override + public int boardingCost( + boolean firstBoarding, + int prevArrivalTime, + int boardStop, + int boardTime, + T trip, + RaptorTransferConstraint transferConstraints + ) { + return delegate.boardingCost( + firstBoarding, + prevArrivalTime, + boardStop, + boardTime, + trip, + transferConstraints + ); + } + + @Override + public int onTripRelativeRidingCost(int boardTime, T tripScheduledBoarded) { + return delegate.onTripRelativeRidingCost(boardTime, tripScheduledBoarded); + } + + @Override + public int transitArrivalCost( + int boardCost, + int alightSlack, + int transitTime, + T trip, + int toStop + ) { + int cost = delegate.transitArrivalCost(boardCost, alightSlack, transitTime, trip, toStop); + + // This is a bit ugly, since it relies on the fact that the 'transitReluctanceFactorIndex' + // returns the 'route.getMode().ordinal()' + if(trip.transitReluctanceFactorIndex() == TransitMode.COACH.ordinal()) { + cost += transitTime * EXTRA_RELUCTANCE_ON_COACH; + } + return cost; + } + + @Override + public int waitCost(int waitTimeInSeconds) { + return delegate.waitCost(waitTimeInSeconds); + } + + @Override + public int calculateRemainingMinCost(int minTravelTime, int minNumTransfers, int fromStop) { + return delegate.calculateRemainingMinCost(minTravelTime, minNumTransfers, fromStop); + } + + @Override + public int costEgress(RaptorAccessEgress egress) { + return delegate.costEgress(egress); + } + +} diff --git a/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/MergePaths.java b/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/MergePaths.java new file mode 100644 index 00000000000..2f7b38a7a08 --- /dev/null +++ b/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/MergePaths.java @@ -0,0 +1,54 @@ +package org.opentripplanner.ext.sorlandsbanen; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiFunction; +import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.raptor.api.path.PathLeg; +import org.opentripplanner.raptor.api.path.RaptorPath; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.request.TripScheduleWithOffset; +import org.opentripplanner.transit.model.basic.TransitMode; + +/** + * Strategy for merging the main results and the extra rail results from Sorlandsbanen. + * Everything from the main result is kept, and any additional rail results from the alternative + * search are added. + */ +class MergePaths implements BiFunction>, Collection>, Collection>> { + + @Override + public Collection> apply(Collection> main, Collection> alternatives) { + Map> result = new HashMap<>(); + addAllToMap(result, main); + addRailToMap(result, alternatives); + return result.values(); + } + + private void addAllToMap(Map> map, Collection> paths) { + for (var it : paths) { + map.put(new PathKey(it), it); + } + } + + private void addRailToMap(Map> map, Collection> paths) { + for (var it : paths) { + if (hasRail(it)) { + // Avoid replacing an existing value if it exists, there might be minor differences in the + // path, in which case we want to keep the main result. + map.computeIfAbsent(new PathKey(it), k -> it); + } + } + } + + private static boolean hasRail(RaptorPath path) { + return path + .legStream() + .filter(PathLeg::isTransitLeg) + .anyMatch(leg -> { + var trip = (TripScheduleWithOffset) leg.asTransitLeg().trip(); + var mode = trip.getOriginalTripPattern().getMode(); + return mode == TransitMode.RAIL; + }); + } +} diff --git a/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/PathKey.java b/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/PathKey.java new file mode 100644 index 00000000000..e4504b3ed14 --- /dev/null +++ b/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/PathKey.java @@ -0,0 +1,60 @@ +package org.opentripplanner.ext.sorlandsbanen; + +import org.opentripplanner.raptor.api.path.PathLeg; +import org.opentripplanner.raptor.api.path.RaptorPath; + + +/** + * The purpose of this class is to create a key to be able to compare paths so duplicate results + * can be ignored. + *

+ * Creating a good key for a path is not easy. For example, should a small variation in the street + * routing for an access/egress leg count as a significant difference? The solution here is + * straightforward. It creates a hash of the access-, egress- and transit-legs in the path, + * ignoring transfer legs. This approach may drop valid results if there are hash collisions, + * but since this is a Sandbox module and the investment in this code is minimal, we will accept + * the risk. + */ +final class PathKey { + + private final int hash; + + PathKey(RaptorPath path) { + this.hash = hash(path); + } + + private static int hash(RaptorPath path) { + int result = 1; + + PathLeg leg = path.accessLeg(); + + while (!leg.isEgressLeg()) { + result = 31 * result + leg.toStop(); + result = 31 * result + leg.toTime(); + + if (leg.isTransitLeg()) { + result = 31 * result + leg.asTransitLeg().trip().pattern().debugInfo().hashCode(); + } + leg = leg.nextLeg(); + } + result = 31 * result + leg.toTime(); + + return result; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o.getClass() != PathKey.class) { + return false; + } + return hash == ((PathKey) o).hash; + } + + @Override + public int hashCode() { + return hash; + } +} diff --git a/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/SorlandsbanenNorwayService.java b/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/SorlandsbanenNorwayService.java new file mode 100644 index 00000000000..ecccb5d2370 --- /dev/null +++ b/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/SorlandsbanenNorwayService.java @@ -0,0 +1,106 @@ +package org.opentripplanner.ext.sorlandsbanen; + +import java.util.Collection; +import java.util.function.BiFunction; +import javax.annotation.Nullable; +import org.opentripplanner.framework.geometry.WgsCoordinate; +import org.opentripplanner.model.GenericLocation; +import org.opentripplanner.raptor.api.path.RaptorPath; +import org.opentripplanner.raptor.spi.ExtraMcRouterSearch; +import org.opentripplanner.raptor.spi.RaptorTransitDataProvider; +import org.opentripplanner.routing.algorithm.raptoradapter.router.street.AccessEgresses; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.RoutingAccessEgress; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitLayer; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripSchedule; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.request.RaptorRoutingRequestTransitData; +import org.opentripplanner.routing.api.request.RouteRequest; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.site.StopLocation; + +/** + * This service is responsible for producing results with rail for the south of Norway. The rail + * line is called "Sørlandsbanen". This rail line is slow and goes inland far from where people + * live. Despite this, people and the operator want to show it in the results for log travel along + * the southern part of Norway where it is an option. Tuning the search has proven to be + * challenging. It is solved here by doing two searches. One normal search and one where the rail + * is given a big cost advantage over coach. If train results are found in the second search, then + * it is added to the results of the first search. Everything found in the first search is always + * returned. + */ +public class SorlandsbanenNorwayService { + + private static final double SOUTH_BORDER_LIMIT = 59.1; + private static final int MIN_DISTANCE_LIMIT = 120_000; + + + @Nullable + public ExtraMcRouterSearch createExtraMcRouterSearch(RouteRequest request, AccessEgresses accessEgresses, TransitLayer transitLayer) { + WgsCoordinate from = findStopCoordinate( + request.from(), + accessEgresses.getAccesses(), + transitLayer + ); + WgsCoordinate to = findStopCoordinate(request.to(), accessEgresses.getEgresses(), transitLayer); + + if (from.isNorthOf(SOUTH_BORDER_LIMIT) && to.isNorthOf(SOUTH_BORDER_LIMIT)) { + return null; + } + + double distance = from.distanceTo(to); + if (distance < MIN_DISTANCE_LIMIT) { + return null; + } + + return new ExtraMcRouterSearch<>() { + @Override + public RaptorTransitDataProvider createTransitDataAlternativeSearch(RaptorTransitDataProvider transitDataMainSearch) { + return new RaptorRoutingRequestTransitData( + (RaptorRoutingRequestTransitData)transitDataMainSearch, + new CoachCostCalculator<>(transitDataMainSearch.multiCriteriaCostCalculator()) + ); + } + + @Override + public BiFunction>, Collection>, Collection>> merger() { + return new MergePaths<>(); + } + }; + } + + /** + * Find a coordinate matching the given location, in order: + * - First return the coordinate of the location if it exists. + * - Then loop through the access/egress stops and try to find the + * stop or station given by the location id, return the stop/station coordinate. + * - Return the stop coordinate of the first access/egress in the list. + */ + @SuppressWarnings("ConstantConditions") + private static WgsCoordinate findStopCoordinate( + GenericLocation location, + Collection accessEgress, + TransitLayer transitLayer + ) { + if (location.lat != null) { + return new WgsCoordinate(location.lat, location.lng); + } + + StopLocation firstStop = null; + for (RoutingAccessEgress it : accessEgress) { + StopLocation stop = transitLayer.getStopByIndex(it.stop()); + if (stop.getId().equals(location.stopId)) { + return stop.getCoordinate(); + } + if (idIsParentStation(stop, location.stopId)) { + return stop.getParentStation().getCoordinate(); + } + if (firstStop == null) { + firstStop = stop; + } + } + return firstStop.getCoordinate(); + } + + private static boolean idIsParentStation(StopLocation stop, FeedScopedId pId) { + return stop.getParentStation() != null && stop.getParentStation().getId().equals(pId); + } +} diff --git a/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/configure/SorlandsbanenNorwayModule.java b/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/configure/SorlandsbanenNorwayModule.java new file mode 100644 index 00000000000..d0b177ac767 --- /dev/null +++ b/application/src/ext/java/org/opentripplanner/ext/sorlandsbanen/configure/SorlandsbanenNorwayModule.java @@ -0,0 +1,17 @@ +package org.opentripplanner.ext.sorlandsbanen.configure; + +import dagger.Module; +import dagger.Provides; +import javax.annotation.Nullable; +import org.opentripplanner.ext.sorlandsbanen.SorlandsbanenNorwayService; +import org.opentripplanner.framework.application.OTPFeature; + +@Module +public class SorlandsbanenNorwayModule { + + @Provides + @Nullable + SorlandsbanenNorwayService providesSorlandsbanenNorwayService() { + return OTPFeature.Sorlandsbanen.isOn() ? new SorlandsbanenNorwayService() : null; + } +} diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java similarity index 68% rename from src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java rename to application/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java index 1806b3e9e32..6def5c85fa1 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java +++ b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java @@ -1,8 +1,10 @@ package org.opentripplanner.ext.stopconsolidation; +import java.util.ArrayList; import java.util.Objects; import org.opentripplanner.ext.stopconsolidation.model.ConsolidatedStopLeg; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.model.plan.Leg; import org.opentripplanner.model.plan.ScheduledTransitLeg; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; @@ -13,6 +15,7 @@ */ public class DecorateConsolidatedStopNames implements ItineraryDecorator { + private static final int MAX_INTRA_STOP_WALK_DISTANCE_METERS = 15; private final StopConsolidationService service; public DecorateConsolidatedStopNames(StopConsolidationService service) { @@ -22,6 +25,7 @@ public DecorateConsolidatedStopNames(StopConsolidationService service) { @Override public void decorate(Itinerary itinerary) { replaceConsolidatedStops(itinerary); + removeShortWalkLegs(itinerary); } /** @@ -51,6 +55,43 @@ private void replaceConsolidatedStops(Itinerary i) { }); } + /** + * Removes walk legs from and to a consolidated stop if they are deemed "short". This means that + * they are from a different element of the consolidated stop. + */ + private void removeShortWalkLegs(Itinerary itinerary) { + var legs = new ArrayList<>(itinerary.getLegs()); + var first = legs.getFirst(); + if ( + service.isPartOfConsolidatedStop(first.getTo().stop) && + isShortWalkLeg(first) + ) { + legs.removeFirst(); + } + var last = legs.getLast(); + if ( + service.isPartOfConsolidatedStop(last.getFrom().stop) && + isShortWalkLeg(last) + ) { + legs.removeLast(); + } + + var transfersRemoved = legs.stream().filter(l -> !isTransferWithinConsolidatedStop(l)).toList(); + + itinerary.setLegs(transfersRemoved); + } + + private boolean isTransferWithinConsolidatedStop(Leg l) { + return isShortWalkLeg(l) && + service.isPartOfConsolidatedStop(l.getFrom().stop) && + service.isPartOfConsolidatedStop(l.getTo().stop); + } + + private static boolean isShortWalkLeg(Leg leg) { + return leg.isWalkingLeg() && + leg.getDistanceMeters() < MAX_INTRA_STOP_WALK_DISTANCE_METERS; + } + /** * Figures out if the from/to stops are part of a consolidated stop group and therefore * some stops need to be replaced. diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationModule.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationModule.java similarity index 82% rename from src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationModule.java rename to application/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationModule.java index 100941d88d4..c4fca42d129 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationModule.java +++ b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationModule.java @@ -4,14 +4,13 @@ import java.util.Collection; import java.util.List; import java.util.Objects; -import javax.annotation.Nonnull; import org.opentripplanner.datastore.api.DataSource; import org.opentripplanner.ext.stopconsolidation.internal.DefaultStopConsolidationService; import org.opentripplanner.ext.stopconsolidation.model.ConsolidatedStopGroup; import org.opentripplanner.ext.stopconsolidation.model.StopReplacement; import org.opentripplanner.graph_builder.model.GraphBuilderModule; import org.opentripplanner.transit.model.network.TripPattern; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,18 +25,18 @@ */ public class StopConsolidationModule implements GraphBuilderModule { - private static final Logger LOG = LoggerFactory.getLogger(TripPattern.class); + private static final Logger LOG = LoggerFactory.getLogger(StopConsolidationModule.class); private final StopConsolidationRepository repository; - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; private final Collection groups; public StopConsolidationModule( - TransitModel transitModel, + TimetableRepository timetableRepository, StopConsolidationRepository repository, Collection groups ) { - this.transitModel = Objects.requireNonNull(transitModel); + this.timetableRepository = Objects.requireNonNull(timetableRepository); this.repository = Objects.requireNonNull(repository); this.groups = Objects.requireNonNull(groups); } @@ -46,23 +45,22 @@ public StopConsolidationModule( public void buildGraph() { repository.addGroups(groups); - var service = new DefaultStopConsolidationService(repository, transitModel); + var service = new DefaultStopConsolidationService(repository, timetableRepository); var stopsToReplace = service.secondaryStops(); var replacements = service.replacements(); - transitModel + timetableRepository .getAllTripPatterns() .stream() .filter(pattern -> pattern.containsAnyStopId(stopsToReplace)) .forEach(pattern -> { LOG.info("Replacing stop(s) in pattern {}", pattern); var modifiedPattern = modifyStopsInPattern(pattern, replacements); - transitModel.addTripPattern(modifiedPattern.getId(), modifiedPattern); + timetableRepository.addTripPattern(modifiedPattern.getId(), modifiedPattern); }); } - @Nonnull private TripPattern modifyStopsInPattern( TripPattern pattern, List replacements @@ -73,14 +71,14 @@ private TripPattern modifyStopsInPattern( } public static StopConsolidationModule of( - TransitModel transitModel, + TimetableRepository timetableRepository, StopConsolidationRepository repo, DataSource ds ) { LOG.info("Reading stop consolidation information from '{}'", ds); try (var inputStream = ds.asInputStream()) { var groups = StopConsolidationParser.parseGroups(inputStream); - return new StopConsolidationModule(transitModel, repo, groups); + return new StopConsolidationModule(timetableRepository, repo, groups); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationParser.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationParser.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationParser.java rename to application/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationParser.java diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationRepository.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationRepository.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationRepository.java rename to application/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationRepository.java diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java similarity index 93% rename from src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java rename to application/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java index 68efe8744cc..0457212e66a 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java +++ b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java @@ -2,6 +2,7 @@ import java.util.List; import java.util.Optional; +import javax.annotation.Nullable; import org.opentripplanner.ext.stopconsolidation.model.StopReplacement; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.organization.Agency; @@ -44,5 +45,5 @@ public interface StopConsolidationService { */ Optional primaryStop(FeedScopedId id); - boolean isPartOfConsolidatedStop(StopLocation sl); + boolean isPartOfConsolidatedStop(@Nullable StopLocation sl); } diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/configure/StopConsolidationRepositoryModule.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/configure/StopConsolidationRepositoryModule.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/stopconsolidation/configure/StopConsolidationRepositoryModule.java rename to application/src/ext/java/org/opentripplanner/ext/stopconsolidation/configure/StopConsolidationRepositoryModule.java diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/configure/StopConsolidationServiceModule.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/configure/StopConsolidationServiceModule.java similarity index 77% rename from src/ext/java/org/opentripplanner/ext/stopconsolidation/configure/StopConsolidationServiceModule.java rename to application/src/ext/java/org/opentripplanner/ext/stopconsolidation/configure/StopConsolidationServiceModule.java index 3851435641c..5c829b20b67 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/configure/StopConsolidationServiceModule.java +++ b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/configure/StopConsolidationServiceModule.java @@ -7,7 +7,7 @@ import org.opentripplanner.ext.stopconsolidation.StopConsolidationRepository; import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; import org.opentripplanner.ext.stopconsolidation.internal.DefaultStopConsolidationService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; @Module public class StopConsolidationServiceModule { @@ -15,7 +15,10 @@ public class StopConsolidationServiceModule { @Provides @Singleton @Nullable - StopConsolidationService service(@Nullable StopConsolidationRepository repo, TransitModel tm) { + StopConsolidationService service( + @Nullable StopConsolidationRepository repo, + TimetableRepository tm + ) { if (repo == null) { return null; } else { diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationRepository.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationRepository.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationRepository.java rename to application/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationRepository.java diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java similarity index 80% rename from src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java rename to application/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java index 9f31e366be5..8e6f31fb6fe 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java +++ b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java @@ -4,15 +4,15 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; -import javax.annotation.Nonnull; import org.opentripplanner.ext.stopconsolidation.StopConsolidationRepository; +import javax.annotation.Nullable; import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; import org.opentripplanner.ext.stopconsolidation.model.ConsolidatedStopGroup; import org.opentripplanner.ext.stopconsolidation.model.StopReplacement; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.StopLocation; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,14 +21,14 @@ public class DefaultStopConsolidationService implements StopConsolidationService private static final Logger LOG = LoggerFactory.getLogger(DefaultStopConsolidationService.class); private final StopConsolidationRepository repo; - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; public DefaultStopConsolidationService( StopConsolidationRepository repo, - TransitModel transitModel + TimetableRepository timetableRepository ) { this.repo = Objects.requireNonNull(repo); - this.transitModel = Objects.requireNonNull(transitModel); + this.timetableRepository = Objects.requireNonNull(timetableRepository); } @Override @@ -37,7 +37,7 @@ public List replacements() { .groups() .stream() .flatMap(group -> { - var primaryStop = transitModel.getStopModel().getRegularStop(group.primary()); + var primaryStop = timetableRepository.getSiteRepository().getRegularStop(group.primary()); if (primaryStop == null) { LOG.error( "Could not find primary stop with id {}. Ignoring stop group {}.", @@ -68,8 +68,12 @@ public boolean isSecondaryStop(StopLocation stop) { } @Override - public boolean isPartOfConsolidatedStop(StopLocation sl) { - return isSecondaryStop(sl) || isPrimaryStop(sl); + public boolean isPartOfConsolidatedStop(@Nullable StopLocation sl) { + if (sl == null) { + return false; + } else { + return isSecondaryStop(sl) || isPrimaryStop(sl); + } } @Override @@ -86,7 +90,6 @@ public StopLocation agencySpecificStop(StopLocation stop, Agency agency) { } } - @Nonnull private Optional findAgencySpecificStop(StopLocation stop, Agency agency) { return repo .groups() @@ -95,7 +98,7 @@ private Optional findAgencySpecificStop(StopLocation stop, Agency .flatMap(g -> g.secondaries().stream()) .filter(secondary -> secondary.getFeedId().equals(agency.getId().getFeedId())) .findAny() - .map(id -> transitModel.getStopModel().getRegularStop(id)); + .map(id -> timetableRepository.getSiteRepository().getRegularStop(id)); } @Override @@ -107,6 +110,6 @@ public Optional primaryStop(FeedScopedId id) { .map(ConsolidatedStopGroup::primary) .findAny() .orElse(id); - return Optional.ofNullable(transitModel.getStopModel().getRegularStop(primaryId)); + return Optional.ofNullable(timetableRepository.getSiteRepository().getRegularStop(primaryId)); } } diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopGroup.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopGroup.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopGroup.java rename to application/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopGroup.java diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLeg.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLeg.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLeg.java rename to application/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLeg.java diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/StopReplacement.java b/application/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/StopReplacement.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/stopconsolidation/model/StopReplacement.java rename to application/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/StopReplacement.java diff --git a/src/ext/java/org/opentripplanner/ext/transferanalyzer/DirectTransferAnalyzer.java b/application/src/ext/java/org/opentripplanner/ext/transferanalyzer/DirectTransferAnalyzer.java similarity index 95% rename from src/ext/java/org/opentripplanner/ext/transferanalyzer/DirectTransferAnalyzer.java rename to application/src/ext/java/org/opentripplanner/ext/transferanalyzer/DirectTransferAnalyzer.java index 979912c5f37..61cd9a0789b 100644 --- a/src/ext/java/org/opentripplanner/ext/transferanalyzer/DirectTransferAnalyzer.java +++ b/application/src/ext/java/org/opentripplanner/ext/transferanalyzer/DirectTransferAnalyzer.java @@ -18,7 +18,7 @@ import org.opentripplanner.routing.graphfinder.StreetGraphFinder; import org.opentripplanner.street.model.vertex.TransitStopVertex; import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,18 +41,18 @@ public class DirectTransferAnalyzer implements GraphBuilderModule { private static final Logger LOG = LoggerFactory.getLogger(DirectTransferAnalyzer.class); private final Graph graph; - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; private final DataImportIssueStore issueStore; private final double radiusMeters; public DirectTransferAnalyzer( Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, DataImportIssueStore issueStore, double radiusMeters ) { this.graph = graph; - this.transitModel = transitModel; + this.timetableRepository = timetableRepository; this.issueStore = issueStore; this.radiusMeters = radiusMeters; } @@ -60,7 +60,7 @@ public DirectTransferAnalyzer( @Override public void buildGraph() { /* Initialize transit index which is needed by the nearby stop finder. */ - transitModel.index(); + timetableRepository.index(); LOG.info("Analyzing transfers (this can be time consuming)..."); @@ -68,7 +68,7 @@ public void buildGraph() { List directTransfersNotFound = new ArrayList<>(); DirectGraphFinder nearbyStopFinderEuclidian = new DirectGraphFinder( - transitModel.getStopModel()::findRegularStops + timetableRepository.getSiteRepository()::findRegularStops ); StreetGraphFinder nearbyStopFinderStreets = new StreetGraphFinder(graph); diff --git a/src/ext/java/org/opentripplanner/ext/transferanalyzer/annotations/TransferCouldNotBeRouted.java b/application/src/ext/java/org/opentripplanner/ext/transferanalyzer/annotations/TransferCouldNotBeRouted.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/transferanalyzer/annotations/TransferCouldNotBeRouted.java rename to application/src/ext/java/org/opentripplanner/ext/transferanalyzer/annotations/TransferCouldNotBeRouted.java diff --git a/src/ext/java/org/opentripplanner/ext/transferanalyzer/annotations/TransferRoutingDistanceTooLong.java b/application/src/ext/java/org/opentripplanner/ext/transferanalyzer/annotations/TransferRoutingDistanceTooLong.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/transferanalyzer/annotations/TransferRoutingDistanceTooLong.java rename to application/src/ext/java/org/opentripplanner/ext/transferanalyzer/annotations/TransferRoutingDistanceTooLong.java diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java index 29701ee2307..f1fde4917cd 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java @@ -109,7 +109,7 @@ public TileJson getTileJson( private List getFeedInfos() { return serverContext .transitService() - .getFeedIds() + .listFeedIds() .stream() .map(serverContext.transitService()::getFeedInfo) .filter(Predicate.not(Objects::isNull)) @@ -140,12 +140,12 @@ private static LayerBuilder createLayerBuilder( layerParameters ); case VehicleParking -> new VehicleParkingsLayerBuilder( - context.graph(), + context.vehicleParkingService(), layerParameters, locale ); case VehicleParkingGroup -> new VehicleParkingGroupsLayerBuilder( - context.graph(), + context.vehicleParkingService(), layerParameters, locale ); diff --git a/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java new file mode 100644 index 00000000000..38a27d4b4c4 --- /dev/null +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java @@ -0,0 +1,73 @@ +package org.opentripplanner.ext.vectortiles.layers; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.temporal.TemporalAdjusters; +import java.util.Collection; +import java.util.List; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; +import org.opentripplanner.apis.gtfs.model.LocalDateRange; +import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.transit.service.PatternByServiceDatesFilter; +import org.opentripplanner.transit.service.TransitService; + +/** + * Predicates for filtering elements of vector tile layers. Currently only contains predicates + * for {@link RegularStop}. Once more types need to be filtered, this may need some refactoring. + */ +public class LayerFilters { + + /** + * No filter is applied: all stops are included in the result. + */ + public static final Predicate NO_FILTER = x -> true; + + /** + * Returns a predicate which only includes stop which are visited by a pattern that is in the current + * "service week", which lasts from Sunday to Sunday. + */ + public static Predicate buildCurrentServiceWeekPredicate( + Function> getPatternsForStop, + Function> getServiceDatesForTrip, + Supplier nowSupplier + ) { + var serviceDate = nowSupplier.get(); + var lastSunday = serviceDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY)); + var nextSundayPlusOne = serviceDate.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)).plusDays(1); + + var filter = new PatternByServiceDatesFilter( + // reminder, the end of the date range is exclusive so it's the next Sunday plus one day + new LocalDateRange(lastSunday, nextSundayPlusOne), + // not used + route -> List.of(), + getServiceDatesForTrip + ); + + return regularStop -> { + var patterns = getPatternsForStop.apply(regularStop); + var patternsInCurrentWeek = filter.filterPatterns(patterns); + return !patternsInCurrentWeek.isEmpty(); + }; + } + + public static Predicate forType(FilterType type, TransitService transitService) { + return switch (type) { + case NONE -> NO_FILTER; + case SUNDAY_TO_SUNDAY_SERVICE_WEEK -> buildCurrentServiceWeekPredicate( + transitService::findPatterns, + trip -> + transitService.getCalendarService().getServiceDatesForServiceId(trip.getServiceId()), + () -> LocalDate.now(transitService.getTimeZone()) + ); + }; + } + + public enum FilterType { + NONE, + SUNDAY_TO_SUNDAY_SERVICE_WEEK, + } +} diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapper.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapper.java similarity index 95% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapper.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapper.java index ea6f9225e11..3a5a33103df 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopPropertyMapper.java @@ -28,7 +28,7 @@ protected AreaStopPropertyMapper( } protected static AreaStopPropertyMapper create(TransitService transitService, Locale locale) { - return new AreaStopPropertyMapper(transitService::getRoutesForStop, locale); + return new AreaStopPropertyMapper(transitService::findRoutes, locale); } @Override diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopsLayerBuilder.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopsLayerBuilder.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopsLayerBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/areastops/AreaStopsLayerBuilder.java diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java similarity index 94% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java index 18b4a5f388d..6268db83b04 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java @@ -44,7 +44,7 @@ public Collection map(Station station) { "type", childStops .stream() - .flatMap(stop -> transitService.getPatternsForStop(stop).stream()) + .flatMap(stop -> transitService.findPatterns(stop).stream()) .map(tripPattern -> tripPattern.getMode().name()) .distinct() .collect(Collectors.joining(",")) @@ -60,7 +60,7 @@ public Collection map(Station station) { OBJECT_MAPPER.writeValueAsString( childStops .stream() - .flatMap(stop -> transitService.getRoutesForStop(stop).stream()) + .flatMap(stop -> transitService.findRoutes(stop).stream()) .distinct() .map(route -> { var obj = OBJECT_MAPPER.createObjectNode(); diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java similarity index 92% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java index 449a1489d89..c157621a740 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java @@ -23,7 +23,7 @@ public class StationsLayerBuilder extends LayerBuilder { MapperType.Digitransit, DigitransitStationPropertyMapper::create ); - private final TransitService transitModel; + private final TransitService transitService; public StationsLayerBuilder( TransitService transitService, @@ -35,12 +35,12 @@ public StationsLayerBuilder( layerParameters.name(), layerParameters.expansionFactor() ); - this.transitModel = transitService; + this.transitService = transitService; } protected List getGeometries(Envelope query) { - return transitModel - .getStations() + return transitService + .listStations() .stream() .map(station -> { Coordinate coordinate = station.getCoordinate().asJtsCoordinate(); diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitRealtimeStopPropertyMapper.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitRealtimeStopPropertyMapper.java similarity index 93% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitRealtimeStopPropertyMapper.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitRealtimeStopPropertyMapper.java index cf555d6412f..6fb2783f7cb 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitRealtimeStopPropertyMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitRealtimeStopPropertyMapper.java @@ -8,12 +8,12 @@ import java.util.List; import java.util.Locale; import org.opentripplanner.apis.support.mapping.PropertyMapper; -import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.routing.stoptimes.ArrivalDeparture; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.collection.ListUtils; public class DigitransitRealtimeStopPropertyMapper extends PropertyMapper { @@ -36,7 +36,7 @@ protected Collection map(RegularStop stop) { var serviceDate = LocalDate.now(transitService.getTimeZone()); boolean stopTimesExist = transitService - .getStopTimesForStop(stop, serviceDate, ArrivalDeparture.BOTH, true) + .findStopTimesInPattern(stop, serviceDate, ArrivalDeparture.BOTH, true) .stream() .anyMatch(stopTime -> stopTime.times.size() > 0); diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java similarity index 96% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java index edf9c7d8188..0322a2749b4 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java @@ -61,7 +61,7 @@ protected static Collection getBaseKeyValues( protected static String getRoutes(TransitService transitService, RegularStop stop) { try { var objects = transitService - .getRoutesForStop(stop) + .findRoutes(stop) .stream() .map(route -> { var routeObject = OBJECT_MAPPER.createObjectNode(); @@ -76,7 +76,7 @@ protected static String getRoutes(TransitService transitService, RegularStop sto } protected static String getType(TransitService transitService, RegularStop stop) { - Collection patternsForStop = transitService.getPatternsForStop(stop); + Collection patternsForStop = transitService.findPatterns(stop); return patternsForStop .stream() diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java similarity index 77% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java index aa664497728..141157f8f3e 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java @@ -5,24 +5,20 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.function.BiFunction; -import java.util.stream.Collectors; +import java.util.function.Predicate; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; +import org.opentripplanner.ext.vectortiles.layers.LayerFilters; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.service.TransitService; -public class StopsLayerBuilder extends LayerBuilder { +public class StopsLayerBuilder extends LayerBuilder { - static Map>> mappers = Map.of( - MapperType.Digitransit, - DigitransitStopPropertyMapper::create - ); private final TransitService transitService; + private final Predicate filter; public StopsLayerBuilder( TransitService transitService, @@ -30,7 +26,7 @@ public StopsLayerBuilder( Locale locale ) { super( - (PropertyMapper) Map + Map .ofEntries( entry(MapperType.Digitransit, new DigitransitStopPropertyMapper(transitService, locale)), entry( @@ -43,12 +39,14 @@ public StopsLayerBuilder( layerParameters.expansionFactor() ); this.transitService = transitService; + this.filter = LayerFilters.forType(layerParameters.filterType(), transitService); } protected List getGeometries(Envelope query) { return transitService .findRegularStops(query) .stream() + .filter(filter) .map(stop -> { Geometry point = stop.getGeometry(); @@ -56,7 +54,7 @@ protected List getGeometries(Envelope query) { return point; }) - .collect(Collectors.toList()); + .toList(); } enum MapperType { diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java similarity index 93% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java index 892d4907395..702fbac9e07 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java @@ -4,11 +4,10 @@ import java.util.Collection; import java.util.List; import java.util.Locale; -import javax.annotation.Nonnull; 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; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; public class DigitransitVehicleParkingPropertyMapper extends PropertyMapper { @@ -27,7 +26,6 @@ protected Collection map(VehicleParking vehicleParking) { return basicMapping(vehicleParking); } - @Nonnull protected ArrayList basicMapping(VehicleParking vehicleParking) { return new ArrayList<>( List.of( diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java similarity index 95% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java index bccc2b4de4d..8f745a4e633 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java @@ -9,8 +9,8 @@ import org.opentripplanner.framework.json.ObjectMappers; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.model.calendar.openinghours.OsmOpeningHoursSupport; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; public class StadtnaviVehicleParkingPropertyMapper extends PropertyMapper { diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingAndGroup.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingAndGroup.java similarity index 69% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingAndGroup.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingAndGroup.java index 7093dbb3407..5968f000d2d 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingAndGroup.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingAndGroup.java @@ -1,8 +1,8 @@ package org.opentripplanner.ext.vectortiles.layers.vehicleparkings; import java.util.Collection; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingGroup; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingGroup; /** * Record that holds {@link VehicleParkingGroup} and a set of {@link VehicleParking} that belong to diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java similarity index 89% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java index 0cd1d84868b..36217e05972 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java @@ -13,7 +13,7 @@ import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; -import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; public class VehicleParkingGroupsLayerBuilder extends LayerBuilder { @@ -21,10 +21,10 @@ public class VehicleParkingGroupsLayerBuilder extends LayerBuilder layerParameters, Locale locale ) { @@ -33,14 +33,13 @@ public VehicleParkingGroupsLayerBuilder( layerParameters.name(), layerParameters.expansionFactor() ); - this.graph = graph; + this.service = service; } @Override protected List getGeometries(Envelope query) { - return graph - .getVehicleParkingService() - .getVehicleParkingGroups() + return service + .listVehicleParkingGroups() .asMap() .entrySet() .stream() diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java similarity index 85% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java index 95326172415..22fb75f7b49 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java +++ b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java @@ -16,8 +16,8 @@ import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; -import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; public class VehicleParkingsLayerBuilder extends LayerBuilder { @@ -28,10 +28,10 @@ public class VehicleParkingsLayerBuilder extends LayerBuilder { ), entry(MapperType.Digitransit, DigitransitVehicleParkingPropertyMapper::create) ); - private final Graph graph; + private final VehicleParkingService service; public VehicleParkingsLayerBuilder( - Graph graph, + VehicleParkingService service, LayerParameters layerParameters, Locale locale ) { @@ -40,14 +40,13 @@ public VehicleParkingsLayerBuilder( layerParameters.name(), layerParameters.expansionFactor() ); - this.graph = graph; + this.service = service; } @Override protected List getGeometries(Envelope query) { - return graph - .getVehicleParkingService() - .getVehicleParkings() + return service + .listVehicleParkings().stream() .map(vehicleParking -> { Coordinate coordinate = vehicleParking.getCoordinate().asJtsCoordinate(); Point point = GeometryUtils.getGeometryFactory().createPoint(coordinate); diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalPlacesLayerBuilder.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalPlacesLayerBuilder.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalPlacesLayerBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalPlacesLayerBuilder.java diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalStationsLayerBuilder.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalStationsLayerBuilder.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalStationsLayerBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalStationsLayerBuilder.java diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalVehiclesLayerBuilder.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalVehiclesLayerBuilder.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalVehiclesLayerBuilder.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalVehiclesLayerBuilder.java diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java b/application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java rename to application/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdater.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdater.java similarity index 90% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdater.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdater.java index 9216eb79995..decbda7abf6 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdater.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdater.java @@ -7,12 +7,12 @@ import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.framework.json.ObjectMappers; -import org.opentripplanner.framework.tostring.ToStringBuilder; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingState; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingState; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.updater.spi.GenericJsonDataSource; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Vehicle parking updater for Bikeep's API. diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdaterParameters.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdaterParameters.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdaterParameters.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdaterParameters.java diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdater.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdater.java similarity index 94% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdater.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdater.java index 2bed1121913..eba0547dbf5 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdater.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdater.java @@ -1,6 +1,6 @@ package org.opentripplanner.ext.vehicleparking.bikely; -import static org.opentripplanner.routing.vehicle_parking.VehicleParkingState.OPERATIONAL; +import static org.opentripplanner.service.vehicleparking.model.VehicleParkingState.OPERATIONAL; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -17,9 +17,9 @@ import org.opentripplanner.framework.io.OtpHttpClient; import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.framework.json.ObjectMappers; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingState; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingState; import org.opentripplanner.transit.model.basic.LocalizedMoney; import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.framework.FeedScopedId; diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdaterParameters.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdaterParameters.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdaterParameters.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdaterParameters.java diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslFacilitiesDownloader.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslFacilitiesDownloader.java similarity index 96% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslFacilitiesDownloader.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslFacilitiesDownloader.java index dcf4ffe29d9..3d6c1943061 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslFacilitiesDownloader.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslFacilitiesDownloader.java @@ -13,8 +13,8 @@ import org.opentripplanner.framework.io.OtpHttpClient; import org.opentripplanner.framework.io.OtpHttpClientException; import org.opentripplanner.framework.io.OtpHttpClientFactory; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingGroup; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingGroup; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubToVehicleParkingGroupMapper.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubToVehicleParkingGroupMapper.java similarity index 97% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubToVehicleParkingGroupMapper.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubToVehicleParkingGroupMapper.java index 1ef0ef3597b..2c4dcad73d6 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubToVehicleParkingGroupMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubToVehicleParkingGroupMapper.java @@ -13,7 +13,7 @@ import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.framework.i18n.TranslatedString; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingGroup; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingGroup; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubsDownloader.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubsDownloader.java similarity index 97% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubsDownloader.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubsDownloader.java index f1f98b6139c..62e76b65035 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubsDownloader.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslHubsDownloader.java @@ -12,7 +12,7 @@ import org.opentripplanner.framework.io.OtpHttpClient; import org.opentripplanner.framework.io.OtpHttpClientException; import org.opentripplanner.framework.io.OtpHttpClientFactory; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingGroup; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingGroup; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkPatch.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkPatch.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkPatch.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkPatch.java diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkToVehicleParkingMapper.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkToVehicleParkingMapper.java similarity index 96% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkToVehicleParkingMapper.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkToVehicleParkingMapper.java index 1f69458dd1f..c3e74f7285e 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkToVehicleParkingMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkToVehicleParkingMapper.java @@ -19,10 +19,10 @@ import org.opentripplanner.framework.i18n.TranslatedString; import org.opentripplanner.model.calendar.openinghours.OHCalendar; import org.opentripplanner.model.calendar.openinghours.OpeningHoursCalendarService; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingGroup; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingState; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingGroup; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingState; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdater.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdater.java similarity index 94% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdater.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdater.java index f5c5b33ef29..7933e968537 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdater.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdater.java @@ -6,10 +6,10 @@ import org.opentripplanner.framework.io.JsonDataListDownloader; import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.model.calendar.openinghours.OpeningHoursCalendarService; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingGroup; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces.VehicleParkingSpacesBuilder; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingGroup; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces.VehicleParkingSpacesBuilder; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.updater.spi.DataSource; import org.slf4j.Logger; diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdaterParameters.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdaterParameters.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdaterParameters.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdaterParameters.java diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUtilizationToPatchMapper.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUtilizationToPatchMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUtilizationToPatchMapper.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUtilizationToPatchMapper.java diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/BicycleParkAPIUpdater.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/BicycleParkAPIUpdater.java similarity index 92% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/BicycleParkAPIUpdater.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/BicycleParkAPIUpdater.java index 21898bc3956..76fd73d3c18 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/BicycleParkAPIUpdater.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/BicycleParkAPIUpdater.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.model.calendar.openinghours.OpeningHoursCalendarService; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; /** * Vehicle parking updater class that extends the {@link ParkAPIUpdater}. Meant for reading bicycle diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/CarParkAPIUpdater.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/CarParkAPIUpdater.java similarity index 92% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/CarParkAPIUpdater.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/CarParkAPIUpdater.java index 445f6bfbda3..06064f4896a 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/CarParkAPIUpdater.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/CarParkAPIUpdater.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import org.opentripplanner.model.calendar.openinghours.OpeningHoursCalendarService; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; /** * Vehicle parking updater class that extends the {@link ParkAPIUpdater}. Meant for reading car diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdater.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdater.java similarity index 93% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdater.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdater.java index c6f775e588f..3e206fc660d 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdater.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdater.java @@ -12,15 +12,15 @@ import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.framework.i18n.TranslatedString; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.calendar.openinghours.OHCalendar; import org.opentripplanner.model.calendar.openinghours.OpeningHoursCalendarService; -import org.opentripplanner.openstreetmap.OSMOpeningHoursParser; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingState; +import org.opentripplanner.osm.OsmOpeningHoursParser; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingState; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.updater.spi.GenericJsonDataSource; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,7 +36,7 @@ abstract class ParkAPIUpdater extends GenericJsonDataSource { private final String feedId; private final Collection staticTags; - private final OSMOpeningHoursParser osmOpeningHoursParser; + private final OsmOpeningHoursParser osmOpeningHoursParser; private final String url; public ParkAPIUpdater( @@ -47,7 +47,7 @@ public ParkAPIUpdater( this.feedId = parameters.feedId(); this.staticTags = parameters.tags(); this.osmOpeningHoursParser = - new OSMOpeningHoursParser(openingHoursCalendarService, parameters.timeZone()); + new OsmOpeningHoursParser(openingHoursCalendarService, parameters.timeZone()); this.url = parameters.url(); } diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdaterParameters.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdaterParameters.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdaterParameters.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdaterParameters.java diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmDatasource.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmDatasource.java similarity index 97% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmDatasource.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmDatasource.java index abfdf4d29be..e05cfdb42ad 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmDatasource.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmDatasource.java @@ -8,11 +8,11 @@ import org.entur.siri21.util.SiriXml; import org.opentripplanner.framework.io.OtpHttpClient; import org.opentripplanner.framework.io.OtpHttpClientFactory; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.updater.spi.DataSource; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.vehicle_parking.AvailabiltyUpdate; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.org.siri.siri21.FacilityConditionStructure; diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterParameters.java b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterParameters.java similarity index 92% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterParameters.java rename to application/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterParameters.java index 5afdffb7067..daecb2b2bb9 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterParameters.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterParameters.java @@ -5,14 +5,13 @@ import java.net.URI; import java.time.Duration; -import org.opentripplanner.ext.vehicleparking.noi.NoiUpdater; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.vehicle_parking.VehicleParkingSourceType; import org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters; /** * Class that extends {@link VehicleParkingUpdaterParameters} with parameters required by {@link - * NoiUpdater}. + * SiriFmDatasource}. */ public record SiriFmUpdaterParameters( String configRef, diff --git a/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalParameters.java b/application/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalParameters.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalParameters.java rename to application/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalParameters.java diff --git a/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalServiceDirectoryFetcher.java b/application/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalServiceDirectoryFetcher.java similarity index 97% rename from src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalServiceDirectoryFetcher.java rename to application/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalServiceDirectoryFetcher.java index 03b0acd59cd..dc0fa2868ec 100644 --- a/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalServiceDirectoryFetcher.java +++ b/application/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/VehicleRentalServiceDirectoryFetcher.java @@ -18,6 +18,7 @@ import org.opentripplanner.updater.spi.GraphUpdater; import org.opentripplanner.updater.vehicle_rental.VehicleRentalUpdater; import org.opentripplanner.updater.vehicle_rental.datasources.VehicleRentalDataSourceFactory; +import org.opentripplanner.updater.vehicle_rental.datasources.params.RentalPickupType; import org.opentripplanner.updater.vehicle_rental.datasources.params.GbfsVehicleRentalDataSourceParameters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -110,7 +111,9 @@ private static List buildListOfNetworksFr networkName, networkParams.geofencingZones(), // overloadingAllowed - not part of GBFS, not supported here - false + false, + // rentalPickupType not supported + RentalPickupType.ALL ) ); } else { diff --git a/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/api/NetworkParameters.java b/application/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/api/NetworkParameters.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/api/NetworkParameters.java rename to application/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/api/NetworkParameters.java diff --git a/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/api/VehicleRentalServiceDirectoryFetcherParameters.java b/application/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/api/VehicleRentalServiceDirectoryFetcherParameters.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/api/VehicleRentalServiceDirectoryFetcherParameters.java rename to application/src/ext/java/org/opentripplanner/ext/vehiclerentalservicedirectory/api/VehicleRentalServiceDirectoryFetcherParameters.java diff --git a/src/ext/resources/org/opentripplanner/ext/vectortiles/router-config.json b/application/src/ext/resources/org/opentripplanner/ext/vectortiles/router-config.json similarity index 99% rename from src/ext/resources/org/opentripplanner/ext/vectortiles/router-config.json rename to application/src/ext/resources/org/opentripplanner/ext/vectortiles/router-config.json index df325d076a3..5eb5c3976da 100644 --- a/src/ext/resources/org/opentripplanner/ext/vectortiles/router-config.json +++ b/application/src/ext/resources/org/opentripplanner/ext/vectortiles/router-config.json @@ -13,4 +13,3 @@ ] } } - diff --git a/src/main/java/META-INF/MANIFEST.MF b/application/src/main/java/META-INF/MANIFEST.MF similarity index 100% rename from src/main/java/META-INF/MANIFEST.MF rename to application/src/main/java/META-INF/MANIFEST.MF diff --git a/src/main/java/com/jhlabs/awt/ShapeStroke.java b/application/src/main/java/com/jhlabs/awt/ShapeStroke.java similarity index 100% rename from src/main/java/com/jhlabs/awt/ShapeStroke.java rename to application/src/main/java/com/jhlabs/awt/ShapeStroke.java diff --git a/src/main/java/com/jhlabs/awt/TextStroke.java b/application/src/main/java/com/jhlabs/awt/TextStroke.java similarity index 100% rename from src/main/java/com/jhlabs/awt/TextStroke.java rename to application/src/main/java/com/jhlabs/awt/TextStroke.java diff --git a/src/main/java/org/opentripplanner/api/common/LocationStringParser.java b/application/src/main/java/org/opentripplanner/api/common/LocationStringParser.java similarity index 100% rename from src/main/java/org/opentripplanner/api/common/LocationStringParser.java rename to application/src/main/java/org/opentripplanner/api/common/LocationStringParser.java diff --git a/src/main/java/org/opentripplanner/api/common/Message.java b/application/src/main/java/org/opentripplanner/api/common/Message.java similarity index 100% rename from src/main/java/org/opentripplanner/api/common/Message.java rename to application/src/main/java/org/opentripplanner/api/common/Message.java diff --git a/src/main/java/org/opentripplanner/api/common/OTPExceptionMapper.java b/application/src/main/java/org/opentripplanner/api/common/OTPExceptionMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/api/common/OTPExceptionMapper.java rename to application/src/main/java/org/opentripplanner/api/common/OTPExceptionMapper.java diff --git a/src/main/java/org/opentripplanner/api/error/PlannerError.java b/application/src/main/java/org/opentripplanner/api/error/PlannerError.java similarity index 100% rename from src/main/java/org/opentripplanner/api/error/PlannerError.java rename to application/src/main/java/org/opentripplanner/api/error/PlannerError.java diff --git a/src/main/java/org/opentripplanner/api/model/serverinfo/ApiConfigInfo.java b/application/src/main/java/org/opentripplanner/api/model/serverinfo/ApiConfigInfo.java similarity index 100% rename from src/main/java/org/opentripplanner/api/model/serverinfo/ApiConfigInfo.java rename to application/src/main/java/org/opentripplanner/api/model/serverinfo/ApiConfigInfo.java diff --git a/src/main/java/org/opentripplanner/api/model/serverinfo/ApiProjectVersion.java b/application/src/main/java/org/opentripplanner/api/model/serverinfo/ApiProjectVersion.java similarity index 100% rename from src/main/java/org/opentripplanner/api/model/serverinfo/ApiProjectVersion.java rename to application/src/main/java/org/opentripplanner/api/model/serverinfo/ApiProjectVersion.java diff --git a/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java b/application/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java similarity index 100% rename from src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java rename to application/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java diff --git a/src/main/java/org/opentripplanner/api/model/serverinfo/ApiVersionControlInfo.java b/application/src/main/java/org/opentripplanner/api/model/serverinfo/ApiVersionControlInfo.java similarity index 100% rename from src/main/java/org/opentripplanner/api/model/serverinfo/ApiVersionControlInfo.java rename to application/src/main/java/org/opentripplanner/api/model/serverinfo/ApiVersionControlInfo.java diff --git a/src/main/java/org/opentripplanner/api/parameter/ApiRequestMode.java b/application/src/main/java/org/opentripplanner/api/parameter/ApiRequestMode.java similarity index 95% rename from src/main/java/org/opentripplanner/api/parameter/ApiRequestMode.java rename to application/src/main/java/org/opentripplanner/api/parameter/ApiRequestMode.java index 6e19b106033..7ac2c6f7d86 100644 --- a/src/main/java/org/opentripplanner/api/parameter/ApiRequestMode.java +++ b/application/src/main/java/org/opentripplanner/api/parameter/ApiRequestMode.java @@ -12,7 +12,8 @@ public enum ApiRequestMode { TRAM(TransitMode.TRAM), SUBWAY(TransitMode.SUBWAY), RAIL(TransitMode.RAIL), - BUS(TransitMode.BUS, TransitMode.COACH), + BUS(TransitMode.BUS), + COACH(TransitMode.COACH), FERRY(TransitMode.FERRY), CABLE_CAR(TransitMode.CABLE_CAR), GONDOLA(TransitMode.GONDOLA), diff --git a/src/main/java/org/opentripplanner/api/parameter/MIMEImageFormat.java b/application/src/main/java/org/opentripplanner/api/parameter/MIMEImageFormat.java similarity index 100% rename from src/main/java/org/opentripplanner/api/parameter/MIMEImageFormat.java rename to application/src/main/java/org/opentripplanner/api/parameter/MIMEImageFormat.java diff --git a/src/main/java/org/opentripplanner/api/parameter/QualifiedMode.java b/application/src/main/java/org/opentripplanner/api/parameter/QualifiedMode.java similarity index 100% rename from src/main/java/org/opentripplanner/api/parameter/QualifiedMode.java rename to application/src/main/java/org/opentripplanner/api/parameter/QualifiedMode.java diff --git a/src/main/java/org/opentripplanner/api/parameter/QualifiedModeSet.java b/application/src/main/java/org/opentripplanner/api/parameter/QualifiedModeSet.java similarity index 100% rename from src/main/java/org/opentripplanner/api/parameter/QualifiedModeSet.java rename to application/src/main/java/org/opentripplanner/api/parameter/QualifiedModeSet.java diff --git a/src/main/java/org/opentripplanner/api/parameter/Qualifier.java b/application/src/main/java/org/opentripplanner/api/parameter/Qualifier.java similarity index 100% rename from src/main/java/org/opentripplanner/api/parameter/Qualifier.java rename to application/src/main/java/org/opentripplanner/api/parameter/Qualifier.java diff --git a/application/src/main/java/org/opentripplanner/api/parameter/package-info.md b/application/src/main/java/org/opentripplanner/api/parameter/package-info.md new file mode 100644 index 00000000000..75c928773f9 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/api/parameter/package-info.md @@ -0,0 +1,5 @@ +# HTTP query parameters + +This package contains classes which interpret incoming HTTP query parameters. Query parameters +arrive as Strings, and Jersey will automatically call constructors with a single String +argument. diff --git a/src/main/java/org/opentripplanner/api/resource/DebugOutput.java b/application/src/main/java/org/opentripplanner/api/resource/DebugOutput.java similarity index 100% rename from src/main/java/org/opentripplanner/api/resource/DebugOutput.java rename to application/src/main/java/org/opentripplanner/api/resource/DebugOutput.java diff --git a/src/main/java/org/opentripplanner/api/resource/GraphInspectorTileResource.java b/application/src/main/java/org/opentripplanner/api/resource/GraphInspectorTileResource.java similarity index 100% rename from src/main/java/org/opentripplanner/api/resource/GraphInspectorTileResource.java rename to application/src/main/java/org/opentripplanner/api/resource/GraphInspectorTileResource.java diff --git a/src/main/java/org/opentripplanner/api/resource/InspectorLayersList.java b/application/src/main/java/org/opentripplanner/api/resource/InspectorLayersList.java similarity index 100% rename from src/main/java/org/opentripplanner/api/resource/InspectorLayersList.java rename to application/src/main/java/org/opentripplanner/api/resource/InspectorLayersList.java diff --git a/src/main/java/org/opentripplanner/api/resource/ServerInfo.java b/application/src/main/java/org/opentripplanner/api/resource/ServerInfo.java similarity index 100% rename from src/main/java/org/opentripplanner/api/resource/ServerInfo.java rename to application/src/main/java/org/opentripplanner/api/resource/ServerInfo.java diff --git a/src/main/java/org/opentripplanner/api/resource/TransitTimingOutput.java b/application/src/main/java/org/opentripplanner/api/resource/TransitTimingOutput.java similarity index 100% rename from src/main/java/org/opentripplanner/api/resource/TransitTimingOutput.java rename to application/src/main/java/org/opentripplanner/api/resource/TransitTimingOutput.java diff --git a/src/main/java/org/opentripplanner/api/resource/UpdaterStatusResource.java b/application/src/main/java/org/opentripplanner/api/resource/UpdaterStatusResource.java similarity index 100% rename from src/main/java/org/opentripplanner/api/resource/UpdaterStatusResource.java rename to application/src/main/java/org/opentripplanner/api/resource/UpdaterStatusResource.java diff --git a/src/main/java/org/opentripplanner/api/resource/WebMercatorTile.java b/application/src/main/java/org/opentripplanner/api/resource/WebMercatorTile.java similarity index 100% rename from src/main/java/org/opentripplanner/api/resource/WebMercatorTile.java rename to application/src/main/java/org/opentripplanner/api/resource/WebMercatorTile.java diff --git a/src/main/java/org/opentripplanner/apis/APIEndpoints.java b/application/src/main/java/org/opentripplanner/apis/APIEndpoints.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/APIEndpoints.java rename to application/src/main/java/org/opentripplanner/apis/APIEndpoints.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GraphQLRequestContext.java b/application/src/main/java/org/opentripplanner/apis/gtfs/GraphQLRequestContext.java similarity index 90% rename from src/main/java/org/opentripplanner/apis/gtfs/GraphQLRequestContext.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/GraphQLRequestContext.java index dfc3e2d75f8..c3ca214b62f 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/GraphQLRequestContext.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/GraphQLRequestContext.java @@ -1,12 +1,11 @@ package org.opentripplanner.apis.gtfs; -import javax.annotation.Nonnull; import org.opentripplanner.routing.api.RoutingService; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.fares.FareService; import org.opentripplanner.routing.graphfinder.GraphFinder; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleService; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; import org.opentripplanner.service.vehiclerental.VehicleRentalService; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.transit.service.TransitService; @@ -15,8 +14,8 @@ public record GraphQLRequestContext( RoutingService routingService, TransitService transitService, FareService fareService, - VehicleParkingService vehicleParkingService, VehicleRentalService vehicleRentalService, + VehicleParkingService vehicleParkingService, RealtimeVehicleService realTimeVehicleService, GraphFinder graphFinder, RouteRequest defaultRouteRequest @@ -26,8 +25,8 @@ public static GraphQLRequestContext ofServerContext(OtpServerRequestContext cont context.routingService(), context.transitService(), context.graph().getFareService(), - context.graph().getVehicleParkingService(), context.vehicleRentalService(), + context.vehicleParkingService(), context.realtimeVehicleService(), context.graphFinder(), context.defaultRouteRequest() @@ -38,7 +37,6 @@ public static GraphQLRequestContext ofServerContext(OtpServerRequestContext cont * Returns a clone of the default route request. The clone is necessary because one HTTP * request can lead to several GraphQL queries, for example through batch or alias queries. */ - @Nonnull @Override public RouteRequest defaultRouteRequest() { return defaultRouteRequest.clone(); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GraphQLScalars.java b/application/src/main/java/org/opentripplanner/apis/gtfs/GraphQLScalars.java similarity index 96% rename from src/main/java/org/opentripplanner/apis/gtfs/GraphQLScalars.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/GraphQLScalars.java index 8ec3172db52..8427777bd38 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/GraphQLScalars.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/GraphQLScalars.java @@ -16,14 +16,13 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Optional; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.Geometry; import org.opentripplanner.framework.graphql.scalar.DateScalarFactory; import org.opentripplanner.framework.graphql.scalar.DurationScalarFactory; import org.opentripplanner.framework.json.ObjectMappers; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.framework.model.Grams; -import org.opentripplanner.framework.time.OffsetDateTimeParser; +import org.opentripplanner.utils.time.OffsetDateTimeParser; public class GraphQLScalars { @@ -65,8 +64,7 @@ public String parseLiteral(Object input) { .coercing( new Coercing() { @Override - public String serialize(@Nonnull Object dataFetcherResult) - throws CoercingSerializeException { + public String serialize(Object dataFetcherResult) throws CoercingSerializeException { if (dataFetcherResult instanceof ZonedDateTime zdt) { return zdt.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); } else if (dataFetcherResult instanceof OffsetDateTime odt) { @@ -123,8 +121,7 @@ public OffsetDateTime parseLiteral(Object input) throws CoercingParseLiteralExce private static final String VALIDATION_ERROR_MESSAGE = "Not a valid WGS84 coordinate value"; @Override - public Double serialize(@Nonnull Object dataFetcherResult) - throws CoercingSerializeException { + public Double serialize(Object dataFetcherResult) throws CoercingSerializeException { if (dataFetcherResult instanceof Double doubleValue) { return doubleValue; } else if (dataFetcherResult instanceof Float floatValue) { @@ -188,8 +185,7 @@ private static Optional validateCoordinate(double coordinate) { "Cost cannot be negative or greater than %d".formatted(MAX_COST); @Override - public Integer serialize(@Nonnull Object dataFetcherResult) - throws CoercingSerializeException { + public Integer serialize(Object dataFetcherResult) throws CoercingSerializeException { if (dataFetcherResult instanceof Integer intValue) { return intValue; } else if (dataFetcherResult instanceof Cost costValue) { @@ -358,8 +354,7 @@ public Grams parseLiteral(Object input) throws CoercingParseLiteralException { "Value is under 0 or greater than 1."; @Override - public Double serialize(@Nonnull Object dataFetcherResult) - throws CoercingSerializeException { + public Double serialize(Object dataFetcherResult) throws CoercingSerializeException { var validationException = new CoercingSerializeException(VALIDATION_ERROR_MESSAGE); if (dataFetcherResult instanceof Double doubleValue) { return validateRatio(doubleValue).orElseThrow(() -> validationException); @@ -425,8 +420,7 @@ private static Optional validateRatio(double ratio) { "Reluctance needs to be between %s and %s".formatted(MIN_Reluctance, MAX_Reluctance); @Override - public Double serialize(@Nonnull Object dataFetcherResult) - throws CoercingSerializeException { + public Double serialize(Object dataFetcherResult) throws CoercingSerializeException { if (dataFetcherResult instanceof Double doubleValue) { return doubleValue; } else if (dataFetcherResult instanceof Float floatValue) { diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GraphQLUtils.java b/application/src/main/java/org/opentripplanner/apis/gtfs/GraphQLUtils.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/GraphQLUtils.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/GraphQLUtils.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java b/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java b/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java similarity index 98% rename from src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java index 43a8399e70c..34e9b2f8346 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java @@ -52,6 +52,7 @@ import org.opentripplanner.apis.gtfs.datafetchers.PlanConnectionImpl; import org.opentripplanner.apis.gtfs.datafetchers.PlanImpl; import org.opentripplanner.apis.gtfs.datafetchers.QueryTypeImpl; +import org.opentripplanner.apis.gtfs.datafetchers.RentalPlaceTypeResolver; import org.opentripplanner.apis.gtfs.datafetchers.RentalVehicleImpl; import org.opentripplanner.apis.gtfs.datafetchers.RentalVehicleTypeImpl; import org.opentripplanner.apis.gtfs.datafetchers.RideHailingEstimateImpl; @@ -123,6 +124,7 @@ protected static GraphQLSchema buildSchema() { ) .type("Node", type -> type.typeResolver(new NodeTypeResolver())) .type("PlaceInterface", type -> type.typeResolver(new PlaceInterfaceTypeResolver())) + .type("RentalPlace", type -> type.typeResolver(new RentalPlaceTypeResolver())) .type("StopPosition", type -> type.typeResolver(new StopPosition() {})) .type("FareProduct", type -> type.typeResolver(new FareProductTypeResolver())) .type("AlertEntity", type -> type.typeResolver(new AlertEntityTypeResolver())) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/IntrospectionTypeWiring.java b/application/src/main/java/org/opentripplanner/apis/gtfs/IntrospectionTypeWiring.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/IntrospectionTypeWiring.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/IntrospectionTypeWiring.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AgencyImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AgencyImpl.java similarity index 99% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AgencyImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AgencyImpl.java index 8a6d55bb078..d8ed772c9e5 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AgencyImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AgencyImpl.java @@ -107,7 +107,7 @@ public DataFetcher url() { private List getRoutes(DataFetchingEnvironment environment) { return getTransitService(environment) - .getAllRoutes() + .listRoutes() .stream() .filter(route -> route.getAgency().equals(getSource(environment))) .collect(Collectors.toList()); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AlertEntityTypeResolver.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AlertEntityTypeResolver.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AlertEntityTypeResolver.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AlertEntityTypeResolver.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AlertImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AlertImpl.java similarity index 92% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AlertImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AlertImpl.java index 90db8ef1605..d7d937d52de 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AlertImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/AlertImpl.java @@ -23,6 +23,7 @@ import org.opentripplanner.apis.gtfs.model.StopOnRouteModel; import org.opentripplanner.apis.gtfs.model.StopOnTripModel; import org.opentripplanner.apis.gtfs.model.UnknownModel; +import org.opentripplanner.framework.graphql.GraphQLUtils; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.TranslatedString; import org.opentripplanner.routing.alertpatch.EntitySelector; @@ -50,9 +51,7 @@ public DataFetcher agency() { .filter(EntitySelector.Agency.class::isInstance) .findAny() .map(EntitySelector.Agency.class::cast) - .map(entitySelector -> - getTransitService(environment).getAgencyForId(entitySelector.agencyId()) - ) + .map(entitySelector -> getTransitService(environment).getAgency(entitySelector.agencyId())) .orElse(null); } @@ -65,11 +64,11 @@ public DataFetcher alertCause() { public DataFetcher alertDescriptionText() { return environment -> { var alert = getSource(environment); - return alert - .descriptionText() - .or(alert::headerText) - .map(t -> t.toString(environment.getLocale())) - .orElse(FALLBACK_EMPTY_STRING); + var descriptionText = GraphQLUtils.getTranslation( + alert.descriptionText().or(alert::headerText).orElse(null), + environment + ); + return descriptionText != null ? descriptionText : FALLBACK_EMPTY_STRING; }; } @@ -103,11 +102,11 @@ public DataFetcher alertHash() { public DataFetcher alertHeaderText() { return environment -> { var alert = getSource(environment); - return alert - .headerText() - .or(alert::descriptionText) - .map(h -> h.toString(environment.getLocale())) - .orElse(FALLBACK_EMPTY_STRING); + var headerText = GraphQLUtils.getTranslation( + alert.headerText().or(alert::descriptionText).orElse(null), + environment + ); + return headerText != null ? headerText : FALLBACK_EMPTY_STRING; }; } @@ -125,7 +124,7 @@ public DataFetcher alertSeverityLevel() { @Override public DataFetcher alertUrl() { return environment -> - getSource(environment).url().map(u -> u.toString(environment.getLocale())).orElse(null); + GraphQLUtils.getTranslation(getSource(environment).url().orElse(null), environment); } @Override @@ -169,24 +168,24 @@ public DataFetcher> entities() { } if (entitySelector instanceof EntitySelector.Agency) { FeedScopedId id = ((EntitySelector.Agency) entitySelector).agencyId(); - Agency agency = getTransitService(environment).getAgencyForId(id); + Agency agency = getTransitService(environment).getAgency(id); return List.of(getAlertEntityOrUnknown(agency, id.toString(), "agency")); } if (entitySelector instanceof EntitySelector.Route) { FeedScopedId id = ((EntitySelector.Route) entitySelector).routeId(); - Route route = getTransitService(environment).getRouteForId(id); + Route route = getTransitService(environment).getRoute(id); return List.of(getAlertEntityOrUnknown(route, id.toString(), "route")); } if (entitySelector instanceof EntitySelector.Trip) { FeedScopedId id = ((EntitySelector.Trip) entitySelector).tripId(); - Trip trip = getTransitService(environment).getTripForId(id); + Trip trip = getTransitService(environment).getTrip(id); return List.of(getAlertEntityOrUnknown(trip, id.toString(), "trip")); } if (entitySelector instanceof EntitySelector.StopAndRoute stopAndRoute) { FeedScopedId stopId = stopAndRoute.stopId(); FeedScopedId routeId = stopAndRoute.routeId(); StopLocation stop = getTransitService(environment).getRegularStop(stopId); - Route route = getTransitService(environment).getRouteForId(routeId); + Route route = getTransitService(environment).getRoute(routeId); return List.of( stop != null && route != null ? new StopOnRouteModel(stop, route) @@ -204,7 +203,7 @@ public DataFetcher> entities() { FeedScopedId stopId = stopAndTrip.stopId(); FeedScopedId tripId = stopAndTrip.tripId(); StopLocation stop = getTransitService(environment).getRegularStop(stopId); - Trip trip = getTransitService(environment).getTripForId(tripId); + Trip trip = getTransitService(environment).getTrip(tripId); return List.of( stop != null && trip != null ? new StopOnTripModel(stop, trip) @@ -221,7 +220,7 @@ public DataFetcher> entities() { if (entitySelector instanceof EntitySelector.RouteTypeAndAgency) { FeedScopedId agencyId = ((EntitySelector.RouteTypeAndAgency) entitySelector).agencyId(); int routeType = ((EntitySelector.RouteTypeAndAgency) entitySelector).routeType(); - Agency agency = getTransitService(environment).getAgencyForId(agencyId); + Agency agency = getTransitService(environment).getAgency(agencyId); return List.of( agency != null ? new RouteTypeModel(agency, routeType, agency.getId().getFeedId()) @@ -243,10 +242,10 @@ public DataFetcher> entities() { if (entitySelector instanceof EntitySelector.DirectionAndRoute) { Direction direction = ((DirectionAndRoute) entitySelector).direction(); FeedScopedId routeId = ((EntitySelector.DirectionAndRoute) entitySelector).routeId(); - Route route = getTransitService(environment).getRouteForId(routeId); + Route route = getTransitService(environment).getRoute(routeId); return route != null ? getTransitService(environment) - .getPatternsForRoute(route) + .findPatterns(route) .stream() .filter(pattern -> pattern.getDirection() == direction) .collect(Collectors.toList()) @@ -300,9 +299,7 @@ public DataFetcher route() { .filter(entitySelector -> entitySelector instanceof EntitySelector.Route) .findAny() .map(EntitySelector.Route.class::cast) - .map(entitySelector -> - getTransitService(environment).getRouteForId(entitySelector.routeId()) - ) + .map(entitySelector -> getTransitService(environment).getRoute(entitySelector.routeId())) .orElse(null); } @@ -330,7 +327,7 @@ public DataFetcher trip() { .filter(entitySelector -> entitySelector instanceof EntitySelector.Trip) .findAny() .map(EntitySelector.Trip.class::cast) - .map(entitySelector -> getTransitService(environment).getTripForId(entitySelector.tripId())) + .map(entitySelector -> getTransitService(environment).getTrip(entitySelector.tripId())) .orElse(null); } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BikeParkImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BikeParkImpl.java similarity index 96% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BikeParkImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BikeParkImpl.java index 81166034ee5..725d6e49377 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BikeParkImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BikeParkImpl.java @@ -6,7 +6,7 @@ import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.framework.graphql.GraphQLUtils; import org.opentripplanner.model.calendar.openinghours.OHCalendar; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; public class BikeParkImpl implements GraphQLDataFetchers.GraphQLBikePark { diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BikeRentalStationImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BikeRentalStationImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BikeRentalStationImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BikeRentalStationImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BookingInfoImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BookingInfoImpl.java similarity index 85% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BookingInfoImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BookingInfoImpl.java index 44ee0985542..0060e6ad7e1 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BookingInfoImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BookingInfoImpl.java @@ -2,6 +2,7 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; +import java.time.Duration; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.transit.model.organization.ContactInfo; import org.opentripplanner.transit.model.timetable.booking.BookingInfo; @@ -31,7 +32,8 @@ public DataFetcher latestBookingTime() { @Override public DataFetcher maximumBookingNoticeSeconds() { - return environment -> getSource(environment).getMaximumBookingNotice().toSeconds(); + return environment -> + getSource(environment).getMaximumBookingNotice().map(Duration::toSeconds).orElse(null); } @Override @@ -41,7 +43,8 @@ public DataFetcher message() { @Override public DataFetcher minimumBookingNoticeSeconds() { - return environment -> getSource(environment).getMinimumBookingNotice().toSeconds(); + return environment -> + getSource(environment).getMinimumBookingNotice().map(Duration::toSeconds).orElse(null); } @Override diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BookingTimeImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BookingTimeImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BookingTimeImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/BookingTimeImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/CarParkImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/CarParkImpl.java similarity index 96% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/CarParkImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/CarParkImpl.java index ff990b4f65c..8947f589ca5 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/CarParkImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/CarParkImpl.java @@ -6,7 +6,7 @@ import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.framework.graphql.GraphQLUtils; import org.opentripplanner.model.calendar.openinghours.OHCalendar; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; public class CarParkImpl implements GraphQLDataFetchers.GraphQLCarPark { diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ContactInfoImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ContactInfoImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ContactInfoImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ContactInfoImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/CoordinatesImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/CoordinatesImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/CoordinatesImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/CoordinatesImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/CurrencyImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/CurrencyImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/CurrencyImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/CurrencyImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/DefaultFareProductImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/DefaultFareProductImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/DefaultFareProductImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/DefaultFareProductImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/DepartureRowImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/DepartureRowImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/DepartureRowImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/DepartureRowImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FareProductTypeResolver.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FareProductTypeResolver.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FareProductTypeResolver.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FareProductTypeResolver.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FareProductUseImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FareProductUseImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FareProductUseImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FareProductUseImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java similarity index 99% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java index d6488d3f375..3d9458152b5 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java @@ -79,7 +79,7 @@ public DataFetcher publisher() { private List getAgencies(DataFetchingEnvironment environment) { String id = getSource(environment); return getTransitService(environment) - .getAgencies() + .listAgencies() .stream() .filter(agency -> agency.getId().getFeedId().equals(id)) .collect(Collectors.toList()); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/GeometryImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/GeometryImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/GeometryImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/GeometryImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java similarity index 90% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java index 9ec83a4bf67..5e892c06368 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java @@ -10,6 +10,7 @@ import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.mapping.NumberMapper; +import org.opentripplanner.apis.gtfs.mapping.RealtimeStateMapper; import org.opentripplanner.ext.restapi.mapping.LocalDateMapper; import org.opentripplanner.ext.ridehailing.model.RideEstimate; import org.opentripplanner.ext.ridehailing.model.RideHailingLeg; @@ -23,9 +24,11 @@ import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.model.plan.TransitLeg; import org.opentripplanner.model.plan.WalkStep; +import org.opentripplanner.model.plan.legreference.LegReferenceSerializer; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.alternativelegs.AlternativeLegs; import org.opentripplanner.routing.alternativelegs.AlternativeLegsFilter; +import org.opentripplanner.routing.alternativelegs.NavigationDirection; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.timetable.Trip; @@ -189,10 +192,12 @@ public DataFetcher realTime() { return environment -> getSource(environment).getRealTime(); } - // TODO @Override - public DataFetcher realtimeState() { - return environment -> null; + public DataFetcher realtimeState() { + return environment -> { + var state = getSource(environment).getRealTimeState(); + return RealtimeStateMapper.map(state); + }; } @Override @@ -271,8 +276,17 @@ private Leg getSource(DataFetchingEnvironment environment) { return environment.getSource(); } + @Override + public DataFetcher> previousLegs() { + return alternativeLegs(NavigationDirection.PREVIOUS); + } + @Override public DataFetcher> nextLegs() { + return alternativeLegs(NavigationDirection.NEXT); + } + + private DataFetcher> alternativeLegs(NavigationDirection direction) { return environment -> { if (environment.getSource() instanceof ScheduledTransitLeg originalLeg) { var args = new GraphQLTypes.GraphQLLegNextLegsArgs(environment.getArguments()); @@ -307,7 +321,7 @@ public DataFetcher> nextLegs() { environment.getSource(), numberOfLegs, environment.getContext().transitService(), - false, + direction, AlternativeLegsFilter.NO_FILTER, limitToExactOriginStop, limitToExactDestinationStop @@ -324,4 +338,15 @@ public DataFetcher> nextLegs() { public DataFetcher accessibilityScore() { return environment -> NumberMapper.toDouble(getSource(environment).accessibilityScore()); } + + @Override + public DataFetcher id() { + return environment -> { + var ref = getSource(environment).getLegReference(); + if (ref == null) { + return null; + } + return LegReferenceSerializer.encode(ref); + }; + } } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/MoneyImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/MoneyImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/MoneyImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/MoneyImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java similarity index 98% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java index 437d75e03e9..bb105be08fb 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/NodeTypeResolver.java @@ -12,7 +12,7 @@ import org.opentripplanner.routing.graphfinder.NearbyStop; import org.opentripplanner.routing.graphfinder.PatternAtStop; import org.opentripplanner.routing.graphfinder.PlaceAtDistance; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle; import org.opentripplanner.transit.model.network.Route; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/OpeningHoursImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/OpeningHoursImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/OpeningHoursImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/OpeningHoursImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java similarity index 99% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java index 88db00c3c4e..fbab1e95400 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java @@ -18,7 +18,6 @@ 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; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.services.TransitAlertService; @@ -31,6 +30,7 @@ import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.time.ServiceDateUtils; public class PatternImpl implements GraphQLDataFetchers.GraphQLPattern { diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlaceImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlaceImpl.java similarity index 98% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlaceImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlaceImpl.java index 145321f809c..abb3a607ab9 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlaceImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlaceImpl.java @@ -11,7 +11,7 @@ import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.StopArrival; import org.opentripplanner.model.plan.VertexType; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlaceInterfaceTypeResolver.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlaceInterfaceTypeResolver.java similarity index 96% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlaceInterfaceTypeResolver.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlaceInterfaceTypeResolver.java index cb2bfc77c32..a1f08fe3dc9 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlaceInterfaceTypeResolver.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlaceInterfaceTypeResolver.java @@ -5,7 +5,7 @@ import graphql.schema.GraphQLSchema; import graphql.schema.TypeResolver; import org.opentripplanner.routing.graphfinder.PatternAtStop; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle; import org.opentripplanner.transit.model.site.RegularStop; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanConnectionImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanConnectionImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanConnectionImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanConnectionImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java similarity index 90% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java index 0e70c13074b..bb8de508953 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java @@ -27,21 +27,22 @@ import org.locationtech.jts.geom.Envelope; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.GraphQLUtils; -import org.opentripplanner.apis.gtfs.PatternByServiceDatesFilter; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLQueryTypeStopsByRadiusArgs; import org.opentripplanner.apis.gtfs.mapping.routerequest.LegacyRouteRequestMapper; import org.opentripplanner.apis.gtfs.mapping.routerequest.RouteRequestMapper; +import org.opentripplanner.apis.gtfs.support.filter.PatternByDateFilterUtil; import org.opentripplanner.apis.gtfs.support.time.LocalDateRangeUtil; import org.opentripplanner.ext.fares.impl.DefaultFareService; import org.opentripplanner.ext.fares.impl.GtfsFaresService; import org.opentripplanner.ext.fares.model.FareRuleSet; -import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.gtfs.mapping.DirectionMapper; import org.opentripplanner.model.TripTimeOnDate; +import org.opentripplanner.model.plan.Leg; +import org.opentripplanner.model.plan.legreference.LegReference; +import org.opentripplanner.model.plan.legreference.LegReferenceSerializer; import org.opentripplanner.routing.alertpatch.EntitySelector; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.api.request.RouteRequest; @@ -54,8 +55,8 @@ import org.opentripplanner.routing.graphfinder.PatternAtStop; import org.opentripplanner.routing.graphfinder.PlaceAtDistance; import org.opentripplanner.routing.graphfinder.PlaceType; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; import org.opentripplanner.service.vehiclerental.VehicleRentalService; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; @@ -71,6 +72,7 @@ import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.service.TransitService; import org.opentripplanner.updater.GtfsRealtimeFuzzyTripMatcher; +import org.opentripplanner.utils.time.ServiceDateUtils; public class QueryTypeImpl implements GraphQLDataFetchers.GraphQLQueryType { @@ -85,7 +87,7 @@ public class QueryTypeImpl implements GraphQLDataFetchers.GraphQLQueryType { @Override public DataFetcher> agencies() { - return environment -> getTransitService(environment).getAgencies(); + return environment -> getTransitService(environment).listAgencies(); } @Override @@ -95,7 +97,7 @@ public DataFetcher agency() { new GraphQLTypes.GraphQLQueryTypeAgencyArgs(environment.getArguments()).getGraphQLId() ); - return getTransitService(environment).getAgencyForId(id); + return getTransitService(environment).getAgency(id); }; } @@ -120,7 +122,8 @@ public DataFetcher bikePark() { .vehicleParkingService(); return vehicleParkingService - .getBikeParks() + .listBikeParks() + .stream() .filter(bikePark -> bikePark.getId().getId().equals(args.getGraphQLId())) .findAny() .orElse(null); @@ -134,7 +137,7 @@ public DataFetcher> bikeParks() { .getContext() .vehicleParkingService(); - return vehicleParkingService.getBikeParks().toList(); + return vehicleParkingService.listBikeParks().stream().toList(); }; } @@ -207,7 +210,8 @@ public DataFetcher carPark() { .vehicleParkingService(); return vehicleParkingService - .getCarParks() + .listCarParks() + .stream() .filter(carPark -> carPark.getId().getId().equals(args.getGraphQLId())) .findAny() .orElse(null); @@ -228,14 +232,15 @@ public DataFetcher> carParks() { if (!idList.isEmpty()) { Map carParkMap = vehicleParkingService - .getCarParks() + .listCarParks() + .stream() .collect(Collectors.toMap(station -> station.getId().getId(), station -> station)); return idList.stream().map(carParkMap::get).toList(); } } - return vehicleParkingService.getCarParks().toList(); + return vehicleParkingService.listCarParks(); }; } @@ -260,7 +265,7 @@ public DataFetcher departureRow() { @Override public DataFetcher> feeds() { - return environment -> getTransitService(environment).getFeedIds(); + return environment -> getTransitService(environment).listFeedIds(); } @Override @@ -272,7 +277,7 @@ public DataFetcher fuzzyTrip() { return new GtfsRealtimeFuzzyTripMatcher(transitService) .getTrip( - transitService.getRouteForId(FeedScopedId.parse(args.getGraphQLRoute())), + transitService.getRoute(FeedScopedId.parse(args.getGraphQLRoute())), DIRECTION_MAPPER.map(args.getGraphQLDirection()), args.getGraphQLTime(), ServiceDateUtils.parseString(args.getGraphQLDate()) @@ -362,6 +367,20 @@ public DataFetcher> nearest() { }; } + @Override + public DataFetcher leg() { + return environment -> { + TransitService transitService = getTransitService(environment); + var args = new GraphQLTypes.GraphQLQueryTypeLegArgs(environment.getArguments()); + String id = args.getGraphQLId(); + LegReference ref = LegReferenceSerializer.decode(id); + if (ref == null) { + return null; + } + return ref.getLeg(transitService); + }; + } + @Override public DataFetcher node() { return environment -> { @@ -375,15 +394,16 @@ public DataFetcher node() { switch (type) { case "Agency": - return transitService.getAgencyForId(FeedScopedId.parse(id)); + return transitService.getAgency(FeedScopedId.parse(id)); case "Alert": - return null; //TODO + return transitService.getTransitAlertService().getAlertById(FeedScopedId.parse(id)); case "BikePark": var bikeParkId = FeedScopedId.parse(id); return vehicleParkingService == null ? null : vehicleParkingService - .getBikeParks() + .listBikeParks() + .stream() .filter(bikePark -> bikePark.getId().equals(bikeParkId)) .findAny() .orElse(null); @@ -404,7 +424,8 @@ public DataFetcher node() { return vehicleParkingService == null ? null : vehicleParkingService - .getCarParks() + .listCarParks() + .stream() .filter(carPark -> carPark.getId().equals(carParkId)) .findAny() .orElse(null); @@ -413,7 +434,7 @@ public DataFetcher node() { case "DepartureRow": return PatternAtStop.fromId(transitService, id); case "Pattern": - return transitService.getTripPatternForId(FeedScopedId.parse(id)); + return transitService.getTripPattern(FeedScopedId.parse(id)); case "placeAtDistance": { String[] parts = id.split(";"); @@ -432,7 +453,7 @@ public DataFetcher node() { return new PlaceAtDistance(place, Double.parseDouble(parts[0])); } case "Route": - return transitService.getRouteForId(FeedScopedId.parse(id)); + return transitService.getRoute(FeedScopedId.parse(id)); case "Stop": return transitService.getRegularStop(FeedScopedId.parse(id)); case "Stoptime": @@ -449,13 +470,14 @@ public DataFetcher node() { return null; //TODO case "Trip": var scopedId = FeedScopedId.parse(id); - return transitService.getTripForId(scopedId); + return transitService.getTrip(scopedId); case "VehicleParking": var vehicleParkingId = FeedScopedId.parse(id); return vehicleParkingService == null ? null : vehicleParkingService - .getVehicleParkings() + .listVehicleParkings() + .stream() .filter(bikePark -> bikePark.getId().equals(vehicleParkingId)) .findAny() .orElse(null); @@ -469,7 +491,7 @@ public DataFetcher node() { public DataFetcher pattern() { return environment -> getTransitService(environment) - .getTripPatternForId( + .getTripPattern( FeedScopedId.parse( new GraphQLTypes.GraphQLQueryTypePatternArgs(environment.getArguments()).getGraphQLId() ) @@ -478,7 +500,7 @@ public DataFetcher pattern() { @Override public DataFetcher> patterns() { - return environment -> getTransitService(environment).getAllTripPatterns(); + return environment -> getTransitService(environment).listTripPatterns(); } @Override @@ -566,7 +588,7 @@ public DataFetcher> rentalVehicles() { public DataFetcher route() { return environment -> getTransitService(environment) - .getRouteForId( + .getRoute( FeedScopedId.parse( new GraphQLTypes.GraphQLQueryTypeRouteArgs(environment.getArguments()).getGraphQLId() ) @@ -585,11 +607,11 @@ public DataFetcher> routes() { .getGraphQLIds() .stream() .map(FeedScopedId::parse) - .map(transitService::getRouteForId) + .map(transitService::getRoute) .toList(); } - Stream routeStream = transitService.getAllRoutes().stream(); + Stream routeStream = transitService.listRoutes().stream(); if (args.getGraphQLFeeds() != null) { List feeds = args.getGraphQLFeeds(); @@ -615,8 +637,11 @@ public DataFetcher> routes() { } if (LocalDateRangeUtil.hasServiceDateFilter(args.getGraphQLServiceDates())) { - var filter = new PatternByServiceDatesFilter(args.getGraphQLServiceDates(), transitService); - routeStream = filter.filterRoutes(routeStream).stream(); + var filter = PatternByDateFilterUtil.ofGraphQL( + args.getGraphQLServiceDates(), + transitService + ); + routeStream = filter.filterRoutes(routeStream.toList()).stream(); } return routeStream.toList(); }; @@ -631,7 +656,7 @@ public DataFetcher serviceTimeRange() { public DataFetcher station() { return environment -> getTransitService(environment) - .getStationById( + .getStation( FeedScopedId.parse( new GraphQLTypes.GraphQLQueryTypeStationArgs(environment.getArguments()).getGraphQLId() ) @@ -650,11 +675,11 @@ public DataFetcher> stations() { .getGraphQLIds() .stream() .map(FeedScopedId::parse) - .map(transitService::getStationById) + .map(transitService::getStation) .collect(Collectors.toList()); } - Stream stationStream = transitService.getStations().stream(); + Stream stationStream = transitService.listStations().stream(); if (args.getGraphQLName() != null) { String name = args.getGraphQLName().toLowerCase(environment.getLocale()); @@ -782,7 +807,7 @@ public DataFetcher> ticketTypes() { public DataFetcher trip() { return environment -> getTransitService(environment) - .getTripForId( + .getTrip( FeedScopedId.parse( new GraphQLTypes.GraphQLQueryTypeTripArgs(environment.getArguments()).getGraphQLId() ) @@ -794,7 +819,7 @@ public DataFetcher> trips() { return environment -> { var args = new GraphQLTypes.GraphQLQueryTypeTripsArgs(environment.getArguments()); - Stream tripStream = getTransitService(environment).getAllTrips().stream(); + Stream tripStream = getTransitService(environment).listTrips().stream(); if (args.getGraphQLFeeds() != null) { List feeds = args.getGraphQLFeeds(); @@ -816,7 +841,8 @@ public DataFetcher vehicleParking() { var vehicleParkingId = FeedScopedId.parse(args.getGraphQLId()); return vehicleParkingService - .getVehicleParkings() + .listVehicleParkings() + .stream() .filter(vehicleParking -> vehicleParking.getId().equals(vehicleParkingId)) .findAny() .orElse(null); @@ -837,14 +863,15 @@ public DataFetcher> vehicleParkings() { if (!idList.isEmpty()) { Map vehicleParkingMap = vehicleParkingService - .getVehicleParkings() + .listVehicleParkings() + .stream() .collect(Collectors.toMap(station -> station.getId().toString(), station -> station)); return idList.stream().map(vehicleParkingMap::get).toList(); } } - return vehicleParkingService.getVehicleParkings().toList(); + return vehicleParkingService.listVehicleParkings(); }; } @@ -865,11 +892,7 @@ public DataFetcher vehicleRentalStation() { return vehicleRentalStationService .getVehicleRentalStations() .stream() - .filter(vehicleRentalStation -> - OTPFeature.GtfsGraphQlApiRentalStationFuzzyMatching.isOn() - ? stationIdFuzzyMatches(vehicleRentalStation, id) - : stationIdMatches(vehicleRentalStation, id) - ) + .filter(vehicleRentalStation -> stationIdMatches(vehicleRentalStation, id)) .findAny() .orElse(null); }; @@ -908,6 +931,26 @@ public DataFetcher> vehicleRentalStations() { }; } + @Override + public DataFetcher> vehicleRentalsByBbox() { + return environment -> { + VehicleRentalService vehicleRentalService = environment + .getContext() + .vehicleRentalService(); + + var args = new GraphQLTypes.GraphQLQueryTypeVehicleRentalsByBboxArgs( + environment.getArguments() + ); + + return vehicleRentalService.getVehicleRentalPlacesForEnvelope( + args.getGraphQLMinimumLongitude(), + args.getGraphQLMinimumLatitude(), + args.getGraphQLMaximumLongitude(), + args.getGraphQLMaximumLatitude() + ); + }; + } + @Override public DataFetcher viewer() { return environment -> new Object(); @@ -920,21 +963,6 @@ private boolean stationIdMatches(VehicleRentalStation station, String feedScoped return station.getId().toString().equals(feedScopedId); } - /** - * This matches station's feedScopedId to the given string if the string is feed scoped (i.e - * contains a `:` separator) or only matches the station's id without the feed to the given - * string. This approach can lead to a random station matching the criteria if there are multiple - * stations with the same id in different feeds. - *

- * TODO this can be potentially removed after a while, only used by Digitransit as of now. - */ - private boolean stationIdFuzzyMatches(VehicleRentalStation station, String idWithoutFeed) { - if (idWithoutFeed != null && idWithoutFeed.contains(":")) { - return stationIdMatches(station, idWithoutFeed); - } - return station.getId().getId().equals(idWithoutFeed); - } - private TransitService getTransitService(DataFetchingEnvironment environment) { return environment.getContext().transitService(); } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RentalPlaceTypeResolver.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RentalPlaceTypeResolver.java new file mode 100644 index 00000000000..9e4e5fdb109 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RentalPlaceTypeResolver.java @@ -0,0 +1,27 @@ +package org.opentripplanner.apis.gtfs.datafetchers; + +import graphql.TypeResolutionEnvironment; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.TypeResolver; +import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; +import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle; + +public class RentalPlaceTypeResolver implements TypeResolver { + + @Override + public GraphQLObjectType getType(TypeResolutionEnvironment env) { + Object o = env.getObject(); + GraphQLSchema schema = env.getSchema(); + + if (o instanceof VehicleRentalStation) { + return schema.getObjectType("VehicleRentalStation"); + } + + if (o instanceof VehicleRentalVehicle) { + return schema.getObjectType("RentalVehicle"); + } + + return null; + } +} diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RentalVehicleImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RentalVehicleImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RentalVehicleImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RentalVehicleImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RentalVehicleTypeImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RentalVehicleTypeImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RentalVehicleTypeImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RentalVehicleTypeImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RideHailingEstimateImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RideHailingEstimateImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RideHailingEstimateImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RideHailingEstimateImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteImpl.java similarity index 95% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteImpl.java index a3f557951f0..9b98b71bd79 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteImpl.java @@ -9,12 +9,12 @@ import java.util.stream.Collectors; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.GraphQLUtils; -import org.opentripplanner.apis.gtfs.PatternByServiceDatesFilter; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLBikesAllowed; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLTransitMode; import org.opentripplanner.apis.gtfs.mapping.BikesAllowedMapper; +import org.opentripplanner.apis.gtfs.support.filter.PatternByDateFilterUtil; import org.opentripplanner.apis.gtfs.support.time.LocalDateRangeUtil; import org.opentripplanner.routing.alertpatch.EntitySelector; import org.opentripplanner.routing.alertpatch.TransitAlert; @@ -178,12 +178,15 @@ public DataFetcher mode() { public DataFetcher> patterns() { return environment -> { final TransitService transitService = getTransitService(environment); - var patterns = transitService.getPatternsForRoute(getSource(environment)); + var patterns = transitService.findPatterns(getSource(environment)); var args = new GraphQLTypes.GraphQLRoutePatternsArgs(environment.getArguments()); if (LocalDateRangeUtil.hasServiceDateFilter(args.getGraphQLServiceDates())) { - var filter = new PatternByServiceDatesFilter(args.getGraphQLServiceDates(), transitService); + var filter = PatternByDateFilterUtil.ofGraphQL( + args.getGraphQLServiceDates(), + transitService + ); return filter.filterPatterns(patterns); } else { return patterns; @@ -228,7 +231,7 @@ public DataFetcher url() { private Iterable getStops(DataFetchingEnvironment environment) { return getTransitService(environment) - .getPatternsForRoute(getSource(environment)) + .findPatterns(getSource(environment)) .stream() .map(TripPattern::getStops) .flatMap(Collection::stream) @@ -237,7 +240,7 @@ private Iterable getStops(DataFetchingEnvironment environment) { private Iterable getTrips(DataFetchingEnvironment environment) { return getTransitService(environment) - .getPatternsForRoute(getSource(environment)) + .findPatterns(getSource(environment)) .stream() .flatMap(TripPattern::scheduledTripsAsStream) .collect(Collectors.toSet()); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteTypeImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteTypeImpl.java similarity index 98% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteTypeImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteTypeImpl.java index bd8b9a7e019..108b4bd2bc0 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteTypeImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteTypeImpl.java @@ -27,7 +27,7 @@ public DataFetcher> routes() { return environment -> { Agency agency = getSource(environment).getAgency(); return getTransitService(environment) - .getAllRoutes() + .listRoutes() .stream() .filter(route -> route.getId().getFeedId().equals(getSource(environment).getFeedId()) && diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopGeometriesImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopGeometriesImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopGeometriesImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopGeometriesImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java similarity index 93% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java index 0730d2fbc91..5a2e6f29204 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java @@ -18,7 +18,8 @@ import org.opentripplanner.apis.gtfs.GraphQLUtils; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; -import org.opentripplanner.framework.time.ServiceDateUtils; +import org.opentripplanner.apis.gtfs.support.filter.PatternByDateFilterUtil; +import org.opentripplanner.apis.gtfs.support.time.LocalDateRangeUtil; import org.opentripplanner.model.StopTimesInPattern; import org.opentripplanner.model.TripTimeOnDate; import org.opentripplanner.routing.alertpatch.EntitySelector; @@ -35,6 +36,7 @@ import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.time.ServiceDateUtils; public class StopImpl implements GraphQLDataFetchers.GraphQLStop { @@ -243,7 +245,19 @@ public DataFetcher platformCode() { @Override public DataFetcher> routes() { - return this::getRoutes; + return env -> { + var args = new GraphQLTypes.GraphQLStopRoutesArgs(env.getArguments()); + var routes = getRoutes(env); + if (LocalDateRangeUtil.hasServiceDateFilter(args.getGraphQLServiceDates())) { + var filter = PatternByDateFilterUtil.ofGraphQL( + args.getGraphQLServiceDates(), + getTransitService(env) + ); + return filter.filterRoutes(routes); + } else { + return routes; + } + }; } @Override @@ -256,7 +270,7 @@ public DataFetcher> stopTimesForPattern() { GraphQLTypes.GraphQLStopStopTimesForPatternArgs args = new GraphQLTypes.GraphQLStopStopTimesForPatternArgs( environment.getArguments() ); - TripPattern pattern = transitService.getTripPatternForId( + TripPattern pattern = transitService.getTripPattern( FeedScopedId.parse(args.getGraphQLId()) ); @@ -264,7 +278,7 @@ public DataFetcher> stopTimesForPattern() { return null; } - if (transitService.hasRealtimeAddedTripPatterns()) { + if (transitService.hasNewTripPatternsForModifiedTrips()) { return getTripTimeOnDatesForPatternAtStopIncludingTripsWithSkippedStops( pattern, stop, @@ -273,7 +287,7 @@ public DataFetcher> stopTimesForPattern() { ); } - return transitService.stopTimesForPatternAtStop( + return transitService.findTripTimeOnDate( stop, pattern, GraphQLUtils.getTimeOrNow(args.getGraphQLStartTime()), @@ -304,7 +318,7 @@ public DataFetcher> stoptimesForPatterns() { var args = new GraphQLTypes.GraphQLStopStoptimesForPatternsArgs(environment.getArguments()); Function> stopTFunction = stop -> - transitService.stopTimesForStop( + transitService.findStopTimesInPattern( stop, GraphQLUtils.getTimeOrNow(args.getGraphQLStartTime()), Duration.ofSeconds(args.getGraphQLTimeRange()), @@ -342,7 +356,7 @@ public DataFetcher> stoptimesForServiceDate() { } Function> stopTFunction = stop -> - transitService.getStopTimesForStop( + transitService.findStopTimesInPattern( stop, date, args.getGraphQLOmitNonPickups() ? ArrivalDeparture.DEPARTURES : ArrivalDeparture.BOTH, @@ -371,7 +385,7 @@ public DataFetcher> stoptimesWithoutPatterns() { Function> stopTFunction = stop -> transitService - .stopTimesForStop( + .findStopTimesInPattern( stop, GraphQLUtils.getTimeOrNow(args.getGraphQLStartTime()), Duration.ofSeconds(args.getGraphQLTimeRange()), @@ -417,7 +431,7 @@ public DataFetcher> transfers() { .getGraphQLMaxDistance(); return getTransitService(environment) - .getTransfersByStop(stop) + .findPathTransfers(stop) .stream() .filter(transfer -> maxDistance == null || transfer.getDistanceMeters() < maxDistance) .filter(transfer -> transfer.to instanceof RegularStop) @@ -438,14 +452,14 @@ public DataFetcher vehicleMode() { environment, stop -> transitService - .getModesOfStopLocation(stop) + .findTransitModes(stop) .stream() .findFirst() .map(Enum::toString) .orElse(null), station -> transitService - .getModesOfStopLocationsGroup(station) + .findTransitModes(station) .stream() .findFirst() .map(Enum::toString) @@ -481,7 +495,7 @@ public DataFetcher zoneId() { private Collection getPatterns(DataFetchingEnvironment environment) { return getValue( environment, - stop -> getTransitService(environment).getPatternsForStop(stop, true), + stop -> getTransitService(environment).findPatterns(stop, true), station -> null ); } @@ -489,7 +503,7 @@ private Collection getPatterns(DataFetchingEnvironment environment) private Collection getRoutes(DataFetchingEnvironment environment) { return getValue( environment, - stop -> getTransitService(environment).getRoutesForStop(stop), + stop -> getTransitService(environment).findRoutes(stop), station -> null ); } @@ -517,7 +531,7 @@ private List getTripTimeOnDatesForPatternAtStopIncludingTripsWit ) .flatMap(tripPattern -> transitService - .stopTimesForPatternAtStop( + .findTripTimeOnDate( stop, tripPattern, startTime, @@ -548,7 +562,7 @@ private Stream getRealtimeAddedPatternsAsStream( ) { return originalPattern .scheduledTripsAsStream() - .map(trip -> transitService.getRealtimeAddedTripPattern(trip.getId(), date)) + .map(trip -> transitService.findNewTripPatternForModifiedTrip(trip.getId(), date)) .filter(tripPattern -> tripPattern != null && tripPattern.isModifiedFromTripPatternWithEqualStops(originalPattern) ); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopOnRouteImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopOnRouteImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopOnRouteImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopOnRouteImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopOnTripImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopOnTripImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopOnTripImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopOnTripImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopRelationshipImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopRelationshipImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopRelationshipImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopRelationshipImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StoptimeImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StoptimeImpl.java similarity index 88% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StoptimeImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StoptimeImpl.java index faf59ef9d6e..d7c8e97e255 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StoptimeImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StoptimeImpl.java @@ -3,10 +3,11 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.apis.gtfs.mapping.RealtimeStateMapper; import org.opentripplanner.framework.graphql.GraphQLUtils; import org.opentripplanner.model.StopTime; import org.opentripplanner.model.TripTimeOnDate; -import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.transit.model.timetable.Trip; public class StoptimeImpl implements GraphQLDataFetchers.GraphQLStoptime { @@ -67,11 +68,11 @@ public DataFetcher realtimeDeparture() { } @Override - public DataFetcher realtimeState() { + public DataFetcher realtimeState() { return environment -> getSource(environment).isCanceledEffectively() - ? RealTimeState.CANCELED.name() - : getSource(environment).getRealTimeState().name(); + ? GraphQLTypes.GraphQLRealtimeState.CANCELED + : RealtimeStateMapper.map(getSource(environment).getRealTimeState()); } @Override @@ -89,6 +90,11 @@ public DataFetcher stopPosition() { return environment -> getSource(environment).getGtfsSequence(); } + @Override + public DataFetcher stopPositionInPattern() { + return environment -> getSource(environment).getStopIndex(); + } + @Override public DataFetcher serviceDay() { return environment -> getSource(environment).getServiceDayMidnight(); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StoptimesInPatternImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StoptimesInPatternImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StoptimesInPatternImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StoptimesInPatternImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/SystemNoticeImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/SystemNoticeImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/SystemNoticeImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/SystemNoticeImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TicketTypeImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TicketTypeImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TicketTypeImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TicketTypeImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TranslatedStringImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TranslatedStringImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TranslatedStringImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TranslatedStringImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java similarity index 97% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java index 21bff637976..8eca58b69e0 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java @@ -23,7 +23,6 @@ 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; import org.opentripplanner.routing.alertpatch.EntitySelector; @@ -39,6 +38,7 @@ import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.time.ServiceDateUtils; public class TripImpl implements GraphQLDataFetchers.GraphQLTrip { @@ -325,14 +325,14 @@ public DataFetcher> stoptimesForDate() { ? ServiceDateUtils.parseString(args.getGraphQLServiceDate()) : LocalDate.now(timeZone); - TripPattern tripPattern = transitService.getPatternForTrip(trip, serviceDate); + TripPattern tripPattern = transitService.findPattern(trip, serviceDate); // no matching pattern found if (tripPattern == null) { return List.of(); } Instant midnight = ServiceDateUtils.asStartOfService(serviceDate, timeZone).toInstant(); - Timetable timetable = transitService.getTimetableForTripPattern(tripPattern, serviceDate); + Timetable timetable = transitService.findTimetable(tripPattern, serviceDate); return TripTimeOnDate.fromTripTimes(timetable, trip, serviceDate, midnight); } catch (ParseException e) { return null; // Invalid date format @@ -397,7 +397,7 @@ private Route getRoute(DataFetchingEnvironment environment) { } private TripPattern getTripPattern(DataFetchingEnvironment environment) { - return getTransitService(environment).getPatternForTrip(environment.getSource()); + return getTransitService(environment).findPattern(environment.getSource()); } private TransitService getTransitService(DataFetchingEnvironment environment) { diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripOccupancyImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripOccupancyImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripOccupancyImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripOccupancyImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/UnknownImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/UnknownImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/UnknownImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/UnknownImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehicleParkingImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehicleParkingImpl.java similarity index 93% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehicleParkingImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehicleParkingImpl.java index 0b55beac689..56bc62e2004 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehicleParkingImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehicleParkingImpl.java @@ -6,9 +6,9 @@ import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.framework.graphql.GraphQLUtils; import org.opentripplanner.model.calendar.openinghours.OHCalendar; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingState; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingState; public class VehicleParkingImpl implements GraphQLDataFetchers.GraphQLVehicleParking { diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehiclePositionImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehiclePositionImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehiclePositionImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehiclePositionImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehicleRentalNetworkImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehicleRentalNetworkImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehicleRentalNetworkImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehicleRentalNetworkImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehicleRentalStationImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehicleRentalStationImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehicleRentalStationImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/VehicleRentalStationImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/debugOutputImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/debugOutputImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/debugOutputImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/debugOutputImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/elevationProfileComponentImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/elevationProfileComponentImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/elevationProfileComponentImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/elevationProfileComponentImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/placeAtDistanceImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/placeAtDistanceImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/placeAtDistanceImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/placeAtDistanceImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/serviceTimeRangeImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/serviceTimeRangeImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/serviceTimeRangeImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/serviceTimeRangeImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stopAtDistanceImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stopAtDistanceImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stopAtDistanceImpl.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stopAtDistanceImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java similarity index 98% rename from src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index 67944543580..dd74347b928 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -18,6 +18,7 @@ import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLBikesAllowed; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLInputField; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLOccupancyStatus; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLRealtimeState; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLRelativeDirection; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLRoutingErrorCode; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLTransitMode; @@ -47,11 +48,11 @@ import org.opentripplanner.routing.graphfinder.NearbyStop; import org.opentripplanner.routing.graphfinder.PatternAtStop; import org.opentripplanner.routing.graphfinder.PlaceAtDistance; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingState; import org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle; import org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle.StopRelationship; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingState; import org.opentripplanner.service.vehiclerental.model.RentalVehicleEntityCounts; import org.opentripplanner.service.vehiclerental.model.RentalVehicleType; import org.opentripplanner.service.vehiclerental.model.RentalVehicleTypeCount; @@ -482,6 +483,8 @@ public interface GraphQLLeg { public DataFetcher headsign(); + public DataFetcher id(); + public DataFetcher interlineWithPreviousLeg(); public DataFetcher intermediatePlace(); @@ -500,9 +503,11 @@ public interface GraphQLLeg { public DataFetcher pickupType(); + public DataFetcher> previousLegs(); + public DataFetcher realTime(); - public DataFetcher realtimeState(); + public DataFetcher realtimeState(); public DataFetcher rentedBike(); @@ -779,6 +784,8 @@ public interface GraphQLQueryType { public DataFetcher fuzzyTrip(); + public DataFetcher leg(); + public DataFetcher> nearest(); public DataFetcher node(); @@ -827,6 +834,8 @@ public interface GraphQLQueryType { public DataFetcher> vehicleRentalStations(); + public DataFetcher> vehicleRentalsByBbox(); + public DataFetcher viewer(); } @@ -837,6 +846,9 @@ public interface GraphQLRealTimeEstimate { public DataFetcher time(); } + /** Rental place union that represents either a VehicleRentalStation or a RentalVehicle */ + public interface GraphQLRentalPlace extends TypeResolver {} + /** Rental vehicle represents a vehicle that belongs to a rental network. */ public interface GraphQLRentalVehicle { public DataFetcher allowPickupNow(); @@ -1078,7 +1090,7 @@ public interface GraphQLStoptime { public DataFetcher realtimeDeparture(); - public DataFetcher realtimeState(); + public DataFetcher realtimeState(); public DataFetcher scheduledArrival(); @@ -1090,6 +1102,8 @@ public interface GraphQLStoptime { public DataFetcher stopPosition(); + public DataFetcher stopPositionInPattern(); + public DataFetcher timepoint(); public DataFetcher trip(); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java similarity index 92% rename from src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java index 67051444cdf..b94541d2470 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java @@ -75,6 +75,63 @@ public enum GraphQLAgencyAlertType { ROUTE_TYPES, } + public static class GraphQLAlertAlertDescriptionTextArgs { + + private String language; + + public GraphQLAlertAlertDescriptionTextArgs(Map args) { + if (args != null) { + this.language = (String) args.get("language"); + } + } + + public String getGraphQLLanguage() { + return this.language; + } + + public void setGraphQLLanguage(String language) { + this.language = language; + } + } + + public static class GraphQLAlertAlertHeaderTextArgs { + + private String language; + + public GraphQLAlertAlertHeaderTextArgs(Map args) { + if (args != null) { + this.language = (String) args.get("language"); + } + } + + public String getGraphQLLanguage() { + return this.language; + } + + public void setGraphQLLanguage(String language) { + this.language = language; + } + } + + public static class GraphQLAlertAlertUrlArgs { + + private String language; + + public GraphQLAlertAlertUrlArgs(Map args) { + if (args != null) { + this.language = (String) args.get("language"); + } + } + + public String getGraphQLLanguage() { + return this.language; + } + + public void setGraphQLLanguage(String language) { + this.language = language; + } + } + /** Cause of a alert */ public enum GraphQLAlertCauseType { ACCIDENT, @@ -972,24 +1029,34 @@ public static class GraphQLInputModeWeightInput { private Double AIRPLANE; private Double BUS; private Double CABLE_CAR; + private Double CARPOOL; + private Double COACH; private Double FERRY; private Double FUNICULAR; private Double GONDOLA; + private Double MONORAIL; private Double RAIL; private Double SUBWAY; + private Double TAXI; private Double TRAM; + private Double TROLLEYBUS; public GraphQLInputModeWeightInput(Map args) { if (args != null) { this.AIRPLANE = (Double) args.get("AIRPLANE"); this.BUS = (Double) args.get("BUS"); this.CABLE_CAR = (Double) args.get("CABLE_CAR"); + this.CARPOOL = (Double) args.get("CARPOOL"); + this.COACH = (Double) args.get("COACH"); this.FERRY = (Double) args.get("FERRY"); this.FUNICULAR = (Double) args.get("FUNICULAR"); this.GONDOLA = (Double) args.get("GONDOLA"); + this.MONORAIL = (Double) args.get("MONORAIL"); this.RAIL = (Double) args.get("RAIL"); this.SUBWAY = (Double) args.get("SUBWAY"); + this.TAXI = (Double) args.get("TAXI"); this.TRAM = (Double) args.get("TRAM"); + this.TROLLEYBUS = (Double) args.get("TROLLEYBUS"); } } @@ -1005,6 +1072,14 @@ public Double getGraphQLCable_Car() { return this.CABLE_CAR; } + public Double getGraphQLCarpool() { + return this.CARPOOL; + } + + public Double getGraphQLCoach() { + return this.COACH; + } + public Double getGraphQLFerry() { return this.FERRY; } @@ -1017,6 +1092,10 @@ public Double getGraphQLGondola() { return this.GONDOLA; } + public Double getGraphQLMonorail() { + return this.MONORAIL; + } + public Double getGraphQLRail() { return this.RAIL; } @@ -1025,10 +1104,18 @@ public Double getGraphQLSubway() { return this.SUBWAY; } + public Double getGraphQLTaxi() { + return this.TAXI; + } + public Double getGraphQLTram() { return this.TRAM; } + public Double getGraphQLTrolleybus() { + return this.TROLLEYBUS; + } + public void setGraphQLAirplane(Double AIRPLANE) { this.AIRPLANE = AIRPLANE; } @@ -1041,6 +1128,14 @@ public void setGraphQLCable_Car(Double CABLE_CAR) { this.CABLE_CAR = CABLE_CAR; } + public void setGraphQLCarpool(Double CARPOOL) { + this.CARPOOL = CARPOOL; + } + + public void setGraphQLCoach(Double COACH) { + this.COACH = COACH; + } + public void setGraphQLFerry(Double FERRY) { this.FERRY = FERRY; } @@ -1053,6 +1148,10 @@ public void setGraphQLGondola(Double GONDOLA) { this.GONDOLA = GONDOLA; } + public void setGraphQLMonorail(Double MONORAIL) { + this.MONORAIL = MONORAIL; + } + public void setGraphQLRail(Double RAIL) { this.RAIL = RAIL; } @@ -1061,9 +1160,17 @@ public void setGraphQLSubway(Double SUBWAY) { this.SUBWAY = SUBWAY; } + public void setGraphQLTaxi(Double TAXI) { + this.TAXI = TAXI; + } + public void setGraphQLTram(Double TRAM) { this.TRAM = TRAM; } + + public void setGraphQLTrolleybus(Double TROLLEYBUS) { + this.TROLLEYBUS = TROLLEYBUS; + } } public static class GraphQLInputPreferredInput { @@ -1268,6 +1375,69 @@ public void setGraphQLOriginModesWithParentStation( } } + public static class GraphQLLegPreviousLegsArgs { + + private List destinationModesWithParentStation; + private Integer numberOfLegs; + private List originModesWithParentStation; + + public GraphQLLegPreviousLegsArgs(Map args) { + if (args != null) { + if (args.get("destinationModesWithParentStation") != null) { + this.destinationModesWithParentStation = + ((List) args.get("destinationModesWithParentStation")).stream() + .map(item -> + item instanceof GraphQLTransitMode + ? item + : GraphQLTransitMode.valueOf((String) item) + ) + .map(GraphQLTransitMode.class::cast) + .collect(Collectors.toList()); + } + this.numberOfLegs = (Integer) args.get("numberOfLegs"); + if (args.get("originModesWithParentStation") != null) { + this.originModesWithParentStation = + ((List) args.get("originModesWithParentStation")).stream() + .map(item -> + item instanceof GraphQLTransitMode + ? item + : GraphQLTransitMode.valueOf((String) item) + ) + .map(GraphQLTransitMode.class::cast) + .collect(Collectors.toList()); + } + } + } + + public List getGraphQLDestinationModesWithParentStation() { + return this.destinationModesWithParentStation; + } + + public Integer getGraphQLNumberOfLegs() { + return this.numberOfLegs; + } + + public List getGraphQLOriginModesWithParentStation() { + return this.originModesWithParentStation; + } + + public void setGraphQLDestinationModesWithParentStation( + List destinationModesWithParentStation + ) { + this.destinationModesWithParentStation = destinationModesWithParentStation; + } + + public void setGraphQLNumberOfLegs(Integer numberOfLegs) { + this.numberOfLegs = numberOfLegs; + } + + public void setGraphQLOriginModesWithParentStation( + List originModesWithParentStation + ) { + this.originModesWithParentStation = originModesWithParentStation; + } + } + public static class GraphQLLocalDateRangeInput { private java.time.LocalDate end; @@ -1492,6 +1662,7 @@ public enum GraphQLPlanAccessMode { BICYCLE, BICYCLE_PARKING, BICYCLE_RENTAL, + CAR, CAR_DROP_OFF, CAR_PARKING, CAR_RENTAL, @@ -1575,6 +1746,7 @@ public enum GraphQLPlanDirectMode { public enum GraphQLPlanEgressMode { BICYCLE, BICYCLE_RENTAL, + CAR, CAR_PICKUP, CAR_RENTAL, FLEX, @@ -1763,6 +1935,35 @@ public void setGraphQLTransitOnly(Boolean transitOnly) { } } + public static class GraphQLPlanPassThroughViaLocationInput { + + private String label; + private List stopLocationIds; + + public GraphQLPlanPassThroughViaLocationInput(Map args) { + if (args != null) { + this.label = (String) args.get("label"); + this.stopLocationIds = (List) args.get("stopLocationIds"); + } + } + + public String getGraphQLLabel() { + return this.label; + } + + public List getGraphQLStopLocationIds() { + return this.stopLocationIds; + } + + public void setGraphQLLabel(String label) { + this.label = label; + } + + public void setGraphQLStopLocationIds(List stopLocationIds) { + this.stopLocationIds = stopLocationIds; + } + } + public static class GraphQLPlanPreferencesInput { private GraphQLAccessibilityPreferencesInput accessibility; @@ -1877,6 +2078,7 @@ public void setGraphQLWalk(GraphQLWalkPreferencesInput walk) { public enum GraphQLPlanTransferMode { BICYCLE, + CAR, WALK, } @@ -1995,6 +2197,75 @@ public void setGraphQLTransit(List transi } } + public static class GraphQLPlanViaLocationInput { + + private GraphQLPlanPassThroughViaLocationInput passThrough; + private GraphQLPlanVisitViaLocationInput visit; + + public GraphQLPlanViaLocationInput(Map args) { + if (args != null) { + this.passThrough = + new GraphQLPlanPassThroughViaLocationInput((Map) args.get("passThrough")); + this.visit = new GraphQLPlanVisitViaLocationInput((Map) args.get("visit")); + } + } + + public GraphQLPlanPassThroughViaLocationInput getGraphQLPassThrough() { + return this.passThrough; + } + + public GraphQLPlanVisitViaLocationInput getGraphQLVisit() { + return this.visit; + } + + public void setGraphQLPassThrough(GraphQLPlanPassThroughViaLocationInput passThrough) { + this.passThrough = passThrough; + } + + public void setGraphQLVisit(GraphQLPlanVisitViaLocationInput visit) { + this.visit = visit; + } + } + + public static class GraphQLPlanVisitViaLocationInput { + + private String label; + private java.time.Duration minimumWaitTime; + private List stopLocationIds; + + public GraphQLPlanVisitViaLocationInput(Map args) { + if (args != null) { + this.label = (String) args.get("label"); + this.minimumWaitTime = (java.time.Duration) args.get("minimumWaitTime"); + this.stopLocationIds = (List) args.get("stopLocationIds"); + } + } + + public String getGraphQLLabel() { + return this.label; + } + + public java.time.Duration getGraphQLMinimumWaitTime() { + return this.minimumWaitTime; + } + + public List getGraphQLStopLocationIds() { + return this.stopLocationIds; + } + + public void setGraphQLLabel(String label) { + this.label = label; + } + + public void setGraphQLMinimumWaitTime(java.time.Duration minimumWaitTime) { + this.minimumWaitTime = minimumWaitTime; + } + + public void setGraphQLStopLocationIds(List stopLocationIds) { + this.stopLocationIds = stopLocationIds; + } + } + public enum GraphQLPropulsionType { COMBUSTION, COMBUSTION_DIESEL, @@ -2432,6 +2703,25 @@ public void setGraphQLTime(Integer time) { } } + public static class GraphQLQueryTypeLegArgs { + + private String id; + + public GraphQLQueryTypeLegArgs(Map args) { + if (args != null) { + this.id = (String) args.get("id"); + } + } + + public String getGraphQLId() { + return this.id; + } + + public void setGraphQLId(String id) { + this.id = id; + } + } + public static class GraphQLQueryTypeNearestArgs { private String after; @@ -2673,6 +2963,7 @@ public static class GraphQLQueryTypePlanArgs { private List transportModes; private GraphQLInputTriangleInput triangle; private GraphQLInputUnpreferredInput unpreferred; + private List via; private Double waitAtBeginningFactor; private Double waitReluctance; private Integer walkBoardCost; @@ -2754,6 +3045,9 @@ public GraphQLQueryTypePlanArgs(Map args) { this.triangle = new GraphQLInputTriangleInput((Map) args.get("triangle")); this.unpreferred = new GraphQLInputUnpreferredInput((Map) args.get("unpreferred")); + if (args.get("via") != null) { + this.via = (List) args.get("via"); + } this.waitAtBeginningFactor = (Double) args.get("waitAtBeginningFactor"); this.waitReluctance = (Double) args.get("waitReluctance"); this.walkBoardCost = (Integer) args.get("walkBoardCost"); @@ -2985,6 +3279,10 @@ public GraphQLInputUnpreferredInput getGraphQLUnpreferred() { return this.unpreferred; } + public List getGraphQLVia() { + return this.via; + } + public Double getGraphQLWaitAtBeginningFactor() { return this.waitAtBeginningFactor; } @@ -3243,6 +3541,10 @@ public void setGraphQLUnpreferred(GraphQLInputUnpreferredInput unpreferred) { this.unpreferred = unpreferred; } + public void setGraphQLVia(List via) { + this.via = via; + } + public void setGraphQLWaitAtBeginningFactor(Double waitAtBeginningFactor) { this.waitAtBeginningFactor = waitAtBeginningFactor; } @@ -3290,6 +3592,7 @@ public static class GraphQLQueryTypePlanConnectionArgs { private GraphQLPlanLabeledLocationInput origin; private GraphQLPlanPreferencesInput preferences; private java.time.Duration searchWindow; + private List via; public GraphQLQueryTypePlanConnectionArgs(Map args) { if (args != null) { @@ -3308,6 +3611,9 @@ public GraphQLQueryTypePlanConnectionArgs(Map args) { this.preferences = new GraphQLPlanPreferencesInput((Map) args.get("preferences")); this.searchWindow = (java.time.Duration) args.get("searchWindow"); + if (args.get("via") != null) { + this.via = (List) args.get("via"); + } } } @@ -3359,6 +3665,10 @@ public java.time.Duration getGraphQLSearchWindow() { return this.searchWindow; } + public List getGraphQLVia() { + return this.via; + } + public void setGraphQLAfter(String after) { this.after = after; } @@ -3406,6 +3716,10 @@ public void setGraphQLPreferences(GraphQLPlanPreferencesInput preferences) { public void setGraphQLSearchWindow(java.time.Duration searchWindow) { this.searchWindow = searchWindow; } + + public void setGraphQLVia(List via) { + this.via = via; + } } public static class GraphQLQueryTypeRentalVehicleArgs { @@ -3907,6 +4221,55 @@ public void setGraphQLIds(List ids) { } } + public static class GraphQLQueryTypeVehicleRentalsByBboxArgs { + + private Double maximumLatitude; + private Double maximumLongitude; + private Double minimumLatitude; + private Double minimumLongitude; + + public GraphQLQueryTypeVehicleRentalsByBboxArgs(Map args) { + if (args != null) { + this.maximumLatitude = (Double) args.get("maximumLatitude"); + this.maximumLongitude = (Double) args.get("maximumLongitude"); + this.minimumLatitude = (Double) args.get("minimumLatitude"); + this.minimumLongitude = (Double) args.get("minimumLongitude"); + } + } + + public Double getGraphQLMaximumLatitude() { + return this.maximumLatitude; + } + + public Double getGraphQLMaximumLongitude() { + return this.maximumLongitude; + } + + public Double getGraphQLMinimumLatitude() { + return this.minimumLatitude; + } + + public Double getGraphQLMinimumLongitude() { + return this.minimumLongitude; + } + + public void setGraphQLMaximumLatitude(Double maximumLatitude) { + this.maximumLatitude = maximumLatitude; + } + + public void setGraphQLMaximumLongitude(Double maximumLongitude) { + this.maximumLongitude = maximumLongitude; + } + + public void setGraphQLMinimumLatitude(Double minimumLatitude) { + this.minimumLatitude = minimumLatitude; + } + + public void setGraphQLMinimumLongitude(Double minimumLongitude) { + this.minimumLongitude = minimumLongitude; + } + } + public enum GraphQLRealtimeState { ADDED, CANCELED, @@ -4231,6 +4594,26 @@ public void setGraphQLLanguage(String language) { } } + public static class GraphQLStopRoutesArgs { + + private GraphQLLocalDateRangeInput serviceDates; + + public GraphQLStopRoutesArgs(Map args) { + if (args != null) { + this.serviceDates = + new GraphQLLocalDateRangeInput((Map) args.get("serviceDates")); + } + } + + public GraphQLLocalDateRangeInput getGraphQLServiceDates() { + return this.serviceDates; + } + + public void setGraphQLServiceDates(GraphQLLocalDateRangeInput serviceDates) { + this.serviceDates = serviceDates; + } + } + public static class GraphQLStopStopTimesForPatternArgs { private String id; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/README.md b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/README.md similarity index 84% rename from src/main/java/org/opentripplanner/apis/gtfs/generated/README.md rename to application/src/main/java/org/opentripplanner/apis/gtfs/generated/README.md index 7fe496f3a24..837c064e219 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/README.md +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/README.md @@ -2,7 +2,7 @@ ## Requirements -- NodeJS (version 16 or newer) +- NodeJS (version 18 or newer) ## Running diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml similarity index 91% rename from src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml rename to application/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml index 29490a28b78..59a2329a461 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml @@ -43,7 +43,7 @@ config: AlertCauseType: org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLAlertCauseType#GraphQLAlertCauseType AlertEffectType: org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLAlertEffectType#GraphQLAlertEffectType AlertSeverityLevelType: org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLAlertSeverityLevelType#GraphQLAlertSeverityLevelType - BikePark: org.opentripplanner.routing.vehicle_parking.VehicleParking#VehicleParking + BikePark: org.opentripplanner.service.vehicleparking.model.VehicleParking#VehicleParking BikeRentalStation: org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace#VehicleRentalPlace BikeRentalStationUris: org.opentripplanner.service.vehiclerental.model.VehicleRentalStationUris#VehicleRentalStationUris VehicleRentalStation: org.opentripplanner.service.vehiclerental.model.VehicleRentalStation#VehicleRentalStation @@ -55,7 +55,7 @@ config: BikesAllowed: org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLBikesAllowed#GraphQLBikesAllowed BookingInfo: org.opentripplanner.transit.model.timetable.booking.BookingInfo#BookingInfo BookingTime: org.opentripplanner.transit.model.timetable.booking.BookingTime#BookingTime - CarPark: org.opentripplanner.routing.vehicle_parking.VehicleParking#VehicleParking + CarPark: org.opentripplanner.service.vehicleparking.model.VehicleParking#VehicleParking ContactInfo: org.opentripplanner.transit.model.organization.ContactInfo Cluster: Object Coordinates: org.locationtech.jts.geom.Coordinate#Coordinate @@ -84,7 +84,7 @@ config: PlanConnection: graphql.execution.DataFetcherResult PlanEdge: graphql.relay.DefaultEdge#DefaultEdge PlanPageInfo: org.opentripplanner.apis.gtfs.model.PlanPageInfo#PlanPageInfo - RealtimeState: String + RealtimeState: org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLRealtimeState#GraphQLRealtimeState RelativeDirection: org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLRelativeDirection#GraphQLRelativeDirection Route: org.opentripplanner.transit.model.network.Route#Route RoutingError: org.opentripplanner.routing.api.response.RoutingError#RoutingError @@ -104,9 +104,9 @@ config: Trip: org.opentripplanner.transit.model.timetable.Trip#Trip TripOccupancy: org.opentripplanner.apis.gtfs.model.TripOccupancy#TripOccupancy Unknown: org.opentripplanner.apis.gtfs.model.UnknownModel#UnknownModel - VehicleParking: org.opentripplanner.routing.vehicle_parking.VehicleParking#VehicleParking - VehicleParkingSpaces: org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces#VehicleParkingSpaces - VehicleParkingState: org.opentripplanner.routing.vehicle_parking.VehicleParkingState#VehicleParkingState + VehicleParking: org.opentripplanner.service.vehicleparking.model.VehicleParking#VehicleParking + VehicleParkingSpaces: org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces#VehicleParkingSpaces + VehicleParkingState: org.opentripplanner.service.vehicleparking.model.VehicleParkingState#VehicleParkingState VertexType: String SystemNotice: org.opentripplanner.model.SystemNotice#SystemNotice VehiclePosition: org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle#RealtimeVehicle @@ -125,4 +125,5 @@ config: FareMedium: org.opentripplanner.model.fare.FareMedium#FareMedium RiderCategory: org.opentripplanner.model.fare.RiderCategory#RiderCategory StopPosition: org.opentripplanner.apis.gtfs.model.StopPosition#StopPosition + RentalPlace: org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace#VehicleRentalPlace diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json similarity index 92% rename from src/main/java/org/opentripplanner/apis/gtfs/generated/package.json rename to application/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json index d6cbf02d5e7..cd5cbf005f0 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json @@ -11,7 +11,7 @@ "license": "LGPL-3.0", "dependencies": { "@graphql-codegen/add": "5.0.3", - "@graphql-codegen/cli": "5.0.2", + "@graphql-codegen/cli": "5.0.3", "@graphql-codegen/java": "4.0.1", "@graphql-codegen/java-resolvers": "3.0.0", "graphql": "16.9.0" diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock similarity index 95% rename from src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock rename to application/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock index 25686abd94a..8ec320cb0e6 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock @@ -699,7 +699,7 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" -"@graphql-codegen/add@5.0.3": +"@graphql-codegen/add@5.0.3", "@graphql-codegen/add@^5.0.3": version "5.0.3" resolved "https://registry.yarnpkg.com/@graphql-codegen/add/-/add-5.0.3.tgz#1ede6bac9a93661ed7fa5808b203d079e1b1d215" integrity sha512-SxXPmramkth8XtBlAHu4H4jYcYXM/o3p01+psU+0NADQowA8jtYkK6MW5rV6T+CxkEaNZItfSmZRPgIuypcqnA== @@ -707,23 +707,15 @@ "@graphql-codegen/plugin-helpers" "^5.0.3" tslib "~2.6.0" -"@graphql-codegen/add@^5.0.2": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@graphql-codegen/add/-/add-5.0.2.tgz#71b3ae0465a4537172dddb84531b6967ca5545f2" - integrity sha512-ouBkSvMFUhda5VoKumo/ZvsZM9P5ZTyDsI8LW18VxSNWOjrTeLXBWHG8Gfaai0HwhflPtCYVABbriEcOmrRShQ== - dependencies: - "@graphql-codegen/plugin-helpers" "^5.0.3" - tslib "~2.6.0" - -"@graphql-codegen/cli@5.0.2": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@graphql-codegen/cli/-/cli-5.0.2.tgz#07ff691c16da4c3dcc0e1995d3231530379ab317" - integrity sha512-MBIaFqDiLKuO4ojN6xxG9/xL9wmfD3ZjZ7RsPjwQnSHBCUXnEkdKvX+JVpx87Pq29Ycn8wTJUguXnTZ7Di0Mlw== +"@graphql-codegen/cli@5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@graphql-codegen/cli/-/cli-5.0.3.tgz#d518ce5c011ff82496badef1342b3ba8d42efbcb" + integrity sha512-ULpF6Sbu2d7vNEOgBtE9avQp2oMgcPY/QBYcCqk0Xru5fz+ISjcovQX29V7CS7y5wWBRzNLoXwJQGeEyWbl05g== dependencies: "@babel/generator" "^7.18.13" "@babel/template" "^7.18.10" "@babel/types" "^7.18.13" - "@graphql-codegen/client-preset" "^4.2.2" + "@graphql-codegen/client-preset" "^4.4.0" "@graphql-codegen/core" "^4.0.2" "@graphql-codegen/plugin-helpers" "^5.0.3" "@graphql-tools/apollo-engine-loader" "^8.0.0" @@ -736,12 +728,12 @@ "@graphql-tools/prisma-loader" "^8.0.0" "@graphql-tools/url-loader" "^8.0.0" "@graphql-tools/utils" "^10.0.0" - "@whatwg-node/fetch" "^0.8.0" + "@whatwg-node/fetch" "^0.9.20" chalk "^4.1.0" cosmiconfig "^8.1.3" debounce "^1.2.0" detect-indent "^6.0.0" - graphql-config "^5.0.2" + graphql-config "^5.1.1" inquirer "^8.0.0" is-glob "^4.0.1" jiti "^1.17.1" @@ -756,20 +748,20 @@ yaml "^2.3.1" yargs "^17.0.0" -"@graphql-codegen/client-preset@^4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@graphql-codegen/client-preset/-/client-preset-4.2.2.tgz#545c62789a5687bee5df8b4738b4911e72ea8051" - integrity sha512-DF9pNWj3TEdA90E9FH5SsUIqiZfr872vqaQOspLVuVXGsaDx8F/JLLzaN+7ucmoo0ff/bLW8munVXYXTmgwwEA== +"@graphql-codegen/client-preset@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@graphql-codegen/client-preset/-/client-preset-4.4.0.tgz#f79d50ee2acb2d129072c1a080af90c30388fff7" + integrity sha512-Q0NHFK7KXLhEaRC/k82ge0dHDfeHJEvvDeV0vV3+oSurHNa/lpxQtbK2BqknZe+JDfZ1YOOvYT93XsAkYD+SQg== dependencies: "@babel/helper-plugin-utils" "^7.20.2" "@babel/template" "^7.20.7" - "@graphql-codegen/add" "^5.0.2" - "@graphql-codegen/gql-tag-operations" "4.0.4" - "@graphql-codegen/plugin-helpers" "^5.0.3" - "@graphql-codegen/typed-document-node" "^5.0.4" - "@graphql-codegen/typescript" "^4.0.4" - "@graphql-codegen/typescript-operations" "^4.1.2" - "@graphql-codegen/visitor-plugin-common" "^4.1.2" + "@graphql-codegen/add" "^5.0.3" + "@graphql-codegen/gql-tag-operations" "4.0.10" + "@graphql-codegen/plugin-helpers" "^5.0.4" + "@graphql-codegen/typed-document-node" "^5.0.10" + "@graphql-codegen/typescript" "^4.1.0" + "@graphql-codegen/typescript-operations" "^4.3.0" + "@graphql-codegen/visitor-plugin-common" "^5.4.0" "@graphql-tools/documents" "^1.0.0" "@graphql-tools/utils" "^10.0.0" "@graphql-typed-document-node/core" "3.2.0" @@ -785,13 +777,13 @@ "@graphql-tools/utils" "^10.0.0" tslib "~2.6.0" -"@graphql-codegen/gql-tag-operations@4.0.4": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@graphql-codegen/gql-tag-operations/-/gql-tag-operations-4.0.4.tgz#572be5db804af5efdc3ca24e4bcac815448730c5" - integrity sha512-dypul0iDLjb07yv+/cRb6qPbn42cFPcwlsJertVl9G6qkS4+3V4806WwSfUht4QVMWnvGfgDkJJqG0yUVKOHwA== +"@graphql-codegen/gql-tag-operations@4.0.10": + version "4.0.10" + resolved "https://registry.yarnpkg.com/@graphql-codegen/gql-tag-operations/-/gql-tag-operations-4.0.10.tgz#c179806a7af68123c076c4324164a3112a4bad37" + integrity sha512-WsBEVL3XQdBboFJJL5WxrUjkuo3B7Sa51R9NbT7PKBe0HCNstoouGZIvQJRUubttFCqTTyoFtNsoRSKB+rsRug== dependencies: - "@graphql-codegen/plugin-helpers" "^5.0.3" - "@graphql-codegen/visitor-plugin-common" "4.1.2" + "@graphql-codegen/plugin-helpers" "^5.0.4" + "@graphql-codegen/visitor-plugin-common" "5.4.0" "@graphql-tools/utils" "^10.0.0" auto-bind "~4.0.0" tslib "~2.6.0" @@ -864,6 +856,18 @@ lodash "~4.17.0" tslib "~2.6.0" +"@graphql-codegen/plugin-helpers@^5.0.4": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@graphql-codegen/plugin-helpers/-/plugin-helpers-5.0.4.tgz#5f4c987c3f308ef1c8809ee0c43af0369867e0f6" + integrity sha512-MOIuHFNWUnFnqVmiXtrI+4UziMTYrcquljaI5f/T/Bc7oO7sXcfkAvgkNWEEi9xWreYwvuer3VHCuPI/lAFWbw== + dependencies: + "@graphql-tools/utils" "^10.0.0" + change-case-all "1.0.15" + common-tags "1.8.2" + import-from "4.0.0" + lodash "~4.17.0" + tslib "~2.6.0" + "@graphql-codegen/schema-ast@^4.0.2": version "4.0.2" resolved "https://registry.yarnpkg.com/@graphql-codegen/schema-ast/-/schema-ast-4.0.2.tgz#aeaa104e4555cca73a058f0a9350b4b0e290b377" @@ -873,36 +877,36 @@ "@graphql-tools/utils" "^10.0.0" tslib "~2.6.0" -"@graphql-codegen/typed-document-node@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@graphql-codegen/typed-document-node/-/typed-document-node-5.0.4.tgz#06e286caacdd66c3566f98433dcb8f1a9c9a9f1d" - integrity sha512-t66Z6erQ4Dh1j6f9pRZmc8uYtHoUI3A49tLmJAlg9/3IV0kCmwrWKJut/G8SeOefDLG8cXBTVtI/YuZOe1Te+w== +"@graphql-codegen/typed-document-node@^5.0.10": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@graphql-codegen/typed-document-node/-/typed-document-node-5.0.10.tgz#5454c66ceefa2280657ce4852fbb57c9bd6df04d" + integrity sha512-YPDUNs6x0muoVWlbY2yEs0lGxFHMTszlGDh6klT/5rqiTDTZg3zz8Wd1ZTihkcH8+V6T0AT9qDWwcx9fcS2tvQ== dependencies: - "@graphql-codegen/plugin-helpers" "^5.0.3" - "@graphql-codegen/visitor-plugin-common" "4.1.2" + "@graphql-codegen/plugin-helpers" "^5.0.4" + "@graphql-codegen/visitor-plugin-common" "5.4.0" auto-bind "~4.0.0" change-case-all "1.0.15" tslib "~2.6.0" -"@graphql-codegen/typescript-operations@^4.1.2": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-operations/-/typescript-operations-4.1.2.tgz#a0f455ae19e16961e5870420ca7515bbe51b5568" - integrity sha512-CtCWK+gW7hS+Ely3lohr8CL1HVLswQzMcaUk3k1sxdWCWKTNq7abMsWa31rTVwRCJ+WNEkM/7S8sIBTpEG683A== +"@graphql-codegen/typescript-operations@^4.3.0": + version "4.3.0" + resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-operations/-/typescript-operations-4.3.0.tgz#c3fba2468cd35dac1fe83a57e0e3f8e02eba4040" + integrity sha512-ZORwMy8OgsiYd9EZUhTMd4/g5LvTFpx6Fh6dNN0cxFkqSc6KhjX0vhzWsyK8N9+ILaHSutT8UTrLMdJi35HzDQ== dependencies: - "@graphql-codegen/plugin-helpers" "^5.0.3" - "@graphql-codegen/typescript" "^4.0.4" - "@graphql-codegen/visitor-plugin-common" "4.1.2" + "@graphql-codegen/plugin-helpers" "^5.0.4" + "@graphql-codegen/typescript" "^4.1.0" + "@graphql-codegen/visitor-plugin-common" "5.4.0" auto-bind "~4.0.0" tslib "~2.6.0" -"@graphql-codegen/typescript@^4.0.4": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript/-/typescript-4.0.4.tgz#e791c61f675ae454951ea077b0ae519ae352cc3e" - integrity sha512-x79CKLfP9UQCX+/I78qxQlMs2Mmq3pF1lKafZo7lAno0f/fvJ+qWUduzdgjRNz+YL+5blGeWcC0pWEDxniO7hw== +"@graphql-codegen/typescript@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript/-/typescript-4.1.0.tgz#db6157b8df8bc5c6777ba519c24fce66536f5fcd" + integrity sha512-/fS53Nh6U6c58GTOxqfyKTLQfQv36P8II/vPw/fg0cdcWbALhRPls69P8vXUWjrElmLKzCrdusBWPp/r+AKUBQ== dependencies: - "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-codegen/plugin-helpers" "^5.0.4" "@graphql-codegen/schema-ast" "^4.0.2" - "@graphql-codegen/visitor-plugin-common" "4.1.2" + "@graphql-codegen/visitor-plugin-common" "5.4.0" auto-bind "~4.0.0" tslib "~2.6.0" @@ -922,12 +926,12 @@ parse-filepath "^1.0.2" tslib "~2.4.0" -"@graphql-codegen/visitor-plugin-common@4.1.2", "@graphql-codegen/visitor-plugin-common@^4.1.2": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-4.1.2.tgz#674c5d5813f6c00dd65e1ee148a62536879e65e2" - integrity sha512-yk7iEAL1kYZ2Gi/pvVjdsZhul5WsYEM4Zcgh2Ev15VicMdJmPHsMhNUsZWyVJV0CaQCYpNOFlGD/11Ea3pn4GA== +"@graphql-codegen/visitor-plugin-common@5.4.0", "@graphql-codegen/visitor-plugin-common@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-5.4.0.tgz#157846e433224b55f9a755e59d02508783977e27" + integrity sha512-tL7hOrO+4MiNfDiHewhRQCiH9GTAh0M9Y/BZxYGGEdnrfGgqK5pCxtjq7EY/L19VGIyU7hhzYTQ0r1HzEbB4Jw== dependencies: - "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-codegen/plugin-helpers" "^5.0.4" "@graphql-tools/optimize" "^2.0.0" "@graphql-tools/relay-operation-optimizer" "^7.0.0" "@graphql-tools/utils" "^10.0.0" @@ -1299,6 +1303,11 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" +"@kamilkisiela/fast-url-parser@^1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@kamilkisiela/fast-url-parser/-/fast-url-parser-1.1.4.tgz#9d68877a489107411b953c54ea65d0658b515809" + integrity sha512-gbkePEBupNydxCelHCESvFSFM8XPh1Zs/OAVRW/rKpEqPAl5PbOM90Si8mv9bvnR53uPD2s/FiRxdvSejpRJew== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1320,33 +1329,6 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@peculiar/asn1-schema@^2.1.6", "@peculiar/asn1-schema@^2.3.0": - version "2.3.3" - resolved "https://registry.yarnpkg.com/@peculiar/asn1-schema/-/asn1-schema-2.3.3.tgz#21418e1f3819e0b353ceff0c2dad8ccb61acd777" - integrity sha512-6GptMYDMyWBHTUKndHaDsRZUO/XMSgIns2krxcm2L7SEExRHwawFvSwNBhqNPR9HJwv3MruAiF1bhN0we6j6GQ== - dependencies: - asn1js "^3.0.5" - pvtsutils "^1.3.2" - tslib "^2.4.0" - -"@peculiar/json-schema@^1.1.12": - version "1.1.12" - resolved "https://registry.yarnpkg.com/@peculiar/json-schema/-/json-schema-1.1.12.tgz#fe61e85259e3b5ba5ad566cb62ca75b3d3cd5339" - integrity sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w== - dependencies: - tslib "^2.0.0" - -"@peculiar/webcrypto@^1.4.0": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@peculiar/webcrypto/-/webcrypto-1.4.1.tgz#821493bd5ad0f05939bd5f53b28536f68158360a" - integrity sha512-eK4C6WTNYxoI7JOabMoZICiyqRRtJB220bh0Mbj5RwRycleZf9BPyZoxsTvpP0FpmVS2aS13NKOuh5/tN3sIRw== - dependencies: - "@peculiar/asn1-schema" "^2.3.0" - "@peculiar/json-schema" "^1.1.12" - pvtsutils "^1.3.2" - tslib "^2.4.1" - webcrypto-core "^1.7.4" - "@repeaterjs/repeater@^3.0.4": version "3.0.4" resolved "https://registry.yarnpkg.com/@repeaterjs/repeater/-/repeater-3.0.4.tgz#a04d63f4d1bf5540a41b01a921c9a7fddc3bd1ca" @@ -1374,27 +1356,11 @@ dependencies: "@types/node" "*" -"@whatwg-node/events@^0.0.2": - version "0.0.2" - resolved "https://registry.yarnpkg.com/@whatwg-node/events/-/events-0.0.2.tgz#7b7107268d2982fc7b7aff5ee6803c64018f84dd" - integrity sha512-WKj/lI4QjnLuPrim0cfO7i+HsDSXHxNv1y0CrJhdntuO3hxWZmnXCwNDnwOvry11OjRin6cgWNF+j/9Pn8TN4w== - "@whatwg-node/events@^0.1.0": version "0.1.1" resolved "https://registry.yarnpkg.com/@whatwg-node/events/-/events-0.1.1.tgz#0ca718508249419587e130da26d40e29d99b5356" integrity sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w== -"@whatwg-node/fetch@^0.8.0": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@whatwg-node/fetch/-/fetch-0.8.1.tgz#ee3c94746132f217e17f78f9e073bb342043d630" - integrity sha512-Fkd1qQHK2tAWxKlC85h9L86Lgbq3BzxMnHSnTsnzNZMMzn6Xi+HlN8/LJ90LxorhSqD54td+Q864LgwUaYDj1Q== - dependencies: - "@peculiar/webcrypto" "^1.4.0" - "@whatwg-node/node-fetch" "^0.3.0" - busboy "^1.6.0" - urlpattern-polyfill "^6.0.2" - web-streams-polyfill "^3.2.1" - "@whatwg-node/fetch@^0.9.0": version "0.9.7" resolved "https://registry.yarnpkg.com/@whatwg-node/fetch/-/fetch-0.9.7.tgz#86b5cda576581beea300191d5c1f626fc7abfff7" @@ -1403,16 +1369,13 @@ "@whatwg-node/node-fetch" "^0.4.6" urlpattern-polyfill "^9.0.0" -"@whatwg-node/node-fetch@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@whatwg-node/node-fetch/-/node-fetch-0.3.0.tgz#7c7e90d03fa09d0ddebff29add6f16d923327d58" - integrity sha512-mPM8WnuHiI/3kFxDeE0SQQXAElbz4onqmm64fEGCwYEcBes2UsvIDI8HwQIqaXCH42A9ajJUPv4WsYoN/9oG6w== +"@whatwg-node/fetch@^0.9.20": + version "0.9.21" + resolved "https://registry.yarnpkg.com/@whatwg-node/fetch/-/fetch-0.9.21.tgz#24a08c441126ae2d0f94544e718bdb4a8c2b5ad0" + integrity sha512-Wt0jPb+04JjobK0pAAN7mEHxVHcGA9HoP3OyCsZtyAecNQeADXCZ1MihFwVwjsgaRYuGVmNlsCmLxlG6mor8Gw== dependencies: - "@whatwg-node/events" "^0.0.2" - busboy "^1.6.0" - fast-querystring "^1.1.1" - fast-url-parser "^1.1.3" - tslib "^2.3.1" + "@whatwg-node/node-fetch" "^0.5.23" + urlpattern-polyfill "^10.0.0" "@whatwg-node/node-fetch@^0.4.6": version "0.4.6" @@ -1425,6 +1388,16 @@ fast-url-parser "^1.1.3" tslib "^2.3.1" +"@whatwg-node/node-fetch@^0.5.23": + version "0.5.26" + resolved "https://registry.yarnpkg.com/@whatwg-node/node-fetch/-/node-fetch-0.5.26.tgz#b660f55bf0039ef7ead75c224fe4240469c88f88" + integrity sha512-4jXDeZ4IH4bylZ6wu14VEx0aDXXhrN4TC279v9rPmn08g4EYekcYf8wdcOOnS9STjDkb6x77/6xBUTqxGgjr8g== + dependencies: + "@kamilkisiela/fast-url-parser" "^1.1.4" + busboy "^1.6.0" + fast-querystring "^1.1.1" + tslib "^2.6.3" + agent-base@^7.0.2, agent-base@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434" @@ -1481,15 +1454,6 @@ asap@~2.0.3: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= -asn1js@^3.0.1, asn1js@^3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/asn1js/-/asn1js-3.0.5.tgz#5ea36820443dbefb51cc7f88a2ebb5b462114f38" - integrity sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ== - dependencies: - pvtsutils "^1.3.2" - pvutils "^1.1.3" - tslib "^2.4.0" - astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" @@ -1572,6 +1536,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.1, braces@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -2144,10 +2115,10 @@ globby@^11.0.3: merge2 "^1.3.0" slash "^3.0.0" -graphql-config@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-5.0.2.tgz#7e962f94ccddcc2ee0aa71d75cf4491ec5092bdb" - integrity sha512-7TPxOrlbiG0JplSZYCyxn2XQtqVhXomEjXUmWJVSS5ET1nPhOJSsIb/WTwqWhcYX6G0RlHXSj9PLtGTKmxLNGg== +graphql-config@^5.1.1: + version "5.1.3" + resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-5.1.3.tgz#343e2867dafd5b009cd97fe6b29a5e9604001819" + integrity sha512-RBhejsPjrNSuwtckRlilWzLVt2j8itl74W9Gke1KejDTz7oaA5kVd6wRn9zK9TS5mcmIYGxf7zN7a1ORMdxp1Q== dependencies: "@graphql-tools/graphql-file-loader" "^8.0.0" "@graphql-tools/json-file-loader" "^8.0.0" @@ -2156,8 +2127,8 @@ graphql-config@^5.0.2: "@graphql-tools/url-loader" "^8.0.0" "@graphql-tools/utils" "^10.0.0" cosmiconfig "^8.1.0" - jiti "^1.18.2" - minimatch "^4.2.3" + jiti "^2.0.0" + minimatch "^9.0.5" string-env-interpolation "^1.0.1" tslib "^2.4.0" @@ -2400,10 +2371,10 @@ jiti@^1.17.1: resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.17.2.tgz#9e193d171c76b1c518a46c243c410c0462fe22d1" integrity sha512-Xf0nU8+8wuiQpLcqdb2HRyHqYwGk2Pd+F7kstyp20ZuqTyCmB9dqpX2NxaxFc1kovraa2bG6c1RL3W7XfapiZg== -jiti@^1.18.2: - version "1.19.1" - resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.19.1.tgz#fa99e4b76a23053e0e7cde098efe1704a14c16f1" - integrity sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg== +jiti@^2.0.0: + version "2.3.3" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.3.3.tgz#39c66fc77476b92a694e65dfe04b294070e2e096" + integrity sha512-EX4oNDwcXSivPrw2qKH2LB5PoFxEvgtv2JgwW0bU858HoLQ+kutSvjLMUqBd0PeJYEinLWhoI9Ol0eYMqj/wNQ== jose@^4.11.4: version "4.14.4" @@ -2580,12 +2551,12 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimatch@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.3.tgz#b4dcece1d674dee104bb0fb833ebb85a78cbbca6" - integrity sha512-lIUdtK5hdofgCTu3aT0sOaHsYR37viUuIc0rwnnDXImbwFRcumyLMeZaM0t0I/fgxS6s6JMfu0rLD1Wz9pv1ng== +minimatch@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== dependencies: - brace-expansion "^1.1.7" + brace-expansion "^2.0.1" ms@2.1.2: version "2.1.2" @@ -2847,18 +2818,6 @@ punycode@^1.3.2: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== -pvtsutils@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/pvtsutils/-/pvtsutils-1.3.2.tgz#9f8570d132cdd3c27ab7d51a2799239bf8d8d5de" - integrity sha512-+Ipe2iNUyrZz+8K/2IOo+kKikdtfhRKzNpQbruF2URmqPtoqAs8g3xS7TJvFF2GcPXjh7DkqMnpVveRFq4PgEQ== - dependencies: - tslib "^2.4.0" - -pvutils@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/pvutils/-/pvutils-1.1.3.tgz#f35fc1d27e7cd3dfbd39c0826d173e806a03f5a3" - integrity sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ== - queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -3163,16 +3122,16 @@ ts-log@^2.2.3: resolved "https://registry.yarnpkg.com/ts-log/-/ts-log-2.2.3.tgz#4da5640fe25a9fb52642cd32391c886721318efb" integrity sha512-XvB+OdKSJ708Dmf9ore4Uf/q62AYDTzFcAdxc8KNML1mmAWywRFVt/dn1KYJH8Agt5UJNujfM3znU5PxgAzA2w== -tslib@^2.0.0, tslib@^2.3.1, tslib@^2.4.1: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== - tslib@^2.0.3, tslib@^2.1.0: version "2.3.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== +tslib@^2.3.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" + integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== + tslib@^2.4.0, tslib@~2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" @@ -3183,6 +3142,11 @@ tslib@^2.5.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== +tslib@^2.6.3: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== + tslib@~2.6.0: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" @@ -3232,12 +3196,10 @@ upper-case@^2.0.2: dependencies: tslib "^2.0.3" -urlpattern-polyfill@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/urlpattern-polyfill/-/urlpattern-polyfill-6.0.2.tgz#a193fe773459865a2a5c93b246bb794b13d07256" - integrity sha512-5vZjFlH9ofROmuWmXM9yj2wljYKgWstGwe8YTyiqM7hVum/g9LyCizPZtb3UqsuppVwety9QJmfc42VggLpTgg== - dependencies: - braces "^3.0.2" +urlpattern-polyfill@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz#f0a03a97bfb03cdf33553e5e79a2aadd22cac8ec" + integrity sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg== urlpattern-polyfill@^9.0.0: version "9.0.0" @@ -3266,22 +3228,6 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" -web-streams-polyfill@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" - integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== - -webcrypto-core@^1.7.4: - version "1.7.6" - resolved "https://registry.yarnpkg.com/webcrypto-core/-/webcrypto-core-1.7.6.tgz#e32c4a12a13de4251f8f9ef336a6cba7cdec9b55" - integrity sha512-TBPiewB4Buw+HI3EQW+Bexm19/W4cP/qZG/02QJCXN+iN+T5sl074vZ3rJcle/ZtDBQSgjkbsQO/1eFcxnSBUA== - dependencies: - "@peculiar/asn1-schema" "^2.1.6" - "@peculiar/json-schema" "^1.1.12" - asn1js "^3.0.1" - pvtsutils "^1.3.2" - tslib "^2.4.0" - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertCauseMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertCauseMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertCauseMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertCauseMapper.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertEffectMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertEffectMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertEffectMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/AlertEffectMapper.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/BikesAllowedMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/BikesAllowedMapper.java similarity index 78% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/BikesAllowedMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/BikesAllowedMapper.java index cd04601d599..79f55f1e50a 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/BikesAllowedMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/BikesAllowedMapper.java @@ -1,13 +1,11 @@ package org.opentripplanner.apis.gtfs.mapping; -import javax.annotation.Nonnull; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLBikesAllowed; import org.opentripplanner.transit.model.network.BikeAccess; public class BikesAllowedMapper { - @Nonnull - public static GraphQLBikesAllowed map(@Nonnull BikeAccess bikesAllowed) { + public static GraphQLBikesAllowed map(BikeAccess bikesAllowed) { return switch (bikesAllowed) { case UNKNOWN -> GraphQLBikesAllowed.NO_INFORMATION; case ALLOWED -> GraphQLBikesAllowed.ALLOWED; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapper.java index 1deb6e3bb0e..69a78b05f55 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapper.java @@ -1,6 +1,5 @@ package org.opentripplanner.apis.gtfs.mapping; -import javax.annotation.Nonnull; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLAbsoluteDirection; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLRelativeDirection; @@ -9,7 +8,6 @@ public final class DirectionMapper { - @Nonnull public static GraphQLAbsoluteDirection map(AbsoluteDirection dir) { return switch (dir) { case NORTH -> GraphQLAbsoluteDirection.NORTH; @@ -23,7 +21,6 @@ public static GraphQLAbsoluteDirection map(AbsoluteDirection dir) { }; } - @Nonnull public static GraphQLRelativeDirection map(RelativeDirection relativeDirection) { return switch (relativeDirection) { case DEPART -> GraphQLRelativeDirection.DEPART; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/NumberMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/NumberMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/NumberMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/NumberMapper.java diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/RealtimeStateMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/RealtimeStateMapper.java new file mode 100644 index 00000000000..6bd46466546 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/RealtimeStateMapper.java @@ -0,0 +1,22 @@ +package org.opentripplanner.apis.gtfs.mapping; + +import javax.annotation.Nullable; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.transit.model.timetable.RealTimeState; + +/** + * Maps from the internal model to the API one. + */ +public class RealtimeStateMapper { + + public static GraphQLTypes.GraphQLRealtimeState map(@Nullable RealTimeState state) { + if (state == null) return null; + return switch (state) { + case SCHEDULED -> GraphQLTypes.GraphQLRealtimeState.SCHEDULED; + case UPDATED -> GraphQLTypes.GraphQLRealtimeState.UPDATED; + case CANCELED, DELETED -> GraphQLTypes.GraphQLRealtimeState.CANCELED; + case ADDED -> GraphQLTypes.GraphQLRealtimeState.ADDED; + case MODIFIED -> GraphQLTypes.GraphQLRealtimeState.MODIFIED; + }; + } +} diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/SeverityMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/SeverityMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/SeverityMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/SeverityMapper.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/TransitModeMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/TransitModeMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/TransitModeMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/TransitModeMapper.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/AccessModeMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/AccessModeMapper.java similarity index 96% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/AccessModeMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/AccessModeMapper.java index ac4c90a1a56..e0e3ac0bbb2 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/AccessModeMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/AccessModeMapper.java @@ -13,6 +13,7 @@ public static StreetMode map(GraphQLTypes.GraphQLPlanAccessMode mode) { case BICYCLE -> StreetMode.BIKE; case BICYCLE_RENTAL -> StreetMode.BIKE_RENTAL; case BICYCLE_PARKING -> StreetMode.BIKE_TO_PARK; + case CAR -> StreetMode.CAR; case CAR_RENTAL -> StreetMode.CAR_RENTAL; case CAR_PARKING -> StreetMode.CAR_TO_PARK; case CAR_DROP_OFF -> StreetMode.CAR_PICKUP; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ArgumentUtils.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ArgumentUtils.java similarity index 98% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ArgumentUtils.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ArgumentUtils.java index b04affeaaf2..8541bd1c3c5 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ArgumentUtils.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ArgumentUtils.java @@ -7,7 +7,6 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; @@ -63,7 +62,6 @@ static Map getParking(DataFetchingEnvironment environment, Strin *

* TODO this ugliness can be removed when the bug gets fixed */ - @Nonnull static Collection> getParkingFilters( DataFetchingEnvironment environment, String type @@ -83,7 +81,6 @@ static Collection> getParkingFilters( *

* TODO this ugliness can be removed when the bug gets fixed */ - @Nonnull static Collection> getParkingPreferred( DataFetchingEnvironment environment, String type @@ -103,7 +100,6 @@ static Set parseSelectFilters(Collection> filters) { return parseFilters(filters, "select"); } - @Nonnull private static Set parseFilters(Collection> filters, String key) { return filters .stream() diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/BicyclePreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/BicyclePreferencesMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/BicyclePreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/BicyclePreferencesMapper.java index 7205757a569..263f6ee33ee 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/BicyclePreferencesMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/BicyclePreferencesMapper.java @@ -8,11 +8,11 @@ import graphql.schema.DataFetchingEnvironment; import java.util.Set; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.routing.api.request.preference.BikePreferences; import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; import org.opentripplanner.routing.api.request.preference.VehicleRentalPreferences; import org.opentripplanner.routing.api.request.preference.VehicleWalkingPreferences; +import org.opentripplanner.utils.time.DurationUtils; public class BicyclePreferencesMapper { @@ -60,7 +60,7 @@ private static void setBicycleWalkPreferences( var mountTime = args.getGraphQLMountDismountTime(); if (mountTime != null) { preferences.withMountDismountTime( - DurationUtils.requireNonNegativeShort(mountTime, "bicycle mount dismount time") + DurationUtils.requireNonNegativeMax30minutes(mountTime, "bicycle mount dismount time") ); } var cost = args.getGraphQLCost(); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/CarPreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/CarPreferencesMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/CarPreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/CarPreferencesMapper.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/DirectModeMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/DirectModeMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/DirectModeMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/DirectModeMapper.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/EgressModeMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/EgressModeMapper.java similarity index 95% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/EgressModeMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/EgressModeMapper.java index f03b160ac97..ddcaa255f2a 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/EgressModeMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/EgressModeMapper.java @@ -12,6 +12,7 @@ public static StreetMode map(GraphQLTypes.GraphQLPlanEgressMode mode) { return switch (mode) { case BICYCLE -> StreetMode.BIKE; case BICYCLE_RENTAL -> StreetMode.BIKE_RENTAL; + case CAR -> StreetMode.CAR; case CAR_RENTAL -> StreetMode.CAR_RENTAL; case CAR_PICKUP -> StreetMode.CAR_PICKUP; case FLEX -> StreetMode.FLEXIBLE; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ItineraryFilterDebugProfileMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ItineraryFilterDebugProfileMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ItineraryFilterDebugProfileMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ItineraryFilterDebugProfileMapper.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapper.java index 050127d9a27..19bee5e430d 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapper.java @@ -12,7 +12,6 @@ import java.util.Map; import java.util.function.Consumer; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.opentripplanner.api.common.LocationStringParser; import org.opentripplanner.api.parameter.QualifiedMode; import org.opentripplanner.api.parameter.QualifiedModeSet; @@ -35,7 +34,6 @@ public class LegacyRouteRequestMapper { - @Nonnull public static RouteRequest toRouteRequest( DataFetchingEnvironment environment, GraphQLRequestContext context @@ -56,6 +54,8 @@ public static RouteRequest toRouteRequest( callWith.argument("from", (Map v) -> request.setFrom(toGenericLocation(v))); callWith.argument("to", (Map v) -> request.setTo(toGenericLocation(v))); + mapViaLocations(request, environment); + request.setDateTime( environment.getArgument("date"), environment.getArgument("time"), @@ -257,6 +257,12 @@ public static RouteRequest toRouteRequest( return request; } + static void mapViaLocations(RouteRequest request, DataFetchingEnvironment env) { + var args = env.getArgument("via"); + var locs = ViaLocationMapper.mapToViaLocations((List>>) args); + request.setViaLocations(locs); + } + private static boolean hasArgument(Map m, String name) { return m.containsKey(name) && m.get(name) != null; } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ModePreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ModePreferencesMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ModePreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ModePreferencesMapper.java index 32d3456df57..663e93acca9 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ModePreferencesMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ModePreferencesMapper.java @@ -168,5 +168,10 @@ private static void validateStreetModes(JourneyRequest journey) { "If BICYCLE is used for access, egress or transfer, then it should be used for all." ); } + if (modes.contains(StreetMode.CAR) && modes.size() != 1) { + throw new IllegalArgumentException( + "If CAR is used for access, egress or transfer, then it should be used for all." + ); + } } } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/OptimizationTypeMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/OptimizationTypeMapper.java similarity index 94% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/OptimizationTypeMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/OptimizationTypeMapper.java index dc17891f9d2..6e848ce7f66 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/OptimizationTypeMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/OptimizationTypeMapper.java @@ -1,12 +1,10 @@ package org.opentripplanner.apis.gtfs.mapping.routerequest; -import javax.annotation.Nonnull; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; public final class OptimizationTypeMapper { - @Nonnull public static VehicleRoutingOptimizeType map(GraphQLTypes.GraphQLOptimizeType optimizeType) { return switch (optimizeType) { case QUICK -> VehicleRoutingOptimizeType.SHORTEST_DURATION; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapper.java similarity index 93% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapper.java index ada358d98b3..23e42f9a70c 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapper.java @@ -9,20 +9,20 @@ import graphql.schema.DataFetchingEnvironment; import java.time.Instant; -import javax.annotation.Nonnull; +import java.util.List; +import java.util.Map; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.framework.graphql.GraphQLUtils; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.model.GenericLocation; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.preference.ItineraryFilterPreferences; import org.opentripplanner.routing.api.request.preference.RoutingPreferences; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.time.DurationUtils; public class RouteRequestMapper { - @Nonnull public static RouteRequest toRouteRequest( DataFetchingEnvironment environment, GraphQLRequestContext context @@ -43,7 +43,7 @@ public static RouteRequest toRouteRequest( request.setLocale(GraphQLUtils.getLocale(environment, args.getGraphQLLocale())); if (args.getGraphQLSearchWindow() != null) { request.setSearchWindow( - DurationUtils.requireNonNegativeLong(args.getGraphQLSearchWindow(), "searchWindow") + DurationUtils.requireNonNegativeMax2days(args.getGraphQLSearchWindow(), "searchWindow") ); } @@ -65,6 +65,8 @@ public static RouteRequest toRouteRequest( setModes(request.journey(), args.getGraphQLModes(), environment); + // sadly we need to use the raw collection because it is cast to the wrong type + mapViaPoints(request, environment.getArgument("via")); return request; } @@ -180,4 +182,8 @@ private static GenericLocation parseGenericLocation( coordinate.getGraphQLLongitude() ); } + + static void mapViaPoints(RouteRequest request, List>> via) { + request.setViaLocations(ViaLocationMapper.mapToViaLocations(via)); + } } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ScooterPreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ScooterPreferencesMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ScooterPreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ScooterPreferencesMapper.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/TransferModeMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/TransferModeMapper.java similarity index 93% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/TransferModeMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/TransferModeMapper.java index ffa7363e3a7..18d2c0e3811 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/TransferModeMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/TransferModeMapper.java @@ -10,6 +10,7 @@ public class TransferModeMapper { public static StreetMode map(GraphQLTypes.GraphQLPlanTransferMode mode) { return switch (mode) { + case CAR -> StreetMode.CAR; case BICYCLE -> StreetMode.BIKE; case WALK -> StreetMode.WALK; }; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/TransitPreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/TransitPreferencesMapper.java similarity index 91% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/TransitPreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/TransitPreferencesMapper.java index d119c9bb8af..4ac55add5a9 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/TransitPreferencesMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/TransitPreferencesMapper.java @@ -7,10 +7,10 @@ import java.util.stream.Collectors; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.mapping.TransitModeMapper; -import org.opentripplanner.framework.collection.CollectionUtils; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.routing.api.request.preference.TransferPreferences; import org.opentripplanner.routing.api.request.preference.TransitPreferences; +import org.opentripplanner.utils.collection.CollectionUtils; +import org.opentripplanner.utils.time.DurationUtils; public class TransitPreferencesMapper { @@ -47,7 +47,7 @@ static void setTransitPreferences( var slack = board.getGraphQLSlack(); if (slack != null) { transitPreferences.withDefaultBoardSlackSec( - (int) DurationUtils.requireNonNegativeMedium(slack, "board slack").toSeconds() + (int) DurationUtils.requireNonNegativeMax2hours(slack, "board slack").toSeconds() ); } var waitReluctance = board.getGraphQLWaitReluctance(); @@ -60,7 +60,7 @@ static void setTransitPreferences( var slack = alight.getGraphQLSlack(); if (slack != null) { transitPreferences.withDefaultAlightSlackSec( - (int) DurationUtils.requireNonNegativeMedium(slack, "alight slack").toSeconds() + (int) DurationUtils.requireNonNegativeMax2hours(slack, "alight slack").toSeconds() ); } } @@ -73,7 +73,7 @@ static void setTransitPreferences( var slack = transfer.getGraphQLSlack(); if (slack != null) { transferPreferences.withSlack( - DurationUtils.requireNonNegativeMedium(slack, "transfer slack") + DurationUtils.requireNonNegativeMax2hours(slack, "transfer slack") ); } var maxTransfers = transfer.getGraphQLMaximumTransfers(); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/VehicleOptimizationTypeMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/VehicleOptimizationTypeMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/VehicleOptimizationTypeMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/VehicleOptimizationTypeMapper.java diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ViaLocationMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ViaLocationMapper.java new file mode 100644 index 00000000000..984f67855e8 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ViaLocationMapper.java @@ -0,0 +1,56 @@ +package org.opentripplanner.apis.gtfs.mapping.routerequest; + +import java.time.Duration; +import java.util.List; +import java.util.Map; +import javax.annotation.Nullable; +import org.opentripplanner.routing.api.request.via.PassThroughViaLocation; +import org.opentripplanner.routing.api.request.via.ViaLocation; +import org.opentripplanner.routing.api.request.via.VisitViaLocation; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.collection.ListUtils; + +/** + * Maps the input data to the data structure needed for via routing. + */ +class ViaLocationMapper { + + static final String FIELD_STOP_LOCATION_IDS = "stopLocationIds"; + static final String FIELD_LABEL = "label"; + static final String FIELD_MINIMUM_WAIT_TIME = "minimumWaitTime"; + static final String FIELD_VISIT = "visit"; + static final String FIELD_PASS_THROUGH = "passThrough"; + + static List mapToViaLocations(@Nullable List>> via) { + return ListUtils + .nullSafeImmutableList(via) + .stream() + .map(ViaLocationMapper::mapViaLocation) + .toList(); + } + + private static ViaLocation mapViaLocation(Map> via) { + var passThrough = via.get(FIELD_PASS_THROUGH); + var visit = via.get(FIELD_VISIT); + + if (passThrough != null && passThrough.get(FIELD_STOP_LOCATION_IDS) != null) { + return new PassThroughViaLocation( + (String) passThrough.get(FIELD_LABEL), + mapStopLocationIds((List) passThrough.get(FIELD_STOP_LOCATION_IDS)) + ); + } else if (visit != null) { + return new VisitViaLocation( + (String) visit.get(FIELD_LABEL), + (Duration) visit.get(FIELD_MINIMUM_WAIT_TIME), + mapStopLocationIds((List) visit.get(FIELD_STOP_LOCATION_IDS)), + List.of() + ); + } else { + throw new IllegalArgumentException("ViaLocation must define either pass-through or visit."); + } + } + + private static List mapStopLocationIds(List ids) { + return ids.stream().map(FeedScopedId::parse).toList(); + } +} diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/WalkPreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/WalkPreferencesMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/WalkPreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/mapping/routerequest/WalkPreferencesMapper.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/model/FeedPublisher.java b/application/src/main/java/org/opentripplanner/apis/gtfs/model/FeedPublisher.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/model/FeedPublisher.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/model/FeedPublisher.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/model/LocalDateRange.java b/application/src/main/java/org/opentripplanner/apis/gtfs/model/LocalDateRange.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/model/LocalDateRange.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/model/LocalDateRange.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/model/PlanPageInfo.java b/application/src/main/java/org/opentripplanner/apis/gtfs/model/PlanPageInfo.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/model/PlanPageInfo.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/model/PlanPageInfo.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/model/RideHailingProvider.java b/application/src/main/java/org/opentripplanner/apis/gtfs/model/RideHailingProvider.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/model/RideHailingProvider.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/model/RideHailingProvider.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/model/RouteTypeModel.java b/application/src/main/java/org/opentripplanner/apis/gtfs/model/RouteTypeModel.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/model/RouteTypeModel.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/model/RouteTypeModel.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/model/StopOnRouteModel.java b/application/src/main/java/org/opentripplanner/apis/gtfs/model/StopOnRouteModel.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/model/StopOnRouteModel.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/model/StopOnRouteModel.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/model/StopOnTripModel.java b/application/src/main/java/org/opentripplanner/apis/gtfs/model/StopOnTripModel.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/model/StopOnTripModel.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/model/StopOnTripModel.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/model/StopPosition.java b/application/src/main/java/org/opentripplanner/apis/gtfs/model/StopPosition.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/model/StopPosition.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/model/StopPosition.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/model/TripOccupancy.java b/application/src/main/java/org/opentripplanner/apis/gtfs/model/TripOccupancy.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/model/TripOccupancy.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/model/TripOccupancy.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/model/UnknownModel.java b/application/src/main/java/org/opentripplanner/apis/gtfs/model/UnknownModel.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/model/UnknownModel.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/model/UnknownModel.java diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/support/filter/PatternByDateFilterUtil.java b/application/src/main/java/org/opentripplanner/apis/gtfs/support/filter/PatternByDateFilterUtil.java new file mode 100644 index 00000000000..c0640aec2b9 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/support/filter/PatternByDateFilterUtil.java @@ -0,0 +1,23 @@ +package org.opentripplanner.apis.gtfs.support.filter; + +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.apis.gtfs.model.LocalDateRange; +import org.opentripplanner.transit.service.PatternByServiceDatesFilter; +import org.opentripplanner.transit.service.TransitService; + +/** + * Utility methods for instantiating a {@link PatternByServiceDatesFilter}. + */ +public class PatternByDateFilterUtil { + + public static PatternByServiceDatesFilter ofGraphQL( + GraphQLTypes.GraphQLLocalDateRangeInput range, + TransitService transitService + ) { + return new PatternByServiceDatesFilter( + new LocalDateRange(range.getGraphQLStart(), range.getGraphQLEnd()), + transitService::findPatterns, + trip -> transitService.getCalendarService().getServiceDatesForServiceId(trip.getServiceId()) + ); + } +} diff --git a/src/main/java/org/opentripplanner/apis/gtfs/support/time/LocalDateRangeUtil.java b/application/src/main/java/org/opentripplanner/apis/gtfs/support/time/LocalDateRangeUtil.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/gtfs/support/time/LocalDateRangeUtil.java rename to application/src/main/java/org/opentripplanner/apis/gtfs/support/time/LocalDateRangeUtil.java diff --git a/src/main/java/org/opentripplanner/apis/support/SemanticHash.java b/application/src/main/java/org/opentripplanner/apis/support/SemanticHash.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/support/SemanticHash.java rename to application/src/main/java/org/opentripplanner/apis/support/SemanticHash.java diff --git a/src/main/java/org/opentripplanner/apis/support/TileJson.java b/application/src/main/java/org/opentripplanner/apis/support/TileJson.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/support/TileJson.java rename to application/src/main/java/org/opentripplanner/apis/support/TileJson.java diff --git a/src/main/java/org/opentripplanner/apis/support/graphql/LoggingDataFetcherExceptionHandler.java b/application/src/main/java/org/opentripplanner/apis/support/graphql/LoggingDataFetcherExceptionHandler.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/support/graphql/LoggingDataFetcherExceptionHandler.java rename to application/src/main/java/org/opentripplanner/apis/support/graphql/LoggingDataFetcherExceptionHandler.java diff --git a/src/main/java/org/opentripplanner/apis/support/mapping/PlannerErrorMapper.java b/application/src/main/java/org/opentripplanner/apis/support/mapping/PlannerErrorMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/support/mapping/PlannerErrorMapper.java rename to application/src/main/java/org/opentripplanner/apis/support/mapping/PlannerErrorMapper.java diff --git a/src/main/java/org/opentripplanner/apis/support/mapping/PropertyMapper.java b/application/src/main/java/org/opentripplanner/apis/support/mapping/PropertyMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/support/mapping/PropertyMapper.java rename to application/src/main/java/org/opentripplanner/apis/support/mapping/PropertyMapper.java diff --git a/src/main/java/org/opentripplanner/apis/support/mapping/StreetNoteMapper.java b/application/src/main/java/org/opentripplanner/apis/support/mapping/StreetNoteMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/support/mapping/StreetNoteMapper.java rename to application/src/main/java/org/opentripplanner/apis/support/mapping/StreetNoteMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/MaxFieldsInResultInstrumentation.java b/application/src/main/java/org/opentripplanner/apis/transmodel/MaxFieldsInResultInstrumentation.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/MaxFieldsInResultInstrumentation.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/MaxFieldsInResultInstrumentation.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/ResponseTooLargeException.java b/application/src/main/java/org/opentripplanner/apis/transmodel/ResponseTooLargeException.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/ResponseTooLargeException.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/ResponseTooLargeException.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java similarity index 89% rename from src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java index 4ce7c1561bb..fe73e8b9887 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java @@ -20,10 +20,10 @@ import java.util.Map; import java.util.stream.Collectors; import org.opentripplanner.apis.transmodel.mapping.TransitIdMapper; -import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.standalone.api.OtpServerRequestContext; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.standalone.config.routerconfig.TransitRoutingConfig; +import org.opentripplanner.transit.service.TimetableRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,16 +67,21 @@ public TransmodelAPIOldPath( */ public static void setUp( TransmodelAPIParameters config, - TransitModel transitModel, - RouteRequest defaultRouteRequest + TimetableRepository timetableRepository, + RouteRequest defaultRouteRequest, + TransitRoutingConfig transitRoutingConfig ) { if (config.hideFeedId()) { - TransitIdMapper.setupFixedFeedId(transitModel.getAgencies()); + TransitIdMapper.setupFixedFeedId(timetableRepository.getAgencies()); } tracingHeaderTags = config.tracingHeaderTags(); maxNumberOfResultFields = config.maxNumberOfResultFields(); - GqlUtil gqlUtil = new GqlUtil(transitModel.getTimeZone()); - schema = TransmodelGraphQLSchema.create(defaultRouteRequest, gqlUtil); + schema = + TransmodelGraphQLSchema.create( + defaultRouteRequest, + timetableRepository.getTimeZone(), + transitRoutingConfig + ); } @POST diff --git a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPIParameters.java b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPIParameters.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPIParameters.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPIParameters.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraph.java b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraph.java similarity index 95% rename from src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraph.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraph.java index 79e767b1fea..e7f3fc7b8e0 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraph.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraph.java @@ -23,8 +23,9 @@ import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.application.OTPRequestTimeoutException; import org.opentripplanner.framework.concurrent.OtpRequestThreadFactory; -import org.opentripplanner.framework.lang.ObjectUtils; import org.opentripplanner.standalone.api.OtpServerRequestContext; +import org.opentripplanner.transit.model.framework.EntityNotFoundException; +import org.opentripplanner.utils.lang.ObjectUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -72,7 +73,7 @@ Response executeGraphQL( return ExecutionResultMapper.timeoutResponse(); } catch (ResponseTooLargeException rtle) { return ExecutionResultMapper.tooLargeResponse(rtle.getMessage()); - } catch (CoercingParseValueException | UnknownOperationException e) { + } catch (EntityNotFoundException | CoercingParseValueException | UnknownOperationException e) { return ExecutionResultMapper.badRequestResponse(e.getMessage()); } catch (Exception systemError) { LOG.error(systemError.getMessage(), systemError); diff --git a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLPlanner.java b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLPlanner.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLPlanner.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLPlanner.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java similarity index 89% rename from src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java index 9ad43606420..922f9f5244b 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java @@ -7,6 +7,7 @@ import static org.opentripplanner.apis.transmodel.model.EnumTypes.FILTER_PLACE_TYPE_ENUM; import static org.opentripplanner.apis.transmodel.model.EnumTypes.MULTI_MODAL_MODE; import static org.opentripplanner.apis.transmodel.model.EnumTypes.TRANSPORT_MODE; +import static org.opentripplanner.apis.transmodel.model.scalars.DateTimeScalarFactory.createMillisecondsSinceEpochAsDateTimeStringScalar; import static org.opentripplanner.model.projectinfo.OtpProjectInfo.projectInfo; import graphql.Scalars; @@ -24,8 +25,10 @@ import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLScalarType; import graphql.schema.GraphQLSchema; import java.time.LocalDate; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -58,6 +61,8 @@ import org.opentripplanner.apis.transmodel.model.framework.ServerInfoType; import org.opentripplanner.apis.transmodel.model.framework.StreetModeDurationInputType; import org.opentripplanner.apis.transmodel.model.framework.SystemNoticeType; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelDirectives; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars; import org.opentripplanner.apis.transmodel.model.framework.ValidityPeriodType; import org.opentripplanner.apis.transmodel.model.network.DestinationDisplayType; import org.opentripplanner.apis.transmodel.model.network.GroupOfLinesType; @@ -74,10 +79,10 @@ import org.opentripplanner.apis.transmodel.model.plan.TripPatternType; import org.opentripplanner.apis.transmodel.model.plan.TripQuery; import org.opentripplanner.apis.transmodel.model.plan.TripType; -import org.opentripplanner.apis.transmodel.model.plan.ViaLocationInputType; -import org.opentripplanner.apis.transmodel.model.plan.ViaSegmentInputType; -import org.opentripplanner.apis.transmodel.model.plan.ViaTripQuery; -import org.opentripplanner.apis.transmodel.model.plan.ViaTripType; +import org.opentripplanner.apis.transmodel.model.plan.legacyvia.ViaLocationInputType; +import org.opentripplanner.apis.transmodel.model.plan.legacyvia.ViaSegmentInputType; +import org.opentripplanner.apis.transmodel.model.plan.legacyvia.ViaTripQuery; +import org.opentripplanner.apis.transmodel.model.plan.legacyvia.ViaTripType; import org.opentripplanner.apis.transmodel.model.siri.et.EstimatedCallType; import org.opentripplanner.apis.transmodel.model.siri.sx.AffectsType; import org.opentripplanner.apis.transmodel.model.siri.sx.PtSituationElementType; @@ -102,12 +107,15 @@ import org.opentripplanner.model.plan.legreference.LegReference; import org.opentripplanner.model.plan.legreference.LegReferenceSerializer; import org.opentripplanner.routing.alertpatch.TransitAlert; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitTuningParameters; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.error.RoutingValidationException; import org.opentripplanner.routing.graphfinder.NearbyStop; import org.opentripplanner.routing.graphfinder.PlaceAtDistance; import org.opentripplanner.routing.graphfinder.PlaceType; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; +import org.opentripplanner.transit.api.model.FilterValues; +import org.opentripplanner.transit.api.request.TripRequest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; @@ -128,59 +136,49 @@ public class TransmodelGraphQLSchema { private final DefaultRouteRequestType routing; - private final GqlUtil gqlUtil; + private final TransitTuningParameters transitTuningParameters; + + private final ZoneId timeZoneId; private final Relay relay = new Relay(); - private TransmodelGraphQLSchema(RouteRequest defaultRequest, GqlUtil gqlUtil) { - this.gqlUtil = gqlUtil; + private TransmodelGraphQLSchema( + RouteRequest defaultRequest, + ZoneId timeZoneId, + TransitTuningParameters transitTuningParameters + ) { + this.timeZoneId = timeZoneId; this.routing = new DefaultRouteRequestType(defaultRequest); + this.transitTuningParameters = transitTuningParameters; } - public static GraphQLSchema create(RouteRequest defaultRequest, GqlUtil gqlUtil) { - return new TransmodelGraphQLSchema(defaultRequest, gqlUtil).create(); + public static GraphQLSchema create( + RouteRequest defaultRequest, + ZoneId timeZoneId, + TransitTuningParameters transitTuningParameters + ) { + return new TransmodelGraphQLSchema(defaultRequest, timeZoneId, transitTuningParameters) + .create(); } - // private BookingArrangement getBookingArrangementForTripTimeShort(TripTimeShort tripTimeShort) { - // Trip trip = index.tripForId.get(tripTimeShort.tripId); - // if (trip == null) { - // return null; - // } - // TripPattern tripPattern = index.patternForTrip.get(trip); - // if (tripPattern == null || tripPattern.stopPattern == null) { - // return null; - // } - // return tripPattern.stopPattern.bookingArrangements[tripTimeShort.stopIndex]; - // } - @SuppressWarnings("unchecked") private GraphQLSchema create() { - /* - multilingualStringType, validityPeriodType, infoLinkType, bookingArrangementType, systemNoticeType, - linkGeometryType, serverInfoType, authorityType, operatorType, noticeType - - - - */ - // Framework + GraphQLScalarType dateTimeScalar = createMillisecondsSinceEpochAsDateTimeStringScalar( + timeZoneId + ); GraphQLOutputType multilingualStringType = MultilingualStringType.create(); - GraphQLObjectType validityPeriodType = ValidityPeriodType.create(gqlUtil); + GraphQLObjectType validityPeriodType = ValidityPeriodType.create(dateTimeScalar); GraphQLObjectType infoLinkType = InfoLinkType.create(); - GraphQLOutputType bookingArrangementType = BookingArrangementType.create(gqlUtil); + GraphQLOutputType bookingArrangementType = BookingArrangementType.create(); GraphQLOutputType systemNoticeType = SystemNoticeType.create(); GraphQLOutputType linkGeometryType = PointsOnLinkType.create(); GraphQLOutputType serverInfoType = ServerInfoType.create(); GraphQLOutputType authorityType = AuthorityType.create( LineType.REF, - PtSituationElementType.REF, - gqlUtil - ); - GraphQLOutputType operatorType = OperatorType.create( - LineType.REF, - ServiceJourneyType.REF, - gqlUtil + PtSituationElementType.REF ); + GraphQLOutputType operatorType = OperatorType.create(LineType.REF, ServiceJourneyType.REF); GraphQLOutputType brandingType = BrandingType.create(); GraphQLOutputType noticeType = NoticeType.create(); GraphQLOutputType rentalVehicleTypeType = RentalVehicleTypeType.create(); @@ -200,7 +198,7 @@ private GraphQLSchema create() { tariffZoneType, EstimatedCallType.REF, PtSituationElementType.REF, - gqlUtil + dateTimeScalar ); GraphQLOutputType quayType = QuayType.create( placeInterface, @@ -210,7 +208,7 @@ private GraphQLSchema create() { EstimatedCallType.REF, PtSituationElementType.REF, tariffZoneType, - gqlUtil + dateTimeScalar ); GraphQLOutputType stopToStopGeometryType = StopToStopGeometryType.create( @@ -245,8 +243,7 @@ private GraphQLSchema create() { stopPlaceType, lineType, ServiceJourneyType.REF, - DatedServiceJourneyType.REF, - gqlUtil + DatedServiceJourneyType.REF ); // Timetable @@ -260,7 +257,7 @@ private GraphQLSchema create() { validityPeriodType, infoLinkType, affectsType, - gqlUtil, + dateTimeScalar, relay ); GraphQLOutputType journeyPatternType = JourneyPatternType.create( @@ -270,8 +267,7 @@ private GraphQLSchema create() { lineType, ServiceJourneyType.REF, stopToStopGeometryType, - ptSituationElementType, - gqlUtil + ptSituationElementType ); GraphQLOutputType estimatedCallType = EstimatedCallType.create( bookingArrangementType, @@ -281,7 +277,7 @@ private GraphQLSchema create() { ptSituationElementType, ServiceJourneyType.REF, DatedServiceJourneyType.REF, - gqlUtil + dateTimeScalar ); GraphQLOutputType serviceJourneyType = ServiceJourneyType.create( @@ -294,16 +290,14 @@ private GraphQLSchema create() { ptSituationElementType, journeyPatternType, estimatedCallType, - TimetabledPassingTimeType.REF, - gqlUtil + TimetabledPassingTimeType.REF ); GraphQLOutputType datedServiceJourneyType = DatedServiceJourneyType.create( serviceJourneyType, journeyPatternType, estimatedCallType, - quayType, - gqlUtil + quayType ); GraphQLOutputType timetabledPassingTime = TimetabledPassingTimeType.create( @@ -311,12 +305,11 @@ private GraphQLSchema create() { noticeType, quayType, destinationDisplayType, - serviceJourneyType, - gqlUtil + serviceJourneyType ); GraphQLObjectType tripPatternTimePenaltyType = TripPatternTimePenaltyType.create(); - GraphQLObjectType tripMetadataType = TripMetadataType.create(gqlUtil); + GraphQLObjectType tripMetadataType = TripMetadataType.create(dateTimeScalar); GraphQLObjectType placeType = PlanPlaceType.create( bikeRentalStationType, rentalVehicleType, @@ -339,13 +332,13 @@ private GraphQLSchema create() { placeType, pathGuidanceType, elevationStepType, - gqlUtil + dateTimeScalar ); GraphQLObjectType tripPatternType = TripPatternType.create( systemNoticeType, legType, tripPatternTimePenaltyType, - gqlUtil + dateTimeScalar ); GraphQLObjectType routingErrorType = RoutingErrorType.create(); @@ -354,22 +347,23 @@ private GraphQLSchema create() { tripPatternType, tripMetadataType, routingErrorType, - gqlUtil + dateTimeScalar ); - GraphQLInputObjectType durationPerStreetModeInput = StreetModeDurationInputType.create(gqlUtil); - GraphQLInputObjectType penaltyForStreetMode = PenaltyForStreetModeType.create(gqlUtil); + GraphQLInputObjectType durationPerStreetModeInput = StreetModeDurationInputType.create(); + GraphQLInputObjectType penaltyForStreetMode = PenaltyForStreetModeType.create(); GraphQLFieldDefinition tripQuery = TripQuery.create( routing, + transitTuningParameters, tripType, durationPerStreetModeInput, penaltyForStreetMode, - gqlUtil + dateTimeScalar ); GraphQLOutputType viaTripType = ViaTripType.create(tripPatternType, routingErrorType); - GraphQLInputObjectType viaLocationInputType = ViaLocationInputType.create(gqlUtil); + GraphQLInputObjectType viaLocationInputType = ViaLocationInputType.create(); GraphQLInputObjectType viaSegmentInputType = ViaSegmentInputType.create(); GraphQLFieldDefinition viaTripQuery = ViaTripQuery.create( @@ -377,7 +371,7 @@ private GraphQLSchema create() { viaTripType, viaLocationInputType, viaSegmentInputType, - gqlUtil + dateTimeScalar ); GraphQLInputObjectType inputPlaceIds = GraphQLInputObjectType @@ -435,7 +429,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("stopPlace") .description("Get a single stopPlace based on its id)") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(stopPlaceType) .argument( GraphQLArgument @@ -457,7 +451,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("stopPlaces") .description("Get all stopPlaces") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(stopPlaceType))) .argument( GraphQLArgument @@ -475,13 +469,10 @@ private GraphQLSchema create() { } TransitService transitService = GqlUtil.getTransitService(env); return transitService - .getStations() + .listStations() .stream() .map(station -> - new MonoOrMultiModalStation( - station, - transitService.getMultiModalStationForStation(station) - ) + new MonoOrMultiModalStation(station, transitService.findMultiModalStation(station)) ) .collect(Collectors.toList()); }) @@ -492,7 +483,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("stopPlacesByBbox") .description("Get all stop places within the specified bounding box") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(stopPlaceType))) .argument( GraphQLArgument @@ -573,7 +564,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("quay") .description("Get a single quay based on its id)") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(quayType) .argument( GraphQLArgument @@ -594,7 +585,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("quays") .description("Get all quays") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(quayType))) .argument( GraphQLArgument @@ -639,7 +630,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("quaysByBbox") .description("Get all quays within the specified bounding box") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(quayType))) .argument( GraphQLArgument @@ -705,7 +696,7 @@ private GraphQLSchema create() { boolean filterByInUse = TRUE.equals(environment.getArgument("filterByInUse")); boolean inUse = !GqlUtil .getTransitService(environment) - .getPatternsForStop(stop, true) + .findPatterns(stop, true) .isEmpty(); return !filterByInUse || inUse; }) @@ -722,7 +713,7 @@ private GraphQLSchema create() { "limits for the input parameters, but the query will timeout and return if the parameters " + "are too high." ) - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type( relay.connectionType( "quayAtDistance", @@ -808,7 +799,7 @@ private GraphQLSchema create() { .description( "Get all places (quays, stop places, car parks etc. with coordinates) within the specified radius from a location. The returned type has two fields place and distance. The search is done by walking so the distance is according to the network of walkables." ) - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type( relay.connectionType( "placeAtDistance", @@ -973,7 +964,7 @@ private GraphQLSchema create() { if (placeAtDistance.place() instanceof StopLocation stop) { return !GqlUtil .getTransitService(environment) - .getPatternsForStop(stop, true) + .findPatterns(stop, true) .isEmpty(); } else { return true; @@ -1008,7 +999,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("authority") .description("Get an authority by ID") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(authorityType) .argument( GraphQLArgument @@ -1020,7 +1011,7 @@ private GraphQLSchema create() { .dataFetcher(environment -> { return GqlUtil .getTransitService(environment) - .getAgencyForId(TransitIdMapper.mapIDToDomain(environment.getArgument("id"))); + .getAgency(TransitIdMapper.mapIDToDomain(environment.getArgument("id"))); }) .build() ) @@ -1029,10 +1020,10 @@ private GraphQLSchema create() { .newFieldDefinition() .name("authorities") .description("Get all authorities") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(authorityType))) .dataFetcher(environment -> { - return new ArrayList<>(GqlUtil.getTransitService(environment).getAgencies()); + return new ArrayList<>(GqlUtil.getTransitService(environment).listAgencies()); }) .build() ) @@ -1041,7 +1032,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("operator") .description("Get a operator by ID") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(operatorType) .argument( GraphQLArgument @@ -1053,7 +1044,7 @@ private GraphQLSchema create() { .dataFetcher(environment -> GqlUtil .getTransitService(environment) - .getOperatorForId(TransitIdMapper.mapIDToDomain(environment.getArgument("id"))) + .getOperator(TransitIdMapper.mapIDToDomain(environment.getArgument("id"))) ) .build() ) @@ -1062,10 +1053,10 @@ private GraphQLSchema create() { .newFieldDefinition() .name("operators") .description("Get all operators") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(operatorType))) .dataFetcher(environment -> { - return new ArrayList<>(GqlUtil.getTransitService(environment).getAllOperators()); + return new ArrayList<>(GqlUtil.getTransitService(environment).listOperators()); }) .build() ) @@ -1074,7 +1065,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("line") .description("Get a single line based on its id") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(lineType) .argument( GraphQLArgument @@ -1090,7 +1081,7 @@ private GraphQLSchema create() { } return GqlUtil .getTransitService(environment) - .getRouteForId(TransitIdMapper.mapIDToDomain(id)); + .getRoute(TransitIdMapper.mapIDToDomain(id)); }) .build() ) @@ -1099,7 +1090,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("lines") .description("Get all lines") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(lineType))) .argument( GraphQLArgument @@ -1162,11 +1153,11 @@ private GraphQLSchema create() { return ((List) environment.getArgument("ids")).stream() .map(TransitIdMapper::mapIDToDomain) .map(id -> { - return GqlUtil.getTransitService(environment).getRouteForId(id); + return GqlUtil.getTransitService(environment).getRoute(id); }) .collect(Collectors.toList()); } - Stream stream = GqlUtil.getTransitService(environment).getAllRoutes().stream(); + Stream stream = GqlUtil.getTransitService(environment).listRoutes().stream(); if ((boolean) environment.getArgument("flexibleOnly")) { Collection flexRoutes = GqlUtil @@ -1234,7 +1225,7 @@ private GraphQLSchema create() { .dataFetcher(environment -> GqlUtil .getTransitService(environment) - .getGroupOfRoutesForId(TransitIdMapper.mapIDToDomain(environment.getArgument("id"))) + .getGroupOfRoutes(TransitIdMapper.mapIDToDomain(environment.getArgument("id"))) ) .build() ) @@ -1244,7 +1235,7 @@ private GraphQLSchema create() { .name("groupsOfLines") .description("Get all groups of lines") .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(groupOfLinesType)))) - .dataFetcher(environment -> GqlUtil.getTransitService(environment).getGroupsOfRoutes()) + .dataFetcher(environment -> GqlUtil.getTransitService(environment).listGroupsOfRoutes()) .build() ) .field( @@ -1252,7 +1243,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("serviceJourney") .description("Get a single service journey based on its id") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(serviceJourneyType) .argument( GraphQLArgument @@ -1264,7 +1255,7 @@ private GraphQLSchema create() { .dataFetcher(environment -> { return GqlUtil .getTransitService(environment) - .getTripForId(TransitIdMapper.mapIDToDomain(environment.getArgument("id"))); + .getTrip(TransitIdMapper.mapIDToDomain(environment.getArgument("id"))); }) .build() ) @@ -1272,14 +1263,14 @@ private GraphQLSchema create() { GraphQLFieldDefinition .newFieldDefinition() .name("serviceJourneys") - .description("Get all service journeys") - .withDirective(gqlUtil.timingData) + .description("Get all _service journeys_") + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(serviceJourneyType))) .argument( GraphQLArgument .newArgument() .name("lines") - .description("Set of ids of lines to fetch serviceJourneys for.") + .description("Set of ids of _lines_ to fetch _service journeys_ for.") .type(new GraphQLList(Scalars.GraphQLID)) .build() ) @@ -1287,7 +1278,7 @@ private GraphQLSchema create() { GraphQLArgument .newArgument() .name("privateCodes") - .description("Set of ids of private codes to fetch serviceJourneys for.") + .description("Set of ids of _private codes_ to fetch _service journeys_ for.") .type(new GraphQLList(Scalars.GraphQLString)) .build() ) @@ -1295,53 +1286,45 @@ private GraphQLSchema create() { GraphQLArgument .newArgument() .name("activeDates") - .description("Set of ids of active dates to fetch serviceJourneys for.") - .type(new GraphQLList(gqlUtil.dateScalar)) + .description("Set of _operating days_ to fetch _service journeys_ for.") + .type(new GraphQLList(TransmodelScalars.DATE_SCALAR)) .build() ) .argument( GraphQLArgument .newArgument() .name("authorities") - .description("Set of ids of authorities to fetch serviceJourneys for.") + .description("Set of ids of _authorities_ to fetch _service journeys_ for.") .type(new GraphQLList(Scalars.GraphQLString)) .build() ) .dataFetcher(environment -> { - List lineIds = mapIDsToDomainNullSafe( - environment.getArgumentOrDefault("lines", List.of()) + var authorities = FilterValues.ofEmptyIsEverything( + "authorities", + mapIDsToDomainNullSafe(environment.getArgument("authorities")) + ); + var lineIds = FilterValues.ofEmptyIsEverything( + "lines", + mapIDsToDomainNullSafe(environment.getArgument("lines")) ); - List privateCodes = environment.getArgumentOrDefault("privateCodes", List.of()); - List activeServiceDates = environment.getArgumentOrDefault( + var privateCodes = FilterValues.ofEmptyIsEverything( + "privateCodes", + environment.>getArgument("privateCodes") + ); + var activeServiceDates = FilterValues.ofEmptyIsEverything( "activeDates", - List.of() + environment.>getArgument("activeDates") ); - // TODO OTP2 - Use FeedScoped ID - List authorities = environment.getArgumentOrDefault("authorities", List.of()); - TransitService transitService = GqlUtil.getTransitService(environment); - return transitService - .getAllTrips() - .stream() - .filter(t -> lineIds.isEmpty() || lineIds.contains(t.getRoute().getId())) - .filter(t -> - privateCodes.isEmpty() || privateCodes.contains(t.getNetexInternalPlanningCode()) - ) - .filter(t -> - authorities.isEmpty() || - authorities.contains(t.getRoute().getAgency().getId().getId()) - ) - .filter(t -> - ( - activeServiceDates.isEmpty() || - transitService - .getCalendarService() - .getServiceDatesForServiceId(t.getServiceId()) - .stream() - .anyMatch(activeServiceDates::contains) - ) - ) - .collect(Collectors.toList()); + TripRequest tripRequest = TripRequest + .of() + .withAgencies(authorities) + .withRoutes(lineIds) + .withNetexInternalPlanningCodes(privateCodes) + .withServiceDates(activeServiceDates) + .build(); + + return GqlUtil.getTransitService(environment).getTrips(tripRequest); }) .build() ) @@ -1350,7 +1333,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("bikeRentalStations") .description("Get all bike rental stations") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .argument( GraphQLArgument .newArgument() @@ -1379,7 +1362,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("bikeRentalStation") .description("Get all bike rental stations") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(bikeRentalStationType) .argument( GraphQLArgument @@ -1406,7 +1389,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("bikeRentalStationsByBbox") .description("Get all bike rental stations within the specified bounding box.") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(bikeRentalStationType))) .argument( GraphQLArgument.newArgument().name("minimumLatitude").type(Scalars.GraphQLFloat).build() @@ -1445,7 +1428,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("bikePark") .description("Get a single bike park based on its id") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(bikeParkType) .argument( GraphQLArgument @@ -1458,7 +1441,8 @@ private GraphQLSchema create() { var bikeParkId = TransitIdMapper.mapIDToDomain(environment.getArgument("id")); return GqlUtil .getVehicleParkingService(environment) - .getBikeParks() + .listBikeParks() + .stream() .filter(bikePark -> bikePark.getId().equals(bikeParkId)) .findFirst() .orElse(null); @@ -1470,12 +1454,13 @@ private GraphQLSchema create() { .newFieldDefinition() .name("bikeParks") .description("Get all bike parks") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(bikeParkType))) .dataFetcher(environment -> GqlUtil .getVehicleParkingService(environment) - .getBikeParks() + .listBikeParks() + .stream() .collect(Collectors.toCollection(ArrayList::new)) ) .build() @@ -1485,7 +1470,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("routingParameters") .description("Get default routing parameters.") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(this.routing.graphQLType) .dataFetcher(environment -> routing.request) .build() @@ -1495,7 +1480,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("situations") .description("Get all active situations.") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(ptSituationElementType)))) .argument( GraphQLArgument @@ -1571,7 +1556,7 @@ private GraphQLSchema create() { .newFieldDefinition() .name("situation") .description("Get a single situation based on its situationNumber") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(ptSituationElementType) .argument( GraphQLArgument @@ -1596,8 +1581,8 @@ private GraphQLSchema create() { GraphQLFieldDefinition .newFieldDefinition() .name("leg") - .description("Refetch a single leg based on its id") - .withDirective(gqlUtil.timingData) + .description("Refetch a single transit leg based on its id") + .withDirective(TransmodelDirectives.TIMING_DATA) .type(LegType.REF) .argument( GraphQLArgument @@ -1623,14 +1608,16 @@ private GraphQLSchema create() { GraphQLFieldDefinition .newFieldDefinition() .name("serverInfo") - .description("Get OTP server information") - .withDirective(gqlUtil.timingData) + .description( + "Get OTP deployment information. This is only useful for developers of OTP itself not regular API users." + ) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(serverInfoType)) .dataFetcher(e -> projectInfo()) .build() ) .field(DatedServiceJourneyQuery.createGetById(datedServiceJourneyType)) - .field(DatedServiceJourneyQuery.createQuery(datedServiceJourneyType, gqlUtil)) + .field(DatedServiceJourneyQuery.createQuery(datedServiceJourneyType)) .build(); return GraphQLSchema @@ -1639,7 +1626,7 @@ private GraphQLSchema create() { .additionalType(placeInterface) .additionalType(timetabledPassingTime) .additionalType(Relay.pageInfoType) - .additionalDirective(gqlUtil.timingData) + .additionalDirective(TransmodelDirectives.TIMING_DATA) .build(); } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelRequestContext.java b/application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelRequestContext.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/TransmodelRequestContext.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/TransmodelRequestContext.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/FilterMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/FilterMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/FilterMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/FilterMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/GenericLocationMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/GenericLocationMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/GenericLocationMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/GenericLocationMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/GeometryMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/GeometryMapper.java similarity index 92% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/GeometryMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/GeometryMapper.java index e2bf687e3b8..664da59d522 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/GeometryMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/GeometryMapper.java @@ -2,7 +2,7 @@ import java.util.ArrayList; import java.util.List; -import org.opentripplanner.apis.transmodel.model.util.EncodedPolylineBeanWithStops; +import org.opentripplanner.apis.transmodel.model.framework.EncodedPolylineBeanWithStops; import org.opentripplanner.framework.geometry.EncodedPolyline; import org.opentripplanner.transit.model.network.TripPattern; diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/OccupancyStatusMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/OccupancyStatusMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/OccupancyStatusMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/OccupancyStatusMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/PlaceMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/PlaceMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/PlaceMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/PlaceMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/PreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/PreferencesMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/PreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/PreferencesMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapper.java similarity index 75% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapper.java index 974b8dd10c3..bf9abd3a60d 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapper.java @@ -10,7 +10,8 @@ class RequestModesMapper { - private static final Predicate IS_BIKE = m -> m == StreetMode.BIKE; + private static final Predicate IS_BIKE_OR_CAR = m -> + m == StreetMode.BIKE || m == StreetMode.CAR; private static final String accessModeKey = "accessMode"; private static final String egressModeKey = "egressMode"; private static final String directModeKey = "directMode"; @@ -27,7 +28,10 @@ static RequestModes mapRequestModes(Map modesInput) { ensureValueAndSet(accessMode, mBuilder::withAccessMode); ensureValueAndSet((StreetMode) modesInput.get(egressModeKey), mBuilder::withEgressMode); ensureValueAndSet((StreetMode) modesInput.get(directModeKey), mBuilder::withDirectMode); - Optional.ofNullable(accessMode).filter(IS_BIKE).ifPresent(mBuilder::withTransferMode); + // The only cases in which the transferMode isn't WALK are when the accessMode is either BIKE or CAR. + // In these cases, the transferMode is the same as the accessMode. This check is not strictly necessary + // if there is a need for more freedom for specifying the transferMode. + Optional.ofNullable(accessMode).filter(IS_BIKE_OR_CAR).ifPresent(mBuilder::withTransferMode); return mBuilder.build(); } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/SelectRequestMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/SelectRequestMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/SelectRequestMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/SelectRequestMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/SeverityMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/SeverityMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/SeverityMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/SeverityMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/TransitIdMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TransitIdMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/TransitIdMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TransitIdMapper.java index 1554a8c9d7c..4bb1bb556e1 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/TransitIdMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TransitIdMapper.java @@ -4,11 +4,10 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,7 +38,6 @@ public static String mapIDToApi(FeedScopedId id) { * Return an empty collection if the collection of ids is null. * If the collection of ids contains null or blank elements, they are ignored. */ - @Nonnull public static List mapIDsToDomainNullSafe(@Nullable Collection ids) { if (ids == null) { return List.of(); diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapper.java similarity index 92% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapper.java index 72cd5fc6260..abb548256a1 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapper.java @@ -11,12 +11,12 @@ import java.util.Locale; import java.util.Map; import org.opentripplanner.apis.transmodel.TransmodelRequestContext; +import org.opentripplanner.apis.transmodel.model.plan.TripQuery; import org.opentripplanner.apis.transmodel.support.DataFetcherDecorator; import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.service.TransitService; public class TripRequestMapper { @@ -40,11 +40,16 @@ public static RouteRequest createRequest(DataFetchingEnvironment environment) { "to", (Map v) -> request.setTo(GenericLocationMapper.toGenericLocation(v)) ); - final TransitService transitService = context.getTransitService(); callWith.argument( "passThroughPoints", (List> v) -> { - request.setPassThroughPoints(PassThroughLocationMapper.toLocations(transitService, v)); + request.setViaLocations(TripViaLocationMapper.toLegacyPassThroughLocations(v)); + } + ); + callWith.argument( + TripQuery.TRIP_VIA_PARAMETER, + (List> v) -> { + request.setViaLocations(TripViaLocationMapper.mapToViaLocations(v)); } ); diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripViaLocationMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripViaLocationMapper.java new file mode 100644 index 00000000000..5f572c89da0 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripViaLocationMapper.java @@ -0,0 +1,98 @@ +package org.opentripplanner.apis.transmodel.mapping; + +import static java.util.stream.Collectors.toList; + +import java.time.Duration; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import javax.annotation.Nullable; +import org.opentripplanner.apis.transmodel.model.plan.TripQuery; +import org.opentripplanner.apis.transmodel.model.plan.ViaLocationInputType; +import org.opentripplanner.apis.transmodel.support.OneOfInputValidator; +import org.opentripplanner.routing.api.request.via.PassThroughViaLocation; +import org.opentripplanner.routing.api.request.via.ViaLocation; +import org.opentripplanner.routing.api.request.via.VisitViaLocation; +import org.opentripplanner.transit.model.framework.FeedScopedId; + +class TripViaLocationMapper { + + static List mapToViaLocations(final List> via) { + return via.stream().map(TripViaLocationMapper::mapViaLocation).collect(toList()); + } + + /** + * @deprecated Legacy passThrough, use via instead + */ + @Deprecated + static List toLegacyPassThroughLocations( + final List> passThroughPoints + ) { + return passThroughPoints + .stream() + .map(TripViaLocationMapper::mapLegacyPassThroughViaLocation) + .filter(Objects::nonNull) + .collect(toList()); + } + + private static ViaLocation mapViaLocation(Map inputMap) { + var fieldName = OneOfInputValidator.validateOneOf( + inputMap, + TripQuery.TRIP_VIA_PARAMETER, + ViaLocationInputType.FIELD_VISIT, + ViaLocationInputType.FIELD_PASS_THROUGH + ); + + Map value = (Map) inputMap.get(fieldName); + + return switch (fieldName) { + case ViaLocationInputType.FIELD_VISIT -> mapVisitViaLocation(value); + case ViaLocationInputType.FIELD_PASS_THROUGH -> mapPassThroughViaLocation(value); + default -> throw new IllegalArgumentException("Unknown field: " + fieldName); + }; + } + + private static VisitViaLocation mapVisitViaLocation(Map inputMap) { + var label = (String) inputMap.get(ViaLocationInputType.FIELD_LABEL); + var minimumWaitTime = (Duration) inputMap.get(ViaLocationInputType.FIELD_MINIMUM_WAIT_TIME); + var stopLocationIds = mapStopLocationIds(inputMap); + return new VisitViaLocation(label, minimumWaitTime, stopLocationIds, List.of()); + } + + private static PassThroughViaLocation mapPassThroughViaLocation(Map inputMap) { + var label = (String) inputMap.get(ViaLocationInputType.FIELD_LABEL); + var stopLocationIds = mapStopLocationIds(inputMap); + return new PassThroughViaLocation(label, stopLocationIds); + } + + private static List mapStopLocationIds(Map map) { + var c = (Collection) map.get(ViaLocationInputType.FIELD_STOP_LOCATION_IDS); + + // When coordinates are added, we need to accept null here... + if (c == null) { + throw new IllegalArgumentException( + "'" + ViaLocationInputType.FIELD_STOP_LOCATION_IDS + "' is not set!" + ); + } + return c.stream().map(TransitIdMapper::mapIDToDomain).toList(); + } + + /** + * @deprecated Legacy passThrough, use via instead + */ + @Deprecated + @Nullable + private static ViaLocation mapLegacyPassThroughViaLocation(Map inputMap) { + final String name = (String) inputMap.get("name"); + List placeIds = (List) inputMap.get("placeIds"); + if (placeIds == null || placeIds.isEmpty()) { + return null; + } + final List stopLocationIds = placeIds + .stream() + .map(TransitIdMapper::mapIDToDomain) + .toList(); + return new PassThroughViaLocation(name, stopLocationIds); + } +} diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaLocationMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaLocationDeprecatedMapper.java similarity index 77% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaLocationMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaLocationDeprecatedMapper.java index af39338fb98..9ef77dfc847 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaLocationMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaLocationDeprecatedMapper.java @@ -5,16 +5,17 @@ import java.time.Duration; import java.util.List; import java.util.Map; -import org.opentripplanner.routing.api.request.ViaLocation; +import org.opentripplanner.routing.api.request.ViaLocationDeprecated; import org.opentripplanner.routing.api.response.RoutingError; import org.opentripplanner.routing.api.response.RoutingErrorCode; import org.opentripplanner.routing.error.RoutingValidationException; -class ViaLocationMapper { +@Deprecated +class ViaLocationDeprecatedMapper { - static ViaLocation mapViaLocation(Map viaLocation) { + static ViaLocationDeprecated mapViaLocation(Map viaLocation) { try { - return new ViaLocation( + return new ViaLocationDeprecated( GenericLocationMapper.toGenericLocation(viaLocation), false, (Duration) viaLocation.get("minSlack"), diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaRequestMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaRequestMapper.java similarity index 92% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaRequestMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaRequestMapper.java index 0781fbe34a6..082b96c1add 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaRequestMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaRequestMapper.java @@ -9,7 +9,7 @@ import org.opentripplanner.framework.graphql.GraphQLUtils; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.RouteViaRequest; -import org.opentripplanner.routing.api.request.ViaLocation; +import org.opentripplanner.routing.api.request.ViaLocationDeprecated; import org.opentripplanner.routing.api.request.request.JourneyRequest; import org.opentripplanner.standalone.api.OtpServerRequestContext; @@ -27,7 +27,10 @@ public static RouteViaRequest createRouteViaRequest(DataFetchingEnvironment envi RouteRequest request = serverContext.defaultRouteRequest(); List> viaInput = environment.getArgument("via"); - List vias = viaInput.stream().map(ViaLocationMapper::mapViaLocation).toList(); + List vias = viaInput + .stream() + .map(ViaLocationDeprecatedMapper::mapViaLocation) + .toList(); List requests; if (environment.containsArgument("segments")) { diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaSegmentMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaSegmentMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaSegmentMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/ViaSegmentMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/CarPreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/CarPreferencesMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/CarPreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/CarPreferencesMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ItineraryFilterPreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ItineraryFilterPreferencesMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ItineraryFilterPreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ItineraryFilterPreferencesMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/RentalPreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/RentalPreferencesMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/RentalPreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/RentalPreferencesMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/StreetPreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/StreetPreferencesMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/StreetPreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/StreetPreferencesMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransferPreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransferPreferencesMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransferPreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransferPreferencesMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransitPreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransitPreferencesMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransitPreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransitPreferencesMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/WalkPreferencesMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/WalkPreferencesMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/WalkPreferencesMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/WalkPreferencesMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java similarity index 99% rename from src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java index b325eac3653..2f8e69cc593 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java @@ -184,7 +184,7 @@ public class EnumTypes { .value("air", TransitMode.AIRPLANE) .value("bicycle", TraverseMode.BICYCLE) .value("bus", TransitMode.BUS) - .value("cableway", TransitMode.CABLE_CAR) + .value("cableway", TransitMode.GONDOLA) .value("water", TransitMode.FERRY) .value("funicular", TransitMode.FUNICULAR) .value("lift", TransitMode.GONDOLA) @@ -455,7 +455,7 @@ public class EnumTypes { .name("TransportMode") .value("air", TransitMode.AIRPLANE) .value("bus", TransitMode.BUS) - .value("cableway", TransitMode.CABLE_CAR) + .value("cableway", TransitMode.GONDOLA) .value("water", TransitMode.FERRY) .value("funicular", TransitMode.FUNICULAR) .value("lift", TransitMode.GONDOLA) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/PlanResponse.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/PlanResponse.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/PlanResponse.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/PlanResponse.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/TransmodelPlaceType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/TransmodelPlaceType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/TransmodelPlaceType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/TransmodelPlaceType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/TransmodelStopPlaceType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/TransmodelStopPlaceType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/TransmodelStopPlaceType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/TransmodelStopPlaceType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/TransmodelTransportSubmode.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/TransmodelTransportSubmode.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/TransmodelTransportSubmode.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/TransmodelTransportSubmode.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/TransportModeSlack.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/TransportModeSlack.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/TransportModeSlack.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/TransportModeSlack.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/TripTimeOnDateHelper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/TripTimeOnDateHelper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/TripTimeOnDateHelper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/TripTimeOnDateHelper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/AuthorityType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/AuthorityType.java similarity index 93% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/AuthorityType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/AuthorityType.java index 27d20c8e423..d18b4da554f 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/AuthorityType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/AuthorityType.java @@ -17,8 +17,7 @@ public class AuthorityType { public static GraphQLObjectType create( GraphQLOutputType lineType, - GraphQLOutputType ptSituationElementType, - GqlUtil gqlUtil + GraphQLOutputType ptSituationElementType ) { return GraphQLObjectType .newObject() @@ -65,11 +64,11 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("lines") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(lineType))) .dataFetcher(environment -> getTransitService(environment) - .getAllRoutes() + .listRoutes() .stream() .filter(route -> Objects.equals(route.getAgency(), environment.getSource())) .collect(Collectors.toList()) @@ -80,7 +79,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("situations") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .description("Get all situations active for the authority.") .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(ptSituationElementType)))) .dataFetcher(environment -> diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/BrandingType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/BrandingType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/BrandingType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/BrandingType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/CoordinateInputType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/CoordinateInputType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/CoordinateInputType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/CoordinateInputType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/util/EncodedPolylineBeanWithStops.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/EncodedPolylineBeanWithStops.java similarity index 80% rename from src/main/java/org/opentripplanner/apis/transmodel/model/util/EncodedPolylineBeanWithStops.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/EncodedPolylineBeanWithStops.java index 92262a17381..23508bf2ef7 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/util/EncodedPolylineBeanWithStops.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/EncodedPolylineBeanWithStops.java @@ -1,4 +1,4 @@ -package org.opentripplanner.apis.transmodel.model.util; +package org.opentripplanner.apis.transmodel.model.framework; import org.opentripplanner.framework.geometry.EncodedPolyline; import org.opentripplanner.transit.model.site.StopLocation; diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/InfoLinkType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/InfoLinkType.java similarity index 94% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/InfoLinkType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/InfoLinkType.java index 6541b48a44d..e0472a2ccf8 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/InfoLinkType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/InfoLinkType.java @@ -20,7 +20,7 @@ public static GraphQLObjectType create() { .description("URI") .dataFetcher(environment -> { AlertUrl source = environment.getSource(); - return source.uri; + return source.uri(); }) .build() ) @@ -32,7 +32,7 @@ public static GraphQLObjectType create() { .description("Label") .dataFetcher(environment -> { AlertUrl source = environment.getSource(); - return source.label; + return source.label(); }) .build() ) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/LocationInputType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/LocationInputType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/LocationInputType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/LocationInputType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/MultilingualStringType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/MultilingualStringType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/MultilingualStringType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/MultilingualStringType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/NoticeType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/NoticeType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/NoticeType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/NoticeType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/OperatorType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/OperatorType.java similarity index 91% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/OperatorType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/OperatorType.java index d45319b9d9e..de58643f5dc 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/OperatorType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/OperatorType.java @@ -14,8 +14,7 @@ public class OperatorType { public static GraphQLObjectType create( GraphQLOutputType lineType, - GraphQLOutputType serviceJourneyType, - GqlUtil gqlUtil + GraphQLOutputType serviceJourneyType ) { return GraphQLObjectType .newObject() @@ -48,12 +47,12 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("lines") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(lineType))) .dataFetcher(environment -> GqlUtil .getTransitService(environment) - .getAllRoutes() + .listRoutes() .stream() .filter(route -> Objects.equals(route.getOperator(), environment.getSource())) .collect(Collectors.toList()) @@ -64,12 +63,12 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("serviceJourney") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(serviceJourneyType))) .dataFetcher(environment -> GqlUtil .getTransitService(environment) - .getAllTrips() + .listTrips() .stream() .filter(trip -> Objects.equals(trip.getOperator(), environment.getSource())) .collect(Collectors.toList()) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/PassThroughPointInputType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/PassThroughPointInputType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/PassThroughPointInputType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/PassThroughPointInputType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/PenaltyForStreetModeType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/PenaltyForStreetModeType.java similarity index 96% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/PenaltyForStreetModeType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/PenaltyForStreetModeType.java index 6d945ae912f..c553fccf667 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/PenaltyForStreetModeType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/PenaltyForStreetModeType.java @@ -19,10 +19,10 @@ import org.opentripplanner.apis.transmodel.model.EnumTypes; import org.opentripplanner.apis.transmodel.model.scalars.DoubleFunction; import org.opentripplanner.apis.transmodel.support.GqlUtil; -import org.opentripplanner.framework.lang.ObjectUtils; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.api.request.framework.TimeAndCostPenalty; import org.opentripplanner.routing.api.request.framework.TimeAndCostPenaltyForEnum; +import org.opentripplanner.utils.lang.ObjectUtils; /** * Access and egress penalty: @@ -47,7 +47,7 @@ public class PenaltyForStreetModeType { private static final String FIELD_TIME_PENALTY = "timePenalty"; private static final String FIELD_COST_FACTOR = "costFactor"; - public static GraphQLInputObjectType create(GqlUtil gqlUtil) { + public static GraphQLInputObjectType create() { return GraphQLInputObjectType .newInputObject() .name("PenaltyForStreetMode") @@ -70,7 +70,7 @@ public static GraphQLInputObjectType create(GqlUtil gqlUtil) { GraphQLInputObjectField .newInputObjectField() .name(FIELD_TIME_PENALTY) - .type(new GraphQLNonNull(gqlUtil.doubleFunctionScalar)) + .type(new GraphQLNonNull(TransmodelScalars.DOUBLE_FUNCTION_SCALAR)) .description( """ Penalty applied to the time for the given list of modes. diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/PointsOnLinkType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/PointsOnLinkType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/PointsOnLinkType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/PointsOnLinkType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/RentalVehicleTypeType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/RentalVehicleTypeType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/RentalVehicleTypeType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/RentalVehicleTypeType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ServerInfoType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ServerInfoType.java similarity index 80% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/ServerInfoType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ServerInfoType.java index ae6889ab033..8f679cafda3 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ServerInfoType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ServerInfoType.java @@ -9,6 +9,7 @@ import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; +import org.opentripplanner.apis.transmodel.support.GqlUtil; public class ServerInfoType { @@ -16,6 +17,13 @@ public static GraphQLOutputType create() { return GraphQLObjectType .newObject() .name("ServerInfo") + .description( + """ + Information about the deployment. This is only useful to developers of OTP itself. + It is not recommended for regular API consumers to use this type as it has no + stability guarantees. + """ + ) .field( GraphQLFieldDefinition .newFieldDefinition() @@ -99,6 +107,21 @@ public static GraphQLOutputType create() { .dataFetcher(e -> projectInfo().getOtpSerializationVersionId()) .build() ) + .field( + GraphQLFieldDefinition + .newFieldDefinition() + .name("internalTransitModelTimeZone") + .description( + """ + The internal time zone of the transit data. + + Note: The input data can be in several time zones, but OTP internally operates on a single one. + """ + ) + .type(Scalars.GraphQLString) + .dataFetcher(e -> GqlUtil.getTransitService(e).getTimeZone()) + .build() + ) .build(); } } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/StreetModeDurationInputType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/StreetModeDurationInputType.java similarity index 95% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/StreetModeDurationInputType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/StreetModeDurationInputType.java index bf274688617..9c92d7253d5 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/StreetModeDurationInputType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/StreetModeDurationInputType.java @@ -17,16 +17,16 @@ import java.util.Objects; import org.opentripplanner.apis.transmodel.model.EnumTypes; import org.opentripplanner.apis.transmodel.support.GqlUtil; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.api.request.framework.DurationForEnum; +import org.opentripplanner.utils.time.DurationUtils; public class StreetModeDurationInputType { private static final String FIELD_STREET_MODE = "streetMode"; private static final String FIELD_DURATION = "duration"; - public static GraphQLInputObjectType create(GqlUtil gqlUtil) { + public static GraphQLInputObjectType create() { return GraphQLInputObjectType .newInputObject() .name("StreetModeDurationInput") @@ -42,7 +42,7 @@ public static GraphQLInputObjectType create(GqlUtil gqlUtil) { GraphQLInputObjectField .newInputObjectField() .name(FIELD_DURATION) - .type(new GraphQLNonNull(gqlUtil.durationScalar)) + .type(new GraphQLNonNull(TransmodelScalars.DURATION_SCALAR)) ) .build(); } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/SystemNoticeType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/SystemNoticeType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/SystemNoticeType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/SystemNoticeType.java diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/TransmodelDirectives.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/TransmodelDirectives.java new file mode 100644 index 00000000000..98ee99a8a64 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/TransmodelDirectives.java @@ -0,0 +1,14 @@ +package org.opentripplanner.apis.transmodel.model.framework; + +import graphql.introspection.Introspection; +import graphql.schema.GraphQLDirective; + +public class TransmodelDirectives { + + public static final GraphQLDirective TIMING_DATA = GraphQLDirective + .newDirective() + .name("timingData") + .description("Add timing data to prometheus, if Actuator API is enabled") + .validLocation(Introspection.DirectiveLocation.FIELD_DEFINITION) + .build(); +} diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/TransmodelScalars.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/TransmodelScalars.java new file mode 100644 index 00000000000..404fbd4a5ba --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/TransmodelScalars.java @@ -0,0 +1,30 @@ +package org.opentripplanner.apis.transmodel.model.framework; + +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLScalarType; +import org.opentripplanner.apis.transmodel.model.scalars.DoubleFunctionFactory; +import org.opentripplanner.apis.transmodel.model.scalars.LocalTimeScalarFactory; +import org.opentripplanner.apis.transmodel.model.scalars.TimeScalarFactory; +import org.opentripplanner.framework.graphql.scalar.DateScalarFactory; +import org.opentripplanner.framework.graphql.scalar.DurationScalarFactory; + +/** + * This class contains all Transmodel custom scalars, except the + * {@link org.opentripplanner.apis.transmodel.support.GqlUtil#dateTimeScalar}. + */ +public class TransmodelScalars { + + public static final GraphQLScalarType DATE_SCALAR; + public static final GraphQLScalarType DOUBLE_FUNCTION_SCALAR; + public static final GraphQLScalarType LOCAL_TIME_SCALAR; + public static final GraphQLObjectType TIME_SCALAR; + public static final GraphQLScalarType DURATION_SCALAR; + + static { + DATE_SCALAR = DateScalarFactory.createTransmodelDateScalar(); + DOUBLE_FUNCTION_SCALAR = DoubleFunctionFactory.createDoubleFunctionScalar(); + LOCAL_TIME_SCALAR = LocalTimeScalarFactory.createLocalTimeScalar(); + TIME_SCALAR = TimeScalarFactory.createSecondsSinceMidnightAsTimeObject(); + DURATION_SCALAR = DurationScalarFactory.createDurationScalar(); + } +} diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ValidityPeriodType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ValidityPeriodType.java similarity index 84% rename from src/main/java/org/opentripplanner/apis/transmodel/model/framework/ValidityPeriodType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ValidityPeriodType.java index 35ea9258322..956c24a60d5 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ValidityPeriodType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ValidityPeriodType.java @@ -2,12 +2,12 @@ import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLScalarType; import org.opentripplanner.apis.transmodel.model.siri.sx.ValidityPeriod; -import org.opentripplanner.apis.transmodel.support.GqlUtil; public class ValidityPeriodType { - public static GraphQLObjectType create(GqlUtil gqlUtil) { + public static GraphQLObjectType create(GraphQLScalarType dateTimeScalar) { return GraphQLObjectType .newObject() .name("ValidityPeriod") @@ -15,7 +15,7 @@ public static GraphQLObjectType create(GqlUtil gqlUtil) { GraphQLFieldDefinition .newFieldDefinition() .name("startTime") - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .description("Start of validity period") .dataFetcher(environment -> { ValidityPeriod period = environment.getSource(); @@ -27,7 +27,7 @@ public static GraphQLObjectType create(GqlUtil gqlUtil) { GraphQLFieldDefinition .newFieldDefinition() .name("endTime") - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .description("End of validity period. Will return 'null' if validity is open-ended.") .dataFetcher(environment -> { ValidityPeriod period = environment.getSource(); diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/network/DestinationDisplayType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/DestinationDisplayType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/network/DestinationDisplayType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/network/DestinationDisplayType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/network/GroupOfLinesType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/GroupOfLinesType.java similarity index 96% rename from src/main/java/org/opentripplanner/apis/transmodel/model/network/GroupOfLinesType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/network/GroupOfLinesType.java index 0339269dbd8..6e52c6662a4 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/network/GroupOfLinesType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/GroupOfLinesType.java @@ -71,7 +71,7 @@ public static GraphQLObjectType create() { .description("All lines part of this group of lines") .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(LineType.REF)))) .dataFetcher(env -> - GqlUtil.getTransitService(env).getRoutesForGroupOfRoutes(env.getSource()) + GqlUtil.getTransitService(env).findRoutes((GroupOfRoutes) env.getSource()) ) .build() ) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/network/JourneyPatternType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/JourneyPatternType.java similarity index 91% rename from src/main/java/org/opentripplanner/apis/transmodel/model/network/JourneyPatternType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/network/JourneyPatternType.java index 0743b02a3c4..dfde7427e5f 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/network/JourneyPatternType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/JourneyPatternType.java @@ -16,6 +16,8 @@ import org.locationtech.jts.geom.LineString; import org.opentripplanner.apis.transmodel.mapping.GeometryMapper; import org.opentripplanner.apis.transmodel.model.EnumTypes; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelDirectives; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars; import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.framework.geometry.EncodedPolyline; import org.opentripplanner.transit.model.network.TripPattern; @@ -33,8 +35,7 @@ public static GraphQLObjectType create( GraphQLOutputType lineType, GraphQLOutputType serviceJourneyType, GraphQLOutputType stopToStopGeometryType, - GraphQLNamedOutputType ptSituationElementType, - GqlUtil gqlUtil + GraphQLNamedOutputType ptSituationElementType ) { return GraphQLObjectType .newObject() @@ -68,7 +69,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("serviceJourneys") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(serviceJourneyType)))) .dataFetcher(e -> ((TripPattern) e.getSource()).scheduledTripsAsStream().collect(Collectors.toList()) @@ -79,9 +80,11 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("serviceJourneysForDate") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .description("List of service journeys for the journey pattern for a given date") - .argument(GraphQLArgument.newArgument().name("date").type(gqlUtil.dateScalar).build()) + .argument( + GraphQLArgument.newArgument().name("date").type(TransmodelScalars.DATE_SCALAR).build() + ) .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(serviceJourneyType)))) .dataFetcher(environment -> { TIntSet services = GqlUtil @@ -163,7 +166,7 @@ public static GraphQLObjectType create( .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(noticeType)))) .dataFetcher(environment -> { TripPattern tripPattern = environment.getSource(); - return GqlUtil.getTransitService(environment).getNoticesByEntity(tripPattern); + return GqlUtil.getTransitService(environment).findNotices(tripPattern); }) .build() ) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/network/LineType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/LineType.java similarity index 83% rename from src/main/java/org/opentripplanner/apis/transmodel/model/network/LineType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/network/LineType.java index 32ea357a0aa..9aa129b2abd 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/network/LineType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/LineType.java @@ -46,7 +46,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("id") .type(new GraphQLNonNull(Scalars.GraphQLID)) - .dataFetcher(environment -> TransitIdMapper.mapEntityIDToApi(environment.getSource())) + .dataFetcher(environment -> TransitIdMapper.mapEntityIDToApi(getSource(environment))) .build() ) .field( @@ -54,7 +54,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("authority") .type(authorityType) - .dataFetcher(environment -> (((Route) environment.getSource()).getAgency())) + .dataFetcher(environment -> (getSource(environment).getAgency())) .build() ) .field( @@ -62,7 +62,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("operator") .type(operatorType) - .dataFetcher(environment -> (((Route) environment.getSource()).getOperator())) + .dataFetcher(environment -> ((getSource(environment)).getOperator())) .build() ) .field( @@ -70,7 +70,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("branding") .type(brandingType) - .dataFetcher(environment -> ((Route) environment.getSource()).getBranding()) + .dataFetcher(environment -> (getSource(environment)).getBranding()) ) .field( GraphQLFieldDefinition @@ -80,7 +80,7 @@ public static GraphQLObjectType create( .description( "Publicly announced code for line, differentiating it from other lines for the same operator." ) - .dataFetcher(environment -> (((Route) environment.getSource()).getShortName())) + .dataFetcher(environment -> ((getSource(environment)).getShortName())) .build() ) .field( @@ -88,7 +88,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("name") .type(Scalars.GraphQLString) - .dataFetcher(environment -> ((Route) environment.getSource()).getLongName()) + .dataFetcher(environment -> (getSource(environment)).getLongName()) .build() ) .field( @@ -96,7 +96,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("transportMode") .type(EnumTypes.TRANSPORT_MODE) - .dataFetcher(environment -> ((Route) environment.getSource()).getMode()) + .dataFetcher(environment -> (getSource(environment)).getMode()) .build() ) .field( @@ -105,9 +105,7 @@ public static GraphQLObjectType create( .name("transportSubmode") .type(EnumTypes.TRANSPORT_SUBMODE) .dataFetcher(environment -> - TransmodelTransportSubmode.fromValue( - ((Route) environment.getSource()).getNetexSubmode() - ) + TransmodelTransportSubmode.fromValue((getSource(environment)).getNetexSubmode()) ) .build() ) @@ -116,7 +114,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("description") .type(Scalars.GraphQLString) - .dataFetcher(environment -> ((Route) environment.getSource()).getDescription()) + .dataFetcher(environment -> (getSource(environment)).getDescription()) .build() ) .field( @@ -143,7 +141,7 @@ public static GraphQLObjectType create( .name("journeyPatterns") .type(new GraphQLList(journeyPatternType)) .dataFetcher(environment -> - GqlUtil.getTransitService(environment).getPatternsForRoute(environment.getSource()) + GqlUtil.getTransitService(environment).findPatterns(getSource(environment)) ) .build() ) @@ -155,7 +153,7 @@ public static GraphQLObjectType create( .dataFetcher(environment -> GqlUtil .getTransitService(environment) - .getPatternsForRoute(environment.getSource()) + .findPatterns(getSource(environment)) .stream() .map(TripPattern::getStops) .flatMap(Collection::stream) @@ -172,7 +170,7 @@ public static GraphQLObjectType create( .dataFetcher(environment -> GqlUtil .getTransitService(environment) - .getPatternsForRoute(environment.getSource()) + .findPatterns(getSource(environment)) .stream() .flatMap(TripPattern::scheduledTripsAsStream) .distinct() @@ -186,8 +184,8 @@ public static GraphQLObjectType create( .name("notices") .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(noticeType)))) .dataFetcher(environment -> { - Route route = environment.getSource(); - return GqlUtil.getTransitService(environment).getNoticesByEntity(route); + Route route = getSource(environment); + return GqlUtil.getTransitService(environment).findNotices(route); }) .build() ) @@ -201,7 +199,7 @@ public static GraphQLObjectType create( GqlUtil .getTransitService(environment) .getTransitAlertService() - .getRouteAlerts(((Route) environment.getSource()).getId()) + .getRouteAlerts((getSource(environment)).getId()) ) .build() ) @@ -211,7 +209,7 @@ public static GraphQLObjectType create( .name("flexibleLineType") .description("Type of flexible line, or null if line is not flexible.") .type(Scalars.GraphQLString) - .dataFetcher(environment -> ((Route) environment.getSource()).getFlexibleLineType()) + .dataFetcher(environment -> (getSource(environment)).getFlexibleLineType()) .build() ) .field( @@ -232,9 +230,13 @@ public static GraphQLObjectType create( .name("groupOfLines") .description("Groups of lines that line is a part of.") .type(new GraphQLNonNull(new GraphQLList(groupOfLinesType))) - .dataFetcher(environment -> ((Route) environment.getSource()).getGroupsOfRoutes()) + .dataFetcher(environment -> (getSource(environment)).getGroupsOfRoutes()) .build() ) .build(); } + + private static Route getSource(DataFetchingEnvironment environment) { + return environment.getSource(); + } } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/network/PresentationType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/PresentationType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/network/PresentationType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/network/PresentationType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/network/StopToStopGeometryType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/StopToStopGeometryType.java similarity index 94% rename from src/main/java/org/opentripplanner/apis/transmodel/model/network/StopToStopGeometryType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/network/StopToStopGeometryType.java index 800eda04cb2..98a965e50be 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/network/StopToStopGeometryType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/network/StopToStopGeometryType.java @@ -3,7 +3,7 @@ import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; -import org.opentripplanner.apis.transmodel.model.util.EncodedPolylineBeanWithStops; +import org.opentripplanner.apis.transmodel.model.framework.EncodedPolylineBeanWithStops; public class StopToStopGeometryType { diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/BannedInputType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/BannedInputType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/BannedInputType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/BannedInputType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ElevationProfileStepType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ElevationProfileStepType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/ElevationProfileStepType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ElevationProfileStepType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/FilterInputType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/FilterInputType.java similarity index 94% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/FilterInputType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/FilterInputType.java index ce792ca3790..1e868eadb86 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/FilterInputType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/FilterInputType.java @@ -7,7 +7,7 @@ public class FilterInputType { - static final GraphQLInputObjectType INPUT_TYPE = GraphQLInputObjectType + public static final GraphQLInputObjectType INPUT_TYPE = GraphQLInputObjectType .newInputObject() .name("TripFilterInput") .description( diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ItineraryFiltersInputType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ItineraryFiltersInputType.java similarity index 97% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/ItineraryFiltersInputType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ItineraryFiltersInputType.java index b5d82af5138..7f0d5b10215 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ItineraryFiltersInputType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ItineraryFiltersInputType.java @@ -8,6 +8,7 @@ import java.util.Map; import java.util.function.Consumer; import org.opentripplanner.apis.transmodel.model.EnumTypes; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars; import org.opentripplanner.apis.transmodel.model.scalars.DoubleFunction; import org.opentripplanner.apis.transmodel.support.DataFetcherDecorator; import org.opentripplanner.apis.transmodel.support.GqlUtil; @@ -26,7 +27,7 @@ public class ItineraryFiltersInputType { private static final String GROUP_SIMILARITY_KEEP_N_ITINERARIES = "groupSimilarityKeepNumOfItineraries"; - public static GraphQLInputObjectType create(GqlUtil gqlUtil, ItineraryFilterPreferences dft) { + public static GraphQLInputObjectType create(ItineraryFilterPreferences dft) { return GraphQLInputObjectType .newInputObject() .name("ItineraryFilters") @@ -59,7 +60,7 @@ public static GraphQLInputObjectType create(GqlUtil gqlUtil, ItineraryFilterPref GraphQLInputObjectField .newInputObjectField() .name("costLimitFunction") - .type(new GraphQLNonNull(gqlUtil.doubleFunctionScalar)) + .type(new GraphQLNonNull(TransmodelScalars.DOUBLE_FUNCTION_SCALAR)) .build() ) .field( diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/JourneyWhiteListed.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/JourneyWhiteListed.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/JourneyWhiteListed.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/JourneyWhiteListed.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/LegType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/LegType.java similarity index 95% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/LegType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/LegType.java index 867d08e3933..4b405f50f66 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/LegType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/LegType.java @@ -12,6 +12,7 @@ import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLScalarType; import graphql.schema.GraphQLType; import graphql.schema.GraphQLTypeReference; import java.util.List; @@ -22,6 +23,8 @@ import org.opentripplanner.apis.transmodel.model.EnumTypes; import org.opentripplanner.apis.transmodel.model.TransmodelTransportSubmode; import org.opentripplanner.apis.transmodel.model.TripTimeOnDateHelper; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelDirectives; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars; import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.framework.geometry.EncodedPolyline; import org.opentripplanner.model.plan.Leg; @@ -30,6 +33,7 @@ import org.opentripplanner.model.plan.TransitLeg; import org.opentripplanner.model.plan.legreference.LegReferenceSerializer; import org.opentripplanner.routing.alternativelegs.AlternativeLegs; +import org.opentripplanner.routing.alternativelegs.NavigationDirection; public class LegType { @@ -51,7 +55,7 @@ public static GraphQLObjectType create( GraphQLObjectType placeType, GraphQLObjectType pathGuidanceType, GraphQLType elevationStepType, - GqlUtil gqlUtil + GraphQLScalarType dateTimeScalar ) { return GraphQLObjectType .newObject() @@ -63,7 +67,9 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("id") - .description("An identifier for the leg, which can be used to re-fetch the information.") + .description( + "An identifier for the leg, which can be used to re-fetch transit leg information." + ) .type(Scalars.GraphQLID) .dataFetcher(env -> LegReferenceSerializer.encode(leg(env).getLegReference())) .build() @@ -73,7 +79,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("aimedStartTime") .description("The aimed date and time this leg starts.") - .type(new GraphQLNonNull(gqlUtil.dateTimeScalar)) + .type(new GraphQLNonNull(dateTimeScalar)) .dataFetcher(env -> // startTime is already adjusted for real-time - need to subtract delay to get aimed time leg(env) @@ -89,7 +95,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("expectedStartTime") .description("The expected, real-time adjusted date and time this leg starts.") - .type(new GraphQLNonNull(gqlUtil.dateTimeScalar)) + .type(new GraphQLNonNull(dateTimeScalar)) .dataFetcher(env -> leg(env).getStartTime().toInstant().toEpochMilli()) .build() ) @@ -98,7 +104,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("aimedEndTime") .description("The aimed date and time this leg ends.") - .type(new GraphQLNonNull(gqlUtil.dateTimeScalar)) + .type(new GraphQLNonNull(dateTimeScalar)) .dataFetcher(env -> // endTime is already adjusted for real-time - need to subtract delay to get aimed time leg(env) .getEndTime() @@ -113,7 +119,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("expectedEndTime") .description("The expected, real-time adjusted date and time this leg ends.") - .type(new GraphQLNonNull(gqlUtil.dateTimeScalar)) + .type(new GraphQLNonNull(dateTimeScalar)) .dataFetcher(env -> leg(env).getEndTime().toInstant().toEpochMilli()) .build() ) @@ -268,7 +274,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("fromEstimatedCall") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .description("EstimatedCall for the quay where the leg originates.") .type(estimatedCallType) .dataFetcher(env -> TripTimeOnDateHelper.getTripTimeOnDateForFromPlace(env.getSource())) @@ -278,7 +284,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("toEstimatedCall") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .description("EstimatedCall for the quay where the leg ends.") .type(estimatedCallType) .dataFetcher(env -> TripTimeOnDateHelper.getTripTimeOnDateForToPlace(env.getSource())) @@ -318,7 +324,7 @@ public static GraphQLObjectType create( .description( "For transit legs, the service date of the trip. For non-transit legs, null." ) - .type(gqlUtil.dateScalar) + .type(TransmodelScalars.DATE_SCALAR) .dataFetcher(environment -> Optional.of((Leg) environment.getSource()).map(Leg::getServiceDate).orElse(null) ) @@ -352,7 +358,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("intermediateEstimatedCalls") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .description( "For ride legs, estimated calls for quays between the Place where the leg originates and the Place where the leg ends. For non-ride legs, empty list." ) @@ -366,7 +372,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("serviceJourneyEstimatedCalls") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .description( "For ride legs, all estimated calls for the service journey. For non-ride legs, empty list." ) @@ -480,7 +486,7 @@ public static GraphQLObjectType create( leg, env.getArgument("previous"), GqlUtil.getTransitService(env), - true, + NavigationDirection.PREVIOUS, env.getArgument("filter") ); }) @@ -520,7 +526,7 @@ public static GraphQLObjectType create( leg, env.getArgument("next"), GqlUtil.getTransitService(env), - false, + NavigationDirection.NEXT, env.getArgument("filter") ); }) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ModeAndSubModeInputType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ModeAndSubModeInputType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/ModeAndSubModeInputType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ModeAndSubModeInputType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ModeInputType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ModeInputType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/ModeInputType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ModeInputType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PlanPlaceType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PlanPlaceType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/PlanPlaceType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PlanPlaceType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostType.java similarity index 98% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostType.java index 41435c83a2f..9272bd86757 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostType.java @@ -10,8 +10,8 @@ import java.util.Map; import org.opentripplanner.framework.graphql.scalar.CostScalarFactory; import org.opentripplanner.framework.model.Cost; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; +import org.opentripplanner.utils.time.DurationUtils; public class RelaxCostType { diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/SelectInputType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/SelectInputType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/SelectInputType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/SelectInputType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TriangleFactorsInputType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TriangleFactorsInputType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/TriangleFactorsInputType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TriangleFactorsInputType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternTimePenaltyType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternTimePenaltyType.java similarity index 98% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternTimePenaltyType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternTimePenaltyType.java index 744113929c7..2ad88762408 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternTimePenaltyType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternTimePenaltyType.java @@ -4,7 +4,7 @@ import graphql.schema.DataFetchingEnvironment; import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLObjectType; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.utils.time.DurationUtils; public class TripPatternTimePenaltyType { diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java similarity index 95% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java index c903016b91b..42899beca55 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java @@ -8,7 +8,7 @@ import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; -import org.opentripplanner.apis.transmodel.support.GqlUtil; +import graphql.schema.GraphQLScalarType; import org.opentripplanner.model.plan.Itinerary; public class TripPatternType { @@ -17,7 +17,7 @@ public static GraphQLObjectType create( GraphQLOutputType systemNoticeType, GraphQLObjectType legType, GraphQLObjectType timePenaltyType, - GqlUtil gqlUtil + GraphQLScalarType dateTimeScalar ) { return GraphQLObjectType .newObject() @@ -30,7 +30,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("startTime") .description("Time that the trip departs.") - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .deprecate("Replaced with expectedStartTime") .dataFetcher(env -> itinerary(env).startTime().toInstant().toEpochMilli()) .build() @@ -40,7 +40,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("endTime") .description("Time that the trip arrives.") - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .deprecate("Replaced with expectedEndTime") .dataFetcher(env -> itinerary(env).endTime().toInstant().toEpochMilli()) .build() @@ -50,7 +50,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("aimedStartTime") .description("The aimed date and time the trip starts.") - .type(new GraphQLNonNull(gqlUtil.dateTimeScalar)) + .type(new GraphQLNonNull(dateTimeScalar)) .dataFetcher(env -> // startTime is already adjusted for real-time - need to subtract delay to get aimed time itinerary(env) @@ -66,7 +66,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("expectedStartTime") .description("The expected, real-time adjusted date and time the trip starts.") - .type(new GraphQLNonNull(gqlUtil.dateTimeScalar)) + .type(new GraphQLNonNull(dateTimeScalar)) .dataFetcher(env -> itinerary(env).startTime().toInstant().toEpochMilli()) .build() ) @@ -75,7 +75,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("aimedEndTime") .description("The aimed date and time the trip ends.") - .type(new GraphQLNonNull(gqlUtil.dateTimeScalar)) + .type(new GraphQLNonNull(dateTimeScalar)) .dataFetcher(env -> // endTime is already adjusted for real-time - need to subtract delay to get aimed time itinerary(env) @@ -91,7 +91,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("expectedEndTime") .description("The expected, real-time adjusted date and time the trip ends.") - .type(new GraphQLNonNull(gqlUtil.dateTimeScalar)) + .type(new GraphQLNonNull(dateTimeScalar)) .dataFetcher(env -> itinerary(env).endTime().toInstant().toEpochMilli()) .build() ) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPlanTimePenaltyDto.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPlanTimePenaltyDto.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPlanTimePenaltyDto.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPlanTimePenaltyDto.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java similarity index 85% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java index b67b26b90b6..ac496131954 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java @@ -11,6 +11,7 @@ import graphql.schema.GraphQLList; import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLScalarType; import org.opentripplanner.apis.transmodel.TransmodelGraphQLPlanner; import org.opentripplanner.apis.transmodel.model.DefaultRouteRequestType; import org.opentripplanner.apis.transmodel.model.EnumTypes; @@ -18,7 +19,8 @@ import org.opentripplanner.apis.transmodel.model.framework.LocationInputType; import org.opentripplanner.apis.transmodel.model.framework.PassThroughPointInputType; import org.opentripplanner.apis.transmodel.model.framework.PenaltyForStreetModeType; -import org.opentripplanner.apis.transmodel.support.GqlUtil; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelDirectives; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitTuningParameters; import org.opentripplanner.routing.api.request.preference.RoutingPreferences; import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; @@ -27,13 +29,20 @@ public class TripQuery { public static final String ACCESS_EGRESS_PENALTY = "accessEgressPenalty"; public static final String MAX_ACCESS_EGRESS_DURATION_FOR_MODE = "maxAccessEgressDurationForMode"; public static final String MAX_DIRECT_DURATION_FOR_MODE = "maxDirectDurationForMode"; + public static final String TRIP_VIA_PARAMETER = "via"; + public static final String DOC_VIA = + """ + The list of via locations the journey is required to visit. All locations are + visited in the order they are listed. + """; public static GraphQLFieldDefinition create( DefaultRouteRequestType routing, + TransitTuningParameters transitTuningParameters, GraphQLOutputType tripType, GraphQLInputObjectType durationPerStreetModeType, GraphQLInputObjectType penaltyForStreetMode, - GqlUtil gqlUtil + GraphQLScalarType dateTimeScalar ) { RoutingPreferences preferences = routing.request.preferences(); @@ -45,7 +54,7 @@ public static GraphQLFieldDefinition create( "trip patterns describing suggested alternatives for the trip." ) .type(new GraphQLNonNull(tripType)) - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .argument( GraphQLArgument .newArgument() @@ -55,7 +64,7 @@ public static GraphQLFieldDefinition create( "(if `false` or not set) or the latest acceptable time of arriving " + "(`true`). Defaults to now." ) - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .build() ) .argument( @@ -72,7 +81,7 @@ Normally this is when the search is performed (now), plus a small grace period t restrictions are applied - all journeys are listed. """ ) - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .build() ) .argument( @@ -80,30 +89,42 @@ Normally this is when the search is performed (now), plus a small grace period t .newArgument() .name("searchWindow") .description( - "The length of the search-window in minutes. This parameter is optional." + - "\n\n" + - "The search-window is defined as the duration between the earliest-departure-time(EDT) and " + - "the latest-departure-time(LDT). OTP will search for all itineraries in this departure " + - "window. If `arriveBy=true` the `dateTime` parameter is the latest-arrival-time, so OTP " + - "will dynamically calculate the EDT. Using a short search-window is faster than using a " + - "longer one, but the search duration is not linear. Using a \"too\" short search-window will " + - "waste resources server side, while using a search-window that is too long will be slow." + - "\n\n" + - "OTP will dynamically calculate a reasonable value for the search-window, if not provided. The " + - "calculation comes with a significant overhead (10-20% extra). Whether you should use the " + - "dynamic calculated value or pass in a value depends on your use-case. For a travel planner " + - "in a small geographical area, with a dense network of public transportation, a fixed value " + - "between 40 minutes and 2 hours makes sense. To find the appropriate search-window, adjust it " + - "so that the number of itineraries on average is around the wanted `numItineraries`. Make " + - "sure you set the `numItineraries` to a high number while testing. For a country wide area like " + - "Norway, using the dynamic search-window is the best." + - "\n\n" + - "When paginating, the search-window is calculated using the `numItineraries` in the original " + - "search together with statistics from the search for the last page. This behaviour is " + - "configured server side, and can not be overridden from the client." + - "\n\n" + - "The search-window used is returned to the response metadata as `searchWindowUsed` for " + - "debugging purposes." + """ + The length of the search-window in minutes. This parameter is optional. + + The search-window is defined as the duration between the earliest-departure-time(EDT) and + the latest-departure-time(LDT). OTP will search for all itineraries in this departure + window. If `arriveBy=true` the `dateTime` parameter is the latest-arrival-time, so OTP + will dynamically calculate the EDT. Using a short search-window is faster than using a + longer one, but the search duration is not linear. Using a \"too\" short search-window will + waste resources server side, while using a search-window that is too long will be slow. + + OTP will dynamically calculate a reasonable value for the search-window, if not provided. The + calculation comes with a significant overhead (10-20%% extra). Whether you should use the + dynamic calculated value or pass in a value depends on your use-case. For a travel planner + in a small geographical area, with a dense network of public transportation, a fixed value + between 40 minutes and 2 hours makes sense. To find the appropriate search-window, adjust it + so that the number of itineraries on average is around the wanted `numTripPatterns`. Make + sure you set the `numTripPatterns` to a high number while testing. For a country wide area like + Norway, using the dynamic search-window is the best. + + When paginating, the search-window is calculated using the `numTripPatterns` in the original + search together with statistics from the search for the last page. This behaviour is + configured server side, and can not be overridden from the client. The paging may even + exceed the maximum value. + + The search-window used is returned to the response metadata as `searchWindowUsed`. + This can be used by the client to calculate the when the next page start/end. + + Note! In some cases you may have to page many times to get all the results you want. + This is intended. Increasing the search-window beyond the max value is NOT going to be + much faster. Instead the client can inform the user about the progress. + + Maximum value: %d minutes (%dh) + """.formatted( + transitTuningParameters.maxSearchWindow().toMinutes(), + transitTuningParameters.maxSearchWindow().toHours() + ) ) .type(Scalars.GraphQLInt) .build() @@ -113,9 +134,12 @@ Normally this is when the search is performed (now), plus a small grace period t .newArgument() .name("pageCursor") .description( - "Use the cursor to go to the next \"page\" of itineraries. Copy the cursor from " + - "the last response and keep the original request as is. This will enable you to " + - "search for itineraries in the next or previous time-window." + """ + Use the cursor to go to the next \"page\" of itineraries. Copy the cursor from the last + response and keep the original request as is. This will enable you to search for + itineraries in the next or previous search-window. The paging will automatically scale + up/down the search-window to fit the `numTripPatterns`. + """ ) .type(Scalars.GraphQLString) .build() @@ -173,10 +197,19 @@ Normally this is when the search is performed (now), plus a small grace period t GraphQLArgument .newArgument() .name("passThroughPoints") + .deprecate("Use via instead") .description("The list of points the journey is required to pass through.") .type(new GraphQLList(new GraphQLNonNull(PassThroughPointInputType.INPUT_TYPE))) .build() ) + .argument( + GraphQLArgument + .newArgument() + .name(TRIP_VIA_PARAMETER) + .description(DOC_VIA) + .type(new GraphQLList(new GraphQLNonNull(ViaLocationInputType.VIA_LOCATION_INPUT))) + .build() + ) .argument( GraphQLArgument .newArgument() @@ -572,7 +605,7 @@ Normally this is when the search is performed (now), plus a small grace period t "Configure the itinerary-filter-chain. NOTE! THESE PARAMETERS ARE USED " + "FOR SERVER-SIDE TUNING AND IS AVAILABLE HERE FOR TESTING ONLY." ) - .type(ItineraryFiltersInputType.create(gqlUtil, preferences.itineraryFilter())) + .type(ItineraryFiltersInputType.create(preferences.itineraryFilter())) .build() ) .argument( diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java similarity index 98% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java index 053b261c08e..d214bed983f 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java @@ -7,10 +7,10 @@ import graphql.schema.GraphQLList; import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLScalarType; import java.util.stream.Collectors; 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; import org.opentripplanner.model.plan.paging.cursor.PageCursor; @@ -21,7 +21,7 @@ public static GraphQLObjectType create( GraphQLObjectType tripPatternType, GraphQLObjectType tripMetadataType, GraphQLObjectType routingErrorType, - GqlUtil gqlUtil + GraphQLScalarType dateTimeScalar ) { return GraphQLObjectType .newObject() @@ -32,7 +32,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("dateTime") .description("The time and date of travel") - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .dataFetcher(env -> ((PlanResponse) env.getSource()).plan.date.toEpochMilli()) .build() ) diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaLocationInputType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaLocationInputType.java new file mode 100644 index 00000000000..ef13f8db18e --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaLocationInputType.java @@ -0,0 +1,126 @@ +package org.opentripplanner.apis.transmodel.model.plan; + +import static graphql.Directives.OneOfDirective; +import static graphql.Scalars.GraphQLString; + +import graphql.language.StringValue; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInputType; +import graphql.schema.GraphQLList; +import graphql.schema.GraphQLNonNull; +import java.time.Duration; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars; + +public class ViaLocationInputType { + + /* type constants */ + + private static final String INPUT_VIA_LOCATION = "TripViaLocationInput"; + private static final String INPUT_VISIT_VIA_LOCATION = "TripVisitViaLocationInput"; + private static final String INPUT_PASS_THROUGH_VIA_LOCATION = "TripPassThroughViaLocationInput"; + + private static final String DOC_VISIT_VIA_LOCATION = + """ + A visit-via-location is a physical visit to one of the stop locations or coordinates listed. An + on-board visit does not count, the traveler must alight or board at the given stop for it to to + be accepted. To visit a coordinate, the traveler must walk(bike or drive) to the closest point + in the street network from a stop and back to another stop to join the transit network. + + NOTE! Coordinates are NOT supported yet. + """; + private static final String DOC_PASS_THROUGH_VIA_LOCATION = + """ + One of the listed stop locations must be visited on-board a transit vehicle or the journey must + alight or board at the location. + """; + private static final String DOC_VIA_LOCATION = + """ + A via-location is used to specifying a location as an intermediate place the router must + route through. The via-location is either a pass-through-location or a visit-via-location. + """; + + /* field constants */ + + public static final String FIELD_LABEL = "label"; + public static final String FIELD_MINIMUM_WAIT_TIME = "minimumWaitTime"; + public static final String FIELD_STOP_LOCATION_IDS = "stopLocationIds"; + + // TODO : Add coordinates + //private static final String FIELD_COORDINATES = "coordinates"; + public static final String FIELD_VISIT = "visit"; + public static final String DOC_FIELD_VISIT = + "Board or alight at a stop location or visit a coordinate."; + public static final String FIELD_PASS_THROUGH = "passThrough"; + public static final String DOC_FIELD_PASS_THROUGH = + "Board, alight or pass-through(on-board) at the stop location."; + + private static final String DOC_LABEL = + "The label/name of the location. This is pass-through " + + "information and is not used in routing."; + private static final String DOC_MINIMUM_WAIT_TIME = + """ + The minimum wait time is used to force the trip to stay the given duration at the + via-location before the trip is continued. + """; + private static final String DOC_STOP_LOCATION_IDS = + """ + A list of stop locations. A stop location can be a quay, a stop place, a multimodal + stop place or a group of stop places. It is enough to visit ONE of the locations + listed. + """; + + static final GraphQLInputObjectType VISIT_VIA_LOCATION_INPUT = GraphQLInputObjectType + .newInputObject() + .name(INPUT_VISIT_VIA_LOCATION) + .description(DOC_VISIT_VIA_LOCATION) + .field(b -> b.name(FIELD_LABEL).description(DOC_LABEL).type(GraphQLString)) + .field(b -> + b + .name(FIELD_MINIMUM_WAIT_TIME) + .description(DOC_MINIMUM_WAIT_TIME) + .type(TransmodelScalars.DURATION_SCALAR) + .defaultValueLiteral(StringValue.of(Duration.ZERO.toString())) + ) + .field(b -> + b + .name(FIELD_STOP_LOCATION_IDS) + .description(DOC_STOP_LOCATION_IDS) + .type(requiredListOfNonNullStrings()) + ) + /* + TODO: Add support for coordinates + */ + .build(); + + static final GraphQLInputObjectType PASS_THROUGH_VIA_LOCATION_INPUT = GraphQLInputObjectType + .newInputObject() + .name(INPUT_PASS_THROUGH_VIA_LOCATION) + .description(DOC_PASS_THROUGH_VIA_LOCATION) + .field(b -> b.name(FIELD_LABEL).description(DOC_LABEL).type(GraphQLString)) + .field(b -> + // This is NOT nonNull, because we might add other parameters later, like 'list of line-ids' + b + .name(FIELD_STOP_LOCATION_IDS) + .description(DOC_STOP_LOCATION_IDS) + .type(requiredListOfNonNullStrings()) + ) + .build(); + + public static final GraphQLInputObjectType VIA_LOCATION_INPUT = GraphQLInputObjectType + .newInputObject() + .name(INPUT_VIA_LOCATION) + .description(DOC_VIA_LOCATION) + .withDirective(OneOfDirective) + .field(b -> b.name(FIELD_VISIT).description(DOC_FIELD_VISIT).type(VISIT_VIA_LOCATION_INPUT)) + .field(b -> + b + .name(FIELD_PASS_THROUGH) + .description(DOC_FIELD_PASS_THROUGH) + .type(PASS_THROUGH_VIA_LOCATION_INPUT) + ) + .build(); + + private static GraphQLInputType requiredListOfNonNullStrings() { + return new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))); + } +} diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaLocationInputType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/legacyvia/ViaLocationInputType.java similarity index 82% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaLocationInputType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/legacyvia/ViaLocationInputType.java index 6ce02240817..1f26d12e7f7 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaLocationInputType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/legacyvia/ViaLocationInputType.java @@ -1,15 +1,15 @@ -package org.opentripplanner.apis.transmodel.model.plan; +package org.opentripplanner.apis.transmodel.model.plan.legacyvia; import graphql.Scalars; import graphql.schema.GraphQLInputObjectField; import graphql.schema.GraphQLInputObjectType; import org.opentripplanner.apis.transmodel.model.framework.CoordinateInputType; -import org.opentripplanner.apis.transmodel.support.GqlUtil; -import org.opentripplanner.routing.api.request.ViaLocation; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars; +import org.opentripplanner.routing.api.request.ViaLocationDeprecated; public class ViaLocationInputType { - public static GraphQLInputObjectType create(GqlUtil gqlUtil) { + public static GraphQLInputObjectType create() { return GraphQLInputObjectType .newInputObject() .name("ViaLocationInput") @@ -57,21 +57,21 @@ public static GraphQLInputObjectType create(GqlUtil gqlUtil) { GraphQLInputObjectField .newInputObjectField() .name("minSlack") - .defaultValue(ViaLocation.DEFAULT_MIN_SLACK) + .defaultValue(ViaLocationDeprecated.DEFAULT_MIN_SLACK) .description( "The minimum time the user wants to stay in the via location before continuing his journey" ) - .type(gqlUtil.durationScalar) + .type(TransmodelScalars.DURATION_SCALAR) ) .field( GraphQLInputObjectField .newInputObjectField() .name("maxSlack") - .defaultValue(ViaLocation.DEFAULT_MAX_SLACK) + .defaultValue(ViaLocationDeprecated.DEFAULT_MAX_SLACK) .description( "The maximum time the user wants to stay in the via location before continuing his journey" ) - .type(gqlUtil.durationScalar) + .type(TransmodelScalars.DURATION_SCALAR) ) .build(); } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaSegmentInputType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/legacyvia/ViaSegmentInputType.java similarity index 95% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaSegmentInputType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/legacyvia/ViaSegmentInputType.java index 0d591a1357a..a2ada7487c3 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaSegmentInputType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/legacyvia/ViaSegmentInputType.java @@ -1,10 +1,11 @@ -package org.opentripplanner.apis.transmodel.model.plan; +package org.opentripplanner.apis.transmodel.model.plan.legacyvia; import graphql.schema.GraphQLInputObjectField; import graphql.schema.GraphQLInputObjectType; import graphql.schema.GraphQLList; import graphql.schema.GraphQLNonNull; import org.opentripplanner.apis.transmodel.model.EnumTypes; +import org.opentripplanner.apis.transmodel.model.plan.FilterInputType; public class ViaSegmentInputType { diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaTripQuery.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/legacyvia/ViaTripQuery.java similarity index 93% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaTripQuery.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/legacyvia/ViaTripQuery.java index 8641dbc60c2..745470c2220 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaTripQuery.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/legacyvia/ViaTripQuery.java @@ -1,4 +1,4 @@ -package org.opentripplanner.apis.transmodel.model.plan; +package org.opentripplanner.apis.transmodel.model.plan.legacyvia; import graphql.Scalars; import graphql.schema.GraphQLArgument; @@ -7,11 +7,13 @@ import graphql.schema.GraphQLList; import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLScalarType; import org.opentripplanner.apis.transmodel.TransmodelGraphQLPlanner; import org.opentripplanner.apis.transmodel.model.DefaultRouteRequestType; import org.opentripplanner.apis.transmodel.model.EnumTypes; import org.opentripplanner.apis.transmodel.model.framework.LocationInputType; -import org.opentripplanner.apis.transmodel.support.GqlUtil; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelDirectives; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars; public class ViaTripQuery { @@ -20,7 +22,7 @@ public static GraphQLFieldDefinition create( GraphQLOutputType viaTripType, GraphQLInputObjectType viaLocationInputType, GraphQLInputObjectType viaSegmentInputType, - GqlUtil gqlUtil + GraphQLScalarType dateTimeScalar ) { return GraphQLFieldDefinition .newFieldDefinition() @@ -28,8 +30,9 @@ public static GraphQLFieldDefinition create( .description( "Via trip search. Find trip patterns traveling via one or more intermediate (via) locations." ) + .deprecate("Use the regular trip query with via stop instead.") .type(new GraphQLNonNull(viaTripType)) - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .argument( GraphQLArgument .newArgument() @@ -39,7 +42,7 @@ public static GraphQLFieldDefinition create( "(if arriveBy=false/not set) or the latest acceptable time of arriving " + "(arriveBy=true). Defaults to now" ) - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .build() ) .argument( @@ -72,7 +75,7 @@ public static GraphQLFieldDefinition create( "The search-window used is returned to the response metadata as `searchWindowUsed` for " + "debugging purposes." ) - .type(new GraphQLNonNull(gqlUtil.durationScalar)) + .type(new GraphQLNonNull(TransmodelScalars.DURATION_SCALAR)) .build() ) .argument( diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaTripType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/legacyvia/ViaTripType.java similarity index 98% rename from src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaTripType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/legacyvia/ViaTripType.java index 8b55222f3b8..740664c02f0 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/ViaTripType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/legacyvia/ViaTripType.java @@ -1,4 +1,4 @@ -package org.opentripplanner.apis.transmodel.model.plan; +package org.opentripplanner.apis.transmodel.model.plan.legacyvia; import graphql.Scalars; import graphql.schema.DataFetchingEnvironment; diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DateTimeScalarFactory.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DateTimeScalarFactory.java similarity index 90% rename from src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DateTimeScalarFactory.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DateTimeScalarFactory.java index 9738a277a41..19681987199 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DateTimeScalarFactory.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DateTimeScalarFactory.java @@ -12,8 +12,7 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.time.temporal.TemporalAccessor; -import javax.annotation.Nonnull; -import org.opentripplanner.framework.time.OffsetDateTimeParser; +import org.opentripplanner.utils.time.OffsetDateTimeParser; public final class DateTimeScalarFactory { @@ -41,7 +40,7 @@ public static GraphQLScalarType createMillisecondsSinceEpochAsDateTimeStringScal .coercing( new Coercing<>() { @Override - public String serialize(@Nonnull Object input) { + public String serialize(Object input) { if (input instanceof Long inputAsLong) { return Instant.ofEpochMilli(inputAsLong).atZone(timeZone).format(FORMATTER); } @@ -49,7 +48,7 @@ public String serialize(@Nonnull Object input) { } @Override - public Long parseValue(@Nonnull Object input) { + public Long parseValue(Object input) { Instant instant = null; if (input instanceof CharSequence inputAsCharSequence) { try { @@ -80,7 +79,7 @@ public Long parseValue(@Nonnull Object input) { } @Override - public Long parseLiteral(@Nonnull Object input) { + public Long parseLiteral(Object input) { if (input instanceof StringValue inputAsStringValue) { return parseValue(inputAsStringValue.getValue()); } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DoubleFunction.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DoubleFunction.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DoubleFunction.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DoubleFunction.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DoubleFunctionFactory.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DoubleFunctionFactory.java similarity index 84% rename from src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DoubleFunctionFactory.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DoubleFunctionFactory.java index fd45b001642..5259c0dd9db 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DoubleFunctionFactory.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/DoubleFunctionFactory.java @@ -10,7 +10,6 @@ import graphql.schema.GraphQLScalarType; import java.util.Locale; import java.util.NoSuchElementException; -import javax.annotation.Nonnull; import org.opentripplanner.routing.api.request.framework.LinearFunctionSerialization; public class DoubleFunctionFactory { @@ -40,9 +39,9 @@ public static GraphQLScalarType createDoubleFunctionScalar() { new Coercing() { @Override public String serialize( - @Nonnull Object dataFetcherResult, - @Nonnull GraphQLContext graphQLContext, - @Nonnull Locale locale + Object dataFetcherResult, + GraphQLContext graphQLContext, + Locale locale ) { var value = (DoubleFunction) dataFetcherResult; return LinearFunctionSerialization.serialize(value.constant(), value.coefficient()); @@ -50,9 +49,9 @@ public String serialize( @Override public DoubleFunction parseValue( - @Nonnull Object input, - @Nonnull GraphQLContext graphQLContext, - @Nonnull Locale locale + Object input, + GraphQLContext graphQLContext, + Locale locale ) throws CoercingParseValueException { try { String text = (String) input; @@ -64,10 +63,10 @@ public DoubleFunction parseValue( @Override public DoubleFunction parseLiteral( - @Nonnull Value input, - @Nonnull CoercedVariables variables, - @Nonnull GraphQLContext graphQLContext, - @Nonnull Locale locale + Value input, + CoercedVariables variables, + GraphQLContext graphQLContext, + Locale locale ) throws CoercingParseLiteralException { if (input instanceof StringValue stringValue) { return parseValue(stringValue.getValue(), graphQLContext, locale); diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/GeoJSONCoordinatesScalar.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/GeoJSONCoordinatesScalar.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/scalars/GeoJSONCoordinatesScalar.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/GeoJSONCoordinatesScalar.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/LocalTimeScalarFactory.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/LocalTimeScalarFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/scalars/LocalTimeScalarFactory.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/LocalTimeScalarFactory.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/TimeScalarFactory.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/TimeScalarFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/scalars/TimeScalarFactory.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/scalars/TimeScalarFactory.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/siri/et/EstimatedCallType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/et/EstimatedCallType.java similarity index 95% rename from src/main/java/org/opentripplanner/apis/transmodel/model/siri/et/EstimatedCallType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/et/EstimatedCallType.java index 3587b3dc0f6..593782af9d8 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/siri/et/EstimatedCallType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/et/EstimatedCallType.java @@ -9,6 +9,7 @@ import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLScalarType; import graphql.schema.GraphQLTypeReference; import java.time.Instant; import java.time.LocalDate; @@ -17,6 +18,8 @@ import java.util.Set; import org.opentripplanner.apis.transmodel.mapping.OccupancyStatusMapper; import org.opentripplanner.apis.transmodel.model.EnumTypes; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelDirectives; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars; import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.model.TripTimeOnDate; import org.opentripplanner.routing.alertpatch.StopCondition; @@ -41,7 +44,7 @@ public static GraphQLObjectType create( GraphQLOutputType ptSituationElementType, GraphQLOutputType serviceJourneyType, GraphQLOutputType datedServiceJourneyType, - GqlUtil gqlUtil + GraphQLScalarType dateTimeScalar ) { return GraphQLObjectType .newObject() @@ -62,7 +65,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("aimedArrivalTime") .description("Scheduled time of arrival at quay. Not affected by read time updated") - .type(new GraphQLNonNull(gqlUtil.dateTimeScalar)) + .type(new GraphQLNonNull(dateTimeScalar)) .dataFetcher(environment -> 1000 * ( @@ -76,7 +79,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("expectedArrivalTime") - .type(new GraphQLNonNull(gqlUtil.dateTimeScalar)) + .type(new GraphQLNonNull(dateTimeScalar)) .description( "Expected time of arrival at quay. Updated with real time information if available. Will be null if an actualArrivalTime exists" ) @@ -92,7 +95,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("actualArrivalTime") - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .description( "Actual time of arrival at quay. Updated from real time information if available." ) @@ -112,7 +115,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("aimedDepartureTime") .description("Scheduled time of departure from quay. Not affected by read time updated") - .type(new GraphQLNonNull(gqlUtil.dateTimeScalar)) + .type(new GraphQLNonNull(dateTimeScalar)) .dataFetcher(environment -> 1000 * ( @@ -126,7 +129,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("expectedDepartureTime") - .type(new GraphQLNonNull(gqlUtil.dateTimeScalar)) + .type(new GraphQLNonNull(dateTimeScalar)) .description( "Expected time of departure from quay. Updated with real time information if available. Will be null if an actualDepartureTime exists" ) @@ -143,7 +146,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("actualDepartureTime") - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .description( "Actual time of departure from quay. Updated with real time information if available." ) @@ -271,7 +274,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("date") - .type(new GraphQLNonNull(gqlUtil.dateScalar)) + .type(new GraphQLNonNull(TransmodelScalars.DATE_SCALAR)) .description("The date the estimated call is valid for.") .dataFetcher(environment -> ((TripTimeOnDate) environment.getSource()).getServiceDay()) .build() @@ -292,7 +295,7 @@ public static GraphQLObjectType create( .dataFetcher(environment -> GqlUtil .getTransitService(environment) - .getTripOnServiceDateForTripAndDay( + .getTripOnServiceDate( new TripIdAndServiceDate( environment.getSource().getTrip().getId(), environment.getSource().getServiceDay() @@ -318,7 +321,7 @@ public static GraphQLObjectType create( TripTimeOnDate tripTimeOnDate = environment.getSource(); return GqlUtil .getTransitService(environment) - .getNoticesByEntity(tripTimeOnDate.getStopTimeKey()); + .findNotices(tripTimeOnDate.getStopTimeKey()); }) .build() ) @@ -326,7 +329,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("situations") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(ptSituationElementType)))) .description("Get all relevant situations for this EstimatedCall.") .dataFetcher(environment -> diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/AffectsType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/AffectsType.java similarity index 96% rename from src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/AffectsType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/AffectsType.java index 4aded08e3e8..e8cbec6ade0 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/AffectsType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/AffectsType.java @@ -8,6 +8,7 @@ import graphql.schema.GraphQLOutputType; import graphql.schema.GraphQLUnionType; import org.opentripplanner.apis.transmodel.model.EnumTypes; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars; import org.opentripplanner.apis.transmodel.model.stop.StopPlaceType; import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.routing.alertpatch.EntitySelector; @@ -23,8 +24,7 @@ public static GraphQLOutputType create( GraphQLOutputType stopPlaceType, GraphQLOutputType lineType, GraphQLOutputType serviceJourneyType, - GraphQLOutputType datedServiceJourneyType, - GqlUtil gqlUtil + GraphQLOutputType datedServiceJourneyType ) { GraphQLObjectType affectedStopPlace = GraphQLObjectType .newObject() @@ -72,7 +72,7 @@ public static GraphQLOutputType create( .type(lineType) .dataFetcher(environment -> { var routeId = environment.getSource().routeId(); - return GqlUtil.getTransitService(environment).getRouteForId(routeId); + return GqlUtil.getTransitService(environment).getRoute(routeId); }) .build() ) @@ -88,7 +88,7 @@ public static GraphQLOutputType create( .type(serviceJourneyType) .dataFetcher(environment -> { var tripId = environment.getSource().tripId(); - return GqlUtil.getTransitService(environment).getTripForId(tripId); + return GqlUtil.getTransitService(environment).getTrip(tripId); }) .build() ) @@ -96,7 +96,7 @@ public static GraphQLOutputType create( GraphQLFieldDefinition .newFieldDefinition() .name("operatingDay") - .type(gqlUtil.dateScalar) + .type(TransmodelScalars.DATE_SCALAR) .dataFetcher(environment -> environment.getSource().serviceDate()) .build() ) @@ -109,7 +109,7 @@ public static GraphQLOutputType create( EntitySelector.Trip entitySelector = environment.getSource(); return GqlUtil .getTransitService(environment) - .getTripOnServiceDateForTripAndDay( + .getTripOnServiceDate( new TripIdAndServiceDate(entitySelector.tripId(), entitySelector.serviceDate()) ); }) @@ -149,7 +149,7 @@ public static GraphQLOutputType create( .type(lineType) .dataFetcher(environment -> { var routeId = environment.getSource().routeId(); - return GqlUtil.getTransitService(environment).getRouteForId(routeId); + return GqlUtil.getTransitService(environment).getRoute(routeId); }) .build() ) @@ -196,7 +196,7 @@ public static GraphQLOutputType create( .type(serviceJourneyType) .dataFetcher(environment -> { var tripId = environment.getSource().tripId(); - return GqlUtil.getTransitService(environment).getTripForId(tripId); + return GqlUtil.getTransitService(environment).getTrip(tripId); }) .build() ) @@ -204,7 +204,7 @@ public static GraphQLOutputType create( GraphQLFieldDefinition .newFieldDefinition() .name("operatingDay") - .type(gqlUtil.dateScalar) + .type(TransmodelScalars.DATE_SCALAR) .dataFetcher(environment -> environment.getSource().serviceDate() ) @@ -219,7 +219,7 @@ public static GraphQLOutputType create( EntitySelector.StopAndTrip entitySelector = environment.getSource(); return GqlUtil .getTransitService(environment) - .getTripOnServiceDateForTripAndDay( + .getTripOnServiceDate( new TripIdAndServiceDate(entitySelector.tripId(), entitySelector.serviceDate()) ); }) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/PtSituationElementType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/PtSituationElementType.java similarity index 96% rename from src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/PtSituationElementType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/PtSituationElementType.java index 0dc0e74d3b3..4d8e4ed6390 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/PtSituationElementType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/PtSituationElementType.java @@ -10,6 +10,7 @@ import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLScalarType; import graphql.schema.GraphQLTypeReference; import java.time.ZonedDateTime; import java.util.AbstractMap; @@ -41,7 +42,7 @@ public static GraphQLObjectType create( GraphQLObjectType validityPeriodType, GraphQLObjectType infoLinkType, GraphQLOutputType affectsType, - GqlUtil gqlUtil, + GraphQLScalarType dateTimeScalar, Relay relay ) { return GraphQLObjectType @@ -68,7 +69,7 @@ public static GraphQLObjectType create( .dataFetcher(environment -> GqlUtil .getTransitService(environment) - .getAgencyForId( + .getAgency( ((TransitAlert) environment.getSource()).entities() .stream() .filter(EntitySelector.Agency.class::isInstance) @@ -93,7 +94,7 @@ public static GraphQLObjectType create( .filter(EntitySelector.Route.class::isInstance) .map(EntitySelector.Route.class::cast) .map(EntitySelector.Route::routeId) - .map(transitService::getRouteForId) + .map(transitService::getRoute) .collect(Collectors.toList()); }) .build() @@ -111,7 +112,7 @@ public static GraphQLObjectType create( .filter(EntitySelector.Trip.class::isInstance) .map(EntitySelector.Trip.class::cast) .map(EntitySelector.Trip::tripId) - .map(transitService::getTripForId) + .map(transitService::getTrip) .collect(Collectors.toList()); }) .build() @@ -148,13 +149,10 @@ public static GraphQLObjectType create( .filter(EntitySelector.Stop.class::isInstance) .map(EntitySelector.Stop.class::cast) .map(EntitySelector.Stop::stopId) - .map(transitService::getStationById) + .map(transitService::getStation) .filter(Objects::nonNull) .map(station -> - new MonoOrMultiModalStation( - station, - transitService.getMultiModalStationForStation(station) - ) + new MonoOrMultiModalStation(station, transitService.findMultiModalStation(station)) ) .toList(); }) @@ -240,7 +238,7 @@ public static GraphQLObjectType create( if (!siriUrls.isEmpty()) { return siriUrls; } - return null; + return emptyList(); }) .build() ) @@ -304,7 +302,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("creationTime") - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .description("Timestamp for when the situation was created.") .dataFetcher(environment -> { final ZonedDateTime creationTime = environment.getSource().creationTime(); @@ -316,7 +314,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("versionedAtTime") - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .description("Timestamp when the situation element was updated.") .dataFetcher(environment -> { final ZonedDateTime updatedTime = environment.getSource().updatedTime(); @@ -360,7 +358,7 @@ public static GraphQLObjectType create( } return GqlUtil .getTransitService(environment) - .getAgencies() + .listAgencies() .stream() .filter(agency -> agency.getId().getFeedId().equals(feedId)) .filter(agency -> agency.getId().getId().startsWith(codespace)) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/ValidityPeriod.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/ValidityPeriod.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/ValidityPeriod.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/ValidityPeriod.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/BikeParkType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/BikeParkType.java similarity index 97% rename from src/main/java/org/opentripplanner/apis/transmodel/model/stop/BikeParkType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/BikeParkType.java index 470111513bf..8a9c965f4a2 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/BikeParkType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/BikeParkType.java @@ -6,7 +6,7 @@ import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; import org.opentripplanner.apis.transmodel.mapping.TransitIdMapper; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; public class BikeParkType { diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/BikeRentalStationType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/BikeRentalStationType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/stop/BikeRentalStationType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/BikeRentalStationType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/MonoOrMultiModalStation.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/MonoOrMultiModalStation.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/stop/MonoOrMultiModalStation.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/MonoOrMultiModalStation.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceAtDistanceType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceAtDistanceType.java similarity index 98% rename from src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceAtDistanceType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceAtDistanceType.java index 809164e9cd2..882c1491bb7 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceAtDistanceType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceAtDistanceType.java @@ -119,7 +119,7 @@ private static Stream getStopPlaces( List res = new ArrayList<>(); - MultiModalStation multiModalStation = transitService.getMultiModalStationForStation(stopPlace); + MultiModalStation multiModalStation = transitService.findMultiModalStation(stopPlace); if ( "child".equals(multiModalMode) || "all".equals(multiModalMode) || multiModalStation == null diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceInterfaceType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceInterfaceType.java similarity index 97% rename from src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceInterfaceType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceInterfaceType.java index 0b6238c119d..f05113f9f74 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceInterfaceType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceInterfaceType.java @@ -5,7 +5,7 @@ import graphql.schema.GraphQLInterfaceType; import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLSchema; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle; import org.opentripplanner.transit.model.site.RegularStop; diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/PlaceType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayAtDistanceType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayAtDistanceType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayAtDistanceType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayAtDistanceType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java similarity index 96% rename from src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java index e146b537c1c..bea8f5de6bf 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java @@ -10,6 +10,7 @@ import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLScalarType; import graphql.schema.GraphQLTypeReference; import java.time.Duration; import java.time.Instant; @@ -19,6 +20,7 @@ import java.util.Optional; import org.locationtech.jts.geom.Geometry; import org.opentripplanner.apis.transmodel.model.EnumTypes; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelDirectives; import org.opentripplanner.apis.transmodel.model.plan.JourneyWhiteListed; import org.opentripplanner.apis.transmodel.model.scalars.GeoJSONCoordinatesScalar; import org.opentripplanner.apis.transmodel.support.GqlUtil; @@ -44,7 +46,7 @@ public static GraphQLObjectType create( GraphQLOutputType estimatedCallType, GraphQLOutputType ptSituationElementType, GraphQLOutputType tariffZoneType, - GqlUtil gqlUtil + GraphQLScalarType dateTimeScalar ) { return GraphQLObjectType .newObject() @@ -122,7 +124,7 @@ public static GraphQLObjectType create( if (station != null) { return new MonoOrMultiModalStation( station, - GqlUtil.getTransitService(env).getMultiModalStationForStation(station) + GqlUtil.getTransitService(env).findMultiModalStation(station) ); } else { return null; @@ -169,13 +171,13 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("lines") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .description("List of lines servicing this quay") .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(lineType)))) .dataFetcher(env -> GqlUtil .getTransitService(env) - .getPatternsForStop(env.getSource(), true) + .findPatterns(env.getSource(), true) .stream() .map(TripPattern::getRoute) .distinct() @@ -187,26 +189,24 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("journeyPatterns") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .description("List of journey patterns servicing this quay") .type(new GraphQLNonNull(new GraphQLList(journeyPatternType))) - .dataFetcher(env -> - GqlUtil.getTransitService(env).getPatternsForStop(env.getSource(), true) - ) + .dataFetcher(env -> GqlUtil.getTransitService(env).findPatterns(env.getSource(), true)) .build() ) .field( GraphQLFieldDefinition .newFieldDefinition() .name("estimatedCalls") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .description("List of visits to this quay as part of vehicle journeys.") .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(estimatedCallType)))) .argument( GraphQLArgument .newArgument() .name("startTime") - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .description( "DateTime for when to fetch estimated calls from. Default value is current time" ) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/RentalVehicleType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/RentalVehicleType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/stop/RentalVehicleType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/RentalVehicleType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopPlaceType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopPlaceType.java similarity index 96% rename from src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopPlaceType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopPlaceType.java index 53621ee9b5a..fa755e8c6f7 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopPlaceType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopPlaceType.java @@ -12,6 +12,7 @@ import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLScalarType; import graphql.schema.GraphQLTypeReference; import java.time.Duration; import java.time.Instant; @@ -29,6 +30,7 @@ import org.opentripplanner.apis.transmodel.mapping.TransitIdMapper; import org.opentripplanner.apis.transmodel.model.EnumTypes; import org.opentripplanner.apis.transmodel.model.TransmodelTransportSubmode; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelDirectives; import org.opentripplanner.apis.transmodel.model.plan.JourneyWhiteListed; import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.framework.graphql.GraphQLUtils; @@ -56,7 +58,7 @@ public static GraphQLObjectType create( GraphQLOutputType tariffZoneType, GraphQLOutputType estimatedCallType, GraphQLOutputType ptSituationElementType, - GqlUtil gqlUtil + GraphQLScalarType dateTimeScalar ) { return GraphQLObjectType .newObject() @@ -181,7 +183,7 @@ public static GraphQLObjectType create( .dataFetcher(environment -> ((MonoOrMultiModalStation) environment.getSource()).getChildStops() .stream() - .map(StopLocation::getGtfsVehicleType) + .map(StopLocation::getVehicleType) .filter(Objects::nonNull) .collect(Collectors.toSet()) ) @@ -227,7 +229,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("quays") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .description("Returns all quays that are children of this stop place") .type(new GraphQLList(quayType)) .argument( @@ -248,7 +250,7 @@ public static GraphQLObjectType create( .filter(stop -> { return !GqlUtil .getTransitService(environment) - .getPatternsForStop(stop, true) + .findPatterns(stop, true) .isEmpty(); }) .collect(Collectors.toList()); @@ -285,14 +287,14 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("estimatedCalls") - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .description("List of visits to this stop place as part of vehicle journeys.") .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(estimatedCallType)))) .argument( GraphQLArgument .newArgument() .name("startTime") - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .description( "DateTime for when to fetch estimated calls from. Default value is current time" ) @@ -447,7 +449,7 @@ public static Stream getTripTimesForStop( ) { TransitService transitService = GqlUtil.getTransitService(environment); - List stopTimesInPatterns = transitService.stopTimesForStop( + List stopTimesInPatterns = transitService.findStopTimesInPattern( stop, startTimeSeconds, timeRange, @@ -512,13 +514,10 @@ public static MonoOrMultiModalStation fetchStopPlaceById( TransitService transitService = GqlUtil.getTransitService(environment); - Station station = transitService.getStationById(id); + Station station = transitService.getStation(id); if (station != null) { - return new MonoOrMultiModalStation( - station, - transitService.getMultiModalStationForStation(station) - ); + return new MonoOrMultiModalStation(station, transitService.findMultiModalStation(station)); } MultiModalStation multiModalStation = transitService.getMultiModalStation(id); @@ -566,7 +565,7 @@ public static Collection fetchStopPlaces( if ("child".equals(multiModalMode)) { return stations .map(s -> { - MultiModalStation parent = transitService.getMultiModalStationForStation(s); + MultiModalStation parent = transitService.findMultiModalStation(s); return new MonoOrMultiModalStation(s, parent); }) .collect(Collectors.toList()); @@ -575,7 +574,7 @@ public static Collection fetchStopPlaces( else if ("all".equals(multiModalMode)) { Set result = new HashSet<>(); stations.forEach(it -> { - MultiModalStation p = transitService.getMultiModalStationForStation(it); + MultiModalStation p = transitService.findMultiModalStation(it); result.add(new MonoOrMultiModalStation(it, p)); if (p != null) { result.add(new MonoOrMultiModalStation(p)); @@ -588,7 +587,7 @@ else if ("all".equals(multiModalMode)) { else if ("parent".equals(multiModalMode)) { Set result = new HashSet<>(); stations.forEach(it -> { - MultiModalStation p = transitService.getMultiModalStationForStation(it); + MultiModalStation p = transitService.findMultiModalStation(it); if (p != null) { result.add(new MonoOrMultiModalStation(p)); } else { @@ -606,7 +605,7 @@ public static boolean isStopPlaceInUse( TransitService transitService ) { for (var quay : station.getChildStops()) { - if (!transitService.getPatternsForStop(quay, true).isEmpty()) { + if (!transitService.findPatterns(quay, true).isEmpty()) { return true; } } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/TariffZoneType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/TariffZoneType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/stop/TariffZoneType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/TariffZoneType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/BookingArrangementType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/BookingArrangementType.java similarity index 97% rename from src/main/java/org/opentripplanner/apis/transmodel/model/timetable/BookingArrangementType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/BookingArrangementType.java index de0f86b1166..727dc37d99b 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/BookingArrangementType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/BookingArrangementType.java @@ -7,14 +7,14 @@ import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; import org.opentripplanner.apis.transmodel.model.EnumTypes; -import org.opentripplanner.apis.transmodel.support.GqlUtil; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars; import org.opentripplanner.transit.model.organization.ContactInfo; import org.opentripplanner.transit.model.timetable.booking.BookingInfo; import org.opentripplanner.transit.model.timetable.booking.BookingTime; public class BookingArrangementType { - public static GraphQLObjectType create(GqlUtil gqlUtil) { + public static GraphQLObjectType create() { GraphQLOutputType contactType = GraphQLObjectType .newObject() .name("Contact") @@ -82,7 +82,7 @@ public static GraphQLObjectType create(GqlUtil gqlUtil) { .newFieldDefinition() .name("latestBookingTime") .description("Latest time the service can be booked. ISO 8601 timestamp") - .type(gqlUtil.localTimeScalar) + .type(TransmodelScalars.LOCAL_TIME_SCALAR) .dataFetcher(environment -> { final BookingTime latestBookingTime = (bookingInfo(environment)).getLatestBookingTime(); return latestBookingTime == null ? null : latestBookingTime.getTime(); diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyQuery.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyQuery.java similarity index 53% rename from src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyQuery.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyQuery.java index c3c8ba420e4..2d381140b73 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyQuery.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyQuery.java @@ -10,13 +10,15 @@ import graphql.schema.GraphQLOutputType; import java.time.LocalDate; import java.util.List; -import java.util.stream.Stream; import org.opentripplanner.apis.transmodel.mapping.TransitIdMapper; import org.opentripplanner.apis.transmodel.model.EnumTypes; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars; import org.opentripplanner.apis.transmodel.support.GqlUtil; +import org.opentripplanner.transit.api.model.FilterValues; +import org.opentripplanner.transit.api.request.TripOnServiceDateRequest; +import org.opentripplanner.transit.api.request.TripOnServiceDateRequestBuilder; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.timetable.TripAlteration; -import org.opentripplanner.transit.model.timetable.TripOnServiceDate; /** * A GraphQL query for retrieving data on DatedServiceJourneys @@ -33,15 +35,12 @@ public static GraphQLFieldDefinition createGetById(GraphQLOutputType datedServic .dataFetcher(environment -> { FeedScopedId id = TransitIdMapper.mapIDToDomain(environment.getArgument("id")); - return GqlUtil.getTransitService(environment).getTripOnServiceDateById(id); + return GqlUtil.getTransitService(environment).getTripOnServiceDate(id); }) .build(); } - public static GraphQLFieldDefinition createQuery( - GraphQLOutputType datedServiceJourneyType, - GqlUtil gqlUtil - ) { + public static GraphQLFieldDefinition createQuery(GraphQLOutputType datedServiceJourneyType) { return GraphQLFieldDefinition .newFieldDefinition() .name("datedServiceJourneys") @@ -69,7 +68,9 @@ public static GraphQLFieldDefinition createQuery( GraphQLArgument .newArgument() .name("operatingDays") - .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(gqlUtil.dateScalar)))) + .type( + new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(TransmodelScalars.DATE_SCALAR))) + ) ) .argument( GraphQLArgument @@ -93,72 +94,54 @@ public static GraphQLFieldDefinition createQuery( .type(new GraphQLList(new GraphQLNonNull(Scalars.GraphQLString))) ) .dataFetcher(environment -> { - Stream stream = GqlUtil + // The null safety checks are not needed here - they are taken care of by the request + // object, but let's use the mapping method and leave this improvement until all APIs + // are pushing this check into the domain request. + var authorities = FilterValues.ofEmptyIsEverything( + "authorities", + mapIDsToDomainNullSafe(environment.getArgument("authorities")) + ); + var lines = FilterValues.ofEmptyIsEverything( + "lines", + mapIDsToDomainNullSafe(environment.getArgument("lines")) + ); + var serviceJourneys = FilterValues.ofEmptyIsEverything( + "serviceJourneys", + mapIDsToDomainNullSafe(environment.getArgument("serviceJourneys")) + ); + var replacementFor = FilterValues.ofEmptyIsEverything( + "replacementFor", + mapIDsToDomainNullSafe(environment.getArgument("replacementFor")) + ); + var privateCodes = FilterValues.ofEmptyIsEverything( + "privateCodes", + environment.>getArgument("privateCodes") + ); + var operatingDays = FilterValues.ofRequired( + "operatingDays", + environment.>getArgument("operatingDays") + ); + var alterations = FilterValues.ofEmptyIsEverything( + "alterations", + environment.>getArgument("alterations") + ); + + TripOnServiceDateRequestBuilder tripOnServiceDateRequestBuilder = TripOnServiceDateRequest + .of(operatingDays) + .withAgencies(authorities) + .withRoutes(lines) + .withServiceJourneys(serviceJourneys) + .withReplacementFor(replacementFor); + + tripOnServiceDateRequestBuilder = + tripOnServiceDateRequestBuilder.withNetexInternalPlanningCodes(privateCodes); + + tripOnServiceDateRequestBuilder = + tripOnServiceDateRequestBuilder.withAlterations(alterations); + + return GqlUtil .getTransitService(environment) - .getAllTripOnServiceDates() - .stream(); - - var lines = mapIDsToDomainNullSafe(environment.getArgument("lines")); - var serviceJourneys = mapIDsToDomainNullSafe(environment.getArgument("serviceJourneys")); - var privateCodes = environment.>getArgument("privateCodes"); - var operatingDays = environment.>getArgument("operatingDays"); - var alterations = environment.>getArgument("alterations"); - var authorities = mapIDsToDomainNullSafe(environment.getArgument("authorities")); - var replacementFor = mapIDsToDomainNullSafe(environment.getArgument("replacementFor")); - - if (!lines.isEmpty()) { - stream = - stream.filter(tripOnServiceDate -> - lines.contains(tripOnServiceDate.getTrip().getRoute().getId()) - ); - } - - if (!serviceJourneys.isEmpty()) { - stream = - stream.filter(tripOnServiceDate -> - serviceJourneys.contains(tripOnServiceDate.getTrip().getId()) - ); - } - - if (privateCodes != null && !privateCodes.isEmpty()) { - stream = - stream.filter(tripOnServiceDate -> - privateCodes.contains(tripOnServiceDate.getTrip().getNetexInternalPlanningCode()) - ); - } - - // At least one operationg day is required - var days = operatingDays.stream().toList(); - - stream = - stream.filter(tripOnServiceDate -> days.contains(tripOnServiceDate.getServiceDate())); - - if (alterations != null && !alterations.isEmpty()) { - stream = - stream.filter(tripOnServiceDate -> - alterations.contains(tripOnServiceDate.getTripAlteration()) - ); - } - - if (!authorities.isEmpty()) { - stream = - stream.filter(tripOnServiceDate -> - authorities.contains(tripOnServiceDate.getTrip().getRoute().getAgency().getId()) - ); - } - - if (!replacementFor.isEmpty()) { - stream = - stream.filter(tripOnServiceDate -> - !tripOnServiceDate.getReplacementFor().isEmpty() && - tripOnServiceDate - .getReplacementFor() - .stream() - .anyMatch(replacement -> replacementFor.contains(replacement.getId())) - ); - } - - return stream.toList(); + .findTripsOnServiceDate(tripOnServiceDateRequestBuilder.build()); }) .build(); } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyType.java similarity index 88% rename from src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyType.java index faeccf930c6..7c550dc9b85 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyType.java @@ -14,6 +14,8 @@ import java.util.List; import java.util.Optional; import org.opentripplanner.apis.transmodel.model.EnumTypes; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelDirectives; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars; import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.routing.TripTimeOnDateHelper; import org.opentripplanner.transit.model.network.TripPattern; @@ -33,8 +35,7 @@ public static GraphQLObjectType create( GraphQLOutputType serviceJourneyType, GraphQLOutputType journeyPatternType, GraphQLType estimatedCallType, - GraphQLType quayType, - GqlUtil gqlUtil + GraphQLType quayType ) { return GraphQLObjectType .newObject() @@ -48,7 +49,7 @@ public static GraphQLObjectType create( .description( "The date this service runs. The date used is based on the service date as opposed to calendar date." ) - .type(gqlUtil.dateScalar) + .type(TransmodelScalars.DATE_SCALAR) .dataFetcher(environment -> Optional .of(tripOnServiceDate(environment)) @@ -124,14 +125,16 @@ public static GraphQLObjectType create( if (first != null && last != null) { throw new AssertException("Both first and last can't be defined simultaneously."); - } else if (first != null) { - if (first > stops.size()) { - return stops.subList(0, first); - } - } else if (last != null) { - if (last > stops.size()) { - return stops.subList(stops.size() - last, stops.size()); - } + } + + if ((first != null && first < 0) || (last != null && last < 0)) { + throw new AssertException("first and last must be positive integers."); + } + + if (first != null && first < stops.size()) { + return stops.subList(0, first); + } else if (last != null && last < stops.size()) { + return stops.subList(stops.size() - last, stops.size()); } return stops; }) @@ -142,7 +145,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("estimatedCalls") .type(new GraphQLList(estimatedCallType)) - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .description( "Returns scheduled passingTimes for this dated service journey, " + "updated with real-time-updates (if available). " @@ -163,7 +166,7 @@ public static GraphQLObjectType create( private static TripPattern tripPattern(DataFetchingEnvironment env) { TransitService transitService = GqlUtil.getTransitService(env); TripOnServiceDate tripOnServiceDate = tripOnServiceDate(env); - return transitService.getPatternForTrip( + return transitService.findPattern( tripOnServiceDate.getTrip(), tripOnServiceDate.getServiceDate() ); diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/InterchangeType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/InterchangeType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/model/timetable/InterchangeType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/InterchangeType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/ServiceJourneyType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/ServiceJourneyType.java similarity index 83% rename from src/main/java/org/opentripplanner/apis/transmodel/model/timetable/ServiceJourneyType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/ServiceJourneyType.java index c0c96b1e393..5d4241c7767 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/ServiceJourneyType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/ServiceJourneyType.java @@ -17,6 +17,8 @@ import org.locationtech.jts.geom.LineString; import org.opentripplanner.apis.transmodel.model.EnumTypes; import org.opentripplanner.apis.transmodel.model.TransmodelTransportSubmode; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelDirectives; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars; import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.framework.geometry.EncodedPolyline; import org.opentripplanner.model.TripTimeOnDate; @@ -41,8 +43,7 @@ public static GraphQLObjectType create( GraphQLOutputType ptSituationElementType, GraphQLOutputType journeyPatternType, GraphQLOutputType estimatedCallType, - GraphQLOutputType timetabledPassingTimeType, - GqlUtil gqlUtil + GraphQLOutputType timetabledPassingTimeType ) { return GraphQLObjectType .newObject() @@ -61,8 +62,8 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("activeDates") - .withDirective(gqlUtil.timingData) - .type(new GraphQLNonNull(new GraphQLList(gqlUtil.dateScalar))) + .withDirective(TransmodelDirectives.TIMING_DATA) + .type(new GraphQLNonNull(new GraphQLList(TransmodelScalars.DATE_SCALAR))) .dataFetcher(environment -> GqlUtil .getTransitService(environment) @@ -74,13 +75,6 @@ public static GraphQLObjectType create( ) .build() ) - // .field(GraphQLFieldDefinition.newFieldDefinition() - // .name("serviceAlteration") - // .type(serviceAlterationEnum) - // .description("Whether journey is as planned, a cancellation or an extra journey. Default is as planned") - // .dataFetcher(environment -> (((Trip) trip(environment)).getServiceAlteration())) - // .build()) - .field( GraphQLFieldDefinition .newFieldDefinition() @@ -174,7 +168,7 @@ public static GraphQLObjectType create( "ServiceJourney is not included in the scheduled data, null is returned." ) .type(journeyPatternType) - .dataFetcher(env -> GqlUtil.getTransitService(env).getPatternForTrip(trip(env))) + .dataFetcher(env -> GqlUtil.getTransitService(env).findPattern(trip(env))) .build() ) .field( @@ -207,7 +201,7 @@ public static GraphQLObjectType create( Integer last = environment.getArgument("last"); TransitService transitService = GqlUtil.getTransitService(environment); - TripPattern tripPattern = transitService.getPatternForTrip(trip(environment)); + TripPattern tripPattern = transitService.findPattern(trip(environment)); if (tripPattern == null) { return List.of(); @@ -217,14 +211,16 @@ public static GraphQLObjectType create( if (first != null && last != null) { throw new AssertException("Both first and last can't be defined simultaneously."); - } else if (first != null) { - if (first > stops.size()) { - return stops.subList(0, first); - } - } else if (last != null) { - if (last > stops.size()) { - return stops.subList(stops.size() - last, stops.size()); - } + } + + if ((first != null && first < 0) || (last != null && last < 0)) { + throw new AssertException("first and last must be positive integers."); + } + + if (first != null && first < stops.size()) { + return stops.subList(0, first); + } else if (last != null && last < stops.size()) { + return stops.subList(stops.size() - last, stops.size()); } return stops; }) @@ -235,13 +231,13 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("passingTimes") .type(new GraphQLNonNull(new GraphQLList(timetabledPassingTimeType))) - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .description( "Returns scheduled passing times only - without real-time-updates, for realtime-data use 'estimatedCalls'" ) .dataFetcher(env -> { Trip trip = trip(env); - TripPattern tripPattern = GqlUtil.getTransitService(env).getPatternForTrip(trip); + TripPattern tripPattern = GqlUtil.getTransitService(env).findPattern(trip); if (tripPattern == null) { return List.of(); } @@ -254,7 +250,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("estimatedCalls") .type(new GraphQLList(estimatedCallType)) - .withDirective(gqlUtil.timingData) + .withDirective(TransmodelDirectives.TIMING_DATA) .description( "Returns scheduled passingTimes for this ServiceJourney for a given date, updated with real-time-updates (if available). " + "NB! This takes a date as argument (default=today) and returns estimatedCalls for that date and should only be used if the date is " + @@ -264,7 +260,7 @@ public static GraphQLObjectType create( GraphQLArgument .newArgument() .name("date") - .type(gqlUtil.dateScalar) + .type(TransmodelScalars.DATE_SCALAR) .description("Date to get estimated calls for. Defaults to today.") .build() ) @@ -292,7 +288,7 @@ public static GraphQLObjectType create( .dataFetcher(environment -> { TripPattern tripPattern = GqlUtil .getTransitService(environment) - .getPatternForTrip(trip(environment)); + .findPattern(trip(environment)); if (tripPattern == null) { return null; } @@ -311,7 +307,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("notices") .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(noticeType)))) - .dataFetcher(env -> GqlUtil.getTransitService(env).getNoticesByEntity(trip(env))) + .dataFetcher(env -> GqlUtil.getTransitService(env).findNotices(trip(env))) .build() ) .field( @@ -328,17 +324,6 @@ public static GraphQLObjectType create( ) .build() ) - // .field(GraphQLFieldDefinition.newFieldDefinition() - // .name("keyValues") - // .description("List of keyValue pairs for the service journey.") - // .type(new GraphQLList(keyValueType)) - // .dataFetcher(environment -> ((Trip) trip(environment)).getKeyValues()) - // .build()) - // .field(GraphQLFieldDefinition.newFieldDefinition() - // .name("flexibleServiceType") - // .description("Type of flexible service, or null if service is not flexible.") - // .type(flexibleServiceTypeEnum) - // .build()) .field( GraphQLFieldDefinition .newFieldDefinition() diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/TimetabledPassingTimeType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/TimetabledPassingTimeType.java similarity index 95% rename from src/main/java/org/opentripplanner/apis/transmodel/model/timetable/TimetabledPassingTimeType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/TimetabledPassingTimeType.java index 9370ed74d93..d7b59790f8e 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/TimetabledPassingTimeType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/TimetabledPassingTimeType.java @@ -8,6 +8,7 @@ import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; import graphql.schema.GraphQLTypeReference; +import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars; import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.ext.flex.trip.FlexTrip; import org.opentripplanner.framework.application.OTPFeature; @@ -25,8 +26,7 @@ public static GraphQLObjectType create( GraphQLOutputType noticeType, GraphQLOutputType quayType, GraphQLOutputType destinationDisplayType, - GraphQLOutputType serviceJourneyType, - GqlUtil gqlUtil + GraphQLOutputType serviceJourneyType ) { return GraphQLObjectType .newObject() @@ -44,7 +44,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("arrival") - .type(gqlUtil.timeScalar) + .type(TransmodelScalars.TIME_SCALAR) .description("Scheduled time of arrival at quay") .dataFetcher(environment -> missingValueToNull(((TripTimeOnDate) environment.getSource()).getScheduledArrival()) @@ -55,7 +55,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("departure") - .type(gqlUtil.timeScalar) + .type(TransmodelScalars.TIME_SCALAR) .description("Scheduled time of departure from quay") .dataFetcher(environment -> missingValueToNull(((TripTimeOnDate) environment.getSource()).getScheduledDeparture()) @@ -111,7 +111,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("earliestDepartureTime") - .type(gqlUtil.timeScalar) + .type(TransmodelScalars.TIME_SCALAR) .description( "Earliest possible departure time for a service journey with a service window." ) @@ -131,7 +131,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("latestArrivalTime") - .type(gqlUtil.timeScalar) + .type(TransmodelScalars.TIME_SCALAR) .description( "Latest possible (planned) arrival time for a service journey with a service window." ) @@ -170,7 +170,7 @@ public static GraphQLObjectType create( TripTimeOnDate tripTimeOnDate = environment.getSource(); return GqlUtil .getTransitService(environment) - .getNoticesByEntity(tripTimeOnDate.getStopTimeKey()); + .findNotices(tripTimeOnDate.getStopTimeKey()); }) .build() ) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/TripMetadataType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/TripMetadataType.java similarity index 90% rename from src/main/java/org/opentripplanner/apis/transmodel/model/timetable/TripMetadataType.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/TripMetadataType.java index ccdb3a9b39d..4301b0721c2 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/TripMetadataType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/TripMetadataType.java @@ -4,14 +4,14 @@ import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; -import org.opentripplanner.apis.transmodel.support.GqlUtil; +import graphql.schema.GraphQLScalarType; import org.opentripplanner.routing.api.response.TripSearchMetadata; public class TripMetadataType { private TripMetadataType() {} - public static GraphQLObjectType create(GqlUtil gqlUtil) { + public static GraphQLObjectType create(GraphQLScalarType dateTimeScalar) { return GraphQLObjectType .newObject() .name("TripSearchData") @@ -26,7 +26,7 @@ public static GraphQLObjectType create(GqlUtil gqlUtil) { "override the value if it is too small or too large. When paging OTP adjusts " + "it to the appropriate size, depending on the number of itineraries found in " + "the current search window. The scaling of the search window ensures faster " + - "paging and limits resource usage. The unit is seconds." + "paging and limits resource usage. The unit is minutes." ) .type(new GraphQLNonNull(Scalars.GraphQLInt)) .dataFetcher(e -> ((TripSearchMetadata) e.getSource()).searchWindowUsed.toMinutes()) @@ -43,7 +43,7 @@ public static GraphQLObjectType create(GqlUtil gqlUtil) { "AFTER the current search." ) .deprecate("Use pageCursor instead") - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .dataFetcher(e -> ((TripSearchMetadata) e.getSource()).nextDateTime.toEpochMilli()) .build() ) @@ -58,7 +58,7 @@ public static GraphQLObjectType create(GqlUtil gqlUtil) { "time-window BEFORE the current search." ) .deprecate("Use pageCursor instead") - .type(gqlUtil.dateTimeScalar) + .type(dateTimeScalar) .dataFetcher(e -> ((TripSearchMetadata) e.getSource()).prevDateTime.toEpochMilli()) .build() ) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/support/AbortOnUnprocessableRequestExecutionStrategy.java b/application/src/main/java/org/opentripplanner/apis/transmodel/support/AbortOnUnprocessableRequestExecutionStrategy.java similarity index 97% rename from src/main/java/org/opentripplanner/apis/transmodel/support/AbortOnUnprocessableRequestExecutionStrategy.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/support/AbortOnUnprocessableRequestExecutionStrategy.java index c395d359131..f47b2404bb2 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/support/AbortOnUnprocessableRequestExecutionStrategy.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/support/AbortOnUnprocessableRequestExecutionStrategy.java @@ -8,7 +8,7 @@ import org.opentripplanner.apis.support.graphql.LoggingDataFetcherExceptionHandler; import org.opentripplanner.apis.transmodel.ResponseTooLargeException; import org.opentripplanner.framework.application.OTPRequestTimeoutException; -import org.opentripplanner.framework.logging.ProgressTracker; +import org.opentripplanner.utils.logging.ProgressTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/apis/transmodel/support/DataFetcherDecorator.java b/application/src/main/java/org/opentripplanner/apis/transmodel/support/DataFetcherDecorator.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/support/DataFetcherDecorator.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/support/DataFetcherDecorator.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java b/application/src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/support/GqlUtil.java b/application/src/main/java/org/opentripplanner/apis/transmodel/support/GqlUtil.java similarity index 62% rename from src/main/java/org/opentripplanner/apis/transmodel/support/GqlUtil.java rename to application/src/main/java/org/opentripplanner/apis/transmodel/support/GqlUtil.java index 16083085500..8e34470ed6a 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/support/GqlUtil.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/support/GqlUtil.java @@ -1,29 +1,18 @@ package org.opentripplanner.apis.transmodel.support; import graphql.Scalars; -import graphql.introspection.Introspection.DirectiveLocation; import graphql.schema.DataFetchingEnvironment; -import graphql.schema.GraphQLDirective; import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLInputObjectField; import graphql.schema.GraphQLList; import graphql.schema.GraphQLNonNull; -import graphql.schema.GraphQLObjectType; -import graphql.schema.GraphQLScalarType; -import java.time.ZoneId; import java.util.List; import java.util.Locale; import org.opentripplanner.apis.transmodel.TransmodelRequestContext; import org.opentripplanner.apis.transmodel.mapping.TransitIdMapper; -import org.opentripplanner.apis.transmodel.model.scalars.DateTimeScalarFactory; -import org.opentripplanner.apis.transmodel.model.scalars.DoubleFunctionFactory; -import org.opentripplanner.apis.transmodel.model.scalars.LocalTimeScalarFactory; -import org.opentripplanner.apis.transmodel.model.scalars.TimeScalarFactory; import org.opentripplanner.framework.graphql.GraphQLUtils; -import org.opentripplanner.framework.graphql.scalar.DateScalarFactory; -import org.opentripplanner.framework.graphql.scalar.DurationScalarFactory; import org.opentripplanner.routing.graphfinder.GraphFinder; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; import org.opentripplanner.service.vehiclerental.VehicleRentalService; import org.opentripplanner.transit.service.TransitService; @@ -33,31 +22,8 @@ */ public class GqlUtil { - public final GraphQLScalarType dateTimeScalar; - public final GraphQLScalarType dateScalar; - public final GraphQLScalarType doubleFunctionScalar; - public final GraphQLScalarType localTimeScalar; - public final GraphQLObjectType timeScalar; - public final GraphQLScalarType durationScalar; - public final GraphQLDirective timingData; - - /** private to prevent util class from instantiation */ - public GqlUtil(ZoneId timeZone) { - this.dateTimeScalar = - DateTimeScalarFactory.createMillisecondsSinceEpochAsDateTimeStringScalar(timeZone); - this.dateScalar = DateScalarFactory.createTransmodelDateScalar(); - this.doubleFunctionScalar = DoubleFunctionFactory.createDoubleFunctionScalar(); - this.localTimeScalar = LocalTimeScalarFactory.createLocalTimeScalar(); - this.timeScalar = TimeScalarFactory.createSecondsSinceMidnightAsTimeObject(); - this.durationScalar = DurationScalarFactory.createDurationScalar(); - this.timingData = - GraphQLDirective - .newDirective() - .name("timingData") - .description("Add timing data to prometheus, if Actuator API is enabled") - .validLocation(DirectiveLocation.FIELD_DEFINITION) - .build(); - } + /** private constructor, prevent instantiation of utility class */ + private GqlUtil() {} public static TransitService getTransitService(DataFetchingEnvironment environment) { return ((TransmodelRequestContext) environment.getContext()).getTransitService(); @@ -72,8 +38,7 @@ public static VehicleParkingService getVehicleParkingService( DataFetchingEnvironment environment ) { return ((TransmodelRequestContext) environment.getContext()).getServerContext() - .graph() - .getVehicleParkingService(); + .vehicleParkingService(); } public static GraphFinder getGraphFinder(DataFetchingEnvironment environment) { @@ -122,10 +87,6 @@ public static int getPositiveNonNullIntegerArgument( return argumentValue; } - public static List listOfNullSafe(T element) { - return element == null ? List.of() : List.of(element); - } - /** * Helper method to support the deprecated 'lang' argument. */ diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/support/OneOfInputValidator.java b/application/src/main/java/org/opentripplanner/apis/transmodel/support/OneOfInputValidator.java new file mode 100644 index 00000000000..0ea554d6b23 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/support/OneOfInputValidator.java @@ -0,0 +1,68 @@ +package org.opentripplanner.apis.transmodel.support; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.Objects; + +/** + * Validate @oneOf directive, this validation is NOT done by the Java GraphQL library at the + * moment(v22.1). Remove this when enforced by the library. The {@code @oneOf} is an experimental + * feature in this version of the library. This applies to the code-first approach, not the + * schema-first approach. + *

+ * See {@link graphql.Directives#OneOfDirective} + */ +public class OneOfInputValidator { + + /** + * Validate that the {@code parent} {@code map} only has one entry. + * + * @param map The input to validate. + * @param inputTypeName The name of the type annotated with @oneOf. The name is used in + * the error message only, in case the validation fails. + * @param definedFields The name of the fields the @oneOf directive apply to. + * + * @return the field with a value set. + */ + public static String validateOneOf( + Map map, + String inputTypeName, + String... definedFields + ) { + var fieldsInInput = Arrays + .stream(definedFields) + .map(k -> map.containsKey(k) ? k : null) + .filter(Objects::nonNull) + .toList(); + + if (fieldsInInput.isEmpty()) { + throw new IllegalArgumentException( + "No entries in '%s @oneOf'. One of '%s' must be set.".formatted( + inputTypeName, + String.join("', '", definedFields) + ) + ); + } + if (fieldsInInput.size() > 1) { + throw new IllegalArgumentException( + "Only one entry in '%s @oneOf' is allowed. Set: '%s'".formatted( + inputTypeName, + String.join("', '", fieldsInInput) + ) + ); + } + + // This is not done in the "standard" validator, so if this is replaced by another validator + // we should consider adding this validation. + var field = fieldsInInput.getFirst(); + if (map.get(field) instanceof Collection c) { + if (c.isEmpty()) { + throw new IllegalArgumentException( + "'%s' can not be empty in '%s @oneOf'.".formatted(field, inputTypeName) + ); + } + } + return field; + } +} diff --git a/application/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/application/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java new file mode 100644 index 00000000000..7070f8b486e --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -0,0 +1,409 @@ +package org.opentripplanner.apis.vectortiles; + +import static org.opentripplanner.inspector.vector.edge.EdgePropertyMapper.streetPermissionAsString; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; +import org.opentripplanner.apis.vectortiles.model.StyleBuilder; +import org.opentripplanner.apis.vectortiles.model.StyleSpec; +import org.opentripplanner.apis.vectortiles.model.TileSource; +import org.opentripplanner.apis.vectortiles.model.TileSource.RasterSource; +import org.opentripplanner.apis.vectortiles.model.VectorSourceLayer; +import org.opentripplanner.apis.vectortiles.model.ZoomDependentNumber; +import org.opentripplanner.apis.vectortiles.model.ZoomDependentNumber.ZoomStop; +import org.opentripplanner.service.vehiclerental.street.StreetVehicleRentalLink; +import org.opentripplanner.standalone.config.debuguiconfig.BackgroundTileLayer; +import org.opentripplanner.street.model.StreetTraversalPermission; +import org.opentripplanner.street.model.edge.AreaEdge; +import org.opentripplanner.street.model.edge.BoardingLocationToStopLink; +import org.opentripplanner.street.model.edge.Edge; +import org.opentripplanner.street.model.edge.ElevatorHopEdge; +import org.opentripplanner.street.model.edge.EscalatorEdge; +import org.opentripplanner.street.model.edge.PathwayEdge; +import org.opentripplanner.street.model.edge.StreetEdge; +import org.opentripplanner.street.model.edge.StreetStationCentroidLink; +import org.opentripplanner.street.model.edge.StreetTransitEntranceLink; +import org.opentripplanner.street.model.edge.StreetTransitStopLink; +import org.opentripplanner.street.model.edge.StreetVehicleParkingLink; +import org.opentripplanner.street.model.edge.TemporaryFreeEdge; +import org.opentripplanner.street.model.edge.TemporaryPartialStreetEdge; +import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex; +import org.opentripplanner.utils.collection.ListUtils; + +/** + * A Mapbox/Mapblibre style specification for rendering debug information about transit and street + * data. + */ +public class DebugStyleSpec { + + private static final TileSource OSM_BACKGROUND = new RasterSource( + "OSM Carto", + List.of("https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"), + 19, + 256, + "© OpenStreetMap Contributors" + ); + private static final TileSource POSITRON_BACKGROUND = new RasterSource( + "Positron", + List.of("https://cartodb-basemaps-a.global.ssl.fastly.net/light_all/{z}/{x}/{y}{ratio}.png"), + 19, + 256, + "© OpenStreetMap, © CARTO" + ); + + private static final List BACKGROUND_LAYERS = List.of( + OSM_BACKGROUND, + POSITRON_BACKGROUND + ); + private static final String MAGENTA = "#f21d52"; + private static final String BRIGHT_GREEN = "#22DD9E"; + private static final String DARK_GREEN = "#136b04"; + private static final String RED = "#fc0f2a"; + private static final String PURPLE = "#BC55F2"; + private static final String BLACK = "#140d0e"; + + private static final int MAX_ZOOM = 23; + private static final int LINE_DETAIL_ZOOM = 13; + private static final ZoomDependentNumber LINE_OFFSET = new ZoomDependentNumber( + List.of(new ZoomStop(LINE_DETAIL_ZOOM, 0.4f), new ZoomStop(MAX_ZOOM, 7)) + ); + private static final ZoomDependentNumber LINE_WIDTH = new ZoomDependentNumber( + List.of(new ZoomStop(LINE_DETAIL_ZOOM, 0.2f), new ZoomStop(MAX_ZOOM, 8)) + ); + private static final ZoomDependentNumber LINE_HALF_WIDTH = new ZoomDependentNumber( + List.of(new ZoomStop(LINE_DETAIL_ZOOM, 0.1f), new ZoomStop(MAX_ZOOM, 6)) + ); + private static final ZoomDependentNumber CIRCLE_STROKE = new ZoomDependentNumber( + List.of(new ZoomStop(15, 0.2f), new ZoomStop(MAX_ZOOM, 3)) + ); + private static final Class[] EDGES_TO_DISPLAY = new Class[] { + StreetEdge.class, + AreaEdge.class, + EscalatorEdge.class, + PathwayEdge.class, + ElevatorHopEdge.class, + TemporaryPartialStreetEdge.class, + TemporaryFreeEdge.class, + }; + private static final String EDGES_GROUP = "Edges"; + private static final String STOPS_GROUP = "Stops"; + private static final String VERTICES_GROUP = "Vertices"; + private static final String PERMISSIONS_GROUP = "Permissions"; + private static final String NO_THRU_TRAFFIC_GROUP = "No-thru traffic"; + + private static final StreetTraversalPermission[] streetModes = new StreetTraversalPermission[] { + StreetTraversalPermission.PEDESTRIAN, + StreetTraversalPermission.BICYCLE, + StreetTraversalPermission.CAR, + }; + private static final String WHEELCHAIR_GROUP = "Wheelchair accessibility"; + + static StyleSpec build( + VectorSourceLayer regularStops, + VectorSourceLayer areaStops, + VectorSourceLayer groupStops, + VectorSourceLayer edges, + VectorSourceLayer vertices, + List extraLayers + ) { + List vectorSources = Stream + .of(regularStops, edges, vertices) + .map(VectorSourceLayer::vectorSource) + .map(TileSource.class::cast) + .toList(); + + List extraRasterSources = extraLayers + .stream() + .map(l -> + (TileSource) new RasterSource( + l.name(), + List.of(l.templateUrl()), + 19, + l.tileSize(), + l.attribution() + ) + ) + .toList(); + var allSources = ListUtils.combine(BACKGROUND_LAYERS, extraRasterSources, vectorSources); + return new StyleSpec( + "OTP Debug Tiles", + allSources, + ListUtils.combine( + backgroundLayers(extraRasterSources), + wheelchair(edges), + noThruTraffic(edges), + traversalPermissions(edges), + edges(edges), + vertices(vertices), + stops(regularStops, areaStops, groupStops) + ) + ); + } + + private static List backgroundLayers(List extraLayers) { + return ListUtils + .combine(BACKGROUND_LAYERS, extraLayers) + .stream() + .map(layer -> { + var builder = StyleBuilder + .ofId(layer.id()) + .displayName(layer.name()) + .typeRaster() + .source(layer) + .minZoom(0); + if (!layer.equals(OSM_BACKGROUND)) { + builder.intiallyHidden(); + } + return builder; + }) + .toList(); + } + + private static List stops( + VectorSourceLayer regularStops, + VectorSourceLayer areaStops, + VectorSourceLayer groupStops + ) { + return List.of( + StyleBuilder + .ofId("area-stop") + .group(STOPS_GROUP) + .typeFill() + .vectorSourceLayer(areaStops) + .fillColor(BRIGHT_GREEN) + .fillOpacity(0.5f) + .fillOutlineColor(BLACK) + .minZoom(6) + .maxZoom(MAX_ZOOM), + StyleBuilder + .ofId("group-stop") + .group(STOPS_GROUP) + .typeFill() + .vectorSourceLayer(groupStops) + .fillColor(BRIGHT_GREEN) + .fillOpacity(0.5f) + .fillOutlineColor(BLACK) + .minZoom(6) + .maxZoom(MAX_ZOOM), + StyleBuilder + .ofId("regular-stop") + .group(STOPS_GROUP) + .typeCircle() + .vectorSourceLayer(regularStops) + .circleStroke( + BLACK, + new ZoomDependentNumber(List.of(new ZoomStop(11, 0.5f), new ZoomStop(MAX_ZOOM, 5))) + ) + .circleRadius( + new ZoomDependentNumber(List.of(new ZoomStop(11, 0.5f), new ZoomStop(MAX_ZOOM, 10))) + ) + .circleColor("#fcf9fa") + .minZoom(10) + .maxZoom(MAX_ZOOM) + ); + } + + private static List vertices(VectorSourceLayer vertices) { + return List.of( + StyleBuilder + .ofId("vertex") + .group(VERTICES_GROUP) + .typeCircle() + .vectorSourceLayer(vertices) + .circleStroke(BLACK, CIRCLE_STROKE) + .circleRadius( + new ZoomDependentNumber(List.of(new ZoomStop(15, 1), new ZoomStop(MAX_ZOOM, 7))) + ) + .circleColor(PURPLE) + .minZoom(15) + .maxZoom(MAX_ZOOM) + .intiallyHidden(), + StyleBuilder + .ofId("parking-vertex") + .group(VERTICES_GROUP) + .typeCircle() + .vectorSourceLayer(vertices) + .vertexFilter(VehicleParkingEntranceVertex.class) + .circleStroke(BLACK, CIRCLE_STROKE) + .circleRadius( + new ZoomDependentNumber(List.of(new ZoomStop(13, 1.4f), new ZoomStop(MAX_ZOOM, 10))) + ) + .circleColor(DARK_GREEN) + .minZoom(13) + .maxZoom(MAX_ZOOM) + .intiallyHidden() + ); + } + + private static List edges(VectorSourceLayer edges) { + return List.of( + StyleBuilder + .ofId("edge") + .group(EDGES_GROUP) + .typeLine() + .vectorSourceLayer(edges) + .lineColor(MAGENTA) + .edgeFilter(EDGES_TO_DISPLAY) + .lineWidth(LINE_HALF_WIDTH) + .lineOffset(LINE_OFFSET) + .minZoom(6) + .maxZoom(MAX_ZOOM) + .intiallyHidden(), + StyleBuilder + .ofId("edge-name") + .group(EDGES_GROUP) + .typeSymbol() + .lineText("name") + .vectorSourceLayer(edges) + .edgeFilter(EDGES_TO_DISPLAY) + .minZoom(17) + .maxZoom(MAX_ZOOM) + .intiallyHidden(), + StyleBuilder + .ofId("link") + .group(EDGES_GROUP) + .typeLine() + .vectorSourceLayer(edges) + .lineColor(BRIGHT_GREEN) + .edgeFilter( + StreetTransitStopLink.class, + StreetTransitEntranceLink.class, + BoardingLocationToStopLink.class, + StreetVehicleRentalLink.class, + StreetVehicleParkingLink.class, + StreetStationCentroidLink.class + ) + .lineWidth(LINE_WIDTH) + .lineOffset(LINE_OFFSET) + .minZoom(13) + .maxZoom(MAX_ZOOM) + .intiallyHidden() + ); + } + + private static List traversalPermissions(VectorSourceLayer edges) { + var permissionStyles = Arrays + .stream(streetModes) + .map(streetTraversalPermission -> + StyleBuilder + .ofId("permission " + streetTraversalPermission) + .vectorSourceLayer(edges) + .group(PERMISSIONS_GROUP) + .typeLine() + .filterValueInProperty( + "permission", + streetTraversalPermission.name(), + StreetTraversalPermission.ALL.name() + ) + .lineCap("butt") + .lineColorMatch("permission", permissionColors(), BLACK) + .lineWidth(LINE_WIDTH) + .lineOffset(LINE_OFFSET) + .minZoom(LINE_DETAIL_ZOOM) + .maxZoom(MAX_ZOOM) + .intiallyHidden() + ) + .toList(); + + var textStyle = StyleBuilder + .ofId("permission-text") + .vectorSourceLayer(edges) + .group(PERMISSIONS_GROUP) + .typeSymbol() + .lineText("permission") + .textOffset(1) + .edgeFilter(EDGES_TO_DISPLAY) + .minZoom(17) + .maxZoom(MAX_ZOOM) + .intiallyHidden(); + + return ListUtils.combine(permissionStyles, List.of(textStyle)); + } + + private static List noThruTraffic(VectorSourceLayer edges) { + var noThruTrafficStyles = Arrays + .stream(streetModes) + .map(streetTraversalPermission -> + StyleBuilder + .ofId("no-thru-traffic " + streetTraversalPermission) + .vectorSourceLayer(edges) + .group(NO_THRU_TRAFFIC_GROUP) + .typeLine() + .filterValueInProperty( + "noThruTraffic", + streetTraversalPermission.name(), + StreetTraversalPermission.ALL.name() + ) + .lineCap("butt") + .lineColorMatch("noThruTraffic", permissionColors(), BLACK) + .lineWidth(LINE_WIDTH) + .lineOffset(LINE_OFFSET) + .minZoom(LINE_DETAIL_ZOOM) + .maxZoom(MAX_ZOOM) + .intiallyHidden() + ) + .toList(); + + var textStyle = StyleBuilder + .ofId("no-thru-traffic-text") + .vectorSourceLayer(edges) + .group(NO_THRU_TRAFFIC_GROUP) + .typeSymbol() + .lineText("noThruTraffic") + .textOffset(1) + .edgeFilter(EDGES_TO_DISPLAY) + .minZoom(17) + .maxZoom(MAX_ZOOM) + .intiallyHidden(); + + return ListUtils.combine(noThruTrafficStyles, List.of(textStyle)); + } + + private static List permissionColors() { + return Arrays + .stream(StreetTraversalPermission.values()) + .flatMap(p -> Stream.of(streetPermissionAsString(p), permissionColor(p))) + .toList(); + } + + private static List wheelchair(VectorSourceLayer edges) { + return List.of( + StyleBuilder + .ofId("wheelchair-accessible") + .vectorSourceLayer(edges) + .group(WHEELCHAIR_GROUP) + .typeLine() + .lineColor(DARK_GREEN) + .booleanFilter("wheelchairAccessible", true) + .lineWidth(LINE_WIDTH) + .lineOffset(LINE_OFFSET) + .minZoom(6) + .maxZoom(MAX_ZOOM) + .intiallyHidden(), + StyleBuilder + .ofId("wheelchair-inaccessible") + .vectorSourceLayer(edges) + .group(WHEELCHAIR_GROUP) + .typeLine() + .lineColor(RED) + .booleanFilter("wheelchairAccessible", false) + .lineWidth(LINE_WIDTH) + .lineOffset(LINE_OFFSET) + .minZoom(6) + .maxZoom(MAX_ZOOM) + .intiallyHidden() + ); + } + + private static String permissionColor(StreetTraversalPermission p) { + return switch (p) { + case NONE -> BLACK; + case PEDESTRIAN -> "#2ba812"; + case BICYCLE, PEDESTRIAN_AND_BICYCLE -> "#10d3b6"; + case CAR -> "#f92e13"; + case BICYCLE_AND_CAR, PEDESTRIAN_AND_CAR -> "#e25f8f"; + case ALL -> "#adb2b0"; + }; + } +} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/application/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java similarity index 98% rename from src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java rename to application/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index f97830232bd..0576e91f312 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/application/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -23,7 +23,6 @@ import java.util.Objects; import java.util.function.Predicate; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.glassfish.grizzly.http.server.Request; import org.opentripplanner.apis.support.TileJson; import org.opentripplanner.apis.vectortiles.model.LayerParams; @@ -148,7 +147,8 @@ public StyleSpec getTileJson(@Context UriInfo uri, @Context HttpHeaders headers) AREA_STOPS.toVectorSourceLayer(stopsSource), GROUP_STOPS.toVectorSourceLayer(stopsSource), EDGES.toVectorSourceLayer(streetSource), - VERTICES.toVectorSourceLayer(streetSource) + VERTICES.toVectorSourceLayer(streetSource), + serverContext.debugUiConfig().additionalBackgroundLayers() ); } @@ -164,11 +164,10 @@ private String tileJsonUrl(String base, List> layers) ); } - @Nonnull private List feedInfos() { return serverContext .transitService() - .getFeedIds() + .listFeedIds() .stream() .map(serverContext.transitService()::getFeedInfo) .filter(Predicate.not(Objects::isNull)) diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java b/application/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java rename to application/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java b/application/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java rename to application/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java b/application/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java similarity index 71% rename from src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java rename to application/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java index d842b5e6687..4e75f37785d 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java +++ b/application/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java @@ -2,17 +2,19 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Stream; import org.opentripplanner.apis.vectortiles.model.ZoomDependentNumber.ZoomStop; -import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.json.ObjectMappers; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.vertex.Vertex; +import org.opentripplanner.utils.collection.ListUtils; /** * Builds a Maplibre/Mapbox vector tile @@ -26,8 +28,9 @@ public class StyleBuilder { private final Map props = new LinkedHashMap<>(); private final Map paint = new LinkedHashMap<>(); private final Map layout = new LinkedHashMap<>(); + private final Map metadata = new LinkedHashMap<>(); private final Map line = new LinkedHashMap<>(); - private List filter = List.of(); + private List filter = List.of(); public static StyleBuilder ofId(String id) { return new StyleBuilder(id); @@ -48,6 +51,7 @@ public enum LayerType { private StyleBuilder(String id) { props.put("id", id); + metadata.put("group", "Other"); } public StyleBuilder minZoom(int i) { @@ -107,18 +111,36 @@ private StyleBuilder type(LayerType type) { return this; } + /** + * Puts the layer into an arbitrarily defined group in the layer selector. This allows you + * to switch the entire group on and off. + */ + public StyleBuilder group(String group) { + metadata.put("group", group); + return this; + } + + /** + * A nice human-readable name for the layer. + */ + public StyleBuilder displayName(String name) { + metadata.put("name", name); + return this; + } + public StyleBuilder lineText(String name) { - layout.put("symbol-placement", "line"); - layout.put("symbol-spacing", 500); + layout.put("symbol-placement", "line-center"); + layout.put("symbol-spacing", 1000); layout.put("text-field", "{%s}".formatted(name)); layout.put("text-font", List.of("KlokanTech Noto Sans Regular")); layout.put( "text-size", - new ZoomDependentNumber(14, List.of(new ZoomStop(14, 12), new ZoomStop(20, 14))).toJson() + new ZoomDependentNumber(List.of(new ZoomStop(10, 6), new ZoomStop(24, 12))).toJson() ); - layout.put("text-max-width", 5); + layout.put("text-max-width", 100); layout.put("text-keep-upright", true); layout.put("text-rotation-alignment", "map"); + layout.put("text-overlap", "never"); paint.put("text-color", "#000"); paint.put("text-halo-color", "#fff"); paint.put("text-halo-blur", 4); @@ -126,6 +148,11 @@ public StyleBuilder lineText(String name) { return this; } + public StyleBuilder textOffset(float offset) { + layout.put("text-offset", List.of(0, offset)); + return this; + } + public StyleBuilder circleColor(String color) { paint.put("circle-color", validateColor(color)); return this; @@ -149,12 +176,42 @@ public StyleBuilder circleRadius(ZoomDependentNumber radius) { } // Line styling + public StyleBuilder lineCap(String lineCap) { + layout.put("line-cap", lineCap); + return this; + } public StyleBuilder lineColor(String color) { paint.put("line-color", validateColor(color)); return this; } + public StyleBuilder lineColorMatch( + String propertyName, + Collection values, + String defaultValue + ) { + paint.put( + "line-color", + ListUtils.combine( + List.of("match", List.of("get", propertyName)), + (Collection) values, + List.of(defaultValue) + ) + ); + return this; + } + + public StyleBuilder lineOpacity(float lineOpacity) { + paint.put("line-opacity", lineOpacity); + return this; + } + + public StyleBuilder lineDasharray(float... dashArray) { + paint.put("line-dasharray", dashArray); + return this; + } + public StyleBuilder lineWidth(float width) { paint.put("line-width", width); return this; @@ -165,6 +222,11 @@ public StyleBuilder lineWidth(ZoomDependentNumber zoomStops) { return this; } + public StyleBuilder lineOffset(ZoomDependentNumber zoomStops) { + paint.put("line-offset", zoomStops.toJson()); + return this; + } + public StyleBuilder fillColor(String color) { paint.put("fill-color", validateColor(color)); return this; @@ -196,6 +258,14 @@ public final StyleBuilder edgeFilter(Class... classToFilter) { return filterClasses(classToFilter); } + /** + * Filter the entities by a boolean property. + */ + public final StyleBuilder booleanFilter(String propertyName, boolean value) { + filter = List.of("==", propertyName, value); + return this; + } + /** * Only apply the style to the given vertices. */ @@ -204,6 +274,16 @@ public final StyleBuilder vertexFilter(Class... classToFilter) return filterClasses(classToFilter); } + public StyleBuilder filterValueInProperty(String propertyName, String... values) { + var newFilter = new ArrayList<>(); + newFilter.add("any"); + for (String value : values) { + newFilter.add(List.of("in", value, List.of("string", List.of("get", propertyName)))); + } + filter = newFilter; + return this; + } + public JsonNode toJson() { validate(); @@ -220,12 +300,13 @@ public JsonNode toJson() { if (!line.isEmpty()) { copy.put("line", line); } + copy.put("metadata", metadata); return OBJECT_MAPPER.valueToTree(copy); } private StyleBuilder filterClasses(Class... classToFilter) { var clazzes = Arrays.stream(classToFilter).map(Class::getSimpleName).toList(); - filter = ListUtils.combine(List.of("in", "class"), clazzes); + filter = new ArrayList<>(ListUtils.combine(List.of("in", "class"), clazzes)); return this; } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleSpec.java b/application/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleSpec.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/vectortiles/model/StyleSpec.java rename to application/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleSpec.java diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java b/application/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java similarity index 71% rename from src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java rename to application/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java index 088ce63d10a..b7f0ce5d048 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java +++ b/application/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.util.List; +import org.opentripplanner.utils.lang.StringUtils; /** * Represent a data source where Maplibre can fetch data for rendering directly in the browser. @@ -12,6 +13,8 @@ public sealed interface TileSource { String id(); + String name(); + /** * Represents a vector tile source which is rendered into a map in the browser. */ @@ -20,17 +23,32 @@ record VectorSource(String id, String url) implements TileSource { public String type() { return "vector"; } + + @Override + public String name() { + return id; + } } /** * Represents a raster-based source for map tiles. These are used mainly for background * map layers with vector data being rendered on top of it. */ - record RasterSource(String id, List tiles, int maxzoom, int tileSize, String attribution) + record RasterSource( + String name, + List tiles, + int maxzoom, + int tileSize, + String attribution + ) implements TileSource { @Override public String type() { return "raster"; } + + public String id() { + return StringUtils.slugify(name); + } } } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/VectorSourceLayer.java b/application/src/main/java/org/opentripplanner/apis/vectortiles/model/VectorSourceLayer.java similarity index 100% rename from src/main/java/org/opentripplanner/apis/vectortiles/model/VectorSourceLayer.java rename to application/src/main/java/org/opentripplanner/apis/vectortiles/model/VectorSourceLayer.java diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/ZoomDependentNumber.java b/application/src/main/java/org/opentripplanner/apis/vectortiles/model/ZoomDependentNumber.java similarity index 66% rename from src/main/java/org/opentripplanner/apis/vectortiles/model/ZoomDependentNumber.java rename to application/src/main/java/org/opentripplanner/apis/vectortiles/model/ZoomDependentNumber.java index d83c4b63495..cc655ba2038 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/ZoomDependentNumber.java +++ b/application/src/main/java/org/opentripplanner/apis/vectortiles/model/ZoomDependentNumber.java @@ -2,21 +2,23 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.LinkedHashMap; +import java.util.ArrayList; import java.util.List; import org.opentripplanner.framework.json.ObjectMappers; /** * A style parameter that allows you to specify a number that changes dependent on the zoom level. */ -public record ZoomDependentNumber(float base, List stops) { +public record ZoomDependentNumber(List stops) { private static final ObjectMapper OBJECT_MAPPER = ObjectMappers.ignoringExtraFields(); public JsonNode toJson() { - var props = new LinkedHashMap<>(); - props.put("base", base); - var vals = stops.stream().map(ZoomStop::toList).toList(); - props.put("stops", vals); - return OBJECT_MAPPER.valueToTree(props); + var interpolation = new ArrayList<>(); + interpolation.add("interpolate"); + interpolation.add(List.of("linear")); + interpolation.add(List.of("zoom")); + stops.forEach(s -> interpolation.addAll(s.toList())); + + return OBJECT_MAPPER.valueToTree(interpolation); } /** diff --git a/src/main/java/org/opentripplanner/astar/AStar.java b/application/src/main/java/org/opentripplanner/astar/AStar.java similarity index 98% rename from src/main/java/org/opentripplanner/astar/AStar.java rename to application/src/main/java/org/opentripplanner/astar/AStar.java index 1b4c69bfc16..86d48a3cbd8 100644 --- a/src/main/java/org/opentripplanner/astar/AStar.java +++ b/application/src/main/java/org/opentripplanner/astar/AStar.java @@ -7,7 +7,6 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.opentripplanner.astar.model.BinHeap; import org.opentripplanner.astar.model.GraphPath; import org.opentripplanner.astar.model.ShortestPathTree; @@ -20,7 +19,7 @@ import org.opentripplanner.astar.spi.SkipEdgeStrategy; import org.opentripplanner.astar.spi.TraverseVisitor; import org.opentripplanner.framework.application.OTPRequestTimeoutException; -import org.opentripplanner.framework.time.DateUtils; +import org.opentripplanner.utils.time.DateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,7 +62,7 @@ public class AStar< Set toVertices, SearchTerminationStrategy terminationStrategy, DominanceFunction dominanceFunction, - @Nonnull Duration timeout, + Duration timeout, Collection initialStates ) { this.heuristic = heuristic; diff --git a/src/main/java/org/opentripplanner/astar/AStarBuilder.java b/application/src/main/java/org/opentripplanner/astar/AStarBuilder.java similarity index 99% rename from src/main/java/org/opentripplanner/astar/AStarBuilder.java rename to application/src/main/java/org/opentripplanner/astar/AStarBuilder.java index a4b0ac32389..349b7185b29 100644 --- a/src/main/java/org/opentripplanner/astar/AStarBuilder.java +++ b/application/src/main/java/org/opentripplanner/astar/AStarBuilder.java @@ -6,7 +6,6 @@ import java.util.List; import java.util.Optional; import java.util.Set; -import javax.annotation.Nonnull; import org.opentripplanner.astar.model.GraphPath; import org.opentripplanner.astar.model.ShortestPathTree; import org.opentripplanner.astar.spi.AStarEdge; @@ -98,7 +97,6 @@ public Builder setDominanceFunction(DominanceFunction dominanceFunction) return builder; } - @Nonnull protected abstract Duration streetRoutingTimeout(); public Builder setOriginBackEdge(Edge originBackEdge) { diff --git a/src/main/java/org/opentripplanner/astar/model/BinHeap.java b/application/src/main/java/org/opentripplanner/astar/model/BinHeap.java similarity index 100% rename from src/main/java/org/opentripplanner/astar/model/BinHeap.java rename to application/src/main/java/org/opentripplanner/astar/model/BinHeap.java diff --git a/src/main/java/org/opentripplanner/astar/model/GraphPath.java b/application/src/main/java/org/opentripplanner/astar/model/GraphPath.java similarity index 100% rename from src/main/java/org/opentripplanner/astar/model/GraphPath.java rename to application/src/main/java/org/opentripplanner/astar/model/GraphPath.java diff --git a/src/main/java/org/opentripplanner/astar/model/ShortestPathTree.java b/application/src/main/java/org/opentripplanner/astar/model/ShortestPathTree.java similarity index 100% rename from src/main/java/org/opentripplanner/astar/model/ShortestPathTree.java rename to application/src/main/java/org/opentripplanner/astar/model/ShortestPathTree.java diff --git a/src/main/java/org/opentripplanner/astar/spi/AStarEdge.java b/application/src/main/java/org/opentripplanner/astar/spi/AStarEdge.java similarity index 98% rename from src/main/java/org/opentripplanner/astar/spi/AStarEdge.java rename to application/src/main/java/org/opentripplanner/astar/spi/AStarEdge.java index 91872021fc1..c4caafb19a9 100644 --- a/src/main/java/org/opentripplanner/astar/spi/AStarEdge.java +++ b/application/src/main/java/org/opentripplanner/astar/spi/AStarEdge.java @@ -1,7 +1,5 @@ package org.opentripplanner.astar.spi; -import javax.annotation.Nonnull; - /** * Represents an edge in the street network. Most edges have a one-to-one mapping to real world * things like street segments or stairs. @@ -43,6 +41,5 @@ public interface AStarEdge< * vehicle is speculatively dropped off and the passenger continues on foot in case * that the destination is inside the zone. */ - @Nonnull State[] traverse(State s0); } diff --git a/src/main/java/org/opentripplanner/astar/spi/AStarRequest.java b/application/src/main/java/org/opentripplanner/astar/spi/AStarRequest.java similarity index 100% rename from src/main/java/org/opentripplanner/astar/spi/AStarRequest.java rename to application/src/main/java/org/opentripplanner/astar/spi/AStarRequest.java diff --git a/src/main/java/org/opentripplanner/astar/spi/AStarState.java b/application/src/main/java/org/opentripplanner/astar/spi/AStarState.java similarity index 100% rename from src/main/java/org/opentripplanner/astar/spi/AStarState.java rename to application/src/main/java/org/opentripplanner/astar/spi/AStarState.java diff --git a/src/main/java/org/opentripplanner/astar/spi/AStarVertex.java b/application/src/main/java/org/opentripplanner/astar/spi/AStarVertex.java similarity index 100% rename from src/main/java/org/opentripplanner/astar/spi/AStarVertex.java rename to application/src/main/java/org/opentripplanner/astar/spi/AStarVertex.java diff --git a/src/main/java/org/opentripplanner/astar/spi/DominanceFunction.java b/application/src/main/java/org/opentripplanner/astar/spi/DominanceFunction.java similarity index 100% rename from src/main/java/org/opentripplanner/astar/spi/DominanceFunction.java rename to application/src/main/java/org/opentripplanner/astar/spi/DominanceFunction.java diff --git a/src/main/java/org/opentripplanner/astar/spi/RemainingWeightHeuristic.java b/application/src/main/java/org/opentripplanner/astar/spi/RemainingWeightHeuristic.java similarity index 100% rename from src/main/java/org/opentripplanner/astar/spi/RemainingWeightHeuristic.java rename to application/src/main/java/org/opentripplanner/astar/spi/RemainingWeightHeuristic.java diff --git a/src/main/java/org/opentripplanner/astar/spi/SearchTerminationStrategy.java b/application/src/main/java/org/opentripplanner/astar/spi/SearchTerminationStrategy.java similarity index 100% rename from src/main/java/org/opentripplanner/astar/spi/SearchTerminationStrategy.java rename to application/src/main/java/org/opentripplanner/astar/spi/SearchTerminationStrategy.java diff --git a/src/main/java/org/opentripplanner/astar/spi/SkipEdgeStrategy.java b/application/src/main/java/org/opentripplanner/astar/spi/SkipEdgeStrategy.java similarity index 100% rename from src/main/java/org/opentripplanner/astar/spi/SkipEdgeStrategy.java rename to application/src/main/java/org/opentripplanner/astar/spi/SkipEdgeStrategy.java diff --git a/src/main/java/org/opentripplanner/astar/spi/TraverseVisitor.java b/application/src/main/java/org/opentripplanner/astar/spi/TraverseVisitor.java similarity index 100% rename from src/main/java/org/opentripplanner/astar/spi/TraverseVisitor.java rename to application/src/main/java/org/opentripplanner/astar/spi/TraverseVisitor.java diff --git a/src/main/java/org/opentripplanner/astar/strategy/ComposingSkipEdgeStrategy.java b/application/src/main/java/org/opentripplanner/astar/strategy/ComposingSkipEdgeStrategy.java similarity index 100% rename from src/main/java/org/opentripplanner/astar/strategy/ComposingSkipEdgeStrategy.java rename to application/src/main/java/org/opentripplanner/astar/strategy/ComposingSkipEdgeStrategy.java diff --git a/src/main/java/org/opentripplanner/astar/strategy/DurationComparator.java b/application/src/main/java/org/opentripplanner/astar/strategy/DurationComparator.java similarity index 100% rename from src/main/java/org/opentripplanner/astar/strategy/DurationComparator.java rename to application/src/main/java/org/opentripplanner/astar/strategy/DurationComparator.java diff --git a/src/main/java/org/opentripplanner/astar/strategy/DurationSkipEdgeStrategy.java b/application/src/main/java/org/opentripplanner/astar/strategy/DurationSkipEdgeStrategy.java similarity index 100% rename from src/main/java/org/opentripplanner/astar/strategy/DurationSkipEdgeStrategy.java rename to application/src/main/java/org/opentripplanner/astar/strategy/DurationSkipEdgeStrategy.java diff --git a/application/src/main/java/org/opentripplanner/astar/strategy/MaxCountTerminationStrategy.java b/application/src/main/java/org/opentripplanner/astar/strategy/MaxCountTerminationStrategy.java new file mode 100644 index 00000000000..66c5496c923 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/astar/strategy/MaxCountTerminationStrategy.java @@ -0,0 +1,36 @@ +package org.opentripplanner.astar.strategy; + +import java.util.function.Predicate; +import org.opentripplanner.astar.spi.AStarState; +import org.opentripplanner.astar.spi.SearchTerminationStrategy; + +/** + * This termination strategy is used to terminate an a-star search after a number of states matching + * some criteria has been found. For example it can be used to limit a search to a maximum number of + * stops. + */ +public class MaxCountTerminationStrategy> + implements SearchTerminationStrategy { + + private final int maxCount; + private final Predicate shouldIncreaseCount; + private int count; + + /** + * @param maxCount Terminate the search after this many matching states have been reached. + * @param shouldIncreaseCount A predicate to check if a state should increase the count or not. + */ + public MaxCountTerminationStrategy(int maxCount, Predicate shouldIncreaseCount) { + this.maxCount = maxCount; + this.shouldIncreaseCount = shouldIncreaseCount; + this.count = 0; + } + + @Override + public boolean shouldSearchTerminate(State current) { + if (shouldIncreaseCount.test(current)) { + count++; + } + return count >= maxCount; + } +} diff --git a/src/main/java/org/opentripplanner/astar/strategy/PathComparator.java b/application/src/main/java/org/opentripplanner/astar/strategy/PathComparator.java similarity index 100% rename from src/main/java/org/opentripplanner/astar/strategy/PathComparator.java rename to application/src/main/java/org/opentripplanner/astar/strategy/PathComparator.java diff --git a/src/main/java/org/opentripplanner/datastore/OtpDataStore.java b/application/src/main/java/org/opentripplanner/datastore/OtpDataStore.java similarity index 95% rename from src/main/java/org/opentripplanner/datastore/OtpDataStore.java rename to application/src/main/java/org/opentripplanner/datastore/OtpDataStore.java index 397d3f64c70..b85622de7f1 100644 --- a/src/main/java/org/opentripplanner/datastore/OtpDataStore.java +++ b/application/src/main/java/org/opentripplanner/datastore/OtpDataStore.java @@ -21,7 +21,6 @@ import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.datastore.api.CompositeDataSource; import org.opentripplanner.datastore.api.DataSource; @@ -135,25 +134,21 @@ public List getRepositoryDescriptions() { * @return The collection may contain elements of type {@link DataSource} or {@link * CompositeDataSource}. */ - @Nonnull public Collection listExistingSourcesFor(FileType type) { assertDataStoreIsOpened(); return sources.get(type).stream().filter(DataSource::exists).collect(Collectors.toList()); } - @Nonnull public DataSource getStreetGraph() { assertDataStoreIsOpened(); return streetGraph; } - @Nonnull public DataSource getGraph() { assertDataStoreIsOpened(); return graph; } - @Nonnull public CompositeDataSource getBuildReportDir() { assertDataStoreIsOpened(); return buildReportDir; @@ -188,11 +183,7 @@ private LocalDataSourceRepository getLocalDataSourceRepo( return localRepos.get(0); } - private DataSource findSingleSource( - @Nullable URI uri, - @Nonnull String filename, - @Nonnull FileType type - ) { + private DataSource findSingleSource(@Nullable URI uri, String filename, FileType type) { if (uri != null) { return findSourceUsingAllRepos(it -> it.findSource(uri, type)); } @@ -201,8 +192,8 @@ private DataSource findSingleSource( private CompositeDataSource findCompositeSource( @Nullable URI uri, - @Nonnull String filename, - @Nonnull FileType type + String filename, + FileType type ) { if (uri != null) { return findSourceUsingAllRepos(it -> it.findCompositeSource(uri, type)); @@ -211,10 +202,7 @@ private CompositeDataSource findCompositeSource( } } - private List findMultipleSources( - @Nonnull Collection uris, - @Nonnull FileType type - ) { + private List findMultipleSources(Collection uris, FileType type) { if (uris == null || uris.isEmpty()) { return localRepository.listExistingSources(type); } @@ -227,8 +215,8 @@ private List findMultipleSources( } private List findMultipleCompositeSources( - @Nonnull Collection uris, - @Nonnull FileType type + Collection uris, + FileType type ) { if (uris.isEmpty()) { return localRepository diff --git a/src/main/java/org/opentripplanner/datastore/api/CompositeDataSource.java b/application/src/main/java/org/opentripplanner/datastore/api/CompositeDataSource.java similarity index 100% rename from src/main/java/org/opentripplanner/datastore/api/CompositeDataSource.java rename to application/src/main/java/org/opentripplanner/datastore/api/CompositeDataSource.java diff --git a/src/main/java/org/opentripplanner/datastore/api/DataSource.java b/application/src/main/java/org/opentripplanner/datastore/api/DataSource.java similarity index 98% rename from src/main/java/org/opentripplanner/datastore/api/DataSource.java rename to application/src/main/java/org/opentripplanner/datastore/api/DataSource.java index e1eafcbdb2a..ee95f50680e 100644 --- a/src/main/java/org/opentripplanner/datastore/api/DataSource.java +++ b/application/src/main/java/org/opentripplanner/datastore/api/DataSource.java @@ -6,7 +6,7 @@ import java.net.URI; import java.text.SimpleDateFormat; import org.opentripplanner.datastore.OtpDataStore; -import org.opentripplanner.framework.text.FileSizeToTextConverter; +import org.opentripplanner.utils.text.FileSizeToTextConverter; /** * A data source is generalized type to represent an file, database blob or unit that OTP read or diff --git a/src/main/java/org/opentripplanner/datastore/api/FileType.java b/application/src/main/java/org/opentripplanner/datastore/api/FileType.java similarity index 100% rename from src/main/java/org/opentripplanner/datastore/api/FileType.java rename to application/src/main/java/org/opentripplanner/datastore/api/FileType.java diff --git a/src/main/java/org/opentripplanner/datastore/api/GoogleStorageDSRepository.java b/application/src/main/java/org/opentripplanner/datastore/api/GoogleStorageDSRepository.java similarity index 100% rename from src/main/java/org/opentripplanner/datastore/api/GoogleStorageDSRepository.java rename to application/src/main/java/org/opentripplanner/datastore/api/GoogleStorageDSRepository.java diff --git a/src/main/java/org/opentripplanner/datastore/api/OtpBaseDirectory.java b/application/src/main/java/org/opentripplanner/datastore/api/OtpBaseDirectory.java similarity index 100% rename from src/main/java/org/opentripplanner/datastore/api/OtpBaseDirectory.java rename to application/src/main/java/org/opentripplanner/datastore/api/OtpBaseDirectory.java diff --git a/src/main/java/org/opentripplanner/datastore/api/OtpDataStoreConfig.java b/application/src/main/java/org/opentripplanner/datastore/api/OtpDataStoreConfig.java similarity index 97% rename from src/main/java/org/opentripplanner/datastore/api/OtpDataStoreConfig.java rename to application/src/main/java/org/opentripplanner/datastore/api/OtpDataStoreConfig.java index 984d66de2e9..ac220d932d6 100644 --- a/src/main/java/org/opentripplanner/datastore/api/OtpDataStoreConfig.java +++ b/application/src/main/java/org/opentripplanner/datastore/api/OtpDataStoreConfig.java @@ -3,7 +3,6 @@ import java.net.URI; import java.util.List; import java.util.regex.Pattern; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.datastore.OtpDataStore; @@ -48,7 +47,6 @@ public interface OtpDataStoreConfig { *

* This parameter is optional. If {@code null} GTFS files are loaded from {@code baseDirectory}. */ - @Nonnull List gtfsFiles(); /** @@ -56,7 +54,6 @@ public interface OtpDataStoreConfig { *

* This parameter is optional. If {@code null} Netex files are loaded from {@code baseDirectory}. */ - @Nonnull List netexFiles(); /** diff --git a/src/main/java/org/opentripplanner/datastore/base/ByteArrayDataSource.java b/application/src/main/java/org/opentripplanner/datastore/base/ByteArrayDataSource.java similarity index 100% rename from src/main/java/org/opentripplanner/datastore/base/ByteArrayDataSource.java rename to application/src/main/java/org/opentripplanner/datastore/base/ByteArrayDataSource.java diff --git a/src/main/java/org/opentripplanner/datastore/base/DataSourceRepository.java b/application/src/main/java/org/opentripplanner/datastore/base/DataSourceRepository.java similarity index 92% rename from src/main/java/org/opentripplanner/datastore/base/DataSourceRepository.java rename to application/src/main/java/org/opentripplanner/datastore/base/DataSourceRepository.java index 92f2a5769b3..51f3e23347e 100644 --- a/src/main/java/org/opentripplanner/datastore/base/DataSourceRepository.java +++ b/application/src/main/java/org/opentripplanner/datastore/base/DataSourceRepository.java @@ -1,7 +1,6 @@ package org.opentripplanner.datastore.base; import java.net.URI; -import javax.annotation.Nonnull; import org.opentripplanner.datastore.api.CompositeDataSource; import org.opentripplanner.datastore.api.DataSource; import org.opentripplanner.datastore.api.FileType; @@ -43,7 +42,7 @@ public interface DataSourceRepository { * @param type the file type to load. * @return the datasource wrapper that can be used to access the data source. */ - DataSource findSource(@Nonnull URI uri, @Nonnull FileType type); + DataSource findSource(URI uri, FileType type); /** * Get the a composite data source (zip/directory) for the given uri and type. @@ -54,5 +53,5 @@ public interface DataSourceRepository { * @param type the file type to load. * @return the datasource wrapper that can be used to access the data source. */ - CompositeDataSource findCompositeSource(@Nonnull URI uri, @Nonnull FileType type); + CompositeDataSource findCompositeSource(URI uri, FileType type); } diff --git a/src/main/java/org/opentripplanner/datastore/base/LocalDataSourceRepository.java b/application/src/main/java/org/opentripplanner/datastore/base/LocalDataSourceRepository.java similarity index 97% rename from src/main/java/org/opentripplanner/datastore/base/LocalDataSourceRepository.java rename to application/src/main/java/org/opentripplanner/datastore/base/LocalDataSourceRepository.java index a68b6753fa1..10776c31f6e 100644 --- a/src/main/java/org/opentripplanner/datastore/base/LocalDataSourceRepository.java +++ b/application/src/main/java/org/opentripplanner/datastore/base/LocalDataSourceRepository.java @@ -1,7 +1,6 @@ package org.opentripplanner.datastore.base; import java.util.List; -import javax.annotation.Nonnull; import org.opentripplanner.datastore.api.CompositeDataSource; import org.opentripplanner.datastore.api.DataSource; import org.opentripplanner.datastore.api.FileType; @@ -43,7 +42,7 @@ static boolean isCurrentDir(String filename) { * @param type the file type to load. * @return the datasource wrapper that can be used to access the data source. */ - CompositeDataSource findCompositeSource(String localFilename, @Nonnull FileType type); + CompositeDataSource findCompositeSource(String localFilename, FileType type); /** * List all existing data sources for the given type. diff --git a/src/main/java/org/opentripplanner/datastore/configure/DataStoreModule.java b/application/src/main/java/org/opentripplanner/datastore/configure/DataStoreModule.java similarity index 100% rename from src/main/java/org/opentripplanner/datastore/configure/DataStoreModule.java rename to application/src/main/java/org/opentripplanner/datastore/configure/DataStoreModule.java diff --git a/src/main/java/org/opentripplanner/datastore/file/AbstractFileDataSource.java b/application/src/main/java/org/opentripplanner/datastore/file/AbstractFileDataSource.java similarity index 100% rename from src/main/java/org/opentripplanner/datastore/file/AbstractFileDataSource.java rename to application/src/main/java/org/opentripplanner/datastore/file/AbstractFileDataSource.java diff --git a/src/main/java/org/opentripplanner/datastore/file/DirectoryDataSource.java b/application/src/main/java/org/opentripplanner/datastore/file/DirectoryDataSource.java similarity index 100% rename from src/main/java/org/opentripplanner/datastore/file/DirectoryDataSource.java rename to application/src/main/java/org/opentripplanner/datastore/file/DirectoryDataSource.java diff --git a/src/main/java/org/opentripplanner/datastore/file/FileDataSource.java b/application/src/main/java/org/opentripplanner/datastore/file/FileDataSource.java similarity index 100% rename from src/main/java/org/opentripplanner/datastore/file/FileDataSource.java rename to application/src/main/java/org/opentripplanner/datastore/file/FileDataSource.java diff --git a/src/main/java/org/opentripplanner/datastore/file/FileDataSourceRepository.java b/application/src/main/java/org/opentripplanner/datastore/file/FileDataSourceRepository.java similarity index 96% rename from src/main/java/org/opentripplanner/datastore/file/FileDataSourceRepository.java rename to application/src/main/java/org/opentripplanner/datastore/file/FileDataSourceRepository.java index 75a157d83a0..ec5555be29e 100644 --- a/src/main/java/org/opentripplanner/datastore/file/FileDataSourceRepository.java +++ b/application/src/main/java/org/opentripplanner/datastore/file/FileDataSourceRepository.java @@ -16,7 +16,6 @@ import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; -import javax.annotation.Nonnull; import org.opentripplanner.datastore.api.CompositeDataSource; import org.opentripplanner.datastore.api.DataSource; import org.opentripplanner.datastore.api.FileType; @@ -56,7 +55,6 @@ public FileDataSourceRepository( /** * Use for unit testing */ - @Nonnull public static CompositeDataSource compositeSource(File file, FileType type) { // The cast is safe return createCompositeSource(file, type); @@ -73,12 +71,12 @@ public void open() { } @Override - public DataSource findSource(@Nonnull URI uri, @Nonnull FileType type) { + public DataSource findSource(URI uri, FileType type) { return new FileDataSource(openFile(uri, type), type); } @Override - public CompositeDataSource findCompositeSource(@Nonnull URI uri, @Nonnull FileType type) { + public CompositeDataSource findCompositeSource(URI uri, FileType type) { return createCompositeSource(openFile(uri, type), type); } diff --git a/src/main/java/org/opentripplanner/datastore/file/TemporaryFileDataSource.java b/application/src/main/java/org/opentripplanner/datastore/file/TemporaryFileDataSource.java similarity index 100% rename from src/main/java/org/opentripplanner/datastore/file/TemporaryFileDataSource.java rename to application/src/main/java/org/opentripplanner/datastore/file/TemporaryFileDataSource.java diff --git a/src/main/java/org/opentripplanner/datastore/file/ZipFileDataSource.java b/application/src/main/java/org/opentripplanner/datastore/file/ZipFileDataSource.java similarity index 100% rename from src/main/java/org/opentripplanner/datastore/file/ZipFileDataSource.java rename to application/src/main/java/org/opentripplanner/datastore/file/ZipFileDataSource.java diff --git a/src/main/java/org/opentripplanner/datastore/file/ZipFileEntryDataSource.java b/application/src/main/java/org/opentripplanner/datastore/file/ZipFileEntryDataSource.java similarity index 100% rename from src/main/java/org/opentripplanner/datastore/file/ZipFileEntryDataSource.java rename to application/src/main/java/org/opentripplanner/datastore/file/ZipFileEntryDataSource.java diff --git a/src/main/java/org/opentripplanner/datastore/file/ZipFileEntryParent.java b/application/src/main/java/org/opentripplanner/datastore/file/ZipFileEntryParent.java similarity index 100% rename from src/main/java/org/opentripplanner/datastore/file/ZipFileEntryParent.java rename to application/src/main/java/org/opentripplanner/datastore/file/ZipFileEntryParent.java diff --git a/src/main/java/org/opentripplanner/datastore/file/ZipStreamDataSourceDecorator.java b/application/src/main/java/org/opentripplanner/datastore/file/ZipStreamDataSourceDecorator.java similarity index 100% rename from src/main/java/org/opentripplanner/datastore/file/ZipStreamDataSourceDecorator.java rename to application/src/main/java/org/opentripplanner/datastore/file/ZipStreamDataSourceDecorator.java diff --git a/src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceMetadata.java b/application/src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceMetadata.java similarity index 97% rename from src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceMetadata.java rename to application/src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceMetadata.java index 9011f99d5ce..8a84b0210b1 100644 --- a/src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceMetadata.java +++ b/application/src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceMetadata.java @@ -9,7 +9,7 @@ import org.apache.hc.core5.http.Header; import org.apache.hc.core5.http.HttpHeaders; import org.opentripplanner.datastore.api.DataSource; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * HTTPS data source metadata returned by the HTTP server (HTTP headers). diff --git a/src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceRepository.java b/application/src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceRepository.java similarity index 93% rename from src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceRepository.java rename to application/src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceRepository.java index 56afc888c73..a0abd07cf38 100644 --- a/src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceRepository.java +++ b/application/src/main/java/org/opentripplanner/datastore/https/HttpsDataSourceRepository.java @@ -4,7 +4,6 @@ import java.time.Duration; import java.util.List; import java.util.Map; -import javax.annotation.Nonnull; import org.apache.hc.core5.http.Header; import org.opentripplanner.datastore.api.CompositeDataSource; import org.opentripplanner.datastore.api.DataSource; @@ -33,7 +32,7 @@ public String description() { public void open() {} @Override - public DataSource findSource(@Nonnull URI uri, @Nonnull FileType type) { + public DataSource findSource(URI uri, FileType type) { if (skipUri(uri)) { return null; } @@ -41,7 +40,7 @@ public DataSource findSource(@Nonnull URI uri, @Nonnull FileType type) { } @Override - public CompositeDataSource findCompositeSource(@Nonnull URI uri, @Nonnull FileType type) { + public CompositeDataSource findCompositeSource(URI uri, FileType type) { if (skipUri(uri)) { return null; } diff --git a/src/main/java/org/opentripplanner/datastore/https/HttpsFileDataSource.java b/application/src/main/java/org/opentripplanner/datastore/https/HttpsFileDataSource.java similarity index 100% rename from src/main/java/org/opentripplanner/datastore/https/HttpsFileDataSource.java rename to application/src/main/java/org/opentripplanner/datastore/https/HttpsFileDataSource.java diff --git a/src/main/java/org/opentripplanner/framework/application/ApplicationShutdownSupport.java b/application/src/main/java/org/opentripplanner/framework/application/ApplicationShutdownSupport.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/application/ApplicationShutdownSupport.java rename to application/src/main/java/org/opentripplanner/framework/application/ApplicationShutdownSupport.java diff --git a/src/main/java/org/opentripplanner/framework/application/LogMDCSupport.java b/application/src/main/java/org/opentripplanner/framework/application/LogMDCSupport.java similarity index 97% rename from src/main/java/org/opentripplanner/framework/application/LogMDCSupport.java rename to application/src/main/java/org/opentripplanner/framework/application/LogMDCSupport.java index 6dccdcd8152..909363badd3 100644 --- a/src/main/java/org/opentripplanner/framework/application/LogMDCSupport.java +++ b/application/src/main/java/org/opentripplanner/framework/application/LogMDCSupport.java @@ -2,7 +2,7 @@ import java.util.Map; import javax.annotation.Nullable; -import org.opentripplanner.framework.lang.StringUtils; +import org.opentripplanner.utils.lang.StringUtils; import org.slf4j.MDC; /** diff --git a/src/main/java/org/opentripplanner/framework/application/OTPFeature.java b/application/src/main/java/org/opentripplanner/framework/application/OTPFeature.java similarity index 89% rename from src/main/java/org/opentripplanner/framework/application/OTPFeature.java rename to application/src/main/java/org/opentripplanner/framework/application/OTPFeature.java index 749772fae12..f71283b572e 100644 --- a/src/main/java/org/opentripplanner/framework/application/OTPFeature.java +++ b/application/src/main/java/org/opentripplanner/framework/application/OTPFeature.java @@ -4,6 +4,7 @@ import java.util.Map; import java.util.function.Supplier; import java.util.stream.Collectors; +import javax.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,6 +18,17 @@ public enum OTPFeature { APIBikeRental(true, false, "Enable the bike rental endpoint."), APIServerInfo(true, false, "Enable the server info endpoint."), APIUpdaterStatus(true, false, "Enable endpoint for graph updaters status."), + IncludeEmptyRailStopsInTransfers( + false, + false, + """ + Turning this on guarantees that Rail stops without scheduled departures still get included + when generating transfers using `ConsiderPatternsForDirectTransfers`. It is common for stops + to be assign at real-time for Rail. Turning this on will help to avoid dropping transfers which + are needed, when the stop is in use later. Turning this on, if + ConsiderPatternsForDirectTransfers is off has no effect. + """ + ), ConsiderPatternsForDirectTransfers( true, false, @@ -31,13 +43,13 @@ public enum OTPFeature { Use the [vector tiles feature if](sandbox/MapboxVectorTilesApi.md) you want a stable map tiles API. """ ), - FloatingBike(true, false, "Enable floating bike routing."), - GtfsGraphQlApi(true, false, "Enable the [GTFS GraphQL API](apis/GTFS-GraphQL-API.md)."), - GtfsGraphQlApiRentalStationFuzzyMatching( + ExtraTransferLegOnSameStop( false, false, - "Does vehicleRentalStation query also allow ids that are not feed scoped." + "Should there be a transfer leg when transferring on the very same stop. Note that for in-seat/interlined transfers no transfer leg will be generated." ), + FloatingBike(true, false, "Enable floating bike routing."), + GtfsGraphQlApi(true, false, "Enable the [GTFS GraphQL API](apis/GTFS-GraphQL-API.md)."), /** * If this feature flag is switched on, then the minimum transfer time is not the minimum transfer * time, but the definitive transfer time. Use this to override what we think the transfer will @@ -112,6 +124,11 @@ public enum OTPFeature { SandboxAPIGeocoder(false, true, "Enable the Geocoder API."), SandboxAPIMapboxVectorTilesApi(false, true, "Enable Mapbox vector tiles API."), SandboxAPIParkAndRideApi(false, true, "Enable park-and-ride endpoint."), + Sorlandsbanen( + false, + true, + "Include train Sørlandsbanen in results when searching in south of Norway. Only relevant in Norway." + ), TransferAnalyzer(false, true, "Analyze transfers during graph build."); private static final Object TEST_LOCK = new Object(); @@ -194,6 +211,7 @@ public boolean isOff() { /** * If feature is turned on, then return supplied object if not return {@code null}. */ + @Nullable public T isOnElseNull(Supplier supplier) { return isOn() ? supplier.get() : null; } diff --git a/src/main/java/org/opentripplanner/framework/application/OTPRequestTimeoutException.java b/application/src/main/java/org/opentripplanner/framework/application/OTPRequestTimeoutException.java similarity index 85% rename from src/main/java/org/opentripplanner/framework/application/OTPRequestTimeoutException.java rename to application/src/main/java/org/opentripplanner/framework/application/OTPRequestTimeoutException.java index a8b0789d7c0..9d71314f153 100644 --- a/src/main/java/org/opentripplanner/framework/application/OTPRequestTimeoutException.java +++ b/application/src/main/java/org/opentripplanner/framework/application/OTPRequestTimeoutException.java @@ -18,10 +18,9 @@ public String getMessage() { /** * The Grizzly web server is configured with a transaction timeout and will set the interrupt - * flag on the current thread. OTP does not have many blocking operations which check the - * interrupted flag, so instead we need to do the check manually. The check has a small - * performance overhead so try to place the check in the beginning of significantly big block of - * calculations. + * flag on the current thread. OTP has few blocking operations which check the interrupted flag, + * so instead we need to do the check manually. The check has a small performance overhead, so + * try to place the check at the beginning of a significant calculations. */ public static void checkForTimeout() { // We call yield() to allow monitoring thread to interrupt current thread. If this work or not diff --git a/src/main/java/org/opentripplanner/framework/application/OtpAppException.java b/application/src/main/java/org/opentripplanner/framework/application/OtpAppException.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/application/OtpAppException.java rename to application/src/main/java/org/opentripplanner/framework/application/OtpAppException.java diff --git a/src/main/java/org/opentripplanner/framework/application/OtpFileNames.java b/application/src/main/java/org/opentripplanner/framework/application/OtpFileNames.java similarity index 74% rename from src/main/java/org/opentripplanner/framework/application/OtpFileNames.java rename to application/src/main/java/org/opentripplanner/framework/application/OtpFileNames.java index 7b6852cb281..6c3a5b6a007 100644 --- a/src/main/java/org/opentripplanner/framework/application/OtpFileNames.java +++ b/application/src/main/java/org/opentripplanner/framework/application/OtpFileNames.java @@ -9,16 +9,18 @@ public class OtpFileNames { public static final String OTP_CONFIG_FILENAME = "otp-config.json"; public static final String BUILD_CONFIG_FILENAME = "build-config.json"; public static final String ROUTER_CONFIG_FILENAME = "router-config.json"; + public static final String DEBUG_UI_CONFIG_FILENAME = "debug-ui-config.json"; /** * Check if a file is a config file using the configuration file name. This method returns {@code - * true} if the file match {@code (otp|build|router)-config.json}. + * true} if the file match {@code (otp|build|router|debug-ui)-config.json}. */ public static boolean isConfigFile(String filename) { return ( OTP_CONFIG_FILENAME.equals(filename) || BUILD_CONFIG_FILENAME.equals(filename) || - ROUTER_CONFIG_FILENAME.equals(filename) + ROUTER_CONFIG_FILENAME.equals(filename) || + DEBUG_UI_CONFIG_FILENAME.equals(filename) ); } } diff --git a/application/src/main/java/org/opentripplanner/framework/collection/TroveUtils.java b/application/src/main/java/org/opentripplanner/framework/collection/TroveUtils.java new file mode 100644 index 00000000000..d3b59624eb9 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/framework/collection/TroveUtils.java @@ -0,0 +1,17 @@ +package org.opentripplanner.framework.collection; + +import gnu.trove.map.TLongObjectMap; +import java.util.HashSet; +import java.util.Set; + +public class TroveUtils { + + public static void addToMapSet(TLongObjectMap> mapSet, long key, U value) { + Set set = mapSet.get(key); + if (set == null) { + set = new HashSet<>(); + mapSet.put(key, set); + } + set.add(value); + } +} diff --git a/src/main/java/org/opentripplanner/framework/concurrent/LogMDCRunnableDecorator.java b/application/src/main/java/org/opentripplanner/framework/concurrent/LogMDCRunnableDecorator.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/concurrent/LogMDCRunnableDecorator.java rename to application/src/main/java/org/opentripplanner/framework/concurrent/LogMDCRunnableDecorator.java diff --git a/src/main/java/org/opentripplanner/framework/concurrent/OtpRequestThreadFactory.java b/application/src/main/java/org/opentripplanner/framework/concurrent/OtpRequestThreadFactory.java similarity index 95% rename from src/main/java/org/opentripplanner/framework/concurrent/OtpRequestThreadFactory.java rename to application/src/main/java/org/opentripplanner/framework/concurrent/OtpRequestThreadFactory.java index e88bbb420cd..cb738363bcb 100644 --- a/src/main/java/org/opentripplanner/framework/concurrent/OtpRequestThreadFactory.java +++ b/application/src/main/java/org/opentripplanner/framework/concurrent/OtpRequestThreadFactory.java @@ -2,7 +2,6 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.util.concurrent.ThreadFactory; -import javax.annotation.Nonnull; import org.opentripplanner.framework.application.LogMDCSupport; /** @@ -34,7 +33,7 @@ public static ThreadFactory of(String nameFormat) { } @Override - public Thread newThread(@Nonnull Runnable r) { + public Thread newThread(Runnable r) { if (LogMDCSupport.isRequestTracingInLoggingEnabled()) { return delegate.newThread(new LogMDCRunnableDecorator(r)); } diff --git a/src/main/java/org/opentripplanner/framework/doc/DocumentedEnum.java b/application/src/main/java/org/opentripplanner/framework/doc/DocumentedEnum.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/doc/DocumentedEnum.java rename to application/src/main/java/org/opentripplanner/framework/doc/DocumentedEnum.java diff --git a/src/main/java/org/opentripplanner/framework/error/DefaultOtpError.java b/application/src/main/java/org/opentripplanner/framework/error/DefaultOtpError.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/error/DefaultOtpError.java rename to application/src/main/java/org/opentripplanner/framework/error/DefaultOtpError.java diff --git a/src/main/java/org/opentripplanner/framework/error/OtpError.java b/application/src/main/java/org/opentripplanner/framework/error/OtpError.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/error/OtpError.java rename to application/src/main/java/org/opentripplanner/framework/error/OtpError.java diff --git a/src/main/java/org/opentripplanner/framework/functional/FunctionUtils.java b/application/src/main/java/org/opentripplanner/framework/functional/FunctionUtils.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/functional/FunctionUtils.java rename to application/src/main/java/org/opentripplanner/framework/functional/FunctionUtils.java diff --git a/src/main/java/org/opentripplanner/framework/geometry/CompactElevationProfile.java b/application/src/main/java/org/opentripplanner/framework/geometry/CompactElevationProfile.java similarity index 98% rename from src/main/java/org/opentripplanner/framework/geometry/CompactElevationProfile.java rename to application/src/main/java/org/opentripplanner/framework/geometry/CompactElevationProfile.java index bdab5f492e3..105c79973cd 100644 --- a/src/main/java/org/opentripplanner/framework/geometry/CompactElevationProfile.java +++ b/application/src/main/java/org/opentripplanner/framework/geometry/CompactElevationProfile.java @@ -4,7 +4,7 @@ import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.CoordinateSequence; import org.locationtech.jts.geom.impl.PackedCoordinateSequence; -import org.opentripplanner.framework.lang.IntUtils; +import org.opentripplanner.utils.lang.IntUtils; /** * Compact elevation profile. To optimize storage, we use the following tricks: diff --git a/src/main/java/org/opentripplanner/framework/geometry/CompactLineStringUtils.java b/application/src/main/java/org/opentripplanner/framework/geometry/CompactLineStringUtils.java similarity index 99% rename from src/main/java/org/opentripplanner/framework/geometry/CompactLineStringUtils.java rename to application/src/main/java/org/opentripplanner/framework/geometry/CompactLineStringUtils.java index d464d96fcee..19bf9824726 100644 --- a/src/main/java/org/opentripplanner/framework/geometry/CompactLineStringUtils.java +++ b/application/src/main/java/org/opentripplanner/framework/geometry/CompactLineStringUtils.java @@ -2,7 +2,7 @@ import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.LineString; -import org.opentripplanner.framework.lang.IntUtils; +import org.opentripplanner.utils.lang.IntUtils; /** * Compact line string. To optimize storage, we use the following tricks: diff --git a/src/main/java/org/opentripplanner/framework/geometry/CoordinateArrayListSequence.java b/application/src/main/java/org/opentripplanner/framework/geometry/CoordinateArrayListSequence.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/geometry/CoordinateArrayListSequence.java rename to application/src/main/java/org/opentripplanner/framework/geometry/CoordinateArrayListSequence.java diff --git a/src/main/java/org/opentripplanner/framework/geometry/DirectionUtils.java b/application/src/main/java/org/opentripplanner/framework/geometry/DirectionUtils.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/geometry/DirectionUtils.java rename to application/src/main/java/org/opentripplanner/framework/geometry/DirectionUtils.java diff --git a/src/main/java/org/opentripplanner/framework/geometry/DlugoszVarLenIntPacker.java b/application/src/main/java/org/opentripplanner/framework/geometry/DlugoszVarLenIntPacker.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/geometry/DlugoszVarLenIntPacker.java rename to application/src/main/java/org/opentripplanner/framework/geometry/DlugoszVarLenIntPacker.java diff --git a/src/main/java/org/opentripplanner/framework/geometry/EncodedPolyline.java b/application/src/main/java/org/opentripplanner/framework/geometry/EncodedPolyline.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/geometry/EncodedPolyline.java rename to application/src/main/java/org/opentripplanner/framework/geometry/EncodedPolyline.java diff --git a/src/main/java/org/opentripplanner/framework/geometry/GeometryUtils.java b/application/src/main/java/org/opentripplanner/framework/geometry/GeometryUtils.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/geometry/GeometryUtils.java rename to application/src/main/java/org/opentripplanner/framework/geometry/GeometryUtils.java diff --git a/src/main/java/org/opentripplanner/framework/geometry/HashGridSpatialIndex.java b/application/src/main/java/org/opentripplanner/framework/geometry/HashGridSpatialIndex.java similarity index 99% rename from src/main/java/org/opentripplanner/framework/geometry/HashGridSpatialIndex.java rename to application/src/main/java/org/opentripplanner/framework/geometry/HashGridSpatialIndex.java index d4082f9e22d..edda3fe4086 100644 --- a/src/main/java/org/opentripplanner/framework/geometry/HashGridSpatialIndex.java +++ b/application/src/main/java/org/opentripplanner/framework/geometry/HashGridSpatialIndex.java @@ -14,7 +14,7 @@ import org.locationtech.jts.geom.LineString; import org.locationtech.jts.index.ItemVisitor; import org.locationtech.jts.index.SpatialIndex; -import org.opentripplanner.framework.lang.IntBox; +import org.opentripplanner.utils.lang.IntBox; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/framework/geometry/PolylineEncoder.java b/application/src/main/java/org/opentripplanner/framework/geometry/PolylineEncoder.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/geometry/PolylineEncoder.java rename to application/src/main/java/org/opentripplanner/framework/geometry/PolylineEncoder.java diff --git a/src/main/java/org/opentripplanner/framework/geometry/SphericalDistanceLibrary.java b/application/src/main/java/org/opentripplanner/framework/geometry/SphericalDistanceLibrary.java similarity index 95% rename from src/main/java/org/opentripplanner/framework/geometry/SphericalDistanceLibrary.java rename to application/src/main/java/org/opentripplanner/framework/geometry/SphericalDistanceLibrary.java index 38c80e86d79..531170ad137 100644 --- a/src/main/java/org/opentripplanner/framework/geometry/SphericalDistanceLibrary.java +++ b/application/src/main/java/org/opentripplanner/framework/geometry/SphericalDistanceLibrary.java @@ -196,6 +196,20 @@ public static double metersToLonDegrees(double distanceMeters, double latDeg) { return dLatDeg / minCosLat; } + /** + * Approximately move a coordinate a given number of meters. This will fail if crossing the anti- + * meridian or any of the poles. + */ + public static WgsCoordinate moveMeters( + WgsCoordinate coordinate, + double latMeters, + double lonMeters + ) { + var degreesLat = metersToDegrees(latMeters); + var degreesLon = metersToLonDegrees(lonMeters, coordinate.latitude()); + return coordinate.add(degreesLat, degreesLon); + } + public static Envelope bounds(double lat, double lon, double latDistance, double lonDistance) { double radiusOfEarth = RADIUS_OF_EARTH_IN_M; diff --git a/src/main/java/org/opentripplanner/framework/geometry/SplitLineString.java b/application/src/main/java/org/opentripplanner/framework/geometry/SplitLineString.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/geometry/SplitLineString.java rename to application/src/main/java/org/opentripplanner/framework/geometry/SplitLineString.java diff --git a/src/main/java/org/opentripplanner/framework/geometry/UnsupportedGeometryException.java b/application/src/main/java/org/opentripplanner/framework/geometry/UnsupportedGeometryException.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/geometry/UnsupportedGeometryException.java rename to application/src/main/java/org/opentripplanner/framework/geometry/UnsupportedGeometryException.java diff --git a/src/main/java/org/opentripplanner/framework/geometry/WgsCoordinate.java b/application/src/main/java/org/opentripplanner/framework/geometry/WgsCoordinate.java similarity index 80% rename from src/main/java/org/opentripplanner/framework/geometry/WgsCoordinate.java rename to application/src/main/java/org/opentripplanner/framework/geometry/WgsCoordinate.java index e818d50c1f6..b5f9d4caaff 100644 --- a/src/main/java/org/opentripplanner/framework/geometry/WgsCoordinate.java +++ b/application/src/main/java/org/opentripplanner/framework/geometry/WgsCoordinate.java @@ -5,8 +5,8 @@ import java.util.Objects; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Point; -import org.opentripplanner.framework.lang.DoubleUtils; -import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; +import org.opentripplanner.utils.lang.DoubleUtils; +import org.opentripplanner.utils.tostring.ValueObjectToStringBuilder; /** * This class represent a OTP coordinate. @@ -163,6 +163,52 @@ public WgsCoordinate roundToApproximate100m() { return new WgsCoordinate(lat, lng); } + /** + * Compute a fairly accurate distance between two coordinates. Use the fast version in + * {@link SphericalDistanceLibrary} if many computations are needed. Return the distance in + * meters between the two coordinates. + */ + public double distanceTo(WgsCoordinate other) { + return SphericalDistanceLibrary.distance( + this.latitude, + this.longitude, + other.latitude, + other.longitude + ); + } + + public boolean isNorthOf(double latitudeBorder) { + return latitude > latitudeBorder; + } + + /** + * Return a new coordinate that is moved an approximate number of meters east. + */ + public WgsCoordinate moveEastMeters(double meters) { + return SphericalDistanceLibrary.moveMeters(this, 0, meters); + } + + /** + * Return a new coordinate that is moved an approximate number of meters west. + */ + public WgsCoordinate moveWestMeters(double meters) { + return SphericalDistanceLibrary.moveMeters(this, 0, -meters); + } + + /** + * Return a new coordinate that is moved an approximate number of meters north. + */ + public WgsCoordinate moveNorthMeters(double meters) { + return SphericalDistanceLibrary.moveMeters(this, meters, 0); + } + + /** + * Return a new coordinate that is moved an approximate number of meters south. + */ + public WgsCoordinate moveSouthMeters(double meters) { + return SphericalDistanceLibrary.moveMeters(this, -meters, 0); + } + /** * Return a string on the form: {@code "(60.12345, 11.12345)"}. Up to 5 digits are used after the * period(.), even if the coordinate is specified with a higher precision. diff --git a/src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java b/application/src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java rename to application/src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java diff --git a/src/main/java/org/opentripplanner/framework/graphql/GraphQLUtils.java b/application/src/main/java/org/opentripplanner/framework/graphql/GraphQLUtils.java similarity index 95% rename from src/main/java/org/opentripplanner/framework/graphql/GraphQLUtils.java rename to application/src/main/java/org/opentripplanner/framework/graphql/GraphQLUtils.java index 334513fd419..ff5485d75b2 100644 --- a/src/main/java/org/opentripplanner/framework/graphql/GraphQLUtils.java +++ b/application/src/main/java/org/opentripplanner/framework/graphql/GraphQLUtils.java @@ -4,7 +4,6 @@ import java.util.Locale; import java.util.Map; import java.util.Optional; -import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; public class GraphQLUtils { @@ -65,7 +64,7 @@ private static Optional getDefaultLocale(DataFetchingEnvironment environ return Optional.ofNullable((Locale) localContext.get("locale")); } - private static boolean acceptAnyLocale(@Nonnull Locale locale) { + private static boolean acceptAnyLocale(Locale locale) { return locale.getLanguage().equals("*"); } } diff --git a/src/main/java/org/opentripplanner/framework/graphql/scalar/CostScalarFactory.java b/application/src/main/java/org/opentripplanner/framework/graphql/scalar/CostScalarFactory.java similarity index 92% rename from src/main/java/org/opentripplanner/framework/graphql/scalar/CostScalarFactory.java rename to application/src/main/java/org/opentripplanner/framework/graphql/scalar/CostScalarFactory.java index 6f710328174..fc109444786 100644 --- a/src/main/java/org/opentripplanner/framework/graphql/scalar/CostScalarFactory.java +++ b/application/src/main/java/org/opentripplanner/framework/graphql/scalar/CostScalarFactory.java @@ -10,9 +10,8 @@ import graphql.schema.GraphQLScalarType; import java.util.Locale; import java.util.NoSuchElementException; -import javax.annotation.Nonnull; import org.opentripplanner.framework.model.Cost; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.utils.time.DurationUtils; public class CostScalarFactory { @@ -54,7 +53,7 @@ private static Cost parseCost(String input) throws CoercingParseValueException { private static Coercing createCoercing() { return new Coercing<>() { @Override - public String serialize(@Nonnull Object result, GraphQLContext c, Locale l) { + public String serialize(Object result, GraphQLContext c, Locale l) { return serializeCost((Cost) result); } @@ -74,7 +73,6 @@ public Cost parseLiteral(Value input, CoercedVariables v, GraphQLContext c, L } @Override - @Nonnull public Value valueToLiteral(Object input, GraphQLContext c, Locale l) { return StringValue.of((String) input); } diff --git a/src/main/java/org/opentripplanner/framework/graphql/scalar/DateScalarFactory.java b/application/src/main/java/org/opentripplanner/framework/graphql/scalar/DateScalarFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/graphql/scalar/DateScalarFactory.java rename to application/src/main/java/org/opentripplanner/framework/graphql/scalar/DateScalarFactory.java diff --git a/src/main/java/org/opentripplanner/framework/graphql/scalar/DurationScalarFactory.java b/application/src/main/java/org/opentripplanner/framework/graphql/scalar/DurationScalarFactory.java similarity index 80% rename from src/main/java/org/opentripplanner/framework/graphql/scalar/DurationScalarFactory.java rename to application/src/main/java/org/opentripplanner/framework/graphql/scalar/DurationScalarFactory.java index 50af0fbc759..5a61816ea06 100644 --- a/src/main/java/org/opentripplanner/framework/graphql/scalar/DurationScalarFactory.java +++ b/application/src/main/java/org/opentripplanner/framework/graphql/scalar/DurationScalarFactory.java @@ -8,8 +8,7 @@ import graphql.schema.GraphQLScalarType; import java.time.Duration; import java.time.format.DateTimeParseException; -import javax.annotation.Nonnull; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.utils.time.DurationUtils; public class DurationScalarFactory { @@ -30,8 +29,7 @@ public static GraphQLScalarType createDurationScalar() { private static class DurationCoercing implements Coercing { @Override - @Nonnull - public String serialize(@Nonnull Object input) throws CoercingSerializeException { + public String serialize(Object input) throws CoercingSerializeException { if (input instanceof Duration duration) { return DurationUtils.formatDurationWithLeadingMinus(duration); } @@ -40,8 +38,7 @@ public String serialize(@Nonnull Object input) throws CoercingSerializeException } @Override - @Nonnull - public Duration parseValue(@Nonnull Object input) throws CoercingParseValueException { + public Duration parseValue(Object input) throws CoercingParseValueException { try { return DurationUtils.duration(input.toString()); } catch (DateTimeParseException dtpe) { @@ -50,8 +47,7 @@ public Duration parseValue(@Nonnull Object input) throws CoercingParseValueExcep } @Override - @Nonnull - public Duration parseLiteral(@Nonnull Object input) throws CoercingParseLiteralException { + public Duration parseLiteral(Object input) throws CoercingParseLiteralException { if (input instanceof StringValue) { return parseValue(((StringValue) input).getValue()); } diff --git a/src/main/java/org/opentripplanner/framework/http/OtpHttpStatus.java b/application/src/main/java/org/opentripplanner/framework/http/OtpHttpStatus.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/http/OtpHttpStatus.java rename to application/src/main/java/org/opentripplanner/framework/http/OtpHttpStatus.java diff --git a/src/main/java/org/opentripplanner/framework/i18n/I18NString.java b/application/src/main/java/org/opentripplanner/framework/i18n/I18NString.java similarity index 57% rename from src/main/java/org/opentripplanner/framework/i18n/I18NString.java rename to application/src/main/java/org/opentripplanner/framework/i18n/I18NString.java index 4f75d214c91..101342c7a6f 100644 --- a/src/main/java/org/opentripplanner/framework/i18n/I18NString.java +++ b/application/src/main/java/org/opentripplanner/framework/i18n/I18NString.java @@ -1,6 +1,7 @@ package org.opentripplanner.framework.i18n; import java.util.Locale; +import javax.annotation.Nullable; /** * This interface is used when providing translations on server side. Sources: OSM tags with @@ -9,9 +10,20 @@ * @author mabu */ public interface I18NString { - /** true if the given value is not {@code null} or has at least one none white-space character. */ - public static boolean hasValue(I18NString value) { - return value != null && !value.toString().isBlank(); + /** + * Return {@code true} if the given value is not {@code null} or has at least one none + * white-space character. + */ + static boolean hasValue(@Nullable I18NString value) { + return !hasNoValue(value); + } + + /** + * Return {@code true} if the given value has at least one none white-space character. + * Return {@code false} if the value is {@code null} or blank. + */ + static boolean hasNoValue(@Nullable I18NString value) { + return value == null || value.toString().isBlank(); } /** @@ -26,8 +38,8 @@ public static boolean hasValue(I18NString value) { */ String toString(Locale locale); - static I18NString assertHasValue(I18NString value) { - if (value == null || value.toString().isBlank()) { + static I18NString assertHasValue(@Nullable I18NString value) { + if (hasNoValue(value)) { throw new IllegalArgumentException( "Value can not be null, empty or just whitespace: " + (value == null ? "null" : "'" + value + "'") diff --git a/src/main/java/org/opentripplanner/framework/i18n/I18NStringMapper.java b/application/src/main/java/org/opentripplanner/framework/i18n/I18NStringMapper.java similarity index 93% rename from src/main/java/org/opentripplanner/framework/i18n/I18NStringMapper.java rename to application/src/main/java/org/opentripplanner/framework/i18n/I18NStringMapper.java index acdb30b301f..ca3de85c221 100644 --- a/src/main/java/org/opentripplanner/framework/i18n/I18NStringMapper.java +++ b/application/src/main/java/org/opentripplanner/framework/i18n/I18NStringMapper.java @@ -1,7 +1,6 @@ package org.opentripplanner.framework.i18n; import java.util.Locale; -import javax.annotation.Nonnull; import javax.annotation.Nullable; public class I18NStringMapper { @@ -17,7 +16,6 @@ public String mapToApi(I18NString string) { return string == null ? null : string.toString(locale); } - @Nonnull public String mapNonnullToApi(I18NString string) { return string.toString(locale); } diff --git a/src/main/java/org/opentripplanner/framework/i18n/LocalizedString.java b/application/src/main/java/org/opentripplanner/framework/i18n/LocalizedString.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/i18n/LocalizedString.java rename to application/src/main/java/org/opentripplanner/framework/i18n/LocalizedString.java diff --git a/src/main/java/org/opentripplanner/framework/i18n/LocalizedStringFormat.java b/application/src/main/java/org/opentripplanner/framework/i18n/LocalizedStringFormat.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/i18n/LocalizedStringFormat.java rename to application/src/main/java/org/opentripplanner/framework/i18n/LocalizedStringFormat.java diff --git a/src/main/java/org/opentripplanner/framework/i18n/NonLocalizedString.java b/application/src/main/java/org/opentripplanner/framework/i18n/NonLocalizedString.java similarity index 84% rename from src/main/java/org/opentripplanner/framework/i18n/NonLocalizedString.java rename to application/src/main/java/org/opentripplanner/framework/i18n/NonLocalizedString.java index 3eddae235e4..dd7dfc8df05 100644 --- a/src/main/java/org/opentripplanner/framework/i18n/NonLocalizedString.java +++ b/application/src/main/java/org/opentripplanner/framework/i18n/NonLocalizedString.java @@ -4,7 +4,6 @@ import java.util.Locale; import java.util.Objects; import java.util.function.Function; -import javax.annotation.Nonnull; import javax.annotation.Nullable; /** @@ -18,7 +17,7 @@ public class NonLocalizedString implements I18NString, Serializable { private final String name; - public NonLocalizedString(@Nonnull String name) { + public NonLocalizedString(String name) { this.name = Objects.requireNonNull(name); } @@ -40,7 +39,7 @@ public static NonLocalizedString ofNullable(@Nullable String name) { */ public static NonLocalizedString ofNullable( @Nullable W wrapper, - @Nonnull Function getValueOp + Function getValueOp ) { return wrapper == null ? null : new NonLocalizedString(getValueOp.apply(wrapper)); } @@ -51,8 +50,8 @@ public static NonLocalizedString ofNullable( */ public static NonLocalizedString ofNullable( @Nullable W wrapper, - @Nonnull Function getValueOp, - @Nonnull String defaultValue + Function getValueOp, + String defaultValue ) { return new NonLocalizedString(wrapper == null ? defaultValue : getValueOp.apply(wrapper)); } @@ -61,11 +60,7 @@ public static NonLocalizedString ofNullable( * Check if name is non-null and returns an instance of {@link NonLocalizedString}, otherwise * returns a {@link NonLocalizedString} with the default name. */ - @Nonnull - public static NonLocalizedString ofNullableOrElse( - @Nullable String name, - @Nonnull String defaultName - ) { + public static NonLocalizedString ofNullableOrElse(@Nullable String name, String defaultName) { return new NonLocalizedString(name == null ? defaultName : name); } @@ -73,11 +68,7 @@ public static NonLocalizedString ofNullableOrElse( * Check if name is non-null and returns an instance of {@link NonLocalizedString}, otherwise * returns a {@link I18NString} with the default name. */ - @Nonnull - public static I18NString ofNullableOrElse( - @Nullable String name, - @Nonnull I18NString defaultName - ) { + public static I18NString ofNullableOrElse(@Nullable String name, I18NString defaultName) { return name == null ? defaultName : new NonLocalizedString(name); } diff --git a/src/main/java/org/opentripplanner/framework/i18n/TranslatedString.java b/application/src/main/java/org/opentripplanner/framework/i18n/TranslatedString.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/i18n/TranslatedString.java rename to application/src/main/java/org/opentripplanner/framework/i18n/TranslatedString.java diff --git a/src/main/java/org/opentripplanner/framework/io/FileUtils.java b/application/src/main/java/org/opentripplanner/framework/io/FileUtils.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/io/FileUtils.java rename to application/src/main/java/org/opentripplanner/framework/io/FileUtils.java diff --git a/src/main/java/org/opentripplanner/framework/io/HttpUtils.java b/application/src/main/java/org/opentripplanner/framework/io/HttpUtils.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/io/HttpUtils.java rename to application/src/main/java/org/opentripplanner/framework/io/HttpUtils.java diff --git a/src/main/java/org/opentripplanner/framework/io/JsonDataListDownloader.java b/application/src/main/java/org/opentripplanner/framework/io/JsonDataListDownloader.java similarity index 89% rename from src/main/java/org/opentripplanner/framework/io/JsonDataListDownloader.java rename to application/src/main/java/org/opentripplanner/framework/io/JsonDataListDownloader.java index 3affa734605..81f8ee5b3c4 100644 --- a/src/main/java/org/opentripplanner/framework/io/JsonDataListDownloader.java +++ b/application/src/main/java/org/opentripplanner/framework/io/JsonDataListDownloader.java @@ -11,7 +11,6 @@ import java.util.Map; import java.util.Objects; import java.util.function.Function; -import javax.annotation.Nonnull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,20 +24,20 @@ public class JsonDataListDownloader { private final OtpHttpClient otpHttpClient; public JsonDataListDownloader( - @Nonnull String url, - @Nonnull String jsonParsePath, - @Nonnull Function elementParser, - @Nonnull Map headers + String url, + String jsonParsePath, + Function elementParser, + Map headers ) { this(url, jsonParsePath, elementParser, headers, new OtpHttpClientFactory().create(LOG)); } public JsonDataListDownloader( - @Nonnull String url, - @Nonnull String jsonParsePath, - @Nonnull Function elementParser, - @Nonnull Map headers, - @Nonnull OtpHttpClient OtpHttpClient + String url, + String jsonParsePath, + Function elementParser, + Map headers, + OtpHttpClient OtpHttpClient ) { this.url = Objects.requireNonNull(url); this.jsonParsePath = Objects.requireNonNull(jsonParsePath); diff --git a/src/main/java/org/opentripplanner/framework/io/OtpHttpClient.java b/application/src/main/java/org/opentripplanner/framework/io/OtpHttpClient.java similarity index 98% rename from src/main/java/org/opentripplanner/framework/io/OtpHttpClient.java rename to application/src/main/java/org/opentripplanner/framework/io/OtpHttpClient.java index 678eb4754bd..ccb88c3c74b 100644 --- a/src/main/java/org/opentripplanner/framework/io/OtpHttpClient.java +++ b/application/src/main/java/org/opentripplanner/framework/io/OtpHttpClient.java @@ -18,6 +18,7 @@ import java.util.Optional; import java.util.stream.Collectors; import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.classic.methods.HttpHead; import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; import org.apache.hc.client5.http.config.RequestConfig; @@ -76,7 +77,7 @@ public List

getHeaders( Map requestHeaderValues ) { return executeAndMapWithResponseHandler( - new HttpGet(uri), + new HttpHead(uri), timeout, requestHeaderValues, response -> { @@ -90,9 +91,6 @@ public List
getHeaders( return Collections.emptyList(); } - if (response.getEntity() == null || response.getEntity().getContent() == null) { - throw new OtpHttpClientException("HTTP request failed: empty response"); - } return Arrays.stream(response.getHeaders()).toList(); } ); @@ -380,6 +378,7 @@ private static RequestConfig requestConfig(Duration timeout) { .custom() .setResponseTimeout(Timeout.of(timeout)) .setConnectionRequestTimeout(Timeout.of(timeout)) + .setProtocolUpgradeEnabled(false) .build(); } diff --git a/src/main/java/org/opentripplanner/framework/io/OtpHttpClientException.java b/application/src/main/java/org/opentripplanner/framework/io/OtpHttpClientException.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/io/OtpHttpClientException.java rename to application/src/main/java/org/opentripplanner/framework/io/OtpHttpClientException.java diff --git a/src/main/java/org/opentripplanner/framework/io/OtpHttpClientFactory.java b/application/src/main/java/org/opentripplanner/framework/io/OtpHttpClientFactory.java similarity index 99% rename from src/main/java/org/opentripplanner/framework/io/OtpHttpClientFactory.java rename to application/src/main/java/org/opentripplanner/framework/io/OtpHttpClientFactory.java index a6436168541..8f7256f642f 100644 --- a/src/main/java/org/opentripplanner/framework/io/OtpHttpClientFactory.java +++ b/application/src/main/java/org/opentripplanner/framework/io/OtpHttpClientFactory.java @@ -132,6 +132,7 @@ private static RequestConfig requestConfig(Duration timeout) { .custom() .setResponseTimeout(Timeout.of(timeout)) .setConnectionRequestTimeout(Timeout.of(timeout)) + .setProtocolUpgradeEnabled(false) .build(); } } diff --git a/src/main/java/org/opentripplanner/framework/json/JsonUtils.java b/application/src/main/java/org/opentripplanner/framework/json/JsonUtils.java similarity index 75% rename from src/main/java/org/opentripplanner/framework/json/JsonUtils.java rename to application/src/main/java/org/opentripplanner/framework/json/JsonUtils.java index 1f235eb6483..17b875b5596 100644 --- a/src/main/java/org/opentripplanner/framework/json/JsonUtils.java +++ b/application/src/main/java/org/opentripplanner/framework/json/JsonUtils.java @@ -2,11 +2,10 @@ import com.fasterxml.jackson.databind.JsonNode; import java.util.Optional; -import javax.annotation.Nonnull; public class JsonUtils { - public static Optional asText(@Nonnull JsonNode node, @Nonnull String field) { + public static Optional asText(JsonNode node, String field) { JsonNode valueNode = node.get(field); if (valueNode == null) { return Optional.empty(); diff --git a/src/main/java/org/opentripplanner/framework/json/ObjectMappers.java b/application/src/main/java/org/opentripplanner/framework/json/ObjectMappers.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/json/ObjectMappers.java rename to application/src/main/java/org/opentripplanner/framework/json/ObjectMappers.java diff --git a/src/main/java/org/opentripplanner/framework/logging/AbstractFilterLogger.java b/application/src/main/java/org/opentripplanner/framework/logging/AbstractFilterLogger.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/logging/AbstractFilterLogger.java rename to application/src/main/java/org/opentripplanner/framework/logging/AbstractFilterLogger.java diff --git a/src/main/java/org/opentripplanner/framework/logging/MaxCountLogger.java b/application/src/main/java/org/opentripplanner/framework/logging/MaxCountLogger.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/logging/MaxCountLogger.java rename to application/src/main/java/org/opentripplanner/framework/logging/MaxCountLogger.java diff --git a/src/main/java/org/opentripplanner/framework/model/Cost.java b/application/src/main/java/org/opentripplanner/framework/model/Cost.java similarity index 95% rename from src/main/java/org/opentripplanner/framework/model/Cost.java rename to application/src/main/java/org/opentripplanner/framework/model/Cost.java index dbd96b81180..47ab4875f5b 100644 --- a/src/main/java/org/opentripplanner/framework/model/Cost.java +++ b/application/src/main/java/org/opentripplanner/framework/model/Cost.java @@ -2,8 +2,8 @@ import java.io.Serializable; import java.time.Duration; -import org.opentripplanner.framework.lang.IntUtils; -import org.opentripplanner.framework.lang.OtpNumberFormat; +import org.opentripplanner.utils.lang.IntUtils; +import org.opentripplanner.utils.lang.OtpNumberFormat; /** * A type safe representation of a cost, like generalized-cost. A cost unit is equivalent of riding diff --git a/src/main/java/org/opentripplanner/framework/model/Grams.java b/application/src/main/java/org/opentripplanner/framework/model/Grams.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/model/Grams.java rename to application/src/main/java/org/opentripplanner/framework/model/Grams.java diff --git a/src/main/java/org/opentripplanner/framework/model/TimeAndCost.java b/application/src/main/java/org/opentripplanner/framework/model/TimeAndCost.java similarity index 89% rename from src/main/java/org/opentripplanner/framework/model/TimeAndCost.java rename to application/src/main/java/org/opentripplanner/framework/model/TimeAndCost.java index e9376dad622..77c568d0b55 100644 --- a/src/main/java/org/opentripplanner/framework/model/TimeAndCost.java +++ b/application/src/main/java/org/opentripplanner/framework/model/TimeAndCost.java @@ -1,7 +1,7 @@ package org.opentripplanner.framework.model; import java.time.Duration; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.utils.time.DurationUtils; /** * Tuple of time(duration) and cost. diff --git a/src/main/java/org/opentripplanner/framework/model/Units.java b/application/src/main/java/org/opentripplanner/framework/model/Units.java similarity index 98% rename from src/main/java/org/opentripplanner/framework/model/Units.java rename to application/src/main/java/org/opentripplanner/framework/model/Units.java index 736846c869f..ab3d77e5703 100644 --- a/src/main/java/org/opentripplanner/framework/model/Units.java +++ b/application/src/main/java/org/opentripplanner/framework/model/Units.java @@ -3,8 +3,8 @@ import static java.lang.Math.abs; import java.util.Locale; -import org.opentripplanner.framework.lang.DoubleUtils; -import org.opentripplanner.framework.lang.IntUtils; +import org.opentripplanner.utils.lang.DoubleUtils; +import org.opentripplanner.utils.lang.IntUtils; /** * This utility can be used to perform sanity checks on common number types. It will also normalize diff --git a/src/main/java/org/opentripplanner/framework/resources/ResourceBundleAdaptor.java b/application/src/main/java/org/opentripplanner/framework/resources/ResourceBundleAdaptor.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/resources/ResourceBundleAdaptor.java rename to application/src/main/java/org/opentripplanner/framework/resources/ResourceBundleAdaptor.java diff --git a/src/main/java/org/opentripplanner/framework/resources/ResourceBundleSingleton.java b/application/src/main/java/org/opentripplanner/framework/resources/ResourceBundleSingleton.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/resources/ResourceBundleSingleton.java rename to application/src/main/java/org/opentripplanner/framework/resources/ResourceBundleSingleton.java diff --git a/src/main/java/org/opentripplanner/framework/retry/OtpRetry.java b/application/src/main/java/org/opentripplanner/framework/retry/OtpRetry.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/retry/OtpRetry.java rename to application/src/main/java/org/opentripplanner/framework/retry/OtpRetry.java diff --git a/src/main/java/org/opentripplanner/framework/retry/OtpRetryBuilder.java b/application/src/main/java/org/opentripplanner/framework/retry/OtpRetryBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/retry/OtpRetryBuilder.java rename to application/src/main/java/org/opentripplanner/framework/retry/OtpRetryBuilder.java diff --git a/src/main/java/org/opentripplanner/framework/retry/OtpRetryException.java b/application/src/main/java/org/opentripplanner/framework/retry/OtpRetryException.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/retry/OtpRetryException.java rename to application/src/main/java/org/opentripplanner/framework/retry/OtpRetryException.java diff --git a/src/main/java/org/opentripplanner/framework/time/ZoneIdFallback.java b/application/src/main/java/org/opentripplanner/framework/time/ZoneIdFallback.java similarity index 95% rename from src/main/java/org/opentripplanner/framework/time/ZoneIdFallback.java rename to application/src/main/java/org/opentripplanner/framework/time/ZoneIdFallback.java index 2d43216e4b2..b645dbe88f4 100644 --- a/src/main/java/org/opentripplanner/framework/time/ZoneIdFallback.java +++ b/application/src/main/java/org/opentripplanner/framework/time/ZoneIdFallback.java @@ -2,7 +2,7 @@ import java.time.ZoneId; import javax.annotation.Nullable; -import org.opentripplanner.framework.logging.Throttle; +import org.opentripplanner.utils.logging.Throttle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/framework/token/Deserializer.java b/application/src/main/java/org/opentripplanner/framework/token/Deserializer.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/token/Deserializer.java rename to application/src/main/java/org/opentripplanner/framework/token/Deserializer.java diff --git a/src/main/java/org/opentripplanner/framework/token/FieldDefinition.java b/application/src/main/java/org/opentripplanner/framework/token/FieldDefinition.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/token/FieldDefinition.java rename to application/src/main/java/org/opentripplanner/framework/token/FieldDefinition.java diff --git a/src/main/java/org/opentripplanner/framework/token/Serializer.java b/application/src/main/java/org/opentripplanner/framework/token/Serializer.java similarity index 95% rename from src/main/java/org/opentripplanner/framework/token/Serializer.java rename to application/src/main/java/org/opentripplanner/framework/token/Serializer.java index 2d01a0ebf5e..3b48792c06d 100644 --- a/src/main/java/org/opentripplanner/framework/token/Serializer.java +++ b/application/src/main/java/org/opentripplanner/framework/token/Serializer.java @@ -1,7 +1,7 @@ package org.opentripplanner.framework.token; import java.util.Base64; -import org.opentripplanner.framework.text.CharacterEscapeFormatter; +import org.opentripplanner.utils.text.CharacterEscapeFormatter; class Serializer { diff --git a/src/main/java/org/opentripplanner/framework/token/Token.java b/application/src/main/java/org/opentripplanner/framework/token/Token.java similarity index 100% rename from src/main/java/org/opentripplanner/framework/token/Token.java rename to application/src/main/java/org/opentripplanner/framework/token/Token.java diff --git a/src/main/java/org/opentripplanner/framework/token/TokenBuilder.java b/application/src/main/java/org/opentripplanner/framework/token/TokenBuilder.java similarity index 96% rename from src/main/java/org/opentripplanner/framework/token/TokenBuilder.java rename to application/src/main/java/org/opentripplanner/framework/token/TokenBuilder.java index 4061d073a2d..4a6af98319d 100644 --- a/src/main/java/org/opentripplanner/framework/token/TokenBuilder.java +++ b/application/src/main/java/org/opentripplanner/framework/token/TokenBuilder.java @@ -2,7 +2,7 @@ import java.time.Duration; import java.time.Instant; -import org.opentripplanner.framework.lang.ObjectUtils; +import org.opentripplanner.utils.lang.ObjectUtils; /** * This class is used to create a {@link Token} before encoding it. diff --git a/src/main/java/org/opentripplanner/framework/token/TokenDefinition.java b/application/src/main/java/org/opentripplanner/framework/token/TokenDefinition.java similarity index 97% rename from src/main/java/org/opentripplanner/framework/token/TokenDefinition.java rename to application/src/main/java/org/opentripplanner/framework/token/TokenDefinition.java index d4ac7a61aec..e8e44f0f293 100644 --- a/src/main/java/org/opentripplanner/framework/token/TokenDefinition.java +++ b/application/src/main/java/org/opentripplanner/framework/token/TokenDefinition.java @@ -4,7 +4,7 @@ import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A token definition is an ordered list of fields. A field has a name and a type. The diff --git a/src/main/java/org/opentripplanner/framework/token/TokenDefinitionBuilder.java b/application/src/main/java/org/opentripplanner/framework/token/TokenDefinitionBuilder.java similarity index 96% rename from src/main/java/org/opentripplanner/framework/token/TokenDefinitionBuilder.java rename to application/src/main/java/org/opentripplanner/framework/token/TokenDefinitionBuilder.java index 06a935c7b47..6fb9f500e88 100644 --- a/src/main/java/org/opentripplanner/framework/token/TokenDefinitionBuilder.java +++ b/application/src/main/java/org/opentripplanner/framework/token/TokenDefinitionBuilder.java @@ -2,8 +2,8 @@ import java.util.ArrayList; import java.util.List; -import org.opentripplanner.framework.collection.ListUtils; -import org.opentripplanner.framework.lang.IntUtils; +import org.opentripplanner.utils.collection.ListUtils; +import org.opentripplanner.utils.lang.IntUtils; public class TokenDefinitionBuilder { diff --git a/src/main/java/org/opentripplanner/framework/token/TokenFormatterConfiguration.java b/application/src/main/java/org/opentripplanner/framework/token/TokenFormatterConfiguration.java similarity index 91% rename from src/main/java/org/opentripplanner/framework/token/TokenFormatterConfiguration.java rename to application/src/main/java/org/opentripplanner/framework/token/TokenFormatterConfiguration.java index 3945014dad5..16f71d7475c 100644 --- a/src/main/java/org/opentripplanner/framework/token/TokenFormatterConfiguration.java +++ b/application/src/main/java/org/opentripplanner/framework/token/TokenFormatterConfiguration.java @@ -1,6 +1,6 @@ package org.opentripplanner.framework.token; -import org.opentripplanner.framework.text.CharacterEscapeFormatter; +import org.opentripplanner.utils.text.CharacterEscapeFormatter; class TokenFormatterConfiguration { diff --git a/src/main/java/org/opentripplanner/framework/token/TokenSchema.java b/application/src/main/java/org/opentripplanner/framework/token/TokenSchema.java similarity index 98% rename from src/main/java/org/opentripplanner/framework/token/TokenSchema.java rename to application/src/main/java/org/opentripplanner/framework/token/TokenSchema.java index 7ac3aa63c9f..35bb836251b 100644 --- a/src/main/java/org/opentripplanner/framework/token/TokenSchema.java +++ b/application/src/main/java/org/opentripplanner/framework/token/TokenSchema.java @@ -3,7 +3,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A token schema contains a set of token definitions, one for each version. This is diff --git a/src/main/java/org/opentripplanner/framework/token/TokenType.java b/application/src/main/java/org/opentripplanner/framework/token/TokenType.java similarity index 96% rename from src/main/java/org/opentripplanner/framework/token/TokenType.java rename to application/src/main/java/org/opentripplanner/framework/token/TokenType.java index aea39949b0e..b60d80f3406 100644 --- a/src/main/java/org/opentripplanner/framework/token/TokenType.java +++ b/application/src/main/java/org/opentripplanner/framework/token/TokenType.java @@ -3,7 +3,7 @@ import java.time.Duration; import java.time.Instant; import javax.annotation.Nullable; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.utils.time.DurationUtils; /** * List of types we can store in a token. diff --git a/src/main/java/org/opentripplanner/framework/token/package.md b/application/src/main/java/org/opentripplanner/framework/token/package.md similarity index 100% rename from src/main/java/org/opentripplanner/framework/token/package.md rename to application/src/main/java/org/opentripplanner/framework/token/package.md diff --git a/src/main/java/org/opentripplanner/graph_builder/ConfiguredDataSource.java b/application/src/main/java/org/opentripplanner/graph_builder/ConfiguredDataSource.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/ConfiguredDataSource.java rename to application/src/main/java/org/opentripplanner/graph_builder/ConfiguredDataSource.java diff --git a/src/main/java/org/opentripplanner/graph_builder/GraphBuilder.java b/application/src/main/java/org/opentripplanner/graph_builder/GraphBuilder.java similarity index 84% rename from src/main/java/org/opentripplanner/graph_builder/GraphBuilder.java rename to application/src/main/java/org/opentripplanner/graph_builder/GraphBuilder.java index 3c1408089a4..0b071b64728 100644 --- a/src/main/java/org/opentripplanner/graph_builder/GraphBuilder.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/GraphBuilder.java @@ -8,23 +8,23 @@ import java.time.Duration; import java.util.ArrayList; import java.util.List; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.ext.emissions.EmissionsDataModel; import org.opentripplanner.ext.stopconsolidation.StopConsolidationRepository; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.application.OtpAppException; -import org.opentripplanner.framework.lang.OtpNumberFormat; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issue.api.DataImportIssueSummary; import org.opentripplanner.graph_builder.model.GraphBuilderModule; import org.opentripplanner.graph_builder.module.configure.DaggerGraphBuilderFactory; import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; import org.opentripplanner.service.worldenvelope.WorldEnvelopeRepository; import org.opentripplanner.standalone.config.BuildConfig; import org.opentripplanner.street.model.StreetLimitationParameters; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; +import org.opentripplanner.utils.lang.OtpNumberFormat; +import org.opentripplanner.utils.time.DurationUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,19 +38,19 @@ public class GraphBuilder implements Runnable { private final List graphBuilderModules = new ArrayList<>(); private final Graph graph; - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; private final DataImportIssueStore issueStore; private boolean hasTransitData = false; @Inject public GraphBuilder( - @Nonnull Graph baseGraph, - @Nonnull TransitModel transitModel, - @Nonnull DataImportIssueStore issueStore + Graph baseGraph, + TimetableRepository timetableRepository, + DataImportIssueStore issueStore ) { this.graph = baseGraph; - this.transitModel = transitModel; + this.timetableRepository = timetableRepository; this.issueStore = issueStore; } @@ -62,8 +62,9 @@ public static GraphBuilder create( BuildConfig config, GraphBuilderDataSources dataSources, Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, WorldEnvelopeRepository worldEnvelopeRepository, + VehicleParkingRepository vehicleParkingService, @Nullable EmissionsDataModel emissionsDataModel, @Nullable StopConsolidationRepository stopConsolidationRepository, StreetLimitationParameters streetLimitationParameters, @@ -75,18 +76,19 @@ public static GraphBuilder create( boolean hasNetex = dataSources.has(NETEX); boolean hasTransitData = hasGtfs || hasNetex; - transitModel.initTimeZone(config.transitModelTimeZone); + timetableRepository.initTimeZone(config.transitModelTimeZone); var builder = DaggerGraphBuilderFactory .builder() .config(config) .graph(graph) - .transitModel(transitModel) + .timetableRepository(timetableRepository) .worldEnvelopeRepository(worldEnvelopeRepository) + .vehicleParkingRepository(vehicleParkingService) .stopConsolidationRepository(stopConsolidationRepository) .streetLimitationParameters(streetLimitationParameters) .dataSources(dataSources) - .timeZoneId(transitModel.getTimeZone()); + .timeZoneId(timetableRepository.getTimeZone()); if (OTPFeature.Co2Emissions.isOn()) { builder.emissionsDataModel(emissionsDataModel); @@ -119,7 +121,7 @@ public static GraphBuilder create( graphBuilder.addModule(factory.tripPatternNamer()); } - if (hasTransitData && transitModel.getAgencyTimeZones().size() > 1) { + if (hasTransitData && timetableRepository.getAgencyTimeZones().size() > 1) { graphBuilder.addModule(factory.timeZoneAdjusterModule()); } @@ -167,6 +169,8 @@ public static GraphBuilder create( graphBuilder.addModule(factory.emissionsModule()); } + graphBuilder.addModuleOptional(factory.routeToCentroidStationIdValidator()); + if (config.dataImportReport) { graphBuilder.addModule(factory.dataImportIssueReporter()); } @@ -197,7 +201,7 @@ public void run() { new DataImportIssueSummary(issueStore.listIssues()).logSummary(); // Log before we validate, this way we have more information if the validation fails - logGraphBuilderCompleteStatus(startTime, graph, transitModel); + logGraphBuilderCompleteStatus(startTime, graph, timetableRepository); validate(); } @@ -206,7 +210,7 @@ private void addModule(GraphBuilderModule module) { graphBuilderModules.add(module); } - private void addModuleOptional(GraphBuilderModule module) { + private void addModuleOptional(@Nullable GraphBuilderModule module) { if (module != null) { graphBuilderModules.add(module); } @@ -226,7 +230,7 @@ public DataImportIssueSummary issueSummary() { * configuration, for example, then this function will throw a {@link OtpAppException}. */ private void validate() { - if (hasTransitData() && !transitModel.hasTransit()) { + if (hasTransitData() && !timetableRepository.hasTransit()) { throw new OtpAppException( "The provided transit data have no trips within the configured transit service period. " + "There is something wrong with your data - see the log above. Another possibility is that the " + @@ -238,14 +242,14 @@ private void validate() { private static void logGraphBuilderCompleteStatus( long startTime, Graph graph, - TransitModel transitModel + TimetableRepository timetableRepository ) { long endTime = System.currentTimeMillis(); String time = DurationUtils.durationToStr(Duration.ofMillis(endTime - startTime)); var f = new OtpNumberFormat(); - var nStops = f.formatNumber(transitModel.getStopModel().stopIndexSize()); - var nPatterns = f.formatNumber(transitModel.getAllTripPatterns().size()); - var nTransfers = f.formatNumber(transitModel.getTransferService().listAll().size()); + var nStops = f.formatNumber(timetableRepository.getSiteRepository().stopIndexSize()); + var nPatterns = f.formatNumber(timetableRepository.getAllTripPatterns().size()); + var nTransfers = f.formatNumber(timetableRepository.getTransferService().listAll().size()); var nVertices = f.formatNumber(graph.countVertices()); var nEdges = f.formatNumber(graph.countEdges()); diff --git a/src/main/java/org/opentripplanner/graph_builder/GraphBuilderDataSources.java b/application/src/main/java/org/opentripplanner/graph_builder/GraphBuilderDataSources.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/GraphBuilderDataSources.java rename to application/src/main/java/org/opentripplanner/graph_builder/GraphBuilderDataSources.java diff --git a/src/main/java/org/opentripplanner/graph_builder/GraphStats.java b/application/src/main/java/org/opentripplanner/graph_builder/GraphStats.java similarity index 96% rename from src/main/java/org/opentripplanner/graph_builder/GraphStats.java rename to application/src/main/java/org/opentripplanner/graph_builder/GraphStats.java index 718622a142d..199146667ed 100644 --- a/src/main/java/org/opentripplanner/graph_builder/GraphStats.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/GraphStats.java @@ -27,7 +27,7 @@ import org.opentripplanner.street.model.vertex.TransitStopVertex; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.transit.model.network.TripPattern; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,7 +60,7 @@ public class GraphStats { private Graph graph; - private TransitModel transitModel; + private TimetableRepository timetableRepository; private CsvWriter writer; @@ -97,7 +97,7 @@ private void run() { File graphFile = new File(graphPath); SerializedGraphObject serializedGraphObject = SerializedGraphObject.load(graphFile); graph = serializedGraphObject.graph; - transitModel = serializedGraphObject.transitModel; + timetableRepository = serializedGraphObject.timetableRepository; /* open output stream (same for all commands) */ if (outPath != null) { @@ -220,7 +220,7 @@ public void run() { "empiricalDistTrips", } ); - Collection patterns = transitModel.getAllTripPatterns(); + Collection patterns = timetableRepository.getAllTripPatterns(); Multiset counts = TreeMultiset.create(); int nPatterns = patterns.size(); LOG.info("total number of patterns is: {}", nPatterns); diff --git a/src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssue.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssue.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssue.java rename to application/src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssue.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueStore.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueStore.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueStore.java rename to application/src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueStore.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummary.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummary.java similarity index 98% rename from src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummary.java rename to application/src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummary.java index ba1e6610a30..da3110d0ce7 100644 --- a/src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummary.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummary.java @@ -8,7 +8,6 @@ import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -74,7 +73,6 @@ public void logSummary() { .forEach(issueType -> ISSUE_LOG.info(String.format(FMT, issueType, summary.get(issueType)))); } - @Nonnull public Map asMap() { return summary; } diff --git a/src/main/java/org/opentripplanner/graph_builder/issue/api/Issue.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/api/Issue.java similarity index 94% rename from src/main/java/org/opentripplanner/graph_builder/issue/api/Issue.java rename to application/src/main/java/org/opentripplanner/graph_builder/issue/api/Issue.java index 24beb48e845..cb50320345c 100644 --- a/src/main/java/org/opentripplanner/graph_builder/issue/api/Issue.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issue/api/Issue.java @@ -1,6 +1,6 @@ package org.opentripplanner.graph_builder.issue.api; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Generic issue type, which can be used to create issues. diff --git a/src/main/java/org/opentripplanner/graph_builder/issue/api/IssueWithSource.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/api/IssueWithSource.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issue/api/IssueWithSource.java rename to application/src/main/java/org/opentripplanner/graph_builder/issue/api/IssueWithSource.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issue/api/NoopDataImportIssueStore.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/api/NoopDataImportIssueStore.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issue/api/NoopDataImportIssueStore.java rename to application/src/main/java/org/opentripplanner/graph_builder/issue/api/NoopDataImportIssueStore.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issue/api/OsmUrlGenerator.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/api/OsmUrlGenerator.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issue/api/OsmUrlGenerator.java rename to application/src/main/java/org/opentripplanner/graph_builder/issue/api/OsmUrlGenerator.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issue/report/Bucket.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/report/Bucket.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issue/report/Bucket.java rename to application/src/main/java/org/opentripplanner/graph_builder/issue/report/Bucket.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issue/report/BucketKey.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/report/BucketKey.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issue/report/BucketKey.java rename to application/src/main/java/org/opentripplanner/graph_builder/issue/report/BucketKey.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issue/report/DataImportIssueReporter.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/report/DataImportIssueReporter.java similarity index 98% rename from src/main/java/org/opentripplanner/graph_builder/issue/report/DataImportIssueReporter.java rename to application/src/main/java/org/opentripplanner/graph_builder/issue/report/DataImportIssueReporter.java index 5d209f26ac9..28daceccbba 100644 --- a/src/main/java/org/opentripplanner/graph_builder/issue/report/DataImportIssueReporter.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issue/report/DataImportIssueReporter.java @@ -8,10 +8,10 @@ import java.util.Map; import java.util.stream.Collectors; import org.opentripplanner.datastore.api.CompositeDataSource; -import org.opentripplanner.framework.logging.ProgressTracker; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.model.GraphBuilderModule; +import org.opentripplanner.utils.logging.ProgressTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/graph_builder/issue/report/GeoJsonWriter.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/report/GeoJsonWriter.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issue/report/GeoJsonWriter.java rename to application/src/main/java/org/opentripplanner/graph_builder/issue/report/GeoJsonWriter.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issue/report/HTMLWriter.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/report/HTMLWriter.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issue/report/HTMLWriter.java rename to application/src/main/java/org/opentripplanner/graph_builder/issue/report/HTMLWriter.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issue/report/IssueColors.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/report/IssueColors.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issue/report/IssueColors.java rename to application/src/main/java/org/opentripplanner/graph_builder/issue/report/IssueColors.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issue/service/DefaultDataImportIssueStore.java b/application/src/main/java/org/opentripplanner/graph_builder/issue/service/DefaultDataImportIssueStore.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issue/service/DefaultDataImportIssueStore.java rename to application/src/main/java/org/opentripplanner/graph_builder/issue/service/DefaultDataImportIssueStore.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeDistanceTraveled.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeDistanceTraveled.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeDistanceTraveled.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeDistanceTraveled.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeGeometry.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeGeometry.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeGeometry.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeGeometry.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeGeometryCaught.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeGeometryCaught.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeGeometryCaught.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/BogusShapeGeometryCaught.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/DisconnectedOsmNode.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/DisconnectedOsmNode.java similarity index 83% rename from src/main/java/org/opentripplanner/graph_builder/issues/DisconnectedOsmNode.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/DisconnectedOsmNode.java index f1c341a46fe..2996bec2d9d 100644 --- a/src/main/java/org/opentripplanner/graph_builder/issues/DisconnectedOsmNode.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issues/DisconnectedOsmNode.java @@ -3,10 +3,10 @@ import org.locationtech.jts.geom.Geometry; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; -import org.opentripplanner.openstreetmap.model.OSMNode; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmNode; +import org.opentripplanner.osm.model.OsmWithTags; -public record DisconnectedOsmNode(OSMNode node, OSMWithTags way, OSMWithTags area) +public record DisconnectedOsmNode(OsmNode node, OsmWithTags way, OsmWithTags area) implements DataImportIssue { private static final String FMT = "Node %s in way %s is coincident but disconnected with area %s"; private static final String HTMLFMT = diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/ElevationFlattened.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/ElevationFlattened.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/ElevationFlattened.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/ElevationFlattened.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/ElevationProfileFailure.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/ElevationProfileFailure.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/ElevationProfileFailure.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/ElevationProfileFailure.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/GraphConnectivity.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/GraphConnectivity.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/GraphConnectivity.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/GraphConnectivity.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/Graphwide.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/Graphwide.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/Graphwide.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/Graphwide.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/HopSpeedFast.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/HopSpeedFast.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/HopSpeedFast.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/HopSpeedFast.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/HopSpeedSlow.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/HopSpeedSlow.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/HopSpeedSlow.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/HopSpeedSlow.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/HopZeroDistance.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/HopZeroDistance.java similarity index 93% rename from src/main/java/org/opentripplanner/graph_builder/issues/HopZeroDistance.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/HopZeroDistance.java index 3ea11b25901..cf11f011d00 100644 --- a/src/main/java/org/opentripplanner/graph_builder/issues/HopZeroDistance.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issues/HopZeroDistance.java @@ -1,10 +1,10 @@ package org.opentripplanner.graph_builder.issues; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.utils.time.DurationUtils; public record HopZeroDistance( int sec, diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/HopZeroTime.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/HopZeroTime.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/HopZeroTime.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/HopZeroTime.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/IgnoredGtfsTransfer.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/IgnoredGtfsTransfer.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/IgnoredGtfsTransfer.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/IgnoredGtfsTransfer.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/InterliningTeleport.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/InterliningTeleport.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/InterliningTeleport.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/InterliningTeleport.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/InvalidGtfsTransfer.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/InvalidGtfsTransfer.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/InvalidGtfsTransfer.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/InvalidGtfsTransfer.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/InvalidOsmGeometry.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/InvalidOsmGeometry.java similarity index 80% rename from src/main/java/org/opentripplanner/graph_builder/issues/InvalidOsmGeometry.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/InvalidOsmGeometry.java index 7f84453a6d8..2f3eca39aeb 100644 --- a/src/main/java/org/opentripplanner/graph_builder/issues/InvalidOsmGeometry.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issues/InvalidOsmGeometry.java @@ -1,9 +1,9 @@ package org.opentripplanner.graph_builder.issues; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; -public record InvalidOsmGeometry(OSMWithTags entity) implements DataImportIssue { +public record InvalidOsmGeometry(OsmWithTags entity) implements DataImportIssue { private static final String FMT = "Invalid OSM geometry %s"; private static final String HTMLFMT = "Invalid OSM geometry '%s'"; diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/InvalidVehicleParkingCapacity.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/InvalidVehicleParkingCapacity.java similarity index 84% rename from src/main/java/org/opentripplanner/graph_builder/issues/InvalidVehicleParkingCapacity.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/InvalidVehicleParkingCapacity.java index c4f5498a769..1e31462178a 100644 --- a/src/main/java/org/opentripplanner/graph_builder/issues/InvalidVehicleParkingCapacity.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issues/InvalidVehicleParkingCapacity.java @@ -1,9 +1,9 @@ package org.opentripplanner.graph_builder.issues; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; -public record InvalidVehicleParkingCapacity(OSMWithTags entity, String capacityValue) +public record InvalidVehicleParkingCapacity(OsmWithTags entity, String capacityValue) implements DataImportIssue { private static final String FMT = "Capacity for osm node %d is not a number: '%s'; it's replaced with '-1' (unknown)."; diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/IsolatedStop.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/IsolatedStop.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/IsolatedStop.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/IsolatedStop.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/LevelAmbiguous.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/LevelAmbiguous.java similarity index 87% rename from src/main/java/org/opentripplanner/graph_builder/issues/LevelAmbiguous.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/LevelAmbiguous.java index 650c8b299ac..a448540b2c5 100644 --- a/src/main/java/org/opentripplanner/graph_builder/issues/LevelAmbiguous.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issues/LevelAmbiguous.java @@ -1,9 +1,9 @@ package org.opentripplanner.graph_builder.issues; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; -public record LevelAmbiguous(String layerName, OSMWithTags entity) implements DataImportIssue { +public record LevelAmbiguous(String layerName, OsmWithTags entity) implements DataImportIssue { private static final String FMT = "Could not infer floor number for layer called '%s' at %s. " + "Vertical movement will still be possible, but elevator cost might be incorrect. " + diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/MissingProjectionInServiceLink.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/MissingProjectionInServiceLink.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/MissingProjectionInServiceLink.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/MissingProjectionInServiceLink.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/MissingShapeGeometry.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/MissingShapeGeometry.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/MissingShapeGeometry.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/MissingShapeGeometry.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/NegativeDwellTime.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/NegativeDwellTime.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/NegativeDwellTime.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/NegativeDwellTime.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/NegativeHopTime.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/NegativeHopTime.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/NegativeHopTime.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/NegativeHopTime.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/NoFutureDates.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/NoFutureDates.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/NoFutureDates.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/NoFutureDates.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideEntranceRemoved.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideEntranceRemoved.java similarity index 91% rename from src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideEntranceRemoved.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideEntranceRemoved.java index 122f99ba488..0170d554358 100644 --- a/src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideEntranceRemoved.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideEntranceRemoved.java @@ -3,7 +3,7 @@ import org.locationtech.jts.geom.Geometry; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingEntrance; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingEntrance; public record ParkAndRideEntranceRemoved(VehicleParkingEntrance vehicleParkingEntrance) implements DataImportIssue { diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideUnlinked.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideUnlinked.java similarity index 84% rename from src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideUnlinked.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideUnlinked.java index 7da16a2891f..4e8ccd14318 100644 --- a/src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideUnlinked.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issues/ParkAndRideUnlinked.java @@ -1,9 +1,9 @@ package org.opentripplanner.graph_builder.issues; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; -public record ParkAndRideUnlinked(String name, OSMWithTags entity) implements DataImportIssue { +public record ParkAndRideUnlinked(String name, OsmWithTags entity) implements DataImportIssue { private static final String FMT = "Park and ride '%s' (%s) not linked to any streets in OSM; entrance might not be placed correctly."; private static final String HTMLFMT = diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/RepeatedStops.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/RepeatedStops.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/RepeatedStops.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/RepeatedStops.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/ShapeGeometryTooFar.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/ShapeGeometryTooFar.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/ShapeGeometryTooFar.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/ShapeGeometryTooFar.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/StopNotLinkedForTransfers.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/StopNotLinkedForTransfers.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/StopNotLinkedForTransfers.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/StopNotLinkedForTransfers.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/TripDegenerate.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/TripDegenerate.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/TripDegenerate.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/TripDegenerate.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/TripUndefinedService.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/TripUndefinedService.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/TripUndefinedService.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/TripUndefinedService.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/TurnRestrictionBad.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/TurnRestrictionBad.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/TurnRestrictionBad.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/TurnRestrictionBad.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/TurnRestrictionException.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/TurnRestrictionException.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/issues/TurnRestrictionException.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/TurnRestrictionException.java diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/TurnRestrictionUnknown.java b/application/src/main/java/org/opentripplanner/graph_builder/issues/TurnRestrictionUnknown.java similarity index 82% rename from src/main/java/org/opentripplanner/graph_builder/issues/TurnRestrictionUnknown.java rename to application/src/main/java/org/opentripplanner/graph_builder/issues/TurnRestrictionUnknown.java index 36e913cba6a..23e20638d86 100644 --- a/src/main/java/org/opentripplanner/graph_builder/issues/TurnRestrictionUnknown.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/issues/TurnRestrictionUnknown.java @@ -1,9 +1,9 @@ package org.opentripplanner.graph_builder.issues; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; -public record TurnRestrictionUnknown(OSMWithTags entity, String tagval) implements DataImportIssue { +public record TurnRestrictionUnknown(OsmWithTags entity, String tagval) implements DataImportIssue { private static final String FMT = "Invalid turn restriction tag %s in turn restriction %d"; private static final String HTMLFMT = "Invalid turn restriction tag %s in '%s'"; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/issues/package-info.md b/application/src/main/java/org/opentripplanner/graph_builder/issues/package-info.md new file mode 100644 index 00000000000..424605d5240 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/graph_builder/issues/package-info.md @@ -0,0 +1,6 @@ +# Graph building issues + +Graph builder data import issues represent errors or exceptional conditions encountered during +the graph building process. They contain descriptive messages and potentially references to the +objects in the graph that they annotate which facilitate visualization and cataloging/mapping of +problems. diff --git a/src/main/java/org/opentripplanner/graph_builder/model/DataSourceConfig.java b/application/src/main/java/org/opentripplanner/graph_builder/model/DataSourceConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/model/DataSourceConfig.java rename to application/src/main/java/org/opentripplanner/graph_builder/model/DataSourceConfig.java diff --git a/src/main/java/org/opentripplanner/graph_builder/model/GraphBuilderModule.java b/application/src/main/java/org/opentripplanner/graph_builder/model/GraphBuilderModule.java similarity index 92% rename from src/main/java/org/opentripplanner/graph_builder/model/GraphBuilderModule.java rename to application/src/main/java/org/opentripplanner/graph_builder/model/GraphBuilderModule.java index e4e67a0f3c1..0a551cff1c9 100644 --- a/src/main/java/org/opentripplanner/graph_builder/model/GraphBuilderModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/model/GraphBuilderModule.java @@ -4,7 +4,7 @@ public interface GraphBuilderModule { /** * Process whatever inputs were supplied to this module and update the model objects(graph, - * transitModel and issueStore). + * timetableRepository and issueStore). */ void buildGraph(); diff --git a/src/main/java/org/opentripplanner/graph_builder/module/AddTransitModelEntitiesToGraph.java b/application/src/main/java/org/opentripplanner/graph_builder/module/AddTransitEntitiesToGraph.java similarity index 83% rename from src/main/java/org/opentripplanner/graph_builder/module/AddTransitModelEntitiesToGraph.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/AddTransitEntitiesToGraph.java index a53730b104c..1d335d7ff4f 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/AddTransitModelEntitiesToGraph.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/AddTransitEntitiesToGraph.java @@ -39,15 +39,16 @@ import org.opentripplanner.transit.model.site.PathwayMode; import org.opentripplanner.transit.model.site.PathwayNode; import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.model.site.StationElement; import org.opentripplanner.transit.model.site.StopLocation; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class AddTransitModelEntitiesToGraph { +public class AddTransitEntitiesToGraph { - private static final Logger LOG = LoggerFactory.getLogger(AddTransitModelEntitiesToGraph.class); + private static final Logger LOG = LoggerFactory.getLogger(AddTransitEntitiesToGraph.class); private final OtpTransitService otpTransitService; @@ -61,7 +62,7 @@ public class AddTransitModelEntitiesToGraph { * @param subwayAccessTime a positive integer for the extra time to access a subway platform, if * negative the default value of zero is used. */ - private AddTransitModelEntitiesToGraph( + private AddTransitEntitiesToGraph( OtpTransitService otpTransitService, int subwayAccessTime, Graph graph @@ -75,43 +76,44 @@ public static void addToGraph( OtpTransitService otpTransitService, int subwayAccessTime, Graph graph, - TransitModel transitModel + TimetableRepository timetableRepository ) { - new AddTransitModelEntitiesToGraph(otpTransitService, subwayAccessTime, graph) - .applyToGraph(transitModel); + new AddTransitEntitiesToGraph(otpTransitService, subwayAccessTime, graph) + .applyToGraph(timetableRepository); } - private void applyToGraph(TransitModel transitModel) { - transitModel.mergeStopModels(otpTransitService.stopModel()); + private void applyToGraph(TimetableRepository timetableRepository) { + timetableRepository.mergeSiteRepositories(otpTransitService.siteRepository()); - addStopsToGraphAndGenerateStopVertexes(transitModel); + addStopsToGraphAndGenerateStopVertexes(timetableRepository); addEntrancesToGraph(); + addStationCentroidsToGraph(); addPathwayNodesToGraph(); addBoardingAreasToGraph(); // Although pathways are loaded from GTFS they are street data, so we will put them in the // street graph. createPathwayEdgesAndAddThemToGraph(); - addFeedInfoToGraph(transitModel); - addAgenciesToGraph(transitModel); - addServicesToTransitModel(transitModel); - addTripPatternsToTransitModel(transitModel); + addFeedInfoToGraph(timetableRepository); + addAgenciesToGraph(timetableRepository); + addServicesToTimetableRepository(timetableRepository); + addTripPatternsToTimetableRepository(timetableRepository); /* Interpret the transfers explicitly defined in transfers.txt. */ - addTransfersToGraph(transitModel); + addTransfersToGraph(timetableRepository); if (OTPFeature.FlexRouting.isOn()) { - addFlexTripsToGraph(transitModel); + addFlexTripsToGraph(timetableRepository); } } - private void addStopsToGraphAndGenerateStopVertexes(TransitModel transitModel) { + private void addStopsToGraphAndGenerateStopVertexes(TimetableRepository timetableRepository) { // Compute the set of modes for each stop based on all the TripPatterns it is part of Map> stopModeMap = new HashMap<>(); for (TripPattern pattern : otpTransitService.getTripPatterns()) { TransitMode mode = pattern.getMode(); - transitModel.addTransitMode(mode); + timetableRepository.addTransitMode(mode); for (var stop : pattern.getStops()) { Set set = stopModeMap.computeIfAbsent(stop, s -> new HashSet<>()); set.add(mode); @@ -120,7 +122,7 @@ private void addStopsToGraphAndGenerateStopVertexes(TransitModel transitModel) { // Add a vertex representing the stop. // It is now possible for these vertices to not be connected to any edges. - for (RegularStop stop : otpTransitService.stopModel().listRegularStops()) { + for (RegularStop stop : otpTransitService.siteRepository().listRegularStops()) { Set modes = stopModeMap.get(stop); TransitStopVertex stopVertex = vertexFactory.transitStop( TransitStopVertex.of().withStop(stop).withModes(modes) @@ -142,6 +144,14 @@ private void addEntrancesToGraph() { } } + private void addStationCentroidsToGraph() { + for (Station station : otpTransitService.siteRepository().listStations()) { + if (station.shouldRouteToCentroid()) { + vertexFactory.stationCentroid(station); + } + } + } + private void addPathwayNodesToGraph() { for (PathwayNode node : otpTransitService.getAllPathwayNodes()) { TransitPathwayNodeVertex nodeVertex = vertexFactory.transitPathwayNode(node); @@ -325,45 +335,47 @@ private StopLevel getStopLevel(StationElementVertex vertex) { : new StopLevel(fromStation.getName(), null); } - private void addFeedInfoToGraph(TransitModel transitModel) { + private void addFeedInfoToGraph(TimetableRepository timetableRepository) { for (FeedInfo info : otpTransitService.getAllFeedInfos()) { - transitModel.addFeedInfo(info); + timetableRepository.addFeedInfo(info); } } - private void addAgenciesToGraph(TransitModel transitModel) { + private void addAgenciesToGraph(TimetableRepository timetableRepository) { for (Agency agency : otpTransitService.getAllAgencies()) { - transitModel.addAgency(agency); + timetableRepository.addAgency(agency); } } - private void addTransfersToGraph(TransitModel transitModel) { - transitModel.getTransferService().addAll(otpTransitService.getAllTransfers()); + private void addTransfersToGraph(TimetableRepository timetableRepository) { + timetableRepository.getTransferService().addAll(otpTransitService.getAllTransfers()); } - private void addServicesToTransitModel(TransitModel transitModel) { + private void addServicesToTimetableRepository(TimetableRepository timetableRepository) { /* Assign 0-based numeric codes to all GTFS service IDs. */ for (FeedScopedId serviceId : otpTransitService.getAllServiceIds()) { - transitModel.getServiceCodes().put(serviceId, transitModel.getServiceCodes().size()); + timetableRepository + .getServiceCodes() + .put(serviceId, timetableRepository.getServiceCodes().size()); } } - private void addTripPatternsToTransitModel(TransitModel transitModel) { + private void addTripPatternsToTimetableRepository(TimetableRepository timetableRepository) { Collection tripPatterns = otpTransitService.getTripPatterns(); /* Loop over all new TripPatterns setting the service codes. */ for (TripPattern tripPattern : tripPatterns) { // TODO this could be more elegant - tripPattern.getScheduledTimetable().setServiceCodes(transitModel.getServiceCodes()); + tripPattern.getScheduledTimetable().setServiceCodes(timetableRepository.getServiceCodes()); // Store the tripPattern in the Graph so it will be serialized and usable in routing. - transitModel.addTripPattern(tripPattern.getId(), tripPattern); + timetableRepository.addTripPattern(tripPattern.getId(), tripPattern); } } - private void addFlexTripsToGraph(TransitModel transitModel) { + private void addFlexTripsToGraph(TimetableRepository timetableRepository) { for (FlexTrip flexTrip : otpTransitService.getAllFlexTrips()) { - transitModel.addFlexTrip(flexTrip.getId(), flexTrip); + timetableRepository.addFlexTrip(flexTrip.getId(), flexTrip); } } diff --git a/src/main/java/org/opentripplanner/graph_builder/module/DirectTransferGenerator.java b/application/src/main/java/org/opentripplanner/graph_builder/module/DirectTransferGenerator.java similarity index 88% rename from src/main/java/org/opentripplanner/graph_builder/module/DirectTransferGenerator.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/DirectTransferGenerator.java index 3137b66070f..c0deb932418 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/DirectTransferGenerator.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/DirectTransferGenerator.java @@ -8,7 +8,6 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.framework.logging.ProgressTracker; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issues.StopNotLinkedForTransfers; import org.opentripplanner.graph_builder.model.GraphBuilderModule; @@ -18,16 +17,15 @@ import org.opentripplanner.graph_builder.module.nearbystops.StreetNearbyStopFinder; import org.opentripplanner.model.PathTransfer; import org.opentripplanner.routing.api.request.RouteRequest; -import org.opentripplanner.routing.api.request.request.StreetRequest; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.graphfinder.NearbyStop; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.vertex.TransitStopVertex; -import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; +import org.opentripplanner.utils.logging.ProgressTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,18 +45,18 @@ public class DirectTransferGenerator implements GraphBuilderModule { private final List transferRequests; private final Graph graph; - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; private final DataImportIssueStore issueStore; public DirectTransferGenerator( Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, DataImportIssueStore issueStore, Duration radiusByDuration, List transferRequests ) { this.graph = graph; - this.transitModel = transitModel; + this.timetableRepository = timetableRepository; this.issueStore = issueStore; this.radiusByDuration = radiusByDuration; this.transferRequests = transferRequests; @@ -67,7 +65,7 @@ public DirectTransferGenerator( @Override public void buildGraph() { /* Initialize transit model index which is needed by the nearby stop finder. */ - transitModel.index(); + timetableRepository.index(); /* The linker will use streets if they are available, or straight-line distance otherwise. */ NearbyStopFinder nearbyStopFinder = createNearbyStopFinder(); @@ -104,8 +102,7 @@ public void buildGraph() { LOG.debug("Linking stop '{}' {}", stop, ts0); for (RouteRequest transferProfile : transferRequests) { - for (NearbyStop sd : findNearbyStops( - nearbyStopFinder, + for (NearbyStop sd : nearbyStopFinder.findNearbyStops( ts0, transferProfile, transferProfile.journey().transfer(), @@ -126,8 +123,7 @@ public void buildGraph() { if (OTPFeature.FlexRouting.isOn()) { // This code is for finding transfers from AreaStops to Stops, transfers // from Stops to AreaStops and between Stops are already covered above. - for (NearbyStop sd : findNearbyStops( - nearbyStopFinder, + for (NearbyStop sd : nearbyStopFinder.findNearbyStops( ts0, transferProfile, transferProfile.journey().transfer(), @@ -168,7 +164,7 @@ public void buildGraph() { progress.step(m -> LOG.info(m)); }); - transitModel.addAllTransfersByStops(transfersByStop); + timetableRepository.addAllTransfersByStops(transfersByStop); LOG.info(progress.completeMessage()); LOG.info( @@ -184,7 +180,7 @@ public void buildGraph() { * enabled. */ private NearbyStopFinder createNearbyStopFinder() { - var transitService = new DefaultTransitService(transitModel); + var transitService = new DefaultTransitService(timetableRepository); NearbyStopFinder finder; if (!graph.hasStreets) { LOG.info( @@ -203,15 +199,5 @@ private NearbyStopFinder createNearbyStopFinder() { } } - private static Iterable findNearbyStops( - NearbyStopFinder nearbyStopFinder, - Vertex vertex, - RouteRequest request, - StreetRequest streetRequest, - boolean reverseDirection - ) { - return nearbyStopFinder.findNearbyStops(vertex, request, streetRequest, reverseDirection); - } - private record TransferKey(StopLocation source, StopLocation target, List edges) {} } diff --git a/src/main/java/org/opentripplanner/graph_builder/module/GraphCoherencyCheckerModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/GraphCoherencyCheckerModule.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/GraphCoherencyCheckerModule.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/GraphCoherencyCheckerModule.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/GtfsFeedId.java b/application/src/main/java/org/opentripplanner/graph_builder/module/GtfsFeedId.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/GtfsFeedId.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/GtfsFeedId.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModule.java similarity index 95% rename from src/main/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModule.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModule.java index 3bb9c3745a8..c4acabefd6c 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModule.java @@ -27,7 +27,7 @@ import org.opentripplanner.street.model.vertex.VertexFactory; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.TraverseModeSet; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,15 +55,15 @@ public class OsmBoardingLocationsModule implements GraphBuilderModule { private final Graph graph; - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; private final VertexFactory vertexFactory; private VertexLinker linker; @Inject - public OsmBoardingLocationsModule(Graph graph, TransitModel transitModel) { + public OsmBoardingLocationsModule(Graph graph, TimetableRepository timetableRepository) { this.graph = graph; - this.transitModel = transitModel; + this.timetableRepository = timetableRepository; this.vertexFactory = new VertexFactory(graph); } @@ -71,7 +71,7 @@ public OsmBoardingLocationsModule(Graph graph, TransitModel transitModel) { public void buildGraph() { LOG.info("Improving boarding locations by checking OSM entities..."); - StreetIndex streetIndex = graph.getStreetIndexSafe(transitModel.getStopModel()); + StreetIndex streetIndex = graph.getStreetIndexSafe(timetableRepository.getSiteRepository()); this.linker = streetIndex.getVertexLinker(); int successes = 0; diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/RouteToCentroidStationIdsValidator.java b/application/src/main/java/org/opentripplanner/graph_builder/module/RouteToCentroidStationIdsValidator.java new file mode 100644 index 00000000000..f7d8664e590 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/RouteToCentroidStationIdsValidator.java @@ -0,0 +1,50 @@ +package org.opentripplanner.graph_builder.module; + +import java.util.Collection; +import java.util.stream.Collectors; +import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; +import org.opentripplanner.graph_builder.model.GraphBuilderModule; +import org.opentripplanner.transit.model.framework.AbstractTransitEntity; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.service.TimetableRepository; + +public class RouteToCentroidStationIdsValidator implements GraphBuilderModule { + + private final DataImportIssueStore issueStore; + private final Collection transitRouteToStationCentroid; + private final TimetableRepository timetableRepository; + + public RouteToCentroidStationIdsValidator( + DataImportIssueStore issueStore, + Collection transitRouteToStationCentroid, + TimetableRepository timetableRepository + ) { + this.issueStore = issueStore; + this.transitRouteToStationCentroid = transitRouteToStationCentroid; + this.timetableRepository = timetableRepository; + } + + private void validate() { + var stationIds = timetableRepository + .getSiteRepository() + .listStations() + .stream() + .map(AbstractTransitEntity::getId) + .collect(Collectors.toSet()); + transitRouteToStationCentroid + .stream() + .filter(id -> !stationIds.contains(id)) + .forEach(id -> + issueStore.add( + "UnknownStationId", + "Config parameter 'transitRouteToStationCentroid' specified a station that does not exist: %s", + id + ) + ); + } + + @Override + public void buildGraph() { + validate(); + } +} diff --git a/src/main/java/org/opentripplanner/graph_builder/module/StreetLinkerModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/StreetLinkerModule.java similarity index 78% rename from src/main/java/org/opentripplanner/graph_builder/module/StreetLinkerModule.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/StreetLinkerModule.java index 48e6e484a0c..83a6f282204 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/StreetLinkerModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/StreetLinkerModule.java @@ -3,32 +3,36 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.function.BiFunction; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.framework.logging.ProgressTracker; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issues.ParkAndRideEntranceRemoved; import org.opentripplanner.graph_builder.model.GraphBuilderModule; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.linking.LinkingDirection; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingHelper; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingHelper; import org.opentripplanner.street.model.edge.Edge; +import org.opentripplanner.street.model.edge.StreetStationCentroidLink; import org.opentripplanner.street.model.edge.StreetTransitEntranceLink; import org.opentripplanner.street.model.edge.StreetTransitStopLink; import org.opentripplanner.street.model.edge.StreetVehicleParkingLink; import org.opentripplanner.street.model.edge.VehicleParkingEdge; +import org.opentripplanner.street.model.vertex.StationCentroidVertex; import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.street.model.vertex.TransitEntranceVertex; import org.opentripplanner.street.model.vertex.TransitStopVertex; import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex; +import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.TraverseModeSet; import org.opentripplanner.transit.model.site.GroupStop; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; +import org.opentripplanner.utils.logging.ProgressTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,31 +49,35 @@ public class StreetLinkerModule implements GraphBuilderModule { private static final TraverseModeSet CAR_ONLY = new TraverseModeSet(TraverseMode.CAR); private static final TraverseModeSet WALK_ONLY = new TraverseModeSet(TraverseMode.WALK); private final Graph graph; - private final TransitModel transitModel; + private final VehicleParkingRepository parkingRepository; + private final TimetableRepository timetableRepository; private final DataImportIssueStore issueStore; private final Boolean addExtraEdgesToAreas; public StreetLinkerModule( Graph graph, - TransitModel transitModel, + VehicleParkingRepository parkingRepository, + TimetableRepository timetableRepository, DataImportIssueStore issueStore, boolean addExtraEdgesToAreas ) { this.graph = graph; - this.transitModel = transitModel; + this.parkingRepository = parkingRepository; + this.timetableRepository = timetableRepository; this.issueStore = issueStore; this.addExtraEdgesToAreas = addExtraEdgesToAreas; } @Override public void buildGraph() { - transitModel.index(); - graph.index(transitModel.getStopModel()); + timetableRepository.index(); + graph.index(timetableRepository.getSiteRepository()); graph.getLinker().setAddExtraEdgesToAreas(this.addExtraEdgesToAreas); if (graph.hasStreets) { - linkTransitStops(graph, transitModel); + linkTransitStops(graph, timetableRepository); linkTransitEntrances(graph); + linkStationCentroids(graph); linkVehicleParks(graph, issueStore); } @@ -77,31 +85,18 @@ public void buildGraph() { graph.calculateConvexHull(); } - public void linkTransitStops(Graph graph, TransitModel transitModel) { + public void linkTransitStops(Graph graph, TimetableRepository timetableRepository) { List vertices = graph.getVerticesOfType(TransitStopVertex.class); var progress = ProgressTracker.track("Linking transit stops to graph", 5000, vertices.size()); LOG.info(progress.startMessage()); Set stopLocationsUsedForFlexTrips = Set.of(); - if (OTPFeature.FlexRouting.isOn()) { - stopLocationsUsedForFlexTrips = - transitModel - .getAllFlexTrips() - .stream() - .flatMap(t -> t.getStops().stream()) - .collect(Collectors.toSet()); - - stopLocationsUsedForFlexTrips.addAll( - stopLocationsUsedForFlexTrips - .stream() - .filter(GroupStop.class::isInstance) - .map(GroupStop.class::cast) - .flatMap(g -> g.getChildLocations().stream().filter(RegularStop.class::isInstance)) - .toList() - ); + stopLocationsUsedForFlexTrips = getStopLocationsUsedForFlexTrips(timetableRepository); } + Set stopLocationsUsedForCarsAllowedTrips = timetableRepository.getStopLocationsUsedForCarsAllowedTrips(); + for (TransitStopVertex tStop : vertices) { // Stops with pathways do not need to be connected to the street network, since there are explicit entrances defined for that if (tStop.hasPathways()) { @@ -116,7 +111,10 @@ public void linkTransitStops(Graph graph, TransitModel transitModel) { StopLinkType linkType = StopLinkType.WALK_ONLY; if ( - OTPFeature.FlexRouting.isOn() && stopLocationsUsedForFlexTrips.contains(tStop.getStop()) + ( + OTPFeature.FlexRouting.isOn() && stopLocationsUsedForFlexTrips.contains(tStop.getStop()) + ) || + stopLocationsUsedForCarsAllowedTrips.contains(tStop.getStop()) ) { linkType = StopLinkType.WALK_AND_CAR; } @@ -175,7 +173,6 @@ private void linkToDriveableEdge(TransitStopVertex tStop) { ); } - @Nonnull private static List createStopLinkEdges( TransitStopVertex vertex, StreetVertex streetVertex @@ -257,6 +254,34 @@ private void linkTransitEntrances(Graph graph) { } } + private void linkStationCentroids(Graph graph) { + BiFunction> stationAndStreetVertexLinker = ( + theStation, + streetVertex + ) -> + List.of( + StreetStationCentroidLink.createStreetStationLink( + (StationCentroidVertex) theStation, + streetVertex + ), + StreetStationCentroidLink.createStreetStationLink( + streetVertex, + (StationCentroidVertex) theStation + ) + ); + + for (StationCentroidVertex station : graph.getVerticesOfType(StationCentroidVertex.class)) { + graph + .getLinker() + .linkVertexPermanently( + station, + new TraverseModeSet(TraverseMode.WALK), + LinkingDirection.BOTH_WAYS, + stationAndStreetVertexLinker + ); + } + } + private void linkVehicleParks(Graph graph, DataImportIssueStore issueStore) { LOG.info("Linking vehicle parks to graph..."); List vehicleParkingToRemove = new ArrayList<>(); @@ -289,8 +314,7 @@ private void linkVehicleParks(Graph graph, DataImportIssueStore issueStore) { } } if (!vehicleParkingToRemove.isEmpty()) { - var vehicleParkingService = graph.getVehicleParkingService(); - vehicleParkingService.updateVehicleParking(List.of(), vehicleParkingToRemove); + parkingRepository.updateVehicleParking(List.of(), vehicleParkingToRemove); } } @@ -335,6 +359,26 @@ private VehicleParking removeVehicleParkingEntranceVertexFromGraph( } } + private Set getStopLocationsUsedForFlexTrips( + TimetableRepository timetableRepository + ) { + Set stopLocations = timetableRepository + .getAllFlexTrips() + .stream() + .flatMap(t -> t.getStops().stream()) + .collect(Collectors.toSet()); + + stopLocations.addAll( + stopLocations + .stream() + .filter(GroupStop.class::isInstance) + .map(GroupStop.class::cast) + .flatMap(g -> g.getChildLocations().stream().filter(RegularStop.class::isInstance)) + .toList() + ); + return stopLocations; + } + private enum StopLinkType { /** * Only ensure that the link leads to a walkable edge. diff --git a/src/main/java/org/opentripplanner/graph_builder/module/TimeZoneAdjusterModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/TimeZoneAdjusterModule.java similarity index 53% rename from src/main/java/org/opentripplanner/graph_builder/module/TimeZoneAdjusterModule.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/TimeZoneAdjusterModule.java index eb3674bf76a..3bd33f08a52 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/TimeZoneAdjusterModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/TimeZoneAdjusterModule.java @@ -7,32 +7,33 @@ import java.util.HashMap; import java.util.Map; import org.opentripplanner.graph_builder.model.GraphBuilderModule; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.service.TimetableRepository; /** * Adjust all scheduled times to match the transit model timezone. */ public class TimeZoneAdjusterModule implements GraphBuilderModule { - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; @Inject - public TimeZoneAdjusterModule(TransitModel transitModel) { - this.transitModel = transitModel; + public TimeZoneAdjusterModule(TimetableRepository timetableRepository) { + this.timetableRepository = timetableRepository; } @Override public void buildGraph() { // TODO: We assume that all time zones follow the same DST rules. In reality we need to split up // the services for each DST transition - final Instant serviceStart = transitModel.getTransitServiceStarts().toInstant(); + final Instant serviceStart = timetableRepository.getTransitServiceStarts().toInstant(); var graphOffset = Duration.ofSeconds( - transitModel.getTimeZone().getRules().getOffset(serviceStart).getTotalSeconds() + timetableRepository.getTimeZone().getRules().getOffset(serviceStart).getTotalSeconds() ); Map agencyShift = new HashMap<>(); - transitModel + timetableRepository .getAllTripPatterns() .forEach(pattern -> { var timeShift = agencyShift.computeIfAbsent( @@ -45,9 +46,15 @@ public void buildGraph() { return; } - pattern - .getScheduledTimetable() - .updateAllTripTimes(it -> it.adjustTimesToGraphTimeZone(timeShift)); + TripPattern updatedPattern = pattern + .copy() + .withScheduledTimeTableBuilder(builder -> + builder.updateAllTripTimes(tt -> tt.adjustTimesToGraphTimeZone(timeShift)) + ) + .build(); + // replace the original pattern with the updated pattern in the transit model + timetableRepository.addTripPattern(updatedPattern.getId(), updatedPattern); }); + timetableRepository.index(); } } diff --git a/src/main/java/org/opentripplanner/graph_builder/module/TripPatternNamer.java b/application/src/main/java/org/opentripplanner/graph_builder/module/TripPatternNamer.java similarity index 96% rename from src/main/java/org/opentripplanner/graph_builder/module/TripPatternNamer.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/TripPatternNamer.java index 744260ba784..238ddc5dc67 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/TripPatternNamer.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/TripPatternNamer.java @@ -12,24 +12,24 @@ import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.TripTimes; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TripPatternNamer implements GraphBuilderModule { private static final Logger LOG = LoggerFactory.getLogger(TripPatternNamer.class); - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; @Inject - public TripPatternNamer(TransitModel transitModel) { - this.transitModel = transitModel; + public TripPatternNamer(TimetableRepository timetableRepository) { + this.timetableRepository = timetableRepository; } @Override public void buildGraph() { /* Generate unique human-readable names for all the TableTripPatterns. */ - generateUniqueNames(transitModel.getAllTripPatterns()); + generateUniqueNames(timetableRepository.getAllTripPatterns()); } /** diff --git a/src/main/java/org/opentripplanner/graph_builder/module/ValidateAndInterpolateStopTimesForEachTrip.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ValidateAndInterpolateStopTimesForEachTrip.java similarity index 99% rename from src/main/java/org/opentripplanner/graph_builder/module/ValidateAndInterpolateStopTimesForEachTrip.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/ValidateAndInterpolateStopTimesForEachTrip.java index b0fc10fbe37..62b8e5c8173 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/ValidateAndInterpolateStopTimesForEachTrip.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/ValidateAndInterpolateStopTimesForEachTrip.java @@ -8,7 +8,6 @@ import org.opentripplanner.ext.flex.trip.FlexTrip; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.geometry.SphericalDistanceLibrary; -import org.opentripplanner.framework.logging.ProgressTracker; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issues.HopSpeedFast; @@ -23,6 +22,7 @@ import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.utils.logging.ProgressTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderFactory.java b/application/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderFactory.java similarity index 89% rename from src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderFactory.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderFactory.java index 9c778481d4d..d4d00fdc2a0 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderFactory.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderFactory.java @@ -19,6 +19,7 @@ import org.opentripplanner.graph_builder.module.DirectTransferGenerator; import org.opentripplanner.graph_builder.module.GraphCoherencyCheckerModule; import org.opentripplanner.graph_builder.module.OsmBoardingLocationsModule; +import org.opentripplanner.graph_builder.module.RouteToCentroidStationIdsValidator; import org.opentripplanner.graph_builder.module.StreetLinkerModule; import org.opentripplanner.graph_builder.module.TimeZoneAdjusterModule; import org.opentripplanner.graph_builder.module.TripPatternNamer; @@ -29,10 +30,11 @@ import org.opentripplanner.gtfs.graphbuilder.GtfsModule; import org.opentripplanner.netex.NetexModule; import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; import org.opentripplanner.service.worldenvelope.WorldEnvelopeRepository; import org.opentripplanner.standalone.config.BuildConfig; import org.opentripplanner.street.model.StreetLimitationParameters; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; @Singleton @Component(modules = { GraphBuilderModules.class }) @@ -58,6 +60,9 @@ public interface GraphBuilderFactory { CalculateWorldEnvelopeModule calculateWorldEnvelopeModule(); StreetLimitationParameters streetLimitationParameters(); + @Nullable + RouteToCentroidStationIdsValidator routeToCentroidStationIdValidator(); + @Nullable StopConsolidationModule stopConsolidationModule(); @@ -73,7 +78,7 @@ interface Builder { Builder graph(Graph graph); @BindsInstance - Builder transitModel(TransitModel transitModel); + Builder timetableRepository(TimetableRepository timetableRepository); @BindsInstance Builder worldEnvelopeRepository(WorldEnvelopeRepository worldEnvelopeRepository); @@ -83,6 +88,9 @@ Builder stopConsolidationRepository( @Nullable StopConsolidationRepository stopConsolidationRepository ); + @BindsInstance + Builder vehicleParkingRepository(VehicleParkingRepository parkingRepository); + @BindsInstance Builder streetLimitationParameters(StreetLimitationParameters streetLimitationParameters); diff --git a/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderModules.java b/application/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderModules.java similarity index 86% rename from src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderModules.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderModules.java index 10d3a997579..5371142d612 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderModules.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderModules.java @@ -24,6 +24,7 @@ import org.opentripplanner.graph_builder.issue.report.DataImportIssueReporter; import org.opentripplanner.graph_builder.issue.service.DefaultDataImportIssueStore; import org.opentripplanner.graph_builder.module.DirectTransferGenerator; +import org.opentripplanner.graph_builder.module.RouteToCentroidStationIdsValidator; import org.opentripplanner.graph_builder.module.StreetLinkerModule; import org.opentripplanner.graph_builder.module.islandpruning.PruneIslands; import org.opentripplanner.graph_builder.module.ned.DegreeGridNEDTileSource; @@ -39,12 +40,13 @@ import org.opentripplanner.gtfs.graphbuilder.GtfsModule; import org.opentripplanner.netex.NetexModule; import org.opentripplanner.netex.configure.NetexConfigure; -import org.opentripplanner.openstreetmap.OsmProvider; +import org.opentripplanner.osm.OsmProvider; import org.opentripplanner.routing.api.request.preference.WalkPreferences; import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; import org.opentripplanner.standalone.config.BuildConfig; import org.opentripplanner.street.model.StreetLimitationParameters; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; /** * Configure all modules which is not simple enough to be injected. @@ -54,10 +56,11 @@ public class GraphBuilderModules { @Provides @Singleton - static OsmModule provideOpenStreetMapModule( + static OsmModule provideOsmModule( GraphBuilderDataSources dataSources, BuildConfig config, Graph graph, + VehicleParkingRepository parkingService, DataImportIssueStore issueStore, StreetLimitationParameters streetLimitationParameters ) { @@ -75,7 +78,7 @@ static OsmModule provideOpenStreetMapModule( } return OsmModule - .of(providers, graph) + .of(providers, graph, parkingService) .withEdgeNamer(config.edgeNamer) .withAreaVisibility(config.areaVisibility) .withPlatformEntriesLinking(config.platformEntriesLinking) @@ -94,7 +97,7 @@ static GtfsModule provideGtfsModule( GraphBuilderDataSources dataSources, BuildConfig config, Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, DataImportIssueStore issueStore ) { List gtfsBundles = new ArrayList<>(); @@ -107,7 +110,7 @@ static GtfsModule provideGtfsModule( } return new GtfsModule( gtfsBundles, - transitModel, + timetableRepository, graph, issueStore, config.getTransitServicePeriod(), @@ -137,13 +140,15 @@ static NetexModule provideNetexModule( GraphBuilderDataSources dataSources, BuildConfig config, Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, + VehicleParkingRepository parkingService, DataImportIssueStore issueStore ) { return new NetexConfigure(config) .createNetexModule( dataSources.getNetexConfiguredDatasource(), - transitModel, + timetableRepository, + parkingService, graph, issueStore ); @@ -154,10 +159,17 @@ static NetexModule provideNetexModule( static StreetLinkerModule provideStreetLinkerModule( BuildConfig config, Graph graph, - TransitModel transitModel, + VehicleParkingRepository parkingRepository, + TimetableRepository timetableRepository, DataImportIssueStore issueStore ) { - return new StreetLinkerModule(graph, transitModel, issueStore, config.areaVisibility); + return new StreetLinkerModule( + graph, + parkingRepository, + timetableRepository, + issueStore, + config.areaVisibility + ); } @Provides @@ -165,14 +177,21 @@ static StreetLinkerModule provideStreetLinkerModule( static PruneIslands providePruneIslands( BuildConfig config, Graph graph, - TransitModel transitModel, + VehicleParkingRepository parkingRepository, + TimetableRepository timetableRepository, DataImportIssueStore issueStore ) { PruneIslands pruneIslands = new PruneIslands( graph, - transitModel, + timetableRepository, issueStore, - new StreetLinkerModule(graph, transitModel, issueStore, config.areaVisibility) + new StreetLinkerModule( + graph, + parkingRepository, + timetableRepository, + issueStore, + config.areaVisibility + ) ); pruneIslands.setPruningThresholdIslandWithoutStops( config.islandPruning.pruningThresholdIslandWithoutStops @@ -228,12 +247,12 @@ static List provideElevationModules( static DirectTransferGenerator provideDirectTransferGenerator( BuildConfig config, Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, DataImportIssueStore issueStore ) { return new DirectTransferGenerator( graph, - transitModel, + timetableRepository, issueStore, config.maxTransferDuration, config.transferRequests @@ -245,12 +264,12 @@ static DirectTransferGenerator provideDirectTransferGenerator( static DirectTransferAnalyzer provideDirectTransferAnalyzer( BuildConfig config, Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, DataImportIssueStore issueStore ) { return new DirectTransferAnalyzer( graph, - transitModel, + timetableRepository, issueStore, config.maxTransferDuration.toSeconds() * WalkPreferences.DEFAULT.speed() ); @@ -292,16 +311,30 @@ static DataImportIssueSummary providesDataImportIssueSummary(DataImportIssueStor @Singleton @Nullable static StopConsolidationModule providesStopConsolidationModule( - TransitModel transitModel, + TimetableRepository timetableRepository, @Nullable StopConsolidationRepository repo, GraphBuilderDataSources dataSources ) { return dataSources .stopConsolidation() - .map(ds -> StopConsolidationModule.of(transitModel, repo, ds)) + .map(ds -> StopConsolidationModule.of(timetableRepository, repo, ds)) .orElse(null); } + @Provides + @Singleton + @Nullable + static RouteToCentroidStationIdsValidator routeToCentroidStationIdValidator( + DataImportIssueStore issueStore, + BuildConfig config, + TimetableRepository timetableRepository + ) { + var ids = config.transitRouteToStationCentroid(); + return ids.isEmpty() + ? null + : new RouteToCentroidStationIdsValidator(issueStore, ids, timetableRepository); + } + /* private methods */ private static ElevationGridCoverageFactory createNedElevationFactory( diff --git a/src/main/java/org/opentripplanner/graph_builder/module/geometry/CalculateWorldEnvelopeModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/geometry/CalculateWorldEnvelopeModule.java similarity index 87% rename from src/main/java/org/opentripplanner/graph_builder/module/geometry/CalculateWorldEnvelopeModule.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/geometry/CalculateWorldEnvelopeModule.java index adcfe525414..87bb931cd3a 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/geometry/CalculateWorldEnvelopeModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/geometry/CalculateWorldEnvelopeModule.java @@ -2,14 +2,14 @@ import jakarta.inject.Inject; import java.util.Collection; -import org.opentripplanner.framework.logging.ProgressTracker; import org.opentripplanner.graph_builder.model.GraphBuilderModule; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.service.worldenvelope.WorldEnvelopeRepository; import org.opentripplanner.service.worldenvelope.model.WorldEnvelope; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.transit.model.site.StopLocation; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; +import org.opentripplanner.utils.logging.ProgressTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,24 +28,24 @@ public class CalculateWorldEnvelopeModule implements GraphBuilderModule { private static final int LOG_EVERY_N_COORDINATE = 1_000_000; private final Graph graph; - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; private final WorldEnvelopeRepository worldEnvelopeRepository; @Inject public CalculateWorldEnvelopeModule( Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, WorldEnvelopeRepository worldEnvelopeRepository ) { this.graph = graph; - this.transitModel = transitModel; + this.timetableRepository = timetableRepository; this.worldEnvelopeRepository = worldEnvelopeRepository; } @Override public void buildGraph() { var vertices = graph.getVertices(); - var stops = transitModel.getStopModel().listStopLocations(); + var stops = timetableRepository.getSiteRepository().listStopLocations(); WorldEnvelope envelope = build(vertices, stops); worldEnvelopeRepository.saveEnvelope(envelope); } diff --git a/src/main/java/org/opentripplanner/graph_builder/module/geometry/GeometryProcessor.java b/application/src/main/java/org/opentripplanner/graph_builder/module/geometry/GeometryProcessor.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/geometry/GeometryProcessor.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/geometry/GeometryProcessor.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/geometry/IndexedLineSegment.java b/application/src/main/java/org/opentripplanner/graph_builder/module/geometry/IndexedLineSegment.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/geometry/IndexedLineSegment.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/geometry/IndexedLineSegment.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/geometry/IndexedLineSegmentComparator.java b/application/src/main/java/org/opentripplanner/graph_builder/module/geometry/IndexedLineSegmentComparator.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/geometry/IndexedLineSegmentComparator.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/geometry/IndexedLineSegmentComparator.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/geometry/ShapeSegmentKey.java b/application/src/main/java/org/opentripplanner/graph_builder/module/geometry/ShapeSegmentKey.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/geometry/ShapeSegmentKey.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/geometry/ShapeSegmentKey.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/GraphIsland.java b/application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/GraphIsland.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/islandpruning/GraphIsland.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/GraphIsland.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/PruneIslands.java b/application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/PruneIslands.java similarity index 97% rename from src/main/java/org/opentripplanner/graph_builder/module/islandpruning/PruneIslands.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/PruneIslands.java index 26349c0d803..8bb3b3fbcd5 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/PruneIslands.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/PruneIslands.java @@ -32,7 +32,7 @@ import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.request.StreetSearchRequest; import org.opentripplanner.street.search.state.State; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,7 +48,7 @@ public class PruneIslands implements GraphBuilderModule { private static final Logger LOG = LoggerFactory.getLogger(PruneIslands.class); private final Graph graph; - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; private final DataImportIssueStore issueStore; private final StreetLinkerModule streetLinkerModule; private int pruningThresholdWithoutStops; @@ -60,12 +60,12 @@ public class PruneIslands implements GraphBuilderModule { public PruneIslands( Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, DataImportIssueStore issueStore, StreetLinkerModule streetLinkerModule ) { this.graph = graph; - this.transitModel = transitModel; + this.timetableRepository = timetableRepository; this.issueStore = issueStore; this.streetLinkerModule = streetLinkerModule; } @@ -81,8 +81,8 @@ public void buildGraph() { adaptivePruningDistance ); - this.vertexLinker = graph.getLinkerSafe(transitModel.getStopModel()); - this.streetIndex = graph.getStreetIndexSafe(transitModel.getStopModel()); + this.vertexLinker = graph.getLinkerSafe(timetableRepository.getSiteRepository()); + this.streetIndex = graph.getStreetIndexSafe(timetableRepository.getSiteRepository()); pruneIslands(TraverseMode.BICYCLE); pruneIslands(TraverseMode.WALK); @@ -91,7 +91,7 @@ public void buildGraph() { // reconnect stops that got disconnected if (streetLinkerModule != null) { LOG.info("Reconnecting stops"); - streetLinkerModule.linkTransitStops(graph, transitModel); + streetLinkerModule.linkTransitStops(graph, timetableRepository); int isolated = 0; for (TransitStopVertex tStop : graph.getVerticesOfType(TransitStopVertex.class)) { if (tStop.getDegreeOut() + tStop.getDegreeIn() == 0) { diff --git a/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/PrunedStopIsland.java b/application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/PrunedStopIsland.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/islandpruning/PrunedStopIsland.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/PrunedStopIsland.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/Subgraph.java b/application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/Subgraph.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/islandpruning/Subgraph.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/Subgraph.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/MinMap.java b/application/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/MinMap.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/nearbystops/MinMap.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/MinMap.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/NearbyStopFinder.java b/application/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/NearbyStopFinder.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/nearbystops/NearbyStopFinder.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/NearbyStopFinder.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/PatternConsideringNearbyStopFinder.java b/application/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/PatternConsideringNearbyStopFinder.java similarity index 82% rename from src/main/java/org/opentripplanner/graph_builder/module/nearbystops/PatternConsideringNearbyStopFinder.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/PatternConsideringNearbyStopFinder.java index 9abf759d076..8df2a25b64e 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/PatternConsideringNearbyStopFinder.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/PatternConsideringNearbyStopFinder.java @@ -1,10 +1,9 @@ package org.opentripplanner.graph_builder.module.nearbystops; -import java.time.Duration; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; -import org.opentripplanner.ext.dataoverlay.routing.DataOverlayContext; import org.opentripplanner.ext.flex.trip.FlexTrip; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.routing.api.request.RouteRequest; @@ -49,6 +48,9 @@ public List findNearbyStops( /* Track the closest stop on each flex trip nearby. */ MinMap, NearbyStop> closestStopForFlexTrip = new MinMap<>(); + /* The end result */ + Set uniqueStopsResult = new HashSet<>(); + /* Iterate over nearby stops via the street network or using straight-line distance. */ for (NearbyStop nearbyStop : delegateNearbyStopFinder.findNearbyStops( vertex, @@ -58,9 +60,17 @@ public List findNearbyStops( )) { StopLocation ts1 = nearbyStop.stop; - if (ts1 instanceof RegularStop) { + if (ts1 instanceof RegularStop regularStop) { /* Consider this destination stop as a candidate for every trip pattern passing through it. */ - for (TripPattern pattern : transitService.getPatternsForStop(ts1)) { + Collection patternsForStop = transitService.findPatterns(ts1); + + if (OTPFeature.IncludeEmptyRailStopsInTransfers.isOn()) { + if (patternsForStop.isEmpty() && regularStop.isRailStop()) { + uniqueStopsResult.add(nearbyStop); + } + } + + for (TripPattern pattern : patternsForStop) { if ( reverseDirection ? pattern.canAlight(nearbyStop.stop) @@ -85,10 +95,9 @@ public List findNearbyStops( } /* Make a transfer from the origin stop to each destination stop that was the closest stop on any pattern. */ - Set uniqueStops = new HashSet<>(); - uniqueStops.addAll(closestStopForFlexTrip.values()); - uniqueStops.addAll(closestStopForPattern.values()); + uniqueStopsResult.addAll(closestStopForFlexTrip.values()); + uniqueStopsResult.addAll(closestStopForPattern.values()); // TODO: don't convert to list - return uniqueStops.stream().toList(); + return uniqueStopsResult.stream().toList(); } } diff --git a/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/StraightLineNearbyStopFinder.java b/application/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/StraightLineNearbyStopFinder.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/nearbystops/StraightLineNearbyStopFinder.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/StraightLineNearbyStopFinder.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/StreetNearbyStopFinder.java b/application/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/StreetNearbyStopFinder.java similarity index 74% rename from src/main/java/org/opentripplanner/graph_builder/module/nearbystops/StreetNearbyStopFinder.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/StreetNearbyStopFinder.java index baf528a739f..8277bd47e4c 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/StreetNearbyStopFinder.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/nearbystops/StreetNearbyStopFinder.java @@ -2,6 +2,7 @@ import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; import java.time.Duration; import java.util.ArrayList; import java.util.Collection; @@ -10,10 +11,8 @@ import java.util.List; import java.util.Set; import org.opentripplanner.astar.model.ShortestPathTree; -import org.opentripplanner.astar.spi.SkipEdgeStrategy; -import org.opentripplanner.astar.strategy.ComposingSkipEdgeStrategy; import org.opentripplanner.astar.strategy.DurationSkipEdgeStrategy; -import org.opentripplanner.astar.strategy.MaxCountSkipEdgeStrategy; +import org.opentripplanner.astar.strategy.MaxCountTerminationStrategy; import org.opentripplanner.ext.dataoverlay.routing.DataOverlayContext; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.application.OTPRequestTimeoutException; @@ -29,8 +28,6 @@ import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.search.StreetSearchBuilder; import org.opentripplanner.street.search.TraverseMode; -import org.opentripplanner.street.search.request.StreetSearchRequest; -import org.opentripplanner.street.search.request.StreetSearchRequestMapper; import org.opentripplanner.street.search.state.State; import org.opentripplanner.street.search.strategy.DominanceFunctions; import org.opentripplanner.transit.model.site.AreaStop; @@ -40,18 +37,39 @@ public class StreetNearbyStopFinder implements NearbyStopFinder { private final Duration durationLimit; private final int maxStopCount; private final DataOverlayContext dataOverlayContext; + private final Set ignoreVertices; /** * Construct a NearbyStopFinder for the given graph and search radius. + * + * @param maxStopCount The maximum stops to return. 0 means no limit. Regardless of the + * maxStopCount we will always return all the directly connected stops. */ public StreetNearbyStopFinder( Duration durationLimit, int maxStopCount, DataOverlayContext dataOverlayContext + ) { + this(durationLimit, maxStopCount, dataOverlayContext, Set.of()); + } + + /** + * Construct a NearbyStopFinder for the given graph and search radius. + * + * @param maxStopCount The maximum stops to return. 0 means no limit. Regardless of the maxStopCount + * we will always return all the directly connected stops. + * @param ignoreVertices A set of stop vertices to ignore and not return NearbyStops for. + */ + public StreetNearbyStopFinder( + Duration durationLimit, + int maxStopCount, + DataOverlayContext dataOverlayContext, + Set ignoreVertices ) { this.dataOverlayContext = dataOverlayContext; this.durationLimit = durationLimit; this.maxStopCount = maxStopCount; + this.ignoreVertices = ignoreVertices; } /** @@ -66,48 +84,59 @@ public Collection findNearbyStops( StreetRequest streetRequest, boolean reverseDirection ) { - return findNearbyStops(Set.of(vertex), reverseDirection, routingRequest, streetRequest); + return findNearbyStops(Set.of(vertex), routingRequest, streetRequest, reverseDirection); } /** * Return all stops within a certain radius of the given vertex, using network distance along * streets. If the origin vertex is a StopVertex, the result will include it. * - * @param originVertices the origin point of the street search + * @param originVertices the origin point of the street search. * @param reverseDirection if true the paths returned instead originate at the nearby stops and - * have the originVertex as the destination + * have the originVertex as the destination. */ public Collection findNearbyStops( Set originVertices, - boolean reverseDirection, RouteRequest request, - StreetRequest streetRequest + StreetRequest streetRequest, + boolean reverseDirection ) { OTPRequestTimeoutException.checkForTimeout(); - List stopsFound = createDirectlyConnectedStops( - originVertices, + List stopsFound = NearbyStop.nearbyStopsForTransitStopVerticesFiltered( + Sets.difference(originVertices, ignoreVertices), reverseDirection, request, streetRequest ); // Return only the origin vertices if there are no valid street modes - if (streetRequest.mode() == StreetMode.NOT_SET) { + if ( + streetRequest.mode() == StreetMode.NOT_SET || + (maxStopCount > 0 && stopsFound.size() >= maxStopCount) + ) { return stopsFound; } + stopsFound = new ArrayList<>(stopsFound); - ShortestPathTree spt = StreetSearchBuilder + var streetSearch = StreetSearchBuilder .of() - .setSkipEdgeStrategy(getSkipEdgeStrategy()) + .setSkipEdgeStrategy(new DurationSkipEdgeStrategy<>(durationLimit)) .setDominanceFunction(new DominanceFunctions.MinimumWeight()) .setRequest(request) .setArriveBy(reverseDirection) .setStreetRequest(streetRequest) .setFrom(reverseDirection ? null : originVertices) .setTo(reverseDirection ? originVertices : null) - .setDataOverlayContext(dataOverlayContext) - .getShortestPathTree(); + .setDataOverlayContext(dataOverlayContext); + + if (maxStopCount > 0) { + streetSearch.setTerminationStrategy( + new MaxCountTerminationStrategy<>(maxStopCount, this::hasReachedStop) + ); + } + + ShortestPathTree spt = streetSearch.getShortestPathTree(); // Only used if OTPFeature.FlexRouting.isOn() Multimap locationsMap = ArrayListMultimap.create(); @@ -116,7 +145,9 @@ public Collection findNearbyStops( // TODO use GenericAStar and a traverseVisitor? Add an earliestArrival switch to genericAStar? for (State state : spt.getAllStates()) { Vertex targetVertex = state.getVertex(); - if (originVertices.contains(targetVertex)) continue; + if (originVertices.contains(targetVertex) || ignoreVertices.contains(targetVertex)) { + continue; + } if (targetVertex instanceof TransitStopVertex tsv && state.isFinal()) { stopsFound.add(NearbyStop.nearbyStopForState(state, tsv.getStop())); } @@ -158,50 +189,6 @@ public Collection findNearbyStops( return stopsFound; } - private SkipEdgeStrategy getSkipEdgeStrategy() { - var durationSkipEdgeStrategy = new DurationSkipEdgeStrategy(durationLimit); - - if (maxStopCount > 0) { - var strategy = new MaxCountSkipEdgeStrategy<>( - maxStopCount, - StreetNearbyStopFinder::hasReachedStop - ); - return new ComposingSkipEdgeStrategy<>(strategy, durationSkipEdgeStrategy); - } - return durationSkipEdgeStrategy; - } - - private static List createDirectlyConnectedStops( - Set originVertices, - boolean reverseDirection, - RouteRequest request, - StreetRequest streetRequest - ) { - List stopsFound = new ArrayList<>(); - - StreetSearchRequest streetSearchRequest = StreetSearchRequestMapper - .mapToTransferRequest(request) - .withArriveBy(reverseDirection) - .withMode(streetRequest.mode()) - .build(); - - /* Add the origin vertices if they are stops */ - for (Vertex vertex : originVertices) { - if (vertex instanceof TransitStopVertex tsv) { - stopsFound.add( - new NearbyStop( - tsv.getStop(), - 0, - Collections.emptyList(), - new State(vertex, streetSearchRequest) - ) - ); - } - } - - return stopsFound; - } - private boolean canBoardFlex(State state, boolean reverse) { Collection edges = reverse ? state.getVertex().getIncoming() @@ -218,13 +205,16 @@ private boolean canBoardFlex(State state, boolean reverse) { *

* 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}. + * the {@link MaxCountTerminationStrategy}. *

* 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 hasReachedStop(State state) { - return state.getVertex() instanceof TransitStopVertex && state.isFinal(); + private boolean hasReachedStop(State state) { + var vertex = state.getVertex(); + return ( + vertex instanceof TransitStopVertex && state.isFinal() && !ignoreVertices.contains(vertex) + ); } } diff --git a/src/main/java/org/opentripplanner/graph_builder/module/ned/DegreeGridNEDTileSource.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/DegreeGridNEDTileSource.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/ned/DegreeGridNEDTileSource.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/ned/DegreeGridNEDTileSource.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/ned/ElevationModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/ElevationModule.java similarity index 99% rename from src/main/java/org/opentripplanner/graph_builder/module/ned/ElevationModule.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/ned/ElevationModule.java index 6bcab049bd4..af8fb943072 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/ned/ElevationModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/ElevationModule.java @@ -29,9 +29,6 @@ import org.locationtech.jts.geom.impl.PackedCoordinateSequence; import org.opentripplanner.framework.geometry.EncodedPolyline; import org.opentripplanner.framework.geometry.SphericalDistanceLibrary; -import org.opentripplanner.framework.lang.IntUtils; -import org.opentripplanner.framework.logging.ProgressTracker; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issues.ElevationFlattened; import org.opentripplanner.graph_builder.issues.ElevationProfileFailure; @@ -43,6 +40,9 @@ import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.edge.StreetElevationExtensionBuilder; import org.opentripplanner.street.model.vertex.Vertex; +import org.opentripplanner.utils.lang.IntUtils; +import org.opentripplanner.utils.logging.ProgressTracker; +import org.opentripplanner.utils.time.DurationUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/graph_builder/module/ned/GeotiffGridCoverageFactoryImpl.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/GeotiffGridCoverageFactoryImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/ned/GeotiffGridCoverageFactoryImpl.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/ned/GeotiffGridCoverageFactoryImpl.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/ned/MissingElevationHandler.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/MissingElevationHandler.java similarity index 99% rename from src/main/java/org/opentripplanner/graph_builder/module/ned/MissingElevationHandler.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/ned/MissingElevationHandler.java index 4ae6c698d03..e0f5672a6ca 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/ned/MissingElevationHandler.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/MissingElevationHandler.java @@ -5,7 +5,6 @@ import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.impl.PackedCoordinateSequence; import org.opentripplanner.astar.model.BinHeap; -import org.opentripplanner.framework.lang.DoubleUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issues.ElevationFlattened; import org.opentripplanner.graph_builder.issues.ElevationProfileFailure; @@ -13,6 +12,7 @@ import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.edge.StreetElevationExtensionBuilder; import org.opentripplanner.street.model.vertex.Vertex; +import org.opentripplanner.utils.lang.DoubleUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/graph_builder/module/ned/NEDGridCoverageFactoryImpl.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/NEDGridCoverageFactoryImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/ned/NEDGridCoverageFactoryImpl.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/ned/NEDGridCoverageFactoryImpl.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/ned/NoDataGridCoverage.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/NoDataGridCoverage.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/ned/NoDataGridCoverage.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/ned/NoDataGridCoverage.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/ned/UnifiedGridCoverage.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/UnifiedGridCoverage.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/ned/UnifiedGridCoverage.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/ned/UnifiedGridCoverage.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/ned/VerticalDatum.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/VerticalDatum.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/ned/VerticalDatum.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/ned/VerticalDatum.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParameters.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParameters.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParameters.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParameters.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParametersBuilder.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParametersBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParametersBuilder.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParametersBuilder.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParametersList.java b/application/src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParametersList.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParametersList.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/ned/parameter/DemExtractParametersList.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/Area.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/Area.java similarity index 89% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/Area.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/Area.java index f0a61e94c5a..a9de4dd6d6e 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/Area.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/Area.java @@ -12,9 +12,9 @@ import org.locationtech.jts.geom.Polygon; import org.locationtech.jts.geom.TopologyException; import org.opentripplanner.framework.geometry.GeometryUtils; -import org.opentripplanner.openstreetmap.model.OSMNode; -import org.opentripplanner.openstreetmap.model.OSMWay; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmNode; +import org.opentripplanner.osm.model.OsmWay; +import org.opentripplanner.osm.model.OsmWithTags; /** * Stores information about an OSM area needed for visibility graph construction. Algorithm based on @@ -25,14 +25,14 @@ class Area { final List outermostRings; // This is the way or relation that has the relevant tags for the area - final OSMWithTags parent; + final OsmWithTags parent; public MultiPolygon jtsMultiPolygon; Area( - OSMWithTags parent, - List outerRingWays, - List innerRingWays, - TLongObjectMap nodes + OsmWithTags parent, + List outerRingWays, + List innerRingWays, + TLongObjectMap nodes ) { this.parent = parent; // ring assignment @@ -84,7 +84,7 @@ class Area { jtsMultiPolygon = calculateJTSMultiPolygon(); } - public List constructRings(List ways) { + public List constructRings(List ways) { if (ways.size() == 0) { // no rings is no rings return Collections.emptyList(); @@ -92,8 +92,8 @@ public List constructRings(List ways) { List closedRings = new ArrayList<>(); - ArrayListMultimap waysByEndpoint = ArrayListMultimap.create(); - for (OSMWay way : ways) { + ArrayListMultimap waysByEndpoint = ArrayListMultimap.create(); + for (OsmWay way : ways) { TLongList refs = way.getNodeRefs(); long start = refs.get(0); @@ -110,7 +110,7 @@ public List constructRings(List ways) { // Precheck for impossible situations, and remove those. TLongList endpointsToRemove = new TLongArrayList(); for (Long endpoint : waysByEndpoint.keySet()) { - Collection list = waysByEndpoint.get(endpoint); + Collection list = waysByEndpoint.get(endpoint); if (list.size() % 2 == 1) { endpointsToRemove.add(endpoint); } @@ -126,9 +126,9 @@ public List constructRings(List ways) { } long firstEndpoint = 0, otherEndpoint = 0; - OSMWay firstWay = null; + OsmWay firstWay = null; for (Long endpoint : waysByEndpoint.keySet()) { - List list = waysByEndpoint.get(endpoint); + List list = waysByEndpoint.get(endpoint); firstWay = list.get(0); TLongList nodeRefs = firstWay.getNodeRefs(); partialRing.addAll(nodeRefs); @@ -161,14 +161,14 @@ private MultiPolygon calculateJTSMultiPolygon() { } private boolean constructRingsRecursive( - ArrayListMultimap waysByEndpoint, + ArrayListMultimap waysByEndpoint, TLongList ring, List closedRings, long endpoint ) { - List ways = new ArrayList<>(waysByEndpoint.get(endpoint)); + List ways = new ArrayList<>(waysByEndpoint.get(endpoint)); - for (OSMWay way : ways) { + for (OsmWay way : ways) { // remove this way from the map TLongList nodeRefs = way.getNodeRefs(); long firstEndpoint = nodeRefs.get(0); @@ -200,9 +200,9 @@ private boolean constructRingsRecursive( // otherwise, we need to start a new partial ring newRing = new TLongArrayList(); - OSMWay firstWay = null; + OsmWay firstWay = null; for (Long entry : waysByEndpoint.keySet()) { - List list = waysByEndpoint.get(entry); + List list = waysByEndpoint.get(entry); firstWay = list.get(0); nodeRefs = firstWay.getNodeRefs(); newRing.addAll(nodeRefs); diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/AreaGroup.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/AreaGroup.java similarity index 82% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/AreaGroup.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/AreaGroup.java index a7bcc9ccb94..4d5428f5596 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/AreaGroup.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/AreaGroup.java @@ -17,9 +17,9 @@ import org.locationtech.jts.geom.Polygon; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.graph_builder.module.osm.Ring.RingConstructionException; -import org.opentripplanner.openstreetmap.model.OSMLevel; -import org.opentripplanner.openstreetmap.model.OSMNode; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmLevel; +import org.opentripplanner.osm.model.OsmNode; +import org.opentripplanner.osm.model.OsmWithTags; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,15 +51,15 @@ public AreaGroup(Collection areas) { List allRings = new ArrayList<>(); // However, JTS will lose the coord<->osmnode mapping, and we will have to reconstruct it. - HashMap nodeMap = new HashMap<>(); + HashMap nodeMap = new HashMap<>(); for (Area area : areas) { for (Ring ring : area.outermostRings) { allRings.add(ring.jtsPolygon); - for (OSMNode node : ring.nodes) { + for (OsmNode node : ring.nodes) { nodeMap.put(new Coordinate(node.lon, node.lat), node); } for (Ring inner : ring.getHoles()) { - for (OSMNode node : inner.nodes) { + for (OsmNode node : inner.nodes) { nodeMap.put(new Coordinate(node.lon, node.lat), node); } } @@ -86,28 +86,28 @@ public AreaGroup(Collection areas) { } } - public static List groupAreas(Map areasLevels) { + public static List groupAreas(Map areasLevels) { DisjointSet groups = new DisjointSet<>(); - Multimap areasForNode = LinkedListMultimap.create(); + Multimap areasForNode = LinkedListMultimap.create(); for (Area area : areasLevels.keySet()) { for (Ring ring : area.outermostRings) { for (Ring inner : ring.getHoles()) { - for (OSMNode node : inner.nodes) { + for (OsmNode node : inner.nodes) { areasForNode.put(node, area); } } - for (OSMNode node : ring.nodes) { + for (OsmNode node : ring.nodes) { areasForNode.put(node, area); } } } // areas that can be joined must share nodes and levels - for (OSMNode osmNode : areasForNode.keySet()) { + for (OsmNode osmNode : areasForNode.keySet()) { for (Area area1 : areasForNode.get(osmNode)) { - OSMLevel level1 = areasLevels.get(area1); + OsmLevel level1 = areasLevels.get(area1); for (Area area2 : areasForNode.get(osmNode)) { - OSMLevel level2 = areasLevels.get(area2); + OsmLevel level2 = areasLevels.get(area2); if ((level1 == null && level2 == null) || (level1 != null && level1.equals(level2))) { groups.union(area1, area2); } @@ -133,14 +133,14 @@ public static List groupAreas(Map areasLevels) { return out; } - public OSMWithTags getSomeOSMObject() { + public OsmWithTags getSomeOsmObject() { return areas.iterator().next().parent; } - private Ring toRing(Polygon polygon, HashMap nodeMap) { - List shell = new ArrayList<>(); + private Ring toRing(Polygon polygon, HashMap nodeMap) { + List shell = new ArrayList<>(); for (Coordinate coord : polygon.getExteriorRing().getCoordinates()) { - OSMNode node = nodeMap.get(coord); + OsmNode node = nodeMap.get(coord); if (node == null) { throw new RingConstructionException(); } @@ -150,9 +150,9 @@ private Ring toRing(Polygon polygon, HashMap nodeMap) { // now the holes for (int i = 0; i < polygon.getNumInteriorRing(); ++i) { LineString interior = polygon.getInteriorRingN(i); - List hole = new ArrayList<>(); + List hole = new ArrayList<>(); for (Coordinate coord : interior.getCoordinates()) { - OSMNode node = nodeMap.get(coord); + OsmNode node = nodeMap.get(coord); if (node == null) { throw new RingConstructionException(); } diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/AreaTooComplicated.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/AreaTooComplicated.java similarity index 82% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/AreaTooComplicated.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/AreaTooComplicated.java index 65d03ba84ce..224045fceb2 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/AreaTooComplicated.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/AreaTooComplicated.java @@ -2,7 +2,7 @@ import org.locationtech.jts.geom.Geometry; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; public record AreaTooComplicated(AreaGroup areaGroup, int nbNodes, int maxAreaNodes) implements DataImportIssue { @@ -11,12 +11,12 @@ public record AreaTooComplicated(AreaGroup areaGroup, int nbNodes, int maxAreaNo @Override public String getMessage() { - return String.format(FMT, areaGroup.getSomeOSMObject().getId(), nbNodes, maxAreaNodes); + return String.format(FMT, areaGroup.getSomeOsmObject().getId(), nbNodes, maxAreaNodes); } @Override public String getHTMLMessage() { - OSMWithTags entity = areaGroup.getSomeOSMObject(); + OsmWithTags entity = areaGroup.getSomeOsmObject(); return String.format(HTMLFMT, entity.url(), entity.getId(), nbNodes, maxAreaNodes); } diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/DisjointSet.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/DisjointSet.java similarity index 94% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/DisjointSet.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/DisjointSet.java index 15bfc3605b5..d130a435eaf 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/DisjointSet.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/DisjointSet.java @@ -9,7 +9,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; -import org.opentripplanner.framework.collection.MapUtils; +import org.opentripplanner.framework.collection.TroveUtils; /** Basic union-find data structure with path compression */ class DisjointSet { @@ -62,7 +62,7 @@ public boolean exists(T element) { public List> sets() { TLongObjectMap> out = new TLongObjectHashMap<>(); setMapping.forEachEntry((k, v) -> { - MapUtils.addToMapSet(out, compact(v), k); + TroveUtils.addToMapSet(out, compact(v), k); return true; }); return new ArrayList<>(out.valueCollection()); diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/ElevatorProcessor.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ElevatorProcessor.java similarity index 90% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/ElevatorProcessor.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/ElevatorProcessor.java index 3a0a9fa404b..490d6a266b9 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/ElevatorProcessor.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ElevatorProcessor.java @@ -7,14 +7,13 @@ import java.util.List; import java.util.Map; import java.util.OptionalInt; -import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issue.api.Issue; -import org.opentripplanner.openstreetmap.model.OSMLevel; -import org.opentripplanner.openstreetmap.model.OSMNode; -import org.opentripplanner.openstreetmap.model.OSMWay; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmLevel; +import org.opentripplanner.osm.model.OsmNode; +import org.opentripplanner.osm.model.OsmWay; +import org.opentripplanner.osm.model.OsmWithTags; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model.edge.ElevatorAlightEdge; @@ -46,9 +45,9 @@ class ElevatorProcessor { private final VertexGenerator vertexGenerator; public ElevatorProcessor( - @Nonnull DataImportIssueStore issueStore, - @Nonnull OsmDatabase osmdb, - @Nonnull VertexGenerator vertexGenerator + DataImportIssueStore issueStore, + OsmDatabase osmdb, + VertexGenerator vertexGenerator ) { this.issueStore = issueStore; this.osmdb = osmdb; @@ -58,14 +57,14 @@ public ElevatorProcessor( public void buildElevatorEdges(Graph graph) { /* build elevator edges */ for (Long nodeId : vertexGenerator.multiLevelNodes().keySet()) { - OSMNode node = osmdb.getNode(nodeId); + OsmNode node = osmdb.getNode(nodeId); // this allows skipping levels, e.g., an elevator that stops // at floor 0, 2, 3, and 5. // Converting to an Array allows us to // subscript it so we can loop over it in twos. Assumedly, it will stay // sorted when we convert it to an Array. // The objects are Integers, but toArray returns Object[] - Map vertices = vertexGenerator.multiLevelNodes().get(nodeId); + Map vertices = vertexGenerator.multiLevelNodes().get(nodeId); /* * first, build FreeEdges to disconnect from the graph, GenericVertices to serve as attachment points, and ElevatorBoard and @@ -78,10 +77,10 @@ public void buildElevatorEdges(Graph graph) { * + GenericVertex, X EndpointVertex, ~~ FreeEdge, == ElevatorBoardEdge/ElevatorAlightEdge Another loop will fill in the * ElevatorHopEdges. */ - OSMLevel[] levels = vertices.keySet().toArray(new OSMLevel[0]); + OsmLevel[] levels = vertices.keySet().toArray(new OsmLevel[0]); Arrays.sort(levels); ArrayList onboardVertices = new ArrayList<>(); - for (OSMLevel level : levels) { + for (OsmLevel level : levels) { // get the node to build the elevator out from OsmVertex sourceVertex = vertices.get(level); String levelName = level.longName; @@ -108,10 +107,10 @@ public void buildElevatorEdges(Graph graph) { } // END elevator edge loop // Add highway=elevators to graph as elevators - Iterator elevators = osmdb.getWays().stream().filter(this::isElevatorWay).iterator(); + Iterator elevators = osmdb.getWays().stream().filter(this::isElevatorWay).iterator(); while (elevators.hasNext()) { - OSMWay elevatorWay = elevators.next(); + OsmWay elevatorWay = elevators.next(); List nodes = Arrays .stream(elevatorWay.getNodeRefs().toArray()) @@ -207,7 +206,7 @@ private static void createElevatorHopEdges( } } - private boolean isElevatorWay(OSMWay way) { + private boolean isElevatorWay(OsmWay way) { if (!way.isElevator()) { return false; } @@ -223,7 +222,7 @@ private boolean isElevatorWay(OSMWay way) { return nodeRefs.get(0) != nodeRefs.get(nodeRefs.size() - 1); } - private OptionalInt parseDuration(OSMWithTags element) { + private OptionalInt parseDuration(OsmWithTags element) { return element.getTagAsInt( "duration", v -> diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorProcessor.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorProcessor.java similarity index 93% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorProcessor.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorProcessor.java index 51cd230a1a4..75e0965d82f 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorProcessor.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorProcessor.java @@ -3,7 +3,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; -import org.opentripplanner.openstreetmap.model.OSMWay; +import org.opentripplanner.osm.model.OsmWay; import org.opentripplanner.street.model.edge.EscalatorEdge; import org.opentripplanner.street.model.vertex.IntersectionVertex; @@ -18,7 +18,7 @@ public EscalatorProcessor(Map intersectionNodes) { this.intersectionNodes = intersectionNodes; } - public void buildEscalatorEdge(OSMWay escalatorWay, double length) { + public void buildEscalatorEdge(OsmWay escalatorWay, double length) { List nodes = Arrays .stream(escalatorWay.getNodeRefs().toArray()) .filter(nodeRef -> diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmDatabase.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmDatabase.java similarity index 87% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/OsmDatabase.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmDatabase.java index 60525b3cb6c..23999d1fec5 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmDatabase.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmDatabase.java @@ -24,10 +24,9 @@ import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LineString; import org.locationtech.jts.geom.Point; -import org.opentripplanner.framework.collection.MapUtils; +import org.opentripplanner.framework.collection.TroveUtils; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.geometry.HashGridSpatialIndex; -import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issue.api.Issue; import org.opentripplanner.graph_builder.issues.DisconnectedOsmNode; @@ -37,19 +36,20 @@ import org.opentripplanner.graph_builder.issues.TurnRestrictionException; import org.opentripplanner.graph_builder.issues.TurnRestrictionUnknown; import org.opentripplanner.graph_builder.module.osm.TurnRestrictionTag.Direction; -import org.opentripplanner.openstreetmap.model.OSMLevel; -import org.opentripplanner.openstreetmap.model.OSMLevel.Source; -import org.opentripplanner.openstreetmap.model.OSMNode; -import org.opentripplanner.openstreetmap.model.OSMRelation; -import org.opentripplanner.openstreetmap.model.OSMRelationMember; -import org.opentripplanner.openstreetmap.model.OSMTag; -import org.opentripplanner.openstreetmap.model.OSMWay; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmLevel; +import org.opentripplanner.osm.model.OsmLevel.Source; +import org.opentripplanner.osm.model.OsmNode; +import org.opentripplanner.osm.model.OsmRelation; +import org.opentripplanner.osm.model.OsmRelationMember; +import org.opentripplanner.osm.model.OsmTag; +import org.opentripplanner.osm.model.OsmWay; +import org.opentripplanner.osm.model.OsmWithTags; import org.opentripplanner.street.model.RepeatingTimePeriod; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model.TurnRestrictionType; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.TraverseModeSet; +import org.opentripplanner.utils.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,22 +60,22 @@ public class OsmDatabase { private final DataImportIssueStore issueStore; /* Map of all nodes used in ways/areas keyed by their OSM ID */ - private final TLongObjectMap nodesById = new TLongObjectHashMap<>(); + private final TLongObjectMap nodesById = new TLongObjectHashMap<>(); /* Map of all bike parking nodes, keyed by their OSM ID */ - private final TLongObjectMap bikeParkingNodes = new TLongObjectHashMap<>(); + private final TLongObjectMap bikeParkingNodes = new TLongObjectHashMap<>(); /* Map of all bike parking nodes, keyed by their OSM ID */ - private final TLongObjectMap carParkingNodes = new TLongObjectHashMap<>(); + private final TLongObjectMap carParkingNodes = new TLongObjectHashMap<>(); /* Map of all non-area ways keyed by their OSM ID */ - private final TLongObjectMap waysById = new TLongObjectHashMap<>(); + private final TLongObjectMap waysById = new TLongObjectHashMap<>(); /* Map of all area ways keyed by their OSM ID */ - private final TLongObjectMap areaWaysById = new TLongObjectHashMap<>(); + private final TLongObjectMap areaWaysById = new TLongObjectHashMap<>(); /* Map of all relations keyed by their OSM ID */ - private final TLongObjectMap relationsById = new TLongObjectHashMap<>(); + private final TLongObjectMap relationsById = new TLongObjectHashMap<>(); /* All walkable areas */ private final List walkableAreas = new ArrayList<>(); @@ -87,12 +87,12 @@ public class OsmDatabase { private final List bikeParkingAreas = new ArrayList<>(); /* Map of all area OSMWay for a given node */ - private final TLongObjectMap> areasForNode = new TLongObjectHashMap<>(); + private final TLongObjectMap> areasForNode = new TLongObjectHashMap<>(); /* Map of all area OSMWay for a given node */ - private final List singleWayAreas = new ArrayList<>(); + private final List singleWayAreas = new ArrayList<>(); - private final Set processedAreas = new HashSet<>(); + private final Set processedAreas = new HashSet<>(); /* Set of area way IDs */ private final TLongSet areaWayIds = new TLongHashSet(); @@ -104,7 +104,7 @@ public class OsmDatabase { private final TLongSet areaNodeIds = new TLongHashSet(); /* Track which vertical level each OSM way belongs to, for building elevators etc. */ - private final Map wayLevels = new HashMap<>(); + private final Map wayLevels = new HashMap<>(); /* Set of turn restrictions for each turn "from" way ID */ private final Multimap turnRestrictionsByFromWay = ArrayListMultimap.create(); @@ -116,7 +116,7 @@ public class OsmDatabase { * Map of all transit stop nodes that lie within an area and which are connected to the area by * a relation. Keyed by the area's OSM way. */ - private final Multimap stopsInAreas = HashMultimap.create(); + private final Multimap stopsInAreas = HashMultimap.create(); /* * ID of the next virtual node we create during building phase. Negative to prevent conflicts @@ -134,15 +134,15 @@ public OsmDatabase(DataImportIssueStore issueStore) { this.issueStore = issueStore; } - public OSMNode getNode(Long nodeId) { + public OsmNode getNode(Long nodeId) { return nodesById.get(nodeId); } - public OSMWay getWay(Long nodeId) { + public OsmWay getWay(Long nodeId) { return waysById.get(nodeId); } - public Collection getWays() { + public Collection getWays() { return Collections.unmodifiableCollection(waysById.valueCollection()); } @@ -158,11 +158,11 @@ public int wayCount() { return waysById.size(); } - public Collection getBikeParkingNodes() { + public Collection getBikeParkingNodes() { return Collections.unmodifiableCollection(bikeParkingNodes.valueCollection()); } - public Collection getCarParkingNodes() { + public Collection getCarParkingNodes() { return Collections.unmodifiableCollection(carParkingNodes.valueCollection()); } @@ -190,16 +190,16 @@ public Collection getToWayTurnRestrictions(Long toWayId) { return turnRestrictionsByToWay.get(toWayId); } - public Collection getStopsInArea(OSMWithTags areaParent) { + public Collection getStopsInArea(OsmWithTags areaParent) { return stopsInAreas.get(areaParent); } - public OSMLevel getLevelForWay(OSMWithTags way) { - return Objects.requireNonNullElse(wayLevels.get(way), OSMLevel.DEFAULT); + public OsmLevel getLevelForWay(OsmWithTags way) { + return Objects.requireNonNullElse(wayLevels.get(way), OsmLevel.DEFAULT); } - public Set getAreasForNode(Long nodeId) { - Set areas = areasForNode.get(nodeId); + public Set getAreasForNode(Long nodeId) { + Set areas = areasForNode.get(nodeId); if (areas == null) { return Set.of(); } @@ -210,7 +210,7 @@ public boolean isNodeBelongsToWay(Long nodeId) { return waysNodeIds.contains(nodeId); } - public void addNode(OSMNode node) { + public void addNode(OsmNode node) { if (node.isBikeParking()) { bikeParkingNodes.put(node.getId(), node); } @@ -233,7 +233,7 @@ public void addNode(OSMNode node) { nodesById.put(node.getId(), node); } - public void addWay(OSMWay way) { + public void addWay(OsmWay way) { /* only add ways once */ long wayId = way.getId(); if (waysById.containsKey(wayId) || areaWaysById.containsKey(wayId)) { @@ -253,11 +253,7 @@ public void addWay(OSMWay way) { applyLevelsForWay(way); - /* An area can be specified as such, or be one by default as an amenity */ - if ( - (way.isArea() || way.isParkAndRide() || way.isBikeParking() || way.isBoardingArea()) && - way.getNodeRefs().size() > 2 - ) { + if (way.isRoutableArea()) { // this is an area that's a simple polygon. So we can just add it straight // to the areas, if it's not part of a relation. if (!areaWayIds.contains(wayId)) { @@ -267,7 +263,7 @@ public void addWay(OSMWay way) { way .getNodeRefs() .forEach(node -> { - MapUtils.addToMapSet(areasForNode, node, way); + TroveUtils.addToMapSet(areasForNode, node, way); return true; }); } @@ -277,7 +273,7 @@ public void addWay(OSMWay way) { waysById.put(wayId, way); } - public void addRelation(OSMRelation relation) { + public void addRelation(OsmRelation relation) { if (relationsById.containsKey(relation.getId())) { return; } @@ -294,7 +290,7 @@ public void addRelation(OSMRelation relation) { if (!relation.isRoutable() && !relation.isParkAndRide() && !relation.isBikeParking()) { return; } - for (OSMRelationMember member : relation.getMembers()) { + for (OsmRelationMember member : relation.getMembers()) { areaWayIds.add(member.getRef()); } applyLevelsForWay(relation); @@ -350,14 +346,14 @@ public void postLoad() { /** * Check if a point is within an epsilon of a node. */ - private static boolean checkIntersectionDistance(Point p, OSMNode n, double epsilon) { + private static boolean checkIntersectionDistance(Point p, OsmNode n, double epsilon) { return Math.abs(p.getY() - n.lat) < epsilon && Math.abs(p.getX() - n.lon) < epsilon; } /** * Check if two nodes are within an epsilon. */ - private static boolean checkDistanceWithin(OSMNode a, OSMNode b, double epsilon) { + private static boolean checkDistanceWithin(OsmNode a, OsmNode b, double epsilon) { return Math.abs(a.lat - b.lat) < epsilon && Math.abs(a.lon - b.lon) < epsilon; } @@ -385,13 +381,13 @@ private void processUnconnectedAreas() { // For each way, intersect with areas int nCreatedNodes = 0; - for (OSMWay way : waysById.valueCollection()) { - OSMLevel wayLevel = getLevelForWay(way); + for (OsmWay way : waysById.valueCollection()) { + OsmLevel wayLevel = getLevelForWay(way); // For each segment of the way for (int i = 0; i < way.getNodeRefs().size() - 1; i++) { - OSMNode nA = nodesById.get(way.getNodeRefs().get(i)); - OSMNode nB = nodesById.get(way.getNodeRefs().get(i + 1)); + OsmNode nA = nodesById.get(way.getNodeRefs().get(i)); + OsmNode nB = nodesById.get(way.getNodeRefs().get(i + 1)); if (nA == null || nB == null) { continue; } @@ -417,7 +413,7 @@ private void processUnconnectedAreas() { } // Skip if area and way are from "incompatible" levels - OSMLevel areaLevel = getLevelForWay(ringSegment.area.parent); + OsmLevel areaLevel = getLevelForWay(ringSegment.area.parent); if (!wayLevel.equals(areaLevel)) { continue; } @@ -455,7 +451,7 @@ private void processUnconnectedAreas() { // if the intersection is extremely close to one of the nodes of the road or the parking lot, just use that node // rather than splitting anything. See issue 1605. - OSMNode splitNode; + OsmNode splitNode; double epsilon = 0.0000001; // note that the if . . . else if structure of this means that if a node at one end of a (way|ring) segment is snapped, @@ -629,8 +625,8 @@ private void processAreaRingForUnconnectedAreas( * @param c The location of the node to create. * @return The created node. */ - private OSMNode createVirtualNode(Coordinate c) { - OSMNode node = new OSMNode(); + private OsmNode createVirtualNode(Coordinate c) { + OsmNode node = new OsmNode(); node.lon = c.x; node.lat = c.y; node.setId(virtualNodeId); @@ -640,7 +636,7 @@ private OSMNode createVirtualNode(Coordinate c) { return node; } - private void applyLevelsForWay(OSMWithTags way) { + private void applyLevelsForWay(OsmWithTags way) { /* Determine OSM level for each way, if it was not already set */ if (!wayLevels.containsKey(way)) { // if this way is not a key in the wayLevels map, a level map was not @@ -648,26 +644,26 @@ private void applyLevelsForWay(OSMWithTags way) { /* try to find a level name in tags */ String levelName = null; - OSMLevel level = OSMLevel.DEFAULT; + OsmLevel level = OsmLevel.DEFAULT; if (way.hasTag("level")) { // TODO: floating-point levels &c. levelName = way.getTag("level"); level = - OSMLevel.fromString(levelName, OSMLevel.Source.LEVEL_TAG, noZeroLevels, issueStore, way); + OsmLevel.fromString(levelName, OsmLevel.Source.LEVEL_TAG, noZeroLevels, issueStore, way); } else if (way.hasTag("layer")) { levelName = way.getTag("layer"); level = - OSMLevel.fromString(levelName, OSMLevel.Source.LAYER_TAG, noZeroLevels, issueStore, way); + OsmLevel.fromString(levelName, OsmLevel.Source.LAYER_TAG, noZeroLevels, issueStore, way); } if (level == null || (!level.reliable)) { issueStore.add(new LevelAmbiguous(levelName, way)); - level = OSMLevel.DEFAULT; + level = OsmLevel.DEFAULT; } wayLevels.put(way, level); } } - private void markNodesForKeeping(Collection osmWays, TLongSet nodeSet) { - for (OSMWay way : osmWays) { + private void markNodesForKeeping(Collection osmWays, TLongSet nodeSet) { + for (OsmWay way : osmWays) { // Since the way is kept, update nodes-with-neighbors TLongList nodes = way.getNodeRefs(); if (nodes.size() > 1) { @@ -680,7 +676,7 @@ private void markNodesForKeeping(Collection osmWays, TLongSet nodeSet) { * Create areas from single ways. */ private void processSingleWayAreas() { - AREA:for (OSMWay way : singleWayAreas) { + AREA:for (OsmWay way : singleWayAreas) { if (processedAreas.contains(way)) { continue; } @@ -692,7 +688,7 @@ private void processSingleWayAreas() { } } try { - newArea(new Area(way, List.of(way), Collections.emptyList(), nodesById)); + addArea(new Area(way, List.of(way), Collections.emptyList(), nodesById)); } catch (Area.AreaConstructionException | Ring.RingConstructionException e) { // this area cannot be constructed, but we already have all the // necessary nodes to construct it. So, something must be wrong with @@ -713,7 +709,7 @@ private void processSingleWayAreas() { * the used ways. */ private void processMultipolygonRelations() { - RELATION:for (OSMRelation relation : relationsById.valueCollection()) { + RELATION:for (OsmRelation relation : relationsById.valueCollection()) { if (processedAreas.contains(relation)) { continue; } @@ -726,10 +722,10 @@ private void processMultipolygonRelations() { continue; } // Area multipolygons -- pedestrian plazas - ArrayList innerWays = new ArrayList<>(); - ArrayList outerWays = new ArrayList<>(); - for (OSMRelationMember member : relation.getMembers()) { - OSMWay way = areaWaysById.get(member.getRef()); + ArrayList innerWays = new ArrayList<>(); + ArrayList outerWays = new ArrayList<>(); + for (OsmRelationMember member : relation.getMembers()) { + OsmWay way = areaWaysById.get(member.getRef()); if (way == null) { // relation includes way which does not exist in the data. Skip. continue RELATION; @@ -738,7 +734,7 @@ private void processMultipolygonRelations() { while (wayNodeIterator.hasNext()) { long nodeId = wayNodeIterator.next(); if (nodesById.containsKey(nodeId)) { - MapUtils.addToMapSet(areasForNode, nodeId, way); + TroveUtils.addToMapSet(areasForNode, nodeId, way); } else { // this area is missing some nodes, perhaps because it is on // the edge of the region, so we will simply not route on it. @@ -755,19 +751,19 @@ private void processMultipolygonRelations() { } processedAreas.add(relation); try { - newArea(new Area(relation, outerWays, innerWays, nodesById)); + addArea(new Area(relation, outerWays, innerWays, nodesById)); } catch (Area.AreaConstructionException | Ring.RingConstructionException e) { issueStore.add(new InvalidOsmGeometry(relation)); continue; } - for (OSMRelationMember member : relation.getMembers()) { + for (OsmRelationMember member : relation.getMembers()) { // multipolygons for attribute mapping if (!(member.hasTypeWay() && waysById.containsKey(member.getRef()))) { continue; } - OSMWithTags way = waysById.get(member.getRef()); + OsmWithTags way = waysById.get(member.getRef()); if (way == null) { continue; } @@ -790,10 +786,12 @@ private void processMultipolygonRelations() { /** * Handler for a new Area (single way area or multipolygon relations) */ - private void newArea(Area area) { - StreetTraversalPermission permissions = area.parent.overridePermissions( - StreetTraversalPermission.PEDESTRIAN_AND_BICYCLE - ); + private void addArea(Area area) { + StreetTraversalPermission permissions = area.parent + .getOsmProvider() + .getWayPropertySet() + .getDataForWay(area.parent) + .getPermission(); if (area.parent.isRoutable() && permissions != StreetTraversalPermission.NONE) { walkableAreas.add(area); } @@ -812,7 +810,7 @@ private void newArea(Area area) { private void processRelations() { LOG.debug("Processing relations..."); - for (OSMRelation relation : relationsById.valueCollection()) { + for (OsmRelation relation : relationsById.valueCollection()) { if (relation.isRestriction()) { processRestriction(relation); } else if (relation.isLevelMap()) { @@ -830,7 +828,7 @@ private void processRelations() { * * @see "https://wiki.openstreetmap.org/wiki/Tag:route%3Dbicycle" */ - private void processBicycleRoute(OSMRelation relation) { + private void processBicycleRoute(OsmRelation relation) { if (relation.isBicycleRoute()) { // we treat networks without known network type like local networks var network = relation.getTagOpt("network").orElse("lcn"); @@ -838,7 +836,7 @@ private void processBicycleRoute(OSMRelation relation) { } } - private void setNetworkForAllMembers(OSMRelation relation, String key) { + private void setNetworkForAllMembers(OsmRelation relation, String key) { relation .getMembers() .forEach(member -> { @@ -855,9 +853,9 @@ private void setNetworkForAllMembers(OSMRelation relation, String key) { /** * Store turn restrictions. */ - private void processRestriction(OSMRelation relation) { + private void processRestriction(OsmRelation relation) { long from = -1, to = -1, via = -1; - for (OSMRelationMember member : relation.getMembers()) { + for (OsmRelationMember member : relation.getMembers()) { String role = member.getRole(); if (role.equals("from")) { from = member.getRef(); @@ -965,7 +963,7 @@ private void processRestriction(OSMRelation relation) { /** * Process an OSM level map. */ - private void processLevelMap(OSMRelation relation) { + private void processLevelMap(OsmRelation relation) { var levelsTag = relation.getTag("levels"); if (!StringUtils.hasValue(levelsTag)) { issueStore.add( @@ -978,16 +976,16 @@ private void processLevelMap(OSMRelation relation) { return; } - Map levels = OSMLevel.mapFromSpecList( + Map levels = OsmLevel.mapFromSpecList( levelsTag, Source.LEVEL_MAP, true, issueStore, relation ); - for (OSMRelationMember member : relation.getMembers()) { + for (OsmRelationMember member : relation.getMembers()) { if (member.hasTypeWay() && waysById.containsKey(member.getRef())) { - OSMWay way = waysById.get(member.getRef()); + OsmWay way = waysById.get(member.getRef()); if (way != null) { String role = member.getRole(); // if the level map relation has a role:xyz tag, this way is something @@ -1007,13 +1005,13 @@ private void processLevelMap(OSMRelation relation) { /** * Handle route=road and route=bicycle relations. */ - private void processRoute(OSMRelation relation) { - for (OSMRelationMember member : relation.getMembers()) { + private void processRoute(OsmRelation relation) { + for (OsmRelationMember member : relation.getMembers()) { if (!(member.hasTypeWay() && waysById.containsKey(member.getRef()))) { continue; } - OSMWithTags way = waysById.get(member.getRef()); + OsmWithTags way = waysById.get(member.getRef()); if (way == null) { continue; } @@ -1025,7 +1023,7 @@ private void processRoute(OSMRelation relation) { addUniqueName(way.getTag("otp:route_name"), relation.getTag("name")) ); } else { - way.addTag(new OSMTag("otp:route_name", relation.getTag("name"))); + way.addTag(new OsmTag("otp:route_name", relation.getTag("name"))); } } if (relation.hasTag("ref")) { @@ -1035,7 +1033,7 @@ private void processRoute(OSMRelation relation) { addUniqueName(way.getTag("otp:route_ref"), relation.getTag("ref")) ); } else { - way.addTag(new OSMTag("otp:route_ref", relation.getTag("ref"))); + way.addTag(new OsmTag("otp:route_ref", relation.getTag("ref"))); } } } @@ -1053,10 +1051,10 @@ private void processRoute(OSMRelation relation) { * @author hannesj * @see "http://wiki.openstreetmap.org/wiki/Tag:public_transport%3Dstop_area" */ - private void processPublicTransportStopArea(OSMRelation relation) { - Set platformAreas = new HashSet<>(); - Set platformNodes = new HashSet<>(); - for (OSMRelationMember member : relation.getMembers()) { + private void processPublicTransportStopArea(OsmRelation relation) { + Set platformAreas = new HashSet<>(); + Set platformNodes = new HashSet<>(); + for (OsmRelationMember member : relation.getMembers()) { switch (member.getType()) { case NODE -> { var node = nodesById.get(member.getRef()); @@ -1077,7 +1075,7 @@ private void processPublicTransportStopArea(OSMRelation relation) { } } - for (OSMWithTags area : platformAreas) { + for (OsmWithTags area : platformAreas) { if (area == null) { throw new RuntimeException( "Could not process public transport relation '%s' (%s)".formatted( @@ -1114,9 +1112,9 @@ static class RingSegment { Ring ring; - OSMNode nA; + OsmNode nA; - OSMNode nB; + OsmNode nB; } private record KeyPair(long id0, long id1) {} diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java similarity index 91% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java index 10c215ee448..e3618d6f93d 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java @@ -8,26 +8,25 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LineString; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.geometry.SphericalDistanceLibrary; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.logging.ProgressTracker; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.model.GraphBuilderModule; import org.opentripplanner.graph_builder.module.osm.parameters.OsmProcessingParameters; -import org.opentripplanner.openstreetmap.OsmProvider; -import org.opentripplanner.openstreetmap.model.OSMLevel; -import org.opentripplanner.openstreetmap.model.OSMNode; -import org.opentripplanner.openstreetmap.model.OSMWay; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.WayProperties; +import org.opentripplanner.osm.OsmProvider; +import org.opentripplanner.osm.model.OsmLevel; +import org.opentripplanner.osm.model.OsmNode; +import org.opentripplanner.osm.model.OsmWay; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.WayProperties; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.util.ElevationUtils; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; import org.opentripplanner.street.model.StreetLimitationParameters; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model.edge.StreetEdge; @@ -35,6 +34,7 @@ import org.opentripplanner.street.model.vertex.BarrierVertex; import org.opentripplanner.street.model.vertex.IntersectionVertex; import org.opentripplanner.street.model.vertex.Vertex; +import org.opentripplanner.utils.logging.ProgressTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,6 +52,7 @@ public class OsmModule implements GraphBuilderModule { */ private final List providers; private final Graph graph; + private final VehicleParkingRepository parkingRepository; private final DataImportIssueStore issueStore; private final OsmProcessingParameters params; private final SafetyValueNormalizer normalizer; @@ -62,8 +63,9 @@ public class OsmModule implements GraphBuilderModule { OsmModule( Collection providers, Graph graph, + VehicleParkingRepository parkingService, DataImportIssueStore issueStore, - @Nonnull StreetLimitationParameters streetLimitationParameters, + StreetLimitationParameters streetLimitationParameters, OsmProcessingParameters params ) { this.providers = List.copyOf(providers); @@ -74,14 +76,23 @@ public class OsmModule implements GraphBuilderModule { this.vertexGenerator = new VertexGenerator(osmdb, graph, params.boardingAreaRefTags()); this.normalizer = new SafetyValueNormalizer(graph, issueStore); this.streetLimitationParameters = Objects.requireNonNull(streetLimitationParameters); + this.parkingRepository = parkingService; } - public static OsmModuleBuilder of(Collection providers, Graph graph) { - return new OsmModuleBuilder(providers, graph); + public static OsmModuleBuilder of( + Collection providers, + Graph graph, + VehicleParkingRepository service + ) { + return new OsmModuleBuilder(providers, graph, service); } - public static OsmModuleBuilder of(OsmProvider provider, Graph graph) { - return of(List.of(provider), graph); + public static OsmModuleBuilder of( + OsmProvider provider, + Graph graph, + VehicleParkingRepository service + ) { + return of(List.of(provider), graph, service); } @Override @@ -92,7 +103,7 @@ public void buildGraph() { "Using OSM way configuration from {}.", provider.getOsmTagMapper().getClass().getSimpleName() ); - provider.readOSM(osmdb); + provider.readOsm(osmdb); } osmdb.postLoad(); @@ -164,7 +175,7 @@ private void build() { } if (!parkingLots.isEmpty()) { - graph.getVehicleParkingService().updateVehicleParking(parkingLots, List.of()); + parkingRepository.updateVehicleParking(parkingLots, List.of()); } var elevatorProcessor = new ElevatorProcessor(issueStore, osmdb, vertexGenerator); @@ -190,7 +201,7 @@ private static double getGeometryLengthMeters(Geometry geometry) { } private List groupAreas(Collection areas) { - Map areasLevels = new HashMap<>(areas.size()); + Map areasLevels = new HashMap<>(areas.size()); for (Area area : areas) { areasLevels.put(area, osmdb.getLevelForWay(area.parent)); } @@ -250,7 +261,7 @@ private void buildBasicGraph() { LOG.info(progress.startMessage()); var escalatorProcessor = new EscalatorProcessor(vertexGenerator.intersectionNodes()); - WAY:for (OSMWay way : osmdb.getWays()) { + WAY:for (OsmWay way : osmdb.getWays()) { WayProperties wayData = way.getOsmProvider().getWayPropertySet().getDataForWay(way); setWayName(way); @@ -268,7 +279,7 @@ private void buildBasicGraph() { String lastLevel = null; for (TLongIterator iter = way.getNodeRefs().iterator(); iter.hasNext();) { long nodeId = iter.next(); - OSMNode node = osmdb.getNode(nodeId); + OsmNode node = osmdb.getNode(nodeId); if (node == null) continue WAY; boolean levelsDiffer = false; String level = node.getTag("level"); @@ -303,12 +314,12 @@ private void buildBasicGraph() { */ Long startNode = null; // where the current edge should start - OSMNode osmStartNode = null; + OsmNode osmStartNode = null; for (int i = 0; i < nodes.size() - 1; i++) { - OSMNode segmentStartOSMNode = osmdb.getNode(nodes.get(i)); + OsmNode segmentStartOsmNode = osmdb.getNode(nodes.get(i)); - if (segmentStartOSMNode == null) { + if (segmentStartOsmNode == null) { continue; } @@ -316,10 +327,10 @@ private void buildBasicGraph() { if (osmStartNode == null) { startNode = nodes.get(i); - osmStartNode = segmentStartOSMNode; + osmStartNode = segmentStartOsmNode; } // where the current edge might end - OSMNode osmEndNode = osmdb.getNode(endNode); + OsmNode osmEndNode = osmdb.getNode(endNode); LineString geometry; @@ -356,7 +367,7 @@ private void buildBasicGraph() { // make or get a shared vertex for flat intersections, // one vertex per level for multilevel nodes like elevators startEndpoint = vertexGenerator.getVertexForOsmNode(osmStartNode, way); - String ele = segmentStartOSMNode.getTag("ele"); + String ele = segmentStartOsmNode.getTag("ele"); if (ele != null) { Double elevation = ElevationUtils.parseEleTag(ele); if (elevation != null) { @@ -413,7 +424,7 @@ private void validateBarriers() { vertices.forEach(bv -> bv.makeBarrierAtEndReachable()); } - private void setWayName(OSMWithTags way) { + private void setWayName(OsmWithTags way) { if (!way.hasTag("name")) { I18NString creativeName = way.getOsmProvider().getWayPropertySet().getCreativeNameForWay(way); if (creativeName != null) { @@ -423,7 +434,7 @@ private void setWayName(OSMWithTags way) { } private void applyEdgesToTurnRestrictions( - OSMWay way, + OsmWay way, long startNode, long endNode, StreetEdge street, @@ -462,7 +473,7 @@ private void applyEdgesToTurnRestrictions( private StreetEdgePair getEdgesForStreet( IntersectionVertex startEndpoint, IntersectionVertex endEndpoint, - OSMWay way, + OsmWay way, int index, StreetTraversalPermission permissions, LineString geometry @@ -516,7 +527,7 @@ private StreetEdgePair getEdgesForStreet( private StreetEdge getEdgeForStreet( IntersectionVertex startEndpoint, IntersectionVertex endEndpoint, - OSMWay way, + OsmWay way, int index, double length, StreetTraversalPermission permissions, diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModuleBuilder.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModuleBuilder.java similarity index 88% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModuleBuilder.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModuleBuilder.java index f0a40fa678f..2f7f4c506c9 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModuleBuilder.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModuleBuilder.java @@ -6,8 +6,9 @@ import org.opentripplanner.graph_builder.module.osm.naming.DefaultNamer; import org.opentripplanner.graph_builder.module.osm.parameters.OsmProcessingParameters; import org.opentripplanner.graph_builder.services.osm.EdgeNamer; -import org.opentripplanner.openstreetmap.OsmProvider; +import org.opentripplanner.osm.OsmProvider; import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; import org.opentripplanner.street.model.StreetLimitationParameters; /** @@ -17,6 +18,7 @@ public class OsmModuleBuilder { private final Collection providers; private final Graph graph; + private final VehicleParkingRepository parkingRepository; private Set boardingAreaRefTags = Set.of(); private DataImportIssueStore issueStore = DataImportIssueStore.NOOP; private EdgeNamer edgeNamer = new DefaultNamer(); @@ -27,9 +29,14 @@ public class OsmModuleBuilder { private int maxAreaNodes; private StreetLimitationParameters streetLimitationParameters = new StreetLimitationParameters(); - OsmModuleBuilder(Collection providers, Graph graph) { + OsmModuleBuilder( + Collection providers, + Graph graph, + VehicleParkingRepository parkingRepository + ) { this.providers = providers; this.graph = graph; + this.parkingRepository = parkingRepository; } public OsmModuleBuilder withBoardingAreaRefTags(Set boardingAreaRefTags) { @@ -81,6 +88,7 @@ public OsmModule build() { return new OsmModule( providers, graph, + parkingRepository, issueStore, streetLimitationParameters, new OsmProcessingParameters( diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessor.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessor.java similarity index 92% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessor.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessor.java index 940ffa68198..af8eb8e6e61 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessor.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessor.java @@ -20,13 +20,13 @@ import org.opentripplanner.graph_builder.issues.InvalidVehicleParkingCapacity; import org.opentripplanner.graph_builder.issues.ParkAndRideUnlinked; import org.opentripplanner.model.calendar.openinghours.OHCalendar; -import org.opentripplanner.openstreetmap.OSMOpeningHoursParser; -import org.opentripplanner.openstreetmap.model.OSMNode; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.OsmOpeningHoursParser; +import org.opentripplanner.osm.model.OsmNode; +import org.opentripplanner.osm.model.OsmWithTags; import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingHelper; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingHelper; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.edge.VehicleParkingEdge; @@ -43,26 +43,26 @@ class ParkingProcessor { private static final Logger LOG = LoggerFactory.getLogger(ParkingProcessor.class); private static final String VEHICLE_PARKING_OSM_FEED_ID = "OSM"; private final DataImportIssueStore issueStore; - private final OSMOpeningHoursParser osmOpeningHoursParser; - private final BiFunction getVertexForOsmNode; + private final OsmOpeningHoursParser osmOpeningHoursParser; + private final BiFunction getVertexForOsmNode; private final VertexFactory vertexFactory; private final VehicleParkingHelper vehicleParkingHelper; public ParkingProcessor( Graph graph, DataImportIssueStore issueStore, - BiFunction getVertexForOsmNode + BiFunction getVertexForOsmNode ) { this.issueStore = issueStore; this.getVertexForOsmNode = getVertexForOsmNode; this.osmOpeningHoursParser = - new OSMOpeningHoursParser(graph.getOpeningHoursCalendarService(), issueStore); + new OsmOpeningHoursParser(graph.getOpeningHoursCalendarService(), issueStore); this.vertexFactory = new VertexFactory(graph); this.vehicleParkingHelper = new VehicleParkingHelper(graph); } public List buildParkAndRideNodes( - Collection nodes, + Collection nodes, boolean isCarParkAndRide ) { LOG.info("Processing {} P+R nodes.", isCarParkAndRide ? "car" : "bike"); @@ -70,7 +70,7 @@ public List buildParkAndRideNodes( List vehicleParkingToAdd = new ArrayList<>(); - for (OSMNode node : nodes) { + for (OsmNode node : nodes) { n++; I18NString creativeName = nameParkAndRideEntity(node); @@ -130,7 +130,7 @@ private List buildParkAndRideAreasForGroups( return vehicleParkingToAdd; } - private OHCalendar parseOpeningHours(OSMWithTags entity) { + private OHCalendar parseOpeningHours(OsmWithTags entity) { final var openingHoursTag = entity.getTag("opening_hours"); if (openingHoursTag != null) { final ZoneId zoneId = entity.getOsmProvider().getZoneId(); @@ -145,7 +145,7 @@ private OHCalendar parseOpeningHours(OSMWithTags entity) { ); } catch (OpeningHoursParseException e) { issueStore.add( - "OSMOpeningHoursUnparsed", + "OsmOpeningHoursUnparsed", "OSM object with id '%s' (%s) has an invalid opening_hours value, it will always be open", id, link @@ -164,11 +164,11 @@ private List processVehicleParkingArea(Area area, Envelope envelo private List processVehicleParkingArea( Ring ring, - OSMWithTags entity, + OsmWithTags entity, Envelope envelope ) { List accessVertices = new ArrayList<>(); - for (OSMNode node : ring.nodes) { + for (OsmNode node : ring.nodes) { envelope.expandToInclude(new Coordinate(node.lon, node.lat)); var accessVertex = getVertexForOsmNode.apply(node, entity); if (accessVertex.getIncoming().isEmpty() || accessVertex.getOutgoing().isEmpty()) { @@ -192,7 +192,7 @@ private VehicleParking buildParkAndRideAreasForGroup(AreaGroup group, boolean is Envelope envelope = new Envelope(); Set accessVertices = new HashSet<>(); - OSMWithTags entity = null; + OsmWithTags entity = null; // Process all nodes from outer rings // These are IntersectionVertices not OsmVertices because there can be both OsmVertices and TransitStopStreetVertices. @@ -288,7 +288,7 @@ private VehicleParking buildParkAndRideAreasForGroup(AreaGroup group, boolean is private List createArtificialEntrances( AreaGroup group, I18NString vehicleParkingName, - OSMWithTags entity, + OsmWithTags entity, boolean isCarPark ) { LOG.debug( @@ -312,10 +312,10 @@ private List createArtificialEntra ); } - private VehicleParking createVehicleParkingObjectFromOsmEntity( + VehicleParking createVehicleParkingObjectFromOsmEntity( boolean isCarParkAndRide, Coordinate coordinate, - OSMWithTags entity, + OsmWithTags entity, I18NString creativeName, List entrances ) { @@ -395,7 +395,7 @@ private VehicleParking createVehicleParkingObjectFromOsmEntity( .build(); } - private I18NString nameParkAndRideEntity(OSMWithTags osmWithTags) { + private I18NString nameParkAndRideEntity(OsmWithTags osmWithTags) { // If there is an explicit name user that. The explicit name is used so that tag-based // translations are used, which are not handled by "CreativeNamer"s. I18NString creativeName = osmWithTags.getAssumedName(); @@ -416,12 +416,12 @@ private I18NString nameParkAndRideEntity(OSMWithTags osmWithTags) { return creativeName; } - private OptionalInt parseCapacity(OSMWithTags element) { + private OptionalInt parseCapacity(OsmWithTags element) { return parseCapacity(element, "capacity"); } - private OptionalInt parseCapacity(OSMWithTags element, String capacityTag) { - return element.getTagAsInt( + private OptionalInt parseCapacity(OsmWithTags element, String capacityTag) { + return element.parseIntOrBoolean( capacityTag, v -> issueStore.add(new InvalidVehicleParkingCapacity(element, v)) ); @@ -430,7 +430,7 @@ private OptionalInt parseCapacity(OSMWithTags element, String capacityTag) { private List createParkingEntrancesFromAccessVertices( Set accessVertices, I18NString vehicleParkingName, - OSMWithTags entity + OsmWithTags entity ) { List entrances = new ArrayList<>(); var sortedAccessVertices = accessVertices diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/Ring.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/Ring.java similarity index 91% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/Ring.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/Ring.java index 754bdbc36b2..53209c0ea8e 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/Ring.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/Ring.java @@ -17,20 +17,20 @@ import org.locationtech.jts.geom.Polygon; import org.opentripplanner.framework.geometry.CoordinateArrayListSequence; import org.opentripplanner.framework.geometry.GeometryUtils; -import org.opentripplanner.openstreetmap.model.OSMNode; +import org.opentripplanner.osm.model.OsmNode; class Ring { private final LinearRing shell; private final List holes = new ArrayList<>(); - public List nodes; + public List nodes; // equivalent to the ring representation, but used for JTS operations public Polygon jtsPolygon; - public Ring(List osmNodes) { + public Ring(List osmNodes) { ArrayList vertices = new ArrayList<>(); nodes = osmNodes; - for (OSMNode node : osmNodes) { + for (OsmNode node : osmNodes) { Coordinate point = new Coordinate(node.lon, node.lat); vertices.add(point); } @@ -49,7 +49,7 @@ public Ring(List osmNodes) { jtsPolygon = calculateJtsPolygon(); } - public Ring(TLongList osmNodes, TLongObjectMap _nodes) { + public Ring(TLongList osmNodes, TLongObjectMap _nodes) { // The collection needs to be mutable, so collect into an ArrayList this( LongStream @@ -73,9 +73,9 @@ public void addHole(Ring hole) { */ boolean isNodeConvex(int i) { int n = nodes.size() - 1; - OSMNode cur = nodes.get(i); - OSMNode prev = nodes.get((i + n - 1) % n); - OSMNode next = nodes.get((i + 1) % n); + OsmNode cur = nodes.get(i); + OsmNode prev = nodes.get((i + n - 1) % n); + OsmNode next = nodes.get((i + 1) % n); return ( (cur.lon - prev.lon) * (next.lat - cur.lat) - (cur.lat - prev.lat) * (next.lon - cur.lon) > 0 ); diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/SafetyValueNormalizer.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/SafetyValueNormalizer.java similarity index 92% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/SafetyValueNormalizer.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/SafetyValueNormalizer.java index a9603d59417..2cb5b01dcc6 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/SafetyValueNormalizer.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/SafetyValueNormalizer.java @@ -4,9 +4,9 @@ import java.util.Set; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issues.Graphwide; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.tagmapping.OsmTagMapper; -import org.opentripplanner.openstreetmap.wayproperty.WayProperties; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.tagmapping.OsmTagMapper; +import org.opentripplanner.osm.wayproperty.WayProperties; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.street.model.edge.AreaEdge; import org.opentripplanner.street.model.edge.AreaEdgeList; @@ -77,7 +77,7 @@ void applyWayProperties( StreetEdge street, StreetEdge backStreet, WayProperties wayData, - OSMWithTags way + OsmWithTags way ) { OsmTagMapper tagMapperForWay = way.getOsmProvider().getOsmTagMapper(); @@ -86,8 +86,8 @@ void applyWayProperties( boolean motorVehicleNoThrough = tagMapperForWay.isMotorVehicleThroughTrafficExplicitlyDisallowed( way ); - boolean bicycleNoThrough = tagMapperForWay.isBicycleNoThroughTrafficExplicitlyDisallowed(way); - boolean walkNoThrough = tagMapperForWay.isWalkNoThroughTrafficExplicitlyDisallowed(way); + boolean bicycleNoThrough = tagMapperForWay.isBicycleThroughTrafficExplicitlyDisallowed(way); + boolean walkNoThrough = tagMapperForWay.isWalkThroughTrafficExplicitlyDisallowed(way); if (street != null) { double bicycleSafety = wayData.bicycleSafety().forward(); diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/StreetEdgePair.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/StreetEdgePair.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/StreetEdgePair.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/StreetEdgePair.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/StreetTraversalPermissionPair.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/StreetTraversalPermissionPair.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/StreetTraversalPermissionPair.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/StreetTraversalPermissionPair.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionTag.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionTag.java similarity index 91% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionTag.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionTag.java index 8bd1464667c..6d6e2af1c18 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionTag.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionTag.java @@ -15,7 +15,7 @@ class TurnRestrictionTag { long via; //Used only for issues so that it can be visualized in a map - long relationOSMID; + long relationOsmID; TurnRestrictionType type; Direction direction; RepeatingTimePeriod time; @@ -23,11 +23,11 @@ class TurnRestrictionTag { public List possibleTo = new ArrayList<>(); public TraverseModeSet modes; - TurnRestrictionTag(long via, TurnRestrictionType type, Direction direction, long relationOSMID) { + TurnRestrictionTag(long via, TurnRestrictionType type, Direction direction, long relationOsmID) { this.via = via; this.type = type; this.direction = direction; - this.relationOSMID = relationOSMID; + this.relationOsmID = relationOsmID; } @Override diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionUnifier.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionUnifier.java similarity index 88% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionUnifier.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionUnifier.java index fc645bd16da..ca0bc4f146b 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionUnifier.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/TurnRestrictionUnifier.java @@ -14,25 +14,25 @@ static void unifyTurnRestrictions(OsmDatabase osmdb, DataImportIssueStore issueS for (TurnRestrictionTag restrictionTag : osmdb.getFromWayTurnRestrictions(fromWay)) { if (restrictionTag.possibleFrom.isEmpty()) { issueStore.add( - new TurnRestrictionBad(restrictionTag.relationOSMID, "No from edge found") + new TurnRestrictionBad(restrictionTag.relationOsmID, "No from edge found") ); continue; } if (restrictionTag.possibleTo.isEmpty()) { - issueStore.add(new TurnRestrictionBad(restrictionTag.relationOSMID, "No to edge found")); + issueStore.add(new TurnRestrictionBad(restrictionTag.relationOsmID, "No to edge found")); continue; } for (StreetEdge from : restrictionTag.possibleFrom) { if (from == null) { issueStore.add( - new TurnRestrictionBad(restrictionTag.relationOSMID, "from-edge is null") + new TurnRestrictionBad(restrictionTag.relationOsmID, "from-edge is null") ); continue; } for (StreetEdge to : restrictionTag.possibleTo) { if (to == null) { issueStore.add( - new TurnRestrictionBad(restrictionTag.relationOSMID, "to-edge is null") + new TurnRestrictionBad(restrictionTag.relationOsmID, "to-edge is null") ); continue; } @@ -45,7 +45,7 @@ static void unifyTurnRestrictions(OsmDatabase osmdb, DataImportIssueStore issueS if (angleDiff >= 160) { issueStore.add( new TurnRestrictionBad( - restrictionTag.relationOSMID, + restrictionTag.relationOsmID, "Left turn restriction is not on edges which turn left" ) ); @@ -56,7 +56,7 @@ static void unifyTurnRestrictions(OsmDatabase osmdb, DataImportIssueStore issueS if (angleDiff <= 200) { issueStore.add( new TurnRestrictionBad( - restrictionTag.relationOSMID, + restrictionTag.relationOsmID, "Right turn restriction is not on edges which turn right" ) ); @@ -67,7 +67,7 @@ static void unifyTurnRestrictions(OsmDatabase osmdb, DataImportIssueStore issueS if ((angleDiff <= 150 || angleDiff > 210)) { issueStore.add( new TurnRestrictionBad( - restrictionTag.relationOSMID, + restrictionTag.relationOsmID, "U-turn restriction is not on U-turn" ) ); @@ -78,7 +78,7 @@ static void unifyTurnRestrictions(OsmDatabase osmdb, DataImportIssueStore issueS if (angleDiff >= 30 && angleDiff < 330) { issueStore.add( new TurnRestrictionBad( - restrictionTag.relationOSMID, + restrictionTag.relationOsmID, "Straight turn restriction is not on edges which go straight" ) ); diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/UnconnectedArea.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/UnconnectedArea.java similarity index 93% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/UnconnectedArea.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/UnconnectedArea.java index 5dd5f851ac2..85366ed66db 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/UnconnectedArea.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/UnconnectedArea.java @@ -16,7 +16,7 @@ public String getMessage() { @Override public String getHTMLMessage() { - return String.format(HTMLFMT, areaGroup.getSomeOSMObject().url(), idList()); + return String.format(HTMLFMT, areaGroup.getSomeOsmObject().url(), idList()); } @Override diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java similarity index 90% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java index 14489777dd4..e6fec74b798 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java @@ -8,10 +8,10 @@ import java.util.Set; import org.locationtech.jts.geom.Coordinate; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.openstreetmap.model.OSMLevel; -import org.opentripplanner.openstreetmap.model.OSMNode; -import org.opentripplanner.openstreetmap.model.OSMWay; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmLevel; +import org.opentripplanner.osm.model.OsmNode; +import org.opentripplanner.osm.model.OsmWay; +import org.opentripplanner.osm.model.OsmWithTags; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.street.model.edge.ElevatorEdge; import org.opentripplanner.street.model.vertex.BarrierVertex; @@ -30,7 +30,7 @@ class VertexGenerator { private final Map intersectionNodes = new HashMap<>(); - private final HashMap> multiLevelNodes = new HashMap<>(); + private final HashMap> multiLevelNodes = new HashMap<>(); private final OsmDatabase osmdb; private final Set boardingAreaRefTags; private final VertexFactory vertexFactory; @@ -51,7 +51,7 @@ public VertexGenerator(OsmDatabase osmdb, Graph graph, Set boardingAreaR * @return vertex The graph vertex. This is not always an OSM vertex; it can also be a * {@link OsmBoardingLocationVertex} */ - IntersectionVertex getVertexForOsmNode(OSMNode node, OSMWithTags way) { + IntersectionVertex getVertexForOsmNode(OsmNode node, OsmWithTags way) { // If the node should be decomposed to multiple levels, // use the numeric level because it is unique, the human level may not be (although // it will likely lead to some head-scratching if it is not). @@ -115,13 +115,13 @@ IntersectionVertex getVertexForOsmNode(OSMNode node, OSMWithTags way) { * Tracks OSM nodes which are decomposed into multiple graph vertices because they are * elevators. They can then be iterated over to build {@link ElevatorEdge} between them. */ - Map> multiLevelNodes() { + Map> multiLevelNodes() { return multiLevelNodes; } void initIntersectionNodes() { Set possibleIntersectionNodes = new HashSet<>(); - for (OSMWay way : osmdb.getWays()) { + for (OsmWay way : osmdb.getWays()) { TLongList nodes = way.getNodeRefs(); nodes.forEach(node -> { if (possibleIntersectionNodes.contains(node)) { @@ -159,9 +159,9 @@ Map intersectionNodes() { * @param node the node to record for * @author mattwigway */ - private OsmVertex recordLevel(OSMNode node, OSMWithTags way) { - OSMLevel level = osmdb.getLevelForWay(way); - Map vertices; + private OsmVertex recordLevel(OsmNode node, OsmWithTags way) { + OsmLevel level = osmdb.getLevelForWay(way); + Map vertices; long nodeId = node.getId(); if (multiLevelNodes.containsKey(nodeId)) { vertices = multiLevelNodes.get(nodeId); @@ -179,7 +179,7 @@ private OsmVertex recordLevel(OSMNode node, OSMWithTags way) { } private void intersectAreaRingNodes(Set possibleIntersectionNodes, Ring outerRing) { - for (OSMNode node : outerRing.nodes) { + for (OsmNode node : outerRing.nodes) { long nodeId = node.getId(); if (possibleIntersectionNodes.contains(nodeId)) { intersectionNodes.put(nodeId, null); diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilder.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilder.java similarity index 92% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilder.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilder.java index 89b71403232..2802ee70a89 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilder.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilder.java @@ -26,11 +26,11 @@ import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.services.osm.EdgeNamer; -import org.opentripplanner.openstreetmap.model.OSMNode; -import org.opentripplanner.openstreetmap.model.OSMRelation; -import org.opentripplanner.openstreetmap.model.OSMRelationMember; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.WayProperties; +import org.opentripplanner.osm.model.OsmNode; +import org.opentripplanner.osm.model.OsmRelation; +import org.opentripplanner.osm.model.OsmRelationMember; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.WayProperties; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.api.request.request.StreetRequest; @@ -78,7 +78,7 @@ class WalkableAreaBuilder { private final OsmDatabase osmdb; - private final Map wayPropertiesCache = new HashMap<>(); + private final Map wayPropertiesCache = new HashMap<>(); private final VertexGenerator vertexBuilder; @@ -179,7 +179,7 @@ public void buildWithoutVisibility(AreaGroup group) { public void buildWithVisibility(AreaGroup group) { // These sets contain the nodes/vertices which can be used to traverse from the rest of the // street network onto the walkable area - Set startingNodes = new HashSet<>(); + Set startingNodes = new HashSet<>(); Set startingVertices = new HashSet<>(); // List of edges belonging to the walkable area @@ -194,8 +194,8 @@ public void buildWithVisibility(AreaGroup group) { .stream() .map(area -> area.parent) .flatMap(osmWithTags -> - osmWithTags instanceof OSMRelation - ? ((OSMRelation) osmWithTags).getMembers().stream().map(OSMRelationMember::getRef) + osmWithTags instanceof OsmRelation + ? ((OsmRelation) osmWithTags).getMembers().stream().map(OsmRelationMember::getRef) : Stream.of(osmWithTags.getId()) ) .collect(Collectors.toSet()); @@ -210,7 +210,7 @@ public void buildWithVisibility(AreaGroup group) { // the points corresponding to concave or hole vertices // or those linked to ways - HashSet visibilityNodes = new HashSet<>(); + HashSet visibilityNodes = new HashSet<>(); HashSet alreadyAddedEdges = new HashSet<>(); HashSet platformLinkingVertices = new HashSet<>(); // we need to accumulate visibility points from all contained areas @@ -219,7 +219,7 @@ public void buildWithVisibility(AreaGroup group) { GeometryFactory geometryFactory = GeometryUtils.getGeometryFactory(); - OSMWithTags areaEntity = group.getSomeOSMObject(); + OsmWithTags areaEntity = group.getSomeOsmObject(); // we also want to fill in the edges of this area anyway, because we can, // and to avoid the numerical problems that they tend to cause @@ -231,8 +231,8 @@ public void buildWithVisibility(AreaGroup group) { // Add stops/entrances from public transit relations into the area // they may provide the only entrance to a platform // which otherwise would be pruned as unconnected island - Collection entrances = osmdb.getStopsInArea(area.parent); - for (OSMNode node : entrances) { + Collection entrances = osmdb.getStopsInArea(area.parent); + for (OsmNode node : entrances) { var vertex = vertexBuilder.getVertexForOsmNode(node, areaEntity); platformLinkingVertices.add(vertex); visibilityNodes.add(node); @@ -253,7 +253,7 @@ public void buildWithVisibility(AreaGroup group) { .toList(); platformLinkingVertices.addAll(endpointsWithin); for (OsmVertex v : endpointsWithin) { - OSMNode node = osmdb.getNode(v.nodeId); + OsmNode node = osmdb.getNode(v.nodeId); visibilityNodes.add(node); startingNodes.add(node); edgeList.addVisibilityVertex(v); @@ -262,7 +262,7 @@ public void buildWithVisibility(AreaGroup group) { } for (int i = 0; i < outerRing.nodes.size(); ++i) { - OSMNode node = outerRing.nodes.get(i); + OsmNode node = outerRing.nodes.get(i); Set newEdges = createEdgesForRingSegment( edgeList, area, @@ -292,7 +292,7 @@ public void buildWithVisibility(AreaGroup group) { } for (Ring innerRing : outerRing.getHoles()) { for (int j = 0; j < innerRing.nodes.size(); ++j) { - OSMNode node = innerRing.nodes.get(j); + OsmNode node = innerRing.nodes.get(j); edges.addAll( createEdgesForRingSegment(edgeList, area, innerRing, j, alreadyAddedEdges) ); @@ -334,7 +334,7 @@ public void buildWithVisibility(AreaGroup group) { float skip_ratio = (float) maxAreaNodes / (float) visibilityNodes.size(); int i = 0; float sum_i = 0; - for (OSMNode nodeI : visibilityNodes) { + for (OsmNode nodeI : visibilityNodes) { sum_i += skip_ratio; if (Math.floor(sum_i) < i + 1) { continue; @@ -346,7 +346,7 @@ public void buildWithVisibility(AreaGroup group) { } int j = 0; float sum_j = 0; - for (OSMNode nodeJ : visibilityNodes) { + for (OsmNode nodeJ : visibilityNodes) { sum_j += skip_ratio; if (Math.floor(sum_j) < j + 1) { continue; @@ -437,7 +437,7 @@ private void pruneAreaEdges( } } - private boolean isStartingNode(OSMNode node, Set osmWayIds) { + private boolean isStartingNode(OsmNode node, Set osmWayIds) { return ( osmdb.isNodeBelongsToWay(node.getId()) || // Do not add if part of same areaGroup @@ -456,8 +456,8 @@ private Set createEdgesForRingSegment( int i, HashSet alreadyAddedEdges ) { - OSMNode node = ring.nodes.get(i); - OSMNode nextNode = ring.nodes.get((i + 1) % ring.nodes.size()); + OsmNode node = ring.nodes.get(i); + OsmNode nextNode = ring.nodes.get((i + 1) % ring.nodes.size()); NodeEdge nodeEdge = new NodeEdge(node, nextNode); if (alreadyAddedEdges.contains(nodeEdge)) { return Set.of(); @@ -497,11 +497,16 @@ private Set createSegments( // do we need to recurse? if (intersects.size() == 1) { Area area = intersects.getFirst(); - OSMWithTags areaEntity = area.parent; + OsmWithTags areaEntity = area.parent; - StreetTraversalPermission areaPermissions = areaEntity.overridePermissions( - StreetTraversalPermission.PEDESTRIAN_AND_BICYCLE - ); + WayProperties wayData; + if (!wayPropertiesCache.containsKey(areaEntity)) { + wayData = areaEntity.getOsmProvider().getWayPropertySet().getDataForWay(areaEntity); + wayPropertiesCache.put(areaEntity, wayData); + } else { + wayData = wayPropertiesCache.get(areaEntity); + } + StreetTraversalPermission areaPermissions = wayData.getPermission(); float carSpeed = areaEntity .getOsmProvider() @@ -520,8 +525,8 @@ private Set createSegments( startEndpoint.getLabel() + " to " + endEndpoint.getLabel(); - I18NString name = namer.getNameForWay(areaEntity, label); + I18NString name = namer.getNameForWay(areaEntity, label); AreaEdgeBuilder streetEdgeBuilder = new AreaEdgeBuilder() .withFromVertex(startEndpoint) .withToVertex(endEndpoint) @@ -543,8 +548,8 @@ private Set createSegments( endEndpoint.getLabel() + " to " + startEndpoint.getLabel(); - name = namer.getNameForWay(areaEntity, label); + name = namer.getNameForWay(areaEntity, label); AreaEdgeBuilder backStreetEdgeBuilder = new AreaEdgeBuilder() .withFromVertex(endEndpoint) .withToVertex(startEndpoint) @@ -559,22 +564,10 @@ private Set createSegments( .withWheelchairAccessible(areaEntity.isWheelchairAccessible()) .withLink(areaEntity.isLink()); - if (!wayPropertiesCache.containsKey(areaEntity)) { - WayProperties wayData = areaEntity - .getOsmProvider() - .getWayPropertySet() - .getDataForWay(areaEntity); - wayPropertiesCache.put(areaEntity, wayData); - } - AreaEdge street = streetEdgeBuilder.buildAndConnect(); + AreaEdge backStreet = backStreetEdgeBuilder.buildAndConnect(); - normalizer.applyWayProperties( - street, - backStreet, - wayPropertiesCache.get(areaEntity), - areaEntity - ); + normalizer.applyWayProperties(street, backStreet, wayData, areaEntity); return Set.of(street, backStreet); } else { // take the part that intersects with the start vertex @@ -634,18 +627,18 @@ private void createNamedAreas(AreaEdgeList edgeList, Ring ring, Collection continue; } NamedArea namedArea = new NamedArea(); - OSMWithTags areaEntity = area.parent; + OsmWithTags areaEntity = area.parent; String id = "way (area) " + areaEntity.getId() + " (splitter linking)"; I18NString name = namer.getNameForWay(areaEntity, id); namedArea.setName(name); + WayProperties wayData; if (!wayPropertiesCache.containsKey(areaEntity)) { - WayProperties wayData = areaEntity - .getOsmProvider() - .getWayPropertySet() - .getDataForWay(areaEntity); + wayData = areaEntity.getOsmProvider().getWayPropertySet().getDataForWay(areaEntity); wayPropertiesCache.put(areaEntity, wayData); + } else { + wayData = wayPropertiesCache.get(areaEntity); } double bicycleSafety = wayPropertiesCache.get(areaEntity).bicycleSafety().forward(); @@ -653,14 +646,8 @@ private void createNamedAreas(AreaEdgeList edgeList, Ring ring, Collection double walkSafety = wayPropertiesCache.get(areaEntity).walkSafety().forward(); namedArea.setWalkSafetyMultiplier(walkSafety); - namedArea.setOriginalEdges(intersection); - - StreetTraversalPermission permission = areaEntity.overridePermissions( - StreetTraversalPermission.PEDESTRIAN_AND_BICYCLE - ); - namedArea.setPermission(permission); - + namedArea.setPermission(wayData.getPermission()); edgeList.addArea(namedArea); } } @@ -700,5 +687,5 @@ public boolean shouldSkipEdge(State current, Edge edge) { } } - private record NodeEdge(OSMNode from, OSMNode to) {} + private record NodeEdge(OsmNode from, OsmNode to) {} } diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/naming/DefaultNamer.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/naming/DefaultNamer.java similarity index 70% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/naming/DefaultNamer.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/naming/DefaultNamer.java index ff7b7d17666..4e8cdaeee08 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/naming/DefaultNamer.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/naming/DefaultNamer.java @@ -3,17 +3,17 @@ import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; import org.opentripplanner.graph_builder.services.osm.EdgeNamer; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; public class DefaultNamer implements EdgeNamer { @Override - public I18NString name(OSMWithTags way) { + public I18NString name(OsmWithTags way) { return way.getAssumedName(); } @Override - public void recordEdges(OSMWithTags way, StreetEdgePair edge) {} + public void recordEdges(OsmWithTags way, StreetEdgePair edge) {} @Override public void postprocess() {} diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/naming/PortlandCustomNamer.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/naming/PortlandCustomNamer.java similarity index 94% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/naming/PortlandCustomNamer.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/naming/PortlandCustomNamer.java index c0ca595fbd7..e05bc736cbb 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/naming/PortlandCustomNamer.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/naming/PortlandCustomNamer.java @@ -5,7 +5,7 @@ import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; import org.opentripplanner.graph_builder.services.osm.EdgeNamer; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; import org.opentripplanner.street.model.edge.StreetEdge; /** @@ -45,7 +45,7 @@ public class PortlandCustomNamer implements EdgeNamer { private final HashSet nameByDestination = new HashSet<>(); @Override - public I18NString name(OSMWithTags way) { + public I18NString name(OsmWithTags way) { var defaultName = way.getAssumedName(); if (!way.hasTag("name")) { // this is already a generated name, so there's no need to add any @@ -70,7 +70,7 @@ public I18NString name(OSMWithTags way) { } @Override - public void recordEdges(OSMWithTags way, StreetEdgePair edgePair) { + public void recordEdges(OsmWithTags way, StreetEdgePair edgePair) { final boolean isHighwayLink = isHighwayLink(way); final boolean isLowerLink = isLowerLink(way); edgePair @@ -186,12 +186,12 @@ private static String nameAccordingToOrigin(StreetEdge e, int maxDepth) { return null; } - private static boolean isHighwayLink(OSMWithTags way) { + private static boolean isHighwayLink(OsmWithTags way) { String highway = way.getTag("highway"); return "motorway_link".equals(highway) || "trunk_link".equals(highway); } - private static boolean isLowerLink(OSMWithTags way) { + private static boolean isLowerLink(OsmWithTags way) { String highway = way.getTag("highway"); return ( "secondary_link".equals(highway) || diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/naming/SidewalkNamer.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/naming/SidewalkNamer.java similarity index 97% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/naming/SidewalkNamer.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/naming/SidewalkNamer.java index eafccc0da1b..582684d3bea 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/naming/SidewalkNamer.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/naming/SidewalkNamer.java @@ -27,12 +27,12 @@ import org.opentripplanner.framework.geometry.HashGridSpatialIndex; import org.opentripplanner.framework.geometry.SphericalDistanceLibrary; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.lang.DoubleUtils; -import org.opentripplanner.framework.logging.ProgressTracker; import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; import org.opentripplanner.graph_builder.services.osm.EdgeNamer; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; import org.opentripplanner.street.model.edge.StreetEdge; +import org.opentripplanner.utils.lang.DoubleUtils; +import org.opentripplanner.utils.logging.ProgressTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -65,12 +65,12 @@ public class SidewalkNamer implements EdgeNamer { private PreciseBuffer preciseBuffer; @Override - public I18NString name(OSMWithTags way) { + public I18NString name(OsmWithTags way) { return way.getAssumedName(); } @Override - public void recordEdges(OSMWithTags way, StreetEdgePair pair) { + public void recordEdges(OsmWithTags way, StreetEdgePair pair) { // This way is a sidewalk and hasn't been named yet (and is not explicitly unnamed) if (way.isSidewalk() && way.hasNoName() && !way.isExplicitlyUnnamed()) { pair diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java similarity index 94% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java index 9d2eead5f7e..175b9c04c5b 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java @@ -4,7 +4,7 @@ import java.time.ZoneId; import javax.annotation.Nullable; import org.opentripplanner.graph_builder.model.DataSourceConfig; -import org.opentripplanner.openstreetmap.tagmapping.OsmTagMapperSource; +import org.opentripplanner.osm.tagmapping.OsmTagMapperSource; /** * Configure an OpenStreetMap extract. diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersBuilder.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersBuilder.java similarity index 95% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersBuilder.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersBuilder.java index 03fd7eaec4e..2d9bb71d9f5 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersBuilder.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersBuilder.java @@ -2,7 +2,7 @@ import java.net.URI; import java.time.ZoneId; -import org.opentripplanner.openstreetmap.tagmapping.OsmTagMapperSource; +import org.opentripplanner.osm.tagmapping.OsmTagMapperSource; /** * Configure an OpenStreetMap extract. diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersList.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersList.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersList.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersList.java diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmProcessingParameters.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmProcessingParameters.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmProcessingParameters.java rename to application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmProcessingParameters.java diff --git a/src/main/java/org/opentripplanner/graph_builder/services/ned/ElevationGridCoverageFactory.java b/application/src/main/java/org/opentripplanner/graph_builder/services/ned/ElevationGridCoverageFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/services/ned/ElevationGridCoverageFactory.java rename to application/src/main/java/org/opentripplanner/graph_builder/services/ned/ElevationGridCoverageFactory.java diff --git a/src/main/java/org/opentripplanner/graph_builder/services/ned/NEDTileSource.java b/application/src/main/java/org/opentripplanner/graph_builder/services/ned/NEDTileSource.java similarity index 100% rename from src/main/java/org/opentripplanner/graph_builder/services/ned/NEDTileSource.java rename to application/src/main/java/org/opentripplanner/graph_builder/services/ned/NEDTileSource.java diff --git a/src/main/java/org/opentripplanner/graph_builder/services/osm/EdgeNamer.java b/application/src/main/java/org/opentripplanner/graph_builder/services/osm/EdgeNamer.java similarity index 87% rename from src/main/java/org/opentripplanner/graph_builder/services/osm/EdgeNamer.java rename to application/src/main/java/org/opentripplanner/graph_builder/services/osm/EdgeNamer.java index 60cf780f714..215a5fefc18 100644 --- a/src/main/java/org/opentripplanner/graph_builder/services/osm/EdgeNamer.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/services/osm/EdgeNamer.java @@ -1,13 +1,12 @@ package org.opentripplanner.graph_builder.services.osm; -import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; import org.opentripplanner.graph_builder.module.osm.naming.DefaultNamer; import org.opentripplanner.graph_builder.module.osm.naming.PortlandCustomNamer; import org.opentripplanner.graph_builder.module.osm.naming.SidewalkNamer; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; import org.opentripplanner.standalone.config.framework.json.OtpVersion; @@ -19,21 +18,21 @@ public interface EdgeNamer { /** * Get the edge name from an OSM way. */ - I18NString name(OSMWithTags way); + I18NString name(OsmWithTags way); /** * Callback function for each way/edge combination so that more complicated names can be built * in the post-processing step. */ - void recordEdges(OSMWithTags way, StreetEdgePair edge); + void recordEdges(OsmWithTags way, StreetEdgePair edge); /** * Called after each edge has been named to build a more complex name out of the relationships - * tracked in {@link EdgeNamer#recordEdges(OSMWithTags, StreetEdgePair)}. + * tracked in {@link EdgeNamer#recordEdges(OsmWithTags, StreetEdgePair)}. */ void postprocess(); - default I18NString getNameForWay(OSMWithTags way, @Nonnull String id) { + default I18NString getNameForWay(OsmWithTags way, String id) { var name = name(way); if (name == null) { diff --git a/src/main/java/org/opentripplanner/gtfs/GenerateTripPatternsOperation.java b/application/src/main/java/org/opentripplanner/gtfs/GenerateTripPatternsOperation.java similarity index 76% rename from src/main/java/org/opentripplanner/gtfs/GenerateTripPatternsOperation.java rename to application/src/main/java/org/opentripplanner/gtfs/GenerateTripPatternsOperation.java index bf26f9c6d7b..e647bc4cb9e 100644 --- a/src/main/java/org/opentripplanner/gtfs/GenerateTripPatternsOperation.java +++ b/application/src/main/java/org/opentripplanner/gtfs/GenerateTripPatternsOperation.java @@ -3,13 +3,13 @@ import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; import com.google.common.collect.Multimap; +import com.google.common.collect.MultimapBuilder; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.opentripplanner.ext.flex.trip.FlexTrip; -import org.opentripplanner.framework.logging.ProgressTracker; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issues.TripDegenerate; import org.opentripplanner.graph_builder.issues.TripUndefinedService; @@ -23,11 +23,13 @@ import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.StopPattern; import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.network.TripPatternBuilder; import org.opentripplanner.transit.model.timetable.Direction; import org.opentripplanner.transit.model.timetable.FrequencyEntry; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.model.timetable.TripTimesFactory; +import org.opentripplanner.utils.logging.ProgressTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,13 +42,18 @@ public class GenerateTripPatternsOperation { private final Map tripPatternIdCounters = new HashMap<>(); - private final OtpTransitServiceBuilder transitDaoBuilder; + private final OtpTransitServiceBuilder transitServiceBuilder; private final DataImportIssueStore issueStore; private final Deduplicator deduplicator; private final Set calendarServiceIds; private final GeometryProcessor geometryProcessor; - private final Multimap tripPatterns; + // TODO the linked hashset configuration ensures that TripPatterns are created in the same order + // as Trips are imported, as a workaround for issue #6067 + private final Multimap tripPatternBuilders = MultimapBuilder + .linkedHashKeys() + .linkedHashSetValues() + .build(); private final ListMultimap frequenciesForTrip = ArrayListMultimap.create(); private int freqCount = 0; @@ -59,18 +66,17 @@ public GenerateTripPatternsOperation( Set calendarServiceIds, GeometryProcessor geometryProcessor ) { - this.transitDaoBuilder = builder; + this.transitServiceBuilder = builder; this.issueStore = issueStore; this.deduplicator = deduplicator; this.calendarServiceIds = calendarServiceIds; this.geometryProcessor = geometryProcessor; - this.tripPatterns = transitDaoBuilder.getTripPatterns(); } public void run() { collectFrequencyByTrip(); - final Collection trips = transitDaoBuilder.getTripsById().values(); + final Collection trips = transitServiceBuilder.getTripsById().values(); var progressLogger = ProgressTracker.track("build trip patterns", 50_000, trips.size()); LOG.info(progressLogger.startMessage()); @@ -85,6 +91,14 @@ public void run() { } } + tripPatternBuilders + .values() + .stream() + .map(TripPatternBuilder::build) + .forEach(tripPattern -> + transitServiceBuilder.getTripPatterns().put(tripPattern.getStopPattern(), tripPattern) + ); + LOG.info(progressLogger.completeMessage()); LOG.info( "Added {} frequency-based and {} single-trip timetable entries.", @@ -107,7 +121,7 @@ public boolean hasScheduledTrips() { * the same trip can be added at once to the same Timetable/TripPattern. */ private void collectFrequencyByTrip() { - for (Frequency freq : transitDaoBuilder.getFrequencies()) { + for (Frequency freq : transitServiceBuilder.getFrequencies()) { frequenciesForTrip.put(freq.getTrip(), freq); } } @@ -119,7 +133,7 @@ private void buildTripPatternForTrip(Trip trip) { return; // Invalid trip, skip it, it will break later } - List stopTimes = transitDaoBuilder.getStopTimesSortedByTrip().get(trip); + List stopTimes = transitServiceBuilder.getStopTimesSortedByTrip().get(trip); // If after filtering this trip does not contain at least 2 stoptimes, it does not serve any purpose. var staticTripWithFewerThan2Stops = @@ -134,8 +148,7 @@ private void buildTripPatternForTrip(Trip trip) { // Get the existing TripPattern for this filtered StopPattern, or create one. StopPattern stopPattern = new StopPattern(stopTimes); - Direction direction = trip.getDirection(); - TripPattern tripPattern = findOrCreateTripPattern(stopPattern, trip, direction); + TripPatternBuilder tripPatternBuilder = findOrCreateTripPattern(stopPattern, trip); // Create a TripTimes object for this list of stoptimes, which form one trip. TripTimes tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, deduplicator); @@ -144,44 +157,42 @@ private void buildTripPatternForTrip(Trip trip) { List frequencies = frequenciesForTrip.get(trip); if (!frequencies.isEmpty()) { for (Frequency freq : frequencies) { - tripPattern.add(new FrequencyEntry(freq, tripTimes)); + tripPatternBuilder.withScheduledTimeTableBuilder(builder -> + builder.addFrequencyEntry(new FrequencyEntry(freq, tripTimes)) + ); freqCount++; } } // This trip was not frequency-based. Add the TripTimes directly to the TripPattern's scheduled timetable. else { - tripPattern.add(tripTimes); + tripPatternBuilder.withScheduledTimeTableBuilder(builder -> builder.addTripTimes(tripTimes)); scheduledCount++; } } - private TripPattern findOrCreateTripPattern( - StopPattern stopPattern, - Trip trip, - Direction direction - ) { + private TripPatternBuilder findOrCreateTripPattern(StopPattern stopPattern, Trip trip) { Route route = trip.getRoute(); - for (TripPattern tripPattern : tripPatterns.get(stopPattern)) { + Direction direction = trip.getDirection(); + for (TripPatternBuilder tripPatternBuilder : tripPatternBuilders.get(stopPattern)) { if ( - tripPattern.getRoute().equals(route) && - tripPattern.getDirection().equals(direction) && - tripPattern.getMode().equals(trip.getMode()) && - tripPattern.getNetexSubmode().equals(trip.getNetexSubMode()) + tripPatternBuilder.getRoute().equals(route) && + tripPatternBuilder.getDirection().equals(direction) && + tripPatternBuilder.getMode().equals(trip.getMode()) && + tripPatternBuilder.getNetexSubmode().equals(trip.getNetexSubMode()) ) { - return tripPattern; + return tripPatternBuilder; } } FeedScopedId patternId = generateUniqueIdForTripPattern(route, direction); - TripPattern tripPattern = TripPattern + TripPatternBuilder tripPatternBuilder = TripPattern .of(patternId) .withRoute(route) .withStopPattern(stopPattern) .withMode(trip.getMode()) .withNetexSubmode(trip.getNetexSubMode()) - .withHopGeometries(geometryProcessor.createHopGeometries(trip)) - .build(); - tripPatterns.put(stopPattern, tripPattern); - return tripPattern; + .withHopGeometries(geometryProcessor.createHopGeometries(trip)); + tripPatternBuilders.put(stopPattern, tripPatternBuilder); + return tripPatternBuilder; } /** diff --git a/src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsBundle.java b/application/src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsBundle.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsBundle.java rename to application/src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsBundle.java diff --git a/src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsFeedParameters.java b/application/src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsFeedParameters.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsFeedParameters.java rename to application/src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsFeedParameters.java diff --git a/src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsFeedParametersBuilder.java b/application/src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsFeedParametersBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsFeedParametersBuilder.java rename to application/src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsFeedParametersBuilder.java diff --git a/src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsModule.java b/application/src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsModule.java similarity index 93% rename from src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsModule.java rename to application/src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsModule.java index 2f7feb5993e..39f88f13281 100644 --- a/src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsModule.java +++ b/application/src/main/java/org/opentripplanner/gtfs/graphbuilder/GtfsModule.java @@ -35,7 +35,7 @@ import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.model.GraphBuilderModule; -import org.opentripplanner.graph_builder.module.AddTransitModelEntitiesToGraph; +import org.opentripplanner.graph_builder.module.AddTransitEntitiesToGraph; import org.opentripplanner.graph_builder.module.GtfsFeedId; import org.opentripplanner.graph_builder.module.ValidateAndInterpolateStopTimesForEachTrip; import org.opentripplanner.graph_builder.module.geometry.GeometryProcessor; @@ -51,7 +51,7 @@ import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.standalone.config.BuildConfig; import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -77,21 +77,21 @@ public class GtfsModule implements GraphBuilderModule { private final List gtfsBundles; private final FareServiceFactory fareServiceFactory; - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; private final Graph graph; private final DataImportIssueStore issueStore; private int nextAgencyId = 1; // used for generating agency IDs to resolve ID conflicts public GtfsModule( List bundles, - TransitModel transitModel, + TimetableRepository timetableRepository, Graph graph, DataImportIssueStore issueStore, ServiceDateInterval transitPeriodLimit, FareServiceFactory fareServiceFactory ) { this.gtfsBundles = bundles; - this.transitModel = transitModel; + this.timetableRepository = timetableRepository; this.graph = graph; this.issueStore = issueStore; this.transitPeriodLimit = transitPeriodLimit; @@ -100,13 +100,13 @@ public GtfsModule( public GtfsModule( List bundles, - TransitModel transitModel, + TimetableRepository timetableRepository, Graph graph, ServiceDateInterval transitPeriodLimit ) { this( bundles, - transitModel, + timetableRepository, graph, DataImportIssueStore.NOOP, transitPeriodLimit, @@ -132,7 +132,7 @@ public void buildGraph() { feedIdsEncountered.put(feedId, gtfsBundle); GTFSToOtpTransitServiceMapper mapper = new GTFSToOtpTransitServiceMapper( - new OtpTransitServiceBuilder(transitModel.getStopModel(), issueStore), + new OtpTransitServiceBuilder(timetableRepository.getSiteRepository(), issueStore), feedId, issueStore, gtfsBundle.discardMinTransferTimes(), @@ -170,7 +170,7 @@ public void buildGraph() { // NB! The calls below have side effects - the builder state is updated! createTripPatterns( graph, - transitModel, + timetableRepository, builder, calendarServiceData.getServiceIds(), geometryProcessor, @@ -182,11 +182,11 @@ public void buildGraph() { // if this or previously processed gtfs bundle has transit that has not been filtered out hasTransit = hasTransit || otpTransitService.hasActiveTransit(); - addTransitModelToGraph(graph, transitModel, gtfsBundle, otpTransitService); + addTimetableRepositoryToGraph(graph, timetableRepository, gtfsBundle, otpTransitService); if (gtfsBundle.blockBasedInterlining()) { new InterlineProcessor( - transitModel.getTransferService(), + timetableRepository.getTransferService(), builder.getStaySeatedNotAllowed(), gtfsBundle.maxInterlineDistance(), issueStore, @@ -206,9 +206,9 @@ public void buildGraph() { gtfsBundles.forEach(GtfsBundle::close); } - transitModel.validateTimeZones(); + timetableRepository.validateTimeZones(); - transitModel.updateCalendarServiceData(hasTransit, calendarServiceData, issueStore); + timetableRepository.updateCalendarServiceData(hasTransit, calendarServiceData, issueStore); } /** @@ -268,7 +268,7 @@ private void validateAndInterpolateStopTimesForEachTrip( */ private void createTripPatterns( Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, OtpTransitServiceBuilder builder, Set calServiceIds, GeometryProcessor geometryProcessor, @@ -282,25 +282,25 @@ private void createTripPatterns( geometryProcessor ); buildTPOp.run(); - transitModel.setHasFrequencyService( - transitModel.hasFrequencyService() || buildTPOp.hasFrequencyBasedTrips() + timetableRepository.setHasFrequencyService( + timetableRepository.hasFrequencyService() || buildTPOp.hasFrequencyBasedTrips() ); - transitModel.setHasScheduledService( - transitModel.hasScheduledService() || buildTPOp.hasScheduledTrips() + timetableRepository.setHasScheduledService( + timetableRepository.hasScheduledService() || buildTPOp.hasScheduledTrips() ); } - private void addTransitModelToGraph( + private void addTimetableRepositoryToGraph( Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, GtfsBundle gtfsBundle, OtpTransitService otpTransitService ) { - AddTransitModelEntitiesToGraph.addToGraph( + AddTransitEntitiesToGraph.addToGraph( otpTransitService, gtfsBundle.subwayAccessTime, graph, - transitModel + timetableRepository ); } diff --git a/src/main/java/org/opentripplanner/gtfs/interlining/InterlineProcessor.java b/application/src/main/java/org/opentripplanner/gtfs/interlining/InterlineProcessor.java similarity index 99% rename from src/main/java/org/opentripplanner/gtfs/interlining/InterlineProcessor.java rename to application/src/main/java/org/opentripplanner/gtfs/interlining/InterlineProcessor.java index 4247af4117e..dbfe3af1c9b 100644 --- a/src/main/java/org/opentripplanner/gtfs/interlining/InterlineProcessor.java +++ b/application/src/main/java/org/opentripplanner/gtfs/interlining/InterlineProcessor.java @@ -12,7 +12,6 @@ import java.util.List; import java.util.Map; import org.opentripplanner.framework.geometry.SphericalDistanceLibrary; -import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issues.InterliningTeleport; import org.opentripplanner.gtfs.mapping.StaySeatedNotAllowed; @@ -27,6 +26,7 @@ import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.utils.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/AgencyAndIdMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/AgencyAndIdMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/AgencyAndIdMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/AgencyAndIdMapper.java diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/AgencyMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/AgencyMapper.java similarity index 92% rename from src/main/java/org/opentripplanner/gtfs/mapping/AgencyMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/AgencyMapper.java index f57a9db8684..5eaadd8881f 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/AgencyMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/AgencyMapper.java @@ -3,9 +3,9 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.organization.Agency; +import org.opentripplanner.utils.collection.MapUtils; /** Responsible for mapping GTFS Agency into the OTP model. */ class AgencyMapper { @@ -36,7 +36,6 @@ private Agency doMap(org.onebusaway.gtfs.model.Agency rhs) { .withLang(rhs.getLang()) .withPhone(rhs.getPhone()) .withFareUrl(rhs.getFareUrl()) - .withBrandingUrl(rhs.getBrandingUrl()) .build(); } } diff --git a/application/src/main/java/org/opentripplanner/gtfs/mapping/BikeAccessMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/BikeAccessMapper.java new file mode 100644 index 00000000000..4175dabcbc4 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/BikeAccessMapper.java @@ -0,0 +1,27 @@ +package org.opentripplanner.gtfs.mapping; + +import org.onebusaway.gtfs.model.Route; +import org.onebusaway.gtfs.model.Trip; +import org.opentripplanner.transit.model.network.BikeAccess; + +/** + * Model bike access for GTFS trips by using the bikes_allowed fields from route and trip. + */ +class BikeAccessMapper { + + public static BikeAccess mapForTrip(Trip rhs) { + return mapValues(rhs.getBikesAllowed()); + } + + public static BikeAccess mapForRoute(Route rhs) { + return mapValues(rhs.getBikesAllowed()); + } + + private static BikeAccess mapValues(int bikesAllowed) { + return switch (bikesAllowed) { + case 1 -> BikeAccess.ALLOWED; + case 2 -> BikeAccess.NOT_ALLOWED; + default -> BikeAccess.UNKNOWN; + }; + } +} diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/BoardingAreaMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/BoardingAreaMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/gtfs/mapping/BoardingAreaMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/BoardingAreaMapper.java index 9c818e97bdb..d757a08d6df 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/BoardingAreaMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/BoardingAreaMapper.java @@ -7,10 +7,10 @@ import java.util.Map; import java.util.Optional; import java.util.function.Function; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.BoardingArea; import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.utils.collection.MapUtils; /** * Responsible for mapping GTFS Boarding areas into the OTP model. diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/BookingRuleMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/BookingRuleMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/BookingRuleMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/BookingRuleMapper.java diff --git a/application/src/main/java/org/opentripplanner/gtfs/mapping/CarAccessMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/CarAccessMapper.java new file mode 100644 index 00000000000..4034814462b --- /dev/null +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/CarAccessMapper.java @@ -0,0 +1,19 @@ +package org.opentripplanner.gtfs.mapping; + +import org.onebusaway.gtfs.model.Trip; +import org.opentripplanner.transit.model.network.CarAccess; + +/** + * Model car access for GTFS trips. + */ +class CarAccessMapper { + + public static CarAccess mapForTrip(Trip rhs) { + int carsAllowed = rhs.getCarsAllowed(); + return switch (carsAllowed) { + case 1 -> CarAccess.ALLOWED; + case 2 -> CarAccess.NOT_ALLOWED; + default -> CarAccess.UNKNOWN; + }; + } +} diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/DirectionMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/DirectionMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/DirectionMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/DirectionMapper.java diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/EntranceMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/EntranceMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/gtfs/mapping/EntranceMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/EntranceMapper.java index 786baeb1ba8..eb005ebd641 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/EntranceMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/EntranceMapper.java @@ -4,10 +4,10 @@ import java.util.HashMap; import java.util.Map; import java.util.function.Function; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.Entrance; import org.opentripplanner.transit.model.site.Station; +import org.opentripplanner.utils.collection.MapUtils; /** * Responsible for mapping GTFS Entrance into the OTP model. diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/FareAttributeMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/FareAttributeMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/gtfs/mapping/FareAttributeMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/FareAttributeMapper.java index 6b1a195b399..87b06edb82b 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/FareAttributeMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/FareAttributeMapper.java @@ -8,9 +8,9 @@ import java.util.Map; import org.opentripplanner.ext.fares.model.FareAttribute; import org.opentripplanner.ext.fares.model.FareAttributeBuilder; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.collection.MapUtils; /** Responsible for mapping GTFS FareAttribute into the OTP model. */ class FareAttributeMapper { diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/FareLegRuleMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/FareLegRuleMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/FareLegRuleMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/FareLegRuleMapper.java diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/FareProductMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/FareProductMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/FareProductMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/FareProductMapper.java diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/FareRuleMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/FareRuleMapper.java similarity index 95% rename from src/main/java/org/opentripplanner/gtfs/mapping/FareRuleMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/FareRuleMapper.java index 35cefa510f9..022de12404b 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/FareRuleMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/FareRuleMapper.java @@ -4,7 +4,7 @@ import java.util.HashMap; import java.util.Map; import org.opentripplanner.ext.fares.model.FareRule; -import org.opentripplanner.framework.collection.MapUtils; +import org.opentripplanner.utils.collection.MapUtils; /** Responsible for mapping GTFS FareRule into the OTP model. */ class FareRuleMapper { diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/FareTransferRuleMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/FareTransferRuleMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/FareTransferRuleMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/FareTransferRuleMapper.java diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/FeedInfoMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/FeedInfoMapper.java similarity index 95% rename from src/main/java/org/opentripplanner/gtfs/mapping/FeedInfoMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/FeedInfoMapper.java index a8ec889372e..1ee10dcfc78 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/FeedInfoMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/FeedInfoMapper.java @@ -5,8 +5,8 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.model.FeedInfo; +import org.opentripplanner.utils.collection.MapUtils; /** Responsible for mapping GTFS FeedInfo into the OTP model. */ class FeedInfoMapper { diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/FrequencyMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/FrequencyMapper.java similarity index 95% rename from src/main/java/org/opentripplanner/gtfs/mapping/FrequencyMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/FrequencyMapper.java index 1144e926499..18927d67000 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/FrequencyMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/FrequencyMapper.java @@ -3,8 +3,8 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.model.Frequency; +import org.opentripplanner.utils.collection.MapUtils; /** Responsible for mapping GTFS Frequency into the OTP model. */ class FrequencyMapper { diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/GTFSToOtpTransitServiceMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/GTFSToOtpTransitServiceMapper.java similarity index 90% rename from src/main/java/org/opentripplanner/gtfs/mapping/GTFSToOtpTransitServiceMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/GTFSToOtpTransitServiceMapper.java index d58410741f9..8e3718be4c6 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/GTFSToOtpTransitServiceMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/GTFSToOtpTransitServiceMapper.java @@ -72,7 +72,6 @@ public class GTFSToOtpTransitServiceMapper { private final FareTransferRuleMapper fareTransferRuleMapper; - private final StopAreaMapper stopAreaMapper; private final DirectionMapper directionMapper; private final DataImportIssueStore issueStore; @@ -106,15 +105,13 @@ public GTFSToOtpTransitServiceMapper( feedInfoMapper = new FeedInfoMapper(feedId); agencyMapper = new AgencyMapper(feedId); stationMapper = new StationMapper(translationHelper, stationTransferPreference); - stopMapper = new StopMapper(translationHelper, stationLookup, builder.stopModel()); + stopMapper = new StopMapper(translationHelper, stationLookup, builder.siteRepository()); entranceMapper = new EntranceMapper(translationHelper, stationLookup); pathwayNodeMapper = new PathwayNodeMapper(translationHelper, stationLookup); boardingAreaMapper = new BoardingAreaMapper(translationHelper, stopLookup); - locationMapper = new LocationMapper(builder.stopModel(), issueStore); - locationGroupMapper = new LocationGroupMapper(stopMapper, locationMapper, builder.stopModel()); - // the use of stop areas were reverted in the spec - // this code will go away, please migrate now! - stopAreaMapper = new StopAreaMapper(stopMapper, locationMapper, builder.stopModel()); + locationMapper = new LocationMapper(builder.siteRepository(), issueStore); + locationGroupMapper = + new LocationGroupMapper(stopMapper, locationMapper, builder.siteRepository()); pathwayMapper = new PathwayMapper(stopMapper, entranceMapper, pathwayNodeMapper, boardingAreaMapper); routeMapper = new RouteMapper(agencyMapper, issueStore, translationHelper); @@ -126,7 +123,6 @@ public GTFSToOtpTransitServiceMapper( stopMapper, locationMapper, locationGroupMapper, - stopAreaMapper, tripMapper, bookingRuleMapper, translationHelper @@ -147,7 +143,7 @@ public FareRulesData getFareRulesService() { } public void mapStopTripAndRouteDataIntoBuilder() { - var stopModel = builder.stopModel(); + var siteRepository = builder.siteRepository(); translationHelper.importTranslations(data.getAllTranslations(), data.getAllFeedInfos()); builder.getAgenciesById().addAll(agencyMapper.map(data.getAllAgencies())); @@ -164,9 +160,8 @@ public void mapStopTripAndRouteDataIntoBuilder() { if (OTPFeature.FlexRouting.isOn()) { // Stop areas and Stop groups are only used in FLEX routes - builder.stopModel().withAreaStops(locationMapper.map(data.getAllLocations())); - builder.stopModel().withGroupStops(locationGroupMapper.map(data.getAllLocationGroups())); - builder.stopModel().withGroupStops(stopAreaMapper.map(data.getAllStopAreas())); + builder.siteRepository().withAreaStops(locationMapper.map(data.getAllLocations())); + builder.siteRepository().withGroupStops(locationGroupMapper.map(data.getAllLocationGroups())); } builder.getPathways().addAll(pathwayMapper.map(data.getAllPathways())); @@ -190,14 +185,14 @@ private void mapGtfsStopsToOtpTypes(Collection s // Map station first, so we can link to them for (org.onebusaway.gtfs.model.Stop it : stops) { if (it.getLocationType() == LOCATION_TYPE_STATION) { - builder.stopModel().withStation(stationMapper.map(it)); + builder.siteRepository().withStation(stationMapper.map(it)); } } // Map Stop, Entrance and PathwayNode, link to station for (org.onebusaway.gtfs.model.Stop it : stops) { if (it.getLocationType() == LOCATION_TYPE_STOP) { - builder.stopModel().withRegularStop(stopMapper.map(it)); + builder.siteRepository().withRegularStop(stopMapper.map(it)); } else if (it.getLocationType() == LOCATION_TYPE_ENTRANCE_EXIT) { builder.getEntrances().add(entranceMapper.map(it)); } else if (it.getLocationType() == LOCATION_TYPE_NODE) { diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/LocationGroupMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/LocationGroupMapper.java similarity index 85% rename from src/main/java/org/opentripplanner/gtfs/mapping/LocationGroupMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/LocationGroupMapper.java index 591a59c492e..cf1022d671a 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/LocationGroupMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/LocationGroupMapper.java @@ -9,28 +9,28 @@ import org.onebusaway.gtfs.model.Location; import org.onebusaway.gtfs.model.LocationGroup; import org.onebusaway.gtfs.model.Stop; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.transit.model.site.GroupStop; import org.opentripplanner.transit.model.site.GroupStopBuilder; -import org.opentripplanner.transit.service.StopModelBuilder; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; +import org.opentripplanner.utils.collection.MapUtils; public class LocationGroupMapper { private final StopMapper stopMapper; private final LocationMapper locationMapper; - private final StopModelBuilder stopModelBuilder; + private final SiteRepositoryBuilder siteRepositoryBuilder; private final Map mappedLocationGroups = new HashMap<>(); public LocationGroupMapper( StopMapper stopMapper, LocationMapper locationMapper, - StopModelBuilder stopModelBuilder + SiteRepositoryBuilder siteRepositoryBuilder ) { this.stopMapper = stopMapper; this.locationMapper = locationMapper; - this.stopModelBuilder = stopModelBuilder; + this.siteRepositoryBuilder = siteRepositoryBuilder; } Collection map(Collection allLocationGroups) { @@ -43,7 +43,7 @@ GroupStop map(LocationGroup original) { } private GroupStop doMap(LocationGroup element) { - GroupStopBuilder groupStopBuilder = stopModelBuilder + GroupStopBuilder groupStopBuilder = siteRepositoryBuilder .groupStop(mapAgencyAndId(element.getId())) .withName(new NonLocalizedString(element.getName())); diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/LocationMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/LocationMapper.java similarity index 86% rename from src/main/java/org/opentripplanner/gtfs/mapping/LocationMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/LocationMapper.java index 79a28ac0f61..4e75eaac312 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/LocationMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/LocationMapper.java @@ -8,24 +8,27 @@ import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.operation.valid.IsValidOp; import org.onebusaway.gtfs.model.Location; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.geometry.UnsupportedGeometryException; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issue.api.Issue; import org.opentripplanner.transit.model.site.AreaStop; -import org.opentripplanner.transit.service.StopModelBuilder; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; +import org.opentripplanner.utils.collection.MapUtils; /** Responsible for mapping GTFS Location into the OTP model. */ public class LocationMapper { private final Map mappedLocations = new HashMap<>(); - private final StopModelBuilder stopModelBuilder; + private final SiteRepositoryBuilder siteRepositoryBuilder; private final DataImportIssueStore issueStore; - public LocationMapper(StopModelBuilder stopModelBuilder, DataImportIssueStore issueStore) { - this.stopModelBuilder = stopModelBuilder; + public LocationMapper( + SiteRepositoryBuilder siteRepositoryBuilder, + DataImportIssueStore issueStore + ) { + this.siteRepositoryBuilder = siteRepositoryBuilder; this.issueStore = issueStore; } @@ -57,7 +60,7 @@ private AreaStop doMap(Location gtfsLocation) { ) ); } - return stopModelBuilder + return siteRepositoryBuilder .areaStop(id) .withName(name) .withUrl(NonLocalizedString.ofNullable(gtfsLocation.getUrl())) diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/PathwayMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/PathwayMapper.java similarity index 98% rename from src/main/java/org/opentripplanner/gtfs/mapping/PathwayMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/PathwayMapper.java index d92087d4d41..3f5633a3da4 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/PathwayMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/PathwayMapper.java @@ -4,10 +4,10 @@ import java.util.HashMap; import java.util.Map; import org.onebusaway.gtfs.model.Stop; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.transit.model.site.Pathway; import org.opentripplanner.transit.model.site.PathwayBuilder; import org.opentripplanner.transit.model.site.StationElement; +import org.opentripplanner.utils.collection.MapUtils; /** Responsible for mapping GTFS Pathway into the OTP model. */ class PathwayMapper { diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/PathwayModeMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/PathwayModeMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/PathwayModeMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/PathwayModeMapper.java diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/PathwayNodeMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/PathwayNodeMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/gtfs/mapping/PathwayNodeMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/PathwayNodeMapper.java index 06c1dfb3f18..ab74d4c8e58 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/PathwayNodeMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/PathwayNodeMapper.java @@ -5,10 +5,10 @@ import java.util.Map; import java.util.Optional; import java.util.function.Function; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.PathwayNode; import org.opentripplanner.transit.model.site.Station; +import org.opentripplanner.utils.collection.MapUtils; /** Responsible for mapping GTFS Node into the OTP model. */ class PathwayNodeMapper { diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/PickDropMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/PickDropMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/PickDropMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/PickDropMapper.java diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/RouteMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/RouteMapper.java similarity index 93% rename from src/main/java/org/opentripplanner/gtfs/mapping/RouteMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/RouteMapper.java index 0c668f64b92..278ece825df 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/RouteMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/RouteMapper.java @@ -3,19 +3,18 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.GroupOfRoutes; import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.utils.collection.MapUtils; /** Responsible for mapping GTFS Route into the OTP model. */ class RouteMapper { private final AgencyMapper agencyMapper; - private final BrandingMapper brandingMapper; private final DataImportIssueStore issueStore; @@ -30,7 +29,6 @@ class RouteMapper { ) { this.agencyMapper = agencyMapper; this.issueStore = issueStore; - this.brandingMapper = new BrandingMapper(); this.translationHelper = helper; } @@ -82,7 +80,6 @@ private Route doMap(org.onebusaway.gtfs.model.Route rhs) { lhs.withColor(rhs.getColor()); lhs.withTextColor(rhs.getTextColor()); lhs.withBikesAllowed(BikeAccessMapper.mapForRoute(rhs)); - lhs.withBranding(brandingMapper.map(rhs)); if (rhs.getNetworkId() != null) { var networkId = GroupOfRoutes .of(new FeedScopedId(rhs.getId().getAgencyId(), rhs.getNetworkId())) diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/ServiceCalendarDateMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/ServiceCalendarDateMapper.java similarity index 95% rename from src/main/java/org/opentripplanner/gtfs/mapping/ServiceCalendarDateMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/ServiceCalendarDateMapper.java index a722a8ad9e3..53e35380198 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/ServiceCalendarDateMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/ServiceCalendarDateMapper.java @@ -3,8 +3,8 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.model.calendar.ServiceCalendarDate; +import org.opentripplanner.utils.collection.MapUtils; /** Responsible for mapping GTFS ServiceCalendarDate into the OTP model. */ class ServiceCalendarDateMapper { diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/ServiceCalendarMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/ServiceCalendarMapper.java similarity index 96% rename from src/main/java/org/opentripplanner/gtfs/mapping/ServiceCalendarMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/ServiceCalendarMapper.java index 1d229c57b19..0bb1f220a30 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/ServiceCalendarMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/ServiceCalendarMapper.java @@ -5,8 +5,8 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.model.calendar.ServiceCalendar; +import org.opentripplanner.utils.collection.MapUtils; /** Responsible for mapping GTFS ServiceCalendar into the OTP model. */ class ServiceCalendarMapper { diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/ServiceDateMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/ServiceDateMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/ServiceDateMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/ServiceDateMapper.java diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/ShapePointMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/ShapePointMapper.java similarity index 95% rename from src/main/java/org/opentripplanner/gtfs/mapping/ShapePointMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/ShapePointMapper.java index 78318559e88..8b24bc8f4ea 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/ShapePointMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/ShapePointMapper.java @@ -3,8 +3,8 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.model.ShapePoint; +import org.opentripplanner.utils.collection.MapUtils; /** Responsible for mapping GTFS ShapePoint into the OTP model. */ class ShapePointMapper { diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/StationMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/StationMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/StationMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/StationMapper.java diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/StaySeatedNotAllowed.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/StaySeatedNotAllowed.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/StaySeatedNotAllowed.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/StaySeatedNotAllowed.java diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/StopMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/StopMapper.java similarity index 90% rename from src/main/java/org/opentripplanner/gtfs/mapping/StopMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/StopMapper.java index 2f7aef34312..e5d68e71fee 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/StopMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/StopMapper.java @@ -6,30 +6,30 @@ import java.util.Map; import java.util.function.Function; import org.onebusaway.gtfs.model.Stop; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.FareZone; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.RegularStopBuilder; import org.opentripplanner.transit.model.site.Station; -import org.opentripplanner.transit.service.StopModelBuilder; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; +import org.opentripplanner.utils.collection.MapUtils; /** Responsible for mapping GTFS Stop into the OTP model. */ class StopMapper { private final Map mappedStops = new HashMap<>(); - private final StopModelBuilder stopModelBuilder; + private final SiteRepositoryBuilder siteRepositoryBuilder; private final TranslationHelper translationHelper; private final Function stationLookUp; StopMapper( TranslationHelper translationHelper, Function stationLookUp, - StopModelBuilder stopModelBuilder + SiteRepositoryBuilder siteRepositoryBuilder ) { this.translationHelper = translationHelper; this.stationLookUp = stationLookUp; - this.stopModelBuilder = stopModelBuilder; + this.siteRepositoryBuilder = siteRepositoryBuilder; } Collection map(Collection allStops) { @@ -44,7 +44,7 @@ RegularStop map(org.onebusaway.gtfs.model.Stop original) { private RegularStop doMap(org.onebusaway.gtfs.model.Stop gtfsStop) { assertLocationTypeIsStop(gtfsStop); StopMappingWrapper base = new StopMappingWrapper(gtfsStop); - RegularStopBuilder builder = stopModelBuilder + RegularStopBuilder builder = siteRepositoryBuilder .regularStop(base.getId()) .withCode(base.getCode()) .withCoordinate(base.getCoordinate()) diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/StopMappingWrapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/StopMappingWrapper.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/StopMappingWrapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/StopMappingWrapper.java diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/StopTimeMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/StopTimeMapper.java similarity index 91% rename from src/main/java/org/opentripplanner/gtfs/mapping/StopTimeMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/StopTimeMapper.java index 67b250c5061..2b1d30c09bd 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/StopTimeMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/StopTimeMapper.java @@ -7,10 +7,9 @@ import org.onebusaway.gtfs.model.Location; import org.onebusaway.gtfs.model.LocationGroup; import org.onebusaway.gtfs.model.Stop; -import org.onebusaway.gtfs.model.StopArea; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.model.StopTime; +import org.opentripplanner.utils.collection.MapUtils; /** * Responsible for mapping GTFS StopTime into the OTP Transit model. @@ -22,7 +21,6 @@ class StopTimeMapper { private final LocationMapper locationMapper; private final LocationGroupMapper locationGroupMapper; - private final StopAreaMapper stopAreaMapper; private final TripMapper tripMapper; private final BookingRuleMapper bookingRuleMapper; @@ -35,7 +33,6 @@ class StopTimeMapper { StopMapper stopMapper, LocationMapper locationMapper, LocationGroupMapper locationGroupMapper, - StopAreaMapper stopAreaMapper, TripMapper tripMapper, BookingRuleMapper bookingRuleMapper, TranslationHelper translationHelper @@ -43,7 +40,6 @@ class StopTimeMapper { this.stopMapper = stopMapper; this.locationMapper = locationMapper; this.locationGroupMapper = locationGroupMapper; - this.stopAreaMapper = stopAreaMapper; this.tripMapper = tripMapper; this.bookingRuleMapper = bookingRuleMapper; this.translationHelper = translationHelper; @@ -71,8 +67,6 @@ private StopTime doMap(org.onebusaway.gtfs.model.StopTime rhs) { case Stop stop -> lhs.setStop(stopMapper.map(stop)); case Location location -> lhs.setStop(locationMapper.map(location)); case LocationGroup locGroup -> lhs.setStop(locationGroupMapper.map(locGroup)); - // TODO: only here for backwards compatibility, this will be removed in the future - case StopArea area -> lhs.setStop(stopAreaMapper.map(area)); default -> throw new IllegalArgumentException( "Unknown location type: %s".formatted(stopLocation) ); diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/TransferMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/TransferMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/TransferMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/TransferMapper.java diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/TransferMappingResult.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/TransferMappingResult.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/TransferMappingResult.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/TransferMappingResult.java diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/TransitModeMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/TransitModeMapper.java similarity index 68% rename from src/main/java/org/opentripplanner/gtfs/mapping/TransitModeMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/TransitModeMapper.java index 608ff6ba2d3..919d71455a2 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/TransitModeMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/TransitModeMapper.java @@ -16,10 +16,11 @@ public static TransitMode mapMode(int routeType) { } /* TPEG Extension https://groups.google.com/d/msg/gtfs-changes/keT5rTPS7Y0/71uMz2l6ke0J */ - if (routeType >= 100 && routeType < 200) { // Railway Service + if (routeType >= 100 && routeType < 200) { + // Railway Service return TransitMode.RAIL; } else if (routeType >= 200 && routeType < 300) { //Coach Service - return TransitMode.BUS; + return TransitMode.COACH; } else if (routeType >= 300 && routeType < 500) { //Suburban Railway Service and Urban Railway service if (routeType >= 401 && routeType <= 402) { return TransitMode.SUBWAY; @@ -28,24 +29,32 @@ public static TransitMode mapMode(int routeType) { return TransitMode.MONORAIL; } return TransitMode.RAIL; - } else if (routeType >= 500 && routeType < 700) { //Metro Service and Underground Service + } else if (routeType >= 500 && routeType < 700) { + // Metro Service and Underground Service return TransitMode.SUBWAY; - } else if (routeType >= 700 && routeType < 900) { //Bus Service and Trolleybus service - if (routeType == 800) { - return TransitMode.TROLLEYBUS; - } + } else if (routeType >= 700 && routeType < 800) { + // Bus Service return TransitMode.BUS; - } else if (routeType >= 900 && routeType < 1000) { //Tram service + } else if (routeType >= 800 && routeType < 900) { + // Trolleybus Service + return TransitMode.TROLLEYBUS; + } else if (routeType >= 900 && routeType < 1000) { + // Tram service return TransitMode.TRAM; - } else if (routeType >= 1000 && routeType < 1100) { //Water Transport Service + } else if (routeType >= 1000 && routeType < 1100) { + // Water Transport Service return TransitMode.FERRY; - } else if (routeType >= 1100 && routeType < 1200) { //Air Service + } else if (routeType >= 1100 && routeType < 1200) { + // Air Service return TransitMode.AIRPLANE; - } else if (routeType >= 1200 && routeType < 1300) { //Ferry Service + } else if (routeType >= 1200 && routeType < 1300) { + // Ferry Service return TransitMode.FERRY; - } else if (routeType >= 1300 && routeType < 1400) { //Telecabin Service + } else if (routeType >= 1300 && routeType < 1400) { + // Telecabin Service return TransitMode.GONDOLA; - } else if (routeType >= 1400 && routeType < 1500) { //Funicular Service + } else if (routeType >= 1400 && routeType < 1500) { + // Funicular Service return TransitMode.FUNICULAR; } else if (routeType >= 1551 && routeType < 1561) { // Carpooling, not defined anywhere, so we've chosen this number space @@ -53,11 +62,13 @@ public static TransitMode mapMode(int routeType) { // standardise return TransitMode.CARPOOL; } else if (routeType >= 1500 && routeType < 1599) { - //Taxi Service + // Taxi Service return TransitMode.TAXI; - } else if (routeType >= 1600 && routeType < 1700) { //Self drive + } else if (routeType >= 1600 && routeType < 1700) { + // Self drive return TransitMode.BUS; - } else if (routeType >= 1700 && routeType < 1800) { //Miscellaneous Service + } else if (routeType >= 1700 && routeType < 1800) { + // Miscellaneous Service return null; } /* Original GTFS route types. Should these be checked before TPEG types? */ diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/TranslationHelper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/TranslationHelper.java similarity index 96% rename from src/main/java/org/opentripplanner/gtfs/mapping/TranslationHelper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/TranslationHelper.java index 03ed54d55f7..ce61c01b05e 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/TranslationHelper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/TranslationHelper.java @@ -7,7 +7,6 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.onebusaway.csv_entities.schema.annotations.CsvField; import org.onebusaway.csv_entities.schema.annotations.CsvFieldNameConvention; @@ -83,9 +82,9 @@ void importTranslations(Collection allTranslations, Collection clazz, - @Nonnull String fieldName, - @Nonnull String recordId, + Class clazz, + String fieldName, + String recordId, @Nullable String defaultValue ) { return getTranslation(clazz, fieldName, recordId, null, defaultValue); @@ -93,9 +92,9 @@ I18NString getTranslation( @Nullable I18NString getTranslation( - @Nonnull Class clazz, - @Nonnull String fieldName, - @Nonnull String recordId, + Class clazz, + String fieldName, + String recordId, @Nullable String recordSubId, @Nullable String defaultValue ) { diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/TripMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/TripMapper.java similarity index 86% rename from src/main/java/org/opentripplanner/gtfs/mapping/TripMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/TripMapper.java index 3a62ba2b269..7b1614aa4d5 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/TripMapper.java +++ b/application/src/main/java/org/opentripplanner/gtfs/mapping/TripMapper.java @@ -5,10 +5,10 @@ import java.util.HashMap; import java.util.Map; import java.util.Optional; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.routing.api.request.framework.TimePenalty; import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.utils.collection.MapUtils; /** Responsible for mapping GTFS TripMapper into the OTP model. */ class TripMapper { @@ -71,6 +71,7 @@ private Trip doMap(org.onebusaway.gtfs.model.Trip rhs) { lhs.withShapeId(AgencyAndIdMapper.mapAgencyAndId(rhs.getShapeId())); lhs.withWheelchairBoarding(WheelchairAccessibilityMapper.map(rhs.getWheelchairAccessible())); lhs.withBikesAllowed(BikeAccessMapper.mapForTrip(rhs)); + lhs.withCarsAllowed(CarAccessMapper.mapForTrip(rhs)); var trip = lhs.build(); mapSafeTimePenalty(rhs).ifPresent(f -> flexSafeTimePenalties.put(trip, f)); @@ -81,8 +82,13 @@ private Optional mapSafeTimePenalty(org.onebusaway.gtfs.model.Trip if (rhs.getSafeDurationFactor() == null && rhs.getSafeDurationOffset() == null) { return Optional.empty(); } else { - var offset = Duration.ofSeconds(rhs.getSafeDurationOffset().longValue()); - return Optional.of(TimePenalty.of(offset, rhs.getSafeDurationFactor().doubleValue())); + var offset = rhs.getSafeDurationOffset() == null + ? Duration.ZERO + : Duration.ofSeconds(rhs.getSafeDurationOffset().longValue()); + var factor = rhs.getSafeDurationFactor() == null + ? 1d + : rhs.getSafeDurationFactor().doubleValue(); + return Optional.of(TimePenalty.of(offset, factor)); } } } diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/WgsCoordinateMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/WgsCoordinateMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/WgsCoordinateMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/WgsCoordinateMapper.java diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/WheelchairAccessibilityMapper.java b/application/src/main/java/org/opentripplanner/gtfs/mapping/WheelchairAccessibilityMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/mapping/WheelchairAccessibilityMapper.java rename to application/src/main/java/org/opentripplanner/gtfs/mapping/WheelchairAccessibilityMapper.java diff --git a/src/main/java/org/opentripplanner/gtfs/package.md b/application/src/main/java/org/opentripplanner/gtfs/package.md similarity index 100% rename from src/main/java/org/opentripplanner/gtfs/package.md rename to application/src/main/java/org/opentripplanner/gtfs/package.md diff --git a/src/main/java/org/opentripplanner/inspector/raster/AreaEdgeRenderer.java b/application/src/main/java/org/opentripplanner/inspector/raster/AreaEdgeRenderer.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/raster/AreaEdgeRenderer.java rename to application/src/main/java/org/opentripplanner/inspector/raster/AreaEdgeRenderer.java diff --git a/src/main/java/org/opentripplanner/inspector/raster/BikeSafetyEdgeRenderer.java b/application/src/main/java/org/opentripplanner/inspector/raster/BikeSafetyEdgeRenderer.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/raster/BikeSafetyEdgeRenderer.java rename to application/src/main/java/org/opentripplanner/inspector/raster/BikeSafetyEdgeRenderer.java diff --git a/src/main/java/org/opentripplanner/inspector/raster/DefaultScalarColorPalette.java b/application/src/main/java/org/opentripplanner/inspector/raster/DefaultScalarColorPalette.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/raster/DefaultScalarColorPalette.java rename to application/src/main/java/org/opentripplanner/inspector/raster/DefaultScalarColorPalette.java diff --git a/src/main/java/org/opentripplanner/inspector/raster/EdgeVertexTileRenderer.java b/application/src/main/java/org/opentripplanner/inspector/raster/EdgeVertexTileRenderer.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/raster/EdgeVertexTileRenderer.java rename to application/src/main/java/org/opentripplanner/inspector/raster/EdgeVertexTileRenderer.java diff --git a/src/main/java/org/opentripplanner/inspector/raster/ElevationEdgeRenderer.java b/application/src/main/java/org/opentripplanner/inspector/raster/ElevationEdgeRenderer.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/raster/ElevationEdgeRenderer.java rename to application/src/main/java/org/opentripplanner/inspector/raster/ElevationEdgeRenderer.java diff --git a/src/main/java/org/opentripplanner/inspector/raster/MapTile.java b/application/src/main/java/org/opentripplanner/inspector/raster/MapTile.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/raster/MapTile.java rename to application/src/main/java/org/opentripplanner/inspector/raster/MapTile.java diff --git a/src/main/java/org/opentripplanner/inspector/raster/NoThruTrafficEdgeRenderer.java b/application/src/main/java/org/opentripplanner/inspector/raster/NoThruTrafficEdgeRenderer.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/raster/NoThruTrafficEdgeRenderer.java rename to application/src/main/java/org/opentripplanner/inspector/raster/NoThruTrafficEdgeRenderer.java diff --git a/src/main/java/org/opentripplanner/inspector/raster/PathwayEdgeRenderer.java b/application/src/main/java/org/opentripplanner/inspector/raster/PathwayEdgeRenderer.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/raster/PathwayEdgeRenderer.java rename to application/src/main/java/org/opentripplanner/inspector/raster/PathwayEdgeRenderer.java diff --git a/src/main/java/org/opentripplanner/inspector/raster/ScalarColorPalette.java b/application/src/main/java/org/opentripplanner/inspector/raster/ScalarColorPalette.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/raster/ScalarColorPalette.java rename to application/src/main/java/org/opentripplanner/inspector/raster/ScalarColorPalette.java diff --git a/src/main/java/org/opentripplanner/inspector/raster/TileRenderer.java b/application/src/main/java/org/opentripplanner/inspector/raster/TileRenderer.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/raster/TileRenderer.java rename to application/src/main/java/org/opentripplanner/inspector/raster/TileRenderer.java diff --git a/src/main/java/org/opentripplanner/inspector/raster/TileRendererManager.java b/application/src/main/java/org/opentripplanner/inspector/raster/TileRendererManager.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/raster/TileRendererManager.java rename to application/src/main/java/org/opentripplanner/inspector/raster/TileRendererManager.java diff --git a/src/main/java/org/opentripplanner/inspector/raster/TraversalPermissionsEdgeRenderer.java b/application/src/main/java/org/opentripplanner/inspector/raster/TraversalPermissionsEdgeRenderer.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/raster/TraversalPermissionsEdgeRenderer.java rename to application/src/main/java/org/opentripplanner/inspector/raster/TraversalPermissionsEdgeRenderer.java diff --git a/src/main/java/org/opentripplanner/inspector/raster/WalkSafetyEdgeRenderer.java b/application/src/main/java/org/opentripplanner/inspector/raster/WalkSafetyEdgeRenderer.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/raster/WalkSafetyEdgeRenderer.java rename to application/src/main/java/org/opentripplanner/inspector/raster/WalkSafetyEdgeRenderer.java diff --git a/src/main/java/org/opentripplanner/inspector/raster/WheelchairEdgeRenderer.java b/application/src/main/java/org/opentripplanner/inspector/raster/WheelchairEdgeRenderer.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/raster/WheelchairEdgeRenderer.java rename to application/src/main/java/org/opentripplanner/inspector/raster/WheelchairEdgeRenderer.java diff --git a/src/main/java/org/opentripplanner/inspector/vector/KeyValue.java b/application/src/main/java/org/opentripplanner/inspector/vector/KeyValue.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/vector/KeyValue.java rename to application/src/main/java/org/opentripplanner/inspector/vector/KeyValue.java diff --git a/src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java b/application/src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java rename to application/src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java diff --git a/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java b/application/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java similarity index 89% rename from src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java rename to application/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java index cb849e0f0ac..70cb5a2ce43 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java +++ b/application/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java @@ -1,6 +1,7 @@ package org.opentripplanner.inspector.vector; import org.opentripplanner.apis.support.mapping.PropertyMapper; +import org.opentripplanner.ext.vectortiles.layers.LayerFilters; /** * Configuration options for a single vector tile layer. @@ -53,4 +54,8 @@ default int cacheMaxSeconds() { default double expansionFactor() { return EXPANSION_FACTOR; } + + default LayerFilters.FilterType filterType() { + return LayerFilters.FilterType.NONE; + } } diff --git a/src/main/java/org/opentripplanner/inspector/vector/VectorTileResponseFactory.java b/application/src/main/java/org/opentripplanner/inspector/vector/VectorTileResponseFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/vector/VectorTileResponseFactory.java rename to application/src/main/java/org/opentripplanner/inspector/vector/VectorTileResponseFactory.java diff --git a/src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java b/application/src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java rename to application/src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java diff --git a/src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java b/application/src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java similarity index 55% rename from src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java rename to application/src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java index d43a91d384d..30763edca9e 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java +++ b/application/src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java @@ -1,17 +1,18 @@ package org.opentripplanner.inspector.vector.edge; -import static org.opentripplanner.framework.lang.DoubleUtils.roundTo2Decimals; import static org.opentripplanner.inspector.vector.KeyValue.kv; +import static org.opentripplanner.utils.lang.DoubleUtils.roundTo2Decimals; import com.google.common.collect.Lists; import java.util.Collection; import java.util.List; import org.opentripplanner.apis.support.mapping.PropertyMapper; -import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.inspector.vector.KeyValue; +import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.edge.EscalatorEdge; import org.opentripplanner.street.model.edge.StreetEdge; +import org.opentripplanner.utils.collection.ListUtils; public class EdgePropertyMapper extends PropertyMapper { @@ -29,8 +30,10 @@ protected Collection map(Edge input) { private static List mapStreetEdge(StreetEdge se) { var props = Lists.newArrayList( - kv("permission", se.getPermission().toString()), - kv("bicycleSafetyFactor", roundTo2Decimals(se.getBicycleSafetyFactor())) + kv("permission", streetPermissionAsString(se.getPermission())), + kv("bicycleSafetyFactor", roundTo2Decimals(se.getBicycleSafetyFactor())), + kv("noThruTraffic", noThruTrafficAsString(se)), + kv("wheelchairAccessible", se.isWheelchairAccessible()) ); if (se.hasBogusName()) { props.addFirst(kv("name", "%s (generated)".formatted(se.getName().toString()))); @@ -39,4 +42,22 @@ private static List mapStreetEdge(StreetEdge se) { } return props; } + + public static String streetPermissionAsString(StreetTraversalPermission permission) { + return permission.name().replace("_AND_", " "); + } + + private static String noThruTrafficAsString(StreetEdge se) { + var noThruPermission = StreetTraversalPermission.NONE; + if (se.isWalkNoThruTraffic()) { + noThruPermission = noThruPermission.add(StreetTraversalPermission.PEDESTRIAN); + } + if (se.isBicycleNoThruTraffic()) { + noThruPermission = noThruPermission.add(StreetTraversalPermission.BICYCLE); + } + if (se.isMotorVehicleNoThruTraffic()) { + noThruPermission = noThruPermission.add(StreetTraversalPermission.CAR); + } + return streetPermissionAsString(noThruPermission); + } } diff --git a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java b/application/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java rename to application/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java diff --git a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java b/application/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java rename to application/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java diff --git a/src/main/java/org/opentripplanner/inspector/vector/stop/GroupStopLayerBuilder.java b/application/src/main/java/org/opentripplanner/inspector/vector/stop/GroupStopLayerBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/vector/stop/GroupStopLayerBuilder.java rename to application/src/main/java/org/opentripplanner/inspector/vector/stop/GroupStopLayerBuilder.java diff --git a/src/main/java/org/opentripplanner/inspector/vector/stop/StopLayerBuilder.java b/application/src/main/java/org/opentripplanner/inspector/vector/stop/StopLayerBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/vector/stop/StopLayerBuilder.java rename to application/src/main/java/org/opentripplanner/inspector/vector/stop/StopLayerBuilder.java diff --git a/src/main/java/org/opentripplanner/inspector/vector/stop/StopLocationPropertyMapper.java b/application/src/main/java/org/opentripplanner/inspector/vector/stop/StopLocationPropertyMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/vector/stop/StopLocationPropertyMapper.java rename to application/src/main/java/org/opentripplanner/inspector/vector/stop/StopLocationPropertyMapper.java diff --git a/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexLayerBuilder.java b/application/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexLayerBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/inspector/vector/vertex/VertexLayerBuilder.java rename to application/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexLayerBuilder.java diff --git a/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java b/application/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java similarity index 91% rename from src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java rename to application/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java index 01f5263b11a..c1f0070eb86 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java +++ b/application/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java @@ -8,15 +8,15 @@ import java.util.List; import java.util.Set; import org.opentripplanner.apis.support.mapping.PropertyMapper; -import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.inspector.vector.KeyValue; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingEntrance; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingEntrance; import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex; import org.opentripplanner.street.model.vertex.BarrierVertex; import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.search.TraverseMode; +import org.opentripplanner.utils.collection.ListUtils; public class VertexPropertyMapper extends PropertyMapper { diff --git a/src/main/java/org/opentripplanner/kryo/BuildConfigSerializer.java b/application/src/main/java/org/opentripplanner/kryo/BuildConfigSerializer.java similarity index 100% rename from src/main/java/org/opentripplanner/kryo/BuildConfigSerializer.java rename to application/src/main/java/org/opentripplanner/kryo/BuildConfigSerializer.java diff --git a/src/main/java/org/opentripplanner/kryo/RouterConfigSerializer.java b/application/src/main/java/org/opentripplanner/kryo/RouterConfigSerializer.java similarity index 100% rename from src/main/java/org/opentripplanner/kryo/RouterConfigSerializer.java rename to application/src/main/java/org/opentripplanner/kryo/RouterConfigSerializer.java diff --git a/src/main/java/org/opentripplanner/kryo/UnmodifiableCollectionsSerializer.java b/application/src/main/java/org/opentripplanner/kryo/UnmodifiableCollectionsSerializer.java similarity index 100% rename from src/main/java/org/opentripplanner/kryo/UnmodifiableCollectionsSerializer.java rename to application/src/main/java/org/opentripplanner/kryo/UnmodifiableCollectionsSerializer.java diff --git a/src/main/java/org/opentripplanner/model/FeedInfo.java b/application/src/main/java/org/opentripplanner/model/FeedInfo.java similarity index 100% rename from src/main/java/org/opentripplanner/model/FeedInfo.java rename to application/src/main/java/org/opentripplanner/model/FeedInfo.java diff --git a/src/main/java/org/opentripplanner/model/Frequency.java b/application/src/main/java/org/opentripplanner/model/Frequency.java similarity index 97% rename from src/main/java/org/opentripplanner/model/Frequency.java rename to application/src/main/java/org/opentripplanner/model/Frequency.java index c4bd653d41b..fd50219d865 100644 --- a/src/main/java/org/opentripplanner/model/Frequency.java +++ b/application/src/main/java/org/opentripplanner/model/Frequency.java @@ -3,9 +3,9 @@ import java.io.Serializable; import java.util.Objects; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.utils.tostring.ToStringBuilder; public final class Frequency implements Serializable { diff --git a/src/main/java/org/opentripplanner/model/GenericLocation.java b/application/src/main/java/org/opentripplanner/model/GenericLocation.java similarity index 86% rename from src/main/java/org/opentripplanner/model/GenericLocation.java rename to application/src/main/java/org/opentripplanner/model/GenericLocation.java index 2b0ecc3f697..bd053cd7147 100644 --- a/src/main/java/org/opentripplanner/model/GenericLocation.java +++ b/application/src/main/java/org/opentripplanner/model/GenericLocation.java @@ -2,9 +2,9 @@ import javax.annotation.Nullable; import org.locationtech.jts.geom.Coordinate; -import org.opentripplanner.framework.lang.StringUtils; -import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.lang.StringUtils; +import org.opentripplanner.utils.tostring.ValueObjectToStringBuilder; /** * Represents a location that is to be used in a routing request. It can be either a from, to, or @@ -17,23 +17,32 @@ public class GenericLocation { * A label for the place, if provided. This is pass-through information and does not affect * routing in any way. */ + @Nullable public final String label; /** * Refers to a specific element in the OTP model. This can currently be a regular stop, area stop, * group stop, station, multi-modal station or group of stations. */ + @Nullable public final FeedScopedId stopId; /** * Coordinates of the location. These can be used by themselves or as a fallback if placeId is not * found. */ + @Nullable public final Double lat; + @Nullable public final Double lng; - public GenericLocation(String label, FeedScopedId stopId, Double lat, Double lng) { + public GenericLocation( + @Nullable String label, + @Nullable FeedScopedId stopId, + @Nullable Double lat, + @Nullable Double lng + ) { this.label = label; this.stopId = stopId; this.lat = lat; diff --git a/src/main/java/org/opentripplanner/model/OtpTransitService.java b/application/src/main/java/org/opentripplanner/model/OtpTransitService.java similarity index 96% rename from src/main/java/org/opentripplanner/model/OtpTransitService.java rename to application/src/main/java/org/opentripplanner/model/OtpTransitService.java index 91351af383d..748c44fa788 100644 --- a/src/main/java/org/opentripplanner/model/OtpTransitService.java +++ b/application/src/main/java/org/opentripplanner/model/OtpTransitService.java @@ -16,7 +16,7 @@ import org.opentripplanner.transit.model.site.Pathway; import org.opentripplanner.transit.model.site.PathwayNode; import org.opentripplanner.transit.model.timetable.Trip; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; /** * Methods for accessing imported entities. @@ -35,7 +35,7 @@ public interface OtpTransitService { Collection getAllFeedInfos(); - StopModel stopModel(); + SiteRepository siteRepository(); /** * This is equivalent to a Transmodel Notice Assignments. The map key may reference entity ids of diff --git a/src/main/java/org/opentripplanner/model/PathTransfer.java b/application/src/main/java/org/opentripplanner/model/PathTransfer.java similarity index 95% rename from src/main/java/org/opentripplanner/model/PathTransfer.java rename to application/src/main/java/org/opentripplanner/model/PathTransfer.java index 161df9fd3b8..5b42a8149e3 100644 --- a/src/main/java/org/opentripplanner/model/PathTransfer.java +++ b/application/src/main/java/org/opentripplanner/model/PathTransfer.java @@ -2,10 +2,10 @@ import java.io.Serializable; import java.util.List; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.transfer.ConstrainedTransfer; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Represents a transfer between stops with the street network path attatched to it. diff --git a/src/main/java/org/opentripplanner/model/PickDrop.java b/application/src/main/java/org/opentripplanner/model/PickDrop.java similarity index 100% rename from src/main/java/org/opentripplanner/model/PickDrop.java rename to application/src/main/java/org/opentripplanner/model/PickDrop.java diff --git a/application/src/main/java/org/opentripplanner/model/RealTimeTripUpdate.java b/application/src/main/java/org/opentripplanner/model/RealTimeTripUpdate.java new file mode 100644 index 00000000000..28fc16a98ac --- /dev/null +++ b/application/src/main/java/org/opentripplanner/model/RealTimeTripUpdate.java @@ -0,0 +1,70 @@ +package org.opentripplanner.model; + +import java.time.LocalDate; +import java.util.Objects; +import javax.annotation.Nullable; +import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.timetable.TripOnServiceDate; +import org.opentripplanner.transit.model.timetable.TripTimes; + +/** + * Represents the real-time update of a single trip. + * + * @param pattern the pattern to which belongs the updated trip. This can be a new + * pattern created in real-time. + * @param updatedTripTimes the new trip times for the updated trip. + * @param serviceDate the service date for which this update applies (updates are valid + * only for one service date) + * @param addedTripOnServiceDate optionally if this trip update adds a new trip, the + * TripOnServiceDate corresponding to this new trip. + * @param tripCreation true if this update creates a new trip, not present in scheduled + * data. + * @param routeCreation true if an added trip cannot be registered under an existing route + * and a new route must be created. + * @param producer the producer of the real-time update. + */ +public record RealTimeTripUpdate( + TripPattern pattern, + TripTimes updatedTripTimes, + LocalDate serviceDate, + @Nullable TripOnServiceDate addedTripOnServiceDate, + boolean tripCreation, + boolean routeCreation, + @Nullable String producer +) { + public RealTimeTripUpdate { + Objects.requireNonNull(pattern); + Objects.requireNonNull(updatedTripTimes); + Objects.requireNonNull(serviceDate); + } + + /** + * Create a real-time update for an existing trip. + */ + public RealTimeTripUpdate( + TripPattern pattern, + TripTimes updatedTripTimes, + LocalDate serviceDate + ) { + this(pattern, updatedTripTimes, serviceDate, null, false, false, null); + } + + public RealTimeTripUpdate( + TripPattern pattern, + TripTimes updatedTripTimes, + LocalDate serviceDate, + @Nullable TripOnServiceDate addedTripOnServiceDate, + boolean tripCreation, + boolean routeCreation + ) { + this( + pattern, + updatedTripTimes, + serviceDate, + addedTripOnServiceDate, + tripCreation, + routeCreation, + null + ); + } +} diff --git a/src/main/java/org/opentripplanner/model/ShapePoint.java b/application/src/main/java/org/opentripplanner/model/ShapePoint.java similarity index 100% rename from src/main/java/org/opentripplanner/model/ShapePoint.java rename to application/src/main/java/org/opentripplanner/model/ShapePoint.java diff --git a/src/main/java/org/opentripplanner/model/StopTime.java b/application/src/main/java/org/opentripplanner/model/StopTime.java similarity index 93% rename from src/main/java/org/opentripplanner/model/StopTime.java rename to application/src/main/java/org/opentripplanner/model/StopTime.java index edd5fbdb52d..0754dbce671 100644 --- a/src/main/java/org/opentripplanner/model/StopTime.java +++ b/application/src/main/java/org/opentripplanner/model/StopTime.java @@ -1,13 +1,15 @@ /* This file is based on code copied from project OneBusAway, see the LICENSE file for further information. */ package org.opentripplanner.model; +import static org.opentripplanner.model.PickDrop.NONE; + import java.util.List; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.StopTimeKey; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.booking.BookingInfo; +import org.opentripplanner.utils.time.TimeUtils; /** * This class is TEMPORALLY used during mapping of GTFS and Netex into the internal Model, it is not @@ -305,4 +307,16 @@ private static int getAvailableTime(int... times) { public boolean hasFlexWindow() { return flexWindowStart != MISSING_VALUE || flexWindowEnd != MISSING_VALUE; } + + /** + * Checks if this stop time combines flex windows with continuous stopping, which is against the + * GTFS spec. + */ + public boolean combinesContinuousStoppingWithFlexWindow() { + return hasContinuousStopping() && hasFlexWindow(); + } + + public boolean hasContinuousStopping() { + return this.flexContinuousPickup != NONE || flexContinuousDropOff != NONE; + } } diff --git a/src/main/java/org/opentripplanner/model/StopTimesInPattern.java b/application/src/main/java/org/opentripplanner/model/StopTimesInPattern.java similarity index 100% rename from src/main/java/org/opentripplanner/model/StopTimesInPattern.java rename to application/src/main/java/org/opentripplanner/model/StopTimesInPattern.java diff --git a/src/main/java/org/opentripplanner/model/SystemNotice.java b/application/src/main/java/org/opentripplanner/model/SystemNotice.java similarity index 95% rename from src/main/java/org/opentripplanner/model/SystemNotice.java rename to application/src/main/java/org/opentripplanner/model/SystemNotice.java index f9af41d3fd0..6e6b910665a 100644 --- a/src/main/java/org/opentripplanner/model/SystemNotice.java +++ b/application/src/main/java/org/opentripplanner/model/SystemNotice.java @@ -1,8 +1,8 @@ package org.opentripplanner.model; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.transit.model.basic.Notice; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A system notice is used to tag elements with system information. diff --git a/src/main/java/org/opentripplanner/model/Timetable.java b/application/src/main/java/org/opentripplanner/model/Timetable.java similarity index 85% rename from src/main/java/org/opentripplanner/model/Timetable.java rename to application/src/main/java/org/opentripplanner/model/Timetable.java index 10c384e6211..c437a60b0d5 100644 --- a/src/main/java/org/opentripplanner/model/Timetable.java +++ b/application/src/main/java/org/opentripplanner/model/Timetable.java @@ -16,15 +16,12 @@ import java.time.LocalDate; import java.time.ZoneId; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Optional; -import java.util.function.UnaryOperator; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.transit.model.framework.DataValidationException; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.framework.Result; @@ -38,6 +35,7 @@ import org.opentripplanner.updater.spi.DataValidationExceptionMapper; import org.opentripplanner.updater.spi.UpdateError; import org.opentripplanner.updater.trip.BackwardsDelayPropagationType; +import org.opentripplanner.utils.time.ServiceDateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,8 +46,7 @@ * one Timetable when stop time updates are being applied: one for the scheduled stop times, one for * each snapshot of updated stop times, another for a working buffer of updated stop times, etc. *

- * TODO OTP2 - Move this to package: org.opentripplanner.model after as Entur NeTEx PRs are merged. - * Also consider moving its dependencies into package org.opentripplanner.routing. The NEW + * TODO OTP2 consider moving dependencies into package org.opentripplanner.routing. The NEW * Timetable should not have any dependencies to [?] */ public class Timetable implements Serializable { @@ -58,28 +55,30 @@ public class Timetable implements Serializable { private final TripPattern pattern; - private final List tripTimes = new ArrayList<>(); + private final List tripTimes; - private final List frequencyEntries = new ArrayList<>(); + private final List frequencyEntries; @Nullable private final LocalDate serviceDate; + Timetable(TimetableBuilder timetableBuilder) { + this.pattern = timetableBuilder.getPattern(); + this.serviceDate = timetableBuilder.getServiceDate(); + this.tripTimes = timetableBuilder.createImmutableOrderedListOfTripTimes(); + this.frequencyEntries = List.copyOf(timetableBuilder.getFrequencies()); + } + /** Construct an empty Timetable. */ - public Timetable(TripPattern pattern) { - this.pattern = pattern; - this.serviceDate = null; + public static TimetableBuilder of() { + return new TimetableBuilder(); } /** - * Copy constructor: create an un-indexed Timetable with the same TripTimes as the specified - * timetable. + * Copy timetable into a builder witch can be used to modify the timetable. */ - Timetable(Timetable tt, @Nonnull LocalDate serviceDate) { - Objects.requireNonNull(serviceDate); - tripTimes.addAll(tt.tripTimes); - this.serviceDate = serviceDate; - this.pattern = tt.pattern; + public TimetableBuilder copyOf() { + return new TimetableBuilder(this); } /** @return the index of TripTimes for this trip ID in this particular Timetable */ @@ -134,17 +133,6 @@ public TripTimes getTripTimes(FeedScopedId tripId) { return null; } - /** - * Set new trip times for trip given a trip index - * - * @param tripIndex trip index of trip - * @param tt new trip times for trip - * @return old trip times of trip - */ - public TripTimes setTripTimes(int tripIndex, TripTimes tt) { - return tripTimes.set(tripIndex, tt); - } - /** * Apply the TripUpdate to the appropriate TripTimes from this Timetable. The existing TripTimes * must not be modified directly because they may be shared with the underlying @@ -386,44 +374,6 @@ public Result createUpdatedTripTimesFromGTFSRT( return Result.success(new TripTimesPatch(newTimes, skippedStopIndices)); } - /** - * Add a trip to this Timetable. The Timetable must be analyzed, compacted, and indexed any time - * trips are added, but this is not done automatically because it is time consuming and should - * only be done once after an entire batch of trips are added. Note that the trip is not added to - * the enclosing pattern here, but in the pattern's wrapper function. Here we don't know if it's a - * scheduled trip or a realtime-added trip. - */ - public void addTripTimes(TripTimes tt) { - tripTimes.add(tt); - } - - /** - * Apply the same update to all trip-times inculuding scheduled and frequency based - * trip times. - *

- * THIS IS NOT THREAD-SAFE - ONLY USE THIS METHOD DURING GRAPH-BUILD! - */ - public void updateAllTripTimes(UnaryOperator update) { - tripTimes.replaceAll(update); - frequencyEntries.replaceAll(it -> - new FrequencyEntry( - it.startTime, - it.endTime, - it.headway, - it.exactTimes, - update.apply(it.tripTimes) - ) - ); - } - - /** - * Add a frequency entry to this Timetable. See addTripTimes method. Maybe Frequency Entries - * should just be TripTimes for simplicity. - */ - public void addFrequencyEntry(FrequencyEntry freq) { - frequencyEntries.add(freq); - } - public boolean isValidFor(LocalDate serviceDate) { return this.serviceDate == null || this.serviceDate.equals(serviceDate); } @@ -473,21 +423,61 @@ public LocalDate getServiceDate() { } /** - * The direction for all the trips in this pattern. + * Return the direction for all the trips in this timetable. + * By construction, all trips in a timetable have the same direction. */ public Direction getDirection() { + return getDirection(tripTimes, frequencyEntries); + } + + /** + * Return an arbitrary TripTimes in this Timetable. + * Return a scheduled trip times if it exists, otherwise return a frequency-based trip times. + */ + public TripTimes getRepresentativeTripTimes() { + return getRepresentativeTripTimes(tripTimes, frequencyEntries); + } + + /** + * @return true if the timetable was created by a real-time update, false if this + * timetable is based on scheduled data. + * Only real-time timetables have a service date. + */ + public boolean isCreatedByRealTimeUpdater() { + return serviceDate != null; + } + + /** + * The direction for the given collections of trip times. + * The method assumes that all trip times have the same directions and picks up one arbitrarily. + * @param scheduledTripTimes all the scheduled-based trip times in a timetable. + * @param frequencies all the frequency-based trip times in a timetable. + */ + static Direction getDirection( + Collection scheduledTripTimes, + Collection frequencies + ) { return Optional - .ofNullable(getRepresentativeTripTimes()) + .ofNullable(getRepresentativeTripTimes(scheduledTripTimes, frequencies)) .map(TripTimes::getTrip) .map(Trip::getDirection) .orElse(Direction.UNKNOWN); } - public TripTimes getRepresentativeTripTimes() { - if (!getTripTimes().isEmpty()) { - return getTripTimes(0); - } else if (!getFrequencyEntries().isEmpty()) { - return getFrequencyEntries().get(0).tripTimes; + /** + * Return an arbitrary TripTimes. + * @param scheduledTripTimes all the scheduled-based trip times in a timetable. + * @param frequencies all the frequency-based trip times in a timetable. + * + */ + private static TripTimes getRepresentativeTripTimes( + Collection scheduledTripTimes, + Collection frequencies + ) { + if (!scheduledTripTimes.isEmpty()) { + return scheduledTripTimes.iterator().next(); + } else if (!frequencies.isEmpty()) { + return frequencies.iterator().next().tripTimes; } else { // Pattern is created only for real-time updates return null; diff --git a/application/src/main/java/org/opentripplanner/model/TimetableBuilder.java b/application/src/main/java/org/opentripplanner/model/TimetableBuilder.java new file mode 100644 index 00000000000..74e89d0d973 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/model/TimetableBuilder.java @@ -0,0 +1,136 @@ +package org.opentripplanner.model; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.UnaryOperator; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.timetable.Direction; +import org.opentripplanner.transit.model.timetable.FrequencyEntry; +import org.opentripplanner.transit.model.timetable.TripTimes; + +public class TimetableBuilder { + + private TripPattern pattern; + private LocalDate serviceDate; + private final Map tripTimes = new HashMap<>(); + private final List frequencies = new ArrayList<>(); + + TimetableBuilder() {} + + TimetableBuilder(Timetable tt) { + pattern = tt.getPattern(); + serviceDate = tt.getServiceDate(); + frequencies.addAll(tt.getFrequencyEntries()); + addAllTripTimes(tt.getTripTimes()); + } + + public TimetableBuilder withTripPattern(TripPattern tripPattern) { + this.pattern = tripPattern; + return this; + } + + public TimetableBuilder withServiceDate(LocalDate serviceDate) { + this.serviceDate = serviceDate; + return this; + } + + /** + * Add a new trip-times to the timetable. If the associated trip already exists, an exception is + * thrown. This is considered a programming error. Use {@link #addOrUpdateTripTimes(TripTimes)} + * if you want to replace an existing trip. + */ + public TimetableBuilder addTripTimes(TripTimes tripTimes) { + var trip = tripTimes.getTrip(); + if (this.tripTimes.containsKey(trip.getId())) { + throw new IllegalStateException( + "Error! TripTimes for the same trip is added twice. Trip: " + trip + ); + } + return addOrUpdateTripTimes(tripTimes); + } + + /** + * Add or update the trip-times. If the trip has an associated trip-times, then the trip-times + * are replaced. If not, the trip-times it is added. Consider using + * {@link #addTripTimes(TripTimes)}. + */ + public TimetableBuilder addOrUpdateTripTimes(TripTimes tripTimes) { + this.tripTimes.put(tripTimes.getTrip().getId(), tripTimes); + return this; + } + + public TimetableBuilder addAllTripTimes(List tripTimes) { + for (TripTimes it : tripTimes) { + addTripTimes(it); + } + return this; + } + + public TimetableBuilder removeTripTimes(TripTimes tripTimesToRemove) { + tripTimes.remove(tripTimesToRemove.getTrip().getId()); + return this; + } + + public TimetableBuilder removeAllTripTimes(Collection tripTimesToBeRemoved) { + for (TripTimes it : tripTimesToBeRemoved) { + tripTimes.remove(it.getTrip().getId()); + } + return this; + } + + /** + * Apply the same update to all trip-times including scheduled and frequency based + * trip times. + *

+ */ + public TimetableBuilder updateAllTripTimes(UnaryOperator update) { + tripTimes.replaceAll((t, tt) -> update.apply(tt)); + frequencies.replaceAll(it -> + new FrequencyEntry( + it.startTime, + it.endTime, + it.headway, + it.exactTimes, + update.apply(it.tripTimes) + ) + ); + return this; + } + + public TimetableBuilder addFrequencyEntry(FrequencyEntry frequencyEntry) { + this.frequencies.add(frequencyEntry); + return this; + } + + /** + * The direction for all the trips in this timetable. + */ + public Direction getDirection() { + return Timetable.getDirection(tripTimes.values(), frequencies); + } + + public Timetable build() { + return new Timetable(this); + } + + List createImmutableOrderedListOfTripTimes() { + return tripTimes.values().stream().sorted().toList(); + } + + TripPattern getPattern() { + return pattern; + } + + LocalDate getServiceDate() { + return serviceDate; + } + + List getFrequencies() { + return frequencies; + } +} diff --git a/src/main/java/org/opentripplanner/model/TimetableSnapshot.java b/application/src/main/java/org/opentripplanner/model/TimetableSnapshot.java similarity index 76% rename from src/main/java/org/opentripplanner/model/TimetableSnapshot.java rename to application/src/main/java/org/opentripplanner/model/TimetableSnapshot.java index d076bf9f1f0..94b490c48a0 100644 --- a/src/main/java/org/opentripplanner/model/TimetableSnapshot.java +++ b/application/src/main/java/org/opentripplanner/model/TimetableSnapshot.java @@ -1,6 +1,6 @@ package org.opentripplanner.model; -import static org.opentripplanner.framework.collection.CollectionUtils.getByNullableKey; +import static org.opentripplanner.utils.collection.CollectionUtils.getByNullableKey; import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableSetMultimap; @@ -13,11 +13,9 @@ import java.util.Comparator; import java.util.ConcurrentModificationException; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.annotation.Nullable; @@ -83,10 +81,14 @@ public class TimetableSnapshot { /** * During the construction phase of the TimetableSnapshot, before it is considered immutable and - * used in routing, this Set holds all timetables that have been modified and are waiting to be - * indexed. This field will be set to null when the TimetableSnapshot becomes read-only. + * used in routing, this Map holds all timetables that have been modified and are waiting to be + * indexed. + * A real-time timetable overrides the scheduled timetable of a TripPattern for only a single + * service date. There can be only one overriding timetable per TripPattern and per service date. + * This is enforced by indexing the map with a pair (TripPattern, service date). + * This map is cleared when the TimetableSnapshot becomes read-only. */ - private final Set dirtyTimetables = new HashSet<>(); + private final Map dirtyTimetables = new HashMap<>(); /** * For each TripPattern (sequence of stops on a particular Route) for which we have received a @@ -110,9 +112,12 @@ public class TimetableSnapshot { * For cases where the trip pattern (sequence of stops visited) has been changed by a realtime * update, a Map associating the updated trip pattern with a compound key of the feed-scoped * trip ID and the service date. + * This index includes only modified trip patterns for existing trips. + * It does not include trip patterns for new trips created by real-time updates (extra journeys). + * . * TODO RT_AB: clarify if this is an index or the original source of truth. */ - private final Map realtimeAddedTripPattern; + private final Map realTimeNewTripPatternsForModifiedTrips; /** * This is an index of TripPatterns, not the primary collection. It tracks which TripPatterns @@ -124,6 +129,11 @@ public class TimetableSnapshot { */ private final SetMultimap patternsForStop; + /** + * The realTimeAdded* maps are indexes on the trips created at runtime (extra-journey), and the + * Route, TripPattern, TripOnServiceDate they refer to. + * They are meant to override the corresponding indexes in TimetableRepositoryIndex. + */ private final Map realtimeAddedRoutes; private final Map realTimeAddedTrips; private final Map realTimeAddedPatternForTrip; @@ -160,7 +170,7 @@ public TimetableSnapshot() { private TimetableSnapshot( Map> timetables, - Map realtimeAddedTripPattern, + Map realTimeNewTripPatternsForModifiedTrips, Map realtimeAddedRoutes, Map realtimeAddedTrips, Map realTimeAddedPatternForTrip, @@ -171,7 +181,7 @@ private TimetableSnapshot( boolean readOnly ) { this.timetables = timetables; - this.realtimeAddedTripPattern = realtimeAddedTripPattern; + this.realTimeNewTripPatternsForModifiedTrips = realTimeNewTripPatternsForModifiedTrips; this.realtimeAddedRoutes = realtimeAddedRoutes; this.realTimeAddedTrips = realtimeAddedTrips; this.realTimeAddedPatternForTrip = realTimeAddedPatternForTrip; @@ -207,16 +217,16 @@ public Timetable resolve(TripPattern pattern, LocalDate serviceDate) { * @return trip pattern created by the updater; null if trip is on the original trip pattern */ @Nullable - public TripPattern getRealtimeAddedTripPattern(FeedScopedId tripId, LocalDate serviceDate) { + public TripPattern getNewTripPatternForModifiedTrip(FeedScopedId tripId, LocalDate serviceDate) { TripIdAndServiceDate tripIdAndServiceDate = new TripIdAndServiceDate(tripId, serviceDate); - return realtimeAddedTripPattern.get(tripIdAndServiceDate); + return realTimeNewTripPatternsForModifiedTrips.get(tripIdAndServiceDate); } /** - * @return if any trip patterns were added. + * @return if any trip patterns were modified */ - public boolean hasRealtimeAddedTripPatterns() { - return !realtimeAddedTripPattern.isEmpty(); + public boolean hasNewTripPatternsForModifiedTrips() { + return !realTimeNewTripPatternsForModifiedTrips.isEmpty(); } /** @@ -227,7 +237,7 @@ public Route getRealtimeAddedRoute(FeedScopedId id) { return getByNullableKey(id, realtimeAddedRoutes); } - public Collection getAllRealTimeAddedRoutes() { + public Collection listRealTimeAddedRoutes() { return Collections.unmodifiableCollection(realtimeAddedRoutes.values()); } @@ -239,7 +249,7 @@ public Trip getRealTimeAddedTrip(FeedScopedId id) { return getByNullableKey(id, realTimeAddedTrips); } - public Collection getAllRealTimeAddedTrips() { + public Collection listRealTimeAddedTrips() { return Collections.unmodifiableCollection(realTimeAddedTrips.values()); } @@ -276,7 +286,7 @@ public TripOnServiceDate getRealTimeAddedTripOnServiceDateForTripAndDay( return getByNullableKey(tripIdAndServiceDate, realTimeAddedTripOnServiceDateForTripAndDay); } - public Collection getAllRealTimeAddedTripOnServiceDate() { + public Collection listRealTimeAddedTripOnServiceDate() { return Collections.unmodifiableCollection(realTimeAddedTripOnServiceDateForTripAndDay.values()); } @@ -289,36 +299,27 @@ public Collection getAllRealTimeAddedTripOnServiceD * @return whether the update was actually applied */ public Result update(RealTimeTripUpdate realTimeTripUpdate) { + validateNotReadOnly(); + TripPattern pattern = realTimeTripUpdate.pattern(); LocalDate serviceDate = realTimeTripUpdate.serviceDate(); TripTimes updatedTripTimes = realTimeTripUpdate.updatedTripTimes(); - if (readOnly) { - throw new ConcurrentModificationException("This TimetableSnapshot is read-only."); - } - Timetable tt = resolve(pattern, serviceDate); - // we need to perform the copy of Timetable here rather than in Timetable.update() - // to avoid repeatedly copying in case several updates are applied to the same timetable - tt = copyTimetable(pattern, serviceDate, tt); + TimetableBuilder ttb = tt.copyOf().withServiceDate(serviceDate); // Assume all trips in a pattern are from the same feed, which should be the case. - // Find trip index - Trip trip = updatedTripTimes.getTrip(); - int tripIndex = tt.getTripIndex(trip.getId()); - if (tripIndex == -1) { - // Trip not found, add it - tt.addTripTimes(updatedTripTimes); - } else { - // Set updated trip times of trip - tt.setTripTimes(tripIndex, updatedTripTimes); - } + ttb.addOrUpdateTripTimes(updatedTripTimes); + + Timetable updated = ttb.build(); + swapTimetable(pattern, tt, updated); + Trip trip = updatedTripTimes.getTrip(); if (pattern.isCreatedByRealtimeUpdater()) { // Remember this pattern for the added trip id and service date FeedScopedId tripId = trip.getId(); TripIdAndServiceDate tripIdAndServiceDate = new TripIdAndServiceDate(tripId, serviceDate); - realtimeAddedTripPattern.put(tripIdAndServiceDate, pattern); + realTimeNewTripPatternsForModifiedTrips.put(tripIdAndServiceDate, pattern); } // To make these trip patterns visible for departureRow searches. @@ -346,8 +347,7 @@ public Result update(RealTimeTripUpdate realTimeTrip } // The time tables are finished during the commit - - return Result.success(UpdateSuccess.noWarnings()); + return Result.success(UpdateSuccess.noWarnings(realTimeTripUpdate.producer())); } /** @@ -364,18 +364,15 @@ public TimetableSnapshot commit() { return commit(null, false); } - @SuppressWarnings("unchecked") public TimetableSnapshot commit(TransitLayerUpdater transitLayerUpdater, boolean force) { - if (readOnly) { - throw new ConcurrentModificationException("This TimetableSnapshot is read-only."); - } + validateNotReadOnly(); if (!force && !this.isDirty()) { return null; } TimetableSnapshot ret = new TimetableSnapshot( Map.copyOf(timetables), - Map.copyOf(realtimeAddedTripPattern), + Map.copyOf(realTimeNewTripPatternsForModifiedTrips), Map.copyOf(realtimeAddedRoutes), Map.copyOf(realTimeAddedTrips), Map.copyOf(realTimeAddedPatternForTrip), @@ -387,7 +384,7 @@ public TimetableSnapshot commit(TransitLayerUpdater transitLayerUpdater, boolean ); if (transitLayerUpdater != null) { - transitLayerUpdater.update(dirtyTimetables, timetables); + transitLayerUpdater.update(dirtyTimetables.values(), timetables); } this.dirtyTimetables.clear(); @@ -402,15 +399,19 @@ public TimetableSnapshot commit(TransitLayerUpdater transitLayerUpdater, boolean * @param feedId feed id to clear the snapshot for */ public void clear(String feedId) { - if (readOnly) { - throw new ConcurrentModificationException("This TimetableSnapshot is read-only."); - } + validateNotReadOnly(); // Clear all data from snapshot. - boolean timetableWasModified = clearTimetable(feedId); - boolean realtimeAddedWasModified = clearRealtimeAddedTripPattern(feedId); - + boolean timetablesWereCleared = clearTimetables(feedId); + boolean newTripPatternsForModifiedTripsWereCleared = clearNewTripPatternsForModifiedTrips( + feedId + ); + boolean addedTripPatternsWereCleared = clearEntriesForRealtimeAddedTrips(feedId); // If this snapshot was modified, it will be dirty after the clear actions. - if (timetableWasModified || realtimeAddedWasModified) { + if ( + timetablesWereCleared || + newTripPatternsForModifiedTripsWereCleared || + addedTripPatternsWereCleared + ) { dirty = true; } } @@ -427,17 +428,15 @@ public void clear(String feedId) { * message and an attempt was made to re-associate it with its originally scheduled trip pattern. */ public boolean revertTripToScheduledTripPattern(FeedScopedId tripId, LocalDate serviceDate) { - if (readOnly) { - throw new ConcurrentModificationException("This TimetableSnapshot is read-only."); - } + validateNotReadOnly(); boolean success = false; - final TripPattern pattern = getRealtimeAddedTripPattern(tripId, serviceDate); + final TripPattern pattern = getNewTripPatternForModifiedTrip(tripId, serviceDate); if (pattern != null) { // Dissociate the given trip from any realtime-added pattern. // The trip will then fall back to its original scheduled pattern. - realtimeAddedTripPattern.remove(new TripIdAndServiceDate(tripId, serviceDate)); + realTimeNewTripPatternsForModifiedTrips.remove(new TripIdAndServiceDate(tripId, serviceDate)); // Remove times for the trip from any timetables // under that now-obsolete realtime-added pattern. SortedSet sortedTimetables = this.timetables.get(pattern); @@ -459,8 +458,11 @@ public boolean revertTripToScheduledTripPattern(FeedScopedId tripId, LocalDate s if (tripTimesToRemove != null) { for (Timetable originalTimetable : sortedTimetables) { if (originalTimetable.getTripTimes().contains(tripTimesToRemove)) { - Timetable updatedTimetable = copyTimetable(pattern, serviceDate, originalTimetable); - updatedTimetable.getTripTimes().remove(tripTimesToRemove); + Timetable updatedTimetable = originalTimetable + .copyOf() + .removeTripTimes(tripTimesToRemove) + .build(); + swapTimetable(pattern, originalTimetable, updatedTimetable); } } } @@ -477,9 +479,7 @@ public boolean revertTripToScheduledTripPattern(FeedScopedId tripId, LocalDate s * @return true if any data has been modified and false if no purging has happened. */ public boolean purgeExpiredData(LocalDate serviceDate) { - if (readOnly) { - throw new ConcurrentModificationException("This TimetableSnapshot is read-only."); - } + validateNotReadOnly(); boolean modified = false; for (Iterator it = timetables.keySet().iterator(); it.hasNext();) { @@ -487,7 +487,7 @@ public boolean purgeExpiredData(LocalDate serviceDate) { SortedSet sortedTimetables = timetables.get(pattern); SortedSet toKeepTimetables = new TreeSet<>(new SortedTimetableComparator()); for (Timetable timetable : sortedTimetables) { - if (serviceDate.compareTo(timetable.getServiceDate()) < 0) { + if (serviceDate.isBefore(timetable.getServiceDate())) { toKeepTimetables.add(timetable); } else { modified = true; @@ -503,13 +503,13 @@ public boolean purgeExpiredData(LocalDate serviceDate) { // Also remove last added trip pattern for days that are purged for ( - Iterator> iterator = realtimeAddedTripPattern + Iterator> iterator = realTimeNewTripPatternsForModifiedTrips .entrySet() .iterator(); iterator.hasNext(); ) { TripIdAndServiceDate tripIdAndServiceDate = iterator.next().getKey(); - if (serviceDate.compareTo(tripIdAndServiceDate.serviceDate()) >= 0) { + if (!serviceDate.isBefore(tripIdAndServiceDate.serviceDate())) { iterator.remove(); modified = true; } @@ -538,7 +538,11 @@ public Collection getPatternsForStop(StopLocation stop) { * Does this snapshot contain any realtime data or is it completely empty? */ public boolean isEmpty() { - return dirtyTimetables.isEmpty() && timetables.isEmpty() && realtimeAddedTripPattern.isEmpty(); + return ( + dirtyTimetables.isEmpty() && + timetables.isEmpty() && + realTimeNewTripPatternsForModifiedTrips.isEmpty() + ); } /** @@ -547,22 +551,42 @@ public boolean isEmpty() { * @param feedId feed id to clear out * @return true if the timetable changed as a result of the call */ - private boolean clearTimetable(String feedId) { + private boolean clearTimetables(String feedId) { return timetables.keySet().removeIf(tripPattern -> feedId.equals(tripPattern.getFeedId())); } /** - * Clear all realtime added trip patterns matching the provided feed id. + * Clear new trip patterns for modified trips matching the provided feed id. * * @param feedId feed id to clear out - * @return true if the realtimeAddedTripPattern changed as a result of the call + * @return true if the newTripPatternForModifiedTrip changed as a result of the call */ - private boolean clearRealtimeAddedTripPattern(String feedId) { - return realtimeAddedTripPattern + private boolean clearNewTripPatternsForModifiedTrips(String feedId) { + return realTimeNewTripPatternsForModifiedTrips + .keySet() + .removeIf(tripIdAndServiceDate -> feedId.equals(tripIdAndServiceDate.tripId().getFeedId())); + } + + /** + * Clear all realtime added routes, trip patterns and trips matching the provided feed id. + * + * */ + private boolean clearEntriesForRealtimeAddedTrips(String feedId) { + // it is sufficient to test for the removal of added trips, since other indexed entities are + // added only if a new trip is added. + boolean removedEntry = realTimeAddedTrips .keySet() - .removeIf(realtimeAddedTripPattern -> - feedId.equals(realtimeAddedTripPattern.tripId().getFeedId()) - ); + .removeIf(id -> feedId.equals(id.getFeedId())); + realTimeAddedPatternForTrip.keySet().removeIf(trip -> feedId.equals(trip.getId().getFeedId())); + realTimeAddedTripOnServiceDateForTripAndDay + .keySet() + .removeIf(tripOnServiceDate -> feedId.equals(tripOnServiceDate.tripId().getFeedId())); + realTimeAddedTripOnServiceDateById.keySet().removeIf(id -> feedId.equals(id.getFeedId())); + realTimeAddedPatternsForRoute + .keySet() + .removeIf(route -> feedId.equals(route.getId().getFeedId())); + realtimeAddedRoutes.keySet().removeIf(id -> feedId.equals(id.getFeedId())); + return removedEntry; } /** @@ -579,36 +603,44 @@ private void addPatternToIndex(TripPattern tripPattern) { } /** - * Make a copy of the given timetable for a given pattern and service date. - * If the timetable was already copied-on write in this snapshot, the same instance will be - * returned. The SortedSet that holds the collection of Timetables for that pattern + * Replace the original Timetable by the updated one in the timetable index. + * The SortedSet that holds the collection of Timetables for that pattern * (sorted by service date) is shared between multiple snapshots and must be copied as well.
* Note on performance: if multiple Timetables are modified in a SortedSet, the SortedSet will be * copied multiple times. The impact on memory/garbage collection is assumed to be minimal * since the collection is small. * The SortedSet is made immutable to prevent change after snapshot publication. */ - private Timetable copyTimetable(TripPattern pattern, LocalDate serviceDate, Timetable tt) { - if (!dirtyTimetables.contains(tt)) { - Timetable old = tt; - tt = new Timetable(tt, serviceDate); - SortedSet sortedTimetables = timetables.get(pattern); - if (sortedTimetables == null) { - sortedTimetables = new TreeSet<>(new SortedTimetableComparator()); - } else { - SortedSet temp = new TreeSet<>(new SortedTimetableComparator()); - temp.addAll(sortedTimetables); - sortedTimetables = temp; - } - if (old.getServiceDate() != null) { - sortedTimetables.remove(old); - } - sortedTimetables.add(tt); - timetables.put(pattern, ImmutableSortedSet.copyOfSorted(sortedTimetables)); - dirtyTimetables.add(tt); - dirty = true; + private void swapTimetable(TripPattern pattern, Timetable original, Timetable updated) { + SortedSet sortedTimetables = timetables.get(pattern); + if (sortedTimetables == null) { + sortedTimetables = new TreeSet<>(new SortedTimetableComparator()); + } else { + SortedSet temp = new TreeSet<>(new SortedTimetableComparator()); + temp.addAll(sortedTimetables); + sortedTimetables = temp; + } + // This is a minor optimization: + // Since sortedTimetables contains only timetables created in real-time, no need to try to + // remove the original if it was not created by real-time. + if (original.isCreatedByRealTimeUpdater()) { + sortedTimetables.remove(original); + } + sortedTimetables.add(updated); + timetables.put(pattern, ImmutableSortedSet.copyOfSorted(sortedTimetables)); + + // if the timetable was already modified by a previous real-time update in the same snapshot + // and for the same service date, + // then the previously updated timetable is superseded by the new one + dirtyTimetables.put(new TripPatternAndServiceDate(pattern, updated.getServiceDate()), updated); + + dirty = true; + } + + private void validateNotReadOnly() { + if (readOnly) { + throw new ConcurrentModificationException("This TimetableSnapshot is read-only."); } - return tt; } protected static class SortedTimetableComparator implements Comparator { @@ -618,4 +650,9 @@ public int compare(Timetable t1, Timetable t2) { return t1.getServiceDate().compareTo(t2.getServiceDate()); } } + + /** + * A pair made of a TripPattern and one of the service dates it is running on. + */ + private record TripPatternAndServiceDate(TripPattern tripPattern, LocalDate serviceDate) {} } diff --git a/src/main/java/org/opentripplanner/model/TimetableSnapshotProvider.java b/application/src/main/java/org/opentripplanner/model/TimetableSnapshotProvider.java similarity index 100% rename from src/main/java/org/opentripplanner/model/TimetableSnapshotProvider.java rename to application/src/main/java/org/opentripplanner/model/TimetableSnapshotProvider.java diff --git a/src/main/java/org/opentripplanner/model/TripStopTimes.java b/application/src/main/java/org/opentripplanner/model/TripStopTimes.java similarity index 100% rename from src/main/java/org/opentripplanner/model/TripStopTimes.java rename to application/src/main/java/org/opentripplanner/model/TripStopTimes.java diff --git a/src/main/java/org/opentripplanner/model/TripTimeOnDate.java b/application/src/main/java/org/opentripplanner/model/TripTimeOnDate.java similarity index 100% rename from src/main/java/org/opentripplanner/model/TripTimeOnDate.java rename to application/src/main/java/org/opentripplanner/model/TripTimeOnDate.java diff --git a/src/main/java/org/opentripplanner/model/TripTimesPatch.java b/application/src/main/java/org/opentripplanner/model/TripTimesPatch.java similarity index 100% rename from src/main/java/org/opentripplanner/model/TripTimesPatch.java rename to application/src/main/java/org/opentripplanner/model/TripTimesPatch.java diff --git a/src/main/java/org/opentripplanner/model/calendar/CalendarService.java b/application/src/main/java/org/opentripplanner/model/calendar/CalendarService.java similarity index 100% rename from src/main/java/org/opentripplanner/model/calendar/CalendarService.java rename to application/src/main/java/org/opentripplanner/model/calendar/CalendarService.java diff --git a/src/main/java/org/opentripplanner/model/calendar/CalendarServiceData.java b/application/src/main/java/org/opentripplanner/model/calendar/CalendarServiceData.java similarity index 98% rename from src/main/java/org/opentripplanner/model/calendar/CalendarServiceData.java rename to application/src/main/java/org/opentripplanner/model/calendar/CalendarServiceData.java index b007fa08ea1..81011f03bd0 100644 --- a/src/main/java/org/opentripplanner/model/calendar/CalendarServiceData.java +++ b/application/src/main/java/org/opentripplanner/model/calendar/CalendarServiceData.java @@ -11,8 +11,8 @@ import java.util.Map; import java.util.Optional; import java.util.Set; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.time.ServiceDateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/model/calendar/ServiceCalendar.java b/application/src/main/java/org/opentripplanner/model/calendar/ServiceCalendar.java similarity index 100% rename from src/main/java/org/opentripplanner/model/calendar/ServiceCalendar.java rename to application/src/main/java/org/opentripplanner/model/calendar/ServiceCalendar.java diff --git a/src/main/java/org/opentripplanner/model/calendar/ServiceCalendarDate.java b/application/src/main/java/org/opentripplanner/model/calendar/ServiceCalendarDate.java similarity index 97% rename from src/main/java/org/opentripplanner/model/calendar/ServiceCalendarDate.java rename to application/src/main/java/org/opentripplanner/model/calendar/ServiceCalendarDate.java index 87fb173a112..9d6ddb748cf 100644 --- a/src/main/java/org/opentripplanner/model/calendar/ServiceCalendarDate.java +++ b/application/src/main/java/org/opentripplanner/model/calendar/ServiceCalendarDate.java @@ -4,8 +4,8 @@ import java.io.Serializable; import java.time.LocalDate; import java.util.Objects; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This class explicitly activate or disable a service by date. It can be used in two ways. diff --git a/src/main/java/org/opentripplanner/model/calendar/ServiceDateInterval.java b/application/src/main/java/org/opentripplanner/model/calendar/ServiceDateInterval.java similarity index 96% rename from src/main/java/org/opentripplanner/model/calendar/ServiceDateInterval.java rename to application/src/main/java/org/opentripplanner/model/calendar/ServiceDateInterval.java index 5d2657912fc..db0aef21bd0 100644 --- a/src/main/java/org/opentripplanner/model/calendar/ServiceDateInterval.java +++ b/application/src/main/java/org/opentripplanner/model/calendar/ServiceDateInterval.java @@ -6,8 +6,7 @@ import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.util.Objects; -import javax.annotation.Nonnull; -import org.opentripplanner.framework.time.ServiceDateUtils; +import org.opentripplanner.utils.time.ServiceDateUtils; /** * Value object which represent a service date interval from a starting date until an end date. @@ -52,7 +51,6 @@ public boolean isUnbounded() { * Return the interval start, inclusive. If the period start is unbounded the {@link * LocalDate#MIN} is returned. */ - @Nonnull public LocalDate getStart() { return start; } @@ -61,7 +59,6 @@ public LocalDate getStart() { * Return the interval end, inclusive. If the period start is unbounded the {@link * LocalDate#MAX} is returned. */ - @Nonnull public LocalDate getEnd() { return end; } diff --git a/src/main/java/org/opentripplanner/model/calendar/impl/CalendarServiceDataFactoryImpl.java b/application/src/main/java/org/opentripplanner/model/calendar/impl/CalendarServiceDataFactoryImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/model/calendar/impl/CalendarServiceDataFactoryImpl.java rename to application/src/main/java/org/opentripplanner/model/calendar/impl/CalendarServiceDataFactoryImpl.java diff --git a/src/main/java/org/opentripplanner/model/calendar/impl/CalendarServiceImpl.java b/application/src/main/java/org/opentripplanner/model/calendar/impl/CalendarServiceImpl.java similarity index 100% rename from src/main/java/org/opentripplanner/model/calendar/impl/CalendarServiceImpl.java rename to application/src/main/java/org/opentripplanner/model/calendar/impl/CalendarServiceImpl.java diff --git a/src/main/java/org/opentripplanner/model/calendar/impl/MultipleCalendarsForServiceIdException.java b/application/src/main/java/org/opentripplanner/model/calendar/impl/MultipleCalendarsForServiceIdException.java similarity index 100% rename from src/main/java/org/opentripplanner/model/calendar/impl/MultipleCalendarsForServiceIdException.java rename to application/src/main/java/org/opentripplanner/model/calendar/impl/MultipleCalendarsForServiceIdException.java diff --git a/src/main/java/org/opentripplanner/model/calendar/impl/UnknownAgencyTimezoneException.java b/application/src/main/java/org/opentripplanner/model/calendar/impl/UnknownAgencyTimezoneException.java similarity index 100% rename from src/main/java/org/opentripplanner/model/calendar/impl/UnknownAgencyTimezoneException.java rename to application/src/main/java/org/opentripplanner/model/calendar/impl/UnknownAgencyTimezoneException.java diff --git a/src/main/java/org/opentripplanner/model/calendar/openinghours/OHCalendar.java b/application/src/main/java/org/opentripplanner/model/calendar/openinghours/OHCalendar.java similarity index 97% rename from src/main/java/org/opentripplanner/model/calendar/openinghours/OHCalendar.java rename to application/src/main/java/org/opentripplanner/model/calendar/openinghours/OHCalendar.java index 7c084d28186..1881ed72dcc 100644 --- a/src/main/java/org/opentripplanner/model/calendar/openinghours/OHCalendar.java +++ b/application/src/main/java/org/opentripplanner/model/calendar/openinghours/OHCalendar.java @@ -8,7 +8,7 @@ import java.time.temporal.ChronoUnit; import java.util.List; import java.util.Objects; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; public class OHCalendar implements Serializable { diff --git a/src/main/java/org/opentripplanner/model/calendar/openinghours/OHCalendarBuilder.java b/application/src/main/java/org/opentripplanner/model/calendar/openinghours/OHCalendarBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/model/calendar/openinghours/OHCalendarBuilder.java rename to application/src/main/java/org/opentripplanner/model/calendar/openinghours/OHCalendarBuilder.java diff --git a/src/main/java/org/opentripplanner/model/calendar/openinghours/OHSearchContext.java b/application/src/main/java/org/opentripplanner/model/calendar/openinghours/OHSearchContext.java similarity index 100% rename from src/main/java/org/opentripplanner/model/calendar/openinghours/OHSearchContext.java rename to application/src/main/java/org/opentripplanner/model/calendar/openinghours/OHSearchContext.java diff --git a/src/main/java/org/opentripplanner/model/calendar/openinghours/OpeningHours.java b/application/src/main/java/org/opentripplanner/model/calendar/openinghours/OpeningHours.java similarity index 97% rename from src/main/java/org/opentripplanner/model/calendar/openinghours/OpeningHours.java rename to application/src/main/java/org/opentripplanner/model/calendar/openinghours/OpeningHours.java index 2918b43bd42..258caedacdc 100644 --- a/src/main/java/org/opentripplanner/model/calendar/openinghours/OpeningHours.java +++ b/application/src/main/java/org/opentripplanner/model/calendar/openinghours/OpeningHours.java @@ -4,7 +4,7 @@ import java.time.LocalTime; import java.util.BitSet; import java.util.Objects; -import org.opentripplanner.framework.time.TimeUtils; +import org.opentripplanner.utils.time.TimeUtils; /** */ diff --git a/src/main/java/org/opentripplanner/model/calendar/openinghours/OpeningHoursCalendarService.java b/application/src/main/java/org/opentripplanner/model/calendar/openinghours/OpeningHoursCalendarService.java similarity index 100% rename from src/main/java/org/opentripplanner/model/calendar/openinghours/OpeningHoursCalendarService.java rename to application/src/main/java/org/opentripplanner/model/calendar/openinghours/OpeningHoursCalendarService.java diff --git a/src/main/java/org/opentripplanner/model/calendar/openinghours/OsmOpeningHoursSupport.java b/application/src/main/java/org/opentripplanner/model/calendar/openinghours/OsmOpeningHoursSupport.java similarity index 97% rename from src/main/java/org/opentripplanner/model/calendar/openinghours/OsmOpeningHoursSupport.java rename to application/src/main/java/org/opentripplanner/model/calendar/openinghours/OsmOpeningHoursSupport.java index acb500fee62..e87a63fc678 100644 --- a/src/main/java/org/opentripplanner/model/calendar/openinghours/OsmOpeningHoursSupport.java +++ b/application/src/main/java/org/opentripplanner/model/calendar/openinghours/OsmOpeningHoursSupport.java @@ -3,7 +3,7 @@ import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.stream.Collectors; -import org.opentripplanner.framework.time.TimeUtils; +import org.opentripplanner.utils.time.TimeUtils; public class OsmOpeningHoursSupport { diff --git a/src/main/java/org/opentripplanner/model/fare/FareMedium.java b/application/src/main/java/org/opentripplanner/model/fare/FareMedium.java similarity index 89% rename from src/main/java/org/opentripplanner/model/fare/FareMedium.java rename to application/src/main/java/org/opentripplanner/model/fare/FareMedium.java index 08a0a738666..caa286b1c31 100644 --- a/src/main/java/org/opentripplanner/model/fare/FareMedium.java +++ b/application/src/main/java/org/opentripplanner/model/fare/FareMedium.java @@ -1,8 +1,8 @@ package org.opentripplanner.model.fare; import java.util.Objects; -import org.opentripplanner.framework.lang.Sandbox; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.lang.Sandbox; /** * diff --git a/src/main/java/org/opentripplanner/model/fare/FareProduct.java b/application/src/main/java/org/opentripplanner/model/fare/FareProduct.java similarity index 96% rename from src/main/java/org/opentripplanner/model/fare/FareProduct.java rename to application/src/main/java/org/opentripplanner/model/fare/FareProduct.java index 189b73807e7..8aa86e5af89 100644 --- a/src/main/java/org/opentripplanner/model/fare/FareProduct.java +++ b/application/src/main/java/org/opentripplanner/model/fare/FareProduct.java @@ -6,10 +6,10 @@ import java.util.Objects; import java.util.UUID; import javax.annotation.Nullable; -import org.opentripplanner.framework.lang.Sandbox; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.lang.Sandbox; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A ticket that a user can purchase to travel. diff --git a/src/main/java/org/opentripplanner/model/fare/FareProductBuilder.java b/application/src/main/java/org/opentripplanner/model/fare/FareProductBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/model/fare/FareProductBuilder.java rename to application/src/main/java/org/opentripplanner/model/fare/FareProductBuilder.java diff --git a/src/main/java/org/opentripplanner/model/fare/FareProductUse.java b/application/src/main/java/org/opentripplanner/model/fare/FareProductUse.java similarity index 83% rename from src/main/java/org/opentripplanner/model/fare/FareProductUse.java rename to application/src/main/java/org/opentripplanner/model/fare/FareProductUse.java index 33c67f56314..99f34503270 100644 --- a/src/main/java/org/opentripplanner/model/fare/FareProductUse.java +++ b/application/src/main/java/org/opentripplanner/model/fare/FareProductUse.java @@ -1,6 +1,6 @@ package org.opentripplanner.model.fare; -import org.opentripplanner.framework.lang.Sandbox; +import org.opentripplanner.utils.lang.Sandbox; /** * diff --git a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java b/application/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java similarity index 96% rename from src/main/java/org/opentripplanner/model/fare/ItineraryFares.java rename to application/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java index 1a64f21c41b..d39180ac3a9 100644 --- a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java +++ b/application/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java @@ -8,9 +8,9 @@ import java.util.List; import java.util.Objects; import java.util.Set; -import org.opentripplanner.framework.lang.Sandbox; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.plan.Leg; +import org.opentripplanner.utils.lang.Sandbox; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * diff --git a/src/main/java/org/opentripplanner/model/fare/RiderCategory.java b/application/src/main/java/org/opentripplanner/model/fare/RiderCategory.java similarity index 59% rename from src/main/java/org/opentripplanner/model/fare/RiderCategory.java rename to application/src/main/java/org/opentripplanner/model/fare/RiderCategory.java index 43f777cd31a..ee293d2142c 100644 --- a/src/main/java/org/opentripplanner/model/fare/RiderCategory.java +++ b/application/src/main/java/org/opentripplanner/model/fare/RiderCategory.java @@ -1,13 +1,12 @@ package org.opentripplanner.model.fare; import java.util.Objects; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opentripplanner.framework.lang.Sandbox; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.lang.Sandbox; @Sandbox -public record RiderCategory(@Nonnull FeedScopedId id, @Nonnull String name, @Nullable String url) { +public record RiderCategory(FeedScopedId id, String name, @Nullable String url) { public RiderCategory { Objects.requireNonNull(id); Objects.requireNonNull(name); diff --git a/src/main/java/org/opentripplanner/model/impl/OtpTransitServiceBuilder.java b/application/src/main/java/org/opentripplanner/model/impl/OtpTransitServiceBuilder.java similarity index 87% rename from src/main/java/org/opentripplanner/model/impl/OtpTransitServiceBuilder.java rename to application/src/main/java/org/opentripplanner/model/impl/OtpTransitServiceBuilder.java index 373b99f0bc6..2b270e8afa4 100644 --- a/src/main/java/org/opentripplanner/model/impl/OtpTransitServiceBuilder.java +++ b/application/src/main/java/org/opentripplanner/model/impl/OtpTransitServiceBuilder.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.opentripplanner.ext.flex.trip.FlexTrip; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.gtfs.mapping.StaySeatedNotAllowed; @@ -15,6 +16,7 @@ import org.opentripplanner.model.Frequency; import org.opentripplanner.model.OtpTransitService; import org.opentripplanner.model.ShapePoint; +import org.opentripplanner.model.Timetable; import org.opentripplanner.model.TripStopTimes; import org.opentripplanner.model.calendar.CalendarServiceData; import org.opentripplanner.model.calendar.ServiceCalendar; @@ -24,7 +26,7 @@ import org.opentripplanner.model.transfer.ConstrainedTransfer; import org.opentripplanner.model.transfer.TransferPoint; import org.opentripplanner.routing.api.request.framework.TimePenalty; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; import org.opentripplanner.transit.model.basic.Notice; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.framework.DefaultEntityById; @@ -51,8 +53,9 @@ import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.StopModelBuilder; +import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -75,7 +78,7 @@ public class OtpTransitServiceBuilder { private final List frequencies = new ArrayList<>(); - private final StopModelBuilder stopModelBuilder; + private final SiteRepositoryBuilder siteRepositoryBuilder; private final Multimap noticeAssignments = ArrayListMultimap.create(); @@ -121,8 +124,8 @@ public class OtpTransitServiceBuilder { private final DataImportIssueStore issueStore; - public OtpTransitServiceBuilder(StopModel stopModel, DataImportIssueStore issueStore) { - this.stopModelBuilder = stopModel.withContext(); + public OtpTransitServiceBuilder(SiteRepository siteRepository, DataImportIssueStore issueStore) { + this.siteRepositoryBuilder = siteRepository.withContext(); this.issueStore = issueStore; } @@ -148,16 +151,16 @@ public List getFrequencies() { return frequencies; } - public StopModelBuilder stopModel() { - return stopModelBuilder; + public SiteRepositoryBuilder siteRepository() { + return siteRepositoryBuilder; } public ImmutableEntityById getGroupsOfStationsById() { - return stopModelBuilder.groupOfStationById(); + return siteRepositoryBuilder.groupOfStationById(); } public ImmutableEntityById getMultiModalStationsById() { - return stopModelBuilder.multiModalStationById(); + return siteRepositoryBuilder.multiModalStationById(); } /** @@ -185,11 +188,11 @@ public Multimap getShapePoints() { } public ImmutableEntityById getStations() { - return stopModelBuilder.stationById(); + return siteRepositoryBuilder.stationById(); } public ImmutableEntityById getStops() { - return stopModelBuilder.regularStopsById(); + return siteRepositoryBuilder.regularStopsById(); } public EntityById getEntrances() { @@ -205,11 +208,11 @@ public EntityById getBoardingAreas() { } public ImmutableEntityById getAreaStops() { - return stopModelBuilder.areaStopById(); + return siteRepositoryBuilder.areaStopById(); } public ImmutableEntityById getGroupStops() { - return stopModelBuilder.groupStopById(); + return siteRepositoryBuilder.groupStopById(); } public TripStopTimes getStopTimesSortedByTrip() { @@ -375,21 +378,40 @@ private void removeStopTimesForNoneExistingTrips() { private void fixOrRemovePatternsWhichReferenceNoneExistingTrips() { int orgSize = tripPatterns.size(); List> removePatterns = new ArrayList<>(); + List updatedPatterns = new ArrayList<>(); for (Map.Entry e : tripPatterns.entries()) { TripPattern ptn = e.getValue(); - ptn.removeTrips(t -> !tripsById.containsKey(t.getId())); - if (ptn.scheduledTripsAsStream().findAny().isEmpty()) { + Set tripTimesToBeRemoved = ptn + .getScheduledTimetable() + .getTripTimes() + .stream() + .filter(tripTimes -> !tripsById.containsKey(tripTimes.getTrip().getId())) + .collect(Collectors.toUnmodifiableSet()); + if (!tripTimesToBeRemoved.isEmpty()) { removePatterns.add(e); + Timetable updatedTimetable = ptn + .getScheduledTimetable() + .copyOf() + .removeAllTripTimes(tripTimesToBeRemoved) + .build(); + TripPattern updatedPattern = ptn.copy().withScheduledTimeTable(updatedTimetable).build(); + if (!updatedTimetable.getTripTimes().isEmpty()) { + updatedPatterns.add(updatedPattern); + } else { + issueStore.add( + "RemovedEmptyTripPattern", + "Removed trip pattern %s as it contains no trips", + updatedPattern.getId() + ); + } } } for (Map.Entry it : removePatterns) { tripPatterns.remove(it.getKey(), it.getValue()); - issueStore.add( - "RemovedEmptyTripPattern", - "Removed trip pattern %s as it contains no trips", - it.getValue().getId() - ); + } + for (TripPattern tripPattern : updatedPatterns) { + tripPatterns.put(tripPattern.getStopPattern(), tripPattern); } logRemove("TripPattern", orgSize, tripPatterns.size(), "No trips for pattern exist."); } diff --git a/src/main/java/org/opentripplanner/model/impl/OtpTransitServiceImpl.java b/application/src/main/java/org/opentripplanner/model/impl/OtpTransitServiceImpl.java similarity index 96% rename from src/main/java/org/opentripplanner/model/impl/OtpTransitServiceImpl.java rename to application/src/main/java/org/opentripplanner/model/impl/OtpTransitServiceImpl.java index 9ca549f1631..2f735f36435 100644 --- a/src/main/java/org/opentripplanner/model/impl/OtpTransitServiceImpl.java +++ b/application/src/main/java/org/opentripplanner/model/impl/OtpTransitServiceImpl.java @@ -26,7 +26,7 @@ import org.opentripplanner.transit.model.site.Pathway; import org.opentripplanner.transit.model.site.PathwayNode; import org.opentripplanner.transit.model.timetable.Trip; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; /** * A in-memory implementation of {@link OtpTransitService}. It's super fast for most methods, but @@ -45,7 +45,7 @@ class OtpTransitServiceImpl implements OtpTransitService { private final Collection feedInfos; - private final StopModel stopModel; + private final SiteRepository siteRepository; private final ImmutableListMultimap noticeAssignments; @@ -77,7 +77,7 @@ class OtpTransitServiceImpl implements OtpTransitService { OtpTransitServiceImpl(OtpTransitServiceBuilder builder) { this.agencies = immutableList(builder.getAgenciesById().values()); this.feedInfos = immutableList(builder.getFeedInfos()); - this.stopModel = builder.stopModel().build(); + this.siteRepository = builder.siteRepository().build(); this.noticeAssignments = ImmutableListMultimap.copyOf(builder.getNoticeAssignments()); this.operators = immutableList(builder.getOperatorsById().values()); this.pathways = immutableList(builder.getPathways()); @@ -109,8 +109,8 @@ public Collection getAllFeedInfos() { } @Override - public StopModel stopModel() { - return stopModel; + public SiteRepository siteRepository() { + return siteRepository; } /** diff --git a/src/main/java/org/opentripplanner/model/modes/AllowAllModesFilter.java b/application/src/main/java/org/opentripplanner/model/modes/AllowAllModesFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/model/modes/AllowAllModesFilter.java rename to application/src/main/java/org/opentripplanner/model/modes/AllowAllModesFilter.java diff --git a/src/main/java/org/opentripplanner/model/modes/AllowMainAndSubModeFilter.java b/application/src/main/java/org/opentripplanner/model/modes/AllowMainAndSubModeFilter.java similarity index 85% rename from src/main/java/org/opentripplanner/model/modes/AllowMainAndSubModeFilter.java rename to application/src/main/java/org/opentripplanner/model/modes/AllowMainAndSubModeFilter.java index ec197522590..a6f75ac0ed9 100644 --- a/src/main/java/org/opentripplanner/model/modes/AllowMainAndSubModeFilter.java +++ b/application/src/main/java/org/opentripplanner/model/modes/AllowMainAndSubModeFilter.java @@ -1,12 +1,11 @@ package org.opentripplanner.model.modes; import java.util.Objects; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.transit.model.basic.MainAndSubMode; import org.opentripplanner.transit.model.basic.SubMode; import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.utils.tostring.ToStringBuilder; class AllowMainAndSubModeFilter implements AllowTransitModeFilter { @@ -14,12 +13,12 @@ class AllowMainAndSubModeFilter implements AllowTransitModeFilter { private final SubMode subMode; - AllowMainAndSubModeFilter(@Nonnull TransitMode mainMode, @Nullable SubMode subMode) { + AllowMainAndSubModeFilter(TransitMode mainMode, @Nullable SubMode subMode) { this.mainMode = mainMode; this.subMode = subMode; } - AllowMainAndSubModeFilter(@Nonnull MainAndSubMode mode) { + AllowMainAndSubModeFilter(MainAndSubMode mode) { this(mode.mainMode(), mode.subMode()); } @@ -34,7 +33,6 @@ public boolean match(TransitMode transitMode, SubMode netexSubMode) { return mainMode == transitMode && subMode == netexSubMode; } - @Nonnull TransitMode mainMode() { return mainMode; } diff --git a/src/main/java/org/opentripplanner/model/modes/AllowMainAndSubModesFilter.java b/application/src/main/java/org/opentripplanner/model/modes/AllowMainAndSubModesFilter.java similarity index 97% rename from src/main/java/org/opentripplanner/model/modes/AllowMainAndSubModesFilter.java rename to application/src/main/java/org/opentripplanner/model/modes/AllowMainAndSubModesFilter.java index 50a20f72c55..5d40b365204 100644 --- a/src/main/java/org/opentripplanner/model/modes/AllowMainAndSubModesFilter.java +++ b/application/src/main/java/org/opentripplanner/model/modes/AllowMainAndSubModesFilter.java @@ -5,9 +5,9 @@ import java.util.Comparator; import java.util.List; import java.util.Objects; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.transit.model.basic.SubMode; import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.utils.tostring.ToStringBuilder; class AllowMainAndSubModesFilter implements AllowTransitModeFilter { diff --git a/src/main/java/org/opentripplanner/model/modes/AllowMainModeFilter.java b/application/src/main/java/org/opentripplanner/model/modes/AllowMainModeFilter.java similarity index 94% rename from src/main/java/org/opentripplanner/model/modes/AllowMainModeFilter.java rename to application/src/main/java/org/opentripplanner/model/modes/AllowMainModeFilter.java index eaa6719d143..9efcceee86e 100644 --- a/src/main/java/org/opentripplanner/model/modes/AllowMainModeFilter.java +++ b/application/src/main/java/org/opentripplanner/model/modes/AllowMainModeFilter.java @@ -1,8 +1,8 @@ package org.opentripplanner.model.modes; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.transit.model.basic.SubMode; import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.utils.tostring.ToStringBuilder; class AllowMainModeFilter implements AllowTransitModeFilter { diff --git a/src/main/java/org/opentripplanner/model/modes/AllowMainModesFilter.java b/application/src/main/java/org/opentripplanner/model/modes/AllowMainModesFilter.java similarity index 94% rename from src/main/java/org/opentripplanner/model/modes/AllowMainModesFilter.java rename to application/src/main/java/org/opentripplanner/model/modes/AllowMainModesFilter.java index f6c8aa3b4a2..0926f6d5621 100644 --- a/src/main/java/org/opentripplanner/model/modes/AllowMainModesFilter.java +++ b/application/src/main/java/org/opentripplanner/model/modes/AllowMainModesFilter.java @@ -3,9 +3,9 @@ import java.util.Collection; import java.util.EnumSet; import java.util.Set; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.transit.model.basic.SubMode; import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.utils.tostring.ToStringBuilder; class AllowMainModesFilter implements AllowTransitModeFilter { diff --git a/src/main/java/org/opentripplanner/model/modes/AllowTransitModeFilter.java b/application/src/main/java/org/opentripplanner/model/modes/AllowTransitModeFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/model/modes/AllowTransitModeFilter.java rename to application/src/main/java/org/opentripplanner/model/modes/AllowTransitModeFilter.java diff --git a/src/main/java/org/opentripplanner/model/modes/ExcludeAllTransitFilter.java b/application/src/main/java/org/opentripplanner/model/modes/ExcludeAllTransitFilter.java similarity index 93% rename from src/main/java/org/opentripplanner/model/modes/ExcludeAllTransitFilter.java rename to application/src/main/java/org/opentripplanner/model/modes/ExcludeAllTransitFilter.java index 163d82170b0..08fdf4a528b 100644 --- a/src/main/java/org/opentripplanner/model/modes/ExcludeAllTransitFilter.java +++ b/application/src/main/java/org/opentripplanner/model/modes/ExcludeAllTransitFilter.java @@ -1,10 +1,10 @@ package org.opentripplanner.model.modes; import java.io.Serializable; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.api.request.request.filter.TransitFilter; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This filter will exclude everything. diff --git a/src/main/java/org/opentripplanner/model/modes/FilterCollection.java b/application/src/main/java/org/opentripplanner/model/modes/FilterCollection.java similarity index 100% rename from src/main/java/org/opentripplanner/model/modes/FilterCollection.java rename to application/src/main/java/org/opentripplanner/model/modes/FilterCollection.java diff --git a/src/main/java/org/opentripplanner/model/modes/FilterFactory.java b/application/src/main/java/org/opentripplanner/model/modes/FilterFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/model/modes/FilterFactory.java rename to application/src/main/java/org/opentripplanner/model/modes/FilterFactory.java diff --git a/src/main/java/org/opentripplanner/model/plan/AbsoluteDirection.java b/application/src/main/java/org/opentripplanner/model/plan/AbsoluteDirection.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/AbsoluteDirection.java rename to application/src/main/java/org/opentripplanner/model/plan/AbsoluteDirection.java diff --git a/src/main/java/org/opentripplanner/model/plan/ElevationProfile.java b/application/src/main/java/org/opentripplanner/model/plan/ElevationProfile.java similarity index 98% rename from src/main/java/org/opentripplanner/model/plan/ElevationProfile.java rename to application/src/main/java/org/opentripplanner/model/plan/ElevationProfile.java index a293039c3c3..91f3a748a37 100644 --- a/src/main/java/org/opentripplanner/model/plan/ElevationProfile.java +++ b/application/src/main/java/org/opentripplanner/model/plan/ElevationProfile.java @@ -4,8 +4,8 @@ import java.util.List; import java.util.Objects; import java.util.function.Predicate; -import org.opentripplanner.framework.lang.DoubleUtils; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.lang.DoubleUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Represents an elevation profile as a list of {@code x,y} coordinates. The {@code x} is the diff --git a/src/main/java/org/opentripplanner/model/plan/Emissions.java b/application/src/main/java/org/opentripplanner/model/plan/Emissions.java similarity index 88% rename from src/main/java/org/opentripplanner/model/plan/Emissions.java rename to application/src/main/java/org/opentripplanner/model/plan/Emissions.java index e19ce3a914a..3339cc8b93f 100644 --- a/src/main/java/org/opentripplanner/model/plan/Emissions.java +++ b/application/src/main/java/org/opentripplanner/model/plan/Emissions.java @@ -1,7 +1,7 @@ package org.opentripplanner.model.plan; -import org.opentripplanner.framework.lang.Sandbox; import org.opentripplanner.framework.model.Grams; +import org.opentripplanner.utils.lang.Sandbox; /** * Represents the emissions of a journey. Each type of emissions has its own field and unit. diff --git a/src/main/java/org/opentripplanner/model/plan/FrequencyTransitLeg.java b/application/src/main/java/org/opentripplanner/model/plan/FrequencyTransitLeg.java similarity index 97% rename from src/main/java/org/opentripplanner/model/plan/FrequencyTransitLeg.java rename to application/src/main/java/org/opentripplanner/model/plan/FrequencyTransitLeg.java index 48c4b1b7b87..dc00dd49f22 100644 --- a/src/main/java/org/opentripplanner/model/plan/FrequencyTransitLeg.java +++ b/application/src/main/java/org/opentripplanner/model/plan/FrequencyTransitLeg.java @@ -2,8 +2,8 @@ import java.util.ArrayList; import java.util.List; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.utils.time.ServiceDateUtils; /** * One leg of a trip -- that is, a temporally continuous piece of the journey that takes place on a diff --git a/src/main/java/org/opentripplanner/model/plan/FrequencyTransitLegBuilder.java b/application/src/main/java/org/opentripplanner/model/plan/FrequencyTransitLegBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/FrequencyTransitLegBuilder.java rename to application/src/main/java/org/opentripplanner/model/plan/FrequencyTransitLegBuilder.java diff --git a/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java b/application/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java rename to application/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java diff --git a/src/main/java/org/opentripplanner/model/plan/Itinerary.java b/application/src/main/java/org/opentripplanner/model/plan/Itinerary.java similarity index 93% rename from src/main/java/org/opentripplanner/model/plan/Itinerary.java rename to application/src/main/java/org/opentripplanner/model/plan/Itinerary.java index dee80addd91..5ff936f3118 100644 --- a/src/main/java/org/opentripplanner/model/plan/Itinerary.java +++ b/application/src/main/java/org/opentripplanner/model/plan/Itinerary.java @@ -13,16 +13,16 @@ import java.util.stream.Stream; import javax.annotation.Nullable; import org.opentripplanner.ext.flex.FlexibleTransitLeg; -import org.opentripplanner.framework.lang.DoubleUtils; import org.opentripplanner.framework.model.TimeAndCost; -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.model.RaptorCostConverter; import org.opentripplanner.raptor.api.path.PathStringBuilder; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.preference.ItineraryFilterPreferences; +import org.opentripplanner.utils.lang.DoubleUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * An Itinerary is one complete way of getting from the start location to the end location. @@ -64,12 +64,14 @@ public class Itinerary implements ItinerarySortKey { /* other properties */ private final List systemNotices = new ArrayList<>(); + private final boolean searchWindowAware; private List legs; private ItineraryFares fare = ItineraryFares.empty(); - public Itinerary(List legs) { + private Itinerary(List legs, boolean searchWindowAware) { setLegs(legs); + this.searchWindowAware = searchWindowAware; // Set aggregated data ItinerariesCalculateLegTotals totals = new ItinerariesCalculateLegTotals(legs); @@ -87,6 +89,21 @@ public Itinerary(List legs) { this.setElevationLost(totals.totalElevationLost); } + /** + * Creates an itinerary that contains scheduled transit which is aware of the search window. + */ + public static Itinerary createScheduledTransitItinerary(List legs) { + return new Itinerary(legs, true); + } + + /** + * Creates an itinerary that creates only street or flex results which are not aware of the + * time window. + */ + public static Itinerary createDirectItinerary(List legs) { + return new Itinerary(legs, false); + } + /** * Time that the trip departs. */ @@ -162,6 +179,15 @@ public boolean isOnStreetAllTheWay() { return isStreetOnly(); } + /** + * Returns true if this itinerary has only flex and walking legs. + */ + public boolean isDirectFlex() { + var containsFlex = legs.stream().anyMatch(Leg::isFlexibleTrip); + var flexOrWalkOnly = legs.stream().allMatch(l -> l.isFlexibleTrip() || l.isWalkingLeg()); + return containsFlex && flexOrWalkOnly; + } + /** TRUE if at least one leg is a transit leg. */ public boolean hasTransit() { return legs @@ -169,6 +195,14 @@ public boolean hasTransit() { .anyMatch(l -> l instanceof ScheduledTransitLeg || l instanceof FlexibleTransitLeg); } + /** + * Returns true if this itinerary was produced by an algorithm that is aware of the search window. + * As of 2024 only the itineraries produced by RAPTOR that do that. + */ + public boolean isSearchWindowAware() { + return searchWindowAware; + } + public Leg firstLeg() { return getLegs().get(0); } @@ -198,7 +232,7 @@ public void removeDeletionFlags(Set removeTags) { } public boolean isFlaggedForDeletion() { - return !getSystemNotices().isEmpty(); + return !systemNotices.isEmpty(); } /** @@ -215,7 +249,7 @@ public Itinerary withTimeShiftToStartAt(ZonedDateTime afterTime) { .stream() .map(leg -> leg.withTimeShift(duration)) .collect(Collectors.toList()); - var newItin = new Itinerary(timeShiftedLegs); + var newItin = new Itinerary(timeShiftedLegs, searchWindowAware); newItin.setGeneralizedCost(getGeneralizedCost()); return newItin; } diff --git a/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java b/application/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java similarity index 94% rename from src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java rename to application/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java index 18939c95f8c..6df5d828633 100644 --- a/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java +++ b/application/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java @@ -1,7 +1,7 @@ package org.opentripplanner.model.plan; import java.time.Instant; -import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; +import org.opentripplanner.utils.tostring.ValueObjectToStringBuilder; /** * This interface is used to sort itineraries and other instances that we might want to sort among diff --git a/src/main/java/org/opentripplanner/model/plan/Leg.java b/application/src/main/java/org/opentripplanner/model/plan/Leg.java similarity index 95% rename from src/main/java/org/opentripplanner/model/plan/Leg.java rename to application/src/main/java/org/opentripplanner/model/plan/Leg.java index 2a0b6726560..b3c9b526f03 100644 --- a/src/main/java/org/opentripplanner/model/plan/Leg.java +++ b/application/src/main/java/org/opentripplanner/model/plan/Leg.java @@ -10,7 +10,6 @@ import javax.annotation.Nullable; import org.locationtech.jts.geom.LineString; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.lang.Sandbox; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.fare.FareProductUse; import org.opentripplanner.model.plan.legreference.LegReference; @@ -22,9 +21,11 @@ import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.organization.Operator; import org.opentripplanner.transit.model.site.FareZone; +import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.model.timetable.booking.BookingInfo; +import org.opentripplanner.utils.lang.Sandbox; /** * One leg of a trip -- that is, a temporally continuous piece of the journey that takes place on a @@ -160,6 +161,7 @@ default boolean overlapInTime(Leg other) { /** * For transit legs, the route agency. For non-transit legs {@code null}. */ + @Nullable default Agency getAgency() { return null; } @@ -170,6 +172,7 @@ default Agency getAgency() { * * @see Trip#getOperator() */ + @Nullable default Operator getOperator() { return null; } @@ -177,6 +180,7 @@ default Operator getOperator() { /** * For transit legs, the route. For non-transit legs, null. */ + @Nullable default Route getRoute() { return null; } @@ -197,6 +201,7 @@ default TripOnServiceDate getTripOnServiceDate() { return null; } + @Nullable default Accessibility getTripWheelchairAccessibility() { return null; } @@ -244,6 +249,11 @@ default boolean getRealTime() { return false; } + @Nullable + default RealTimeState getRealTimeState() { + return null; + } + /** * Whether this Leg describes a flexible trip. The reason we need this is that FlexTrip does not * inherit from Trip, so that the information that the Trip is flexible would be lost when @@ -256,6 +266,7 @@ default boolean isFlexibleTrip() { /** * Is this a frequency-based trip with non-strict departure times? */ + @Nullable default Boolean getNonExactFrequency() { return null; } @@ -265,6 +276,7 @@ default Boolean getNonExactFrequency() { * non-strict frequency trips, but could become important for real-time trips, strict frequency * trips, and scheduled trips with empirical headways. */ + @Nullable default Integer getHeadway() { return null; } @@ -284,10 +296,11 @@ default int getAgencyTimeZoneOffset() { /** * For transit legs, the type of the route. Non transit -1 When 0-7: 0 Tram, 1 Subway, 2 Train, 3 - * Bus, 4 Ferry, 5 Cable Car, 6 Gondola, 7 Funicular When equal or highter than 100, it is coded + * Bus, 4 Ferry, 5 Cable Tram, 6 Gondola, 7 Funicular When equal or highter than 100, it is coded * using the Hierarchical Vehicle Type (HVT) codes from the European TPEG standard Also see * http://groups.google.com/group/gtfs-changes/msg/ed917a69cf8c5bef */ + @Nullable default Integer getRouteType() { return null; } @@ -295,6 +308,7 @@ default Integer getRouteType() { /** * For transit legs, the headsign of the bus or train being used. For non-transit legs, null. */ + @Nullable default I18NString getHeadsign() { return null; } @@ -307,6 +321,7 @@ default I18NString getHeadsign() { * for a given trip may happen at service date March 25th and service time 25:00, which in local * time would be Mach 26th 01:00. */ + @Nullable default LocalDate getServiceDate() { return null; } @@ -314,6 +329,7 @@ default LocalDate getServiceDate() { /** * For transit leg, the route's branding URL (if one exists). For non-transit legs, null. */ + @Nullable default String getRouteBrandingUrl() { return null; } @@ -332,6 +348,7 @@ default String getRouteBrandingUrl() { * For transit legs, intermediate stops between the Place where the leg originates and the Place * where the leg ends. For non-transit legs, {@code null}. */ + @Nullable default List getIntermediateStops() { return null; } @@ -339,6 +356,7 @@ default List getIntermediateStops() { /** * The leg's geometry. */ + @Nullable LineString getLegGeometry(); /** @@ -347,6 +365,7 @@ default List getIntermediateStops() { * The elevation profile as a comma-separated list of x,y values. x is the distance from the start * of the leg, y is the elevation at this distance. */ + @Nullable default ElevationProfile getElevationProfile() { return null; } @@ -359,49 +378,59 @@ default List getWalkSteps() { } default Set getStreetNotes() { - return null; + return Set.of(); } default Set getTransitAlerts() { return Set.of(); } + @Nullable default PickDrop getBoardRule() { return null; } + @Nullable default PickDrop getAlightRule() { return null; } + @Nullable default BookingInfo getDropOffBookingInfo() { return null; } + @Nullable default BookingInfo getPickupBookingInfo() { return null; } + @Nullable default ConstrainedTransfer getTransferFromPrevLeg() { return null; } + @Nullable default ConstrainedTransfer getTransferToNextLeg() { return null; } + @Nullable default Integer getBoardStopPosInPattern() { return null; } + @Nullable default Integer getAlightStopPosInPattern() { return null; } + @Nullable default Integer getBoardingGtfsStopSequence() { return null; } + @Nullable default Integer getAlightGtfsStopSequence() { return null; } @@ -409,6 +438,7 @@ default Integer getAlightGtfsStopSequence() { /** * Is this leg walking with a bike? */ + @Nullable default Boolean getWalkingBike() { return null; } @@ -430,10 +460,12 @@ default Float accessibilityScore() { return null; } + @Nullable default Boolean getRentedVehicle() { return null; } + @Nullable default String getVehicleRentalNetwork() { return null; } @@ -448,6 +480,7 @@ default String getVehicleRentalNetwork() { */ int getGeneralizedCost(); + @Nullable default LegReference getLegReference() { return null; } diff --git a/src/main/java/org/opentripplanner/model/plan/LegTime.java b/application/src/main/java/org/opentripplanner/model/plan/LegTime.java similarity index 88% rename from src/main/java/org/opentripplanner/model/plan/LegTime.java rename to application/src/main/java/org/opentripplanner/model/plan/LegTime.java index 354ce4f4b0b..71ced95942a 100644 --- a/src/main/java/org/opentripplanner/model/plan/LegTime.java +++ b/application/src/main/java/org/opentripplanner/model/plan/LegTime.java @@ -3,24 +3,21 @@ import java.time.Duration; import java.time.ZonedDateTime; import java.util.Objects; -import javax.annotation.Nonnull; import javax.annotation.Nullable; /** * A scheduled time of a transit vehicle at a certain location with a optional realtime information. */ -public record LegTime(@Nonnull ZonedDateTime scheduledTime, @Nullable RealTimeEstimate estimated) { +public record LegTime(ZonedDateTime scheduledTime, @Nullable RealTimeEstimate estimated) { public LegTime { Objects.requireNonNull(scheduledTime); } - @Nonnull public static LegTime of(ZonedDateTime realtime, int delaySecs) { var delay = Duration.ofSeconds(delaySecs); return new LegTime(realtime.minus(delay), new RealTimeEstimate(realtime, delay)); } - @Nonnull public static LegTime ofStatic(ZonedDateTime staticTime) { return new LegTime(staticTime, null); } diff --git a/src/main/java/org/opentripplanner/model/plan/Place.java b/application/src/main/java/org/opentripplanner/model/plan/Place.java similarity index 98% rename from src/main/java/org/opentripplanner/model/plan/Place.java rename to application/src/main/java/org/opentripplanner/model/plan/Place.java index fe3a9dee420..4e2e2a425f1 100644 --- a/src/main/java/org/opentripplanner/model/plan/Place.java +++ b/application/src/main/java/org/opentripplanner/model/plan/Place.java @@ -3,7 +3,6 @@ import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.LocalizedString; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex; import org.opentripplanner.street.model.vertex.StreetVertex; @@ -14,6 +13,7 @@ import org.opentripplanner.street.search.state.State; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A Place is where a journey starts or ends, or a transit stop along the way. diff --git a/src/main/java/org/opentripplanner/model/plan/RelativeDirection.java b/application/src/main/java/org/opentripplanner/model/plan/RelativeDirection.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/RelativeDirection.java rename to application/src/main/java/org/opentripplanner/model/plan/RelativeDirection.java diff --git a/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLeg.java b/application/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLeg.java similarity index 94% rename from src/main/java/org/opentripplanner/model/plan/ScheduledTransitLeg.java rename to application/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLeg.java index d94ec1895c2..f3fba29515e 100644 --- a/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLeg.java +++ b/application/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLeg.java @@ -10,16 +10,12 @@ import java.util.List; import java.util.Objects; import java.util.Set; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.LineString; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.geometry.SphericalDistanceLibrary; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.lang.DoubleUtils; -import org.opentripplanner.framework.time.ServiceDateUtils; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.fare.FareProductUse; import org.opentripplanner.model.plan.legreference.LegReference; @@ -34,10 +30,14 @@ import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.organization.Operator; import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.model.timetable.booking.BookingInfo; +import org.opentripplanner.utils.lang.DoubleUtils; +import org.opentripplanner.utils.time.ServiceDateUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * One leg of a trip -- that is, a temporally continuous piece of the journey that takes place on a @@ -96,10 +96,7 @@ protected ScheduledTransitLeg(ScheduledTransitLegBuilder builder) { setDistanceMeters(getDistanceFromCoordinates(transitLegCoordinates)); this.directDistanceMeters = getDistanceFromCoordinates( - List.of( - transitLegCoordinates.get(0), - transitLegCoordinates.get(transitLegCoordinates.size() - 1) - ) + List.of(transitLegCoordinates.getFirst(), transitLegCoordinates.getLast()) ); } @@ -139,22 +136,23 @@ public Boolean isInterlinedWithPreviousLeg() { @Override public Agency getAgency() { - return getTrip().getRoute().getAgency(); + return trip().getRoute().getAgency(); } @Override + @Nullable public Operator getOperator() { - return getTrip().getOperator(); + return trip().getOperator(); } @Override public Route getRoute() { - return getTrip().getRoute(); + return trip().getRoute(); } @Override public Trip getTrip() { - return tripTimes.getTrip(); + return trip(); } @Override @@ -181,9 +179,8 @@ public LegTime end() { } @Override - @Nonnull public TransitMode getMode() { - return getTrip().getMode(); + return trip().getMode(); } @Override @@ -227,6 +224,11 @@ public boolean getRealTime() { ); } + @Override + public RealTimeState getRealTimeState() { + return tripTimes.getRealTimeState(); + } + @Override public double getDistanceMeters() { return distanceMeters; @@ -243,7 +245,7 @@ public double getDirectDistanceMeters() { @Override public Integer getRouteType() { - return getTrip().getRoute().getGtfsType(); + return trip().getRoute().getGtfsType(); } @Override @@ -296,6 +298,7 @@ public Set getTransitAlerts() { } @Override + @Nullable public PickDrop getBoardRule() { if (transferFromPrevLeg != null && transferFromPrevLeg.getTransferConstraint().isStaySeated()) { return null; @@ -304,6 +307,7 @@ public PickDrop getBoardRule() { } @Override + @Nullable public PickDrop getAlightRule() { if (transferToNextLeg != null && transferToNextLeg.getTransferConstraint().isStaySeated()) { return null; @@ -430,6 +434,13 @@ public String toString() { .toString(); } + /** + * Non-null getter for trip + */ + private Trip trip() { + return tripTimes.getTrip(); + } + private List extractTransitLegCoordinates( TripPattern tripPattern, int boardStopIndexInPattern, diff --git a/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLegBuilder.java b/application/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLegBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/ScheduledTransitLegBuilder.java rename to application/src/main/java/org/opentripplanner/model/plan/ScheduledTransitLegBuilder.java diff --git a/src/main/java/org/opentripplanner/model/plan/SortOrder.java b/application/src/main/java/org/opentripplanner/model/plan/SortOrder.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/SortOrder.java rename to application/src/main/java/org/opentripplanner/model/plan/SortOrder.java diff --git a/src/main/java/org/opentripplanner/model/plan/StopArrival.java b/application/src/main/java/org/opentripplanner/model/plan/StopArrival.java similarity index 95% rename from src/main/java/org/opentripplanner/model/plan/StopArrival.java rename to application/src/main/java/org/opentripplanner/model/plan/StopArrival.java index 489b122da09..d43df69ff21 100644 --- a/src/main/java/org/opentripplanner/model/plan/StopArrival.java +++ b/application/src/main/java/org/opentripplanner/model/plan/StopArrival.java @@ -1,6 +1,6 @@ package org.opentripplanner.model.plan; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This class is used to represent a stop arrival event mostly for intermediate visits to a stops diff --git a/src/main/java/org/opentripplanner/model/plan/StopArrivalMapper.java b/application/src/main/java/org/opentripplanner/model/plan/StopArrivalMapper.java similarity index 96% rename from src/main/java/org/opentripplanner/model/plan/StopArrivalMapper.java rename to application/src/main/java/org/opentripplanner/model/plan/StopArrivalMapper.java index 25bab2a7c3f..c6a719addd5 100644 --- a/src/main/java/org/opentripplanner/model/plan/StopArrivalMapper.java +++ b/application/src/main/java/org/opentripplanner/model/plan/StopArrivalMapper.java @@ -3,9 +3,9 @@ import java.time.LocalDate; import java.time.ZoneId; import java.util.Objects; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.utils.time.ServiceDateUtils; /** * Maps leg-related information to an instance of {@link StopArrival}. diff --git a/src/main/java/org/opentripplanner/model/plan/StreetLeg.java b/application/src/main/java/org/opentripplanner/model/plan/StreetLeg.java similarity index 97% rename from src/main/java/org/opentripplanner/model/plan/StreetLeg.java rename to application/src/main/java/org/opentripplanner/model/plan/StreetLeg.java index 6384159a4ec..a61c68dccc5 100644 --- a/src/main/java/org/opentripplanner/model/plan/StreetLeg.java +++ b/application/src/main/java/org/opentripplanner/model/plan/StreetLeg.java @@ -7,11 +7,11 @@ import java.util.Set; import javax.annotation.Nullable; import org.locationtech.jts.geom.LineString; -import org.opentripplanner.framework.lang.DoubleUtils; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.fare.FareProductUse; import org.opentripplanner.street.model.note.StreetNote; import org.opentripplanner.street.search.TraverseMode; +import org.opentripplanner.utils.lang.DoubleUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * One leg of a trip -- that is, a temporally continuous piece of the journey that takes place using diff --git a/src/main/java/org/opentripplanner/model/plan/StreetLegBuilder.java b/application/src/main/java/org/opentripplanner/model/plan/StreetLegBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/StreetLegBuilder.java rename to application/src/main/java/org/opentripplanner/model/plan/StreetLegBuilder.java diff --git a/src/main/java/org/opentripplanner/model/plan/TransitLeg.java b/application/src/main/java/org/opentripplanner/model/plan/TransitLeg.java similarity index 91% rename from src/main/java/org/opentripplanner/model/plan/TransitLeg.java rename to application/src/main/java/org/opentripplanner/model/plan/TransitLeg.java index 736739ca970..f7ac3e42544 100644 --- a/src/main/java/org/opentripplanner/model/plan/TransitLeg.java +++ b/application/src/main/java/org/opentripplanner/model/plan/TransitLeg.java @@ -1,13 +1,11 @@ package org.opentripplanner.model.plan; -import javax.annotation.Nonnull; import org.opentripplanner.transit.model.basic.TransitMode; public interface TransitLeg extends Leg { /** * The mode (e.g., BUS) used when traversing this leg. */ - @Nonnull TransitMode getMode(); @Override diff --git a/src/main/java/org/opentripplanner/model/plan/TripPlan.java b/application/src/main/java/org/opentripplanner/model/plan/TripPlan.java similarity index 93% rename from src/main/java/org/opentripplanner/model/plan/TripPlan.java rename to application/src/main/java/org/opentripplanner/model/plan/TripPlan.java index 2640d655bde..ccd2af8b333 100644 --- a/src/main/java/org/opentripplanner/model/plan/TripPlan.java +++ b/application/src/main/java/org/opentripplanner/model/plan/TripPlan.java @@ -3,7 +3,7 @@ import java.time.Instant; import java.util.Collection; import java.util.List; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A TripPlan is a set of ways to get from point A to point B at time T. diff --git a/src/main/java/org/opentripplanner/model/plan/UnknownTransitPathLeg.java b/application/src/main/java/org/opentripplanner/model/plan/UnknownTransitPathLeg.java similarity index 94% rename from src/main/java/org/opentripplanner/model/plan/UnknownTransitPathLeg.java rename to application/src/main/java/org/opentripplanner/model/plan/UnknownTransitPathLeg.java index df43bbcb411..45a9c6561d3 100644 --- a/src/main/java/org/opentripplanner/model/plan/UnknownTransitPathLeg.java +++ b/application/src/main/java/org/opentripplanner/model/plan/UnknownTransitPathLeg.java @@ -4,11 +4,12 @@ import java.time.ZonedDateTime; import java.util.List; +import javax.annotation.Nullable; import org.locationtech.jts.geom.LineString; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.fare.FareProductUse; import org.opentripplanner.raptor.spi.RaptorCostCalculator; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A transit search may return an unknown transit path. A path consisting of a mix of @@ -84,6 +85,7 @@ public double getDistanceMeters() { } @Override + @Nullable public LineString getLegGeometry() { return null; } diff --git a/src/main/java/org/opentripplanner/model/plan/VehicleParkingWithEntrance.java b/application/src/main/java/org/opentripplanner/model/plan/VehicleParkingWithEntrance.java similarity index 91% rename from src/main/java/org/opentripplanner/model/plan/VehicleParkingWithEntrance.java rename to application/src/main/java/org/opentripplanner/model/plan/VehicleParkingWithEntrance.java index 5d28bcd02f2..131ef4cad7c 100644 --- a/src/main/java/org/opentripplanner/model/plan/VehicleParkingWithEntrance.java +++ b/application/src/main/java/org/opentripplanner/model/plan/VehicleParkingWithEntrance.java @@ -1,7 +1,7 @@ package org.opentripplanner.model.plan; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingEntrance; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingEntrance; public class VehicleParkingWithEntrance { diff --git a/src/main/java/org/opentripplanner/model/plan/VertexType.java b/application/src/main/java/org/opentripplanner/model/plan/VertexType.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/VertexType.java rename to application/src/main/java/org/opentripplanner/model/plan/VertexType.java diff --git a/src/main/java/org/opentripplanner/model/plan/WalkStep.java b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java similarity index 97% rename from src/main/java/org/opentripplanner/model/plan/WalkStep.java rename to application/src/main/java/org/opentripplanner/model/plan/WalkStep.java index 13249d5da52..45f2b5da701 100644 --- a/src/main/java/org/opentripplanner/model/plan/WalkStep.java +++ b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java @@ -6,10 +6,10 @@ import java.util.Set; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.lang.DoubleUtils; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.note.StreetNote; +import org.opentripplanner.utils.lang.DoubleUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Represents one instruction in walking directions. Three examples from New York City: diff --git a/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java b/application/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java similarity index 97% rename from src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java rename to application/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java index 25c6ee25b6b..8d4df6634fd 100644 --- a/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java +++ b/application/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java @@ -7,10 +7,10 @@ import javax.annotation.Nullable; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.lang.DoubleUtils; -import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.note.StreetNote; +import org.opentripplanner.utils.lang.DoubleUtils; +import org.opentripplanner.utils.lang.IntUtils; public class WalkStepBuilder { diff --git a/src/main/java/org/opentripplanner/model/plan/grouppriority/TransitGroupPriorityItineraryDecorator.java b/application/src/main/java/org/opentripplanner/model/plan/grouppriority/TransitGroupPriorityItineraryDecorator.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/grouppriority/TransitGroupPriorityItineraryDecorator.java rename to application/src/main/java/org/opentripplanner/model/plan/grouppriority/TransitGroupPriorityItineraryDecorator.java diff --git a/src/main/java/org/opentripplanner/model/plan/legreference/LegReference.java b/application/src/main/java/org/opentripplanner/model/plan/legreference/LegReference.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/legreference/LegReference.java rename to application/src/main/java/org/opentripplanner/model/plan/legreference/LegReference.java diff --git a/src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializer.java b/application/src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializer.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializer.java rename to application/src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializer.java diff --git a/src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceType.java b/application/src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceType.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceType.java rename to application/src/main/java/org/opentripplanner/model/plan/legreference/LegReferenceType.java diff --git a/src/main/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReference.java b/application/src/main/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReference.java similarity index 95% rename from src/main/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReference.java rename to application/src/main/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReference.java index b008dea5737..5defff73cec 100644 --- a/src/main/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReference.java +++ b/application/src/main/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReference.java @@ -3,7 +3,6 @@ import java.time.LocalDate; import java.time.ZoneId; import javax.annotation.Nullable; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.Timetable; import org.opentripplanner.model.plan.ScheduledTransitLeg; import org.opentripplanner.model.plan.ScheduledTransitLegBuilder; @@ -15,6 +14,7 @@ import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.time.ServiceDateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,7 +69,7 @@ public ScheduledTransitLeg getLeg(TransitService transitService) { Trip trip; TripOnServiceDate tripOnServiceDate = null; if (tripOnServiceDateId != null) { - tripOnServiceDate = transitService.getTripOnServiceDateById(tripOnServiceDateId); + tripOnServiceDate = transitService.getTripOnServiceDate(tripOnServiceDateId); if (tripOnServiceDate == null) { LOG.info( "Invalid transit leg reference: trip on service date '{}' not found", @@ -87,14 +87,14 @@ public ScheduledTransitLeg getLeg(TransitService transitService) { } trip = tripOnServiceDate.getTrip(); } else { - trip = transitService.getTripForId(tripId); + trip = transitService.getTrip(tripId); if (trip == null) { LOG.info("Invalid transit leg reference: trip '{}' not found", tripId); return null; } } - TripPattern tripPattern = transitService.getPatternForTrip(trip, serviceDate); + TripPattern tripPattern = transitService.findPattern(trip, serviceDate); if (tripPattern == null) { LOG.info( "Invalid transit leg reference: trip pattern not found for trip '{}' and service date {} ", @@ -130,7 +130,7 @@ public ScheduledTransitLeg getLeg(TransitService transitService) { return null; } - Timetable timetable = transitService.getTimetableForTripPattern(tripPattern, serviceDate); + Timetable timetable = transitService.findTimetable(tripPattern, serviceDate); TripTimes tripTimes = timetable.getTripTimes(trip); if (tripTimes == null) { @@ -177,7 +177,7 @@ public ScheduledTransitLeg getLeg(TransitService transitService) { new AlertToLegMapper( transitService.getTransitAlertService(), - transitService::getMultiModalStationForStation + transitService::findMultiModalStation ) .addTransitAlertsToLeg(leg, false); diff --git a/src/main/java/org/opentripplanner/model/plan/paging/PagingSearchWindowAdjuster.java b/application/src/main/java/org/opentripplanner/model/plan/paging/PagingSearchWindowAdjuster.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/paging/PagingSearchWindowAdjuster.java rename to application/src/main/java/org/opentripplanner/model/plan/paging/PagingSearchWindowAdjuster.java diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/DeduplicationPageCut.java b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/DeduplicationPageCut.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/paging/cursor/DeduplicationPageCut.java rename to application/src/main/java/org/opentripplanner/model/plan/paging/cursor/DeduplicationPageCut.java diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursor.java b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursor.java similarity index 94% rename from src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursor.java rename to application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursor.java index a52dc0429c1..ead71fbeb38 100644 --- a/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursor.java +++ b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursor.java @@ -3,10 +3,10 @@ import java.time.Duration; import java.time.Instant; import javax.annotation.Nullable; -import org.opentripplanner.framework.collection.ListSection; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; +import org.opentripplanner.utils.collection.ListSection; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This class holds all the information needed to page to the next/previous page. It is serialized diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactory.java b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactory.java similarity index 98% rename from src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactory.java rename to application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactory.java index 92f59319cc1..4e2fad2a398 100644 --- a/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactory.java +++ b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactory.java @@ -6,9 +6,9 @@ import java.time.Duration; import java.time.Instant; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; +import org.opentripplanner.utils.tostring.ToStringBuilder; public class PageCursorFactory { diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorInput.java b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorInput.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorInput.java rename to application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorInput.java diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializer.java b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializer.java similarity index 98% rename from src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializer.java rename to application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializer.java index 396c7499d2f..ac2a8e1df0b 100644 --- a/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializer.java +++ b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializer.java @@ -1,10 +1,10 @@ package org.opentripplanner.model.plan.paging.cursor; import javax.annotation.Nullable; -import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.framework.token.TokenSchema; import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; +import org.opentripplanner.utils.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageType.java b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageType.java similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/paging/cursor/PageType.java rename to application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageType.java diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/pagecursor.excalidraw b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/pagecursor.excalidraw similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/paging/cursor/images/pagecursor.excalidraw rename to application/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/pagecursor.excalidraw diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-arrival-crop-sw-prev-page.svg b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-arrival-crop-sw-prev-page.svg similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-arrival-crop-sw-prev-page.svg rename to application/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-arrival-crop-sw-prev-page.svg diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-arrival-crop-sw.svg b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-arrival-crop-sw.svg similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-arrival-crop-sw.svg rename to application/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-arrival-crop-sw.svg diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-arrival.svg b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-arrival.svg similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-arrival.svg rename to application/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-arrival.svg diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-departure-crop-sw-next-page.svg b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-departure-crop-sw-next-page.svg similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-departure-crop-sw-next-page.svg rename to application/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-departure-crop-sw-next-page.svg diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-departure-crop-sw.svg b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-departure-crop-sw.svg similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-departure-crop-sw.svg rename to application/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-departure-crop-sw.svg diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-departure.svg b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-departure.svg similarity index 100% rename from src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-departure.svg rename to application/src/main/java/org/opentripplanner/model/plan/paging/cursor/images/sort-by-departure.svg diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/readme.md b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/readme.md similarity index 95% rename from src/main/java/org/opentripplanner/model/plan/paging/cursor/readme.md rename to application/src/main/java/org/opentripplanner/model/plan/paging/cursor/readme.md index e98071cfa62..0eab721bcc3 100644 --- a/src/main/java/org/opentripplanner/model/plan/paging/cursor/readme.md +++ b/application/src/main/java/org/opentripplanner/model/plan/paging/cursor/readme.md @@ -13,7 +13,7 @@ moving on to the next. ## Terminology -- **search-window (sw)** The search window is the minutes Raptor iterate over and the time-window +- **search-window (sw)** The search window is the minutes Raptor iterates over and the time-window the itinerary must start within to be included in the result. The search-window may change from a request to the next page. **sw'** is the search window for the new next/previous page. The search window may change between requests, so we need to account for it when computing the next/previous @@ -28,7 +28,7 @@ moving on to the next. - **<< previous page** The trip search constructed to retrieve itineraries AFTER the original search. - **crop-search-window** If the `maxNumOfItineraries` limit is reached in the - `ItineraryFilterChain`, then one or more itineraries are removed. The filter remove itineraries + `ItineraryFilterChain`, then one or more itineraries are removed. The filter removes itineraries from the beginning or end of the list depending on the page cursor type (next/previous) and the sort order(arrival/departure time). @@ -55,8 +55,8 @@ _previous-page_ must reverse the itinerary-filtering: `crop itineraries at START - In this case the `<< Previous page` is the same as in [sort-by-arrival](#sort-by-arrival) and not shown. - For the `Next page >>` we must adjust the `edt'`. -- In rare cases we get duplicate itineraries. This happens if the `removed itinerary` depart before, - but arrive after the `duplicate`. +- In rare cases we get duplicate itineraries. This happens if the `removed itinerary` departs before, + but arrives after the `duplicate`. ### sort-by-arrival, crop-search-window & original-prev-page @@ -99,7 +99,7 @@ This is the basic `sort-by-departure` (arrive-by search) without removing itiner In this case the itineraries are dropped from the search results in the `Original Search` and the `<< Previous page` must be adjusted. We use the first removed itinerary to set both the `edt'` and the `lat'`. An `optimal itinarary` in the original search is lost (not found) in the previous page -if it departs AFTER the `remoed itinerary` and arrive before - hopefully this is a rare case. +if it departs AFTER the `removed itinerary` and arrives before - hopefully this is a rare case. The `Next page >>` is the same as the basic case [sort-by-departure](#sort-by-departure). diff --git a/src/main/java/org/opentripplanner/model/projectinfo/GraphFileHeader.java b/application/src/main/java/org/opentripplanner/model/projectinfo/GraphFileHeader.java similarity index 100% rename from src/main/java/org/opentripplanner/model/projectinfo/GraphFileHeader.java rename to application/src/main/java/org/opentripplanner/model/projectinfo/GraphFileHeader.java diff --git a/src/main/java/org/opentripplanner/model/projectinfo/MavenProjectVersion.java b/application/src/main/java/org/opentripplanner/model/projectinfo/MavenProjectVersion.java similarity index 100% rename from src/main/java/org/opentripplanner/model/projectinfo/MavenProjectVersion.java rename to application/src/main/java/org/opentripplanner/model/projectinfo/MavenProjectVersion.java diff --git a/src/main/java/org/opentripplanner/model/projectinfo/OtpProjectInfo.java b/application/src/main/java/org/opentripplanner/model/projectinfo/OtpProjectInfo.java similarity index 88% rename from src/main/java/org/opentripplanner/model/projectinfo/OtpProjectInfo.java rename to application/src/main/java/org/opentripplanner/model/projectinfo/OtpProjectInfo.java index 37651d4522f..c49fbc1ae4f 100644 --- a/src/main/java/org/opentripplanner/model/projectinfo/OtpProjectInfo.java +++ b/application/src/main/java/org/opentripplanner/model/projectinfo/OtpProjectInfo.java @@ -80,7 +80,7 @@ public String toString() { * dev-2.x} */ public String getVersionString() { - String format = "version: %s, ser.ver.id: %s, commit: %s, branch: %s"; + String format = "Version: %s, ser.ver.id: %s, commit: %s, branch: %s"; return String.format( format, version.version, @@ -91,8 +91,8 @@ public String getVersionString() { } /** - * This method compare the maven project version, an return {@code true} if both are the same. Two - * different SNAPSHOT versions are considered the same - work in progress. + * This method compares the maven project version, and return {@code true} if both are the same. + * Two different SNAPSHOT versions are considered the same version - they are work in progress. */ public boolean sameVersion(OtpProjectInfo other) { return this.version.sameVersion(other.version); @@ -100,8 +100,8 @@ public boolean sameVersion(OtpProjectInfo other) { /** * The OTP Serialization version id is used to determine if OTP and a serialized blob(Graph.obj) - * of the otp internal model are compatible. This filed is writen into the Graph.obj file header - * and checked when loading the graph later. + * of the otp internal model are compatible. This field is written into the Graph.obj + * file header and checked when loading the graph later. */ public String getOtpSerializationVersionId() { return graphFileHeaderInfo.otpSerializationVersionId(); diff --git a/src/main/java/org/opentripplanner/model/projectinfo/OtpProjectInfoParser.java b/application/src/main/java/org/opentripplanner/model/projectinfo/OtpProjectInfoParser.java similarity index 100% rename from src/main/java/org/opentripplanner/model/projectinfo/OtpProjectInfoParser.java rename to application/src/main/java/org/opentripplanner/model/projectinfo/OtpProjectInfoParser.java diff --git a/src/main/java/org/opentripplanner/model/projectinfo/VersionControlInfo.java b/application/src/main/java/org/opentripplanner/model/projectinfo/VersionControlInfo.java similarity index 94% rename from src/main/java/org/opentripplanner/model/projectinfo/VersionControlInfo.java rename to application/src/main/java/org/opentripplanner/model/projectinfo/VersionControlInfo.java index d2bbca43e66..6cd6a47f5ef 100644 --- a/src/main/java/org/opentripplanner/model/projectinfo/VersionControlInfo.java +++ b/application/src/main/java/org/opentripplanner/model/projectinfo/VersionControlInfo.java @@ -3,7 +3,7 @@ import static org.opentripplanner.model.projectinfo.OtpProjectInfo.UNKNOWN; import java.io.Serializable; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; public class VersionControlInfo implements Serializable { diff --git a/src/main/java/org/opentripplanner/model/transfer/ConstrainedTransfer.java b/application/src/main/java/org/opentripplanner/model/transfer/ConstrainedTransfer.java similarity index 98% rename from src/main/java/org/opentripplanner/model/transfer/ConstrainedTransfer.java rename to application/src/main/java/org/opentripplanner/model/transfer/ConstrainedTransfer.java index d289727fd57..a5e6c624d9c 100644 --- a/src/main/java/org/opentripplanner/model/transfer/ConstrainedTransfer.java +++ b/application/src/main/java/org/opentripplanner/model/transfer/ConstrainedTransfer.java @@ -3,9 +3,9 @@ import java.io.Serializable; import java.util.Objects; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorConstrainedTransfer; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A constrained transfer is a transfer which is restricted in one ore more ways by the transit data diff --git a/src/main/java/org/opentripplanner/model/transfer/DefaultTransferService.java b/application/src/main/java/org/opentripplanner/model/transfer/DefaultTransferService.java similarity index 100% rename from src/main/java/org/opentripplanner/model/transfer/DefaultTransferService.java rename to application/src/main/java/org/opentripplanner/model/transfer/DefaultTransferService.java diff --git a/src/main/java/org/opentripplanner/model/transfer/RouteStationTransferPoint.java b/application/src/main/java/org/opentripplanner/model/transfer/RouteStationTransferPoint.java similarity index 100% rename from src/main/java/org/opentripplanner/model/transfer/RouteStationTransferPoint.java rename to application/src/main/java/org/opentripplanner/model/transfer/RouteStationTransferPoint.java diff --git a/src/main/java/org/opentripplanner/model/transfer/RouteStopTransferPoint.java b/application/src/main/java/org/opentripplanner/model/transfer/RouteStopTransferPoint.java similarity index 93% rename from src/main/java/org/opentripplanner/model/transfer/RouteStopTransferPoint.java rename to application/src/main/java/org/opentripplanner/model/transfer/RouteStopTransferPoint.java index 7b81f44c6a6..627d82f7ccd 100644 --- a/src/main/java/org/opentripplanner/model/transfer/RouteStopTransferPoint.java +++ b/application/src/main/java/org/opentripplanner/model/transfer/RouteStopTransferPoint.java @@ -1,9 +1,9 @@ package org.opentripplanner.model.transfer; import java.io.Serializable; -import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.utils.tostring.ValueObjectToStringBuilder; public final class RouteStopTransferPoint implements TransferPoint, Serializable { diff --git a/src/main/java/org/opentripplanner/model/transfer/StationTransferPoint.java b/application/src/main/java/org/opentripplanner/model/transfer/StationTransferPoint.java similarity index 91% rename from src/main/java/org/opentripplanner/model/transfer/StationTransferPoint.java rename to application/src/main/java/org/opentripplanner/model/transfer/StationTransferPoint.java index 53219e7fbcc..4af961ff0f4 100644 --- a/src/main/java/org/opentripplanner/model/transfer/StationTransferPoint.java +++ b/application/src/main/java/org/opentripplanner/model/transfer/StationTransferPoint.java @@ -1,8 +1,8 @@ package org.opentripplanner.model.transfer; import java.io.Serializable; -import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; import org.opentripplanner.transit.model.site.Station; +import org.opentripplanner.utils.tostring.ValueObjectToStringBuilder; public final class StationTransferPoint implements TransferPoint, Serializable { diff --git a/src/main/java/org/opentripplanner/model/transfer/StopTransferPoint.java b/application/src/main/java/org/opentripplanner/model/transfer/StopTransferPoint.java similarity index 100% rename from src/main/java/org/opentripplanner/model/transfer/StopTransferPoint.java rename to application/src/main/java/org/opentripplanner/model/transfer/StopTransferPoint.java diff --git a/src/main/java/org/opentripplanner/model/transfer/TransferConstraint.java b/application/src/main/java/org/opentripplanner/model/transfer/TransferConstraint.java similarity index 99% rename from src/main/java/org/opentripplanner/model/transfer/TransferConstraint.java rename to application/src/main/java/org/opentripplanner/model/transfer/TransferConstraint.java index bc8dc4cd28f..e6509c7d8ca 100644 --- a/src/main/java/org/opentripplanner/model/transfer/TransferConstraint.java +++ b/application/src/main/java/org/opentripplanner/model/transfer/TransferConstraint.java @@ -10,9 +10,9 @@ import java.util.function.IntSupplier; import javax.annotation.Nullable; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; import org.opentripplanner.raptor.api.model.SearchDirection; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This class holds transfer constraint information. diff --git a/src/main/java/org/opentripplanner/model/transfer/TransferPoint.java b/application/src/main/java/org/opentripplanner/model/transfer/TransferPoint.java similarity index 100% rename from src/main/java/org/opentripplanner/model/transfer/TransferPoint.java rename to application/src/main/java/org/opentripplanner/model/transfer/TransferPoint.java diff --git a/src/main/java/org/opentripplanner/model/transfer/TransferPointMap.java b/application/src/main/java/org/opentripplanner/model/transfer/TransferPointMap.java similarity index 100% rename from src/main/java/org/opentripplanner/model/transfer/TransferPointMap.java rename to application/src/main/java/org/opentripplanner/model/transfer/TransferPointMap.java diff --git a/src/main/java/org/opentripplanner/model/transfer/TransferPriority.java b/application/src/main/java/org/opentripplanner/model/transfer/TransferPriority.java similarity index 100% rename from src/main/java/org/opentripplanner/model/transfer/TransferPriority.java rename to application/src/main/java/org/opentripplanner/model/transfer/TransferPriority.java diff --git a/src/main/java/org/opentripplanner/model/transfer/TransferService.java b/application/src/main/java/org/opentripplanner/model/transfer/TransferService.java similarity index 100% rename from src/main/java/org/opentripplanner/model/transfer/TransferService.java rename to application/src/main/java/org/opentripplanner/model/transfer/TransferService.java diff --git a/src/main/java/org/opentripplanner/model/transfer/TripTransferPoint.java b/application/src/main/java/org/opentripplanner/model/transfer/TripTransferPoint.java similarity index 93% rename from src/main/java/org/opentripplanner/model/transfer/TripTransferPoint.java rename to application/src/main/java/org/opentripplanner/model/transfer/TripTransferPoint.java index ca3359f27dd..5dd23269779 100644 --- a/src/main/java/org/opentripplanner/model/transfer/TripTransferPoint.java +++ b/application/src/main/java/org/opentripplanner/model/transfer/TripTransferPoint.java @@ -1,8 +1,8 @@ package org.opentripplanner.model.transfer; import java.io.Serializable; -import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.utils.tostring.ValueObjectToStringBuilder; public final class TripTransferPoint implements TransferPoint, Serializable { diff --git a/src/main/java/org/opentripplanner/netex/NetexBundle.java b/application/src/main/java/org/opentripplanner/netex/NetexBundle.java similarity index 90% rename from src/main/java/org/opentripplanner/netex/NetexBundle.java rename to application/src/main/java/org/opentripplanner/netex/NetexBundle.java index 3cd52cd246e..b061c9e9352 100644 --- a/src/main/java/org/opentripplanner/netex/NetexBundle.java +++ b/application/src/main/java/org/opentripplanner/netex/NetexBundle.java @@ -3,6 +3,7 @@ import jakarta.xml.bind.JAXBException; import java.io.Closeable; import java.io.IOException; +import java.util.Collection; import java.util.List; import java.util.Set; import org.opentripplanner.datastore.api.CompositeDataSource; @@ -19,6 +20,7 @@ import org.opentripplanner.netex.mapping.NetexMapper; import org.opentripplanner.netex.validation.Validator; import org.opentripplanner.transit.model.framework.Deduplicator; +import org.opentripplanner.transit.model.framework.FeedScopedId; import org.rutebanken.netex.model.PublicationDeliveryStructure; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,6 +46,7 @@ public class NetexBundle implements Closeable { private final String feedId; private final Set ferryIdsNotAllowedForBicycle; + private final Collection routeToCentroidStopPlaceIds; private final double maxStopToShapeSnapDistance; private final boolean noTransfersOnIsolatedStops; private final Set ignoredFeatures; @@ -61,6 +64,7 @@ public NetexBundle( NetexDataSourceHierarchy hierarchy, OtpTransitServiceBuilder transitBuilder, Set ferryIdsNotAllowedForBicycle, + Collection routeToCentroidStopPlaceIds, double maxStopToShapeSnapDistance, boolean noTransfersOnIsolatedStops, Set ignorableFeatures @@ -70,6 +74,7 @@ public NetexBundle( this.hierarchy = hierarchy; this.transitBuilder = transitBuilder; this.ferryIdsNotAllowedForBicycle = ferryIdsNotAllowedForBicycle; + this.routeToCentroidStopPlaceIds = Set.copyOf(routeToCentroidStopPlaceIds); this.maxStopToShapeSnapDistance = maxStopToShapeSnapDistance; this.noTransfersOnIsolatedStops = noTransfersOnIsolatedStops; this.ignoredFeatures = Set.copyOf(ignorableFeatures); @@ -93,6 +98,7 @@ public OtpTransitServiceBuilder loadBundle( deduplicator, issueStore, ferryIdsNotAllowedForBicycle, + routeToCentroidStopPlaceIds, maxStopToShapeSnapDistance, noTransfersOnIsolatedStops ); @@ -119,19 +125,19 @@ public void close() throws IOException { /** Load all files entries in the bundle */ private void loadFileEntries() { // Load global shared files - loadFilesThenMapToOtpTransitModel("shared file", hierarchy.sharedEntries()); + loadFilesThenMapToTimetableRepository("shared file", hierarchy.sharedEntries()); for (GroupEntries group : hierarchy.groups()) { LOG.info("reading group {}", group.name()); scopeInputData(() -> { // Load shared group files - loadFilesThenMapToOtpTransitModel("shared group file", group.sharedEntries()); + loadFilesThenMapToTimetableRepository("shared group file", group.sharedEntries()); for (DataSource entry : group.independentEntries()) { scopeInputData(() -> { // Load each independent file in group - loadFilesThenMapToOtpTransitModel("group file", List.of(entry)); + loadFilesThenMapToTimetableRepository("group file", List.of(entry)); }); } }); @@ -158,7 +164,7 @@ private void scopeInputData(Runnable task) { * when read, would lead to missing references, since the order entries are read is not enforced * in any way. */ - private void loadFilesThenMapToOtpTransitModel( + private void loadFilesThenMapToTimetableRepository( String fileDescription, Iterable entries ) { diff --git a/src/main/java/org/opentripplanner/netex/NetexModule.java b/application/src/main/java/org/opentripplanner/netex/NetexModule.java similarity index 76% rename from src/main/java/org/opentripplanner/netex/NetexModule.java rename to application/src/main/java/org/opentripplanner/netex/NetexModule.java index 2bf3403395c..e5422c5ac77 100644 --- a/src/main/java/org/opentripplanner/netex/NetexModule.java +++ b/application/src/main/java/org/opentripplanner/netex/NetexModule.java @@ -5,7 +5,7 @@ import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.model.GraphBuilderModule; -import org.opentripplanner.graph_builder.module.AddTransitModelEntitiesToGraph; +import org.opentripplanner.graph_builder.module.AddTransitEntitiesToGraph; import org.opentripplanner.graph_builder.module.ValidateAndInterpolateStopTimesForEachTrip; import org.opentripplanner.model.OtpTransitService; import org.opentripplanner.model.TripStopTimes; @@ -13,9 +13,10 @@ import org.opentripplanner.model.calendar.ServiceDateInterval; import org.opentripplanner.model.impl.OtpTransitServiceBuilder; import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingHelper; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingHelper; import org.opentripplanner.standalone.config.BuildConfig; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; /** * This module is used for importing the NeTEx CEN Technical Standard for exchanging Public @@ -28,7 +29,8 @@ public class NetexModule implements GraphBuilderModule { private final int subwayAccessTime; private final Graph graph; - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; + private final VehicleParkingRepository parkingRepository; private final DataImportIssueStore issueStore; /** @@ -41,14 +43,16 @@ public class NetexModule implements GraphBuilderModule { public NetexModule( Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, + VehicleParkingRepository parkingRepository, DataImportIssueStore issueStore, int subwayAccessTime, ServiceDateInterval transitPeriodLimit, List netexBundles ) { this.graph = graph; - this.transitModel = transitModel; + this.timetableRepository = timetableRepository; + this.parkingRepository = parkingRepository; this.issueStore = issueStore; this.subwayAccessTime = subwayAccessTime; this.transitPeriodLimit = transitPeriodLimit; @@ -70,7 +74,7 @@ public void buildGraph() { ); transitBuilder.limitServiceDays(transitPeriodLimit); for (var tripOnServiceDate : transitBuilder.getTripOnServiceDates().values()) { - transitModel.addTripOnServiceDate(tripOnServiceDate.getId(), tripOnServiceDate); + timetableRepository.addTripOnServiceDate(tripOnServiceDate); } calendarServiceData.add(transitBuilder.buildCalendarServiceData()); @@ -87,28 +91,32 @@ public void buildGraph() { // if this or previously processed netex bundle has transit that has not been filtered out hasActiveTransit = hasActiveTransit || otpService.hasActiveTransit(); - // TODO OTP2 - Move this into the AddTransitModelEntitiesToGraph + // TODO OTP2 - Move this into the AddTransitEntitiesToGraph // - and make sure they also work with GTFS feeds - GTFS do no // - have operators and notice assignments. - transitModel.getOperators().addAll(otpService.getAllOperators()); - transitModel.addNoticeAssignments(otpService.getNoticeAssignments()); + timetableRepository.addOperators(otpService.getAllOperators()); + timetableRepository.addNoticeAssignments(otpService.getNoticeAssignments()); - AddTransitModelEntitiesToGraph.addToGraph( + AddTransitEntitiesToGraph.addToGraph( otpService, subwayAccessTime, graph, - transitModel + timetableRepository ); - transitModel.validateTimeZones(); + timetableRepository.validateTimeZones(); var lots = transitBuilder.vehicleParkings(); - graph.getVehicleParkingService().updateVehicleParking(lots, List.of()); + parkingRepository.updateVehicleParking(lots, List.of()); var linker = new VehicleParkingHelper(graph); lots.forEach(linker::linkVehicleParkingToGraph); } - transitModel.updateCalendarServiceData(hasActiveTransit, calendarServiceData, issueStore); + timetableRepository.updateCalendarServiceData( + hasActiveTransit, + calendarServiceData, + issueStore + ); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/src/main/java/org/opentripplanner/netex/config/IgnorableFeature.java b/application/src/main/java/org/opentripplanner/netex/config/IgnorableFeature.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/config/IgnorableFeature.java rename to application/src/main/java/org/opentripplanner/netex/config/IgnorableFeature.java diff --git a/src/main/java/org/opentripplanner/netex/config/NetexFeedParameters.java b/application/src/main/java/org/opentripplanner/netex/config/NetexFeedParameters.java similarity index 96% rename from src/main/java/org/opentripplanner/netex/config/NetexFeedParameters.java rename to application/src/main/java/org/opentripplanner/netex/config/NetexFeedParameters.java index 0c6c75c4db3..604a28b1ab5 100644 --- a/src/main/java/org/opentripplanner/netex/config/NetexFeedParameters.java +++ b/application/src/main/java/org/opentripplanner/netex/config/NetexFeedParameters.java @@ -11,8 +11,8 @@ import java.util.Objects; import java.util.Set; import java.util.regex.Pattern; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.graph_builder.model.DataSourceConfig; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Parameters to configure the NETEX import. Se the generated build-config documentation or @@ -34,6 +34,7 @@ public class NetexFeedParameters implements DataSourceConfig { private static final Set IGNORED_FEATURES = Set.of(PARKING); private static final Set FERRY_IDS_NOT_ALLOWED_FOR_BICYCLE = Collections.emptySet(); + private static final Set ROUTE_TO_CENTROID_STATION_IDS = Collections.emptySet(); public static final NetexFeedParameters DEFAULT = new NetexFeedParameters(); @@ -196,6 +197,7 @@ public static class Builder { private String groupFilePattern; private String ignoreFilePattern; private final Set ferryIdsNotAllowedForBicycle = new HashSet<>(); + private final Set routeToCentroidStopPlaceIds = new HashSet<>(); private boolean noTransfersOnIsolatedStops; private final Set ignoredFeatures; @@ -251,6 +253,11 @@ public Builder addFerryIdsNotAllowedForBicycle(Collection ferryId) { return this; } + public Builder addRouteToCentroidStopPlaceIds(Collection stationIds) { + routeToCentroidStopPlaceIds.addAll(stationIds); + return this; + } + public Builder withNoTransfersOnIsolatedStops(boolean noTransfersOnIsolatedStops) { this.noTransfersOnIsolatedStops = noTransfersOnIsolatedStops; return this; diff --git a/src/main/java/org/opentripplanner/netex/configure/NetexConfigure.java b/application/src/main/java/org/opentripplanner/netex/configure/NetexConfigure.java similarity index 88% rename from src/main/java/org/opentripplanner/netex/configure/NetexConfigure.java rename to application/src/main/java/org/opentripplanner/netex/configure/NetexConfigure.java index 50c49836246..5771828395e 100644 --- a/src/main/java/org/opentripplanner/netex/configure/NetexConfigure.java +++ b/application/src/main/java/org/opentripplanner/netex/configure/NetexConfigure.java @@ -11,8 +11,9 @@ import org.opentripplanner.netex.config.NetexFeedParameters; import org.opentripplanner.netex.loader.NetexDataSourceHierarchy; import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; import org.opentripplanner.standalone.config.BuildConfig; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; /** * Responsible for dependency injection and creating main NeTEx module objects. This decouple the @@ -35,7 +36,8 @@ public NetexConfigure(BuildConfig builderParams) { public NetexModule createNetexModule( Iterable> netexSources, - TransitModel transitModel, + TimetableRepository timetableRepository, + VehicleParkingRepository parkingRepsitory, Graph graph, DataImportIssueStore issueStore ) { @@ -43,7 +45,7 @@ public NetexModule createNetexModule( for (ConfiguredDataSource it : netexSources) { var transitServiceBuilder = new OtpTransitServiceBuilder( - transitModel.getStopModel(), + timetableRepository.getSiteRepository(), issueStore ); netexBundles.add(netexBundle(transitServiceBuilder, it)); @@ -51,7 +53,8 @@ public NetexModule createNetexModule( return new NetexModule( graph, - transitModel, + timetableRepository, + parkingRepsitory, issueStore, buildParams.getSubwayAccessTimeSeconds(), buildParams.getTransitServicePeriod(), @@ -73,6 +76,7 @@ public NetexBundle netexBundle( hierarchy(source, config), transitServiceBuilder, config.ferryIdsNotAllowedForBicycle(), + buildParams.transitRouteToStationCentroid(), buildParams.maxStopToShapeSnapDistance, config.noTransfersOnIsolatedStops(), config.ignoredFeatures() diff --git a/src/main/java/org/opentripplanner/netex/images/Colaboration.png b/application/src/main/java/org/opentripplanner/netex/images/Colaboration.png similarity index 100% rename from src/main/java/org/opentripplanner/netex/images/Colaboration.png rename to application/src/main/java/org/opentripplanner/netex/images/Colaboration.png diff --git a/src/main/java/org/opentripplanner/netex/images/Colaboration.uxf b/application/src/main/java/org/opentripplanner/netex/images/Colaboration.uxf similarity index 100% rename from src/main/java/org/opentripplanner/netex/images/Colaboration.uxf rename to application/src/main/java/org/opentripplanner/netex/images/Colaboration.uxf diff --git a/src/main/java/org/opentripplanner/netex/images/DegignOverview.png b/application/src/main/java/org/opentripplanner/netex/images/DegignOverview.png similarity index 100% rename from src/main/java/org/opentripplanner/netex/images/DegignOverview.png rename to application/src/main/java/org/opentripplanner/netex/images/DegignOverview.png diff --git a/src/main/java/org/opentripplanner/netex/images/DegignOverview.uxf b/application/src/main/java/org/opentripplanner/netex/images/DegignOverview.uxf similarity index 100% rename from src/main/java/org/opentripplanner/netex/images/DegignOverview.uxf rename to application/src/main/java/org/opentripplanner/netex/images/DegignOverview.uxf diff --git a/src/main/java/org/opentripplanner/netex/images/PackageDependencies.png b/application/src/main/java/org/opentripplanner/netex/images/PackageDependencies.png similarity index 100% rename from src/main/java/org/opentripplanner/netex/images/PackageDependencies.png rename to application/src/main/java/org/opentripplanner/netex/images/PackageDependencies.png diff --git a/src/main/java/org/opentripplanner/netex/images/PackageDependencies.uxf b/application/src/main/java/org/opentripplanner/netex/images/PackageDependencies.uxf similarity index 100% rename from src/main/java/org/opentripplanner/netex/images/PackageDependencies.uxf rename to application/src/main/java/org/opentripplanner/netex/images/PackageDependencies.uxf diff --git a/src/main/java/org/opentripplanner/netex/index/NetexEntityIndex.java b/application/src/main/java/org/opentripplanner/netex/index/NetexEntityIndex.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/index/NetexEntityIndex.java rename to application/src/main/java/org/opentripplanner/netex/index/NetexEntityIndex.java diff --git a/src/main/java/org/opentripplanner/netex/index/api/HMapValidationRule.java b/application/src/main/java/org/opentripplanner/netex/index/api/HMapValidationRule.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/index/api/HMapValidationRule.java rename to application/src/main/java/org/opentripplanner/netex/index/api/HMapValidationRule.java diff --git a/src/main/java/org/opentripplanner/netex/index/api/NetexEntityIndexReadOnlyView.java b/application/src/main/java/org/opentripplanner/netex/index/api/NetexEntityIndexReadOnlyView.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/index/api/NetexEntityIndexReadOnlyView.java rename to application/src/main/java/org/opentripplanner/netex/index/api/NetexEntityIndexReadOnlyView.java diff --git a/src/main/java/org/opentripplanner/netex/index/api/ReadOnlyHierarchicalMap.java b/application/src/main/java/org/opentripplanner/netex/index/api/ReadOnlyHierarchicalMap.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/index/api/ReadOnlyHierarchicalMap.java rename to application/src/main/java/org/opentripplanner/netex/index/api/ReadOnlyHierarchicalMap.java diff --git a/src/main/java/org/opentripplanner/netex/index/api/ReadOnlyHierarchicalMapById.java b/application/src/main/java/org/opentripplanner/netex/index/api/ReadOnlyHierarchicalMapById.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/index/api/ReadOnlyHierarchicalMapById.java rename to application/src/main/java/org/opentripplanner/netex/index/api/ReadOnlyHierarchicalMapById.java diff --git a/src/main/java/org/opentripplanner/netex/index/api/ReadOnlyHierarchicalVersionMapById.java b/application/src/main/java/org/opentripplanner/netex/index/api/ReadOnlyHierarchicalVersionMapById.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/index/api/ReadOnlyHierarchicalVersionMapById.java rename to application/src/main/java/org/opentripplanner/netex/index/api/ReadOnlyHierarchicalVersionMapById.java diff --git a/src/main/java/org/opentripplanner/netex/index/hierarchy/AbstractHierarchicalMap.java b/application/src/main/java/org/opentripplanner/netex/index/hierarchy/AbstractHierarchicalMap.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/index/hierarchy/AbstractHierarchicalMap.java rename to application/src/main/java/org/opentripplanner/netex/index/hierarchy/AbstractHierarchicalMap.java diff --git a/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalElement.java b/application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalElement.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalElement.java rename to application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalElement.java diff --git a/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMap.java b/application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMap.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMap.java rename to application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMap.java diff --git a/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapById.java b/application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapById.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapById.java rename to application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapById.java diff --git a/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMultimap.java b/application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMultimap.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMultimap.java rename to application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMultimap.java diff --git a/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalVersionMapById.java b/application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalVersionMapById.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalVersionMapById.java rename to application/src/main/java/org/opentripplanner/netex/index/hierarchy/HierarchicalVersionMapById.java diff --git a/src/main/java/org/opentripplanner/netex/index/hierarchy/ValidOnDate.java b/application/src/main/java/org/opentripplanner/netex/index/hierarchy/ValidOnDate.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/index/hierarchy/ValidOnDate.java rename to application/src/main/java/org/opentripplanner/netex/index/hierarchy/ValidOnDate.java diff --git a/src/main/java/org/opentripplanner/netex/issues/DayTypeScheduleIsEmpty.java b/application/src/main/java/org/opentripplanner/netex/issues/DayTypeScheduleIsEmpty.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/issues/DayTypeScheduleIsEmpty.java rename to application/src/main/java/org/opentripplanner/netex/issues/DayTypeScheduleIsEmpty.java diff --git a/src/main/java/org/opentripplanner/netex/issues/InterchangeMaxWaitTimeNotGuaranteed.java b/application/src/main/java/org/opentripplanner/netex/issues/InterchangeMaxWaitTimeNotGuaranteed.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/issues/InterchangeMaxWaitTimeNotGuaranteed.java rename to application/src/main/java/org/opentripplanner/netex/issues/InterchangeMaxWaitTimeNotGuaranteed.java diff --git a/src/main/java/org/opentripplanner/netex/issues/InterchangePointMappingFailed.java b/application/src/main/java/org/opentripplanner/netex/issues/InterchangePointMappingFailed.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/issues/InterchangePointMappingFailed.java rename to application/src/main/java/org/opentripplanner/netex/issues/InterchangePointMappingFailed.java diff --git a/src/main/java/org/opentripplanner/netex/issues/InterchangeWithoutConstraint.java b/application/src/main/java/org/opentripplanner/netex/issues/InterchangeWithoutConstraint.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/issues/InterchangeWithoutConstraint.java rename to application/src/main/java/org/opentripplanner/netex/issues/InterchangeWithoutConstraint.java diff --git a/src/main/java/org/opentripplanner/netex/issues/ObjectNotFound.java b/application/src/main/java/org/opentripplanner/netex/issues/ObjectNotFound.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/issues/ObjectNotFound.java rename to application/src/main/java/org/opentripplanner/netex/issues/ObjectNotFound.java diff --git a/src/main/java/org/opentripplanner/netex/issues/StopPlaceWithoutCoordinates.java b/application/src/main/java/org/opentripplanner/netex/issues/StopPlaceWithoutCoordinates.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/issues/StopPlaceWithoutCoordinates.java rename to application/src/main/java/org/opentripplanner/netex/issues/StopPlaceWithoutCoordinates.java diff --git a/src/main/java/org/opentripplanner/netex/issues/StopPlaceWithoutQuays.java b/application/src/main/java/org/opentripplanner/netex/issues/StopPlaceWithoutQuays.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/issues/StopPlaceWithoutQuays.java rename to application/src/main/java/org/opentripplanner/netex/issues/StopPlaceWithoutQuays.java diff --git a/src/main/java/org/opentripplanner/netex/loader/GroupEntries.java b/application/src/main/java/org/opentripplanner/netex/loader/GroupEntries.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/loader/GroupEntries.java rename to application/src/main/java/org/opentripplanner/netex/loader/GroupEntries.java diff --git a/src/main/java/org/opentripplanner/netex/loader/NetexDataSourceHierarchy.java b/application/src/main/java/org/opentripplanner/netex/loader/NetexDataSourceHierarchy.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/loader/NetexDataSourceHierarchy.java rename to application/src/main/java/org/opentripplanner/netex/loader/NetexDataSourceHierarchy.java diff --git a/src/main/java/org/opentripplanner/netex/loader/NetexXmlParser.java b/application/src/main/java/org/opentripplanner/netex/loader/NetexXmlParser.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/loader/NetexXmlParser.java rename to application/src/main/java/org/opentripplanner/netex/loader/NetexXmlParser.java diff --git a/src/main/java/org/opentripplanner/netex/loader/parser/FareFrameParser.java b/application/src/main/java/org/opentripplanner/netex/loader/parser/FareFrameParser.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/loader/parser/FareFrameParser.java rename to application/src/main/java/org/opentripplanner/netex/loader/parser/FareFrameParser.java diff --git a/src/main/java/org/opentripplanner/netex/loader/parser/NetexDocumentParser.java b/application/src/main/java/org/opentripplanner/netex/loader/parser/NetexDocumentParser.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/loader/parser/NetexDocumentParser.java rename to application/src/main/java/org/opentripplanner/netex/loader/parser/NetexDocumentParser.java diff --git a/src/main/java/org/opentripplanner/netex/loader/parser/NetexParser.java b/application/src/main/java/org/opentripplanner/netex/loader/parser/NetexParser.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/loader/parser/NetexParser.java rename to application/src/main/java/org/opentripplanner/netex/loader/parser/NetexParser.java diff --git a/src/main/java/org/opentripplanner/netex/loader/parser/NoticeParser.java b/application/src/main/java/org/opentripplanner/netex/loader/parser/NoticeParser.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/loader/parser/NoticeParser.java rename to application/src/main/java/org/opentripplanner/netex/loader/parser/NoticeParser.java diff --git a/src/main/java/org/opentripplanner/netex/loader/parser/ResourceFrameParser.java b/application/src/main/java/org/opentripplanner/netex/loader/parser/ResourceFrameParser.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/loader/parser/ResourceFrameParser.java rename to application/src/main/java/org/opentripplanner/netex/loader/parser/ResourceFrameParser.java diff --git a/src/main/java/org/opentripplanner/netex/loader/parser/ServiceCalendarFrameParser.java b/application/src/main/java/org/opentripplanner/netex/loader/parser/ServiceCalendarFrameParser.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/loader/parser/ServiceCalendarFrameParser.java rename to application/src/main/java/org/opentripplanner/netex/loader/parser/ServiceCalendarFrameParser.java diff --git a/src/main/java/org/opentripplanner/netex/loader/parser/ServiceFrameParser.java b/application/src/main/java/org/opentripplanner/netex/loader/parser/ServiceFrameParser.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/loader/parser/ServiceFrameParser.java rename to application/src/main/java/org/opentripplanner/netex/loader/parser/ServiceFrameParser.java diff --git a/src/main/java/org/opentripplanner/netex/loader/parser/SiteFrameParser.java b/application/src/main/java/org/opentripplanner/netex/loader/parser/SiteFrameParser.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/loader/parser/SiteFrameParser.java rename to application/src/main/java/org/opentripplanner/netex/loader/parser/SiteFrameParser.java diff --git a/src/main/java/org/opentripplanner/netex/loader/parser/TimeTableFrameParser.java b/application/src/main/java/org/opentripplanner/netex/loader/parser/TimeTableFrameParser.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/loader/parser/TimeTableFrameParser.java rename to application/src/main/java/org/opentripplanner/netex/loader/parser/TimeTableFrameParser.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/AuthorityToAgencyMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/AuthorityToAgencyMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/netex/mapping/AuthorityToAgencyMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/AuthorityToAgencyMapper.java index ec466cc2e27..f954c3a4c24 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/AuthorityToAgencyMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/AuthorityToAgencyMapper.java @@ -2,10 +2,10 @@ import static org.opentripplanner.netex.mapping.support.NetexObjectDecorator.withOptional; -import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.netex.mapping.support.FeedScopedIdFactory; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.organization.AgencyBuilder; +import org.opentripplanner.utils.lang.StringUtils; import org.rutebanken.netex.model.Authority; /** diff --git a/src/main/java/org/opentripplanner/netex/mapping/BookingInfoMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/BookingInfoMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/BookingInfoMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/BookingInfoMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/BookingMethodMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/BookingMethodMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/BookingMethodMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/BookingMethodMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/BrandingMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/BrandingMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/BrandingMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/BrandingMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/DirectionMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/DirectionMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/DirectionMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/DirectionMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/DurationMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/DurationMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/DurationMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/DurationMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/FlexStopsMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/FlexStopsMapper.java similarity index 94% rename from src/main/java/org/opentripplanner/netex/mapping/FlexStopsMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/FlexStopsMapper.java index 7e06db882f1..f53eb67b01a 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/FlexStopsMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/FlexStopsMapper.java @@ -15,7 +15,7 @@ import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; -import org.opentripplanner.transit.service.StopModelBuilder; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; import org.rutebanken.netex.model.FlexibleArea; import org.rutebanken.netex.model.FlexibleStopPlace; import org.rutebanken.netex.model.KeyListStructure; @@ -34,14 +34,14 @@ class FlexStopsMapper { "UnrestrictedPublicTransportAreas"; private final FeedScopedIdFactory idFactory; private final HashGridSpatialIndex stopsSpatialIndex; - private final StopModelBuilder stopModelBuilder; + private final SiteRepositoryBuilder siteRepositoryBuilder; private final DataImportIssueStore issueStore; private final TransportModeMapper transportModeMapper = new TransportModeMapper(); FlexStopsMapper( FeedScopedIdFactory idFactory, Collection stops, - StopModelBuilder stopModelBuilder, + SiteRepositoryBuilder siteRepositoryBuilder, DataImportIssueStore issueStore ) { this.idFactory = idFactory; @@ -50,7 +50,7 @@ class FlexStopsMapper { Envelope env = new Envelope(stop.getCoordinate().asJtsCoordinate()); this.stopsSpatialIndex.insert(env, stop); } - this.stopModelBuilder = stopModelBuilder; + this.siteRepositoryBuilder = siteRepositoryBuilder; this.issueStore = issueStore; } @@ -100,7 +100,7 @@ StopLocation map(FlexibleStopPlace flexibleStopPlace) { } else { // We create a new GroupStop, even if the stop place consists of a single area, in order to // get the ids for the area and stop place correct - var builder = stopModelBuilder + var builder = siteRepositoryBuilder .groupStop(idFactory.createId(flexibleStopPlace.getId())) .withName(new NonLocalizedString(flexibleStopPlace.getName().getValue())) .withEncompassingAreaGeometries(areaGeometries); @@ -118,7 +118,7 @@ AreaStop mapFlexArea(FlexibleArea area, Geometry geometry, String backupName) { } var areaName = area.getName(); - return stopModelBuilder + return siteRepositoryBuilder .areaStop(idFactory.createId(area.getId())) .withName(new NonLocalizedString(areaName != null ? areaName.getValue() : backupName)) .withGeometry(geometry) @@ -140,7 +140,7 @@ List findStopsInFlexArea( List stops = stopsSpatialIndex .query(geometry.getEnvelopeInternal()) .stream() - .filter(stop -> flexibleStopTransitMode == stop.getGtfsVehicleType()) + .filter(stop -> flexibleStopTransitMode == stop.getVehicleType()) .filter(stop -> geometry.contains(stop.getGeometry())) .toList(); diff --git a/src/main/java/org/opentripplanner/netex/mapping/GroupNetexMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/GroupNetexMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/GroupNetexMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/GroupNetexMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/GroupOfRoutesMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/GroupOfRoutesMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/GroupOfRoutesMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/GroupOfRoutesMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/GroupOfStationsMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/GroupOfStationsMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/GroupOfStationsMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/GroupOfStationsMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/MultiModalStationMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/MultiModalStationMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/MultiModalStationMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/MultiModalStationMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/MultilingualStringMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/MultilingualStringMapper.java similarity index 89% rename from src/main/java/org/opentripplanner/netex/mapping/MultilingualStringMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/MultilingualStringMapper.java index 0f0e2336bc7..668c9feea46 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/MultilingualStringMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/MultilingualStringMapper.java @@ -1,7 +1,7 @@ package org.opentripplanner.netex.mapping; import javax.annotation.Nullable; -import org.opentripplanner.framework.lang.StringUtils; +import org.opentripplanner.utils.lang.StringUtils; import org.rutebanken.netex.model.MultilingualString; public class MultilingualStringMapper { diff --git a/src/main/java/org/opentripplanner/netex/mapping/NetexMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/NetexMapper.java similarity index 95% rename from src/main/java/org/opentripplanner/netex/mapping/NetexMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/NetexMapper.java index 025a2349874..c8d4f80af63 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/NetexMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/NetexMapper.java @@ -66,6 +66,7 @@ public class NetexMapper { private final CalendarServiceBuilder calendarServiceBuilder; private final TripCalendarBuilder tripCalendarBuilder; private final Set ferryIdsNotAllowedForBicycle; + private final Set routeToCentroidStopPlaceIds; private final double maxStopToShapeSnapDistance; private final boolean noTransfersOnIsolatedStops; @@ -93,6 +94,7 @@ public NetexMapper( Deduplicator deduplicator, DataImportIssueStore issueStore, Set ferryIdsNotAllowedForBicycle, + Collection routeToCentroidStopPlaceIds, double maxStopToShapeSnapDistance, boolean noTransfersOnIsolatedStops ) { @@ -101,6 +103,7 @@ public NetexMapper( this.idFactory = new FeedScopedIdFactory(feedId); this.issueStore = issueStore; this.ferryIdsNotAllowedForBicycle = ferryIdsNotAllowedForBicycle; + this.routeToCentroidStopPlaceIds = Set.copyOf(routeToCentroidStopPlaceIds); this.noTransfersOnIsolatedStops = noTransfersOnIsolatedStops; this.maxStopToShapeSnapDistance = maxStopToShapeSnapDistance; this.calendarServiceBuilder = new CalendarServiceBuilder(idFactory); @@ -306,10 +309,11 @@ private void mapStopPlaceAndQuays(TariffZoneMapper tariffZoneMapper) { idFactory, currentNetexIndex.getQuayById(), tariffZoneMapper, - transitBuilder.stopModel(), + transitBuilder.siteRepository(), zoneId, issueStore, - noTransfersOnIsolatedStops + noTransfersOnIsolatedStops, + routeToCentroidStopPlaceIds ); for (String stopPlaceId : currentNetexIndex.getStopPlaceById().localKeys()) { Collection stopPlaceAllVersions = currentNetexIndex @@ -317,8 +321,8 @@ private void mapStopPlaceAndQuays(TariffZoneMapper tariffZoneMapper) { .lookup(stopPlaceId); stopMapper.mapParentAndChildStops(stopPlaceAllVersions); } - transitBuilder.stopModel().withRegularStops(stopMapper.resultStops); - transitBuilder.stopModel().withStations(stopMapper.resultStations); + transitBuilder.siteRepository().withRegularStops(stopMapper.resultStops); + transitBuilder.siteRepository().withStations(stopMapper.resultStations); currentMapperIndexes.addStationByMultiModalStationRfs( stopMapper.resultStationByMultiModalStationRfs ); @@ -335,7 +339,7 @@ private void mapMultiModalStopPlaces() { .get(multiModalStopPlace.getId()); var multiModalStation = mapper.map(multiModalStopPlace, stations); if (multiModalStation != null) { - transitBuilder.stopModel().withMultiModalStation(multiModalStation); + transitBuilder.siteRepository().withMultiModalStation(multiModalStation); } } } @@ -350,7 +354,9 @@ private void mapGroupsOfStopPlaces() { for (GroupOfStopPlaces groupOfStopPlaces : currentNetexIndex .getGroupOfStopPlacesById() .localValues()) { - transitBuilder.stopModel().withGroupOfStation(groupOfStationsMapper.map(groupOfStopPlaces)); + transitBuilder + .siteRepository() + .withGroupOfStation(groupOfStationsMapper.map(groupOfStopPlaces)); } } @@ -367,19 +373,19 @@ private void mapFlexibleStopPlaces() { FlexStopsMapper flexStopsMapper = new FlexStopsMapper( idFactory, transitBuilder.getStops().values(), - transitBuilder.stopModel(), + transitBuilder.siteRepository(), issueStore ); for (FlexibleStopPlace flexibleStopPlace : flexibleStopPlaces) { StopLocation stopLocation = flexStopsMapper.map(flexibleStopPlace); if (stopLocation instanceof AreaStop areaStop) { - transitBuilder.stopModel().withAreaStop(areaStop); + transitBuilder.siteRepository().withAreaStop(areaStop); } else if (stopLocation instanceof GroupStop groupStop) { - transitBuilder.stopModel().withGroupStop(groupStop); + transitBuilder.siteRepository().withGroupStop(groupStop); for (var child : groupStop.getChildLocations()) { if (child instanceof AreaStop areaStop) { - transitBuilder.stopModel().withAreaStop(areaStop); + transitBuilder.siteRepository().withAreaStop(areaStop); } } } @@ -440,9 +446,9 @@ private void mapTripPatterns(Map serviceIds) { issueStore, idFactory, transitBuilder.getOperatorsById(), - transitBuilder.stopModel().regularStopsById(), - transitBuilder.stopModel().areaStopById(), - transitBuilder.stopModel().groupStopById(), + transitBuilder.siteRepository().regularStopsById(), + transitBuilder.siteRepository().areaStopById(), + transitBuilder.siteRepository().groupStopById(), transitBuilder.getRoutes(), currentNetexIndex.getRouteById(), currentNetexIndex.getJourneyPatternsById(), diff --git a/src/main/java/org/opentripplanner/netex/mapping/NoticeAssignmentMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/NoticeAssignmentMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/NoticeAssignmentMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/NoticeAssignmentMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/NoticeMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/NoticeMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/NoticeMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/NoticeMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/OpenGisMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/OpenGisMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/OpenGisMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/OpenGisMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/OperatorToAgencyMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/OperatorToAgencyMapper.java similarity index 96% rename from src/main/java/org/opentripplanner/netex/mapping/OperatorToAgencyMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/OperatorToAgencyMapper.java index f7bd2643769..b4cf9f3e4de 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/OperatorToAgencyMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/OperatorToAgencyMapper.java @@ -1,10 +1,10 @@ package org.opentripplanner.netex.mapping; -import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.netex.mapping.support.FeedScopedIdFactory; import org.opentripplanner.transit.model.organization.Operator; import org.opentripplanner.transit.model.organization.OperatorBuilder; +import org.opentripplanner.utils.lang.StringUtils; import org.rutebanken.netex.model.ContactStructure; /** diff --git a/src/main/java/org/opentripplanner/netex/mapping/QuayMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/QuayMapper.java similarity index 86% rename from src/main/java/org/opentripplanner/netex/mapping/QuayMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/QuayMapper.java index 5e9285043d5..db67941e323 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/QuayMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/QuayMapper.java @@ -1,7 +1,6 @@ package org.opentripplanner.netex.mapping; import java.util.Collection; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; @@ -12,7 +11,7 @@ import org.opentripplanner.transit.model.site.FareZone; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; -import org.opentripplanner.transit.service.StopModelBuilder; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; import org.rutebanken.netex.model.MultilingualString; import org.rutebanken.netex.model.Quay; @@ -22,16 +21,16 @@ class QuayMapper { private final FeedScopedIdFactory idFactory; - private final StopModelBuilder stopModelBuilder; + private final SiteRepositoryBuilder siteRepositoryBuilder; QuayMapper( FeedScopedIdFactory idFactory, DataImportIssueStore issueStore, - StopModelBuilder stopModelBuilder + SiteRepositoryBuilder siteRepositoryBuilder ) { this.idFactory = idFactory; this.issueStore = issueStore; - this.stopModelBuilder = stopModelBuilder; + this.siteRepositoryBuilder = siteRepositoryBuilder; } /** @@ -39,14 +38,14 @@ class QuayMapper { */ @Nullable RegularStop mapQuayToStop( - @Nonnull Quay quay, + Quay quay, Station parentStation, Collection fareZones, NetexMainAndSubMode transitMode, Accessibility wheelchair ) { var id = idFactory.createId(quay.getId()); - return stopModelBuilder.computeRegularStopIfAbsent( + return siteRepositoryBuilder.computeRegularStopIfAbsent( id, it -> map(it, quay, parentStation, fareZones, transitMode, wheelchair) ); @@ -54,7 +53,7 @@ RegularStop mapQuayToStop( private RegularStop map( FeedScopedId id, - @Nonnull Quay quay, + Quay quay, Station parentStation, Collection fareZones, NetexMainAndSubMode transitMode, @@ -71,7 +70,7 @@ private RegularStop map( return null; } - var builder = stopModelBuilder + var builder = siteRepositoryBuilder .regularStop(id) .withParentStation(parentStation) .withName(parentStation.getName()) diff --git a/src/main/java/org/opentripplanner/netex/mapping/RouteMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/RouteMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/RouteMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/RouteMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/ServiceLinkMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/ServiceLinkMapper.java similarity index 99% rename from src/main/java/org/opentripplanner/netex/mapping/ServiceLinkMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/ServiceLinkMapper.java index 2b2152be4e0..090f475e22e 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/ServiceLinkMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/ServiceLinkMapper.java @@ -3,6 +3,7 @@ import jakarta.xml.bind.JAXBElement; import java.util.Arrays; import java.util.List; +import javax.annotation.Nullable; import net.opengis.gml._3.LineStringType; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.CoordinateSequence; @@ -116,6 +117,7 @@ private LineString[] generateGeometriesFromServiceLinks( return geometries; } + @Nullable private LineString mapServiceLink( ServiceLink serviceLink, StopPattern stopPattern, diff --git a/src/main/java/org/opentripplanner/netex/mapping/StationMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/StationMapper.java similarity index 86% rename from src/main/java/org/opentripplanner/netex/mapping/StationMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/StationMapper.java index e94cf23fc4a..27773a9f66c 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/StationMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/StationMapper.java @@ -7,6 +7,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Set; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; @@ -16,7 +17,7 @@ import org.opentripplanner.netex.support.JAXBUtils; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.Station; -import org.opentripplanner.transit.service.StopModelBuilder; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; import org.rutebanken.netex.model.LimitedUseTypeEnumeration; import org.rutebanken.netex.model.LocaleStructure; import org.rutebanken.netex.model.MultilingualString; @@ -34,25 +35,33 @@ class StationMapper { private final ZoneId defaultTimeZone; private final boolean noTransfersOnIsolatedStops; - private final StopModelBuilder stopModelBuilder; + + private final Set routeToCentroidStopPlaceIds; + + private final SiteRepositoryBuilder siteRepositoryBuilder; StationMapper( DataImportIssueStore issueStore, FeedScopedIdFactory idFactory, ZoneId defaultTimeZone, boolean noTransfersOnIsolatedStops, - StopModelBuilder stopModelBuilder + Set routeToCentroidStopPlaceIds, + SiteRepositoryBuilder siteRepositoryBuilder ) { this.issueStore = issueStore; this.idFactory = idFactory; this.defaultTimeZone = defaultTimeZone; this.noTransfersOnIsolatedStops = noTransfersOnIsolatedStops; - this.stopModelBuilder = stopModelBuilder; + this.routeToCentroidStopPlaceIds = routeToCentroidStopPlaceIds; + this.siteRepositoryBuilder = siteRepositoryBuilder; } Station map(StopPlace stopPlace) { var id = idFactory.createId(stopPlace.getId()); - return stopModelBuilder.computeStationIfAbsent(id, it -> mapStopPlaceToStation(it, stopPlace)); + return siteRepositoryBuilder.computeStationIfAbsent( + id, + it -> mapStopPlaceToStation(it, stopPlace) + ); } Station mapStopPlaceToStation(FeedScopedId id, StopPlace stopPlace) { @@ -60,6 +69,7 @@ Station mapStopPlaceToStation(FeedScopedId id, StopPlace stopPlace) { .of(id) .withName(resolveName(stopPlace)) .withCoordinate(mapCoordinate(stopPlace)) + .withShouldRouteToCentroid(shouldRouteToCentroid(id)) .withDescription( NonLocalizedString.ofNullable(stopPlace.getDescription(), MultilingualString::getValue) ) @@ -81,6 +91,10 @@ Station mapStopPlaceToStation(FeedScopedId id, StopPlace stopPlace) { return builder.build(); } + private boolean shouldRouteToCentroid(FeedScopedId stopPlaceId) { + return routeToCentroidStopPlaceIds.contains(stopPlaceId); + } + private ZoneId ofZoneId(String stopPlaceId, String zoneId) { try { return ZoneId.of(zoneId); diff --git a/src/main/java/org/opentripplanner/netex/mapping/StopAndStationMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/StopAndStationMapper.java similarity index 95% rename from src/main/java/org/opentripplanner/netex/mapping/StopAndStationMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/StopAndStationMapper.java index dd6d6a6f9f7..0a5ab4ba16c 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/StopAndStationMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/StopAndStationMapper.java @@ -22,10 +22,11 @@ import org.opentripplanner.netex.mapping.support.NetexMainAndSubMode; import org.opentripplanner.netex.mapping.support.StopPlaceVersionAndValidityComparator; import org.opentripplanner.transit.model.basic.Accessibility; +import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.FareZone; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; -import org.opentripplanner.transit.service.StopModelBuilder; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; import org.rutebanken.netex.model.Quay; import org.rutebanken.netex.model.Quays_RelStructure; import org.rutebanken.netex.model.StopPlace; @@ -67,10 +68,11 @@ class StopAndStationMapper { FeedScopedIdFactory idFactory, ReadOnlyHierarchicalVersionMapById quayIndex, TariffZoneMapper tariffZoneMapper, - StopModelBuilder stopModelBuilder, + SiteRepositoryBuilder siteRepositoryBuilder, ZoneId defaultTimeZone, DataImportIssueStore issueStore, - boolean noTransfersOnIsolatedStops + boolean noTransfersOnIsolatedStops, + Set routeToCentroidStopPlaceIds ) { this.stationMapper = new StationMapper( @@ -78,9 +80,10 @@ class StopAndStationMapper { idFactory, defaultTimeZone, noTransfersOnIsolatedStops, - stopModelBuilder + routeToCentroidStopPlaceIds, + siteRepositoryBuilder ); - this.quayMapper = new QuayMapper(idFactory, issueStore, stopModelBuilder); + this.quayMapper = new QuayMapper(idFactory, issueStore, siteRepositoryBuilder); this.tariffZoneMapper = tariffZoneMapper; this.quayIndex = quayIndex; this.issueStore = issueStore; diff --git a/src/main/java/org/opentripplanner/netex/mapping/StopPlaceTypeMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/StopPlaceTypeMapper.java similarity index 98% rename from src/main/java/org/opentripplanner/netex/mapping/StopPlaceTypeMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/StopPlaceTypeMapper.java index 22fbb1fca1c..b98ce0fd39f 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/StopPlaceTypeMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/StopPlaceTypeMapper.java @@ -29,7 +29,7 @@ private TransitMode mapVehicleMode(StopPlace stopPlace) { case AIR -> TransitMode.AIRPLANE; case BUS -> TransitMode.BUS; case TROLLEY_BUS -> TransitMode.TROLLEYBUS; - case CABLEWAY -> TransitMode.CABLE_CAR; + case CABLEWAY -> TransitMode.GONDOLA; case COACH -> TransitMode.COACH; case FUNICULAR -> TransitMode.FUNICULAR; case METRO -> TransitMode.SUBWAY; diff --git a/src/main/java/org/opentripplanner/netex/mapping/StopTimesMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/StopTimesMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/StopTimesMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/StopTimesMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/StopTimesMapperResult.java b/application/src/main/java/org/opentripplanner/netex/mapping/StopTimesMapperResult.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/StopTimesMapperResult.java rename to application/src/main/java/org/opentripplanner/netex/mapping/StopTimesMapperResult.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/StopTransferPriorityMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/StopTransferPriorityMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/StopTransferPriorityMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/StopTransferPriorityMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/TariffZoneMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/TariffZoneMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/TariffZoneMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/TariffZoneMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/TransferMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/TransferMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/TransferMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/TransferMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/TransportModeMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/TransportModeMapper.java similarity index 98% rename from src/main/java/org/opentripplanner/netex/mapping/TransportModeMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/TransportModeMapper.java index 82a5f99c9c7..5db45f93c8d 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/TransportModeMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/TransportModeMapper.java @@ -32,7 +32,7 @@ public TransitMode mapAllVehicleModesOfTransport(AllVehicleModesOfTransportEnume return switch (mode) { case AIR -> TransitMode.AIRPLANE; case BUS -> TransitMode.BUS; - case CABLEWAY -> TransitMode.CABLE_CAR; + case CABLEWAY -> TransitMode.GONDOLA; case COACH -> TransitMode.COACH; case FUNICULAR -> TransitMode.FUNICULAR; case METRO -> TransitMode.SUBWAY; diff --git a/src/main/java/org/opentripplanner/netex/mapping/TripCalendarBuilder.java b/application/src/main/java/org/opentripplanner/netex/mapping/TripCalendarBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/TripCalendarBuilder.java rename to application/src/main/java/org/opentripplanner/netex/mapping/TripCalendarBuilder.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/TripMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/TripMapper.java similarity index 98% rename from src/main/java/org/opentripplanner/netex/mapping/TripMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/TripMapper.java index 30b87d248a0..02b5de80bb3 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/TripMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/TripMapper.java @@ -137,7 +137,7 @@ Trip mapServiceJourney(ServiceJourney serviceJourney, Supplier headsign) ); // TODO RTM - Instead of getting the first headsign from the StopTime this could be the - // - default behaviour of the TransitModel - So, in the NeTEx mapper we would just + // - default behaviour of the TimetableRepository - So, in the NeTEx mapper we would just // - ignore setting the headsign on the Trip. builder.withHeadsign(new NonLocalizedString(headsign.get())); diff --git a/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapper.java similarity index 99% rename from src/main/java/org/opentripplanner/netex/mapping/TripPatternMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapper.java index 740224b4489..c7b85e72af8 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapper.java @@ -255,8 +255,10 @@ Optional mapTripPattern(JourneyPattern_VersionStructure .withHopGeometries( serviceLinkMapper.getGeometriesByJourneyPattern(journeyPattern, stopPattern) ) + .withScheduledTimeTableBuilder(builder -> + builder.addAllTripTimes(createTripTimes(trips, tripStopTimes)) + ) .build(); - createTripTimes(trips, tripStopTimes).forEach(tripPattern::add); return Optional.of( new TripPatternMapperResult( diff --git a/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapperResult.java b/application/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapperResult.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/TripPatternMapperResult.java rename to application/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapperResult.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/TripServiceAlterationMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/TripServiceAlterationMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/TripServiceAlterationMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/TripServiceAlterationMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/VehicleParkingMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/VehicleParkingMapper.java similarity index 95% rename from src/main/java/org/opentripplanner/netex/mapping/VehicleParkingMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/VehicleParkingMapper.java index 862c5f0c648..f29d9760077 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/VehicleParkingMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/VehicleParkingMapper.java @@ -9,8 +9,8 @@ import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.netex.mapping.support.FeedScopedIdFactory; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; import org.rutebanken.netex.model.Parking; import org.rutebanken.netex.model.ParkingVehicleEnumeration; diff --git a/src/main/java/org/opentripplanner/netex/mapping/WgsCoordinateMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/WgsCoordinateMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/WgsCoordinateMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/WgsCoordinateMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/WheelChairMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/WheelChairMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/WheelChairMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/WheelChairMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/calendar/CalendarServiceBuilder.java b/application/src/main/java/org/opentripplanner/netex/mapping/calendar/CalendarServiceBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/calendar/CalendarServiceBuilder.java rename to application/src/main/java/org/opentripplanner/netex/mapping/calendar/CalendarServiceBuilder.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/calendar/DatedServiceJourneyMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/calendar/DatedServiceJourneyMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/calendar/DatedServiceJourneyMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/calendar/DatedServiceJourneyMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/calendar/DayOfWeekMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/calendar/DayOfWeekMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/calendar/DayOfWeekMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/calendar/DayOfWeekMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/calendar/DayTypeAssignmentMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/calendar/DayTypeAssignmentMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/calendar/DayTypeAssignmentMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/calendar/DayTypeAssignmentMapper.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/calendar/OperatingDayMapper.java b/application/src/main/java/org/opentripplanner/netex/mapping/calendar/OperatingDayMapper.java similarity index 77% rename from src/main/java/org/opentripplanner/netex/mapping/calendar/OperatingDayMapper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/calendar/OperatingDayMapper.java index 63c554c95fa..be398d34902 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/calendar/OperatingDayMapper.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/calendar/OperatingDayMapper.java @@ -1,7 +1,6 @@ package org.opentripplanner.netex.mapping.calendar; import java.time.LocalDate; -import javax.annotation.Nonnull; import org.rutebanken.netex.model.OperatingDay; class OperatingDayMapper { @@ -9,7 +8,7 @@ class OperatingDayMapper { /** Utility class, prevent instantiation. */ private OperatingDayMapper() {} - static LocalDate map(@Nonnull OperatingDay opDay) { + static LocalDate map(OperatingDay opDay) { return opDay.getCalendarDate().toLocalDate(); } } diff --git a/src/main/java/org/opentripplanner/netex/mapping/support/FeedScopedIdFactory.java b/application/src/main/java/org/opentripplanner/netex/mapping/support/FeedScopedIdFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/support/FeedScopedIdFactory.java rename to application/src/main/java/org/opentripplanner/netex/mapping/support/FeedScopedIdFactory.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/support/NetexMainAndSubMode.java b/application/src/main/java/org/opentripplanner/netex/mapping/support/NetexMainAndSubMode.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/support/NetexMainAndSubMode.java rename to application/src/main/java/org/opentripplanner/netex/mapping/support/NetexMainAndSubMode.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/support/NetexMapperIndexes.java b/application/src/main/java/org/opentripplanner/netex/mapping/support/NetexMapperIndexes.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/support/NetexMapperIndexes.java rename to application/src/main/java/org/opentripplanner/netex/mapping/support/NetexMapperIndexes.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/support/NetexObjectDecorator.java b/application/src/main/java/org/opentripplanner/netex/mapping/support/NetexObjectDecorator.java similarity index 91% rename from src/main/java/org/opentripplanner/netex/mapping/support/NetexObjectDecorator.java rename to application/src/main/java/org/opentripplanner/netex/mapping/support/NetexObjectDecorator.java index e096cc499b7..1f4b8b0c786 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/support/NetexObjectDecorator.java +++ b/application/src/main/java/org/opentripplanner/netex/mapping/support/NetexObjectDecorator.java @@ -1,7 +1,6 @@ package org.opentripplanner.netex.mapping.support; import java.util.function.Consumer; -import javax.annotation.Nonnull; import org.rutebanken.netex.model.VersionOfObjectRefStructure; import org.slf4j.Logger; @@ -46,7 +45,7 @@ public static void foo() {} * the right scope - this class is just a utility class, or the messenger. * @param ref the unexpected reference to an unmapped object. */ - public static void logUnmappedEntityRef(Logger log, @Nonnull VersionOfObjectRefStructure ref) { + public static void logUnmappedEntityRef(Logger log, VersionOfObjectRefStructure ref) { log.warn("Unexpected entity {} in NeTEx import. The entity is ignored.", ref); } } diff --git a/src/main/java/org/opentripplanner/netex/mapping/support/ServiceAlterationFilter.java b/application/src/main/java/org/opentripplanner/netex/mapping/support/ServiceAlterationFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/support/ServiceAlterationFilter.java rename to application/src/main/java/org/opentripplanner/netex/mapping/support/ServiceAlterationFilter.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/support/StopPlaceVersionAndValidityComparator.java b/application/src/main/java/org/opentripplanner/netex/mapping/support/StopPlaceVersionAndValidityComparator.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/support/StopPlaceVersionAndValidityComparator.java rename to application/src/main/java/org/opentripplanner/netex/mapping/support/StopPlaceVersionAndValidityComparator.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/support/ValidityComparator.java b/application/src/main/java/org/opentripplanner/netex/mapping/support/ValidityComparator.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/support/ValidityComparator.java rename to application/src/main/java/org/opentripplanner/netex/mapping/support/ValidityComparator.java diff --git a/src/main/java/org/opentripplanner/netex/mapping/support/ValidityHelper.java b/application/src/main/java/org/opentripplanner/netex/mapping/support/ValidityHelper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/mapping/support/ValidityHelper.java rename to application/src/main/java/org/opentripplanner/netex/mapping/support/ValidityHelper.java diff --git a/src/main/java/org/opentripplanner/netex/package.md b/application/src/main/java/org/opentripplanner/netex/package.md similarity index 100% rename from src/main/java/org/opentripplanner/netex/package.md rename to application/src/main/java/org/opentripplanner/netex/package.md diff --git a/src/main/java/org/opentripplanner/netex/support/JAXBUtils.java b/application/src/main/java/org/opentripplanner/netex/support/JAXBUtils.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/support/JAXBUtils.java rename to application/src/main/java/org/opentripplanner/netex/support/JAXBUtils.java diff --git a/src/main/java/org/opentripplanner/netex/support/JourneyPatternHelper.java b/application/src/main/java/org/opentripplanner/netex/support/JourneyPatternHelper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/support/JourneyPatternHelper.java rename to application/src/main/java/org/opentripplanner/netex/support/JourneyPatternHelper.java diff --git a/src/main/java/org/opentripplanner/netex/support/NetexVersionHelper.java b/application/src/main/java/org/opentripplanner/netex/support/NetexVersionHelper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/support/NetexVersionHelper.java rename to application/src/main/java/org/opentripplanner/netex/support/NetexVersionHelper.java diff --git a/src/main/java/org/opentripplanner/netex/support/ServiceJourneyHelper.java b/application/src/main/java/org/opentripplanner/netex/support/ServiceJourneyHelper.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/support/ServiceJourneyHelper.java rename to application/src/main/java/org/opentripplanner/netex/support/ServiceJourneyHelper.java diff --git a/src/main/java/org/opentripplanner/netex/support/ServiceJourneyInfo.java b/application/src/main/java/org/opentripplanner/netex/support/ServiceJourneyInfo.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/support/ServiceJourneyInfo.java rename to application/src/main/java/org/opentripplanner/netex/support/ServiceJourneyInfo.java diff --git a/src/main/java/org/opentripplanner/netex/support/stoptime/AbstractStopTimeAdaptor.java b/application/src/main/java/org/opentripplanner/netex/support/stoptime/AbstractStopTimeAdaptor.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/support/stoptime/AbstractStopTimeAdaptor.java rename to application/src/main/java/org/opentripplanner/netex/support/stoptime/AbstractStopTimeAdaptor.java diff --git a/src/main/java/org/opentripplanner/netex/support/stoptime/AreaStopTimeAdaptor.java b/application/src/main/java/org/opentripplanner/netex/support/stoptime/AreaStopTimeAdaptor.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/support/stoptime/AreaStopTimeAdaptor.java rename to application/src/main/java/org/opentripplanner/netex/support/stoptime/AreaStopTimeAdaptor.java diff --git a/src/main/java/org/opentripplanner/netex/support/stoptime/RegularStopTimeAdaptor.java b/application/src/main/java/org/opentripplanner/netex/support/stoptime/RegularStopTimeAdaptor.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/support/stoptime/RegularStopTimeAdaptor.java rename to application/src/main/java/org/opentripplanner/netex/support/stoptime/RegularStopTimeAdaptor.java diff --git a/src/main/java/org/opentripplanner/netex/support/stoptime/StopTimeAdaptor.java b/application/src/main/java/org/opentripplanner/netex/support/stoptime/StopTimeAdaptor.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/support/stoptime/StopTimeAdaptor.java rename to application/src/main/java/org/opentripplanner/netex/support/stoptime/StopTimeAdaptor.java diff --git a/src/main/java/org/opentripplanner/netex/validation/AbstractHMapValidationRule.java b/application/src/main/java/org/opentripplanner/netex/validation/AbstractHMapValidationRule.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/validation/AbstractHMapValidationRule.java rename to application/src/main/java/org/opentripplanner/netex/validation/AbstractHMapValidationRule.java diff --git a/src/main/java/org/opentripplanner/netex/validation/DSJOperatingDayNotFound.java b/application/src/main/java/org/opentripplanner/netex/validation/DSJOperatingDayNotFound.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/validation/DSJOperatingDayNotFound.java rename to application/src/main/java/org/opentripplanner/netex/validation/DSJOperatingDayNotFound.java diff --git a/src/main/java/org/opentripplanner/netex/validation/DSJServiceJourneyNotFound.java b/application/src/main/java/org/opentripplanner/netex/validation/DSJServiceJourneyNotFound.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/validation/DSJServiceJourneyNotFound.java rename to application/src/main/java/org/opentripplanner/netex/validation/DSJServiceJourneyNotFound.java diff --git a/src/main/java/org/opentripplanner/netex/validation/JourneyPatternNotFoundInSJ.java b/application/src/main/java/org/opentripplanner/netex/validation/JourneyPatternNotFoundInSJ.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/validation/JourneyPatternNotFoundInSJ.java rename to application/src/main/java/org/opentripplanner/netex/validation/JourneyPatternNotFoundInSJ.java diff --git a/src/main/java/org/opentripplanner/netex/validation/JourneyPatternSJMismatch.java b/application/src/main/java/org/opentripplanner/netex/validation/JourneyPatternSJMismatch.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/validation/JourneyPatternSJMismatch.java rename to application/src/main/java/org/opentripplanner/netex/validation/JourneyPatternSJMismatch.java diff --git a/src/main/java/org/opentripplanner/netex/validation/PassengerStopAssignmentQuayNotFound.java b/application/src/main/java/org/opentripplanner/netex/validation/PassengerStopAssignmentQuayNotFound.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/validation/PassengerStopAssignmentQuayNotFound.java rename to application/src/main/java/org/opentripplanner/netex/validation/PassengerStopAssignmentQuayNotFound.java diff --git a/src/main/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTime.java b/application/src/main/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTime.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTime.java rename to application/src/main/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTime.java diff --git a/src/main/java/org/opentripplanner/netex/validation/Validator.java b/application/src/main/java/org/opentripplanner/netex/validation/Validator.java similarity index 100% rename from src/main/java/org/opentripplanner/netex/validation/Validator.java rename to application/src/main/java/org/opentripplanner/netex/validation/Validator.java diff --git a/src/main/java/org/opentripplanner/openstreetmap/OSMOpeningHoursParser.java b/application/src/main/java/org/opentripplanner/osm/OsmOpeningHoursParser.java similarity index 98% rename from src/main/java/org/opentripplanner/openstreetmap/OSMOpeningHoursParser.java rename to application/src/main/java/org/opentripplanner/osm/OsmOpeningHoursParser.java index fcb8162f740..2391eb9aab4 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/OSMOpeningHoursParser.java +++ b/application/src/main/java/org/opentripplanner/osm/OsmOpeningHoursParser.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap; +package org.opentripplanner.osm; import static ch.poole.openinghoursparser.RuleModifier.Modifier.CLOSED; import static ch.poole.openinghoursparser.RuleModifier.Modifier.OFF; @@ -39,9 +39,9 @@ * * Part of the code is copied from https://github.com/leonardehrenfried/opening-hours-evaluator */ -public class OSMOpeningHoursParser { +public class OsmOpeningHoursParser { - private static final Logger LOG = LoggerFactory.getLogger(OSMOpeningHoursParser.class); + private static final Logger LOG = LoggerFactory.getLogger(OsmOpeningHoursParser.class); private final OpeningHoursCalendarService openingHoursCalendarService; @@ -76,14 +76,14 @@ public class OSMOpeningHoursParser { entry(Month.DEC, java.time.Month.DECEMBER) ); - public OSMOpeningHoursParser( + public OsmOpeningHoursParser( OpeningHoursCalendarService openingHoursCalendarService, DataImportIssueStore issueStore ) { this(openingHoursCalendarService, () -> null, issueStore); } - public OSMOpeningHoursParser( + public OsmOpeningHoursParser( OpeningHoursCalendarService openingHoursCalendarService, Supplier zoneIdSupplier, DataImportIssueStore issueStore @@ -94,7 +94,7 @@ public OSMOpeningHoursParser( this.issueStore = issueStore; } - public OSMOpeningHoursParser( + public OsmOpeningHoursParser( OpeningHoursCalendarService openingHoursCalendarService, ZoneId zoneId ) { diff --git a/src/main/java/org/opentripplanner/openstreetmap/OpenStreetMapParser.java b/application/src/main/java/org/opentripplanner/osm/OsmParser.java similarity index 83% rename from src/main/java/org/opentripplanner/openstreetmap/OpenStreetMapParser.java rename to application/src/main/java/org/opentripplanner/osm/OsmParser.java index e46fc94b784..8a5f8e32448 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/OpenStreetMapParser.java +++ b/application/src/main/java/org/opentripplanner/osm/OsmParser.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap; +package org.opentripplanner.osm; import java.util.HashMap; import java.util.List; @@ -7,26 +7,26 @@ import org.openstreetmap.osmosis.osmbinary.BinaryParser; import org.openstreetmap.osmosis.osmbinary.Osmformat; import org.opentripplanner.graph_builder.module.osm.OsmDatabase; -import org.opentripplanner.openstreetmap.model.OSMMemberType; -import org.opentripplanner.openstreetmap.model.OSMNode; -import org.opentripplanner.openstreetmap.model.OSMRelation; -import org.opentripplanner.openstreetmap.model.OSMRelationMember; -import org.opentripplanner.openstreetmap.model.OSMTag; -import org.opentripplanner.openstreetmap.model.OSMWay; +import org.opentripplanner.osm.model.OsmMemberType; +import org.opentripplanner.osm.model.OsmNode; +import org.opentripplanner.osm.model.OsmRelation; +import org.opentripplanner.osm.model.OsmRelationMember; +import org.opentripplanner.osm.model.OsmTag; +import org.opentripplanner.osm.model.OsmWay; /** * Parser for the OpenStreetMap PBF Format. * * @since 0.4 */ -class OpenStreetMapParser extends BinaryParser { +class OsmParser extends BinaryParser { private final OsmDatabase osmdb; private final Map stringTable = new HashMap<>(); private final OsmProvider provider; private OsmParserPhase parsePhase; - public OpenStreetMapParser(OsmDatabase osmdb, OsmProvider provider) { + public OsmParser(OsmDatabase osmdb, OsmProvider provider) { this.osmdb = Objects.requireNonNull(osmdb); this.provider = Objects.requireNonNull(provider); } @@ -63,12 +63,12 @@ protected void parseRelations(List rels) { } for (Osmformat.Relation i : rels) { - OSMRelation tmp = new OSMRelation(); + OsmRelation tmp = new OsmRelation(); tmp.setId(i.getId()); tmp.setOsmProvider(provider); for (int j = 0; j < i.getKeysCount(); j++) { - OSMTag tag = new OSMTag(); + OsmTag tag = new OsmTag(); String key = internalize(getStringById(i.getKeys(j))); String value = internalize(getStringById(i.getVals(j))); tag.setK(key); @@ -78,7 +78,7 @@ protected void parseRelations(List rels) { long lastMid = 0; for (int j = 0; j < i.getMemidsCount(); j++) { - OSMRelationMember relMember = new OSMRelationMember(); + OsmRelationMember relMember = new OsmRelationMember(); long mid = lastMid + i.getMemids(j); relMember.setRef(mid); @@ -87,11 +87,11 @@ protected void parseRelations(List rels) { relMember.setRole(internalize(getStringById(i.getRolesSid(j)))); if (i.getTypes(j) == Osmformat.Relation.MemberType.NODE) { - relMember.setType(OSMMemberType.NODE); + relMember.setType(OsmMemberType.NODE); } else if (i.getTypes(j) == Osmformat.Relation.MemberType.WAY) { - relMember.setType(OSMMemberType.WAY); + relMember.setType(OsmMemberType.WAY); } else if (i.getTypes(j) == Osmformat.Relation.MemberType.RELATION) { - relMember.setType(OSMMemberType.RELATION); + relMember.setType(OsmMemberType.RELATION); } else { assert false; // TODO; Illegal file? } @@ -113,7 +113,7 @@ protected void parseDense(Osmformat.DenseNodes nodes) { } for (int i = 0; i < nodes.getIdCount(); i++) { - OSMNode tmp = new OSMNode(); + OsmNode tmp = new OsmNode(); long lat = nodes.getLat(i) + lastLat; lastLat = lat; @@ -134,7 +134,7 @@ protected void parseDense(Osmformat.DenseNodes nodes) { int keyid = nodes.getKeysVals(j++); int valid = nodes.getKeysVals(j++); - OSMTag tag = new OSMTag(); + OsmTag tag = new OsmTag(); String key = internalize(getStringById(keyid)); String value = internalize(getStringById(valid)); tag.setK(key); @@ -155,7 +155,7 @@ protected void parseNodes(List nodes) { } for (Osmformat.Node i : nodes) { - OSMNode tmp = new OSMNode(); + OsmNode tmp = new OsmNode(); tmp.setId(i.getId()); tmp.setOsmProvider(provider); tmp.lat = parseLat(i.getLat()); @@ -165,7 +165,7 @@ protected void parseNodes(List nodes) { String key = internalize(getStringById(i.getKeys(j))); // if handler.retain_tag(key) // TODO: filter tags String value = internalize(getStringById(i.getVals(j))); - OSMTag tag = new OSMTag(); + OsmTag tag = new OsmTag(); tag.setK(key); tag.setV(value); tmp.addTag(tag); @@ -182,12 +182,12 @@ protected void parseWays(List ways) { } for (Osmformat.Way i : ways) { - OSMWay tmp = new OSMWay(); + OsmWay tmp = new OsmWay(); tmp.setId(i.getId()); tmp.setOsmProvider(provider); for (int j = 0; j < i.getKeysCount(); j++) { - OSMTag tag = new OSMTag(); + OsmTag tag = new OsmTag(); String key = internalize(getStringById(i.getKeys(j))); String value = internalize(getStringById(i.getVals(j))); tag.setK(key); diff --git a/src/main/java/org/opentripplanner/openstreetmap/OsmParserPhase.java b/application/src/main/java/org/opentripplanner/osm/OsmParserPhase.java similarity index 56% rename from src/main/java/org/opentripplanner/openstreetmap/OsmParserPhase.java rename to application/src/main/java/org/opentripplanner/osm/OsmParserPhase.java index 00b22aaa599..f4b1125aaea 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/OsmParserPhase.java +++ b/application/src/main/java/org/opentripplanner/osm/OsmParserPhase.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap; +package org.opentripplanner.osm; enum OsmParserPhase { Relations, diff --git a/src/main/java/org/opentripplanner/openstreetmap/OsmProvider.java b/application/src/main/java/org/opentripplanner/osm/OsmProvider.java similarity index 87% rename from src/main/java/org/opentripplanner/openstreetmap/OsmProvider.java rename to application/src/main/java/org/opentripplanner/osm/OsmProvider.java index e35a846cbbd..597fd516b0e 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/OsmProvider.java +++ b/application/src/main/java/org/opentripplanner/osm/OsmProvider.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap; +package org.opentripplanner.osm; import java.io.ByteArrayInputStream; import java.io.File; @@ -10,13 +10,13 @@ import org.opentripplanner.datastore.api.FileType; import org.opentripplanner.datastore.file.FileDataSource; import org.opentripplanner.framework.application.OtpFileNames; -import org.opentripplanner.framework.logging.ProgressTracker; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.module.osm.OsmDatabase; -import org.opentripplanner.openstreetmap.tagmapping.OsmTagMapper; -import org.opentripplanner.openstreetmap.tagmapping.OsmTagMapperSource; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; +import org.opentripplanner.osm.tagmapping.OsmTagMapper; +import org.opentripplanner.osm.tagmapping.OsmTagMapperSource; +import org.opentripplanner.osm.wayproperty.WayPropertySet; +import org.opentripplanner.utils.logging.ProgressTracker; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,9 +66,9 @@ public OsmProvider( this.cacheDataInMem = cacheDataInMem; } - public void readOSM(OsmDatabase osmdb) { + public void readOsm(OsmDatabase osmdb) { try { - OpenStreetMapParser parser = new OpenStreetMapParser(osmdb, this); + OsmParser parser = new OsmParser(osmdb, this); parsePhase(parser, OsmParserPhase.Relations); osmdb.doneFirstPhaseRelations(); @@ -105,7 +105,7 @@ private static InputStream track(OsmParserPhase phase, long size, InputStream in return ProgressTracker.track("Parse OSM " + phase, 1000, size, inputStream, m -> LOG.info(m)); } - private void parsePhase(OpenStreetMapParser parser, OsmParserPhase phase) throws IOException { + private void parsePhase(OsmParser parser, OsmParserPhase phase) throws IOException { parser.setPhase(phase); BlockInputStream in = null; try { diff --git a/src/main/java/org/opentripplanner/openstreetmap/issues/FloorNumberUnknownAssumedGroundLevel.java b/application/src/main/java/org/opentripplanner/osm/issues/FloorNumberUnknownAssumedGroundLevel.java similarity index 83% rename from src/main/java/org/opentripplanner/openstreetmap/issues/FloorNumberUnknownAssumedGroundLevel.java rename to application/src/main/java/org/opentripplanner/osm/issues/FloorNumberUnknownAssumedGroundLevel.java index bc7adeb07bd..c468f7dbd52 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/issues/FloorNumberUnknownAssumedGroundLevel.java +++ b/application/src/main/java/org/opentripplanner/osm/issues/FloorNumberUnknownAssumedGroundLevel.java @@ -1,9 +1,9 @@ -package org.opentripplanner.openstreetmap.issues; +package org.opentripplanner.osm.issues; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; -public record FloorNumberUnknownAssumedGroundLevel(String layer, OSMWithTags entity) +public record FloorNumberUnknownAssumedGroundLevel(String layer, OsmWithTags entity) implements DataImportIssue { private static final String FMT = "%s : could not determine floor number for layer %s, assumed to be ground-level."; diff --git a/src/main/java/org/opentripplanner/openstreetmap/issues/FloorNumberUnknownGuessedFromAltitude.java b/application/src/main/java/org/opentripplanner/osm/issues/FloorNumberUnknownGuessedFromAltitude.java similarity index 84% rename from src/main/java/org/opentripplanner/openstreetmap/issues/FloorNumberUnknownGuessedFromAltitude.java rename to application/src/main/java/org/opentripplanner/osm/issues/FloorNumberUnknownGuessedFromAltitude.java index 74e7cff3fda..0f4022eb86f 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/issues/FloorNumberUnknownGuessedFromAltitude.java +++ b/application/src/main/java/org/opentripplanner/osm/issues/FloorNumberUnknownGuessedFromAltitude.java @@ -1,12 +1,12 @@ -package org.opentripplanner.openstreetmap.issues; +package org.opentripplanner.osm.issues; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; public record FloorNumberUnknownGuessedFromAltitude( String layer, Integer floorNumber, - OSMWithTags entity + OsmWithTags entity ) implements DataImportIssue { private static final String FMT = diff --git a/src/main/java/org/opentripplanner/openstreetmap/model/OSMLevel.java b/application/src/main/java/org/opentripplanner/osm/model/OsmLevel.java similarity index 85% rename from src/main/java/org/opentripplanner/openstreetmap/model/OSMLevel.java rename to application/src/main/java/org/opentripplanner/osm/model/OsmLevel.java index 6f121ed0e13..6048260d486 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/model/OSMLevel.java +++ b/application/src/main/java/org/opentripplanner/osm/model/OsmLevel.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap.model; +package org.opentripplanner.osm.model; import java.util.ArrayList; import java.util.HashMap; @@ -7,14 +7,14 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.openstreetmap.issues.FloorNumberUnknownAssumedGroundLevel; -import org.opentripplanner.openstreetmap.issues.FloorNumberUnknownGuessedFromAltitude; +import org.opentripplanner.osm.issues.FloorNumberUnknownAssumedGroundLevel; +import org.opentripplanner.osm.issues.FloorNumberUnknownGuessedFromAltitude; -public class OSMLevel implements Comparable { +public class OsmLevel implements Comparable { public static final Pattern RANGE_PATTERN = Pattern.compile("^[0-9]+-[0-9]+$"); public static final double METERS_PER_FLOOR = 3; - public static final OSMLevel DEFAULT = new OSMLevel( + public static final OsmLevel DEFAULT = new OsmLevel( 0, 0.0, "default level", @@ -29,7 +29,7 @@ public class OSMLevel implements Comparable { public final Source source; public final boolean reliable; - public OSMLevel( + public OsmLevel( int floorNumber, double altitudeMeters, String shortName, @@ -49,12 +49,12 @@ public OSMLevel( * makes an OSMLevel from one of the semicolon-separated fields in an OSM level map relation's * levels= tag. */ - public static OSMLevel fromString( + public static OsmLevel fromString( String spec, Source source, boolean incrementNonNegative, DataImportIssueStore issueStore, - OSMWithTags osmObj + OsmWithTags osmObj ) { /* extract any altitude information after the @ character */ Double altitude = null; @@ -126,15 +126,15 @@ public static OSMLevel fromString( issueStore.add(new FloorNumberUnknownAssumedGroundLevel(spec, osmObj)); reliable = false; } - return new OSMLevel(floorNumber, altitude, shortName, longName, source, reliable); + return new OsmLevel(floorNumber, altitude, shortName, longName, source, reliable); } - public static List fromSpecList( + public static List fromSpecList( String specList, Source source, boolean incrementNonNegative, DataImportIssueStore issueStore, - OSMWithTags osmObj + OsmWithTags osmObj ) { List levelSpecs = new ArrayList<>(); @@ -153,22 +153,22 @@ public static List fromSpecList( } /* build an OSMLevel for each level spec in the list */ - List levels = new ArrayList<>(); + List levels = new ArrayList<>(); for (String spec : levelSpecs) { levels.add(fromString(spec, source, incrementNonNegative, issueStore, osmObj)); } return levels; } - public static Map mapFromSpecList( + public static Map mapFromSpecList( String specList, Source source, boolean incrementNonNegative, DataImportIssueStore issueStore, - OSMWithTags osmObj + OsmWithTags osmObj ) { - Map map = new HashMap<>(); - for (OSMLevel level : fromSpecList( + Map map = new HashMap<>(); + for (OsmLevel level : fromSpecList( specList, source, incrementNonNegative, @@ -181,7 +181,7 @@ public static Map mapFromSpecList( } @Override - public int compareTo(OSMLevel other) { + public int compareTo(OsmLevel other) { return this.floorNumber - other.floorNumber; } @@ -195,10 +195,10 @@ public boolean equals(Object other) { if (other == null) { return false; } - if (!(other instanceof OSMLevel)) { + if (!(other instanceof OsmLevel)) { return false; } - return this.floorNumber == ((OSMLevel) other).floorNumber; + return this.floorNumber == ((OsmLevel) other).floorNumber; } public enum Source { diff --git a/application/src/main/java/org/opentripplanner/osm/model/OsmMemberType.java b/application/src/main/java/org/opentripplanner/osm/model/OsmMemberType.java new file mode 100644 index 00000000000..c27b6e577d1 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/osm/model/OsmMemberType.java @@ -0,0 +1,7 @@ +package org.opentripplanner.osm.model; + +public enum OsmMemberType { + NODE, + WAY, + RELATION, +} diff --git a/src/main/java/org/opentripplanner/openstreetmap/model/OSMNode.java b/application/src/main/java/org/opentripplanner/osm/model/OsmNode.java similarity index 95% rename from src/main/java/org/opentripplanner/openstreetmap/model/OSMNode.java rename to application/src/main/java/org/opentripplanner/osm/model/OsmNode.java index d181cde4564..c5539d1296e 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/model/OSMNode.java +++ b/application/src/main/java/org/opentripplanner/osm/model/OsmNode.java @@ -1,10 +1,10 @@ -package org.opentripplanner.openstreetmap.model; +package org.opentripplanner.osm.model; import java.util.Set; import org.locationtech.jts.geom.Coordinate; import org.opentripplanner.street.model.StreetTraversalPermission; -public class OSMNode extends OSMWithTags { +public class OsmNode extends OsmWithTags { static final Set MOTOR_VEHICLE_BARRIERS = Set.of("bollard", "bar", "chain"); diff --git a/src/main/java/org/opentripplanner/openstreetmap/model/OSMRelation.java b/application/src/main/java/org/opentripplanner/osm/model/OsmRelation.java similarity index 79% rename from src/main/java/org/opentripplanner/openstreetmap/model/OSMRelation.java rename to application/src/main/java/org/opentripplanner/osm/model/OsmRelation.java index e181cf97713..7c6d684ebfd 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/model/OSMRelation.java +++ b/application/src/main/java/org/opentripplanner/osm/model/OsmRelation.java @@ -1,17 +1,17 @@ -package org.opentripplanner.openstreetmap.model; +package org.opentripplanner.osm.model; import java.util.ArrayList; import java.util.List; -public class OSMRelation extends OSMWithTags { +public class OsmRelation extends OsmWithTags { - private final List members = new ArrayList<>(); + private final List members = new ArrayList<>(); - public void addMember(OSMRelationMember member) { + public void addMember(OsmRelationMember member) { members.add(member); } - public List getMembers() { + public List getMembers() { return members; } diff --git a/src/main/java/org/opentripplanner/openstreetmap/model/OSMRelationMember.java b/application/src/main/java/org/opentripplanner/osm/model/OsmRelationMember.java similarity index 72% rename from src/main/java/org/opentripplanner/openstreetmap/model/OSMRelationMember.java rename to application/src/main/java/org/opentripplanner/osm/model/OsmRelationMember.java index e2ad2ff9691..0cf1118f59f 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/model/OSMRelationMember.java +++ b/application/src/main/java/org/opentripplanner/osm/model/OsmRelationMember.java @@ -1,20 +1,20 @@ -package org.opentripplanner.openstreetmap.model; +package org.opentripplanner.osm.model; -import static org.opentripplanner.openstreetmap.model.OSMMemberType.WAY; +import static org.opentripplanner.osm.model.OsmMemberType.WAY; -public class OSMRelationMember { +public class OsmRelationMember { - private OSMMemberType type; + private OsmMemberType type; private long ref; private String role; - public OSMMemberType getType() { + public OsmMemberType getType() { return type; } - public void setType(OSMMemberType type) { + public void setType(OsmMemberType type) { this.type = type; } diff --git a/src/main/java/org/opentripplanner/openstreetmap/model/OSMTag.java b/application/src/main/java/org/opentripplanner/osm/model/OsmTag.java similarity index 71% rename from src/main/java/org/opentripplanner/openstreetmap/model/OSMTag.java rename to application/src/main/java/org/opentripplanner/osm/model/OsmTag.java index 40bfe1e8560..a0f90c01ab5 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/model/OSMTag.java +++ b/application/src/main/java/org/opentripplanner/osm/model/OsmTag.java @@ -1,13 +1,13 @@ -package org.opentripplanner.openstreetmap.model; +package org.opentripplanner.osm.model; -public class OSMTag { +public class OsmTag { private String k; private String v; - public OSMTag() {} + public OsmTag() {} - public OSMTag(String k, String v) { + public OsmTag(String k, String v) { this.k = k; this.v = v; } diff --git a/src/main/java/org/opentripplanner/openstreetmap/model/OSMWay.java b/application/src/main/java/org/opentripplanner/osm/model/OsmWay.java similarity index 91% rename from src/main/java/org/opentripplanner/openstreetmap/model/OSMWay.java rename to application/src/main/java/org/opentripplanner/osm/model/OsmWay.java index b1e90044bf2..7b5fbe56748 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/model/OSMWay.java +++ b/application/src/main/java/org/opentripplanner/osm/model/OsmWay.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap.model; +package org.opentripplanner.osm.model; import gnu.trove.list.TLongList; import gnu.trove.list.array.TLongArrayList; @@ -6,7 +6,7 @@ import org.opentripplanner.graph_builder.module.osm.StreetTraversalPermissionPair; import org.opentripplanner.street.model.StreetTraversalPermission; -public class OSMWay extends OSMWithTags { +public class OsmWay extends OsmWithTags { private static final Set ESCALATOR_CONVEYING_TAGS = Set.of( "yes", @@ -14,6 +14,7 @@ public class OSMWay extends OSMWithTags { "backward", "reversible" ); + private final TLongList nodes = new TLongArrayList(); public void addNodeRef(long nodeRef) { @@ -137,8 +138,23 @@ public boolean isBackwardEscalator() { return isEscalator() && "backward".equals(this.getTag("conveying")); } - public boolean isArea() { - return isTag("area", "yes"); + /** + * Returns true if the way is considered an area. + * + * An area can be specified as such, or be one by default as an amenity. + */ + public boolean isRoutableArea() { + return ( + !isTag("area", "no") && + ( + isTag("area", "yes") || + isParking() || + isBikeParking() || + isBoardingArea() || + isIndoorRoutable() + ) && + getNodeRefs().size() > 2 + ); } /** diff --git a/src/main/java/org/opentripplanner/openstreetmap/model/OSMWithTags.java b/application/src/main/java/org/opentripplanner/osm/model/OsmWithTags.java similarity index 91% rename from src/main/java/org/opentripplanner/openstreetmap/model/OSMWithTags.java rename to application/src/main/java/org/opentripplanner/osm/model/OsmWithTags.java index b53739bf6a1..67f737e4c79 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/model/OSMWithTags.java +++ b/application/src/main/java/org/opentripplanner/osm/model/OsmWithTags.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap.model; +package org.opentripplanner.osm.model; import java.util.Arrays; import java.util.HashMap; @@ -11,21 +11,20 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.framework.i18n.TranslatedString; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.graph_builder.module.osm.OsmModule; -import org.opentripplanner.openstreetmap.OsmProvider; +import org.opentripplanner.osm.OsmProvider; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.transit.model.basic.Accessibility; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A base class for OSM entities containing common methods. */ -public class OSMWithTags { +public class OsmWithTags { /** * highway=* values that we don't want to even consider when building the graph. @@ -46,8 +45,11 @@ public class OSMWithTags { "escape" ); + private static final Set INDOOR_ROUTABLE_VALUES = Set.of("corridor", "area"); + private static final Set LEVEL_TAGS = Set.of("level", "layer"); private static final Set DEFAULT_LEVEL = Set.of("0"); + private static final Consumer NO_OP = i -> {}; /* To save memory this is only created when an entity actually has tags. */ private Map tags; @@ -83,7 +85,7 @@ public void setId(long id) { /** * Adds a tag. */ - public void addTag(OSMTag tag) { + public void addTag(OsmTag tag) { if (tags == null) tags = new HashMap<>(); tags.put(tag.getK().toLowerCase(), tag.getV()); @@ -92,7 +94,7 @@ public void addTag(OSMTag tag) { /** * Adds a tag. */ - public OSMWithTags addTag(String key, String value) { + public OsmWithTags addTag(String key, String value) { if (key == null || value == null) { return this; } @@ -199,7 +201,6 @@ public String getTag(String tag) { * * @return A tags value converted to lower case. An empty Optional if tags is not present. */ - @Nonnull public Optional getTagOpt(String network) { return Optional.ofNullable(getTag(network)); } @@ -220,6 +221,33 @@ public OptionalInt getTagAsInt(String tag, Consumer errorHandler) { return OptionalInt.empty(); } + /** + * Some tags are allowed to have values like 55, "true" or "false". + *

+ * "true", "yes" is returned as 1. + *

+ * "false", "no" is returned as 0 + *

+ * Everything else is returned as an emtpy optional. + */ + public OptionalInt parseIntOrBoolean(String tag, Consumer errorHandler) { + var maybeInt = getTagAsInt(tag, NO_OP); + if (maybeInt.isPresent()) { + return maybeInt; + } else { + if (isTagTrue(tag)) { + return OptionalInt.of(1); + } else if (isTagFalse(tag)) { + return OptionalInt.of(0); + } else if (hasTag(tag)) { + errorHandler.accept(getTag(tag)); + return OptionalInt.empty(); + } else { + return OptionalInt.empty(); + } + } + } + /** * Checks is a tag contains the specified value. */ @@ -243,6 +271,7 @@ public boolean isOneOfTags(String key, Set oneOfTags) { * Returns a name-like value for an entity (if one exists). The otp: namespaced tags are created * by {@link OsmModule} */ + @Nullable public I18NString getAssumedName() { if (tags == null) { return null; @@ -275,10 +304,6 @@ public I18NString getAssumedName() { * other language found in OSM tag. */ public Map generateI18NForPattern(String pattern) { - if (pattern == null) { - return null; - } - Map i18n = new HashMap<>(); i18n.put(null, new StringBuffer()); Matcher matcher = Pattern.compile("\\{(.*?)}").matcher(pattern); @@ -292,17 +317,15 @@ public Map generateI18NForPattern(String pattern) { String defKey = matcher.group(1); // scan all translated tags Map i18nTags = getTagsByPrefix(defKey); - if (i18nTags != null) { - for (Map.Entry kv : i18nTags.entrySet()) { - if (!kv.getKey().equals(defKey)) { - String lang = kv.getKey().substring(defKey.length() + 1); - if (!i18n.containsKey(lang)) i18n.put(lang, new StringBuffer(i18n.get(null))); - } + for (Map.Entry kv : i18nTags.entrySet()) { + if (!kv.getKey().equals(defKey)) { + String lang = kv.getKey().substring(defKey.length() + 1); + if (!i18n.containsKey(lang)) i18n.put(lang, new StringBuffer(i18n.get(null))); } } // get the simple value (eg: description=...) String defTag = getTag(defKey); - if (defTag == null && i18nTags != null && i18nTags.size() != 0) { + if (defTag == null && !i18nTags.isEmpty()) { defTag = i18nTags.values().iterator().next(); } // get the translated value, if exists @@ -320,7 +343,7 @@ public Map generateI18NForPattern(String pattern) { return out; } - public Map getTagsByPrefix(String prefix) { + private Map getTagsByPrefix(String prefix) { Map out = new HashMap<>(); for (Map.Entry entry : tags.entrySet()) { String k = entry.getKey(); @@ -328,9 +351,6 @@ public Map getTagsByPrefix(String prefix) { out.put(k, entry.getValue()); } } - if (out.isEmpty()) { - return null; - } return out; } @@ -423,6 +443,13 @@ public boolean isPedestrianExplicitlyAllowed() { return doesTagAllowAccess("foot"); } + /** + * @return True if this node / area is a parking. + */ + public boolean isParking() { + return isTag("amenity", "parking"); + } + /** * @return True if this node / area is a park and ride. */ @@ -430,7 +457,7 @@ public boolean isParkAndRide() { String parkingType = getTag("parking"); String parkAndRide = getTag("park_ride"); return ( - isTag("amenity", "parking") && + isParking() && ( (parkingType != null && parkingType.contains("park_and_ride")) || (parkAndRide != null && !parkAndRide.equalsIgnoreCase("no")) @@ -504,6 +531,7 @@ public void setCreativeName(I18NString creativeName) { this.creativeName = creativeName; } + @Nullable public String url() { return null; } @@ -513,7 +541,6 @@ public String url() { *

* Values are split by semicolons. */ - @Nonnull public Set getMultiTagValues(Set refTags) { return refTags .stream() @@ -542,7 +569,7 @@ public void setOsmProvider(OsmProvider provider) { public boolean isRoutable() { if (isOneOfTags("highway", NON_ROUTABLE_HIGHWAYS)) { return false; - } else if (hasTag("highway") || isPlatform()) { + } else if (hasTag("highway") || isPlatform() || isIndoorRoutable()) { if (isGeneralAccessDenied()) { // There are exceptions. return ( @@ -559,6 +586,10 @@ public boolean isRoutable() { return false; } + public boolean isIndoorRoutable() { + return isOneOfTags("indoor", INDOOR_ROUTABLE_VALUES); + } + /** * Is this a link to another road, like a highway ramp. */ @@ -593,7 +624,7 @@ public boolean isNamed() { * Perhaps this entity has a name that isn't in the source data, but it's also possible that * it's explicitly tagged as not having one. * - * @see OSMWithTags#isExplicitlyUnnamed() + * @see OsmWithTags#isExplicitlyUnnamed() */ public boolean hasNoName() { return !isNamed(); @@ -603,7 +634,7 @@ public boolean hasNoName() { * Whether this entity explicitly doesn't have a name. This is different to no name being * set on the entity in OSM. * - * @see OSMWithTags#isNamed() + * @see OsmWithTags#isNamed() * @see https://wiki.openstreetmap.org/wiki/Tag:noname%3Dyes */ public boolean isExplicitlyUnnamed() { @@ -622,7 +653,6 @@ private boolean isTagDeniedAccess(String tagName) { * Returns level tag (i.e. building floor) or layer tag values, defaults to "0" * Some entities can have a semicolon separated list of levels (e.g. elevators) */ - @Nonnull public Set getLevels() { var levels = getMultiTagValues(LEVEL_TAGS); if (levels.isEmpty()) { diff --git a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/AtlantaMapper.java b/application/src/main/java/org/opentripplanner/osm/tagmapping/AtlantaMapper.java similarity index 70% rename from src/main/java/org/opentripplanner/openstreetmap/tagmapping/AtlantaMapper.java rename to application/src/main/java/org/opentripplanner/osm/tagmapping/AtlantaMapper.java index f9539188904..34ba62a1daa 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/AtlantaMapper.java +++ b/application/src/main/java/org/opentripplanner/osm/tagmapping/AtlantaMapper.java @@ -1,9 +1,9 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; -import static org.opentripplanner.openstreetmap.wayproperty.WayPropertiesBuilder.withModes; +import static org.opentripplanner.osm.wayproperty.WayPropertiesBuilder.withModes; import static org.opentripplanner.street.model.StreetTraversalPermission.ALL; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; +import org.opentripplanner.osm.wayproperty.WayPropertySet; /** * OSM way properties for the Atlanta, Georgia, USA area. @@ -13,10 +13,9 @@ * * @author demory * @see OsmTagMapper - * @see DefaultMapper */ -class AtlantaMapper implements OsmTagMapper { +class AtlantaMapper extends OsmTagMapper { @Override public void populateProperties(WayPropertySet props) { @@ -27,7 +26,6 @@ public void populateProperties(WayPropertySet props) { // Max speed limit in Georgia is 70 mph ~= 113kmh ~= 31.3m/s props.maxPossibleCarSpeed = 31.4f; - // Read the rest from the default set - new DefaultMapper().populateProperties(props); + super.populateProperties(props); } } diff --git a/application/src/main/java/org/opentripplanner/osm/tagmapping/ConstantSpeedMapper.java b/application/src/main/java/org/opentripplanner/osm/tagmapping/ConstantSpeedMapper.java new file mode 100644 index 00000000000..e2ecb998159 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/osm/tagmapping/ConstantSpeedMapper.java @@ -0,0 +1,45 @@ +package org.opentripplanner.osm.tagmapping; + +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.WayPropertySet; + +/** + * OSM way properties for optimizing distance (not traveling time) in routing. + */ +class ConstantSpeedFinlandMapper extends FinlandMapper { + + private float speed; + + public ConstantSpeedFinlandMapper() { + super(); + this.speed = 22.22f; // 80 kmph by default + } + + public ConstantSpeedFinlandMapper(float speed) { + super(); + this.speed = speed; + } + + @Override + public void populateProperties(WayPropertySet props) { + props.setCarSpeed("highway=*", speed); + super.populateProperties(props); + props.maxPossibleCarSpeed = speed; + } + + @Override + public float getCarSpeedForWay(OsmWithTags way, boolean backward) { + /* + * Set the same 80 km/h speed for all roads, so that car routing finds shortest path + */ + return speed; + } + + @Override + public Float getMaxUsedCarSpeed(WayPropertySet wayPropertySet) { + // This is needed because the way property set uses normal speed limits from Finland mapper + // to set the walk safety limits which resets the maximum used car speed to be something else + // than what is used for the street edge car speeds. + return speed; + } +} diff --git a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/FinlandMapper.java b/application/src/main/java/org/opentripplanner/osm/tagmapping/FinlandMapper.java similarity index 89% rename from src/main/java/org/opentripplanner/openstreetmap/tagmapping/FinlandMapper.java rename to application/src/main/java/org/opentripplanner/osm/tagmapping/FinlandMapper.java index 5ea949e8d5c..d9ddd1ede76 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/FinlandMapper.java +++ b/application/src/main/java/org/opentripplanner/osm/tagmapping/FinlandMapper.java @@ -1,16 +1,17 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; -import static org.opentripplanner.openstreetmap.wayproperty.MixinPropertiesBuilder.ofWalkSafety; -import static org.opentripplanner.openstreetmap.wayproperty.WayPropertiesBuilder.withModes; +import static org.opentripplanner.osm.wayproperty.MixinPropertiesBuilder.ofWalkSafety; +import static org.opentripplanner.osm.wayproperty.WayPropertiesBuilder.withModes; import static org.opentripplanner.street.model.StreetTraversalPermission.ALL; import static org.opentripplanner.street.model.StreetTraversalPermission.CAR; import static org.opentripplanner.street.model.StreetTraversalPermission.NONE; import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN; import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN_AND_BICYCLE; +import java.util.Set; import org.opentripplanner.framework.functional.FunctionUtils.TriFunction; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.WayPropertySet; import org.opentripplanner.street.model.StreetTraversalPermission; /** @@ -23,13 +24,20 @@ * * @author juusokor * @see OsmTagMapper - * @see DefaultMapper */ -class FinlandMapper implements OsmTagMapper { +class FinlandMapper extends OsmTagMapper { + + private static final Set NOTHROUGH_DRIVING_TAGS = Set.of( + "parking_aisle", + "driveway", + "alley", + "emergency_access", + "drive-through" + ); @Override public void populateProperties(WayPropertySet props) { - TriFunction defaultWalkSafetyForPermission = ( + TriFunction defaultWalkSafetyForPermission = ( permission, speedLimit, way @@ -76,9 +84,6 @@ else if (speedLimit <= 16.65f) { // Don't recommend walking in trunk road tunnels props.setProperties("highway=trunk;tunnel=yes", withModes(CAR).bicycleSafety(7.47)); - // Do not walk on "moottoriliikennetie" - props.setProperties("motorroad=yes", withModes(CAR).bicycleSafety(7.47)); - // Remove informal and private roads props.setProperties("highway=*;informal=yes", withModes(NONE)); props.setProperties("highway=service;access=private", withModes(NONE)); @@ -203,12 +208,11 @@ else if (speedLimit <= 16.65f) { // ~= 16 kph props.setCarSpeed("highway=track", 4.5f); - // Read the rest from the default set - new DefaultMapper().populateProperties(props); + super.populateProperties(props); } @Override - public boolean isBicycleNoThroughTrafficExplicitlyDisallowed(OSMWithTags way) { + public boolean isBicycleThroughTrafficExplicitlyDisallowed(OsmWithTags way) { String bicycle = way.getTag("bicycle"); return ( isVehicleThroughTrafficExplicitlyDisallowed(way) || @@ -217,8 +221,16 @@ public boolean isBicycleNoThroughTrafficExplicitlyDisallowed(OSMWithTags way) { } @Override - public boolean isWalkNoThroughTrafficExplicitlyDisallowed(OSMWithTags way) { + public boolean isWalkThroughTrafficExplicitlyDisallowed(OsmWithTags way) { String foot = way.getTag("foot"); return isGeneralNoThroughTraffic(way) || doesTagValueDisallowThroughTraffic(foot); } + + @Override + public boolean isMotorVehicleThroughTrafficExplicitlyDisallowed(OsmWithTags way) { + if (super.isMotorVehicleThroughTrafficExplicitlyDisallowed(way)) { + return true; + } + return way.isOneOfTags("service", NOTHROUGH_DRIVING_TAGS); + } } diff --git a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/GermanyMapper.java b/application/src/main/java/org/opentripplanner/osm/tagmapping/GermanyMapper.java similarity index 89% rename from src/main/java/org/opentripplanner/openstreetmap/tagmapping/GermanyMapper.java rename to application/src/main/java/org/opentripplanner/osm/tagmapping/GermanyMapper.java index 908d9838f53..af56b572bd8 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/GermanyMapper.java +++ b/application/src/main/java/org/opentripplanner/osm/tagmapping/GermanyMapper.java @@ -1,13 +1,13 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; -import static org.opentripplanner.openstreetmap.wayproperty.MixinPropertiesBuilder.ofBicycleSafety; -import static org.opentripplanner.openstreetmap.wayproperty.WayPropertiesBuilder.withModes; +import static org.opentripplanner.osm.wayproperty.MixinPropertiesBuilder.ofBicycleSafety; +import static org.opentripplanner.osm.wayproperty.WayPropertiesBuilder.withModes; import static org.opentripplanner.street.model.StreetTraversalPermission.ALL; import static org.opentripplanner.street.model.StreetTraversalPermission.BICYCLE_AND_CAR; import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN; import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN_AND_BICYCLE; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; +import org.opentripplanner.osm.wayproperty.WayPropertySet; /** * OSM way properties for German roads. Speed limits where adjusted to German regulation and some @@ -15,9 +15,8 @@ * networks. * * @see OsmTagMapper - * @see DefaultMapper */ -class GermanyMapper implements OsmTagMapper { +class GermanyMapper extends OsmTagMapper { @Override public void populateProperties(WayPropertySet props) { @@ -88,7 +87,6 @@ public void populateProperties(WayPropertySet props) { props.setProperties("highway=unclassified;cycleway=lane", withModes(ALL).bicycleSafety(0.87)); - // Read the rest from the default set - new DefaultMapper().populateProperties(props); + super.populateProperties(props); } } diff --git a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/HamburgMapper.java b/application/src/main/java/org/opentripplanner/osm/tagmapping/HamburgMapper.java similarity index 69% rename from src/main/java/org/opentripplanner/openstreetmap/tagmapping/HamburgMapper.java rename to application/src/main/java/org/opentripplanner/osm/tagmapping/HamburgMapper.java index f893fbb5519..755f5864ba2 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/HamburgMapper.java +++ b/application/src/main/java/org/opentripplanner/osm/tagmapping/HamburgMapper.java @@ -1,20 +1,19 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; /** * Modified mapper to allow through traffic for combination access=customers and customers=HVV. * * @see GermanyMapper * @see OsmTagMapper - * @see DefaultMapper * * @author Maintained by HBT (geofox-team@hbt.de) */ public class HamburgMapper extends GermanyMapper { @Override - public boolean isGeneralNoThroughTraffic(OSMWithTags way) { + public boolean isGeneralNoThroughTraffic(OsmWithTags way) { String access = way.getTag("access"); boolean isNoThroughTraffic = doesTagValueDisallowThroughTraffic(access); diff --git a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/HoustonMapper.java b/application/src/main/java/org/opentripplanner/osm/tagmapping/HoustonMapper.java similarity index 67% rename from src/main/java/org/opentripplanner/openstreetmap/tagmapping/HoustonMapper.java rename to application/src/main/java/org/opentripplanner/osm/tagmapping/HoustonMapper.java index 7fdde133465..1d24dbafffb 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/HoustonMapper.java +++ b/application/src/main/java/org/opentripplanner/osm/tagmapping/HoustonMapper.java @@ -1,10 +1,10 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; -import static org.opentripplanner.openstreetmap.wayproperty.WayPropertiesBuilder.withModes; +import static org.opentripplanner.osm.wayproperty.WayPropertiesBuilder.withModes; import static org.opentripplanner.street.model.StreetTraversalPermission.NONE; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; -import org.opentripplanner.openstreetmap.wayproperty.specifier.ExactMatchSpecifier; +import org.opentripplanner.osm.wayproperty.WayPropertySet; +import org.opentripplanner.osm.wayproperty.specifier.ExactMatchSpecifier; /** * OSM way properties for the Houston, Texas, USA area. @@ -14,7 +14,7 @@ * 1. In Houston we want to disallow usage of downtown pedestrian tunnel system. */ -class HoustonMapper implements OsmTagMapper { +class HoustonMapper extends OsmTagMapper { @Override public void populateProperties(WayPropertySet props) { @@ -26,11 +26,9 @@ public void populateProperties(WayPropertySet props) { new ExactMatchSpecifier("highway=footway;layer=-1;tunnel=yes;indoor=yes"), withModes(NONE) ); - // Max speed limit in Texas is 38 m/s ~= 85 mph ~= 137 kph props.maxPossibleCarSpeed = 38f; - // Read the rest from the default set - new DefaultMapper().populateProperties(props); + super.populateProperties(props); } } diff --git a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/NorwayMapper.java b/application/src/main/java/org/opentripplanner/osm/tagmapping/NorwayMapper.java similarity index 95% rename from src/main/java/org/opentripplanner/openstreetmap/tagmapping/NorwayMapper.java rename to application/src/main/java/org/opentripplanner/osm/tagmapping/NorwayMapper.java index efe7850f08b..c37de8533c6 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/NorwayMapper.java +++ b/application/src/main/java/org/opentripplanner/osm/tagmapping/NorwayMapper.java @@ -1,8 +1,8 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; -import static org.opentripplanner.openstreetmap.wayproperty.MixinPropertiesBuilder.ofBicycleSafety; -import static org.opentripplanner.openstreetmap.wayproperty.MixinPropertiesBuilder.ofWalkSafety; -import static org.opentripplanner.openstreetmap.wayproperty.WayPropertiesBuilder.withModes; +import static org.opentripplanner.osm.wayproperty.MixinPropertiesBuilder.ofBicycleSafety; +import static org.opentripplanner.osm.wayproperty.MixinPropertiesBuilder.ofWalkSafety; +import static org.opentripplanner.osm.wayproperty.WayPropertiesBuilder.withModes; import static org.opentripplanner.street.model.StreetTraversalPermission.ALL; import static org.opentripplanner.street.model.StreetTraversalPermission.CAR; import static org.opentripplanner.street.model.StreetTraversalPermission.NONE; @@ -10,12 +10,12 @@ import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN_AND_BICYCLE; import java.util.function.BiFunction; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; -import org.opentripplanner.openstreetmap.wayproperty.specifier.BestMatchSpecifier; -import org.opentripplanner.openstreetmap.wayproperty.specifier.Condition; -import org.opentripplanner.openstreetmap.wayproperty.specifier.ExactMatchSpecifier; -import org.opentripplanner.openstreetmap.wayproperty.specifier.LogicalOrSpecifier; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.WayPropertySet; +import org.opentripplanner.osm.wayproperty.specifier.BestMatchSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.Condition; +import org.opentripplanner.osm.wayproperty.specifier.ExactMatchSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.LogicalOrSpecifier; /** * OSM way properties for Norwegian roads. The main difference compared to the default property set @@ -24,9 +24,9 @@ * * @author seime * @see OsmTagMapper - * @see DefaultMapper + * @see OsmTagMapper */ -class NorwayMapper implements OsmTagMapper { +class NorwayMapper extends OsmTagMapper { @Override public void populateProperties(WayPropertySet props) { @@ -121,7 +121,7 @@ else if (speedLimit >= 11.1f) { "residential" ); - BiFunction cycleSafetyHighway = (speedLimit, way) -> { + BiFunction cycleSafetyHighway = (speedLimit, way) -> { if (way.isPedestrianExplicitlyDenied()) { return cycleSafetyVeryHighTraffic; } @@ -621,7 +621,7 @@ else if (speedLimit >= 11.1f) { props.defaultCarSpeed = 22.22f; // 80 km/h props.maxPossibleCarSpeed = 30.56f; // 110 km/h - new DefaultMapper().populateNotesAndNames(props); + super.populateNotesAndNames(props); props.setSlopeOverride(new BestMatchSpecifier("bridge=*"), true); props.setSlopeOverride(new BestMatchSpecifier("cutting=*"), true); diff --git a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/DefaultMapper.java b/application/src/main/java/org/opentripplanner/osm/tagmapping/OsmTagMapper.java similarity index 90% rename from src/main/java/org/opentripplanner/openstreetmap/tagmapping/DefaultMapper.java rename to application/src/main/java/org/opentripplanner/osm/tagmapping/OsmTagMapper.java index c5d1c0d1582..55bc87f5cad 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/DefaultMapper.java +++ b/application/src/main/java/org/opentripplanner/osm/tagmapping/OsmTagMapper.java @@ -1,8 +1,8 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; -import static org.opentripplanner.openstreetmap.wayproperty.MixinPropertiesBuilder.ofBicycleSafety; -import static org.opentripplanner.openstreetmap.wayproperty.MixinPropertiesBuilder.ofWalkSafety; -import static org.opentripplanner.openstreetmap.wayproperty.WayPropertiesBuilder.withModes; +import static org.opentripplanner.osm.wayproperty.MixinPropertiesBuilder.ofBicycleSafety; +import static org.opentripplanner.osm.wayproperty.MixinPropertiesBuilder.ofWalkSafety; +import static org.opentripplanner.osm.wayproperty.WayPropertiesBuilder.withModes; import static org.opentripplanner.street.model.StreetTraversalPermission.ALL; import static org.opentripplanner.street.model.StreetTraversalPermission.BICYCLE_AND_CAR; import static org.opentripplanner.street.model.StreetTraversalPermission.CAR; @@ -10,10 +10,12 @@ import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN; import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN_AND_BICYCLE; -import org.opentripplanner.openstreetmap.wayproperty.WayProperties; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; -import org.opentripplanner.openstreetmap.wayproperty.specifier.BestMatchSpecifier; -import org.opentripplanner.openstreetmap.wayproperty.specifier.LogicalOrSpecifier; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.WayProperties; +import org.opentripplanner.osm.wayproperty.WayPropertySet; +import org.opentripplanner.osm.wayproperty.specifier.BestMatchSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.ExactMatchSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.LogicalOrSpecifier; import org.opentripplanner.routing.services.notes.StreetNotesService; /** @@ -38,12 +40,11 @@ * prevailing 'props.setProperties' statement) has a 'foot=yes' tag the permissions are overridden * and walking is allowed on that way. *

- * TODO clarify why this needs a separate factory interface. * * @author bdferris, novalis - * @see OsmTagMapper */ -class DefaultMapper implements OsmTagMapper { + +public class OsmTagMapper { /* Populate properties on existing WayPropertySet */ public void populateProperties(WayPropertySet props) { @@ -102,6 +103,10 @@ public void populateProperties(WayPropertySet props) { props.setProperties("highway=trunk", withModes(CAR).bicycleSafety(7.47)); props.setProperties("highway=motorway", withModes(CAR).bicycleSafety(8)); + // Do not walk on "moottoriliikennetie"/"Kraftfahrstrasse"/"Limited access road" + // https://en.wikipedia.org/wiki/Limited-access_road + props.setProperties(new ExactMatchSpecifier("motorroad=yes"), withModes(CAR)); + /* cycleway=lane */ props.setProperties( "highway=*;cycleway=lane", @@ -405,7 +410,7 @@ public void populateProperties(WayPropertySet props) { withModes(PEDESTRIAN_AND_BICYCLE).bicycleSafety(0.75) ); props.setProperties( - "highway=footway;bicycle=yes;area=yes", + new ExactMatchSpecifier("highway=footway;bicycle=yes;area=yes"), withModes(PEDESTRIAN_AND_BICYCLE).bicycleSafety(0.9) ); props.setProperties( @@ -613,7 +618,10 @@ public void populateProperties(WayPropertySet props) { // slope overrides props.setSlopeOverride(new BestMatchSpecifier("bridge=*"), true); props.setSlopeOverride(new BestMatchSpecifier("embankment=*"), true); + props.setSlopeOverride(new BestMatchSpecifier("cutting=*"), true); props.setSlopeOverride(new BestMatchSpecifier("tunnel=*"), true); + props.setSlopeOverride(new BestMatchSpecifier("location=underground"), true); + props.setSlopeOverride(new BestMatchSpecifier("indoor=yes"), true); } public void populateNotesAndNames(WayPropertySet props) { @@ -715,4 +723,72 @@ public void populateNotesAndNames(WayPropertySet props) { props.createNames("amenity=parking;name=*", "name.park_and_ride_name"); props.createNames("amenity=parking", "name.park_and_ride_station"); } + + public boolean doesTagValueDisallowThroughTraffic(String tagValue) { + return ( + "no".equals(tagValue) || + "destination".equals(tagValue) || + "private".equals(tagValue) || + "customers".equals(tagValue) || + "delivery".equals(tagValue) + ); + } + + public float getCarSpeedForWay(OsmWithTags way, boolean backward) { + return way.getOsmProvider().getWayPropertySet().getCarSpeedForWay(way, backward); + } + + public Float getMaxUsedCarSpeed(WayPropertySet wayPropertySet) { + return wayPropertySet.maxUsedCarSpeed; + } + + public boolean isGeneralNoThroughTraffic(OsmWithTags way) { + String access = way.getTag("access"); + return doesTagValueDisallowThroughTraffic(access); + } + + public boolean isVehicleThroughTrafficExplicitlyDisallowed(OsmWithTags way) { + String vehicle = way.getTag("vehicle"); + if (vehicle != null) { + return doesTagValueDisallowThroughTraffic(vehicle); + } else { + return isGeneralNoThroughTraffic(way); + } + } + + /** + * Returns true if through traffic for motor vehicles is not allowed. + */ + public boolean isMotorVehicleThroughTrafficExplicitlyDisallowed(OsmWithTags way) { + String motorVehicle = way.getTag("motor_vehicle"); + if (motorVehicle != null) { + return doesTagValueDisallowThroughTraffic(motorVehicle); + } else { + return isVehicleThroughTrafficExplicitlyDisallowed(way); + } + } + + /** + * Returns true if through traffic for bicycle is not allowed. + */ + public boolean isBicycleThroughTrafficExplicitlyDisallowed(OsmWithTags way) { + String bicycle = way.getTag("bicycle"); + if (bicycle != null) { + return doesTagValueDisallowThroughTraffic(bicycle); + } else { + return isVehicleThroughTrafficExplicitlyDisallowed(way); + } + } + + /** + * Returns true if through traffic for walk is not allowed. + */ + public boolean isWalkThroughTrafficExplicitlyDisallowed(OsmWithTags way) { + String foot = way.getTag("foot"); + if (foot != null) { + return doesTagValueDisallowThroughTraffic(foot); + } else { + return isGeneralNoThroughTraffic(way); + } + } } diff --git a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/OsmTagMapperSource.java b/application/src/main/java/org/opentripplanner/osm/tagmapping/OsmTagMapperSource.java similarity index 88% rename from src/main/java/org/opentripplanner/openstreetmap/tagmapping/OsmTagMapperSource.java rename to application/src/main/java/org/opentripplanner/osm/tagmapping/OsmTagMapperSource.java index d430ad05f7d..98593ef70d0 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/OsmTagMapperSource.java +++ b/application/src/main/java/org/opentripplanner/osm/tagmapping/OsmTagMapperSource.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; /** * This is the list of {@link OsmTagMapper} sources. The enum provide a mapping between the enum @@ -18,7 +18,7 @@ public enum OsmTagMapperSource { public OsmTagMapper getInstance() { return switch (this) { - case DEFAULT -> new DefaultMapper(); + case DEFAULT -> new OsmTagMapper(); case NORWAY -> new NorwayMapper(); case UK -> new UKMapper(); case FINLAND -> new FinlandMapper(); diff --git a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/PortlandMapper.java b/application/src/main/java/org/opentripplanner/osm/tagmapping/PortlandMapper.java similarity index 77% rename from src/main/java/org/opentripplanner/openstreetmap/tagmapping/PortlandMapper.java rename to application/src/main/java/org/opentripplanner/osm/tagmapping/PortlandMapper.java index 1a09b3b6714..7da8f8ca886 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/PortlandMapper.java +++ b/application/src/main/java/org/opentripplanner/osm/tagmapping/PortlandMapper.java @@ -1,15 +1,15 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; -import static org.opentripplanner.openstreetmap.wayproperty.MixinPropertiesBuilder.ofBicycleSafety; -import static org.opentripplanner.openstreetmap.wayproperty.MixinPropertiesBuilder.ofWalkSafety; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.ExactMatchSpecifier.exact; +import static org.opentripplanner.osm.wayproperty.MixinPropertiesBuilder.ofBicycleSafety; +import static org.opentripplanner.osm.wayproperty.MixinPropertiesBuilder.ofWalkSafety; +import static org.opentripplanner.osm.wayproperty.specifier.ExactMatchSpecifier.exact; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; -import org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.Absent; -import org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.GreaterThan; -import org.opentripplanner.openstreetmap.wayproperty.specifier.ExactMatchSpecifier; +import org.opentripplanner.osm.wayproperty.WayPropertySet; +import org.opentripplanner.osm.wayproperty.specifier.Condition.Absent; +import org.opentripplanner.osm.wayproperty.specifier.Condition.GreaterThan; +import org.opentripplanner.osm.wayproperty.specifier.ExactMatchSpecifier; -class PortlandMapper implements OsmTagMapper { +class PortlandMapper extends OsmTagMapper { @Override public void populateProperties(WayPropertySet props) { @@ -57,7 +57,6 @@ public void populateProperties(WayPropertySet props) { // Max speed limit in Oregon is 70 mph ~= 113kmh ~= 31.3m/s props.maxPossibleCarSpeed = 31.4f; - // Read the rest from the default set - new DefaultMapper().populateProperties(props); + super.populateProperties(props); } } diff --git a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/UKMapper.java b/application/src/main/java/org/opentripplanner/osm/tagmapping/UKMapper.java similarity index 85% rename from src/main/java/org/opentripplanner/openstreetmap/tagmapping/UKMapper.java rename to application/src/main/java/org/opentripplanner/osm/tagmapping/UKMapper.java index 7639c6594b2..35a575b00c8 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/UKMapper.java +++ b/application/src/main/java/org/opentripplanner/osm/tagmapping/UKMapper.java @@ -1,9 +1,11 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; -import static org.opentripplanner.openstreetmap.wayproperty.WayPropertiesBuilder.withModes; +import static org.opentripplanner.osm.wayproperty.WayPropertiesBuilder.withModes; import static org.opentripplanner.street.model.StreetTraversalPermission.ALL; +import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; +import org.opentripplanner.osm.wayproperty.WayProperties; +import org.opentripplanner.osm.wayproperty.WayPropertySet; /** * OSM way properties for UK roads. The main differences compared to the default property set are: @@ -19,9 +21,9 @@ * * @author marcusyoung * @see OsmTagMapper - * @see DefaultMapper + * @see OsmTagMapper */ -class UKMapper implements OsmTagMapper { +class UKMapper extends OsmTagMapper { @Override public void populateProperties(WayPropertySet props) { @@ -73,7 +75,10 @@ public void populateProperties(WayPropertySet props) { props.setCarSpeed("highway=secondary_link", 13.4f); // ~= 30mph props.setCarSpeed("highway=tertiary", 15.7f); // ~= 35mph - // Read the rest from the default set - new DefaultMapper().populateProperties(props); + WayProperties pedestrianWayProperties = withModes(PEDESTRIAN).build(); + props.setProperties("indoor=area", pedestrianWayProperties); + props.setProperties("indoor=corridor", pedestrianWayProperties); + + super.populateProperties(props); } } diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/CreativeNamer.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/CreativeNamer.java similarity index 81% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/CreativeNamer.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/CreativeNamer.java index 24f39399761..87053ddb324 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/CreativeNamer.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/CreativeNamer.java @@ -1,7 +1,7 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; /** * A CreativeNamer makes up names for ways that don't have one in the OSM data set. It does this by @@ -22,7 +22,7 @@ public CreativeNamer(String pattern) { this.creativeNamePattern = pattern; } - public I18NString generateCreativeName(OSMWithTags way) { + public I18NString generateCreativeName(OsmWithTags way) { return LocalizedStringMapper.getInstance().map(creativeNamePattern, way); } } diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/CreativeNamerPicker.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/CreativeNamerPicker.java similarity index 79% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/CreativeNamerPicker.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/CreativeNamerPicker.java index 15ea53c5b1e..5e57456c03a 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/CreativeNamerPicker.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/CreativeNamerPicker.java @@ -1,6 +1,6 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; -import org.opentripplanner.openstreetmap.wayproperty.specifier.OsmSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.OsmSpecifier; /** * Describes how unnamed OSM ways are to be named based on the tags they possess. The CreativeNamer diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/LocalizedStringMapper.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/LocalizedStringMapper.java similarity index 94% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/LocalizedStringMapper.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/LocalizedStringMapper.java index 9ea4268b6b7..50bc407e74d 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/LocalizedStringMapper.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/LocalizedStringMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; @@ -12,7 +12,7 @@ import org.opentripplanner.framework.i18n.LocalizedString; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.framework.resources.ResourceBundleSingleton; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; class LocalizedStringMapper { @@ -45,7 +45,7 @@ static LocalizedStringMapper getInstance() { * from properties Files * @param way OSM way from which tag values are read */ - LocalizedString map(String key, OSMWithTags way) { + LocalizedString map(String key, OsmWithTags way) { List lparams = new ArrayList<>(4); //Which tags do we want from way List tagNames = getTagNames(key); diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/MixinProperties.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/MixinProperties.java similarity index 76% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/MixinProperties.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/MixinProperties.java index fa7cd1db27e..66c550caf10 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/MixinProperties.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/MixinProperties.java @@ -1,6 +1,6 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; -import org.opentripplanner.openstreetmap.wayproperty.specifier.OsmSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.OsmSpecifier; /** * Mixins are like {@link WayProperties} but they only contain walk and bicycle safety features (not diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/MixinPropertiesBuilder.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/MixinPropertiesBuilder.java similarity index 92% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/MixinPropertiesBuilder.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/MixinPropertiesBuilder.java index dd16a28e3ec..a9b20a83864 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/MixinPropertiesBuilder.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/MixinPropertiesBuilder.java @@ -1,6 +1,6 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; -import org.opentripplanner.openstreetmap.wayproperty.specifier.OsmSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.OsmSpecifier; /** * Builder for {@link MixinProperties}. If you don't set the safety features they will have a default diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/NotePicker.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/NotePicker.java similarity index 73% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/NotePicker.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/NotePicker.java index 3d420aafa12..4b442f0ef33 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/NotePicker.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/NotePicker.java @@ -1,6 +1,6 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; -import org.opentripplanner.openstreetmap.wayproperty.specifier.OsmSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.OsmSpecifier; /** * Defines which OSM ways get notes and what kind of notes they get. diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/NoteProperties.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/NoteProperties.java similarity index 84% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/NoteProperties.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/NoteProperties.java index dc5affc1e61..aba20442090 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/NoteProperties.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/NoteProperties.java @@ -1,10 +1,10 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; import java.util.Map; import java.util.regex.Pattern; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.TranslatedString; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; import org.opentripplanner.street.model.note.StreetNote; import org.opentripplanner.street.model.note.StreetNoteAndMatcher; import org.opentripplanner.street.model.note.StreetNoteMatcher; @@ -13,16 +13,16 @@ public class NoteProperties { private static final Pattern patternMatcher = Pattern.compile("\\{(.*?)}"); - public String notePattern; + private final String notePattern; - public StreetNoteMatcher noteMatcher; + private final StreetNoteMatcher noteMatcher; public NoteProperties(String notePattern, StreetNoteMatcher noteMatcher) { this.notePattern = notePattern; this.noteMatcher = noteMatcher; } - public StreetNoteAndMatcher generateNote(OSMWithTags way) { + public StreetNoteAndMatcher generateNote(OsmWithTags way) { I18NString text; //TODO: this could probably be made without patternMatch for {} since all notes (at least currently) have {note} as notePattern if (patternMatcher.matcher(notePattern).matches()) { diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/SafetyFeatures.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/SafetyFeatures.java similarity index 89% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/SafetyFeatures.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/SafetyFeatures.java index ab68fd978c2..e4f03ab3e29 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/SafetyFeatures.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/SafetyFeatures.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; /** * Record that holds forward and back safety factors for cycling or walking. diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/SlopeOverridePicker.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/SlopeOverridePicker.java similarity index 81% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/SlopeOverridePicker.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/SlopeOverridePicker.java index 21b319a3310..5699bbe2533 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/SlopeOverridePicker.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/SlopeOverridePicker.java @@ -1,6 +1,6 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; -import org.opentripplanner.openstreetmap.wayproperty.specifier.OsmSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.OsmSpecifier; public class SlopeOverridePicker { diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/SpeedPicker.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/SpeedPicker.java similarity index 54% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/SpeedPicker.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/SpeedPicker.java index ca75f3858b0..44cdcdf5e08 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/SpeedPicker.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/SpeedPicker.java @@ -1,6 +1,6 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; -import org.opentripplanner.openstreetmap.wayproperty.specifier.OsmSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.OsmSpecifier; /** * Choose a speed that should be applied to a given segment diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/WayProperties.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/WayProperties.java similarity index 93% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/WayProperties.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/WayProperties.java index 4facfd041c8..7171a3cee3c 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/WayProperties.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/WayProperties.java @@ -1,8 +1,7 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; import java.util.Objects; import java.util.Optional; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.street.model.StreetTraversalPermission; @@ -13,7 +12,6 @@ */ public class WayProperties { - @Nonnull private final StreetTraversalPermission permission; @Nullable @@ -31,7 +29,6 @@ public class WayProperties { /** * The value for the bicycle safety. If none has been set a default value of 1 is returned. */ - @Nonnull public SafetyFeatures bicycleSafety() { return Objects.requireNonNullElse(bicycleSafetyFeatures, SafetyFeatures.DEFAULT); } @@ -39,12 +36,10 @@ public SafetyFeatures bicycleSafety() { /** * The value for the walk safety. If none has been set a default value of 1 is returned. */ - @Nonnull public SafetyFeatures walkSafety() { return Objects.requireNonNullElse(walkSafetyFeatures, SafetyFeatures.DEFAULT); } - @Nonnull public StreetTraversalPermission getPermission() { return permission; } @@ -52,7 +47,6 @@ public StreetTraversalPermission getPermission() { /** * An optional value for the walk safety. If none has been set an empty Optional is returned. */ - @Nonnull protected Optional walkSafetyOpt() { return Optional.ofNullable(walkSafetyFeatures); } @@ -60,7 +54,6 @@ protected Optional walkSafetyOpt() { /** * An optional value for the bicycle safety. If none has been set an empty Optional is returned. */ - @Nonnull protected Optional bicycleSafetyOpt() { return Optional.ofNullable(bicycleSafetyFeatures); } diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/WayPropertiesBuilder.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertiesBuilder.java similarity index 98% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/WayPropertiesBuilder.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertiesBuilder.java index b91d1040a7d..505a6f84833 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/WayPropertiesBuilder.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertiesBuilder.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; import javax.annotation.Nullable; import org.opentripplanner.street.model.StreetTraversalPermission; diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/WayPropertyPicker.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertyPicker.java similarity index 69% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/WayPropertyPicker.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertyPicker.java index 351cdcc9911..93407f84357 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/WayPropertyPicker.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertyPicker.java @@ -1,6 +1,6 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; -import org.opentripplanner.openstreetmap.wayproperty.specifier.OsmSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.OsmSpecifier; /** * Associates an OSMSpecifier with some WayProperties. The WayProperties will be applied an OSM way diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/WayPropertySet.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertySet.java similarity index 94% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/WayPropertySet.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertySet.java index 9a414a56080..d8d75e11054 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/WayPropertySet.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/WayPropertySet.java @@ -1,6 +1,6 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; -import static org.opentripplanner.openstreetmap.wayproperty.WayPropertiesBuilder.withModes; +import static org.opentripplanner.osm.wayproperty.WayPropertiesBuilder.withModes; import static org.opentripplanner.street.model.StreetTraversalPermission.ALL; import java.util.ArrayList; @@ -15,9 +15,9 @@ import org.opentripplanner.framework.functional.FunctionUtils.TriFunction; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.specifier.BestMatchSpecifier; -import org.opentripplanner.openstreetmap.wayproperty.specifier.OsmSpecifier; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.specifier.BestMatchSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.OsmSpecifier; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model.note.StreetNoteAndMatcher; import org.opentripplanner.street.model.note.StreetNoteMatcher; @@ -37,7 +37,7 @@ public class WayPropertySet { private static final Logger LOG = LoggerFactory.getLogger(WayPropertySet.class); /** Sets 1.0 as default safety value for all permissions. */ - private final TriFunction DEFAULT_SAFETY_RESOLVER = + private final TriFunction DEFAULT_SAFETY_RESOLVER = ((permission, speedLimit, osmWay) -> 1.0); private final List wayProperties; @@ -64,9 +64,9 @@ public class WayPropertySet { */ public float maxUsedCarSpeed = 0f; /** Resolves walk safety value for each {@link StreetTraversalPermission}. */ - private TriFunction defaultWalkSafetyForPermission; + private TriFunction defaultWalkSafetyForPermission; /** Resolves bicycle safety value for each {@link StreetTraversalPermission}. */ - private TriFunction defaultBicycleSafetyForPermission; + private TriFunction defaultBicycleSafetyForPermission; /** The WayProperties applied to all ways that do not match any WayPropertyPicker. */ private final WayProperties defaultProperties; private final DataImportIssueStore issueStore; @@ -105,7 +105,7 @@ public WayPropertySet(DataImportIssueStore issueStore) { * Applies the WayProperties whose OSMPicker best matches this way. In addition, WayProperties * that are mixins will have their safety values applied if they match at all. */ - public WayProperties getDataForWay(OSMWithTags way) { + public WayProperties getDataForWay(OsmWithTags way) { WayProperties backwardResult = defaultProperties; WayProperties forwardResult = defaultProperties; int bestBackwardScore = 0; @@ -187,7 +187,7 @@ public WayProperties getDataForWay(OSMWithTags way) { return result; } - public I18NString getCreativeNameForWay(OSMWithTags way) { + public I18NString getCreativeNameForWay(OsmWithTags way) { CreativeNamer bestNamer = null; int bestScore = 0; for (CreativeNamerPicker picker : creativeNamers) { @@ -208,7 +208,7 @@ public I18NString getCreativeNameForWay(OSMWithTags way) { /** * Calculate the automobile speed, in meters per second, for this way. */ - public float getCarSpeedForWay(OSMWithTags way, boolean backward) { + public float getCarSpeedForWay(OsmWithTags way, boolean backward) { // first, check for maxspeed tags Float speed = null; Float currentSpeed; @@ -288,7 +288,7 @@ public float getCarSpeedForWay(OSMWithTags way, boolean backward) { } } - public Set getNoteForWay(OSMWithTags way) { + public Set getNoteForWay(OsmWithTags way) { HashSet out = new HashSet<>(); for (NotePicker picker : notes) { OsmSpecifier specifier = picker.specifier; @@ -300,7 +300,7 @@ public Set getNoteForWay(OSMWithTags way) { return out; } - public boolean getSlopeOverride(OSMWithTags way) { + public boolean getSlopeOverride(OsmWithTags way) { boolean result = false; int bestScore = 0; for (SlopeOverridePicker picker : slopeOverrides) { @@ -418,7 +418,7 @@ public void createNotes(String spec, String patternKey, StreetNoteMatcher matche * provide a default for each permission. Safety can vary based on car speed limit on a way. */ public void setDefaultWalkSafetyForPermission( - TriFunction defaultWalkSafetyForPermission + TriFunction defaultWalkSafetyForPermission ) { if (!this.defaultWalkSafetyForPermission.equals(DEFAULT_SAFETY_RESOLVER)) { throw new IllegalStateException("A custom default walk safety resolver was already set"); @@ -431,7 +431,7 @@ public void setDefaultWalkSafetyForPermission( * provide a default for each permission. Safety can vary based on car speed limit on a way. */ public void setDefaultBicycleSafetyForPermission( - TriFunction defaultBicycleSafetyForPermission + TriFunction defaultBicycleSafetyForPermission ) { if (!this.defaultBicycleSafetyForPermission.equals(DEFAULT_SAFETY_RESOLVER)) { throw new IllegalStateException("A custom default cycling safety resolver was already set"); @@ -481,7 +481,7 @@ public List getWayProperties() { return Collections.unmodifiableList(wayProperties); } - private String dumpTags(OSMWithTags way) { + private String dumpTags(OsmWithTags way) { /* generate warning message */ String all_tags = null; Map tags = way.getTags(); diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/specifier/BestMatchSpecifier.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/BestMatchSpecifier.java similarity index 90% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/specifier/BestMatchSpecifier.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/BestMatchSpecifier.java index 293bcf84644..7dacc61e6b8 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/specifier/BestMatchSpecifier.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/BestMatchSpecifier.java @@ -1,9 +1,9 @@ -package org.opentripplanner.openstreetmap.wayproperty.specifier; +package org.opentripplanner.osm.wayproperty.specifier; import java.util.Arrays; import java.util.stream.Collectors; -import org.opentripplanner.framework.tostring.ToStringBuilder; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Specifies a class of OSM tagged entities (e.g. ways) by a list of tags and their values (which @@ -26,12 +26,16 @@ public class BestMatchSpecifier implements OsmSpecifier { public static final int NO_MATCH_SCORE = 0; private final Condition[] conditions; + /** + * @deprecated Logic is fuzzy and unpredictable, use ExactMatchSpecifier instead + */ + @Deprecated public BestMatchSpecifier(String spec) { conditions = OsmSpecifier.parseConditions(spec, ";"); } @Override - public Scores matchScores(OSMWithTags way) { + public Scores matchScores(OsmWithTags way) { int backwardScore = 0, forwardScore = 0; int backwardMatches = 0, forwardMatches = 0; @@ -59,7 +63,7 @@ public Scores matchScores(OSMWithTags way) { } @Override - public int matchScore(OSMWithTags way) { + public int matchScore(OsmWithTags way) { int score = 0; int matches = 0; for (var test : conditions) { diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/specifier/Condition.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/Condition.java similarity index 79% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/specifier/Condition.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/Condition.java index 4ad180c16c3..24b3671ca98 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/specifier/Condition.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/Condition.java @@ -1,11 +1,11 @@ -package org.opentripplanner.openstreetmap.wayproperty.specifier; +package org.opentripplanner.osm.wayproperty.specifier; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.MatchResult.EXACT; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.MatchResult.NONE; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.MatchResult.WILDCARD; +import static org.opentripplanner.osm.wayproperty.specifier.Condition.MatchResult.EXACT; +import static org.opentripplanner.osm.wayproperty.specifier.Condition.MatchResult.NONE; +import static org.opentripplanner.osm.wayproperty.specifier.Condition.MatchResult.WILDCARD; import java.util.Arrays; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; public sealed interface Condition { String key(); @@ -14,17 +14,17 @@ default MatchResult matchType() { return EXACT; } - boolean isExtendedKeyMatch(OSMWithTags way, String exKey); + boolean isExtendedKeyMatch(OsmWithTags way, String exKey); /** * Test to what degree the OSM entity matches with this operation when taking the regular tag keys * into account. */ - default boolean isMatch(OSMWithTags way) { + default boolean isMatch(OsmWithTags way) { return isExtendedKeyMatch(way, this.key()); } - default MatchResult match(OSMWithTags way) { + default MatchResult match(OsmWithTags way) { return isMatch(way) ? matchType() : NONE; } @@ -35,7 +35,7 @@ default MatchResult match(OSMWithTags way) { * For example, it should not match a way with `cycleway:right=lane` when the `cycleway=lane` was * required but `cycleway:left=lane` should match. */ - default boolean isLeftMatch(OSMWithTags way) { + default boolean isLeftMatch(OsmWithTags way) { var leftKey = this.key() + ":left"; if (way.hasTag(leftKey)) { return isExtendedKeyMatch(way, leftKey); @@ -51,7 +51,7 @@ default boolean isLeftMatch(OSMWithTags way) { * For example, it should not match a way with `cycleway:left=lane` when the `cycleway=lane` was * required but `cycleway:right=lane` should match. */ - default boolean isRightMatch(OSMWithTags way) { + default boolean isRightMatch(OsmWithTags way) { var rightKey = this.key() + ":right"; if (way.hasTag(rightKey)) { return isExtendedKeyMatch(way, rightKey); @@ -64,7 +64,7 @@ default boolean isRightMatch(OSMWithTags way) { * Test to what degree the OSM entity matches with this operation when taking the ':both' key * suffixes into account. */ - default boolean isExplicitBothMatch(OSMWithTags way) { + default boolean isExplicitBothMatch(OsmWithTags way) { var bothKey = this.key() + ":both"; if (way.hasTag(bothKey)) { return isExtendedKeyMatch(way, bothKey); @@ -73,7 +73,7 @@ default boolean isExplicitBothMatch(OSMWithTags way) { } } - default boolean isForwardMatch(OSMWithTags way) { + default boolean isForwardMatch(OsmWithTags way) { var forwardKey = this.key() + ":forward"; if (way.hasTag(forwardKey)) { return isExtendedKeyMatch(way, forwardKey); @@ -83,11 +83,11 @@ default boolean isForwardMatch(OSMWithTags way) { } } - default MatchResult matchForward(OSMWithTags way) { + default MatchResult matchForward(OsmWithTags way) { return isForwardMatch(way) ? matchType() : NONE; } - default boolean isBackwardMatch(OSMWithTags way) { + default boolean isBackwardMatch(OsmWithTags way) { var backwardKey = this.key() + ":backward"; if (way.hasTag(backwardKey)) { return isExtendedKeyMatch(way, backwardKey); @@ -97,7 +97,7 @@ default boolean isBackwardMatch(OSMWithTags way) { } } - default MatchResult matchBackward(OSMWithTags way) { + default MatchResult matchBackward(OsmWithTags way) { return isBackwardMatch(way) ? matchType() : NONE; } @@ -112,7 +112,7 @@ enum MatchResult { */ record Equals(String key, String value) implements Condition { @Override - public boolean isExtendedKeyMatch(OSMWithTags way, String exKey) { + public boolean isExtendedKeyMatch(OsmWithTags way, String exKey) { return way.hasTag(exKey) && way.isTag(exKey, value); } @@ -131,7 +131,7 @@ public MatchResult matchType() { return WILDCARD; } @Override - public boolean isExtendedKeyMatch(OSMWithTags way, String exKey) { + public boolean isExtendedKeyMatch(OsmWithTags way, String exKey) { return way.hasTag(exKey); } @@ -146,7 +146,7 @@ public String toString() { */ record Absent(String key) implements Condition { @Override - public boolean isExtendedKeyMatch(OSMWithTags way, String exKey) { + public boolean isExtendedKeyMatch(OsmWithTags way, String exKey) { return !way.hasTag(exKey); } @@ -161,7 +161,7 @@ public String toString() { */ record GreaterThan(String key, int value) implements Condition { @Override - public boolean isExtendedKeyMatch(OSMWithTags way, String exKey) { + public boolean isExtendedKeyMatch(OsmWithTags way, String exKey) { var maybeInt = way.getTagAsInt(exKey, ignored -> {}); return maybeInt.isPresent() && maybeInt.getAsInt() > value; } @@ -177,7 +177,7 @@ public String toString() { */ record LessThan(String key, int value) implements Condition { @Override - public boolean isExtendedKeyMatch(OSMWithTags way, String exKey) { + public boolean isExtendedKeyMatch(OsmWithTags way, String exKey) { var maybeInt = way.getTagAsInt(exKey, ignored -> {}); return maybeInt.isPresent() && maybeInt.getAsInt() < value; } @@ -199,7 +199,7 @@ record InclusiveRange(String key, int upper, int lower) implements Condition { } @Override - public boolean isExtendedKeyMatch(OSMWithTags way, String exKey) { + public boolean isExtendedKeyMatch(OsmWithTags way, String exKey) { var maybeInt = way.getTagAsInt(exKey, ignored -> {}); return maybeInt.isPresent() && maybeInt.getAsInt() >= lower && maybeInt.getAsInt() <= upper; } @@ -215,7 +215,7 @@ public String toString() { */ record OneOf(String key, String... values) implements Condition { @Override - public boolean isExtendedKeyMatch(OSMWithTags way, String exKey) { + public boolean isExtendedKeyMatch(OsmWithTags way, String exKey) { return Arrays.stream(values).anyMatch(value -> way.isTag(exKey, value)); } @@ -237,7 +237,7 @@ public OneOfOrAbsent(String key) { } @Override - public boolean isExtendedKeyMatch(OSMWithTags way, String exKey) { + public boolean isExtendedKeyMatch(OsmWithTags way, String exKey) { return ( !way.hasTag(exKey) || Arrays.stream(values).anyMatch(value -> way.isTag(exKey, value)) ); diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/specifier/ExactMatchSpecifier.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/ExactMatchSpecifier.java similarity index 81% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/specifier/ExactMatchSpecifier.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/ExactMatchSpecifier.java index 48c3b5edb64..547c5caf6be 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/specifier/ExactMatchSpecifier.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/ExactMatchSpecifier.java @@ -1,9 +1,9 @@ -package org.opentripplanner.openstreetmap.wayproperty.specifier; +package org.opentripplanner.osm.wayproperty.specifier; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; /** * This specifier allows you to specify a very precise match. It will only result in a positive when @@ -15,7 +15,7 @@ * If you'd use a {@link BestMatchSpecifier} then the likelihood of the long spec matching unwanted * ways would be high. * - * @see org.opentripplanner.openstreetmap.tagmapping.HoustonMapper + * @see org.opentripplanner.osm.tagmapping.HoustonMapper */ public class ExactMatchSpecifier implements OsmSpecifier { @@ -39,7 +39,7 @@ public ExactMatchSpecifier(Condition... conditions) { } @Override - public Scores matchScores(OSMWithTags way) { + public Scores matchScores(OsmWithTags way) { return new Scores( allForwardTagsMatch(way) ? bestMatchScore : NO_MATCH_SCORE, allBackwardTagsMatch(way) ? bestMatchScore : NO_MATCH_SCORE @@ -47,7 +47,7 @@ public Scores matchScores(OSMWithTags way) { } @Override - public int matchScore(OSMWithTags way) { + public int matchScore(OsmWithTags way) { if (allTagsMatch(way)) { return bestMatchScore; } else { @@ -60,15 +60,15 @@ public String toDocString() { return conditions.stream().map(Object::toString).collect(Collectors.joining("; ")); } - public boolean allTagsMatch(OSMWithTags way) { + public boolean allTagsMatch(OsmWithTags way) { return conditions.stream().allMatch(o -> o.isMatch(way)); } - public boolean allBackwardTagsMatch(OSMWithTags way) { + public boolean allBackwardTagsMatch(OsmWithTags way) { return conditions.stream().allMatch(c -> c.isBackwardMatch(way)); } - public boolean allForwardTagsMatch(OSMWithTags way) { + public boolean allForwardTagsMatch(OsmWithTags way) { return conditions.stream().allMatch(c -> c.isForwardMatch(way)); } diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/specifier/LogicalOrSpecifier.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/LogicalOrSpecifier.java similarity index 86% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/specifier/LogicalOrSpecifier.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/LogicalOrSpecifier.java index 74db280115b..9d4e2d0d24f 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/specifier/LogicalOrSpecifier.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/LogicalOrSpecifier.java @@ -1,9 +1,9 @@ -package org.opentripplanner.openstreetmap.wayproperty.specifier; +package org.opentripplanner.osm.wayproperty.specifier; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; /** * Allows to specify a 'logical or' condition to specify a match. This intended to be used with a @@ -31,12 +31,12 @@ public LogicalOrSpecifier(String... specs) { } @Override - public Scores matchScores(OSMWithTags way) { + public Scores matchScores(OsmWithTags way) { return Scores.of(matchScore(way)); } @Override - public int matchScore(OSMWithTags way) { + public int matchScore(OsmWithTags way) { var oneMatchesExactly = subSpecs.stream().anyMatch(subspec -> subspec.allTagsMatch(way)); if (oneMatchesExactly) { return 1; diff --git a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/specifier/OsmSpecifier.java b/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/OsmSpecifier.java similarity index 87% rename from src/main/java/org/opentripplanner/openstreetmap/wayproperty/specifier/OsmSpecifier.java rename to application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/OsmSpecifier.java index 71d629552ff..23604537f7a 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/wayproperty/specifier/OsmSpecifier.java +++ b/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/OsmSpecifier.java @@ -1,7 +1,7 @@ -package org.opentripplanner.openstreetmap.wayproperty.specifier; +package org.opentripplanner.osm.wayproperty.specifier; import java.util.Arrays; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; /** * An interface for assigning match scores for OSM entities (mostly ways). The higher the score the @@ -33,14 +33,14 @@ static Condition[] parseConditions(String spec, String separator) { * * @param way an OSM tagged object to compare to this specifier */ - Scores matchScores(OSMWithTags way); + Scores matchScores(OsmWithTags way); /** * Calculates a score expressing how well an OSM entity's tags match this specifier. This does - * exactly the same thing as {@link OsmSpecifier#matchScores(OSMWithTags)} but without regard for + * exactly the same thing as {@link OsmSpecifier#matchScores(OsmWithTags)} but without regard for * :left, :right, :forward, :backward and :both. */ - int matchScore(OSMWithTags way); + int matchScore(OsmWithTags way); /** * Convert this specifier to a human-readable identifier that represents this in (generated) diff --git a/src/main/java/org/opentripplanner/routing/TripTimeOnDateHelper.java b/application/src/main/java/org/opentripplanner/routing/TripTimeOnDateHelper.java similarity index 81% rename from src/main/java/org/opentripplanner/routing/TripTimeOnDateHelper.java rename to application/src/main/java/org/opentripplanner/routing/TripTimeOnDateHelper.java index 72665edf657..feb5191a612 100644 --- a/src/main/java/org/opentripplanner/routing/TripTimeOnDateHelper.java +++ b/application/src/main/java/org/opentripplanner/routing/TripTimeOnDateHelper.java @@ -4,13 +4,13 @@ import java.time.LocalDate; import java.util.ArrayList; import java.util.List; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.Timetable; import org.opentripplanner.model.TripTimeOnDate; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.time.ServiceDateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,9 +23,9 @@ public static List getTripTimeOnDates( Trip trip, LocalDate serviceDate ) { - TripPattern pattern = transitService.getPatternForTrip(trip, serviceDate); + TripPattern pattern = transitService.findPattern(trip, serviceDate); - Timetable timetable = transitService.getTimetableForTripPattern(pattern, serviceDate); + Timetable timetable = transitService.findTimetable(pattern, serviceDate); // If realtime moved pattern back to original trip, fetch it instead if (timetable.getTripIndex(trip.getId()) == -1) { @@ -33,8 +33,8 @@ public static List getTripTimeOnDates( "Trip {} not found in realtime pattern. This should not happen, and indicates a bug.", trip ); - pattern = transitService.getPatternForTrip(trip); - timetable = transitService.getTimetableForTripPattern(pattern, serviceDate); + pattern = transitService.findPattern(trip); + timetable = transitService.findTimetable(pattern, serviceDate); } // This check is made here to avoid changing TripTimeOnDate.fromTripTimes diff --git a/src/main/java/org/opentripplanner/routing/alertpatch/AlertCause.java b/application/src/main/java/org/opentripplanner/routing/alertpatch/AlertCause.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/alertpatch/AlertCause.java rename to application/src/main/java/org/opentripplanner/routing/alertpatch/AlertCause.java diff --git a/src/main/java/org/opentripplanner/routing/alertpatch/AlertEffect.java b/application/src/main/java/org/opentripplanner/routing/alertpatch/AlertEffect.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/alertpatch/AlertEffect.java rename to application/src/main/java/org/opentripplanner/routing/alertpatch/AlertEffect.java diff --git a/src/main/java/org/opentripplanner/routing/alertpatch/AlertSeverity.java b/application/src/main/java/org/opentripplanner/routing/alertpatch/AlertSeverity.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/alertpatch/AlertSeverity.java rename to application/src/main/java/org/opentripplanner/routing/alertpatch/AlertSeverity.java diff --git a/application/src/main/java/org/opentripplanner/routing/alertpatch/AlertUrl.java b/application/src/main/java/org/opentripplanner/routing/alertpatch/AlertUrl.java new file mode 100644 index 00000000000..fcce3720538 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/routing/alertpatch/AlertUrl.java @@ -0,0 +1,10 @@ +package org.opentripplanner.routing.alertpatch; + +import java.util.Objects; +import javax.annotation.Nullable; + +public record AlertUrl(String uri, @Nullable String label) { + public AlertUrl { + Objects.requireNonNull(uri); + } +} diff --git a/src/main/java/org/opentripplanner/routing/alertpatch/EntityKey.java b/application/src/main/java/org/opentripplanner/routing/alertpatch/EntityKey.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/alertpatch/EntityKey.java rename to application/src/main/java/org/opentripplanner/routing/alertpatch/EntityKey.java diff --git a/src/main/java/org/opentripplanner/routing/alertpatch/EntitySelector.java b/application/src/main/java/org/opentripplanner/routing/alertpatch/EntitySelector.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/alertpatch/EntitySelector.java rename to application/src/main/java/org/opentripplanner/routing/alertpatch/EntitySelector.java diff --git a/src/main/java/org/opentripplanner/routing/alertpatch/StopCondition.java b/application/src/main/java/org/opentripplanner/routing/alertpatch/StopCondition.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/alertpatch/StopCondition.java rename to application/src/main/java/org/opentripplanner/routing/alertpatch/StopCondition.java diff --git a/src/main/java/org/opentripplanner/routing/alertpatch/StopConditionsHelper.java b/application/src/main/java/org/opentripplanner/routing/alertpatch/StopConditionsHelper.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/alertpatch/StopConditionsHelper.java rename to application/src/main/java/org/opentripplanner/routing/alertpatch/StopConditionsHelper.java diff --git a/src/main/java/org/opentripplanner/routing/alertpatch/TimePeriod.java b/application/src/main/java/org/opentripplanner/routing/alertpatch/TimePeriod.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/alertpatch/TimePeriod.java rename to application/src/main/java/org/opentripplanner/routing/alertpatch/TimePeriod.java diff --git a/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlert.java b/application/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlert.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/alertpatch/TransitAlert.java rename to application/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlert.java index d7a3c93abe5..4555573c8ca 100644 --- a/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlert.java +++ b/application/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlert.java @@ -8,7 +8,6 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; @@ -214,7 +213,7 @@ public boolean noServiceAt(Instant instant) { } @Override - public boolean sameAs(@Nonnull TransitAlert other) { + public boolean sameAs(TransitAlert other) { return ( getId().equals(other.getId()) && Objects.equals(headerText, other.headerText) && @@ -237,7 +236,6 @@ public boolean sameAs(@Nonnull TransitAlert other) { ); } - @Nonnull @Override public TransitBuilder copy() { return new TransitAlertBuilder(this); diff --git a/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlertBuilder.java b/application/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlertBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/alertpatch/TransitAlertBuilder.java rename to application/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlertBuilder.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java b/application/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java index 7ac3dd1caf6..e0b06eab561 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java @@ -14,7 +14,6 @@ import javax.annotation.Nullable; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.application.OTPRequestTimeoutException; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.grouppriority.TransitGroupPriorityItineraryDecorator; import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; @@ -38,6 +37,7 @@ import org.opentripplanner.service.paging.PagingService; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.transit.model.network.grouppriority.TransitGroupPriorityService; +import org.opentripplanner.utils.time.ServiceDateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -230,10 +230,18 @@ private Duration searchWindowUsed() { : Duration.ofSeconds(raptorSearchParamsUsed.searchWindowInSeconds()); } - private Void routeDirectStreet( + private List routeDirectStreet( List itineraries, Collection routingErrors ) { + // TODO: Add support for via search to the direct-street search and remove this. + // The direct search is used to prune away silly transit results and it + // would be nice to also support via as a feature in the direct-street + // search. + if (request.isViaSearch()) { + return null; + } + debugTimingAggregator.startedDirectStreetRouter(); try { itineraries.addAll(DirectStreetRouter.route(serverContext, request)); diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index 071814a7abf..65776948cbb 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -13,8 +13,6 @@ import javax.annotation.Nullable; import org.opentripplanner.ext.accessibilityscore.DecorateWithAccessibilityScore; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.framework.collection.ListSection; -import org.opentripplanner.framework.lang.Sandbox; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; @@ -25,6 +23,7 @@ import org.opentripplanner.routing.algorithm.filterchain.filters.street.RemoveNonTransitItinerariesBasedOnGeneralizedCost; import org.opentripplanner.routing.algorithm.filterchain.filters.street.RemoveParkAndRideWithMostlyWalkingFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.street.RemoveWalkOnlyFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.system.FlexSearchWindowFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.system.NumItinerariesFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.system.OutsideSearchWindowFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.system.PagingFilter; @@ -57,6 +56,8 @@ import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.transit.model.site.MultiModalStation; import org.opentripplanner.transit.model.site.Station; +import org.opentripplanner.utils.collection.ListSection; +import org.opentripplanner.utils.lang.Sandbox; /** * Create a filter chain based on the given config. @@ -89,6 +90,7 @@ public class ItineraryListFilterChainBuilder { private boolean removeTransitIfWalkingIsBetter = true; private ItinerarySortKey itineraryPageCut; private boolean transitGroupPriorityUsed = false; + private boolean filterDirectFlexBySearchWindow = true; /** * Sandbox filters which decorate the itineraries with extra information. @@ -470,6 +472,13 @@ public ItineraryListFilterChain build() { ); } + if (earliestDepartureTime != null && filterDirectFlexBySearchWindow) { + addRemoveFilter( + filters, + new FlexSearchWindowFilter(earliestDepartureTime, searchWindow, sortOrder) + ); + } + // Remove itineraries present in the page retrieved before this page/search. if (itineraryPageCut != null) { addRemoveFilter( @@ -533,6 +542,11 @@ public ItineraryListFilterChain build() { return new ItineraryListFilterChain(filters, debugHandler); } + public ItineraryListFilterChainBuilder withFilterDirectFlexBySearchWindow(boolean b) { + this.filterDirectFlexBySearchWindow = b; + return this; + } + /** * If enabled, this adds the filter to remove itineraries which have the same stops and routes. * These are sometimes called "time-shifted duplicates" but since those terms have so many diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/GroupBySimilarity.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/GroupBySimilarity.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/GroupBySimilarity.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/GroupBySimilarity.java index 0f671524a06..5cec3046710 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/GroupBySimilarity.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/GroupBySimilarity.java @@ -1,7 +1,7 @@ package org.opentripplanner.routing.algorithm.filterchain.api; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilterChainBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Group itineraries by similarity and reduce the number of itineraries down to an given maximum diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java similarity index 95% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java index a173f6b454b..da33b6f92a0 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java @@ -1,7 +1,7 @@ package org.opentripplanner.routing.algorithm.filterchain.api; -import org.opentripplanner.framework.lang.DoubleUtils; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; +import org.opentripplanner.utils.lang.DoubleUtils; /** * Input parameters for diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalking.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalking.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalking.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalking.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingFilter.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilter.java diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/FlexSearchWindowFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/FlexSearchWindowFilter.java new file mode 100644 index 00000000000..efbb9bf4d08 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/FlexSearchWindowFilter.java @@ -0,0 +1,65 @@ +package org.opentripplanner.routing.algorithm.filterchain.filters.system; + +import java.time.Duration; +import java.time.Instant; +import java.util.function.Predicate; +import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.model.plan.SortOrder; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; + +/** + * The flex router doesn't use the transit router's search-window, but nevertheless using it + * for filtering is useful when combining flex with transit. + *

+ * The flex router also searches the previous day (arrive by) or the next one (depart after). + * If you didn't filter the flex results by something you could get yesterday's or tomorrow's + * trips where you would not expect it. + */ +public class FlexSearchWindowFilter implements RemoveItineraryFlagger { + + public static final String TAG = "flex-outside-search-window"; + + private final Instant earliestDepartureTime; + private final Instant latestArrivalTime; + private final SortOrder sortOrder; + + public FlexSearchWindowFilter( + Instant earliestDepartureTime, + Duration searchWindow, + SortOrder sortOrder + ) { + this.earliestDepartureTime = earliestDepartureTime; + this.latestArrivalTime = earliestDepartureTime.plus(searchWindow); + this.sortOrder = sortOrder; + } + + @Override + public String name() { + return TAG; + } + + @Override + public Predicate shouldBeFlaggedForRemoval() { + return it -> { + if (it.isDirectFlex()) { + return switch (sortOrder) { + case STREET_AND_DEPARTURE_TIME -> { + var time = it.startTime().toInstant(); + yield time.isBefore(earliestDepartureTime); + } + case STREET_AND_ARRIVAL_TIME -> { + var time = it.startTime().toInstant(); + yield time.isAfter(latestArrivalTime); + } + }; + } else { + return false; + } + }; + } + + @Override + public boolean skipAlreadyFlaggedItineraries() { + return false; + } +} diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilter.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilter.java index aed5eeb4f95..77c297fcfa5 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilter.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilter.java @@ -2,10 +2,10 @@ import java.util.List; import java.util.function.Consumer; -import org.opentripplanner.framework.collection.ListSection; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; +import org.opentripplanner.utils.collection.ListSection; /** * Flag all itineraries after the provided limit. This flags the itineraries at the end of the list diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterResults.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterResults.java similarity index 92% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterResults.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterResults.java index 8b11be099f7..401dc95026d 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterResults.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterResults.java @@ -2,12 +2,12 @@ import java.time.Instant; import java.util.List; -import org.opentripplanner.framework.collection.ListSection; -import org.opentripplanner.framework.collection.ListUtils; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; +import org.opentripplanner.utils.collection.ListSection; +import org.opentripplanner.utils.collection.ListUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * The NumItinerariesFilter removes itineraries from a list of itineraries based on the number to diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilter.java similarity index 75% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilter.java index ba3ef4b04f3..5ab6834437b 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilter.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilter.java @@ -7,8 +7,10 @@ import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; /** - * This filter will remove all itineraries that are outside the search-window. In some - * cases the access is time-shifted after the end of the search-window. These results + * This filter will remove all itineraries that are both search-window aware and outside the + * search-window. Only those that use transit are search-window aware, street and flex itineraries are not. + *

+ * In some cases the access is time-shifted after the end of the search-window. These results * should appear again when paging to the next page. Hence, this filter will remove * such itineraries. The same is true for when paging to the previous page for arriveBy=true. *

@@ -35,8 +37,12 @@ public String name() { @Override public Predicate shouldBeFlaggedForRemoval() { return it -> { - var time = it.startTime().toInstant(); - return time.isBefore(earliestDepartureTime) || !time.isBefore(latestDepartureTime); + if (it.isSearchWindowAware()) { + var time = it.startTime().toInstant(); + return time.isBefore(earliestDepartureTime) || !time.isBefore(latestDepartureTime); + } else { + return false; + } }; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilter.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilter.java index 1ef109525f6..417ffca9d83 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilter.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilter.java @@ -3,12 +3,12 @@ import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.framework.collection.ListSection; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; +import org.opentripplanner.utils.collection.ListSection; /** * This class is used to enforce the cut/limit between two pages. It removes potential duplicates diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/SingleCriteriaComparator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/SingleCriteriaComparator.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/SingleCriteriaComparator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/SingleCriteriaComparator.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/Group.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/Group.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/Group.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/Group.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/Item.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/Item.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/Item.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/Item.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/McMaxLimitFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/McMaxLimitFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/McMaxLimitFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/McMaxLimitFilter.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/State.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/State.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/State.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/State.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/DecorateTransitAlert.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/DecorateTransitAlert.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/DecorateTransitAlert.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/DecorateTransitAlert.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/KeepItinerariesWithFewestTransfers.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/KeepItinerariesWithFewestTransfers.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/KeepItinerariesWithFewestTransfers.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/KeepItinerariesWithFewestTransfers.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java index 430f00372d0..4af0acd00cb 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java @@ -4,11 +4,11 @@ import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; +import org.opentripplanner.utils.lang.IntUtils; /** * This filter removes all transit results which have a generalized-cost higher than the max-limit diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSame.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSame.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSame.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSame.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilter.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilter.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimit.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimit.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimit.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimit.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/RemoveFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/RemoveFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/RemoveFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/RemoveFilter.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/SortingFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/SortingFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/SortingFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/SortingFilter.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandler.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandler.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandler.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandler.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacher.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacher.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacher.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacher.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStations.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStations.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStations.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStations.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistance.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistance.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistance.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistance.java index ee67e4f76d0..eb25cf9275c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistance.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistance.java @@ -2,12 +2,12 @@ import java.util.Comparator; import java.util.List; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.model.plan.TransitLeg; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.GroupId; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This class creates a group identifier for an itinerary based on the longest legs which together diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameFirstOrLastTrip.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameFirstOrLastTrip.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameFirstOrLastTrip.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameFirstOrLastTrip.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStops.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStops.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStops.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStops.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparator.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparator.java index f11caf5ceaa..a904a6990ca 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparator.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparator.java @@ -4,9 +4,9 @@ import static java.util.Comparator.comparingInt; import java.util.Comparator; -import org.opentripplanner.framework.collection.CompositeComparator; import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; +import org.opentripplanner.utils.collection.CompositeComparator; /** * This comparator implements the itinerary sort order defined by the {@link SortOrder}. diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/GroupId.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/GroupId.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/GroupId.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/GroupId.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDecorator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDecorator.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDecorator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDecorator.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/RemoveItineraryFlagger.java b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/RemoveItineraryFlagger.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/RemoveItineraryFlagger.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/RemoveItineraryFlagger.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.excalidraw b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.excalidraw similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.excalidraw rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.excalidraw diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.svg b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.svg similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.svg rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.svg diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md b/application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md rename to application/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/AlertToLegMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/AlertToLegMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/mapping/AlertToLegMapper.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/mapping/AlertToLegMapper.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java index 11302098f25..2e7bf1b7040 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java @@ -134,7 +134,7 @@ public Itinerary generateItinerary(GraphPath path) { } } - Itinerary itinerary = new Itinerary(legs); + Itinerary itinerary = Itinerary.createDirectItinerary(legs); calculateElevations(itinerary, path.edges); diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/ItinerariesHelper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/ItinerariesHelper.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/mapping/ItinerariesHelper.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/mapping/ItinerariesHelper.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java similarity index 91% rename from src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java index ec58d444914..97dbda4bb68 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java @@ -24,8 +24,10 @@ public static PagingService createPagingService( ) { return new PagingService( transitTuningParameters.pagingSearchWindowAdjustments(), + // The dynamic search-window is not the same as requested search-window, but in lack + // of a something else we use the raptor dynamic min here. raptorTuningParameters.dynamicSearchWindowCoefficients().minWindow(), - raptorTuningParameters.dynamicSearchWindowCoefficients().maxWindow(), + transitTuningParameters.maxSearchWindow(), searchWindowOf(raptorSearchParamsUsed), edt(searchStartTime, raptorSearchParamsUsed), lat(searchStartTime, raptorSearchParamsUsed), diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java similarity index 85% rename from src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java index d7098c20661..64c59b71603 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java @@ -1,12 +1,14 @@ package org.opentripplanner.routing.algorithm.mapping; -import static org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter.toOtpDomainCost; +import static org.opentripplanner.raptor.api.model.RaptorCostConverter.toOtpDomainCost; import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Set; import org.opentripplanner.astar.model.GraphPath; +import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.model.GenericLocation; @@ -37,8 +39,8 @@ import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.request.StreetSearchRequest; import org.opentripplanner.street.search.request.StreetSearchRequestMapper; +import org.opentripplanner.street.search.state.EdgeTraverser; import org.opentripplanner.street.search.state.State; -import org.opentripplanner.street.search.state.StateEditor; import org.opentripplanner.transit.model.timetable.TripIdAndServiceDate; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.service.TransitService; @@ -105,9 +107,16 @@ public Itinerary createItinerary(RaptorPath path) { Leg transitLeg = null; + PathLeg previousLeg = null; while (!pathLeg.isEgressLeg()) { // Map transit leg if (pathLeg.isTransitLeg()) { + if ( + OTPFeature.ExtraTransferLegOnSameStop.isOn() && + isPathTransferAtSameStop(previousLeg, pathLeg) + ) { + legs.add(createTransferLegAtSameStop(previousLeg, pathLeg)); + } transitLeg = mapTransitLeg(transitLeg, pathLeg.asTransitLeg()); legs.add(transitLeg); } @@ -123,6 +132,7 @@ else if (pathLeg.isTransferLeg()) { } } + previousLeg = pathLeg; pathLeg = pathLeg.nextLeg(); } @@ -131,7 +141,7 @@ else if (pathLeg.isTransferLeg()) { Itinerary mapped = mapEgressLeg(egressPathLeg); legs.addAll(mapped == null ? List.of() : mapped.getLegs()); - Itinerary itinerary = new Itinerary(legs); + Itinerary itinerary = Itinerary.createScheduledTransitItinerary(legs); // Map general itinerary fields itinerary.setArrivedAtDestinationWithRentedVehicle( @@ -164,6 +174,19 @@ else if (pathLeg.isTransferLeg()) { return itinerary; } + private static boolean isPathTransferAtSameStop( + PathLeg previousLeg, + PathLeg currentLeg + ) { + return ( + previousLeg != null && + previousLeg.isTransitLeg() && + currentLeg.isTransitLeg() && + !previousLeg.asTransitLeg().isStaySeatedOntoNextLeg() && + (previousLeg.asTransitLeg().toStop() == currentLeg.asTransitLeg().fromStop()) + ); + } + private List mapAccessLeg(AccessPathLeg accessPathLeg) { if (accessPathLeg.access().isFree()) { return List.of(); @@ -257,13 +280,34 @@ private TripOnServiceDate getTripOnServiceDate(T tripSchedule) { tripSchedule.getOriginalTripTimes().getTrip().getId(), tripSchedule.getServiceDate() ); - return transitService.getTripOnServiceDateForTripAndDay(tripIdAndServiceDate); + return transitService.getTripOnServiceDate(tripIdAndServiceDate); } private boolean isFree(EgressPathLeg egressPathLeg) { return egressPathLeg.egress().isFree(); } + /** + * If a routing result transfers at the very same stop, RAPTOR doesn't add a path leg. However, + * sometimes we want to create a zero distance leg so a UI can show a transfer. Since it would + * be considered backwards-incompatible, this is an opt-in feature. + */ + private Leg createTransferLegAtSameStop(PathLeg previousLeg, PathLeg nextLeg) { + var transferStop = Place.forStop(transitLayer.getStopByIndex(previousLeg.toStop())); + return StreetLeg + .create() + .withMode(TraverseMode.WALK) + .withStartTime(createZonedDateTime(previousLeg.toTime())) + .withEndTime(createZonedDateTime(nextLeg.fromTime())) + .withFrom(transferStop) + .withTo(transferStop) + .withDistanceMeters(0) + .withGeneralizedCost(0) + .withGeometry(GeometryUtils.makeLineString(transferStop.coordinate, transferStop.coordinate)) + .withWalkSteps(List.of()) + .build(); + } + private List mapTransferLeg(TransferPathLeg pathLeg, TraverseMode transferMode) { var transferFromStop = transitLayer.getStopByIndex(pathLeg.fromStop()); var transferToStop = transitLayer.getStopByIndex(pathLeg.toStop()); @@ -317,24 +361,15 @@ private List mapNonTransitLeg( .build() ); } else { - StateEditor se = new StateEditor(edges.get(0).getFromVertex(), transferStreetRequest); - se.setTimeSeconds(createZonedDateTime(pathLeg.fromTime()).toEpochSecond()); - - State s = se.makeState(); - ArrayList transferStates = new ArrayList<>(); - transferStates.add(s); - for (Edge e : edges) { - var states = e.traverse(s); - if (State.isEmpty(states)) { - s = null; - } else { - transferStates.add(states[0]); - s = states[0]; - } - } - - State[] states = transferStates.toArray(new State[0]); - var graphPath = new GraphPath<>(states[states.length - 1]); + var legTransferSearchRequest = transferStreetRequest + .copyOf(createZonedDateTime(pathLeg.fromTime()).toInstant()) + .build(); + var initialStates = State.getInitialStates( + Set.of(edges.getFirst().getFromVertex()), + legTransferSearchRequest + ); + var state = EdgeTraverser.traverseEdges(initialStates, edges); + var graphPath = new GraphPath<>(state.get()); Itinerary subItinerary = graphPathToItineraryMapper.generateItinerary(graphPath); @@ -347,7 +382,7 @@ private List mapNonTransitLeg( } private Itinerary mapDirectPath(RaptorPath path) { - return new Itinerary( + return Itinerary.createScheduledTransitItinerary( List.of( new UnknownTransitPathLeg( mapPlace(request.from()), diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java similarity index 95% rename from src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java index c1fab68f999..277efda3810 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java @@ -86,12 +86,13 @@ public static ItineraryListFilterChain createFilterChain( ) .withTransitAlerts( context.transitService().getTransitAlertService(), - context.transitService()::getMultiModalStationForStation + context.transitService()::findMultiModalStation ) .withSearchWindow(earliestDepartureTimeUsed, searchWindowUsed) .withPageCursorInputSubscriber(pageCursorInputSubscriber) .withRemoveWalkAllTheWayResults(removeWalkAllTheWayResults) .withRemoveTransitIfWalkingIsBetter(true) + .withFilterDirectFlexBySearchWindow(params.filterDirectFlexBySearchWindow()) .withDebugEnabled(params.debug()); if (!request.preferences().transit().relaxTransitGroupPriority().isNormal()) { @@ -113,7 +114,9 @@ public static ItineraryListFilterChain createFilterChain( builder.withEmissions(new DecorateWithEmission(context.emissionsService())); } - if (context.stopConsolidationService() != null) { + if ( + context.stopConsolidationService() != null && context.stopConsolidationService().isActive() + ) { builder.withConsolidatedStopNamesDecorator( new DecorateConsolidatedStopNames(context.stopConsolidationService()) ); diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RoutingResponseMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RoutingResponseMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/mapping/RoutingResponseMapper.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RoutingResponseMapper.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index 94905bb840a..32f5ccf533b 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -7,7 +7,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import org.opentripplanner.framework.geometry.DirectionUtils; @@ -296,7 +295,6 @@ private void processState(State backState, State forwardState) { current.addEdge(edge); } - @Nonnull private static RelativeDirection relativeDirectionForTransitLink(StreetTransitEntranceLink link) { if (link.isExit()) { return EXIT_STATION; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/TripPlanMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/TripPlanMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/mapping/TripPlanMapper.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/mapping/TripPlanMapper.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/api/DefaultTripPattern.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/api/DefaultTripPattern.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/api/DefaultTripPattern.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/api/DefaultTripPattern.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/api/SlackProvider.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/api/SlackProvider.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/api/SlackProvider.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/api/SlackProvider.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/path/PathDiff.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/path/PathDiff.java similarity index 90% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/path/PathDiff.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/path/PathDiff.java index 18f1fa4f64a..d595c8abcff 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/path/PathDiff.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/path/PathDiff.java @@ -1,8 +1,8 @@ package org.opentripplanner.routing.algorithm.raptoradapter.path; -import static org.opentripplanner.framework.text.Table.Align.Center; -import static org.opentripplanner.framework.text.Table.Align.Left; -import static org.opentripplanner.framework.text.Table.Align.Right; +import static org.opentripplanner.utils.text.Table.Align.Center; +import static org.opentripplanner.utils.text.Table.Align.Left; +import static org.opentripplanner.utils.text.Table.Align.Right; import java.util.ArrayList; import java.util.Collection; @@ -10,16 +10,16 @@ import java.util.List; import java.util.function.Consumer; import java.util.stream.Collectors; -import org.opentripplanner.framework.collection.CompositeComparator; -import org.opentripplanner.framework.text.Table; -import org.opentripplanner.framework.text.TableBuilder; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.PathLeg; import org.opentripplanner.raptor.api.path.RaptorPath; import org.opentripplanner.routing.util.DiffEntry; import org.opentripplanner.routing.util.DiffTool; +import org.opentripplanner.utils.collection.CompositeComparator; +import org.opentripplanner.utils.text.Table; +import org.opentripplanner.utils.text.TableBuilder; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; /** * This class is used to diff two set of paths. You may ask for the diff result or pass in a logger diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/AdditionalSearchDays.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/AdditionalSearchDays.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/AdditionalSearchDays.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/AdditionalSearchDays.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/FilterTransitWhenDirectModeIsEmpty.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/FilterTransitWhenDirectModeIsEmpty.java similarity index 81% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/FilterTransitWhenDirectModeIsEmpty.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/FilterTransitWhenDirectModeIsEmpty.java index 01a8c9ab112..0ed9bdb0558 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/FilterTransitWhenDirectModeIsEmpty.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/FilterTransitWhenDirectModeIsEmpty.java @@ -5,13 +5,13 @@ /** *

- * In OTP the street search and transit search is done as to separate searches. The results is then - * merged and filtered to remove none optimal itineraries. But, when the client do NOT provide a - * ´directMode´, OTP do not do the streetSearch. And, the removal of none optimal results is not - * done, there is not street results to use to prune bad transit results with. In other words OTP is + * In OTP, the street search and transit search are done separately. The results are then + * merged and filtered to remove non-optimal itineraries. But, when the client does NOT provide a + * ´directMode´, OTP does not do the streetSearch. And, the removal of non-optimal results is not + * done, there are no street results to use to prune bad transit results with. In other words, OTP is * forced to return at least one itinerary with at least one transit leg. So, instead of walking - * maybe 100 meters, the OTP suggest you need to walk to the closest buss stop, take the bus one - * stop and walk back, oten with more walking than just those 100 meters. + * maybe 100 meters, OTP suggests you need to walk to the closest bus stop, take the bus for one + * stop and walk back, often with more walking than just those 100 meters. *

* Let say OTP produces these internal results: *

    @@ -31,7 +31,7 @@ *

    * If no directMode is set, the responsibility of this class it to always filter away itineraries * with a generalized-cost that is higher than the WALK-ALL-THE-WAY. We achieve this by setting the - * directMode before searching. This trigger the direct street search, and later the result is + * directMode before searching. This triggers the direct street search, and later the result is * passed into the filter chain where none optimal results are removed. Finally the street itinerary * is removed and the request street mode rest to the original state. *

    @@ -55,7 +55,7 @@ public class FilterTransitWhenDirectModeIsEmpty { private final StreetMode originalDirectMode; public FilterTransitWhenDirectModeIsEmpty(RequestModes modes) { - this.originalDirectMode = modes.directMode; + this(modes.directMode); } public FilterTransitWhenDirectModeIsEmpty(StreetMode originalDirectMode) { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java similarity index 86% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java index 37bb7270902..d332013d5ac 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java @@ -11,12 +11,15 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; +import java.util.stream.IntStream; +import javax.annotation.Nullable; import org.opentripplanner.ext.ridehailing.RideHailingAccessShifter; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.raptor.RaptorService; import org.opentripplanner.raptor.api.path.RaptorPath; import org.opentripplanner.raptor.api.response.RaptorResponse; +import org.opentripplanner.raptor.spi.ExtraMcRouterSearch; import org.opentripplanner.routing.algorithm.mapping.RaptorPathToItineraryMapper; import org.opentripplanner.routing.algorithm.raptoradapter.router.street.AccessEgressPenaltyDecorator; import org.opentripplanner.routing.algorithm.raptoradapter.router.street.AccessEgressRouter; @@ -41,7 +44,10 @@ import org.opentripplanner.routing.framework.DebugTimingAggregator; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.street.search.TemporaryVerticesContainer; +import org.opentripplanner.transit.model.framework.EntityNotFoundException; +import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.grouppriority.TransitGroupPriorityService; +import org.opentripplanner.transit.model.site.StopLocation; public class TransitRouter { @@ -133,11 +139,15 @@ private TransitRouterResult route() { serverContext.raptorConfig().isMultiThreaded(), accessEgresses.getAccesses(), accessEgresses.getEgresses(), - serverContext.meterRegistry() + serverContext.meterRegistry(), + this::listStopIndexes ); // Route transit - var raptorService = new RaptorService<>(serverContext.raptorConfig()); + var raptorService = new RaptorService<>( + serverContext.raptorConfig(), + createExtraMcRouterSearch(accessEgresses, transitLayer) + ); var transitResponse = raptorService.route(raptorRequest, requestTransitDataProvider); checkIfTransitConnectionExists(transitResponse); @@ -250,20 +260,19 @@ private Collection fetchAccessEgresses(AccessEgre .valueOf(streetRequest.mode()); int stopCountLimit = accessRequest.preferences().street().accessEgress().maxStopCount(); - var nearbyStops = AccessEgressRouter.streetSearch( + var nearbyStops = AccessEgressRouter.findAccessEgresses( accessRequest, temporaryVerticesContainer, streetRequest, serverContext.dataOverlayContext(accessRequest), - type.isEgress(), + type, durationLimit, stopCountLimit ); + var accessEgresses = AccessEgressMapper.mapNearbyStops(nearbyStops, type); + accessEgresses = timeshiftRideHailing(streetRequest, type, accessEgresses); - List results = new ArrayList<>( - AccessEgressMapper.mapNearbyStops(nearbyStops, type.isEgress()) - ); - results = timeshiftRideHailing(streetRequest, type, results); + var results = new ArrayList<>(accessEgresses); // Special handling of flex accesses if (OTPFeature.FlexRouting.isOn() && streetRequest.mode() == StreetMode.FLEXIBLE) { @@ -274,21 +283,20 @@ private Collection fetchAccessEgresses(AccessEgre additionalSearchDays, serverContext.flexParameters(), serverContext.dataOverlayContext(accessRequest), - type.isEgress() + type ); - results.addAll(AccessEgressMapper.mapFlexAccessEgresses(flexAccessList, type.isEgress())); + results.addAll(AccessEgressMapper.mapFlexAccessEgresses(flexAccessList, type)); } return results; } /** - * Given a list of {@code results} shift the access ones which contain driving - * so that they only start at the time when the ride hailing vehicle can actually be there - * to pick up passengers. + * Given a list of {@code results} shift the access ones that contain driving so that they only + * start at the time when the ride hailing vehicle can actually be there to pick up passengers. *

    - * If there are accesses/egresses with only walking then they remain unchanged. + * If there are accesses/egresses with only walking, then they remain unchanged. *

    * This method is a good candidate to be moved to the access/egress filter chain when that has * been added. @@ -363,9 +371,41 @@ private TemporaryVerticesContainer createTemporaryVerticesContainer( ) { return new TemporaryVerticesContainer( serverContext.graph(), - request, + request.from(), + request.to(), request.journey().access().mode(), request.journey().egress().mode() ); } + + private IntStream listStopIndexes(FeedScopedId stopLocationId) { + Collection stops = serverContext + .transitService() + .findStopOrChildStops(stopLocationId); + + if (stops.isEmpty()) { + throw new EntityNotFoundException( + "Stop, station, multimodal station or group of stations", + stopLocationId + ); + } + return stops.stream().mapToInt(StopLocation::getIndex); + } + + /** + * An optional factory for creating a decorator around the multi-criteria RangeRaptor instance. + */ + @Nullable + private ExtraMcRouterSearch createExtraMcRouterSearch( + AccessEgresses accessEgresses, + TransitLayer transitLayer + ) { + if (OTPFeature.Sorlandsbanen.isOff()) { + return null; + } + var service = serverContext.sorlandsbanenService(); + return service == null + ? null + : service.createExtraMcRouterSearch(request, accessEgresses, transitLayer); + } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouterResult.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouterResult.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouterResult.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouterResult.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/performance/PerformanceTimersForRaptor.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/performance/PerformanceTimersForRaptor.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/performance/PerformanceTimersForRaptor.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/performance/PerformanceTimersForRaptor.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressPenaltyDecorator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressPenaltyDecorator.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressPenaltyDecorator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressPenaltyDecorator.java diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressRouter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressRouter.java new file mode 100644 index 00000000000..0ae2df4e105 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressRouter.java @@ -0,0 +1,95 @@ +package org.opentripplanner.routing.algorithm.raptoradapter.router.street; + +import java.time.Duration; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nullable; +import org.opentripplanner.ext.dataoverlay.routing.DataOverlayContext; +import org.opentripplanner.framework.application.OTPRequestTimeoutException; +import org.opentripplanner.graph_builder.module.nearbystops.StreetNearbyStopFinder; +import org.opentripplanner.routing.api.request.RouteRequest; +import org.opentripplanner.routing.api.request.request.StreetRequest; +import org.opentripplanner.routing.graphfinder.NearbyStop; +import org.opentripplanner.street.search.TemporaryVerticesContainer; +import org.opentripplanner.utils.collection.ListUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This uses a street search to find paths to all the access/egress stop within range + */ +public class AccessEgressRouter { + + private static final Logger LOG = LoggerFactory.getLogger(AccessEgressRouter.class); + + private AccessEgressRouter() {} + + /** + * Find accesses or egresses. + */ + public static Collection findAccessEgresses( + RouteRequest request, + TemporaryVerticesContainer verticesContainer, + StreetRequest streetRequest, + @Nullable DataOverlayContext dataOverlayContext, + AccessEgressType accessOrEgress, + Duration durationLimit, + int maxStopCount + ) { + OTPRequestTimeoutException.checkForTimeout(); + + // Note: We calculate access/egresses in two parts. First we fetch the stops with zero distance. + // Then we do street search. This is because some stations might use the centroid for street + // routing, but should still give zero distance access/egresses to its child-stops. + var zeroDistanceAccessEgress = findAccessEgressWithZeroDistance( + verticesContainer, + request, + streetRequest, + accessOrEgress + ); + + // When looking for street accesses/egresses we ignore the already found direct accesses/egresses + var ignoreVertices = zeroDistanceAccessEgress + .stream() + .map(nearbyStop -> nearbyStop.state.getVertex()) + .collect(Collectors.toSet()); + + var originVertices = accessOrEgress.isAccess() + ? verticesContainer.getFromVertices() + : verticesContainer.getToVertices(); + var streetAccessEgress = new StreetNearbyStopFinder( + durationLimit, + maxStopCount, + dataOverlayContext, + ignoreVertices + ) + .findNearbyStops(originVertices, request, streetRequest, accessOrEgress.isEgress()); + + var results = ListUtils.combine(zeroDistanceAccessEgress, streetAccessEgress); + LOG.debug("Found {} {} stops", results.size(), accessOrEgress); + return results; + } + + /** + * Return a list of direct accesses/egresses that do not require any street search. This will + * return an empty list if the source/destination is not a stopId. + */ + private static List findAccessEgressWithZeroDistance( + TemporaryVerticesContainer verticesContainer, + RouteRequest routeRequest, + StreetRequest streetRequest, + AccessEgressType accessOrEgress + ) { + var transitStopVertices = accessOrEgress.isAccess() + ? verticesContainer.getFromStopVertices() + : verticesContainer.getToStopVertices(); + + return NearbyStop.nearbyStopsForTransitStopVerticesFiltered( + transitStopVertices, + accessOrEgress.isEgress(), + routeRequest, + streetRequest + ); + } +} diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressType.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressType.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressType.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressType.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgresses.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgresses.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgresses.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgresses.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectFlexRouter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectFlexRouter.java similarity index 89% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectFlexRouter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectFlexRouter.java index 8e4cf1b222f..6d54973bff9 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectFlexRouter.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectFlexRouter.java @@ -28,27 +28,28 @@ public static List route( try ( var temporaryVertices = new TemporaryVerticesContainer( serverContext.graph(), - request, + request.from(), + request.to(), request.journey().direct().mode(), request.journey().direct().mode() ) ) { // Prepare access/egress transfers - Collection accessStops = AccessEgressRouter.streetSearch( + Collection accessStops = AccessEgressRouter.findAccessEgresses( request, temporaryVertices, request.journey().direct(), serverContext.dataOverlayContext(request), - false, + AccessEgressType.ACCESS, serverContext.flexParameters().maxAccessWalkDuration(), 0 ); - Collection egressStops = AccessEgressRouter.streetSearch( + Collection egressStops = AccessEgressRouter.findAccessEgresses( request, temporaryVertices, request.journey().direct(), serverContext.dataOverlayContext(request), - true, + AccessEgressType.EGRESS, serverContext.flexParameters().maxEgressWalkDuration(), 0 ); diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java similarity index 95% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java index 11463902dcd..7d73d705dfe 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java @@ -18,6 +18,12 @@ import org.opentripplanner.street.search.TemporaryVerticesContainer; import org.opentripplanner.street.search.state.State; +/** + * Generates "direct" street routes, i.e. those that do not use transit and are on the street + * network for the entire itinerary. + * + * @see DirectFlexRouter + */ public class DirectStreetRouter { public static List route(OtpServerRequestContext serverContext, RouteRequest request) { @@ -30,7 +36,8 @@ public static List route(OtpServerRequestContext serverContext, Route try ( var temporaryVertices = new TemporaryVerticesContainer( serverContext.graph(), - directRequest, + directRequest.from(), + directRequest.to(), request.journey().direct().mode(), request.journey().direct().mode() ) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/FlexAccessEgressRouter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/FlexAccessEgressRouter.java similarity index 83% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/FlexAccessEgressRouter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/FlexAccessEgressRouter.java index 68dda38211a..f5aa9142fac 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/FlexAccessEgressRouter.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/FlexAccessEgressRouter.java @@ -27,31 +27,31 @@ public static Collection routeAccessEgress( AdditionalSearchDays searchDays, FlexParameters config, DataOverlayContext dataOverlayContext, - boolean isEgress + AccessEgressType accessOrEgress ) { OTPRequestTimeoutException.checkForTimeout(); TransitService transitService = serverContext.transitService(); - Collection accessStops = !isEgress - ? AccessEgressRouter.streetSearch( + Collection accessStops = accessOrEgress.isAccess() + ? AccessEgressRouter.findAccessEgresses( request, verticesContainer, new StreetRequest(StreetMode.WALK), dataOverlayContext, - false, + AccessEgressType.ACCESS, serverContext.flexParameters().maxAccessWalkDuration(), 0 ) : List.of(); - Collection egressStops = isEgress - ? AccessEgressRouter.streetSearch( + Collection egressStops = accessOrEgress.isEgress() + ? AccessEgressRouter.findAccessEgresses( request, verticesContainer, new StreetRequest(StreetMode.WALK), dataOverlayContext, - true, + AccessEgressType.EGRESS, serverContext.flexParameters().maxEgressWalkDuration(), 0 ) @@ -69,6 +69,8 @@ public static Collection routeAccessEgress( egressStops ); - return isEgress ? flexRouter.createFlexEgresses() : flexRouter.createFlexAccesses(); + return accessOrEgress.isEgress() + ? flexRouter.createFlexEgresses() + : flexRouter.createFlexAccesses(); } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgress.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgress.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgress.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgress.java index 3f68d91321e..584e690d3ee 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgress.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgress.java @@ -3,7 +3,7 @@ import java.util.Objects; import org.opentripplanner.framework.model.TimeAndCost; import org.opentripplanner.raptor.api.model.RaptorConstants; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.street.search.state.State; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultRaptorTransfer.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultRaptorTransfer.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultRaptorTransfer.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultRaptorTransfer.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/FlexAccessEgressAdapter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/FlexAccessEgressAdapter.java similarity index 85% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/FlexAccessEgressAdapter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/FlexAccessEgressAdapter.java index 04f51e76681..64650ab9e92 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/FlexAccessEgressAdapter.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/FlexAccessEgressAdapter.java @@ -4,6 +4,7 @@ import org.opentripplanner.framework.model.TimeAndCost; import org.opentripplanner.model.StopTime; import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.routing.algorithm.raptoradapter.router.street.AccessEgressType; /** * This class is used to adapt the FlexAccessEgress into a time-dependent multi-leg DefaultAccessEgress. @@ -12,10 +13,15 @@ public class FlexAccessEgressAdapter extends DefaultAccessEgress { private final FlexAccessEgress flexAccessEgress; - public FlexAccessEgressAdapter(FlexAccessEgress flexAccessEgress, boolean isEgress) { + public FlexAccessEgressAdapter( + FlexAccessEgress flexAccessEgress, + AccessEgressType accessOrEgress + ) { super( flexAccessEgress.stop().getIndex(), - isEgress ? flexAccessEgress.lastState().reverse() : flexAccessEgress.lastState() + accessOrEgress.isEgress() + ? flexAccessEgress.lastState().reverse() + : flexAccessEgress.lastState() ); this.flexAccessEgress = flexAccessEgress; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/RaptorTransferIndex.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/RaptorTransferIndex.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/RaptorTransferIndex.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/RaptorTransferIndex.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/RoutingAccessEgress.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/RoutingAccessEgress.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/RoutingAccessEgress.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/RoutingAccessEgress.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/SlackProvider.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/SlackProvider.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/SlackProvider.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/SlackProvider.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/Transfer.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/Transfer.java similarity index 90% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/Transfer.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/Transfer.java index c6086100f5d..32d54787e6f 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/Transfer.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/Transfer.java @@ -4,16 +4,17 @@ import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.Set; import org.locationtech.jts.geom.Coordinate; -import org.opentripplanner.framework.logging.Throttle; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.raptor.api.model.RaptorTransfer; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; import org.opentripplanner.routing.api.request.preference.WalkPreferences; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.search.request.StreetSearchRequest; import org.opentripplanner.street.search.state.EdgeTraverser; -import org.opentripplanner.street.search.state.StateEditor; +import org.opentripplanner.street.search.state.State; +import org.opentripplanner.utils.logging.Throttle; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -84,10 +85,8 @@ public Optional asRaptorTransfer(StreetSearchRequest request) { ); } - StateEditor se = new StateEditor(edges.get(0).getFromVertex(), request); - se.setTimeSeconds(0); - - var state = EdgeTraverser.traverseEdges(se.makeState(), edges); + var initialStates = State.getInitialStates(Set.of(edges.getFirst().getFromVertex()), request); + var state = EdgeTraverser.traverseEdges(initialStates, edges); return state.map(s -> new DefaultRaptorTransfer( diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayer.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayer.java similarity index 94% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayer.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayer.java index e5f0544f584..c7d6a7809ed 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayer.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayer.java @@ -14,18 +14,18 @@ import org.opentripplanner.routing.algorithm.raptoradapter.transit.request.RaptorRequestTransferCache; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.transit.model.site.StopLocation; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; /** - * This is a replica of public transportation data already present in TransitModel, but rearranged + * This is a replica of public transportation data already present in TimetableRepository, but rearranged * and indexed differently for efficient use by the Raptor router. Patterns and trips are split out * by days, retaining only the services actually running on any particular day. * * TODO RT_AB: this name may reflect usage in R5, where the TransportNetwork encompasses two * sub-aggregates (one for the streets and one for the public transit data). Here, the TransitLayer - * seems to just be an indexed and rearranged copy of the main TransitModel instance. TG has + * seems to just be an indexed and rearranged copy of the main TimetableRepository instance. TG has * indicated that "layer" should be restricted in its standard OO meaning, and this class should - * really be merged into TransitModel. + * really be merged into TimetableRepository. */ public class TransitLayer { @@ -48,7 +48,7 @@ public class TransitLayer { */ private final TransferService transferService; - private final StopModel stopModel; + private final SiteRepository siteRepository; private final RaptorRequestTransferCache transferCache; @@ -69,7 +69,7 @@ public TransitLayer(TransitLayer transitLayer) { transitLayer.tripPatternsRunningOnDate, transitLayer.transfersByStopIndex, transitLayer.transferService, - transitLayer.stopModel, + transitLayer.siteRepository, transitLayer.transferCache, transitLayer.constrainedTransfers, transitLayer.transferIndexGenerator, @@ -81,7 +81,7 @@ public TransitLayer( Map> tripPatternsRunningOnDate, List> transfersByStopIndex, TransferService transferService, - StopModel stopModel, + SiteRepository siteRepository, RaptorRequestTransferCache transferCache, ConstrainedTransfersForPatterns constrainedTransfers, TransferIndexGenerator transferIndexGenerator, @@ -90,7 +90,7 @@ public TransitLayer( this.tripPatternsRunningOnDate = new HashMap<>(tripPatternsRunningOnDate); this.transfersByStopIndex = transfersByStopIndex; this.transferService = transferService; - this.stopModel = stopModel; + this.siteRepository = siteRepository; this.transferCache = transferCache; this.constrainedTransfers = constrainedTransfers; this.transferIndexGenerator = transferIndexGenerator; @@ -99,7 +99,7 @@ public TransitLayer( @Nullable public StopLocation getStopByIndex(int stop) { - return stop == -1 ? null : this.stopModel.stopByIndex(stop); + return stop == -1 ? null : this.siteRepository.stopByIndex(stop); } /** @@ -112,7 +112,7 @@ public Collection getTripPatternsForRunningDate(LocalDate da } public int getStopCount() { - return stopModel.stopIndexSize(); + return siteRepository.stopIndexSize(); } /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitTuningParameters.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitTuningParameters.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitTuningParameters.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitTuningParameters.java index b62459db679..c2e518a9ec1 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitTuningParameters.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitTuningParameters.java @@ -2,9 +2,9 @@ import java.time.Duration; import java.util.List; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.transit.model.site.StopTransferPriority; +import org.opentripplanner.utils.time.DurationUtils; public interface TransitTuningParameters { List PAGING_SEARCH_WINDOW_ADJUSTMENTS = DurationUtils.durations("4h 2h 1h 30m 20m 10m"); diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDate.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDate.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDate.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDate.java index 1411424dfc6..eeaf1312677 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDate.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDate.java @@ -8,10 +8,10 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import javax.annotation.Nullable; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.transit.model.network.RoutingTripPattern; import org.opentripplanner.transit.model.timetable.FrequencyEntry; import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.utils.time.ServiceDateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripSchedule.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripSchedule.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripSchedule.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripSchedule.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearch.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearch.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearch.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearch.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchForward.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchForward.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchForward.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchForward.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchReverse.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchReverse.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchReverse.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchReverse.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchStrategy.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchStrategy.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchStrategy.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchStrategy.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedTransferBoarding.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedTransferBoarding.java similarity index 94% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedTransferBoarding.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedTransferBoarding.java index 63a0d50aa03..bf5de51e2c8 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedTransferBoarding.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedTransferBoarding.java @@ -1,7 +1,6 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.constrainedtransfer; import java.util.function.Consumer; -import javax.annotation.Nonnull; import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent; @@ -20,7 +19,7 @@ public class ConstrainedTransferBoarding private final int earliestBoardTime; public ConstrainedTransferBoarding( - @Nonnull RaptorTransferConstraint constraint, + RaptorTransferConstraint constraint, int tripIndex, T trip, int stopPositionInPattern, @@ -41,7 +40,6 @@ public int tripIndex() { } @Override - @Nonnull public T trip() { return trip; } @@ -62,7 +60,6 @@ public int earliestBoardTime() { } @Override - @Nonnull public RaptorTransferConstraint transferConstraint() { return constraint; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedTransfersForPatterns.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedTransfersForPatterns.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedTransfersForPatterns.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedTransfersForPatterns.java index f3b8eac0dd2..670c223e87d 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedTransfersForPatterns.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedTransfersForPatterns.java @@ -2,7 +2,7 @@ import java.util.List; import java.util.Objects; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This is a container for returning transfers from and to stop-positions indexed by diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferForPattern.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferForPattern.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferForPattern.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferForPattern.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferForPatternByStopPos.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferForPatternByStopPos.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferForPatternByStopPos.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferForPatternByStopPos.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferIndexGenerator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferIndexGenerator.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferIndexGenerator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferIndexGenerator.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferPointForPatternFactory.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferPointForPatternFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferPointForPatternFactory.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferPointForPatternFactory.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferPointMatcher.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferPointMatcher.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferPointMatcher.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferPointMatcher.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/CostCalculatorFactory.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/CostCalculatorFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/CostCalculatorFactory.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/CostCalculatorFactory.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculator.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculator.java index 43faa3f0c40..1d4827a4ef6 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculator.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculator.java @@ -3,6 +3,7 @@ import javax.annotation.Nullable; import org.opentripplanner.model.transfer.TransferConstraint; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; import org.opentripplanner.raptor.spi.RaptorCostCalculator; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultTripSchedule.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultTripSchedule.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultTripSchedule.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultTripSchedule.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/FactorStrategy.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/FactorStrategy.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/FactorStrategy.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/FactorStrategy.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/GeneralizedCostParameters.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/GeneralizedCostParameters.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/GeneralizedCostParameters.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/GeneralizedCostParameters.java index e1271aca199..eee0fbf36c0 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/GeneralizedCostParameters.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/GeneralizedCostParameters.java @@ -3,9 +3,9 @@ import java.util.BitSet; import java.util.Objects; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.preference.AccessibilityPreferences; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This class define how to calculate the cost when cost is part of the multi-criteria pareto diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/GeneralizedCostParametersBuilder.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/GeneralizedCostParametersBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/GeneralizedCostParametersBuilder.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/GeneralizedCostParametersBuilder.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/IndexBasedFactorStrategy.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/IndexBasedFactorStrategy.java similarity index 93% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/IndexBasedFactorStrategy.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/IndexBasedFactorStrategy.java index 152f199248c..9fac19cd940 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/IndexBasedFactorStrategy.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/IndexBasedFactorStrategy.java @@ -1,6 +1,7 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.cost; import java.util.Arrays; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; /** * This class keep a facto for each index and the minimum factor for fast retrieval during Raptor diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/PatternCostCalculator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/PatternCostCalculator.java similarity index 92% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/PatternCostCalculator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/PatternCostCalculator.java index 734355f0ac5..d611c73b7ad 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/PatternCostCalculator.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/PatternCostCalculator.java @@ -1,7 +1,6 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.cost; import java.util.BitSet; -import javax.annotation.Nonnull; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; import org.opentripplanner.raptor.spi.RaptorCostCalculator; @@ -13,9 +12,9 @@ class PatternCostCalculator implements RaptorCost private final RaptorCostLinearFunction unpreferredCost; PatternCostCalculator( - @Nonnull RaptorCostCalculator delegate, - @Nonnull BitSet unpreferredPatterns, - @Nonnull RaptorCostLinearFunction unpreferredCost + RaptorCostCalculator delegate, + BitSet unpreferredPatterns, + RaptorCostLinearFunction unpreferredCost ) { this.unpreferredPatterns = unpreferredPatterns; this.delegate = delegate; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostLinearFunction.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostLinearFunction.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostLinearFunction.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostLinearFunction.java index b636b26bebe..f231acf9270 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostLinearFunction.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostLinearFunction.java @@ -2,6 +2,7 @@ import java.util.Objects; import org.opentripplanner.framework.model.Cost; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.framework.LinearFunctionSerialization; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/SingleValueFactorStrategy.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/SingleValueFactorStrategy.java similarity index 91% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/SingleValueFactorStrategy.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/SingleValueFactorStrategy.java index 59cf04eb2db..3e5b868afdb 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/SingleValueFactorStrategy.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/SingleValueFactorStrategy.java @@ -1,5 +1,7 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.cost; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; + /** * This {@link FactorStrategy} keep a single value and use it every time the factor is needed. The * {@link #minFactor()} return the same value. diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculator.java similarity index 94% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculator.java index d0697f78692..693cac45031 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculator.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculator.java @@ -1,7 +1,7 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.cost; -import javax.annotation.Nonnull; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; import org.opentripplanner.raptor.spi.RaptorCostCalculator; import org.opentripplanner.routing.api.request.preference.AccessibilityPreferences; @@ -14,8 +14,8 @@ public class WheelchairCostCalculator private final int[] wheelchairBoardingCost; public WheelchairCostCalculator( - @Nonnull RaptorCostCalculator delegate, - @Nonnull AccessibilityPreferences wheelchairAccessibility + RaptorCostCalculator delegate, + AccessibilityPreferences wheelchairAccessibility ) { this.delegate = delegate; this.wheelchairBoardingCost = createWheelchairCost(wheelchairAccessibility); diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyAlightEvent.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyAlightEvent.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyAlightEvent.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyAlightEvent.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardOrAlightEvent.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardOrAlightEvent.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardOrAlightEvent.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardOrAlightEvent.java index 927b1d966ed..b2cbb51fb00 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardOrAlightEvent.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardOrAlightEvent.java @@ -1,7 +1,6 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.frequency; import java.time.LocalDate; -import javax.annotation.Nonnull; import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; import org.opentripplanner.raptor.api.model.RaptorTripPattern; import org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent; @@ -90,7 +89,6 @@ public int earliestBoardTime() { } @Override - @Nonnull public RaptorTransferConstraint transferConstraint() { return RaptorTransferConstraint.REGULAR_TRANSFER; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardingEvent.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardingEvent.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardingEvent.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/FrequencyBoardingEvent.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyAlightSearch.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyAlightSearch.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyAlightSearch.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyAlightSearch.java index 2f020e22cf5..ff97fd9bdaa 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyAlightSearch.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyAlightSearch.java @@ -60,6 +60,6 @@ public RaptorBoardOrAlightEvent search( } } } - return null; + return RaptorBoardOrAlightEvent.empty(earliestBoardTime); } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyBoardSearch.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyBoardSearch.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyBoardSearch.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/frequency/TripFrequencyBoardSearch.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/AccessEgressMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/AccessEgressMapper.java similarity index 74% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/AccessEgressMapper.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/AccessEgressMapper.java index fd7619ac297..2205a2feb7b 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/AccessEgressMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/AccessEgressMapper.java @@ -5,6 +5,7 @@ import java.util.Objects; import java.util.stream.Collectors; import org.opentripplanner.ext.flex.FlexAccessEgress; +import org.opentripplanner.routing.algorithm.raptoradapter.router.street.AccessEgressType; import org.opentripplanner.routing.algorithm.raptoradapter.transit.DefaultAccessEgress; import org.opentripplanner.routing.algorithm.raptoradapter.transit.FlexAccessEgressAdapter; import org.opentripplanner.routing.algorithm.raptoradapter.transit.RoutingAccessEgress; @@ -15,33 +16,36 @@ public class AccessEgressMapper { public static List mapNearbyStops( Collection accessStops, - boolean isEgress + AccessEgressType accessOrEgress ) { return accessStops .stream() - .map(stopAtDistance -> mapNearbyStop(stopAtDistance, isEgress)) + .map(nearbyStop -> mapNearbyStop(nearbyStop, accessOrEgress)) .filter(Objects::nonNull) .collect(Collectors.toList()); } public static Collection mapFlexAccessEgresses( Collection flexAccessEgresses, - boolean isEgress + AccessEgressType accessOrEgress ) { return flexAccessEgresses .stream() - .map(flexAccessEgress -> new FlexAccessEgressAdapter(flexAccessEgress, isEgress)) + .map(flexAccessEgress -> new FlexAccessEgressAdapter(flexAccessEgress, accessOrEgress)) .collect(Collectors.toList()); } - private static RoutingAccessEgress mapNearbyStop(NearbyStop nearbyStop, boolean isEgress) { + private static RoutingAccessEgress mapNearbyStop( + NearbyStop nearbyStop, + AccessEgressType accessOrEgress + ) { if (!(nearbyStop.stop instanceof RegularStop)) { return null; } return new DefaultAccessEgress( nearbyStop.stop.getIndex(), - isEgress ? nearbyStop.state.reverse() : nearbyStop.state + accessOrEgress.isEgress() ? nearbyStop.state.reverse() : nearbyStop.state ); } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/GeneralizedCostParametersMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/GeneralizedCostParametersMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/GeneralizedCostParametersMapper.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/GeneralizedCostParametersMapper.java diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/LookupStopIndexCallback.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/LookupStopIndexCallback.java new file mode 100644 index 00000000000..91946ab07e9 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/LookupStopIndexCallback.java @@ -0,0 +1,35 @@ +package org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers; + +import java.util.Collection; +import java.util.stream.IntStream; +import org.opentripplanner.transit.model.framework.FeedScopedId; + +/** + * The raptor mapper does not have access to the transit layer, so it needs help to + * lookup stop-location indexes (Stop index used by Raptor). There is a one-to-one + * mapping between stops and stop-index, but a station, multimodal-station or group-of-stations + * will most likely contain more than one stop. + */ +@FunctionalInterface +public interface LookupStopIndexCallback { + /** + * The implementation of this method should list all stop indexes part of the entity referenced + * by the given id. + * @return a stream of stop indexes. We return a stream here because we need to merge this with + * the indexes of other stops. + */ + IntStream lookupStopLocationIndexes(FeedScopedId stopLocationId); + + /** + * Take a set of stop location ids and convert them into a sorted distinct list of + * stop indexes. + */ + default int[] lookupStopLocationIndexes(Collection stopLocationIds) { + return stopLocationIds + .stream() + .flatMapToInt(this::lookupStopLocationIndexes) + .sorted() + .distinct() + .toArray(); + } +} diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java similarity index 66% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java index 948b132e408..c5a75b02bbc 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java @@ -7,25 +7,29 @@ import java.time.ZonedDateTime; import java.util.Collection; import java.util.List; +import java.util.function.Predicate; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.raptor.api.model.GeneralizedCostRelaxFunction; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.model.RelaxFunction; import org.opentripplanner.raptor.api.request.DebugRequestBuilder; +import org.opentripplanner.raptor.api.request.MultiCriteriaRequest; import org.opentripplanner.raptor.api.request.Optimization; import org.opentripplanner.raptor.api.request.PassThroughPoint; import org.opentripplanner.raptor.api.request.RaptorRequest; import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; +import org.opentripplanner.raptor.api.request.RaptorViaLocation; import org.opentripplanner.raptor.rangeraptor.SystemErrDebugLogger; import org.opentripplanner.routing.algorithm.raptoradapter.router.performance.PerformanceTimersForRaptor; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; import org.opentripplanner.routing.api.request.DebugEventType; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; +import org.opentripplanner.routing.api.request.preference.TransitPreferences; +import org.opentripplanner.routing.api.request.via.ViaLocation; import org.opentripplanner.transit.model.network.grouppriority.DefaultTransitGroupPriorityCalculator; -import org.opentripplanner.transit.model.site.StopLocation; public class RaptorRequestMapper { @@ -35,6 +39,7 @@ public class RaptorRequestMapper { private final long transitSearchTimeZeroEpocSecond; private final boolean isMultiThreadedEnbled; private final MeterRegistry meterRegistry; + private final LookupStopIndexCallback lookUpStopIndex; private RaptorRequestMapper( RouteRequest request, @@ -42,7 +47,8 @@ private RaptorRequestMapper( Collection accessPaths, Collection egressPaths, long transitSearchTimeZeroEpocSecond, - MeterRegistry meterRegistry + MeterRegistry meterRegistry, + LookupStopIndexCallback lookUpStopIndex ) { this.request = request; this.isMultiThreadedEnbled = isMultiThreaded; @@ -50,6 +56,7 @@ private RaptorRequestMapper( this.egressPaths = egressPaths; this.transitSearchTimeZeroEpocSecond = transitSearchTimeZeroEpocSecond; this.meterRegistry = meterRegistry; + this.lookUpStopIndex = lookUpStopIndex; } public static RaptorRequest mapRequest( @@ -58,7 +65,8 @@ public static RaptorRequest mapRequest( boolean isMultiThreaded, Collection accessPaths, Collection egressPaths, - MeterRegistry meterRegistry + MeterRegistry meterRegistry, + LookupStopIndexCallback lookUpStopIndex ) { return new RaptorRequestMapper( request, @@ -66,7 +74,8 @@ public static RaptorRequest mapRequest( accessPaths, egressPaths, transitSearchTimeZero.toEpochSecond(), - meterRegistry + meterRegistry, + lookUpStopIndex ) .doMap(); } @@ -77,6 +86,13 @@ private RaptorRequest doMap() { var preferences = request.preferences(); + // TODO Fix the Raptor search so pass-through and via search can be used together. + if (hasViaLocationsAndPassThroughLocations()) { + throw new IllegalArgumentException( + "A mix of via-locations and pass-through is not allowed in this version." + ); + } + if (request.pageCursor() == null) { int time = relativeTime(request.dateTime()); @@ -114,13 +130,20 @@ private RaptorRequest doMap() { var pt = preferences.transit(); var r = pt.raptor(); - // Note! If a pass-through-point exists, then the transit-group-priority feature is disabled - if (!request.getPassThroughPoints().isEmpty()) { + if (hasPassThroughOnly()) { mcBuilder.withPassThroughPoints(mapPassThroughPoints()); + } else if (hasViaLocationsOnly()) { + builder.searchParams().addViaLocations(mapViaLocations()); + // relax transit group priority can be used with via-visit-stop, but not with pass-through + if (pt.isRelaxTransitGroupPrioritySet()) { + mapRelaxTransitGroupPriority(mcBuilder, pt); + } + } else if (pt.isRelaxTransitGroupPrioritySet()) { + mapRelaxTransitGroupPriority(mcBuilder, pt); + } else { + // The deprecated relaxGeneralizedCostAtDestination is only enabled, if there is no + // via location and the relaxTransitGroupPriority is not used (Normal). r.relaxGeneralizedCostAtDestination().ifPresent(mcBuilder::withRelaxCostAtDestination); - } else if (!pt.relaxTransitGroupPriority().isNormal()) { - mcBuilder.withTransitPriorityCalculator(new DefaultTransitGroupPriorityCalculator()); - mcBuilder.withRelaxC1(mapRelaxCost(pt.relaxTransitGroupPriority())); } }); @@ -175,19 +198,63 @@ private RaptorRequest doMap() { ) ); } - return builder.build(); } + private boolean hasPassThroughOnly() { + return ( + request.isViaSearch() && + request.getViaLocations().stream().allMatch(ViaLocation::isPassThroughLocation) + ); + } + + private boolean hasViaLocationsOnly() { + return ( + request.isViaSearch() && + request.getViaLocations().stream().noneMatch(ViaLocation::isPassThroughLocation) + ); + } + + private boolean hasViaLocationsAndPassThroughLocations() { + var c = request.getViaLocations(); + return ( + request.isViaSearch() && + c.stream().anyMatch(ViaLocation::isPassThroughLocation) && + c.stream().anyMatch(Predicate.not(ViaLocation::isPassThroughLocation)) + ); + } + + private List mapViaLocations() { + return request.getViaLocations().stream().map(this::mapViaLocation).toList(); + } + + private RaptorViaLocation mapViaLocation(ViaLocation input) { + if (input.isPassThroughLocation()) { + var builder = RaptorViaLocation.allowPassThrough(input.label()); + for (int stopIndex : lookUpStopIndex.lookupStopLocationIndexes(input.stopLocationIds())) { + builder.addViaStop(stopIndex); + } + return builder.build(); + } + // Visit Via location + else { + var builder = RaptorViaLocation.via(input.label(), input.minimumWaitTime()); + for (int stopIndex : lookUpStopIndex.lookupStopLocationIndexes(input.stopLocationIds())) { + builder.addViaStop(stopIndex); + } + return builder.build(); + } + } + private List mapPassThroughPoints() { - return request - .getPassThroughPoints() - .stream() - .map(p -> { - final int[] stops = p.stopLocations().stream().mapToInt(StopLocation::getIndex).toArray(); - return new PassThroughPoint(p.name(), stops); - }) - .toList(); + return request.getViaLocations().stream().map(this::mapPassThroughPoints).toList(); + } + + private PassThroughPoint mapPassThroughPoints(ViaLocation location) { + return new PassThroughPoint( + location.label(), + lookUpStopIndex.lookupStopLocationIndexes(location.stopLocationIds()) + ); } static RelaxFunction mapRelaxCost(CostLinearFunction relax) { @@ -207,6 +274,14 @@ private int relativeTime(Instant time) { return (int) (time.getEpochSecond() - transitSearchTimeZeroEpocSecond); } + private static void mapRelaxTransitGroupPriority( + MultiCriteriaRequest.Builder mcBuilder, + TransitPreferences pt + ) { + mcBuilder.withTransitPriorityCalculator(new DefaultTransitGroupPriorityCalculator()); + mcBuilder.withRelaxC1(mapRelaxCost(pt.relaxTransitGroupPriority())); + } + private static void addLogListenerForEachEventTypeRequested( DebugRequestBuilder target, DebugEventType type, diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransfersMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransfersMapper.java similarity index 79% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransfersMapper.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransfersMapper.java index c7e9ea05320..ff47cb3ea74 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransfersMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransfersMapper.java @@ -5,7 +5,7 @@ import org.opentripplanner.model.PathTransfer; import org.opentripplanner.routing.algorithm.raptoradapter.transit.Transfer; import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; import org.opentripplanner.transit.service.TransitService; class TransfersMapper { @@ -14,11 +14,14 @@ class TransfersMapper { * Copy pre-calculated transfers from the original graph * @return a list where each element is a list of transfers for the corresponding stop index */ - static List> mapTransfers(StopModel stopModel, TransitService transitService) { + static List> mapTransfers( + SiteRepository siteRepository, + TransitService transitService + ) { List> transferByStopIndex = new ArrayList<>(); - for (int i = 0; i < stopModel.stopIndexSize(); ++i) { - var stop = stopModel.stopByIndex(i); + for (int i = 0; i < siteRepository.stopIndexSize(); ++i) { + var stop = siteRepository.stopByIndex(i); if (stop == null) { continue; @@ -26,7 +29,7 @@ static List> mapTransfers(StopModel stopModel, TransitService tra ArrayList list = new ArrayList<>(); - for (PathTransfer pathTransfer : transitService.getTransfersByStop(stop)) { + for (PathTransfer pathTransfer : transitService.findPathTransfers(stop)) { if (pathTransfer.to instanceof RegularStop) { int toStopIndex = pathTransfer.to.getIndex(); Transfer newTransfer; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapper.java similarity index 81% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapper.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapper.java index d375b4c546c..d6f9c0709c5 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapper.java @@ -7,35 +7,31 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; import javax.annotation.Nullable; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.model.Timetable; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.routing.algorithm.raptoradapter.transit.Transfer; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitLayer; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitTuningParameters; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripPatternForDate; import org.opentripplanner.routing.algorithm.raptoradapter.transit.constrainedtransfer.ConstrainedTransfersForPatterns; import org.opentripplanner.routing.algorithm.raptoradapter.transit.constrainedtransfer.TransferIndexGenerator; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; import org.opentripplanner.routing.algorithm.raptoradapter.transit.request.RaptorRequestTransferCache; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.StopTransferPriority; -import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.transit.service.TransitService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Maps the TransitLayer object from the TransitModel object. The ServiceDay hierarchy is reversed, + * Maps the TransitLayer object from the TimetableRepository object. The ServiceDay hierarchy is reversed, * with service days at the top level, which contains TripPatternForDate objects that contain only * TripSchedules running on that particular date. This makes it faster to filter out TripSchedules * when doing Range Raptor searches. @@ -50,28 +46,18 @@ public class TransitLayerMapper { private static final Logger LOG = LoggerFactory.getLogger(TransitLayerMapper.class); private final TransitService transitService; - private final StopModel stopModel; + private final SiteRepository siteRepository; - private TransitLayerMapper(TransitModel transitModel) { - this.transitService = new DefaultTransitService(transitModel); - this.stopModel = transitModel.getStopModel(); + private TransitLayerMapper(TimetableRepository timetableRepository) { + this.transitService = new DefaultTransitService(timetableRepository); + this.siteRepository = timetableRepository.getSiteRepository(); } public static TransitLayer map( TransitTuningParameters tuningParameters, - TransitModel transitModel + TimetableRepository timetableRepository ) { - return new TransitLayerMapper(transitModel).map(tuningParameters); - } - - // TODO We could save time by either pre-sorting these, or by using a sorting algorithm that is - // optimized for sorting nearly-sorted lists. - static List getSortedTripTimes(Timetable timetable) { - return timetable - .getTripTimes() - .stream() - .sorted(Comparator.comparing(TripTimes::sortIndex)) - .collect(Collectors.toList()); + return new TransitLayerMapper(timetableRepository).map(tuningParameters); } private TransitLayer map(TransitTuningParameters tuningParameters) { @@ -79,13 +65,13 @@ private TransitLayer map(TransitTuningParameters tuningParameters) { List> transferByStopIndex; ConstrainedTransfersForPatterns constrainedTransfers = null; - LOG.info("Mapping transitLayer from TransitModel..."); + LOG.info("Mapping transitLayer from TimetableRepository..."); - Collection allTripPatterns = transitService.getAllTripPatterns(); + Collection allTripPatterns = transitService.listTripPatterns(); tripPatternsByStopByDate = mapTripPatterns(allTripPatterns); - transferByStopIndex = mapTransfers(stopModel, transitService); + transferByStopIndex = mapTransfers(siteRepository, transitService); TransferIndexGenerator transferIndexGenerator = null; if (OTPFeature.TransferConstraints.isOn()) { @@ -102,11 +88,11 @@ private TransitLayer map(TransitTuningParameters tuningParameters) { tripPatternsByStopByDate, transferByStopIndex, transitService.getTransferService(), - stopModel, + siteRepository, transferCache, constrainedTransfers, transferIndexGenerator, - createStopBoardAlightTransferCosts(stopModel, tuningParameters) + createStopBoardAlightTransferCosts(siteRepository, tuningParameters) ); } @@ -123,7 +109,7 @@ private HashMap> mapTripPatterns( transitService.getServiceCodesRunningForDate() ); - Set allServiceDates = transitService.getAllServiceCodes(); + Set allServiceDates = transitService.listServiceDates(); List tripPatternForDates = Collections.synchronizedList(new ArrayList<>()); @@ -183,7 +169,7 @@ private HashMap> keyByRunningPeriodDates( */ @Nullable static int[] createStopBoardAlightTransferCosts( - StopModel stops, + SiteRepository stops, TransitTuningParameters tuningParams ) { if (!tuningParams.enableStopTransferPriority()) { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerUpdater.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerUpdater.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerUpdater.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerUpdater.java index 934bec39c11..8b307321ca8 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerUpdater.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerUpdater.java @@ -30,7 +30,7 @@ * the updated copy in an atomic operation. This ensures that any TransitLayer that is referenced * from the Graph is never changed. * - * This is a way of keeping the TransitLayer up to date (in sync with the TransitModel plus its most + * This is a way of keeping the TransitLayer up to date (in sync with the TimetableRepository plus its most * recent TimetableSnapshot) without repeatedly deriving it from scratch every few seconds. The same * incremental changes are applied to both the TimetableSnapshot and the TransitLayer and they are * published together. @@ -60,7 +60,7 @@ public TransitLayerUpdater(TransitEditorService transitService) { } public void update( - Set updatedTimetables, + Collection updatedTimetables, Map> timetables ) { if (!transitService.hasRealtimeTransitLayer()) { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapper.java similarity index 77% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapper.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapper.java index cd00b9356dc..256a268e2c7 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapper.java @@ -3,12 +3,9 @@ import gnu.trove.set.TIntSet; import java.time.LocalDate; import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.stream.Collectors; import javax.annotation.Nullable; import org.opentripplanner.model.Timetable; @@ -33,8 +30,6 @@ public class TripPatternForDateMapper { private static final Logger LOG = LoggerFactory.getLogger(TripPatternForDateMapper.class); - private final ConcurrentMap> sortedTripTimesForTimetable = new ConcurrentHashMap<>(); - private final Map serviceCodesRunningForDate; /** @@ -69,19 +64,7 @@ public TripPatternForDate map(Timetable timetable, LocalDate serviceDate) { List times = new ArrayList<>(); - // The TripTimes are not sorted by departure time in the source timetable because - // OTP1 performs a simple/ linear search. Raptor results depend on trips being - // sorted. We reuse the same timetables many times on different days, so cache the - // sorted versions to avoid repeated compute-intensive sorting. Anecdotally this - // reduces mapping time by more than half, but it is still rather slow. NL Mapping - // takes 32 seconds sorting every timetable, 9 seconds with cached sorting, and 6 - // seconds with no timetable sorting at all. - List sortedTripTimes = sortedTripTimesForTimetable.computeIfAbsent( - timetable, - TransitLayerMapper::getSortedTripTimes - ); - - for (TripTimes tripTimes : sortedTripTimes) { + for (TripTimes tripTimes : timetable.getTripTimes()) { if (!serviceCodesRunning.contains(tripTimes.getServiceCode())) { continue; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/BoardAlight.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/BoardAlight.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/BoardAlight.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/BoardAlight.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRequestTransferCache.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRequestTransferCache.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRequestTransferCache.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRequestTransferCache.java index 99ad83d3f4d..d778f491142 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRequestTransferCache.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRequestTransferCache.java @@ -6,8 +6,6 @@ import java.util.List; import java.util.Objects; import java.util.concurrent.ExecutionException; -import javax.annotation.Nonnull; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.algorithm.raptoradapter.transit.RaptorTransferIndex; import org.opentripplanner.routing.algorithm.raptoradapter.transit.Transfer; import org.opentripplanner.routing.api.request.RouteRequest; @@ -18,6 +16,7 @@ import org.opentripplanner.routing.api.request.preference.WheelchairPreferences; import org.opentripplanner.street.search.request.StreetSearchRequest; import org.opentripplanner.street.search.request.StreetSearchRequestMapper; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,8 +56,7 @@ public RaptorTransferIndex get(List> transfersByStopIndex, RouteR private CacheLoader cacheLoader() { return new CacheLoader<>() { @Override - @Nonnull - public RaptorTransferIndex load(@Nonnull CacheKey cacheKey) { + public RaptorTransferIndex load(CacheKey cacheKey) { LOG.info("Adding runtime request to cache: {}", cacheKey.options); return RaptorTransferIndex.create(cacheKey.transfersByStopIndex, cacheKey.request); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitData.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitData.java similarity index 90% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitData.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitData.java index 5b9d81fa6c3..d7846645d98 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitData.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitData.java @@ -4,14 +4,12 @@ import java.util.BitSet; import java.util.Iterator; import java.util.List; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.transfer.TransferService; import org.opentripplanner.raptor.api.model.RaptorConstrainedTransfer; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTransfer; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.spi.IntIterator; import org.opentripplanner.raptor.spi.RaptorConstrainedBoardingSearch; import org.opentripplanner.raptor.spi.RaptorCostCalculator; @@ -31,6 +29,7 @@ import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.transit.model.network.RoutingTripPattern; import org.opentripplanner.transit.model.network.grouppriority.TransitGroupPriorityService; +import org.opentripplanner.utils.time.ServiceDateUtils; /** * This is the data provider for the Range Raptor search engine. It uses data from the TransitLayer, @@ -129,6 +128,23 @@ public RaptorRoutingRequestTransitData( ); } + public RaptorRoutingRequestTransitData( + RaptorRoutingRequestTransitData original, + RaptorCostCalculator newCostCalculator + ) { + this.transitLayer = original.transitLayer; + this.transitSearchTimeZero = original.transitSearchTimeZero; + this.activeTripPatternsPerStop = original.activeTripPatternsPerStop; + this.patternIndex = original.patternIndex; + this.transferIndex = original.transferIndex; + this.transferService = original.transferService; + this.constrainedTransfers = original.constrainedTransfers; + this.validTransitDataStartTime = original.validTransitDataStartTime; + this.validTransitDataEndTime = original.validTransitDataEndTime; + this.generalizedCostCalculator = newCostCalculator; + this.slackProvider = original.slackProvider(); + } + @Override public Iterator getTransfersFromStop(int stopIndex) { return transferIndex.getForwardTransfers(stopIndex).iterator(); @@ -200,7 +216,6 @@ public RaptorConstrainedTransfer findConstrainedTransfer( }; } - @Nonnull @Override public RaptorStopNameResolver stopNameResolver() { return (int stopIndex) -> { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreator.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreator.java index 815bf839e31..bde424f8269 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreator.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreator.java @@ -1,6 +1,6 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.request; -import static org.opentripplanner.framework.time.ServiceDateUtils.secondsSinceStartOfTime; +import static org.opentripplanner.utils.time.ServiceDateUtils.secondsSinceStartOfTime; import gnu.trove.list.array.TIntArrayList; import gnu.trove.map.TObjectIntMap; @@ -14,13 +14,13 @@ import java.util.List; import java.util.Map; import java.util.function.Predicate; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitLayer; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripPatternForDate; import org.opentripplanner.transit.model.network.RoutingTripPattern; import org.opentripplanner.transit.model.network.grouppriority.TransitGroupPriorityService; import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.ServiceDateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RouteRequestTransitDataProviderFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RouteRequestTransitDataProviderFilter.java similarity index 93% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RouteRequestTransitDataProviderFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RouteRequestTransitDataProviderFilter.java index 44d9f3cdb3d..514a5b56f9a 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RouteRequestTransitDataProviderFilter.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RouteRequestTransitDataProviderFilter.java @@ -12,6 +12,7 @@ import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.BikeAccess; +import org.opentripplanner.transit.model.network.CarAccess; import org.opentripplanner.transit.model.network.RoutingTripPattern; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; @@ -20,6 +21,8 @@ public class RouteRequestTransitDataProviderFilter implements TransitDataProvide private final boolean requireBikesAllowed; + private final boolean requireCarsAllowed; + private final boolean wheelchairEnabled; private final WheelchairPreferences wheelchairPreferences; @@ -41,6 +44,7 @@ public class RouteRequestTransitDataProviderFilter implements TransitDataProvide public RouteRequestTransitDataProviderFilter(RouteRequest request) { this( request.journey().transfer().mode() == StreetMode.BIKE, + request.journey().transfer().mode() == StreetMode.CAR, request.wheelchair(), request.preferences().wheelchair(), request.preferences().transit().includePlannedCancellations(), @@ -53,6 +57,7 @@ public RouteRequestTransitDataProviderFilter(RouteRequest request) { // This constructor is used only for testing public RouteRequestTransitDataProviderFilter( boolean requireBikesAllowed, + boolean requireCarsAllowed, boolean wheelchairEnabled, WheelchairPreferences wheelchairPreferences, boolean includePlannedCancellations, @@ -61,6 +66,7 @@ public RouteRequestTransitDataProviderFilter( List filters ) { this.requireBikesAllowed = requireBikesAllowed; + this.requireCarsAllowed = requireCarsAllowed; this.wheelchairEnabled = wheelchairEnabled; this.wheelchairPreferences = wheelchairPreferences; this.includePlannedCancellations = includePlannedCancellations; @@ -97,10 +103,12 @@ public boolean tripPatternPredicate(TripPatternForDate tripPatternForDate) { public boolean tripTimesPredicate(TripTimes tripTimes, boolean withFilters) { final Trip trip = tripTimes.getTrip(); - if (requireBikesAllowed) { - if (bikeAccessForTrip(trip) != BikeAccess.ALLOWED) { - return false; - } + if (requireBikesAllowed && bikeAccessForTrip(trip) != BikeAccess.ALLOWED) { + return false; + } + + if (requireCarsAllowed && trip.getCarsAllowed() != CarAccess.ALLOWED) { + return false; } if (wheelchairEnabled) { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TransitDataProviderFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TransitDataProviderFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TransitDataProviderFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TransitDataProviderFilter.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripPatternForDates.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripPatternForDates.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripPatternForDates.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripPatternForDates.java index 0fb39b227ea..a94aa0850ba 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripPatternForDates.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripPatternForDates.java @@ -2,7 +2,6 @@ import java.util.BitSet; import java.util.function.IntUnaryOperator; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorTripPattern; import org.opentripplanner.raptor.api.model.SearchDirection; import org.opentripplanner.raptor.spi.IntIterator; @@ -18,6 +17,7 @@ import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.RoutingTripPattern; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A collection of all the TripSchedules active on a range of consecutive days. The outer list of diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearch.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearch.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearch.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearch.java index 7be4f1eecf9..628a16511ce 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearch.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearch.java @@ -1,15 +1,14 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.request; import java.util.function.IntUnaryOperator; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.model.SearchDirection; import org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent; import org.opentripplanner.raptor.spi.RaptorTripScheduleSearch; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * The purpose of this class is to optimize the search for a trip schedule for a given pattern and @@ -76,7 +75,6 @@ public int stopPositionInPattern() { } @Override - @Nonnull public RaptorTransferConstraint transferConstraint() { return RaptorTransferConstraint.REGULAR_TRANSFER; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearch.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearch.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearch.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearch.java index 78bc2101775..7bd5062d8dc 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearch.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearch.java @@ -1,14 +1,13 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.request; import java.util.function.IntUnaryOperator; -import javax.annotation.Nonnull; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.model.SearchDirection; import org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent; import org.opentripplanner.raptor.spi.RaptorTripScheduleSearch; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * The purpose of this class is to optimize the search for a trip schedule for a given pattern and @@ -16,7 +15,7 @@ * trips are ordered after the FIRST stop boarding times. We also assume that trips do not pass each * other; Hence trips IN SERVICE on a given day will be in order for all other stops too. *

    - * The search use a binary search if the number of trip schedules is above a given threshold. A + * The search uses a binary search if the number of trip schedules is above a given threshold. A * linear search is slow when the number of schedules is very large, let say more than 300 trip * schedules. * @@ -74,7 +73,6 @@ public int stopPositionInPattern() { } @Override - @Nonnull public RaptorTransferConstraint transferConstraint() { return RaptorTransferConstraint.REGULAR_TRANSFER; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleSearchFactory.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleSearchFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleSearchFactory.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleSearchFactory.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleWithOffset.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleWithOffset.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleWithOffset.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleWithOffset.java index aca998b24ca..d692f0079f6 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleWithOffset.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleWithOffset.java @@ -2,7 +2,6 @@ import java.time.LocalDate; import java.util.function.IntUnaryOperator; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorTripPattern; import org.opentripplanner.raptor.spi.IntIterator; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripPatternForDate; @@ -10,6 +9,7 @@ import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This represents a single trip within a TripPattern, but with a time offset in seconds. This is diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripSearchTimetable.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripSearchTimetable.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripSearchTimetable.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripSearchTimetable.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/OptimizeMinSafeTransferCost.png b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/OptimizeMinSafeTransferCost.png similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/OptimizeMinSafeTransferCost.png rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/OptimizeMinSafeTransferCost.png diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/OptimizeTransferService.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/OptimizeTransferService.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/OptimizeTransferService.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/OptimizeTransferService.java index 8a4f25d8910..4d8a79b3f4f 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/OptimizeTransferService.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/OptimizeTransferService.java @@ -3,7 +3,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import org.opentripplanner.framework.logging.Throttle; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.RaptorPath; import org.opentripplanner.routing.algorithm.raptoradapter.path.PathDiff; @@ -11,6 +10,7 @@ import org.opentripplanner.routing.algorithm.transferoptimization.model.MinSafeTransferTimeCalculator; import org.opentripplanner.routing.algorithm.transferoptimization.model.TransferWaitTimeCostCalculator; import org.opentripplanner.routing.algorithm.transferoptimization.services.OptimizePathDomainService; +import org.opentripplanner.utils.logging.Throttle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/TransferOptimizationObjCol.svg b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/TransferOptimizationObjCol.svg similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/TransferOptimizationObjCol.svg rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/TransferOptimizationObjCol.svg diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPath.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPath.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPath.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPath.java index ad4df23a42c..f2a36e1678c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPath.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPath.java @@ -3,12 +3,12 @@ import java.util.function.Supplier; import org.opentripplanner.model.transfer.TransferConstraint; import org.opentripplanner.raptor.api.model.RaptorConstrainedTransfer; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.AccessPathLeg; import org.opentripplanner.raptor.api.path.PathLeg; import org.opentripplanner.raptor.api.path.PathStringBuilder; import org.opentripplanner.raptor.api.path.RaptorPath; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.path.Path; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/TransferOptimizationParameters.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/TransferOptimizationParameters.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/TransferOptimizationParameters.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/TransferOptimizationParameters.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/TransferOptimized.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/TransferOptimized.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/TransferOptimized.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/TransferOptimized.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/configure/TransferOptimizationServiceConfigurator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/configure/TransferOptimizationServiceConfigurator.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/configure/TransferOptimizationServiceConfigurator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/configure/TransferOptimizationServiceConfigurator.java index cb5f3d7fdab..214e79216e5 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/configure/TransferOptimizationServiceConfigurator.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/configure/TransferOptimizationServiceConfigurator.java @@ -3,8 +3,8 @@ import java.util.function.IntFunction; import javax.annotation.Nullable; import org.opentripplanner.model.transfer.TransferService; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.api.request.MultiCriteriaRequest; import org.opentripplanner.raptor.spi.RaptorCostCalculator; import org.opentripplanner.raptor.spi.RaptorTransitDataProvider; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/BasicStopTime.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/BasicStopTime.java similarity index 93% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/BasicStopTime.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/BasicStopTime.java index 9d073b2ae64..5fd9e73e398 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/BasicStopTime.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/BasicStopTime.java @@ -1,7 +1,7 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model; import java.util.Objects; -import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; +import org.opentripplanner.utils.tostring.ValueObjectToStringBuilder; /** Basic stop and time value object. */ final class BasicStopTime implements StopTime { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculator.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculator.java index 49b3c29559e..fde6b3d4a64 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculator.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculator.java @@ -1,14 +1,14 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model; -import static org.opentripplanner.framework.time.DurationUtils.durationInSeconds; +import static org.opentripplanner.utils.time.DurationUtils.durationInSeconds; import java.util.Collection; import java.util.function.ToIntFunction; -import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.RaptorPath; import org.opentripplanner.raptor.api.path.TransitPathLeg; import org.opentripplanner.raptor.spi.RaptorSlackProvider; +import org.opentripplanner.utils.lang.IntUtils; /** * This is a calculator to calculate a min-safe-transfer-time. The min-safe-transfer-time is used to diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTail.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTail.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTail.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTail.java index 8d18c461101..efe53d8e090 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTail.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTail.java @@ -1,13 +1,12 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; import org.opentripplanner.model.transfer.TransferConstraint; import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.model.RaptorValueFormatter; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.api.path.TransitPathLeg; import org.opentripplanner.raptor.path.PathBuilder; import org.opentripplanner.raptor.path.PathBuilderLeg; @@ -16,6 +15,7 @@ import org.opentripplanner.raptor.spi.RaptorSlackProvider; import org.opentripplanner.routing.algorithm.transferoptimization.api.OptimizedPath; import org.opentripplanner.routing.algorithm.transferoptimization.api.TransferOptimized; +import org.opentripplanner.utils.tostring.ValueObjectToStringBuilder; /** * This class is used to decorate a {@link TransitPathLeg} with information about transfers diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/PathTailFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/PathTailFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/PathTailFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/PathTailFilter.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopPriorityCostCalculator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopPriorityCostCalculator.java similarity index 94% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopPriorityCostCalculator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopPriorityCostCalculator.java index 48a4b733b58..6ea660e654f 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopPriorityCostCalculator.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopPriorityCostCalculator.java @@ -1,7 +1,7 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model; -import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitLayer; +import org.opentripplanner.utils.lang.IntUtils; /** * This class calculates an extra stop priority cost by using the stop-board-alight-transfer-cost diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopTime.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopTime.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopTime.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopTime.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TransferWaitTimeCostCalculator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TransferWaitTimeCostCalculator.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TransferWaitTimeCostCalculator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TransferWaitTimeCostCalculator.java index a5336999b09..ee33f1d86c3 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TransferWaitTimeCostCalculator.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TransferWaitTimeCostCalculator.java @@ -1,6 +1,6 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model; -import static org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter.toRaptorCost; +import static org.opentripplanner.raptor.api.model.RaptorCostConverter.toRaptorCost; /** * This calculator uses the {@code minSafeTransferTime}(t0) and an inverse log function to calculate diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripStopTime.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripStopTime.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripStopTime.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripStopTime.java index 75fd589a45b..27299e407f4 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripStopTime.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripStopTime.java @@ -1,8 +1,8 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model; import java.util.Objects; -import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.utils.tostring.ValueObjectToStringBuilder; /** * @param The TripSchedule type defined by the user of the raptor API. diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripToTripTransfer.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripToTripTransfer.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripToTripTransfer.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripToTripTransfer.java index 0dce8933e3f..2aa13d0cd16 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripToTripTransfer.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripToTripTransfer.java @@ -1,10 +1,10 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.transfer.ConstrainedTransfer; import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * @param The TripSchedule type defined by the user of the raptor API. diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilter.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilter.java index 8de4c8fa847..6b8dbef7f4e 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilter.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilter.java @@ -4,10 +4,10 @@ import java.util.List; import java.util.Set; import java.util.function.ToIntFunction; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.routing.algorithm.transferoptimization.model.OptimizedPathTail; import org.opentripplanner.routing.algorithm.transferoptimization.model.PathTailFilter; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This class takes a list of "cost functions" and creates a filter chain for them. The precedence diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilterFactory.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilterFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilterFactory.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilterFactory.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughPathTailFilter.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughPathTailFilter.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughPathTailFilter.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughPathTailFilter.java index 46b1a9020b0..bff656bb940 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughPathTailFilter.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughPathTailFilter.java @@ -7,11 +7,11 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.request.PassThroughPoint; import org.opentripplanner.routing.algorithm.transferoptimization.model.OptimizedPathTail; import org.opentripplanner.routing.algorithm.transferoptimization.model.PathTailFilter; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Create a filter chain function and find the best combination of transfers for the journey diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughPointsIterator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughPointsIterator.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughPointsIterator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughPointsIterator.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PathTailC2Calculator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PathTailC2Calculator.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PathTailC2Calculator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PathTailC2Calculator.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/package.md b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/package.md similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/package.md rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/package.md diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainService.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainService.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainService.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainService.java index ca8f953ced5..ebfbf6d76b9 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainService.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainService.java @@ -8,9 +8,9 @@ import java.util.Set; import java.util.stream.Collectors; import javax.annotation.Nullable; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.RaptorPath; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.api.path.TransferPathLeg; import org.opentripplanner.raptor.api.path.TransitPathLeg; import org.opentripplanner.raptor.spi.RaptorCostCalculator; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGenerator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGenerator.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGenerator.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGenerator.java index f06e2142073..0e5e5ebd8e0 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGenerator.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGenerator.java @@ -5,7 +5,6 @@ import java.util.Comparator; import java.util.Iterator; import java.util.List; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.model.transfer.ConstrainedTransfer; import org.opentripplanner.raptor.api.model.RaptorTransfer; @@ -229,12 +228,10 @@ private int calcRegularTransferEarliestBoardTime( return from.time() + transferDuration; } - @Nonnull private StopTime getFromStopTime(final TransitPathLeg leg) { return StopTime.stopTime(leg.fromStop(), leg.fromTime()); } - @Nonnull private TripStopTime findMinimumToStopTime(List> transfers) { return transfers .stream() diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferServiceAdaptor.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferServiceAdaptor.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferServiceAdaptor.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferServiceAdaptor.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelector.java b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelector.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelector.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelector.java index 9e0a4257f57..646939a9ac5 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelector.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelector.java @@ -2,10 +2,10 @@ import java.util.HashSet; import java.util.Set; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.routing.algorithm.transferoptimization.model.OptimizedPathTail; import org.opentripplanner.routing.algorithm.transferoptimization.model.PathTailFilter; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This class takes a list of transit legs and returns the best leg based on the {@link diff --git a/src/main/java/org/opentripplanner/routing/algorithm/via/ViaRoutingWorker.java b/application/src/main/java/org/opentripplanner/routing/algorithm/via/ViaRoutingWorker.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/via/ViaRoutingWorker.java rename to application/src/main/java/org/opentripplanner/routing/algorithm/via/ViaRoutingWorker.java index 94dff22547b..a4ff6753d5a 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/via/ViaRoutingWorker.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/via/ViaRoutingWorker.java @@ -12,7 +12,7 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.RouteViaRequest; -import org.opentripplanner.routing.api.request.ViaLocation; +import org.opentripplanner.routing.api.request.ViaLocationDeprecated; import org.opentripplanner.routing.api.response.InputField; import org.opentripplanner.routing.api.response.RoutingError; import org.opentripplanner.routing.api.response.RoutingErrorCode; @@ -121,7 +121,7 @@ private ViaRoutingResponse combineRoutingResponse(List routingR private List filterTransits( Itinerary i, List itineraries, - ViaLocation viaLocation + ViaLocationDeprecated viaLocation ) { return itineraries.stream().filter(withinSlackTest(i, viaLocation)).toList(); } @@ -129,7 +129,7 @@ private List filterTransits( /** * Only allow departures within min/max slack time. */ - private Predicate withinSlackTest(Itinerary i, ViaLocation v) { + private Predicate withinSlackTest(Itinerary i, ViaLocationDeprecated v) { var earliestDeparturetime = i.endTime().plus(v.minSlack()); var latestDeparturetime = i.endTime().plus(v.maxSlack()); diff --git a/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegs.java b/application/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegs.java similarity index 90% rename from src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegs.java rename to application/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegs.java index 6b51c0b1282..f65a045a8e3 100644 --- a/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegs.java +++ b/application/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegs.java @@ -16,8 +16,6 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; -import javax.annotation.Nonnull; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.Timetable; import org.opentripplanner.model.TripTimeOnDate; import org.opentripplanner.model.plan.Leg; @@ -30,6 +28,7 @@ import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.time.ServiceDateUtils; /** * A helper class to fetch previous/next alternative legs for a scheduled transit leg. @@ -46,18 +45,10 @@ public static List getAlternativeLegs( Leg leg, Integer numberLegs, TransitService transitService, - boolean searchBackward, + NavigationDirection direction, AlternativeLegsFilter filter ) { - return getAlternativeLegs( - leg, - numberLegs, - transitService, - searchBackward, - filter, - false, - false - ); + return getAlternativeLegs(leg, numberLegs, transitService, direction, filter, false, false); } /** @@ -67,9 +58,8 @@ public static List getAlternativeLegs( * @param numberLegs The number of alternative legs requested. If fewer legs are found, * only the found legs are returned. * @param transitService The transit service used for the search - * @param includeDepartBefore Boolean indicating whether the alternative legs should depart - * earlier or later than the original leg True if earlier, false if - * later. + * @param direction Indicating whether the alternative legs should depart before or + * after than the original. * @param filter AlternativeLegsFilter indicating which properties of the original * leg should not change in the alternative legs * @param exactOriginStop Boolean indicating whether the exact departure stop of the original @@ -83,7 +73,7 @@ public static List getAlternativeLegs( Leg leg, Integer numberLegs, TransitService transitService, - boolean includeDepartBefore, + NavigationDirection direction, AlternativeLegsFilter filter, boolean exactOriginStop, boolean exactDestinationStop @@ -106,7 +96,7 @@ public static List getAlternativeLegs( ScheduledTransitLeg::getStartTime ); - if (includeDepartBefore) { + if (direction == NavigationDirection.PREVIOUS) { legComparator = legComparator.reversed(); } @@ -114,19 +104,13 @@ public static List getAlternativeLegs( return origins .stream() - .flatMap(stop -> transitService.getPatternsForStop(stop, true).stream()) + .flatMap(stop -> transitService.findPatterns(stop, true).stream()) .filter(tripPattern -> tripPattern.getStops().stream().anyMatch(destinations::contains)) .filter(tripPatternPredicate) .distinct() .flatMap(tripPattern -> withBoardingAlightingPositions(origins, destinations, tripPattern)) .flatMap(t -> - generateLegs( - transitService, - t, - leg.getStartTime(), - leg.getServiceDate(), - includeDepartBefore - ) + generateLegs(transitService, t, leg.getStartTime(), leg.getServiceDate(), direction) ) .filter(Predicate.not(leg::isPartiallySameTransitLeg)) .sorted(legComparator) @@ -138,13 +122,12 @@ public static List getAlternativeLegs( * This has been copied and slightly modified from StopTimesHelper. * TODO: Adapt after new transit model is in place */ - @Nonnull private static Stream generateLegs( TransitService transitService, TripPatternBetweenStops tripPatternBetweenStops, ZonedDateTime departureTime, LocalDate originalDate, - boolean includeDepartBefore + NavigationDirection direction ) { TripPattern pattern = tripPatternBetweenStops.tripPattern; int boardingPosition = tripPatternBetweenStops.positions.boardingPosition; @@ -157,7 +140,7 @@ private static Stream generateLegs( tts.getServiceDayMidnight() + tts.getRealtimeDeparture() ); - if (includeDepartBefore) { + if (direction == NavigationDirection.PREVIOUS) { comparator = comparator.reversed(); } @@ -167,7 +150,7 @@ private static Stream generateLegs( var serviceDates = List.of(originalDate.minusDays(1), originalDate, originalDate.plusDays(1)); for (LocalDate serviceDate : serviceDates) { - Timetable timetable = transitService.getTimetableForTripPattern(pattern, serviceDate); + Timetable timetable = transitService.findTimetable(pattern, serviceDate); ZonedDateTime midnight = ServiceDateUtils.asStartOfService( serviceDate, transitService.getTimeZone() @@ -187,7 +170,7 @@ private static Stream generateLegs( continue; } - boolean departureTimeInRange = includeDepartBefore + boolean departureTimeInRange = direction == NavigationDirection.PREVIOUS ? tripTimes.getDepartureTime(boardingPosition) <= secondsSinceMidnight : tripTimes.getDepartureTime(boardingPosition) >= secondsSinceMidnight; @@ -224,7 +207,6 @@ private static Stream generateLegs( return res.stream(); } - @Nonnull private static ScheduledTransitLeg mapToLeg( ZoneId timeZone, TripPattern pattern, @@ -247,7 +229,7 @@ private static ScheduledTransitLeg mapToLeg( tripTimes.getArrivalTime(alightingPosition) ); - TripOnServiceDate tripOnServiceDate = transitService.getTripOnServiceDateForTripAndDay( + TripOnServiceDate tripOnServiceDate = transitService.getTripOnServiceDate( new TripIdAndServiceDate(tripTimeOnDate.getTrip().getId(), tripTimeOnDate.getServiceDay()) ); @@ -264,7 +246,6 @@ private static ScheduledTransitLeg mapToLeg( .build(); } - @Nonnull private static Stream withBoardingAlightingPositions( Collection origins, Collection destinations, diff --git a/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegsFilter.java b/application/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegsFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegsFilter.java rename to application/src/main/java/org/opentripplanner/routing/alternativelegs/AlternativeLegsFilter.java diff --git a/application/src/main/java/org/opentripplanner/routing/alternativelegs/NavigationDirection.java b/application/src/main/java/org/opentripplanner/routing/alternativelegs/NavigationDirection.java new file mode 100644 index 00000000000..8254e3e28b7 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/routing/alternativelegs/NavigationDirection.java @@ -0,0 +1,16 @@ +package org.opentripplanner.routing.alternativelegs; + +/** + * This enum describes how the user navigates on a list of items. + */ +public enum NavigationDirection { + /** + * Get the next set of items. + */ + NEXT, + + /** + * Get the previous set of items. + */ + PREVIOUS, +} diff --git a/src/main/java/org/opentripplanner/routing/api/RoutingService.java b/application/src/main/java/org/opentripplanner/routing/api/RoutingService.java similarity index 74% rename from src/main/java/org/opentripplanner/routing/api/RoutingService.java rename to application/src/main/java/org/opentripplanner/routing/api/RoutingService.java index f840ac27524..fcea16e3991 100644 --- a/src/main/java/org/opentripplanner/routing/api/RoutingService.java +++ b/application/src/main/java/org/opentripplanner/routing/api/RoutingService.java @@ -8,5 +8,10 @@ public interface RoutingService { RoutingResponse route(RouteRequest request); + /** + * @deprecated We will replace the complex via-search with a simpler version part of the + * existing trip search. + */ + @Deprecated ViaRoutingResponse route(RouteViaRequest request); } diff --git a/src/main/java/org/opentripplanner/routing/api/request/DebugEventType.java b/application/src/main/java/org/opentripplanner/routing/api/request/DebugEventType.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/request/DebugEventType.java rename to application/src/main/java/org/opentripplanner/routing/api/request/DebugEventType.java diff --git a/src/main/java/org/opentripplanner/routing/api/request/DebugRaptor.java b/application/src/main/java/org/opentripplanner/routing/api/request/DebugRaptor.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/DebugRaptor.java rename to application/src/main/java/org/opentripplanner/routing/api/request/DebugRaptor.java index 0b9ff4f0c30..a0d7bd6de2e 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/DebugRaptor.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/DebugRaptor.java @@ -9,7 +9,7 @@ import java.util.List; import java.util.Set; import java.util.regex.Pattern; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/routing/api/request/RequestModes.java b/application/src/main/java/org/opentripplanner/routing/api/request/RequestModes.java similarity index 95% rename from src/main/java/org/opentripplanner/routing/api/request/RequestModes.java rename to application/src/main/java/org/opentripplanner/routing/api/request/RequestModes.java index 72b06f62979..f10686216a8 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/RequestModes.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/RequestModes.java @@ -3,8 +3,7 @@ import static org.opentripplanner.routing.api.request.StreetMode.NOT_SET; import java.util.Objects; -import javax.annotation.Nonnull; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; public class RequestModes { @@ -18,16 +17,12 @@ public class RequestModes { StreetMode.WALK ); - @Nonnull public final StreetMode accessMode; - @Nonnull public final StreetMode egressMode; - @Nonnull public final StreetMode directMode; - @Nonnull public final StreetMode transferMode; private RequestModes( diff --git a/src/main/java/org/opentripplanner/routing/api/request/RequestModesBuilder.java b/application/src/main/java/org/opentripplanner/routing/api/request/RequestModesBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/request/RequestModesBuilder.java rename to application/src/main/java/org/opentripplanner/routing/api/request/RequestModesBuilder.java diff --git a/src/main/java/org/opentripplanner/routing/api/request/RouteRequest.java b/application/src/main/java/org/opentripplanner/routing/api/request/RouteRequest.java similarity index 85% rename from src/main/java/org/opentripplanner/routing/api/request/RouteRequest.java rename to application/src/main/java/org/opentripplanner/routing/api/request/RouteRequest.java index 76e5dcc558a..4e36b1b58db 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/RouteRequest.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/RouteRequest.java @@ -1,6 +1,6 @@ package org.opentripplanner.routing.api.request; -import static org.opentripplanner.framework.time.DurationUtils.durationInSeconds; +import static org.opentripplanner.utils.time.DurationUtils.durationInSeconds; import java.io.Serializable; import java.time.Duration; @@ -11,20 +11,24 @@ import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.function.Consumer; import javax.annotation.Nullable; -import org.opentripplanner.framework.collection.ListSection; -import org.opentripplanner.framework.time.DateUtils; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.GenericLocation; import org.opentripplanner.model.plan.SortOrder; import org.opentripplanner.model.plan.paging.cursor.PageCursor; import org.opentripplanner.routing.api.request.preference.RoutingPreferences; import org.opentripplanner.routing.api.request.request.JourneyRequest; +import org.opentripplanner.routing.api.request.via.ViaLocation; import org.opentripplanner.routing.api.response.InputField; import org.opentripplanner.routing.api.response.RoutingError; import org.opentripplanner.routing.api.response.RoutingErrorCode; import org.opentripplanner.routing.error.RoutingValidationException; +import org.opentripplanner.standalone.config.routerconfig.TransitRoutingConfig; +import org.opentripplanner.utils.collection.ListSection; +import org.opentripplanner.utils.lang.ObjectUtils; +import org.opentripplanner.utils.time.DateUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,14 +39,6 @@ * All defaults should be specified here in the RouteRequest, NOT as annotations on query parameters * in web services that create RouteRequests. This establishes a priority chain for default values: * RouteRequest field initializers, then JSON router config, then query parameters. - * - * @Deprecated tag is added to all parameters that are not currently functional in either the Raptor - * router or other non-transit routing (walk, bike, car etc.) - *

    - * TODO OTP2 Many fields are deprecated in this class, the reason is documented in the - * RoutingResource class, not here. Eventually the field will be removed from this - * class, but we want to keep it in the RoutingResource as long as we support the - * REST API. */ public class RouteRequest implements Cloneable, Serializable { @@ -56,7 +52,7 @@ public class RouteRequest implements Cloneable, Serializable { private GenericLocation to; - private List passThroughPoints = Collections.emptyList(); + private List via = Collections.emptyList(); private Instant dateTime = Instant.now(); @@ -110,14 +106,15 @@ public RoutingPreferences preferences() { return preferences; } - public void withPreferences(Consumer body) { + public RouteRequest withPreferences(Consumer body) { this.preferences = preferences.copyOf().apply(body).build(); + return this; } /** * The booking time is used to exclude services which are not bookable at the * requested booking time. If a service is bookable at this time or later, the service - * is included. This apply to FLEX access, egress and direct services. + * is included. This applies to FLEX access, egress and direct services. */ public Instant bookingTime() { return bookingTime; @@ -182,6 +179,12 @@ public SortOrder itinerariesSortOrder() { * Adjust the 'dateTime' if the page cursor is set to "goto next/previous page". The date-time is * used for many things, for example finding the days to search, but the transit search is using * the cursor[if exist], not the date-time. + *

    + * The direct mode is also unset when there is a page cursor because for anything other than the + * initial page we don't want to see direct results. + *

    + * See also {@link org.opentripplanner.routing.algorithm.raptoradapter.router.FilterTransitWhenDirectModeIsEmpty}, + * it uses a direct search to prune transit. */ public void applyPageCursor() { if (pageCursor != null) { @@ -278,32 +281,40 @@ public void setTo(GenericLocation to) { this.to = to; } - public List getPassThroughPoints() { - return passThroughPoints; + /** + * Return {@code true} if at least one via location is set! + */ + public boolean isViaSearch() { + return !via.isEmpty(); + } + + public List getViaLocations() { + return via; } - public void setPassThroughPoints(final List passThroughPoints) { - this.passThroughPoints = passThroughPoints; + public RouteRequest setViaLocations(final List via) { + this.via = via; + return this; } /** * This is the time/duration in seconds from the earliest-departure-time(EDT) to - * latest-departure-time(LDT). In case of a reverse search it will be the time from earliest to + * latest-departure-time(LDT). In case of a reverse search, it will be the time from earliest to * latest arrival time (LAT - EAT). *

    - * All optimal travels that depart within the search window is guaranteed to be found. + * All optimal itineraries that depart within the search window are guaranteed to be found. *

    * This is sometimes referred to as the Range Raptor Search Window - but could be used in a none * Transit search as well; Hence this is named search-window and not raptor-search-window. Do not * confuse this with the travel-window, which is the time between EDT to LAT. *

    * Use {@code null} to unset, and {@link Duration#ZERO} to do one Raptor iteration. The value is - * dynamically assigned a suitable value, if not set. In a small to medium size operation you may - * use a fixed value, like 60 minutes. If you have a mixture of high frequency cities routes and + * dynamically assigned a suitable value, if not set. In a small-to-medium size operation, you may + * use a fixed value, like 60 minutes. If you have a mixture of high-frequency city routes and * infrequent long distant journeys, the best option is normally to use the dynamic auto * assignment. *

    - * There is no need to set this when going to the next/previous page any more. + * There is no need to set this when going to the next/previous page anymore. */ public Duration searchWindow() { return searchWindow; @@ -325,12 +336,25 @@ private boolean hasMaxSearchWindow() { return maxSearchWindow != null; } + /** + * For testing only. Use {@link TransitRoutingConfig#maxSearchWindow()} instead. + * @see #initMaxSearchWindow(Duration) + */ public Duration maxSearchWindow() { return maxSearchWindow; } - public void setMaxSearchWindow(@Nullable Duration maxSearchWindow) { - this.maxSearchWindow = maxSearchWindow; + /** + * Initialize the maxSearchWindow from the transit config. This is necessary because the + * default route request is configured before the {@link TransitRoutingConfig}. + */ + public void initMaxSearchWindow(Duration maxSearchWindow) { + this.maxSearchWindow = + ObjectUtils.requireNotInitialized( + "maxSearchWindow", + this.maxSearchWindow, + Objects.requireNonNull(maxSearchWindow) + ); } public Locale locale() { diff --git a/src/main/java/org/opentripplanner/routing/api/request/RouteViaRequest.java b/application/src/main/java/org/opentripplanner/routing/api/request/RouteViaRequest.java similarity index 93% rename from src/main/java/org/opentripplanner/routing/api/request/RouteViaRequest.java rename to application/src/main/java/org/opentripplanner/routing/api/request/RouteViaRequest.java index 97e492ffd98..7d91558cf77 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/RouteViaRequest.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/RouteViaRequest.java @@ -14,7 +14,11 @@ /** * Trip planning request with a list of via points. + * + * @deprecated We will replace the complex via-search with a simpler version part of the + * existing trip search. */ +@Deprecated public class RouteViaRequest implements Serializable { private final GenericLocation from; @@ -27,7 +31,10 @@ public class RouteViaRequest implements Serializable { private final Locale locale; private final Integer numItineraries; - private RouteViaRequest(List viaLocations, List viaJourneys) { + private RouteViaRequest( + List viaLocations, + List viaJourneys + ) { if (viaLocations == null || viaLocations.isEmpty()) { throw new IllegalArgumentException("viaLocations must not be empty"); } @@ -67,7 +74,10 @@ private RouteViaRequest(Builder builder) { this.numItineraries = builder.numItineraries; } - public static Builder of(List viaLocations, List viaJourneys) { + public static Builder of( + List viaLocations, + List viaJourneys + ) { return new Builder(new RouteViaRequest(viaLocations, viaJourneys)); } @@ -230,8 +240,8 @@ public Builder withNumItineraries(Integer numItineraries) { } /** - * ViaSegments contains the {@link JourneyRequest} to the next {@link ViaLocation}. The last + * ViaSegments contains the {@link JourneyRequest} to the next {@link ViaLocationDeprecated}. The last * segment has null viaLocation, as `to` is the destination of that segment. */ - public record ViaSegment(JourneyRequest journeyRequest, ViaLocation viaLocation) {} + public record ViaSegment(JourneyRequest journeyRequest, ViaLocationDeprecated viaLocation) {} } diff --git a/src/main/java/org/opentripplanner/routing/api/request/RoutingTag.java b/application/src/main/java/org/opentripplanner/routing/api/request/RoutingTag.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/request/RoutingTag.java rename to application/src/main/java/org/opentripplanner/routing/api/request/RoutingTag.java diff --git a/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java b/application/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/StreetMode.java rename to application/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java index 56e716d9d62..cbc2764f030 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java @@ -36,10 +36,8 @@ public enum StreetMode implements DocumentedEnum { SCOOTER_RENTAL(Feature.ACCESS, Feature.EGRESS, Feature.WALKING, Feature.SCOOTER, Feature.RENTING), /** * Car only - *

    - * Direct mode only. */ - CAR(Feature.ACCESS, Feature.DRIVING), + CAR(Feature.ACCESS, Feature.TRANSFER, Feature.EGRESS, Feature.DRIVING), /** * Start in the car, drive to a parking area, and walk the rest of the way. *

    diff --git a/src/main/java/org/opentripplanner/routing/api/request/ViaLocation.java b/application/src/main/java/org/opentripplanner/routing/api/request/ViaLocationDeprecated.java similarity index 82% rename from src/main/java/org/opentripplanner/routing/api/request/ViaLocation.java rename to application/src/main/java/org/opentripplanner/routing/api/request/ViaLocationDeprecated.java index 9701095a382..7d864dddb16 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/ViaLocation.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/ViaLocationDeprecated.java @@ -11,8 +11,12 @@ * @param passThroughPoint Does the via point represent a pass through * @param minSlack Minimum time that is allowed to wait for interchange. * @param maxSlack Maximum time to wait for next departure. + * + * @deprecated We will replace the complex via-search with a simpler version part of the + * existing trip search. */ -public record ViaLocation( +@Deprecated +public record ViaLocationDeprecated( GenericLocation point, boolean passThroughPoint, Duration minSlack, @@ -21,7 +25,7 @@ public record ViaLocation( public static final Duration DEFAULT_MAX_SLACK = Duration.ofHours(1); public static final Duration DEFAULT_MIN_SLACK = Duration.ofMinutes(5); - public ViaLocation { + public ViaLocationDeprecated { Objects.requireNonNull(minSlack); Objects.requireNonNull(maxSlack); Objects.requireNonNull(point); diff --git a/src/main/java/org/opentripplanner/routing/api/request/framework/AbstractLinearFunction.java b/application/src/main/java/org/opentripplanner/routing/api/request/framework/AbstractLinearFunction.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/request/framework/AbstractLinearFunction.java rename to application/src/main/java/org/opentripplanner/routing/api/request/framework/AbstractLinearFunction.java diff --git a/src/main/java/org/opentripplanner/routing/api/request/framework/CostLinearFunction.java b/application/src/main/java/org/opentripplanner/routing/api/request/framework/CostLinearFunction.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/request/framework/CostLinearFunction.java rename to application/src/main/java/org/opentripplanner/routing/api/request/framework/CostLinearFunction.java diff --git a/src/main/java/org/opentripplanner/routing/api/request/framework/DurationForEnum.java b/application/src/main/java/org/opentripplanner/routing/api/request/framework/DurationForEnum.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/framework/DurationForEnum.java rename to application/src/main/java/org/opentripplanner/routing/api/request/framework/DurationForEnum.java index e6dacaac19d..c6586aa8b0f 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/framework/DurationForEnum.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/framework/DurationForEnum.java @@ -7,7 +7,7 @@ import java.util.Map; import java.util.Objects; import java.util.function.Consumer; -import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; +import org.opentripplanner.utils.tostring.ValueObjectToStringBuilder; /** * This class is used to store a {@link Duration} value for each of the enum type values. diff --git a/src/main/java/org/opentripplanner/routing/api/request/framework/LinearFunctionSerialization.java b/application/src/main/java/org/opentripplanner/routing/api/request/framework/LinearFunctionSerialization.java similarity index 95% rename from src/main/java/org/opentripplanner/routing/api/request/framework/LinearFunctionSerialization.java rename to application/src/main/java/org/opentripplanner/routing/api/request/framework/LinearFunctionSerialization.java index cb9dfb5c4cc..a6c846ccb35 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/framework/LinearFunctionSerialization.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/framework/LinearFunctionSerialization.java @@ -7,10 +7,10 @@ import java.util.function.BiFunction; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.opentripplanner.framework.lang.IntUtils; -import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.framework.model.Units; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.utils.lang.IntUtils; +import org.opentripplanner.utils.lang.StringUtils; +import org.opentripplanner.utils.time.DurationUtils; /** * This class can serialize and parse a linear function of time/duration/cost on the form diff --git a/src/main/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenalty.java b/application/src/main/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenalty.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenalty.java rename to application/src/main/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenalty.java diff --git a/src/main/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyForEnum.java b/application/src/main/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyForEnum.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyForEnum.java rename to application/src/main/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyForEnum.java index 2f439801cb5..ace9b813937 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyForEnum.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyForEnum.java @@ -7,7 +7,7 @@ import java.util.Objects; import java.util.function.Consumer; import org.opentripplanner.framework.model.TimeAndCost; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A map of {@link TimeAndCost} indexed by enum type {@code T}. diff --git a/src/main/java/org/opentripplanner/routing/api/request/framework/TimePenalty.java b/application/src/main/java/org/opentripplanner/routing/api/request/framework/TimePenalty.java similarity index 92% rename from src/main/java/org/opentripplanner/routing/api/request/framework/TimePenalty.java rename to application/src/main/java/org/opentripplanner/routing/api/request/framework/TimePenalty.java index 3ee07034135..99643b69d02 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/framework/TimePenalty.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/framework/TimePenalty.java @@ -1,8 +1,8 @@ package org.opentripplanner.routing.api.request.framework; import java.time.Duration; -import org.opentripplanner.framework.lang.StringUtils; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.utils.lang.StringUtils; +import org.opentripplanner.utils.time.DurationUtils; public final class TimePenalty extends AbstractLinearFunction { diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java index 9998f0a3b1c..42925339fd1 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java @@ -7,12 +7,12 @@ import java.util.Map; import java.util.Objects; import java.util.function.Consumer; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.api.request.framework.DurationForEnum; import org.opentripplanner.routing.api.request.framework.TimeAndCostPenalty; import org.opentripplanner.routing.api.request.framework.TimeAndCostPenaltyForEnum; import org.opentripplanner.routing.api.request.framework.TimePenalty; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Preferences for access/egress routing on street network diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/AccessibilityPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/AccessibilityPreferences.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/preference/AccessibilityPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/AccessibilityPreferences.java index 303bda51858..d4d232ab3f6 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/AccessibilityPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/AccessibilityPreferences.java @@ -3,7 +3,7 @@ import java.util.Objects; import java.util.function.Consumer; import org.opentripplanner.framework.model.Cost; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Preferences for how to treat trips or stops with accessibility restrictions, like wheelchair diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java index 5767b74eaa8..038d6c140da 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java @@ -1,17 +1,17 @@ package org.opentripplanner.routing.api.request.preference; -import static org.opentripplanner.framework.lang.DoubleUtils.doubleEquals; -import static org.opentripplanner.framework.lang.ObjectUtils.ifNotNull; import static org.opentripplanner.routing.core.VehicleRoutingOptimizeType.SAFE_STREETS; import static org.opentripplanner.routing.core.VehicleRoutingOptimizeType.TRIANGLE; +import static org.opentripplanner.utils.lang.DoubleUtils.doubleEquals; +import static org.opentripplanner.utils.lang.ObjectUtils.ifNotNull; import java.io.Serializable; import java.util.Objects; import java.util.function.Consumer; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.framework.model.Units; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * The bike preferences contain all speed, reluctance, cost and factor preferences for biking diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java index cc9b7ba62d8..3ea3634c623 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java @@ -1,15 +1,15 @@ package org.opentripplanner.routing.api.request.preference; -import static org.opentripplanner.framework.lang.ObjectUtils.ifNotNull; +import static org.opentripplanner.utils.lang.ObjectUtils.ifNotNull; import java.io.Serializable; import java.time.Duration; import java.util.Objects; 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.utils.lang.DoubleUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * The car preferences contain all speed, reluctance, cost and factor preferences for driving diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/ElevatorPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/ElevatorPreferences.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/preference/ElevatorPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/ElevatorPreferences.java index 7ee6409d7b7..7e5e55d6263 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/ElevatorPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/ElevatorPreferences.java @@ -5,7 +5,7 @@ import java.util.function.Consumer; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.framework.model.Units; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * TODO: how long does it /really/ take to an elevator? diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterDebugProfile.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterDebugProfile.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterDebugProfile.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterDebugProfile.java diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferences.java similarity index 93% rename from src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferences.java index 91f3071d4ed..f18cf5ce9c1 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferences.java @@ -4,9 +4,9 @@ import java.util.Objects; import java.util.function.Consumer; import org.opentripplanner.framework.model.Units; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Group by Similarity filter parameters. See the configuration for documentation of each field. @@ -31,7 +31,7 @@ public final class ItineraryFilterPreferences { private final boolean removeItinerariesWithSameRoutesAndStops; private final TransitGeneralizedCostFilterParams transitGeneralizedCostLimit; private final CostLinearFunction removeTransitWithHigherCostThanBestOnStreetOnly; - private final boolean removeTransitIfWalkingIsBetter; + private final boolean filterDirectFlexBySearchWindow; private ItineraryFilterPreferences() { this.accessibilityScore = false; @@ -52,7 +52,7 @@ private ItineraryFilterPreferences() { ); this.removeTransitWithHigherCostThanBestOnStreetOnly = CostLinearFunction.of(Duration.ofMinutes(1), 1.3); - this.removeTransitIfWalkingIsBetter = false; + this.filterDirectFlexBySearchWindow = true; } private ItineraryFilterPreferences(Builder builder) { @@ -73,7 +73,7 @@ private ItineraryFilterPreferences(Builder builder) { this.transitGeneralizedCostLimit = Objects.requireNonNull(builder.transitGeneralizedCostLimit); this.removeTransitWithHigherCostThanBestOnStreetOnly = Objects.requireNonNull(builder.removeTransitWithHigherCostThanBestOnStreetOnly); - this.removeTransitIfWalkingIsBetter = builder.removeTransitIfWalkingIsBetter; + this.filterDirectFlexBySearchWindow = builder.filterDirectFlexBySearchWindow; } public static Builder of() { @@ -136,8 +136,8 @@ public CostLinearFunction removeTransitWithHigherCostThanBestOnStreetOnly() { return removeTransitWithHigherCostThanBestOnStreetOnly; } - public boolean removeTransitIfWalkingIsBetter() { - return removeTransitIfWalkingIsBetter; + public boolean filterDirectFlexBySearchWindow() { + return filterDirectFlexBySearchWindow; } @Override @@ -187,7 +187,7 @@ public String toString() { "removeItinerariesWithSameRoutesAndStops", removeItinerariesWithSameRoutesAndStops ) - .addBoolIfTrue("removeTransitIfWalkingIsBetter", removeTransitIfWalkingIsBetter) + .addBoolIfTrue("filterDirectFlexBySearchWindow", filterDirectFlexBySearchWindow) .toString(); } @@ -200,7 +200,6 @@ public boolean equals(Object o) { accessibilityScore == that.accessibilityScore && Double.compare(that.bikeRentalDistanceRatio, bikeRentalDistanceRatio) == 0 && debug == that.debug && - removeTransitIfWalkingIsBetter == that.removeTransitIfWalkingIsBetter && filterItinerariesWithSameFirstOrLastTrip == that.filterItinerariesWithSameFirstOrLastTrip && Double.compare( that.groupedOtherThanSameLegsMaxCostMultiplier, @@ -217,7 +216,8 @@ public boolean equals(Object o) { removeTransitWithHigherCostThanBestOnStreetOnly, that.removeTransitWithHigherCostThanBestOnStreetOnly ) && - Objects.equals(transitGeneralizedCostLimit, that.transitGeneralizedCostLimit) + Objects.equals(transitGeneralizedCostLimit, that.transitGeneralizedCostLimit) && + filterDirectFlexBySearchWindow == that.filterDirectFlexBySearchWindow ); } @@ -237,7 +237,7 @@ public int hashCode() { removeItinerariesWithSameRoutesAndStops, transitGeneralizedCostLimit, removeTransitWithHigherCostThanBestOnStreetOnly, - removeTransitIfWalkingIsBetter + filterDirectFlexBySearchWindow ); } @@ -257,7 +257,7 @@ public static class Builder { private boolean removeItinerariesWithSameRoutesAndStops; private TransitGeneralizedCostFilterParams transitGeneralizedCostLimit; private CostLinearFunction removeTransitWithHigherCostThanBestOnStreetOnly; - private boolean removeTransitIfWalkingIsBetter; + private boolean filterDirectFlexBySearchWindow; public ItineraryFilterPreferences original() { return original; @@ -341,11 +341,6 @@ public Builder withRemoveTransitWithHigherCostThanBestOnStreetOnly( return this; } - public Builder withRemoveTransitIfWalkingIsBetter(boolean removeTransitIfWalkingIsBetter) { - this.removeTransitIfWalkingIsBetter = removeTransitIfWalkingIsBetter; - return this; - } - public Builder(ItineraryFilterPreferences original) { this.original = original; this.accessibilityScore = original.accessibilityScore; @@ -365,7 +360,7 @@ public Builder(ItineraryFilterPreferences original) { this.transitGeneralizedCostLimit = original.transitGeneralizedCostLimit; this.removeTransitWithHigherCostThanBestOnStreetOnly = original.removeTransitWithHigherCostThanBestOnStreetOnly; - this.removeTransitIfWalkingIsBetter = original.removeTransitIfWalkingIsBetter; + this.filterDirectFlexBySearchWindow = original.filterDirectFlexBySearchWindow; } public Builder apply(Consumer body) { @@ -377,5 +372,10 @@ public ItineraryFilterPreferences build() { var value = new ItineraryFilterPreferences(this); return original.equals(value) ? original : value; } + + public Builder withFilterDirectFlexBySearchWindow(boolean filterDirectFlexBySearchWindow) { + this.filterDirectFlexBySearchWindow = filterDirectFlexBySearchWindow; + return this; + } } } diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/RaptorPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/RaptorPreferences.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/preference/RaptorPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/RaptorPreferences.java index 03ed9482ff8..e9318bc8dc3 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/RaptorPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/RaptorPreferences.java @@ -11,10 +11,10 @@ import java.util.function.Consumer; import javax.annotation.Nullable; import org.opentripplanner.framework.model.Units; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.SearchDirection; import org.opentripplanner.raptor.api.request.Optimization; import org.opentripplanner.raptor.api.request.RaptorProfile; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Set of optimizations to use with Raptor. These are available here for testing purposes. diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/Relax.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/Relax.java similarity index 92% rename from src/main/java/org/opentripplanner/routing/api/request/preference/Relax.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/Relax.java index 8f10ffd1525..a5e61325483 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/Relax.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/Relax.java @@ -1,8 +1,8 @@ package org.opentripplanner.routing.api.request.preference; import java.util.Locale; -import org.opentripplanner.framework.lang.DoubleUtils; -import org.opentripplanner.framework.lang.IntUtils; +import org.opentripplanner.utils.lang.DoubleUtils; +import org.opentripplanner.utils.lang.IntUtils; /** * Relax a value by the given ratio and slack. The relaxed value diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java index 58ca5b180bf..5eccc970101 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java @@ -1,12 +1,11 @@ package org.opentripplanner.routing.api.request.preference; import static java.util.Objects.requireNonNull; -import static org.opentripplanner.framework.lang.ObjectUtils.ifNotNull; +import static org.opentripplanner.utils.lang.ObjectUtils.ifNotNull; import java.io.Serializable; import java.util.Objects; import java.util.function.Consumer; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.street.search.TraverseMode; @@ -81,7 +80,6 @@ public StreetPreferences street() { /** * Preferences for how strict wheel-accessibility settings are */ - @Nonnull public WheelchairPreferences wheelchair() { return wheelchair; } @@ -108,7 +106,6 @@ public VehicleParkingPreferences parking(TraverseMode mode) { /** * Get rental preferences for the traverse mode. Note, only car, scooter and bike are supported. */ - @Nonnull public VehicleRentalPreferences rental(TraverseMode mode) { return switch (mode) { case BICYCLE -> bike.rental(); @@ -131,7 +128,6 @@ public VehicleRentalPreferences rental(StreetMode mode) { }; } - @Nonnull public ItineraryFilterPreferences itineraryFilter() { return itineraryFilter; } diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java index 1d5cf83a54b..6a20cbcd293 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java @@ -1,16 +1,16 @@ package org.opentripplanner.routing.api.request.preference; -import static org.opentripplanner.framework.lang.DoubleUtils.doubleEquals; -import static org.opentripplanner.framework.lang.ObjectUtils.ifNotNull; import static org.opentripplanner.routing.core.VehicleRoutingOptimizeType.SAFE_STREETS; import static org.opentripplanner.routing.core.VehicleRoutingOptimizeType.TRIANGLE; +import static org.opentripplanner.utils.lang.DoubleUtils.doubleEquals; +import static org.opentripplanner.utils.lang.ObjectUtils.ifNotNull; import java.io.Serializable; import java.util.Objects; import java.util.function.Consumer; import org.opentripplanner.framework.model.Units; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * The scooter preferences contain all speed, reluctance, cost and factor preferences for scooter diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/StreetPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/StreetPreferences.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/api/request/preference/StreetPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/StreetPreferences.java index 6ea6ee1fc3a..bb526ceaa31 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/StreetPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/StreetPreferences.java @@ -1,7 +1,6 @@ package org.opentripplanner.routing.api.request.preference; import static java.time.Duration.ofHours; -import static java.time.Duration.ofMinutes; import static java.util.Objects.requireNonNull; import java.io.Serializable; @@ -9,15 +8,13 @@ import java.util.Map; import java.util.Objects; import java.util.function.Consumer; -import javax.annotation.Nonnull; -import org.opentripplanner.framework.lang.DoubleUtils; import org.opentripplanner.framework.model.Units; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.api.request.framework.DurationForEnum; -import org.opentripplanner.routing.api.request.framework.TimeAndCostPenalty; import org.opentripplanner.street.search.intersection_model.DrivingDirection; import org.opentripplanner.street.search.intersection_model.IntersectionTraversalModel; +import org.opentripplanner.utils.lang.DoubleUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This class holds preferences for street routing in general, not mode specific. @@ -100,7 +97,6 @@ public DurationForEnum maxDirectDuration() { * CAR). So the default timeout for a street search is set quite high. This is used to abort the * search if the max distance is not reached within the timeout. */ - @Nonnull public Duration routingTimeout() { return routingTimeout; } diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/SystemPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/SystemPreferences.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/preference/SystemPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/SystemPreferences.java index 442ab33434a..f35a65c2f03 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/SystemPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/SystemPreferences.java @@ -9,8 +9,8 @@ import java.util.Set; import java.util.function.Consumer; import org.opentripplanner.ext.dataoverlay.api.DataOverlayParameters; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.api.request.RoutingTag; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Configure system related features - a system feature is a non-functional feature. It diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java index ae4f1039f32..cca9105f112 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java @@ -1,7 +1,7 @@ package org.opentripplanner.routing.api.request.preference; -import static org.opentripplanner.framework.lang.DoubleUtils.doubleEquals; -import static org.opentripplanner.framework.lang.DoubleUtils.roundTo2Decimals; +import static org.opentripplanner.utils.lang.DoubleUtils.doubleEquals; +import static org.opentripplanner.utils.lang.DoubleUtils.roundTo2Decimals; /** * Sets the (bicycle or scooter) triangle routing parameters -- the relative importance of safety, diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/TransferOptimizationPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/TransferOptimizationPreferences.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/api/request/preference/TransferOptimizationPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/TransferOptimizationPreferences.java index 41a1954603b..7ba6e609ce9 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/TransferOptimizationPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/TransferOptimizationPreferences.java @@ -1,13 +1,13 @@ package org.opentripplanner.routing.api.request.preference; -import static org.opentripplanner.framework.lang.DoubleUtils.doubleEquals; +import static org.opentripplanner.utils.lang.DoubleUtils.doubleEquals; import java.io.Serializable; import java.util.Objects; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.model.Units; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.algorithm.transferoptimization.api.TransferOptimizationParameters; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * See {@link TransferOptimizationParameters} for documentation on this class. diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/TransferPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/TransferPreferences.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/preference/TransferPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/TransferPreferences.java index 464b9872bdd..f996dd5e6f4 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/TransferPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/TransferPreferences.java @@ -1,7 +1,7 @@ package org.opentripplanner.routing.api.request.preference; import static java.util.Objects.requireNonNull; -import static org.opentripplanner.framework.lang.DoubleUtils.doubleEquals; +import static org.opentripplanner.utils.lang.DoubleUtils.doubleEquals; import java.io.Serializable; import java.time.Duration; @@ -9,9 +9,9 @@ import java.util.function.Consumer; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.framework.model.Units; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.algorithm.transferoptimization.api.TransferOptimizationParameters; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Parameters for doing transfers between transit legs. diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java index 78f30277e72..a237dd53527 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java @@ -7,10 +7,10 @@ import java.util.Objects; import java.util.function.Consumer; import org.opentripplanner.framework.model.Cost; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.framework.DurationForEnum; import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Preferences for transit routing. @@ -137,6 +137,10 @@ public CostLinearFunction relaxTransitGroupPriority() { return relaxTransitGroupPriority; } + public boolean isRelaxTransitGroupPrioritySet() { + return !relaxTransitGroupPriority.isNormal(); + } + /** * When true, real-time updates are ignored during this search. */ diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferences.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferences.java index f7183812c3a..732171c7b80 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferences.java @@ -7,9 +7,9 @@ import java.util.Set; import java.util.function.Consumer; import org.opentripplanner.framework.model.Cost; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.api.request.preference.filter.VehicleParkingFilter; import org.opentripplanner.routing.api.request.preference.filter.VehicleParkingSelect; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * The parking preferences contain preferences for car and bicycle parking. These preferences diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java index 6c9bbfea875..4c00014f30d 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java @@ -7,7 +7,7 @@ import java.util.function.Consumer; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.framework.model.Units; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Preferences for renting a Bike, Car or other type of vehicle. diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java index b7adc04df1c..50b3735a85d 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java @@ -6,7 +6,7 @@ import java.util.function.Consumer; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.framework.model.Units; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Preferences for walking a vehicle. diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/WalkPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/WalkPreferences.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/preference/WalkPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/WalkPreferences.java index 8e5061d752b..4a5969049ba 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/WalkPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/WalkPreferences.java @@ -1,13 +1,13 @@ package org.opentripplanner.routing.api.request.preference; -import static org.opentripplanner.framework.lang.DoubleUtils.doubleEquals; +import static org.opentripplanner.utils.lang.DoubleUtils.doubleEquals; import java.io.Serializable; import java.util.Objects; import java.util.function.Consumer; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.framework.model.Units; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * The walk preferences contain all speed, reluctance, cost and factor preferences for walking diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/WheelchairPreferences.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/WheelchairPreferences.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/api/request/preference/WheelchairPreferences.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/WheelchairPreferences.java index 737c5057943..d8a53d8e098 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/WheelchairPreferences.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/WheelchairPreferences.java @@ -6,7 +6,7 @@ import java.util.Objects; import java.util.function.Consumer; import org.opentripplanner.framework.model.Units; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * See the configuration for documentation of each field. diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingFilter.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingFilter.java similarity index 93% rename from src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingFilter.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingFilter.java index c4f5cee422f..c03d8d18bea 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingFilter.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingFilter.java @@ -4,9 +4,8 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; -import javax.annotation.Nonnull; -import org.opentripplanner.framework.tostring.ToStringBuilder; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A filter class that checks if parking faclities match certain conditions for @@ -87,7 +86,6 @@ public int hashCode() { return Arrays.hashCode(not) + Arrays.hashCode(select); } - @Nonnull private static VehicleParkingSelect[] makeFilter(Collection select) { return select.stream().filter(f -> !f.isEmpty()).toArray(VehicleParkingSelect[]::new); } diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingSelect.java b/application/src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingSelect.java similarity index 92% rename from src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingSelect.java rename to application/src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingSelect.java index 2d3935461d4..d30f0c6795d 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingSelect.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/preference/filter/VehicleParkingSelect.java @@ -2,7 +2,7 @@ import java.util.Collections; import java.util.Set; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; /** * A set of conditions that can be used to check if a parking facility should be included/excluded diff --git a/src/main/java/org/opentripplanner/routing/api/request/request/JourneyRequest.java b/application/src/main/java/org/opentripplanner/routing/api/request/request/JourneyRequest.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/request/request/JourneyRequest.java rename to application/src/main/java/org/opentripplanner/routing/api/request/request/JourneyRequest.java diff --git a/src/main/java/org/opentripplanner/routing/api/request/request/StreetRequest.java b/application/src/main/java/org/opentripplanner/routing/api/request/request/StreetRequest.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/request/request/StreetRequest.java rename to application/src/main/java/org/opentripplanner/routing/api/request/request/StreetRequest.java diff --git a/src/main/java/org/opentripplanner/routing/api/request/request/TransitRequest.java b/application/src/main/java/org/opentripplanner/routing/api/request/request/TransitRequest.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/request/request/TransitRequest.java rename to application/src/main/java/org/opentripplanner/routing/api/request/request/TransitRequest.java diff --git a/src/main/java/org/opentripplanner/routing/api/request/request/filter/AllowAllTransitFilter.java b/application/src/main/java/org/opentripplanner/routing/api/request/request/filter/AllowAllTransitFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/request/request/filter/AllowAllTransitFilter.java rename to application/src/main/java/org/opentripplanner/routing/api/request/request/filter/AllowAllTransitFilter.java diff --git a/src/main/java/org/opentripplanner/routing/api/request/request/filter/SelectRequest.java b/application/src/main/java/org/opentripplanner/routing/api/request/request/filter/SelectRequest.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/request/filter/SelectRequest.java rename to application/src/main/java/org/opentripplanner/routing/api/request/request/filter/SelectRequest.java index a1610ed8947..8ae98b8dfc9 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/request/filter/SelectRequest.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/request/filter/SelectRequest.java @@ -4,12 +4,12 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.modes.AllowTransitModeFilter; import org.opentripplanner.transit.model.basic.MainAndSubMode; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.utils.tostring.ToStringBuilder; public class SelectRequest implements Serializable { diff --git a/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitFilter.java b/application/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitFilter.java rename to application/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitFilter.java diff --git a/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitFilterRequest.java b/application/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitFilterRequest.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitFilterRequest.java rename to application/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitFilterRequest.java index 38f79b82baa..6380ace7c83 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitFilterRequest.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitFilterRequest.java @@ -5,9 +5,9 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.utils.tostring.ToStringBuilder; public class TransitFilterRequest implements Serializable, TransitFilter { diff --git a/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitGroupSelect.java b/application/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitGroupSelect.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitGroupSelect.java rename to application/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitGroupSelect.java index dfa5daa0e31..caa8c9e0d65 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitGroupSelect.java +++ b/application/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitGroupSelect.java @@ -5,9 +5,9 @@ import java.util.Comparator; import java.util.List; import java.util.Objects; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Select a given set of transit routes base on the list of diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/via/AbstractViaLocation.java b/application/src/main/java/org/opentripplanner/routing/api/request/via/AbstractViaLocation.java new file mode 100644 index 00000000000..2f694df53cb --- /dev/null +++ b/application/src/main/java/org/opentripplanner/routing/api/request/via/AbstractViaLocation.java @@ -0,0 +1,44 @@ +package org.opentripplanner.routing.api.request.via; + +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import javax.annotation.Nullable; +import org.opentripplanner.transit.model.framework.FeedScopedId; + +public abstract class AbstractViaLocation implements ViaLocation { + + private final String label; + private final List stopLocationIds; + + public AbstractViaLocation(String label, Collection stopLocationIds) { + this.label = label; + this.stopLocationIds = List.copyOf(stopLocationIds); + } + + @Nullable + @Override + public String label() { + return label; + } + + @Override + public List stopLocationIds() { + return stopLocationIds; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + AbstractViaLocation that = (AbstractViaLocation) o; + return ( + Objects.equals(label, that.label) && Objects.equals(stopLocationIds, that.stopLocationIds) + ); + } + + @Override + public int hashCode() { + return Objects.hash(label, stopLocationIds); + } +} diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/via/PassThroughViaLocation.java b/application/src/main/java/org/opentripplanner/routing/api/request/via/PassThroughViaLocation.java new file mode 100644 index 00000000000..9da6ae5cd23 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/routing/api/request/via/PassThroughViaLocation.java @@ -0,0 +1,38 @@ +package org.opentripplanner.routing.api.request.via; + +import java.util.Collection; +import javax.annotation.Nullable; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.tostring.ToStringBuilder; + +/** + * One of the listed stop locations or one of its children must be visited. An on-board + * intermediate stop visit is ok, as well as boarding or alighting at one of the stops. + */ +public class PassThroughViaLocation extends AbstractViaLocation { + + @SuppressWarnings("DataFlowIssue") + public PassThroughViaLocation(@Nullable String label, Collection stopLocationIds) { + super(label, stopLocationIds); + if (stopLocationIds.isEmpty()) { + throw new IllegalArgumentException( + "A pass through via location must have at least one stop location." + + (label == null ? "" : " Label: " + label) + ); + } + } + + @Override + public boolean isPassThroughLocation() { + return true; + } + + @Override + public String toString() { + return ToStringBuilder + .of(PassThroughViaLocation.class) + .addObj("label", label()) + .addCol("stopLocationIds", stopLocationIds()) + .toString(); + } +} diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/via/ViaLocation.java b/application/src/main/java/org/opentripplanner/routing/api/request/via/ViaLocation.java new file mode 100644 index 00000000000..4a3476954c8 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/routing/api/request/via/ViaLocation.java @@ -0,0 +1,56 @@ +package org.opentripplanner.routing.api.request.via; + +import java.time.Duration; +import java.util.List; +import javax.annotation.Nullable; +import org.opentripplanner.framework.geometry.WgsCoordinate; +import org.opentripplanner.transit.model.framework.FeedScopedId; + +/** + * Defines a via location which the journey must route through. At least one stop location or + * coordinate must exist. When routing, the via-location is visited if at least one of the stops + * or coordinates is visited, before the journey continues. There is no need to visit any other + * stop location or coordinate. + *

    + * The stop locations and coordinates are distinct locations. In earlier versions of OTP the + * coordinates were used as a fallback for when a stop was not found. But in this version, a + * {@link org.opentripplanner.transit.model.framework.EntityNotFoundException} is thrown if + * one of the stops does not exist. The search does NOT try to be smart and recover from an + * entity not found exception. + */ +public interface ViaLocation { + /** + * Get an optional name/label of for debugging and logging. Not used in business logic. + */ + @Nullable + String label(); + + /** + * The minimum wait time is used to force the trip to stay the given duration at the via location + * before the trip is continued. This cannot be used together with allow-pass-through, since a + * pass-through stop is visited on-board. + */ + default Duration minimumWaitTime() { + return Duration.ZERO; + } + + /** + * Returns {@code true} if this location is a pass-through-point. Only stops can be visited and + * the {@code minimumWaitTime} must be zero. + */ + boolean isPassThroughLocation(); + + /** + * A list of stops which can be used as via location together with the {@code coordinates}. A stop + * location can be a stop, a station, a multimodal station or a group of stations. + */ + List stopLocationIds(); + + /** + * A list of coordinates used together with the {@code stopLocationIds} as the via location. + * This is optional, an empty list is returned if no coordinates are available. + */ + default List coordinates() { + return List.of(); + } +} diff --git a/application/src/main/java/org/opentripplanner/routing/api/request/via/VisitViaLocation.java b/application/src/main/java/org/opentripplanner/routing/api/request/via/VisitViaLocation.java new file mode 100644 index 00000000000..550b1646aeb --- /dev/null +++ b/application/src/main/java/org/opentripplanner/routing/api/request/via/VisitViaLocation.java @@ -0,0 +1,103 @@ +package org.opentripplanner.routing.api.request.via; + +import java.time.Duration; +import java.util.List; +import java.util.Objects; +import javax.annotation.Nullable; +import org.opentripplanner.framework.geometry.WgsCoordinate; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; + +/** + * A visit-via-location is a physical visit to one of the stops or coordinates listed. An on-board + * visit does not count. The traveler must alight or board at the given stop for it to to be + * accepted. To visit a coordinate, the traveler must walk(bike or drive) to the closest point in + * the street network from a stop and back to another stop to join the transit network. + *

    + * TODO: NOTE! Coordinates are NOT supported yet. + */ +public class VisitViaLocation extends AbstractViaLocation { + + private static final Duration MINIMUM_WAIT_TIME_MAX_LIMIT = Duration.ofHours(24); + + private final Duration minimumWaitTime; + private final List coordinates; + + public VisitViaLocation( + @Nullable String label, + @Nullable Duration minimumWaitTime, + List stopLocationIds, + List coordinates + ) { + super(label, stopLocationIds); + this.minimumWaitTime = + DurationUtils.requireNonNegative( + minimumWaitTime == null ? Duration.ZERO : minimumWaitTime, + MINIMUM_WAIT_TIME_MAX_LIMIT, + "minimumWaitTime" + ); + this.coordinates = List.copyOf(coordinates); + + if (stopLocationIds().isEmpty() && coordinates().isEmpty()) { + throw new IllegalArgumentException( + "A via location must have at least one stop location or a coordinate." + + (label == null ? "" : " Label: " + label) + ); + } + } + + /** + * The minimum wait time is used to force the trip to stay the given duration at the via location + * before the trip is continued. This cannot be used together with allow-pass-through, since a + * pass-through stop is visited on-board. + */ + @Override + public Duration minimumWaitTime() { + return minimumWaitTime; + } + + @Override + public boolean isPassThroughLocation() { + return false; + } + + @Override + public List coordinates() { + return coordinates; + } + + @Override + public String toString() { + return ToStringBuilder + .of(VisitViaLocation.class) + .addObj("label", label()) + .addDuration("minimumWaitTime", minimumWaitTime, Duration.ZERO) + .addCol("stopLocationIds", stopLocationIds()) + .addObj("coordinates", coordinates) + .toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + if (!super.equals(o)) { + return false; + } + VisitViaLocation that = (VisitViaLocation) o; + return ( + Objects.equals(minimumWaitTime, that.minimumWaitTime) && + Objects.equals(coordinates, that.coordinates) + ); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), minimumWaitTime, coordinates); + } +} diff --git a/src/main/java/org/opentripplanner/routing/api/response/InputField.java b/application/src/main/java/org/opentripplanner/routing/api/response/InputField.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/response/InputField.java rename to application/src/main/java/org/opentripplanner/routing/api/response/InputField.java diff --git a/src/main/java/org/opentripplanner/routing/api/response/RoutingError.java b/application/src/main/java/org/opentripplanner/routing/api/response/RoutingError.java similarity index 93% rename from src/main/java/org/opentripplanner/routing/api/response/RoutingError.java rename to application/src/main/java/org/opentripplanner/routing/api/response/RoutingError.java index 2c948e1777c..d5c8173f09e 100644 --- a/src/main/java/org/opentripplanner/routing/api/response/RoutingError.java +++ b/application/src/main/java/org/opentripplanner/routing/api/response/RoutingError.java @@ -1,7 +1,7 @@ package org.opentripplanner.routing.api.response; import java.util.Objects; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; public class RoutingError { diff --git a/src/main/java/org/opentripplanner/routing/api/response/RoutingErrorCode.java b/application/src/main/java/org/opentripplanner/routing/api/response/RoutingErrorCode.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/response/RoutingErrorCode.java rename to application/src/main/java/org/opentripplanner/routing/api/response/RoutingErrorCode.java diff --git a/src/main/java/org/opentripplanner/routing/api/response/RoutingResponse.java b/application/src/main/java/org/opentripplanner/routing/api/response/RoutingResponse.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/api/response/RoutingResponse.java rename to application/src/main/java/org/opentripplanner/routing/api/response/RoutingResponse.java index f7bcaca72e2..fe9f6457cf4 100644 --- a/src/main/java/org/opentripplanner/routing/api/response/RoutingResponse.java +++ b/application/src/main/java/org/opentripplanner/routing/api/response/RoutingResponse.java @@ -1,10 +1,10 @@ package org.opentripplanner.routing.api.response; import java.util.List; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.plan.TripPlan; import org.opentripplanner.model.plan.paging.cursor.PageCursor; import org.opentripplanner.routing.framework.DebugTimingAggregator; +import org.opentripplanner.utils.tostring.ToStringBuilder; public class RoutingResponse { diff --git a/src/main/java/org/opentripplanner/routing/api/response/TripSearchMetadata.java b/application/src/main/java/org/opentripplanner/routing/api/response/TripSearchMetadata.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/api/response/TripSearchMetadata.java rename to application/src/main/java/org/opentripplanner/routing/api/response/TripSearchMetadata.java index a5eb5842f23..704a1cb8e18 100644 --- a/src/main/java/org/opentripplanner/routing/api/response/TripSearchMetadata.java +++ b/application/src/main/java/org/opentripplanner/routing/api/response/TripSearchMetadata.java @@ -4,7 +4,7 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Meta-data about the trip search performed. diff --git a/src/main/java/org/opentripplanner/routing/api/response/ViaRoutingResponse.java b/application/src/main/java/org/opentripplanner/routing/api/response/ViaRoutingResponse.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/response/ViaRoutingResponse.java rename to application/src/main/java/org/opentripplanner/routing/api/response/ViaRoutingResponse.java diff --git a/src/main/java/org/opentripplanner/routing/api/response/ViaRoutingResponseConnection.java b/application/src/main/java/org/opentripplanner/routing/api/response/ViaRoutingResponseConnection.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/api/response/ViaRoutingResponseConnection.java rename to application/src/main/java/org/opentripplanner/routing/api/response/ViaRoutingResponseConnection.java diff --git a/src/main/java/org/opentripplanner/routing/core/FareType.java b/application/src/main/java/org/opentripplanner/routing/core/FareType.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/core/FareType.java rename to application/src/main/java/org/opentripplanner/routing/core/FareType.java diff --git a/src/main/java/org/opentripplanner/routing/core/VehicleRoutingOptimizeType.java b/application/src/main/java/org/opentripplanner/routing/core/VehicleRoutingOptimizeType.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/core/VehicleRoutingOptimizeType.java rename to application/src/main/java/org/opentripplanner/routing/core/VehicleRoutingOptimizeType.java diff --git a/src/main/java/org/opentripplanner/routing/error/GraphNotFoundException.java b/application/src/main/java/org/opentripplanner/routing/error/GraphNotFoundException.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/error/GraphNotFoundException.java rename to application/src/main/java/org/opentripplanner/routing/error/GraphNotFoundException.java diff --git a/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java b/application/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java rename to application/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java diff --git a/src/main/java/org/opentripplanner/routing/error/RoutingValidationException.java b/application/src/main/java/org/opentripplanner/routing/error/RoutingValidationException.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/error/RoutingValidationException.java rename to application/src/main/java/org/opentripplanner/routing/error/RoutingValidationException.java diff --git a/src/main/java/org/opentripplanner/routing/fares/FareService.java b/application/src/main/java/org/opentripplanner/routing/fares/FareService.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/fares/FareService.java rename to application/src/main/java/org/opentripplanner/routing/fares/FareService.java diff --git a/src/main/java/org/opentripplanner/routing/fares/FareServiceFactory.java b/application/src/main/java/org/opentripplanner/routing/fares/FareServiceFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/fares/FareServiceFactory.java rename to application/src/main/java/org/opentripplanner/routing/fares/FareServiceFactory.java diff --git a/src/main/java/org/opentripplanner/routing/framework/DebugTimingAggregator.java b/application/src/main/java/org/opentripplanner/routing/framework/DebugTimingAggregator.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/framework/DebugTimingAggregator.java rename to application/src/main/java/org/opentripplanner/routing/framework/DebugTimingAggregator.java diff --git a/src/main/java/org/opentripplanner/routing/framework/MicrometerUtils.java b/application/src/main/java/org/opentripplanner/routing/framework/MicrometerUtils.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/framework/MicrometerUtils.java rename to application/src/main/java/org/opentripplanner/routing/framework/MicrometerUtils.java diff --git a/src/main/java/org/opentripplanner/routing/graph/Graph.java b/application/src/main/java/org/opentripplanner/routing/graph/Graph.java similarity index 92% rename from src/main/java/org/opentripplanner/routing/graph/Graph.java rename to application/src/main/java/org/opentripplanner/routing/graph/Graph.java index fa3d12b92f7..70ce563700c 100644 --- a/src/main/java/org/opentripplanner/routing/graph/Graph.java +++ b/application/src/main/java/org/opentripplanner/routing/graph/Graph.java @@ -12,7 +12,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.prefs.Preferences; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.locationtech.jts.geom.Geometry; import org.opentripplanner.ext.dataoverlay.configuration.DataOverlayParameterBindings; @@ -23,7 +22,6 @@ import org.opentripplanner.routing.graph.index.StreetIndex; import org.opentripplanner.routing.linking.VertexLinker; import org.opentripplanner.routing.services.notes.StreetNotesService; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.vertex.TransitStopVertex; @@ -31,7 +29,7 @@ import org.opentripplanner.street.model.vertex.VertexLabel; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,10 +42,10 @@ * In OTP1, the Graph contained vertices and edges representing the entire transportation network, * including edges representing both street segments and public transit lines connecting stops. In * OTP2, the Graph edges now represent only the street network. Transit routing is performed on - * other data structures suited to the Raptor algorithm (the TransitModel). Some transit-related + * other data structures suited to the Raptor algorithm (the TimetableRepository). Some transit-related * vertices are still present in the Graph, specifically those representing transit stops, * entrances, and elevators. Their presence in the street graph creates a connection between the two - * routable data structures (identifying where stops in the TransitModel are located relative to + * routable data structures (identifying where stops in the TimetableRepository are located relative to * roads). *

    * Other data structures related to street routing, such as elevation data and vehicle parking @@ -112,7 +110,6 @@ public class Graph implements Serializable { // static variable in CompactElevationProfile in SerializedGraphObject private double distanceBetweenElevationSamples; - private final VehicleParkingService vehicleParkingService = new VehicleParkingService(); private FareService fareService; /** @@ -285,9 +282,9 @@ public int countEdges() { * - graph. This allows a module to index the streetIndex BEFORE another module add * - something that should go into the index; Hence, inconsistent data. */ - public void index(StopModel stopModel) { + public void index(SiteRepository siteRepository) { LOG.info("Index street model..."); - streetIndex = new StreetIndex(this, stopModel); + streetIndex = new StreetIndex(this, siteRepository); LOG.info("Index street model complete."); } @@ -298,7 +295,7 @@ public OpeningHoursCalendarService getOpeningHoursCalendarService() { /** * Get streetIndex, safe to use while routing, but do not use during graph build. - * @see #getStreetIndexSafe(StopModel) + * @see #getStreetIndexSafe(SiteRepository) */ public StreetIndex getStreetIndex() { return this.streetIndex; @@ -308,14 +305,14 @@ public StreetIndex getStreetIndex() { * Get streetIndex during graph build, both OSM street data and transit data must be loaded * before calling this. */ - public StreetIndex getStreetIndexSafe(StopModel stopModel) { - indexIfNotIndexed(stopModel); + public StreetIndex getStreetIndexSafe(SiteRepository siteRepository) { + indexIfNotIndexed(siteRepository); return this.streetIndex; } /** * Get VertexLinker, safe to use while routing, but do not use during graph build. - * @see #getLinkerSafe(StopModel) + * @see #getLinkerSafe(SiteRepository) */ public VertexLinker getLinker() { return streetIndex.getVertexLinker(); @@ -325,8 +322,8 @@ public VertexLinker getLinker() { * Get VertexLinker during graph build, both OSM street data and transit data must be loaded * before calling this. */ - public VertexLinker getLinkerSafe(StopModel stopModel) { - indexIfNotIndexed(stopModel); + public VertexLinker getLinkerSafe(SiteRepository siteRepository) { + indexIfNotIndexed(siteRepository); return streetIndex.getVertexLinker(); } @@ -363,11 +360,6 @@ public void setDistanceBetweenElevationSamples(double distanceBetweenElevationSa CompactElevationProfile.setDistanceBetweenSamplesM(distanceBetweenElevationSamples); } - @Nonnull - public VehicleParkingService getVehicleParkingService() { - return vehicleParkingService; - } - public FareService getFareService() { return fareService; } @@ -376,9 +368,9 @@ public void setFareService(FareService fareService) { this.fareService = fareService; } - private void indexIfNotIndexed(StopModel stopModel) { + private void indexIfNotIndexed(SiteRepository siteRepository) { if (streetIndex == null) { - index(stopModel); + index(siteRepository); } } } diff --git a/src/main/java/org/opentripplanner/routing/graph/SerializedGraphObject.java b/application/src/main/java/org/opentripplanner/routing/graph/SerializedGraphObject.java similarity index 89% rename from src/main/java/org/opentripplanner/routing/graph/SerializedGraphObject.java rename to application/src/main/java/org/opentripplanner/routing/graph/SerializedGraphObject.java index b2404adc5d1..a152b96682d 100644 --- a/src/main/java/org/opentripplanner/routing/graph/SerializedGraphObject.java +++ b/application/src/main/java/org/opentripplanner/routing/graph/SerializedGraphObject.java @@ -21,12 +21,11 @@ import org.opentripplanner.ext.stopconsolidation.StopConsolidationRepository; import org.opentripplanner.framework.application.OtpAppException; import org.opentripplanner.framework.geometry.CompactElevationProfile; -import org.opentripplanner.framework.lang.OtpNumberFormat; -import org.opentripplanner.framework.logging.ProgressTracker; import org.opentripplanner.graph_builder.issue.api.DataImportIssueSummary; import org.opentripplanner.model.projectinfo.GraphFileHeader; import org.opentripplanner.model.projectinfo.OtpProjectInfo; import org.opentripplanner.routing.graph.kryosupport.KryoBuilder; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; import org.opentripplanner.service.worldenvelope.WorldEnvelopeRepository; import org.opentripplanner.standalone.config.BuildConfig; import org.opentripplanner.standalone.config.RouterConfig; @@ -35,7 +34,9 @@ import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.transit.model.basic.SubMode; import org.opentripplanner.transit.model.network.RoutingTripPattern; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; +import org.opentripplanner.utils.lang.OtpNumberFormat; +import org.opentripplanner.utils.logging.ProgressTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,7 +56,7 @@ public class SerializedGraphObject implements Serializable { private static final Logger LOG = LoggerFactory.getLogger(SerializedGraphObject.class); public final Graph graph; - public final TransitModel transitModel; + public final TimetableRepository timetableRepository; public final WorldEnvelopeRepository worldEnvelopeRepository; private final Collection edges; @@ -79,11 +80,13 @@ public class SerializedGraphObject implements Serializable { private final int routingTripPatternCounter; public final EmissionsDataModel emissionsDataModel; public final StreetLimitationParameters streetLimitationParameters; + public final VehicleParkingRepository parkingRepository; public SerializedGraphObject( Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, WorldEnvelopeRepository worldEnvelopeRepository, + VehicleParkingRepository parkingRepository, BuildConfig buildConfig, RouterConfig routerConfig, DataImportIssueSummary issueSummary, @@ -93,8 +96,9 @@ public SerializedGraphObject( ) { this.graph = graph; this.edges = graph.getEdges(); - this.transitModel = transitModel; + this.timetableRepository = timetableRepository; this.worldEnvelopeRepository = worldEnvelopeRepository; + this.parkingRepository = parkingRepository; this.buildConfig = buildConfig; this.routerConfig = routerConfig; this.issueSummary = issueSummary; @@ -184,9 +188,9 @@ private static SerializedGraphObject load(InputStream inputStream, String source ); LOG.debug("Graph read."); serObj.reconstructEdgeLists(); - serObj.transitModel.getStopModel().reindexAfterDeserialization(); - serObj.transitModel.index(); - logSerializationCompleteStatus(serObj.graph, serObj.transitModel); + serObj.timetableRepository.getSiteRepository().reindexAfterDeserialization(); + serObj.timetableRepository.index(); + logSerializationCompleteStatus(serObj.graph, serObj.timetableRepository); return serObj; } catch (IOException e) { LOG.error("IO exception while loading graph: {}", e.getLocalizedMessage(), e); @@ -256,11 +260,14 @@ private void save(OutputStream outputStream, String graphName, long size) { // ((InstanceCountingClassResolver) kryo.getClassResolver()).summarize(); } - private static void logSerializationCompleteStatus(Graph graph, TransitModel transitModel) { + private static void logSerializationCompleteStatus( + Graph graph, + TimetableRepository timetableRepository + ) { var f = new OtpNumberFormat(); - var nStops = f.formatNumber(transitModel.getStopModel().stopIndexSize()); - var nTransfers = f.formatNumber(transitModel.getTransferService().listAll().size()); - var nPatterns = f.formatNumber(transitModel.getAllTripPatterns().size()); + var nStops = f.formatNumber(timetableRepository.getSiteRepository().stopIndexSize()); + var nTransfers = f.formatNumber(timetableRepository.getTransferService().listAll().size()); + var nPatterns = f.formatNumber(timetableRepository.getAllTripPatterns().size()); var nVertices = f.formatNumber(graph.countVertices()); var nEdges = f.formatNumber(graph.countEdges()); diff --git a/src/main/java/org/opentripplanner/routing/graph/index/EdgeSpatialIndex.java b/application/src/main/java/org/opentripplanner/routing/graph/index/EdgeSpatialIndex.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/graph/index/EdgeSpatialIndex.java rename to application/src/main/java/org/opentripplanner/routing/graph/index/EdgeSpatialIndex.java diff --git a/src/main/java/org/opentripplanner/routing/graph/index/StreetIndex.java b/application/src/main/java/org/opentripplanner/routing/graph/index/StreetIndex.java similarity index 83% rename from src/main/java/org/opentripplanner/routing/graph/index/StreetIndex.java rename to application/src/main/java/org/opentripplanner/routing/graph/index/StreetIndex.java index 93e333076b0..b632cd5c3e9 100644 --- a/src/main/java/org/opentripplanner/routing/graph/index/StreetIndex.java +++ b/application/src/main/java/org/opentripplanner/routing/graph/index/StreetIndex.java @@ -1,6 +1,7 @@ package org.opentripplanner.routing.graph.index; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -18,7 +19,6 @@ import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.LocalizedString; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.framework.logging.ProgressTracker; import org.opentripplanner.model.GenericLocation; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.graph.Graph; @@ -31,6 +31,7 @@ import org.opentripplanner.street.model.edge.TemporaryFreeEdge; import org.opentripplanner.street.model.edge.TemporaryPartialStreetEdge; import org.opentripplanner.street.model.edge.TemporaryPartialStreetEdgeBuilder; +import org.opentripplanner.street.model.vertex.StationCentroidVertex; import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.street.model.vertex.TemporaryStreetLocation; import org.opentripplanner.street.model.vertex.TransitStopVertex; @@ -39,7 +40,8 @@ import org.opentripplanner.street.search.TraverseModeSet; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.utils.logging.ProgressTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,24 +57,30 @@ public class StreetIndex { private static final Logger LOG = LoggerFactory.getLogger(StreetIndex.class); - private final StopModel stopModel; + private final SiteRepository siteRepository; private final VertexLinker vertexLinker; private final Map transitStopVertices; + /** + * This list contains transitStationVertices for the stations that are configured to route to centroid + */ + private final Map stationCentroidVertices; + private final EdgeSpatialIndex edgeSpatialIndex; private final HashGridSpatialIndex verticesTree; /** * Should only be called by the graph. */ - public StreetIndex(Graph graph, StopModel stopModel) { - this.stopModel = stopModel; + public StreetIndex(Graph graph, SiteRepository siteRepository) { + this.siteRepository = siteRepository; this.edgeSpatialIndex = new EdgeSpatialIndex(); this.verticesTree = new HashGridSpatialIndex<>(); - this.vertexLinker = new VertexLinker(graph, stopModel, edgeSpatialIndex); + this.vertexLinker = new VertexLinker(graph, siteRepository, edgeSpatialIndex); this.transitStopVertices = toImmutableMap(graph.getVerticesOfType(TransitStopVertex.class)); + this.stationCentroidVertices = createStationCentroidVertexMap(graph); postSetup(graph.getVertices()); } @@ -174,7 +182,8 @@ public Collection getEdgesForEnvelope(Envelope envelope) { * * @param endVertex: whether this is a start vertex (if it's false) or end vertex (if it's true) */ - public Set getVerticesForLocation( + @Nullable + public Set getStreetVerticesForLocation( GenericLocation location, StreetMode streetMode, boolean endVertex, @@ -186,7 +195,7 @@ public Set getVerticesForLocation( if (nonTransitMode.isInCar()) { // Fetch coordinate from stop, if not given in request if (location.stopId != null && location.getCoordinate() == null) { - var coordinate = stopModel.getCoordinateById(location.stopId); + var coordinate = siteRepository.getCoordinateById(location.stopId); if (coordinate != null) { location = new GenericLocation( @@ -200,16 +209,24 @@ public Set getVerticesForLocation( } else { // Check if Stop/StopCollection is found by FeedScopeId if (location.stopId != null) { - Set transitStopVertices = getStopVerticesById(location.stopId); - if (transitStopVertices != null && !transitStopVertices.isEmpty()) { - return transitStopVertices; + var streetVertices = getStreetVerticesById(location.stopId); + if (!streetVertices.isEmpty()) { + return streetVertices; } } } // Check if coordinate is provided and connect it to graph if (location.getCoordinate() != null) { - return Set.of(createVertexFromLocation(location, streetMode, endVertex, tempEdges)); + return Set.of( + createVertexFromCoordinate( + location.getCoordinate(), + location.label, + streetMode, + endVertex, + tempEdges + ) + ); } return null; @@ -227,29 +244,25 @@ public String toString() { } /** - * Finds the appropriate vertex for this location. + * Create the appropriate vertex for this coordinate. * * @param endVertex: whether this is a start vertex (if it's false) or end vertex (if it's true) */ - public Vertex getVertexForLocationForTest( - GenericLocation location, + public Vertex createVertexForCoordinateForTest( + Coordinate location, StreetMode streetMode, boolean endVertex, Set tempEdges ) { - // Check if coordinate is provided and connect it to graph - if (location.getCoordinate() == null) { - return null; - } - return createVertexFromLocation(location, streetMode, endVertex, tempEdges); + return createVertexFromCoordinate(location, null, streetMode, endVertex, tempEdges); } /** * @param id Id of Stop, Station, MultiModalStation or GroupOfStations * @return The associated TransitStopVertex or all underlying TransitStopVertices */ - private Set getStopVerticesById(FeedScopedId id) { - return stopModel + public Set getStopOrChildStopsVertices(FeedScopedId id) { + return siteRepository .findStopOrChildStops(id) .stream() .filter(RegularStop.class::isInstance) @@ -258,6 +271,20 @@ private Set getStopVerticesById(FeedScopedId id) { .collect(Collectors.toSet()); } + /** + * Get the street vertices for an id. If the id corresponds to a regular stop we will return the + * coordinate for the stop. + * If the id corresponds to a station we will either return the coordinates of the child stops or + * the station centroid if the station is configured to route to centroid. + */ + public Set getStreetVerticesById(FeedScopedId id) { + var stationVertex = stationCentroidVertices.get(id); + if (stationVertex != null) { + return Set.of(stationVertex); + } + return Collections.unmodifiableSet(getStopOrChildStopsVertices(id)); + } + private static void createHalfLocationForTest( TemporaryStreetLocation base, I18NString name, @@ -326,32 +353,33 @@ private static LineString edgeGeometryOrStraightLine(Edge e) { return geometry; } - private Vertex createVertexFromLocation( - GenericLocation location, + private Vertex createVertexFromCoordinate( + Coordinate coordinate, + @Nullable String label, StreetMode streetMode, boolean endVertex, Set tempEdges ) { if (endVertex) { - LOG.debug("Finding end vertex for {}", location); + LOG.debug("Creating end vertex for {}", coordinate); } else { - LOG.debug("Finding start vertex for {}", location); + LOG.debug("Creating start vertex for {}", coordinate); } I18NString name; - if (location.label == null || location.label.isEmpty()) { + if (label == null || label.isEmpty()) { if (endVertex) { name = new LocalizedString("destination"); } else { name = new LocalizedString("origin"); } } else { - name = new NonLocalizedString(location.label); + name = new NonLocalizedString(label); } TemporaryStreetLocation temporaryStreetLocation = new TemporaryStreetLocation( UUID.randomUUID().toString(), - location.getCoordinate(), + coordinate, name, endVertex ); @@ -385,7 +413,7 @@ private Vertex createVertexFromLocation( temporaryStreetLocation.getIncoming().isEmpty() && temporaryStreetLocation.getOutgoing().isEmpty() ) { - LOG.warn("Couldn't link {}", location); + LOG.warn("Couldn't link {}", coordinate); } temporaryStreetLocation.setWheelchairAccessible(true); @@ -435,4 +463,14 @@ private static Map toImmutableMap( } return Map.copyOf(map); } + + private static Map createStationCentroidVertexMap( + Graph graph + ) { + return graph + .getVerticesOfType(StationCentroidVertex.class) + .stream() + .filter(vertex -> vertex.getStation().shouldRouteToCentroid()) + .collect(Collectors.toUnmodifiableMap(v -> v.getStation().getId(), v -> v)); + } } diff --git a/src/main/java/org/opentripplanner/routing/graph/kryosupport/AtomicIntegerSerializer.java b/application/src/main/java/org/opentripplanner/routing/graph/kryosupport/AtomicIntegerSerializer.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/graph/kryosupport/AtomicIntegerSerializer.java rename to application/src/main/java/org/opentripplanner/routing/graph/kryosupport/AtomicIntegerSerializer.java diff --git a/src/main/java/org/opentripplanner/routing/graph/kryosupport/JavaImmutableListSerializer.java b/application/src/main/java/org/opentripplanner/routing/graph/kryosupport/JavaImmutableListSerializer.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/graph/kryosupport/JavaImmutableListSerializer.java rename to application/src/main/java/org/opentripplanner/routing/graph/kryosupport/JavaImmutableListSerializer.java diff --git a/src/main/java/org/opentripplanner/routing/graph/kryosupport/JavaImmutableMapSerializer.java b/application/src/main/java/org/opentripplanner/routing/graph/kryosupport/JavaImmutableMapSerializer.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/graph/kryosupport/JavaImmutableMapSerializer.java rename to application/src/main/java/org/opentripplanner/routing/graph/kryosupport/JavaImmutableMapSerializer.java diff --git a/src/main/java/org/opentripplanner/routing/graph/kryosupport/JavaImmutableSetSerializer.java b/application/src/main/java/org/opentripplanner/routing/graph/kryosupport/JavaImmutableSetSerializer.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/graph/kryosupport/JavaImmutableSetSerializer.java rename to application/src/main/java/org/opentripplanner/routing/graph/kryosupport/JavaImmutableSetSerializer.java diff --git a/src/main/java/org/opentripplanner/routing/graph/kryosupport/KryoBuilder.java b/application/src/main/java/org/opentripplanner/routing/graph/kryosupport/KryoBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/graph/kryosupport/KryoBuilder.java rename to application/src/main/java/org/opentripplanner/routing/graph/kryosupport/KryoBuilder.java diff --git a/src/main/java/org/opentripplanner/routing/graphfinder/DirectGraphFinder.java b/application/src/main/java/org/opentripplanner/routing/graphfinder/DirectGraphFinder.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/graphfinder/DirectGraphFinder.java rename to application/src/main/java/org/opentripplanner/routing/graphfinder/DirectGraphFinder.java diff --git a/src/main/java/org/opentripplanner/routing/graphfinder/GraphFinder.java b/application/src/main/java/org/opentripplanner/routing/graphfinder/GraphFinder.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/graphfinder/GraphFinder.java rename to application/src/main/java/org/opentripplanner/routing/graphfinder/GraphFinder.java diff --git a/src/main/java/org/opentripplanner/routing/graphfinder/NearbyStop.java b/application/src/main/java/org/opentripplanner/routing/graphfinder/NearbyStop.java similarity index 60% rename from src/main/java/org/opentripplanner/routing/graphfinder/NearbyStop.java rename to application/src/main/java/org/opentripplanner/routing/graphfinder/NearbyStop.java index ada17120c6b..a6581812ee4 100644 --- a/src/main/java/org/opentripplanner/routing/graphfinder/NearbyStop.java +++ b/application/src/main/java/org/opentripplanner/routing/graphfinder/NearbyStop.java @@ -1,11 +1,20 @@ package org.opentripplanner.routing.graphfinder; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; import org.opentripplanner.astar.model.GraphPath; +import org.opentripplanner.routing.api.request.RouteRequest; +import org.opentripplanner.routing.api.request.request.StreetRequest; import org.opentripplanner.street.model.edge.Edge; +import org.opentripplanner.street.model.vertex.TransitStopVertex; +import org.opentripplanner.street.model.vertex.Vertex; +import org.opentripplanner.street.search.request.StreetSearchRequestMapper; import org.opentripplanner.street.search.state.State; import org.opentripplanner.transit.model.site.StopLocation; @@ -43,6 +52,62 @@ public static NearbyStop nearbyStopForState(State state, StopLocation stop) { return new NearbyStop(stop, effectiveWalkDistance, edges, state); } + /** + * Create a NearbyStop with zero distance and no edges. + */ + public static NearbyStop ofZeroDistance(StopLocation stop, State state) { + return new NearbyStop(stop, 0d, Collections.emptyList(), state); + } + + /** + * Create zero distance NearbyStops given a list of TransitStopVertices + */ + public static List nearbyStopsForTransitStopVertices( + Set stopVertices, + boolean reverseDirection, + RouteRequest routeRequest, + StreetRequest streetRequest + ) { + if (stopVertices.isEmpty()) { + return List.of(); + } + + var streetSearchRequest = StreetSearchRequestMapper + .mapToTransferRequest(routeRequest) + .withArriveBy(reverseDirection) + .withMode(streetRequest.mode()) + .build(); + + return stopVertices + .stream() + .map(s -> ofZeroDistance(s.getStop(), new State(s, streetSearchRequest))) + .toList(); + } + + /** + * Given a list of Vertices, find the TransitStopVertices and create zero distance NearbyStops + * for them. + */ + public static List nearbyStopsForTransitStopVerticesFiltered( + Collection vertices, + boolean reverseDirection, + RouteRequest routeRequest, + StreetRequest streetRequest + ) { + var transitStops = vertices + .stream() + .filter(v -> v instanceof TransitStopVertex) + .map(v -> (TransitStopVertex) v) + .collect(Collectors.toSet()); + + return nearbyStopsForTransitStopVertices( + transitStops, + reverseDirection, + routeRequest, + streetRequest + ); + } + /** * Return {@code true} if this instance has a lower weight/cost than the given {@code other}. * If the state is not set, the distance is used for comparison instead. If the diff --git a/src/main/java/org/opentripplanner/routing/graphfinder/PatternAtStop.java b/application/src/main/java/org/opentripplanner/routing/graphfinder/PatternAtStop.java similarity index 95% rename from src/main/java/org/opentripplanner/routing/graphfinder/PatternAtStop.java rename to application/src/main/java/org/opentripplanner/routing/graphfinder/PatternAtStop.java index a8602a77737..ae1380c8f1a 100644 --- a/src/main/java/org/opentripplanner/routing/graphfinder/PatternAtStop.java +++ b/application/src/main/java/org/opentripplanner/routing/graphfinder/PatternAtStop.java @@ -6,13 +6,13 @@ import java.util.Base64; import java.util.List; import java.util.Objects; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.TripTimeOnDate; import org.opentripplanner.routing.stoptimes.ArrivalDeparture; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A reference to a pattern at a specific stop. @@ -48,7 +48,7 @@ public static PatternAtStop fromId(TransitService transitService, String id) { ); return new PatternAtStop( transitService.getRegularStop(stopId), - transitService.getTripPatternForId(patternId) + transitService.getTripPattern(patternId) ); } @@ -70,7 +70,7 @@ public List getStoptimes( int numberOfDepartures, ArrivalDeparture arrivalDeparture ) { - return transitService.stopTimesForPatternAtStop( + return transitService.findTripTimeOnDate( stop, pattern, startTime, diff --git a/src/main/java/org/opentripplanner/routing/graphfinder/PlaceAtDistance.java b/application/src/main/java/org/opentripplanner/routing/graphfinder/PlaceAtDistance.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/graphfinder/PlaceAtDistance.java rename to application/src/main/java/org/opentripplanner/routing/graphfinder/PlaceAtDistance.java diff --git a/src/main/java/org/opentripplanner/routing/graphfinder/PlaceFinderTraverseVisitor.java b/application/src/main/java/org/opentripplanner/routing/graphfinder/PlaceFinderTraverseVisitor.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/graphfinder/PlaceFinderTraverseVisitor.java rename to application/src/main/java/org/opentripplanner/routing/graphfinder/PlaceFinderTraverseVisitor.java index 16420a0d9eb..1928d4f574b 100644 --- a/src/main/java/org/opentripplanner/routing/graphfinder/PlaceFinderTraverseVisitor.java +++ b/application/src/main/java/org/opentripplanner/routing/graphfinder/PlaceFinderTraverseVisitor.java @@ -6,7 +6,7 @@ import java.util.Set; import org.opentripplanner.astar.spi.SkipEdgeStrategy; import org.opentripplanner.astar.spi.TraverseVisitor; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex; import org.opentripplanner.street.model.edge.Edge; @@ -174,7 +174,7 @@ private boolean shouldInclude(List filterByPlaceTypes, PlaceType type private boolean stopHasPatternsWithMode(RegularStop stop, Set modes) { return transitService - .getPatternsForStop(stop) + .findPatterns(stop) .stream() .map(TripPattern::getMode) .anyMatch(modes::contains); @@ -234,7 +234,7 @@ private void handleStop(RegularStop stop, double distance) { private void handlePatternsAtStop(RegularStop stop, double distance) { if (includePatternAtStops) { List patterns = transitService - .getPatternsForStop(stop) + .findPatterns(stop) .stream() .filter(pattern -> filterByModes.isEmpty() || filterByModes.contains(pattern.getMode())) .filter(pattern -> diff --git a/src/main/java/org/opentripplanner/routing/graphfinder/PlaceType.java b/application/src/main/java/org/opentripplanner/routing/graphfinder/PlaceType.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/graphfinder/PlaceType.java rename to application/src/main/java/org/opentripplanner/routing/graphfinder/PlaceType.java diff --git a/src/main/java/org/opentripplanner/routing/graphfinder/StopFinderTraverseVisitor.java b/application/src/main/java/org/opentripplanner/routing/graphfinder/StopFinderTraverseVisitor.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/graphfinder/StopFinderTraverseVisitor.java rename to application/src/main/java/org/opentripplanner/routing/graphfinder/StopFinderTraverseVisitor.java index 5c75e8c9322..854e33831ae 100644 --- a/src/main/java/org/opentripplanner/routing/graphfinder/StopFinderTraverseVisitor.java +++ b/application/src/main/java/org/opentripplanner/routing/graphfinder/StopFinderTraverseVisitor.java @@ -4,11 +4,11 @@ import java.util.List; import org.opentripplanner.astar.spi.SkipEdgeStrategy; import org.opentripplanner.astar.spi.TraverseVisitor; -import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.vertex.TransitStopVertex; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.search.state.State; +import org.opentripplanner.utils.collection.ListUtils; /** * A TraverseVisitor used in finding stops while walking the street graph. diff --git a/src/main/java/org/opentripplanner/routing/graphfinder/StreetGraphFinder.java b/application/src/main/java/org/opentripplanner/routing/graphfinder/StreetGraphFinder.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/graphfinder/StreetGraphFinder.java rename to application/src/main/java/org/opentripplanner/routing/graphfinder/StreetGraphFinder.java index 71f65209ddf..061e692fa3f 100644 --- a/src/main/java/org/opentripplanner/routing/graphfinder/StreetGraphFinder.java +++ b/application/src/main/java/org/opentripplanner/routing/graphfinder/StreetGraphFinder.java @@ -95,7 +95,8 @@ private void findClosestUsingStreets( try ( var temporaryVertices = new TemporaryVerticesContainer( graph, - rr, + rr.from(), + rr.to(), StreetMode.WALK, StreetMode.WALK ) diff --git a/src/main/java/org/opentripplanner/routing/impl/DelegatingTransitAlertServiceImpl.java b/application/src/main/java/org/opentripplanner/routing/impl/DelegatingTransitAlertServiceImpl.java similarity index 95% rename from src/main/java/org/opentripplanner/routing/impl/DelegatingTransitAlertServiceImpl.java rename to application/src/main/java/org/opentripplanner/routing/impl/DelegatingTransitAlertServiceImpl.java index 8da6fc21aa7..e63894b1a2c 100644 --- a/src/main/java/org/opentripplanner/routing/impl/DelegatingTransitAlertServiceImpl.java +++ b/application/src/main/java/org/opentripplanner/routing/impl/DelegatingTransitAlertServiceImpl.java @@ -11,7 +11,7 @@ import org.opentripplanner.routing.services.TransitAlertService; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.timetable.Direction; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.updater.alert.TransitAlertProvider; /** @@ -30,14 +30,14 @@ public class DelegatingTransitAlertServiceImpl implements TransitAlertService { private final ArrayList transitAlertServices = new ArrayList<>(); /** - * Constructor which scans over all existing GraphUpdaters associated with a TransitModel + * Constructor which scans over all existing GraphUpdaters associated with a TimetableRepository * instance and retains references to all their TransitAlertService instances. * This implies that these instances are expected to remain in use indefinitely (not be replaced * with new instances or taken out of service over time). */ - public DelegatingTransitAlertServiceImpl(TransitModel transitModel) { - if (transitModel.getUpdaterManager() != null) { - transitModel + public DelegatingTransitAlertServiceImpl(TimetableRepository timetableRepository) { + if (timetableRepository.getUpdaterManager() != null) { + timetableRepository .getUpdaterManager() .getUpdaterList() .stream() diff --git a/src/main/java/org/opentripplanner/routing/impl/GraphPathFinder.java b/application/src/main/java/org/opentripplanner/routing/impl/GraphPathFinder.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/impl/GraphPathFinder.java rename to application/src/main/java/org/opentripplanner/routing/impl/GraphPathFinder.java diff --git a/src/main/java/org/opentripplanner/routing/impl/TransitAlertServiceImpl.java b/application/src/main/java/org/opentripplanner/routing/impl/TransitAlertServiceImpl.java similarity index 94% rename from src/main/java/org/opentripplanner/routing/impl/TransitAlertServiceImpl.java rename to application/src/main/java/org/opentripplanner/routing/impl/TransitAlertServiceImpl.java index 0cc24c691e9..04b58d050ee 100644 --- a/src/main/java/org/opentripplanner/routing/impl/TransitAlertServiceImpl.java +++ b/application/src/main/java/org/opentripplanner/routing/impl/TransitAlertServiceImpl.java @@ -13,7 +13,7 @@ import org.opentripplanner.routing.services.TransitAlertService; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.timetable.Direction; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; /** * This is the primary implementation of TransitAlertService, which actually retains its own set @@ -32,12 +32,12 @@ */ public class TransitAlertServiceImpl implements TransitAlertService { - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; private Multimap alerts = HashMultimap.create(); - public TransitAlertServiceImpl(TransitModel transitModel) { - this.transitModel = transitModel; + public TransitAlertServiceImpl(TimetableRepository timetableRepository) { + this.timetableRepository = timetableRepository; } @Override @@ -85,8 +85,8 @@ public Collection getStopAlerts( } if (result.isEmpty()) { // Search for alerts on parent-stop - if (transitModel != null) { - var quay = transitModel.getStopModel().getRegularStop(stopId); + if (timetableRepository != null) { + var quay = timetableRepository.getSiteRepository().getRegularStop(stopId); if (quay != null) { // TODO - SIRI: Add alerts from parent- and multimodal-stops /* diff --git a/src/main/java/org/opentripplanner/routing/linking/DisposableEdgeCollection.java b/application/src/main/java/org/opentripplanner/routing/linking/DisposableEdgeCollection.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/linking/DisposableEdgeCollection.java rename to application/src/main/java/org/opentripplanner/routing/linking/DisposableEdgeCollection.java diff --git a/src/main/java/org/opentripplanner/routing/linking/FlexLocationAdder.java b/application/src/main/java/org/opentripplanner/routing/linking/FlexLocationAdder.java similarity index 77% rename from src/main/java/org/opentripplanner/routing/linking/FlexLocationAdder.java rename to application/src/main/java/org/opentripplanner/routing/linking/FlexLocationAdder.java index 047e44f229a..e9d29f596c7 100644 --- a/src/main/java/org/opentripplanner/routing/linking/FlexLocationAdder.java +++ b/application/src/main/java/org/opentripplanner/routing/linking/FlexLocationAdder.java @@ -8,15 +8,19 @@ import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.vertex.IntersectionVertex; import org.opentripplanner.transit.model.site.AreaStop; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; class FlexLocationAdder { - static void addFlexLocations(StreetEdge edge, IntersectionVertex v0, StopModel stopModel) { + static void addFlexLocations( + StreetEdge edge, + IntersectionVertex v0, + SiteRepository siteRepository + ) { if (edge.getPermission().allows(StreetTraversalPermission.PEDESTRIAN_AND_CAR)) { Point p = GeometryUtils.getGeometryFactory().createPoint(v0.getCoordinate()); Envelope env = p.getEnvelopeInternal(); - for (AreaStop areaStop : stopModel.findAreaStops(env)) { + for (AreaStop areaStop : siteRepository.findAreaStops(env)) { if (!areaStop.getGeometry().disjoint(p)) { v0.addAreaStops(Set.of(areaStop)); } diff --git a/src/main/java/org/opentripplanner/routing/linking/LinkingDirection.java b/application/src/main/java/org/opentripplanner/routing/linking/LinkingDirection.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/linking/LinkingDirection.java rename to application/src/main/java/org/opentripplanner/routing/linking/LinkingDirection.java diff --git a/src/main/java/org/opentripplanner/routing/linking/SameEdgeAdjuster.java b/application/src/main/java/org/opentripplanner/routing/linking/SameEdgeAdjuster.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/linking/SameEdgeAdjuster.java rename to application/src/main/java/org/opentripplanner/routing/linking/SameEdgeAdjuster.java diff --git a/src/main/java/org/opentripplanner/routing/linking/Scope.java b/application/src/main/java/org/opentripplanner/routing/linking/Scope.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/linking/Scope.java rename to application/src/main/java/org/opentripplanner/routing/linking/Scope.java diff --git a/src/main/java/org/opentripplanner/routing/linking/VertexLinker.java b/application/src/main/java/org/opentripplanner/routing/linking/VertexLinker.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/linking/VertexLinker.java rename to application/src/main/java/org/opentripplanner/routing/linking/VertexLinker.java index 9616fbab792..48f5ff997c8 100644 --- a/src/main/java/org/opentripplanner/routing/linking/VertexLinker.java +++ b/application/src/main/java/org/opentripplanner/routing/linking/VertexLinker.java @@ -34,7 +34,7 @@ import org.opentripplanner.street.model.vertex.VertexFactory; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.TraverseModeSet; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; /** * This class links transit stops to streets by splitting the streets (unless the stop is extremely @@ -71,7 +71,7 @@ public class VertexLinker { private final Graph graph; - private final StopModel stopModel; + private final SiteRepository siteRepository; private final VertexFactory vertexFactory; // TODO Temporary code until we refactor WalkableAreaBuilder (#3152) @@ -81,11 +81,15 @@ public class VertexLinker { * Construct a new VertexLinker. NOTE: Only one VertexLinker should be active on a graph at any * given time. */ - public VertexLinker(Graph graph, StopModel stopModel, EdgeSpatialIndex edgeSpatialIndex) { + public VertexLinker( + Graph graph, + SiteRepository siteRepository, + EdgeSpatialIndex edgeSpatialIndex + ) { this.edgeSpatialIndex = edgeSpatialIndex; this.graph = graph; this.vertexFactory = new VertexFactory(graph); - this.stopModel = stopModel; + this.siteRepository = siteRepository; } public void linkVertexPermanently( @@ -397,7 +401,7 @@ else if ( } // TODO Consider moving this code if (OTPFeature.FlexRouting.isOn()) { - FlexLocationAdder.addFlexLocations(edge, start, stopModel); + FlexLocationAdder.addFlexLocations(edge, start, siteRepository); } return start; diff --git a/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java b/application/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java rename to application/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java index 01736aac80e..5f654d39deb 100644 --- a/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java +++ b/application/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java @@ -3,7 +3,6 @@ import java.time.ZoneId; import org.opentripplanner.framework.application.OTPRequestTimeoutException; import org.opentripplanner.framework.time.ZoneIdFallback; -import org.opentripplanner.framework.tostring.MultiLineToStringBuilder; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.routing.algorithm.RoutingWorker; import org.opentripplanner.routing.algorithm.via.ViaRoutingWorker; @@ -13,6 +12,7 @@ import org.opentripplanner.routing.api.response.RoutingResponse; import org.opentripplanner.routing.api.response.ViaRoutingResponse; import org.opentripplanner.standalone.api.OtpServerRequestContext; +import org.opentripplanner.utils.tostring.MultiLineToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/routing/services/TransitAlertService.java b/application/src/main/java/org/opentripplanner/routing/services/TransitAlertService.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/services/TransitAlertService.java rename to application/src/main/java/org/opentripplanner/routing/services/TransitAlertService.java diff --git a/src/main/java/org/opentripplanner/routing/services/notes/StreetNoteModel.java b/application/src/main/java/org/opentripplanner/routing/services/notes/StreetNoteModel.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/services/notes/StreetNoteModel.java rename to application/src/main/java/org/opentripplanner/routing/services/notes/StreetNoteModel.java diff --git a/src/main/java/org/opentripplanner/routing/services/notes/StreetNotesService.java b/application/src/main/java/org/opentripplanner/routing/services/notes/StreetNotesService.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/services/notes/StreetNotesService.java rename to application/src/main/java/org/opentripplanner/routing/services/notes/StreetNotesService.java diff --git a/src/main/java/org/opentripplanner/routing/stoptimes/ArrivalDeparture.java b/application/src/main/java/org/opentripplanner/routing/stoptimes/ArrivalDeparture.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/stoptimes/ArrivalDeparture.java rename to application/src/main/java/org/opentripplanner/routing/stoptimes/ArrivalDeparture.java diff --git a/src/main/java/org/opentripplanner/routing/stoptimes/StopTimesHelper.java b/application/src/main/java/org/opentripplanner/routing/stoptimes/StopTimesHelper.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/stoptimes/StopTimesHelper.java rename to application/src/main/java/org/opentripplanner/routing/stoptimes/StopTimesHelper.java index 4d4abf577db..b8fe8c9b216 100644 --- a/src/main/java/org/opentripplanner/routing/stoptimes/StopTimesHelper.java +++ b/application/src/main/java/org/opentripplanner/routing/stoptimes/StopTimesHelper.java @@ -14,7 +14,6 @@ import java.util.Comparator; import java.util.List; import java.util.Queue; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.StopTimesInPattern; import org.opentripplanner.model.Timetable; @@ -24,6 +23,7 @@ import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.time.ServiceDateUtils; public class StopTimesHelper { @@ -59,7 +59,7 @@ public static List stopTimesForStop( List result = new ArrayList<>(); // Fetch all patterns, including those from realtime sources - Collection patterns = transitService.getPatternsForStop(stop, true); + Collection patterns = transitService.findPatterns(stop, true); for (TripPattern pattern : patterns) { Queue pq = listTripTimeOnDatesForPatternAtStop( @@ -101,9 +101,9 @@ public static List stopTimesForStop( .asStartOfService(serviceDate, transitService.getTimeZone()) .toInstant(); - for (TripPattern pattern : transitService.getPatternsForStop(stop, true)) { + for (TripPattern pattern : transitService.findPatterns(stop, true)) { StopTimesInPattern stopTimes = new StopTimesInPattern(pattern); - Timetable tt = transitService.getTimetableForTripPattern(pattern, serviceDate); + Timetable tt = transitService.findTimetable(pattern, serviceDate); List stops = pattern.getStops(); for (int i = 0; i < stops.size(); i++) { StopLocation currStop = stops.get(i); @@ -225,7 +225,7 @@ private static Queue listTripTimeOnDatesForPatternAtStop( // Loop through all possible days for (LocalDate serviceDate : serviceDates) { - Timetable timetable = transitService.getTimetableForTripPattern(pattern, serviceDate); + Timetable timetable = transitService.findTimetable(pattern, serviceDate); ZonedDateTime midnight = ServiceDateUtils.asStartOfService(serviceDate, zoneId); int secondsSinceMidnight = ServiceDateUtils.secondsSinceStartOfService( midnight, @@ -291,7 +291,7 @@ private static boolean isReplacedByAnotherPattern( TripPattern pattern, TransitService transitService ) { - final TripPattern replacement = transitService.getRealtimeAddedTripPattern( + final TripPattern replacement = transitService.findNewTripPatternForModifiedTrip( trip.getId(), serviceDate ); diff --git a/src/main/java/org/opentripplanner/routing/util/ConcurrentPublished.java b/application/src/main/java/org/opentripplanner/routing/util/ConcurrentPublished.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/util/ConcurrentPublished.java rename to application/src/main/java/org/opentripplanner/routing/util/ConcurrentPublished.java diff --git a/src/main/java/org/opentripplanner/routing/util/DiffEntry.java b/application/src/main/java/org/opentripplanner/routing/util/DiffEntry.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/util/DiffEntry.java rename to application/src/main/java/org/opentripplanner/routing/util/DiffEntry.java diff --git a/src/main/java/org/opentripplanner/routing/util/DiffList.java b/application/src/main/java/org/opentripplanner/routing/util/DiffList.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/util/DiffList.java rename to application/src/main/java/org/opentripplanner/routing/util/DiffList.java diff --git a/src/main/java/org/opentripplanner/routing/util/DiffTool.java b/application/src/main/java/org/opentripplanner/routing/util/DiffTool.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/util/DiffTool.java rename to application/src/main/java/org/opentripplanner/routing/util/DiffTool.java diff --git a/src/main/java/org/opentripplanner/routing/util/ElevationUtils.java b/application/src/main/java/org/opentripplanner/routing/util/ElevationUtils.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/util/ElevationUtils.java rename to application/src/main/java/org/opentripplanner/routing/util/ElevationUtils.java diff --git a/src/main/java/org/opentripplanner/routing/util/SlopeCosts.java b/application/src/main/java/org/opentripplanner/routing/util/SlopeCosts.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/util/SlopeCosts.java rename to application/src/main/java/org/opentripplanner/routing/util/SlopeCosts.java diff --git a/src/main/java/org/opentripplanner/routing/util/elevation/ToblersHikingFunction.java b/application/src/main/java/org/opentripplanner/routing/util/elevation/ToblersHikingFunction.java similarity index 100% rename from src/main/java/org/opentripplanner/routing/util/elevation/ToblersHikingFunction.java rename to application/src/main/java/org/opentripplanner/routing/util/elevation/ToblersHikingFunction.java diff --git a/src/main/java/org/opentripplanner/service/package.md b/application/src/main/java/org/opentripplanner/service/package.md similarity index 100% rename from src/main/java/org/opentripplanner/service/package.md rename to application/src/main/java/org/opentripplanner/service/package.md diff --git a/src/main/java/org/opentripplanner/service/paging/PagingService.java b/application/src/main/java/org/opentripplanner/service/paging/PagingService.java similarity index 99% rename from src/main/java/org/opentripplanner/service/paging/PagingService.java rename to application/src/main/java/org/opentripplanner/service/paging/PagingService.java index 3aa8033105a..b9a11ab5ffa 100644 --- a/src/main/java/org/opentripplanner/service/paging/PagingService.java +++ b/application/src/main/java/org/opentripplanner/service/paging/PagingService.java @@ -5,7 +5,6 @@ import java.util.List; import java.util.Objects; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.SortOrder; import org.opentripplanner.model.plan.paging.PagingSearchWindowAdjuster; @@ -14,6 +13,7 @@ import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; import org.opentripplanner.model.plan.paging.cursor.PageType; import org.opentripplanner.routing.api.response.TripSearchMetadata; +import org.opentripplanner.utils.tostring.ToStringBuilder; public class PagingService { diff --git a/src/main/java/org/opentripplanner/service/realtimevehicles/RealtimeVehicleRepository.java b/application/src/main/java/org/opentripplanner/service/realtimevehicles/RealtimeVehicleRepository.java similarity index 100% rename from src/main/java/org/opentripplanner/service/realtimevehicles/RealtimeVehicleRepository.java rename to application/src/main/java/org/opentripplanner/service/realtimevehicles/RealtimeVehicleRepository.java diff --git a/src/main/java/org/opentripplanner/service/realtimevehicles/RealtimeVehicleService.java b/application/src/main/java/org/opentripplanner/service/realtimevehicles/RealtimeVehicleService.java similarity index 80% rename from src/main/java/org/opentripplanner/service/realtimevehicles/RealtimeVehicleService.java rename to application/src/main/java/org/opentripplanner/service/realtimevehicles/RealtimeVehicleService.java index 949b196faeb..d697853880d 100644 --- a/src/main/java/org/opentripplanner/service/realtimevehicles/RealtimeVehicleService.java +++ b/application/src/main/java/org/opentripplanner/service/realtimevehicles/RealtimeVehicleService.java @@ -1,7 +1,6 @@ package org.opentripplanner.service.realtimevehicles; import java.util.List; -import javax.annotation.Nonnull; import org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.OccupancyStatus; @@ -12,11 +11,11 @@ public interface RealtimeVehicleService { * Get the realtime vehicles for a certain trip pattern. Service contains all the vehicles that * exist in input feeds but doesn't store any historical data. */ - List getRealtimeVehicles(@Nonnull TripPattern pattern); + List getRealtimeVehicles(TripPattern pattern); /** * Get the latest occupancy status for a certain trip. Service contains all the vehicles that * exist in input feeds but doesn't store any historical data. */ - OccupancyStatus getVehicleOccupancyStatus(@Nonnull Trip trip); + OccupancyStatus getVehicleOccupancyStatus(Trip trip); } diff --git a/src/main/java/org/opentripplanner/service/realtimevehicles/configure/RealtimeVehicleRepositoryModule.java b/application/src/main/java/org/opentripplanner/service/realtimevehicles/configure/RealtimeVehicleRepositoryModule.java similarity index 100% rename from src/main/java/org/opentripplanner/service/realtimevehicles/configure/RealtimeVehicleRepositoryModule.java rename to application/src/main/java/org/opentripplanner/service/realtimevehicles/configure/RealtimeVehicleRepositoryModule.java diff --git a/src/main/java/org/opentripplanner/service/realtimevehicles/configure/RealtimeVehicleServiceModule.java b/application/src/main/java/org/opentripplanner/service/realtimevehicles/configure/RealtimeVehicleServiceModule.java similarity index 100% rename from src/main/java/org/opentripplanner/service/realtimevehicles/configure/RealtimeVehicleServiceModule.java rename to application/src/main/java/org/opentripplanner/service/realtimevehicles/configure/RealtimeVehicleServiceModule.java diff --git a/src/main/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleService.java b/application/src/main/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleService.java similarity index 91% rename from src/main/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleService.java rename to application/src/main/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleService.java index 0058cdd9e15..9bd5c96c899 100644 --- a/src/main/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleService.java +++ b/application/src/main/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleService.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javax.annotation.Nonnull; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleRepository; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleService; import org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle; @@ -58,7 +57,7 @@ public void clearRealtimeVehicles(TripPattern pattern) { * @see DefaultRealtimeVehicleService#setRealtimeVehicles(TripPattern, List) */ @Override - public List getRealtimeVehicles(@Nonnull TripPattern pattern) { + public List getRealtimeVehicles(TripPattern pattern) { if (pattern.getOriginalTripPattern() != null) { pattern = pattern.getOriginalTripPattern(); } @@ -66,10 +65,9 @@ public List getRealtimeVehicles(@Nonnull TripPattern pattern) { return vehicles.getOrDefault(pattern, List.of()); } - @Nonnull @Override - public OccupancyStatus getVehicleOccupancyStatus(@Nonnull Trip trip) { - return getOccupancyStatus(trip.getId(), transitService.getPatternForTrip(trip)); + public OccupancyStatus getVehicleOccupancyStatus(Trip trip) { + return getOccupancyStatus(trip.getId(), transitService.findPattern(trip)); } /** diff --git a/src/main/java/org/opentripplanner/service/realtimevehicles/model/RealtimeVehicle.java b/application/src/main/java/org/opentripplanner/service/realtimevehicles/model/RealtimeVehicle.java similarity index 98% rename from src/main/java/org/opentripplanner/service/realtimevehicles/model/RealtimeVehicle.java rename to application/src/main/java/org/opentripplanner/service/realtimevehicles/model/RealtimeVehicle.java index e06ae5ebaa7..fb0cbb28dbe 100644 --- a/src/main/java/org/opentripplanner/service/realtimevehicles/model/RealtimeVehicle.java +++ b/application/src/main/java/org/opentripplanner/service/realtimevehicles/model/RealtimeVehicle.java @@ -2,7 +2,6 @@ import java.time.Instant; import java.util.Optional; -import javax.annotation.Nonnull; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.StopLocation; @@ -91,7 +90,6 @@ public Optional stop() { return Optional.ofNullable(stop); } - @Nonnull public Trip trip() { return trip; } diff --git a/src/main/java/org/opentripplanner/service/realtimevehicles/model/RealtimeVehicleBuilder.java b/application/src/main/java/org/opentripplanner/service/realtimevehicles/model/RealtimeVehicleBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/service/realtimevehicles/model/RealtimeVehicleBuilder.java rename to application/src/main/java/org/opentripplanner/service/realtimevehicles/model/RealtimeVehicleBuilder.java diff --git a/application/src/main/java/org/opentripplanner/service/vehicleparking/VehicleParkingRepository.java b/application/src/main/java/org/opentripplanner/service/vehicleparking/VehicleParkingRepository.java new file mode 100644 index 00000000000..7d9e4f110ce --- /dev/null +++ b/application/src/main/java/org/opentripplanner/service/vehicleparking/VehicleParkingRepository.java @@ -0,0 +1,19 @@ +package org.opentripplanner.service.vehicleparking; + +import com.google.common.collect.ListMultimap; +import java.util.Collection; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingGroup; + +/** + * The writable data store of parking facilities. + */ +public interface VehicleParkingRepository { + void updateVehicleParking( + Collection parkingToAdd, + Collection parkingToRemove + ); + Collection listVehicleParkings(); + + ListMultimap getVehicleParkingGroups(); +} diff --git a/application/src/main/java/org/opentripplanner/service/vehicleparking/VehicleParkingService.java b/application/src/main/java/org/opentripplanner/service/vehicleparking/VehicleParkingService.java new file mode 100644 index 00000000000..4603367979e --- /dev/null +++ b/application/src/main/java/org/opentripplanner/service/vehicleparking/VehicleParkingService.java @@ -0,0 +1,25 @@ +package org.opentripplanner.service.vehicleparking; + +import com.google.common.collect.ListMultimap; +import java.util.Collection; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingGroup; + +/** + * The read-only service for getting information about parking facilities. + *

    + * For writing data see {@link VehicleParkingRepository} + */ +public interface VehicleParkingService { + Collection listBikeParks(); + + Collection listCarParks(); + + Collection listVehicleParkings(); + + ListMultimap listVehicleParkingGroups(); + + boolean hasBikeParking(); + + boolean hasCarParking(); +} diff --git a/application/src/main/java/org/opentripplanner/service/vehicleparking/configure/VehicleParkingRepositoryModule.java b/application/src/main/java/org/opentripplanner/service/vehicleparking/configure/VehicleParkingRepositoryModule.java new file mode 100644 index 00000000000..23c5b3e0e51 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/service/vehicleparking/configure/VehicleParkingRepositoryModule.java @@ -0,0 +1,12 @@ +package org.opentripplanner.service.vehicleparking.configure; + +import dagger.Binds; +import dagger.Module; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; + +@Module +public interface VehicleParkingRepositoryModule { + @Binds + VehicleParkingRepository bind(DefaultVehicleParkingRepository repo); +} diff --git a/application/src/main/java/org/opentripplanner/service/vehicleparking/configure/VehicleParkingServiceModule.java b/application/src/main/java/org/opentripplanner/service/vehicleparking/configure/VehicleParkingServiceModule.java new file mode 100644 index 00000000000..50dbe4b2bcb --- /dev/null +++ b/application/src/main/java/org/opentripplanner/service/vehicleparking/configure/VehicleParkingServiceModule.java @@ -0,0 +1,12 @@ +package org.opentripplanner.service.vehicleparking.configure; + +import dagger.Binds; +import dagger.Module; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingService; + +@Module +public interface VehicleParkingServiceModule { + @Binds + VehicleParkingService bind(DefaultVehicleParkingService service); +} diff --git a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingService.java b/application/src/main/java/org/opentripplanner/service/vehicleparking/internal/DefaultVehicleParkingRepository.java similarity index 65% rename from src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingService.java rename to application/src/main/java/org/opentripplanner/service/vehicleparking/internal/DefaultVehicleParkingRepository.java index b0c08a2309b..ef8f9db99bf 100644 --- a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingService.java +++ b/application/src/main/java/org/opentripplanner/service/vehicleparking/internal/DefaultVehicleParkingRepository.java @@ -1,23 +1,23 @@ -package org.opentripplanner.routing.vehicle_parking; +package org.opentripplanner.service.vehicleparking.internal; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.ListMultimap; import com.google.common.collect.Multimap; -import java.io.Serializable; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Collection; import java.util.HashSet; import java.util.Set; -import java.util.stream.Stream; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingGroup; -/** - * Service that holds all the {@link VehicleParking} instances and an index for fetching parking - * locations within a {@link VehicleParkingGroup}. This class is thread-safe because the collections - * held here are immutable and only updated in atomic operations that replace the existing - * collection with a new copy. - * - *

    THIS CLASS IS THREAD-SAFE

    - */ -public class VehicleParkingService implements Serializable { +@Singleton +public class DefaultVehicleParkingRepository implements VehicleParkingRepository { + + @Inject + public DefaultVehicleParkingRepository() {} /** * To ensure that his is thread-safe, the set stored here should always be immutable. @@ -38,6 +38,7 @@ public class VehicleParkingService implements Serializable { * service by replacing the existing with a new copy that includes old ones that were not removed * in the update and the new ones that were added in the update. */ + @Override public void updateVehicleParking( Collection parkingToAdd, Collection parkingToRemove @@ -65,27 +66,13 @@ public void updateVehicleParking( vehicleParkings = Set.copyOf(updatedVehicleParkings); } - public Stream getBikeParks() { - return vehicleParkings.stream().filter(VehicleParking::hasBicyclePlaces); - } - - public Stream getCarParks() { - return vehicleParkings.stream().filter(VehicleParking::hasAnyCarPlaces); - } - - public Stream getVehicleParkings() { - return vehicleParkings.stream(); + @Override + public Collection listVehicleParkings() { + return Set.copyOf(vehicleParkings); } - public ImmutableListMultimap getVehicleParkingGroups() { + @Override + public ListMultimap getVehicleParkingGroups() { return vehicleParkingGroups; } - - public boolean hasBikeParking() { - return vehicleParkings.stream().anyMatch(VehicleParking::hasBicyclePlaces); - } - - public boolean hasCarParking() { - return vehicleParkings.stream().anyMatch(VehicleParking::hasAnyCarPlaces); - } } diff --git a/application/src/main/java/org/opentripplanner/service/vehicleparking/internal/DefaultVehicleParkingService.java b/application/src/main/java/org/opentripplanner/service/vehicleparking/internal/DefaultVehicleParkingService.java new file mode 100644 index 00000000000..b874c4338b7 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/service/vehicleparking/internal/DefaultVehicleParkingService.java @@ -0,0 +1,68 @@ +package org.opentripplanner.service.vehicleparking.internal; + +import com.google.common.collect.ListMultimap; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import java.io.Serializable; +import java.util.Collection; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingGroup; + +/** + * Service that holds all the {@link VehicleParking} instances and an index for fetching parking + * locations within a {@link VehicleParkingGroup}. This class is thread-safe because the collections + * held here are immutable and only updated in atomic operations that replace the existing + * collection with a new copy. + * + *

    THIS CLASS IS THREAD-SAFE

    + */ +@Singleton +public class DefaultVehicleParkingService implements Serializable, VehicleParkingService { + + private final VehicleParkingRepository repository; + + @Inject + public DefaultVehicleParkingService(VehicleParkingRepository repository) { + this.repository = repository; + } + + @Override + public Collection listBikeParks() { + return repository + .listVehicleParkings() + .stream() + .filter(VehicleParking::hasBicyclePlaces) + .toList(); + } + + @Override + public Collection listCarParks() { + return repository + .listVehicleParkings() + .stream() + .filter(VehicleParking::hasAnyCarPlaces) + .toList(); + } + + @Override + public Collection listVehicleParkings() { + return repository.listVehicleParkings(); + } + + @Override + public ListMultimap listVehicleParkingGroups() { + return repository.getVehicleParkingGroups(); + } + + @Override + public boolean hasBikeParking() { + return repository.listVehicleParkings().stream().anyMatch(VehicleParking::hasBicyclePlaces); + } + + @Override + public boolean hasCarParking() { + return repository.listVehicleParkings().stream().anyMatch(VehicleParking::hasAnyCarPlaces); + } +} diff --git a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java b/application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParking.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java rename to application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParking.java index 098af909296..c9539f21eef 100644 --- a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java +++ b/application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParking.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.vehicle_parking; +package org.opentripplanner.service.vehicleparking.model; import java.io.Serializable; import java.util.ArrayList; @@ -9,10 +9,10 @@ import javax.annotation.Nullable; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.calendar.openinghours.OHCalendar; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Vehicle parking locations, which may allow bicycle and/or car parking. diff --git a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingEntrance.java b/application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingEntrance.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingEntrance.java rename to application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingEntrance.java index b91776b0265..d905441641b 100644 --- a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingEntrance.java +++ b/application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingEntrance.java @@ -1,13 +1,13 @@ -package org.opentripplanner.routing.vehicle_parking; +package org.opentripplanner.service.vehicleparking.model; import java.io.Serializable; import java.util.Objects; import javax.annotation.Nullable; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.tostring.ToStringBuilder; public class VehicleParkingEntrance implements Serializable { diff --git a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingGroup.java b/application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingGroup.java similarity index 94% rename from src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingGroup.java rename to application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingGroup.java index 535f201a0de..07548efa11a 100644 --- a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingGroup.java +++ b/application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingGroup.java @@ -1,11 +1,11 @@ -package org.opentripplanner.routing.vehicle_parking; +package org.opentripplanner.service.vehicleparking.model; import java.util.Objects; import javax.annotation.Nullable; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Group of vehicle parking locations. diff --git a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingGroupBuilder.java b/application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingGroupBuilder.java similarity index 93% rename from src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingGroupBuilder.java rename to application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingGroupBuilder.java index 42603e33159..7f109f38002 100644 --- a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingGroupBuilder.java +++ b/application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingGroupBuilder.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.vehicle_parking; +package org.opentripplanner.service.vehicleparking.model; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; diff --git a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingHelper.java b/application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingHelper.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingHelper.java rename to application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingHelper.java index 257f2805ca2..5832a8d5f91 100644 --- a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingHelper.java +++ b/application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingHelper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.vehicle_parking; +package org.opentripplanner.service.vehicleparking.model; import java.util.List; import java.util.Objects; diff --git a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingSpaces.java b/application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingSpaces.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingSpaces.java rename to application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingSpaces.java index 8b21cc21f2c..6827e6af198 100644 --- a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingSpaces.java +++ b/application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingSpaces.java @@ -1,8 +1,8 @@ -package org.opentripplanner.routing.vehicle_parking; +package org.opentripplanner.service.vehicleparking.model; import java.io.Serializable; import java.util.Objects; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * The number of spaces by type. {@code null} if unknown. diff --git a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingState.java b/application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingState.java similarity index 80% rename from src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingState.java rename to application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingState.java index ff9178a9b34..e3af795459c 100644 --- a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingState.java +++ b/application/src/main/java/org/opentripplanner/service/vehicleparking/model/VehicleParkingState.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.vehicle_parking; +package org.opentripplanner.service.vehicleparking.model; /** * The state of the vehicle parking. TEMPORARILY_CLOSED and CLOSED are distinct states so that they diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/VehicleRentalRepository.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/VehicleRentalRepository.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/VehicleRentalRepository.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/VehicleRentalRepository.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/VehicleRentalService.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/VehicleRentalService.java similarity index 86% rename from src/main/java/org/opentripplanner/service/vehiclerental/VehicleRentalService.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/VehicleRentalService.java index 93fe12a1c7c..fa65dd86987 100644 --- a/src/main/java/org/opentripplanner/service/vehiclerental/VehicleRentalService.java +++ b/application/src/main/java/org/opentripplanner/service/vehiclerental/VehicleRentalService.java @@ -38,4 +38,14 @@ List getVehicleRentalStationForEnvelope( double maxLon, double maxLat ); + + /** + * Gets all vehicle rental places inside an envelope. + */ + List getVehicleRentalPlacesForEnvelope( + double minLon, + double minLat, + double maxLon, + double maxLat + ); } diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/configure/VehicleRentalRepositoryModule.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/configure/VehicleRentalRepositoryModule.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/configure/VehicleRentalRepositoryModule.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/configure/VehicleRentalRepositoryModule.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/configure/VehicleRentalServiceModule.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/configure/VehicleRentalServiceModule.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/configure/VehicleRentalServiceModule.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/configure/VehicleRentalServiceModule.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/internal/DefaultVehicleRentalService.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/internal/DefaultVehicleRentalService.java similarity index 88% rename from src/main/java/org/opentripplanner/service/vehiclerental/internal/DefaultVehicleRentalService.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/internal/DefaultVehicleRentalService.java index 996f4cbcc9d..1f66d654cdb 100644 --- a/src/main/java/org/opentripplanner/service/vehiclerental/internal/DefaultVehicleRentalService.java +++ b/application/src/main/java/org/opentripplanner/service/vehiclerental/internal/DefaultVehicleRentalService.java @@ -119,4 +119,23 @@ private Stream getVehicleRentalStationsAsStream() { .filter(VehicleRentalStation.class::isInstance) .map(VehicleRentalStation.class::cast); } + + @Override + public List getVehicleRentalPlacesForEnvelope( + double minLon, + double minLat, + double maxLon, + double maxLat + ) { + Envelope envelope = new Envelope( + new Coordinate(minLon, minLat), + new Coordinate(maxLon, maxLat) + ); + + Stream vehicleRentalPlaceStream = getVehicleRentalPlaces() + .stream() + .filter(vr -> envelope.contains(new Coordinate(vr.getLongitude(), vr.getLatitude()))); + + return vehicleRentalPlaceStream.toList(); + } } diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/model/GeofencingZone.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/model/GeofencingZone.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/model/GeofencingZone.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/model/GeofencingZone.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleEntityCounts.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleEntityCounts.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleEntityCounts.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleEntityCounts.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleType.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleType.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleType.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleType.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleTypeCount.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleTypeCount.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleTypeCount.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/model/RentalVehicleTypeCount.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalPlace.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalPlace.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalPlace.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalPlace.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalStation.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalStation.java similarity index 98% rename from src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalStation.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalStation.java index d6e72023a31..ff17ee00593 100644 --- a/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalStation.java +++ b/application/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalStation.java @@ -9,10 +9,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.framework.collection.SetUtils; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.street.model.RentalFormFactor; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.collection.SetUtils; /** * Implements the {@link VehicleRentalPlace} class which contains Javadoc. diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalStationUris.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalStationUris.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalStationUris.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalStationUris.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalSystem.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalSystem.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalSystem.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalSystem.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalSystemAppInformation.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalSystemAppInformation.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalSystemAppInformation.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalSystemAppInformation.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalVehicle.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalVehicle.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalVehicle.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalVehicle.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/street/BusinessAreaBorder.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/street/BusinessAreaBorder.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/street/BusinessAreaBorder.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/street/BusinessAreaBorder.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/street/CompositeRentalRestrictionExtension.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/street/CompositeRentalRestrictionExtension.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/street/CompositeRentalRestrictionExtension.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/street/CompositeRentalRestrictionExtension.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/street/GeofencingZoneExtension.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/street/GeofencingZoneExtension.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/street/GeofencingZoneExtension.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/street/GeofencingZoneExtension.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/street/NoRestriction.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/street/NoRestriction.java similarity index 100% rename from src/main/java/org/opentripplanner/service/vehiclerental/street/NoRestriction.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/street/NoRestriction.java diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java similarity index 93% rename from src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java index 385b347d24a..99775b6112d 100644 --- a/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java +++ b/application/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java @@ -1,6 +1,5 @@ package org.opentripplanner.service.vehiclerental.street; -import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.vertex.StreetVertex; @@ -38,12 +37,7 @@ public static StreetVehicleRentalLink createStreetVehicleRentalLink( return connectToGraph(new StreetVehicleRentalLink(fromv, tov)); } - public String toString() { - return "StreetVehicleRentalLink(" + fromv + " -> " + tov + ")"; - } - @Override - @Nonnull public State[] traverse(State s0) { // Disallow traversing two StreetBikeRentalLinks in a row. // This prevents the router from using bike rental stations as shortcuts to get around diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java similarity index 99% rename from src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java index dc9fed8b9a3..0935909e0c7 100644 --- a/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java +++ b/application/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java @@ -2,7 +2,6 @@ import java.util.Collections; import java.util.Set; -import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; @@ -33,7 +32,6 @@ public static VehicleRentalEdge createVehicleRentalEdge( } @Override - @Nonnull public State[] traverse(State s0) { if (!s0.getRequest().mode().includesRenting()) { return State.empty(); diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalPlaceVertex.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalPlaceVertex.java similarity index 96% rename from src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalPlaceVertex.java rename to application/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalPlaceVertex.java index 5a04d56d60c..903747b0206 100644 --- a/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalPlaceVertex.java +++ b/application/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalPlaceVertex.java @@ -1,6 +1,5 @@ package org.opentripplanner.service.vehiclerental.street; -import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.street.model.vertex.Vertex; @@ -20,7 +19,6 @@ public VehicleRentalPlaceVertex(VehicleRentalPlace station) { this.station = station; } - @Nonnull @Override public I18NString getName() { return station.getName(); diff --git a/src/main/java/org/opentripplanner/service/worldenvelope/WorldEnvelopeRepository.java b/application/src/main/java/org/opentripplanner/service/worldenvelope/WorldEnvelopeRepository.java similarity index 93% rename from src/main/java/org/opentripplanner/service/worldenvelope/WorldEnvelopeRepository.java rename to application/src/main/java/org/opentripplanner/service/worldenvelope/WorldEnvelopeRepository.java index 5aba781f79c..bdf9df4f8d3 100644 --- a/src/main/java/org/opentripplanner/service/worldenvelope/WorldEnvelopeRepository.java +++ b/application/src/main/java/org/opentripplanner/service/worldenvelope/WorldEnvelopeRepository.java @@ -2,7 +2,6 @@ import java.io.Serializable; import java.util.Optional; -import javax.annotation.Nonnull; import org.opentripplanner.service.worldenvelope.model.WorldEnvelope; /** @@ -27,5 +26,5 @@ public interface WorldEnvelopeRepository extends Serializable { Optional retrieveEnvelope(); - void saveEnvelope(@Nonnull WorldEnvelope envelope); + void saveEnvelope(WorldEnvelope envelope); } diff --git a/src/main/java/org/opentripplanner/service/worldenvelope/WorldEnvelopeService.java b/application/src/main/java/org/opentripplanner/service/worldenvelope/WorldEnvelopeService.java similarity index 100% rename from src/main/java/org/opentripplanner/service/worldenvelope/WorldEnvelopeService.java rename to application/src/main/java/org/opentripplanner/service/worldenvelope/WorldEnvelopeService.java diff --git a/src/main/java/org/opentripplanner/service/worldenvelope/configure/WorldEnvelopeRepositoryModule.java b/application/src/main/java/org/opentripplanner/service/worldenvelope/configure/WorldEnvelopeRepositoryModule.java similarity index 100% rename from src/main/java/org/opentripplanner/service/worldenvelope/configure/WorldEnvelopeRepositoryModule.java rename to application/src/main/java/org/opentripplanner/service/worldenvelope/configure/WorldEnvelopeRepositoryModule.java diff --git a/src/main/java/org/opentripplanner/service/worldenvelope/configure/WorldEnvelopeServiceModule.java b/application/src/main/java/org/opentripplanner/service/worldenvelope/configure/WorldEnvelopeServiceModule.java similarity index 100% rename from src/main/java/org/opentripplanner/service/worldenvelope/configure/WorldEnvelopeServiceModule.java rename to application/src/main/java/org/opentripplanner/service/worldenvelope/configure/WorldEnvelopeServiceModule.java diff --git a/src/main/java/org/opentripplanner/service/worldenvelope/internal/DefaultWorldEnvelopeRepository.java b/application/src/main/java/org/opentripplanner/service/worldenvelope/internal/DefaultWorldEnvelopeRepository.java similarity index 90% rename from src/main/java/org/opentripplanner/service/worldenvelope/internal/DefaultWorldEnvelopeRepository.java rename to application/src/main/java/org/opentripplanner/service/worldenvelope/internal/DefaultWorldEnvelopeRepository.java index 1fea3c4aeda..226122c803b 100644 --- a/src/main/java/org/opentripplanner/service/worldenvelope/internal/DefaultWorldEnvelopeRepository.java +++ b/application/src/main/java/org/opentripplanner/service/worldenvelope/internal/DefaultWorldEnvelopeRepository.java @@ -4,7 +4,6 @@ import jakarta.inject.Singleton; import java.io.Serializable; import java.util.Optional; -import javax.annotation.Nonnull; import org.opentripplanner.service.worldenvelope.WorldEnvelopeRepository; import org.opentripplanner.service.worldenvelope.model.WorldEnvelope; @@ -26,7 +25,7 @@ public Optional retrieveEnvelope() { } @Override - public void saveEnvelope(@Nonnull WorldEnvelope envelope) { + public void saveEnvelope(WorldEnvelope envelope) { this.envelope = envelope; } } diff --git a/src/main/java/org/opentripplanner/service/worldenvelope/internal/DefaultWorldEnvelopeService.java b/application/src/main/java/org/opentripplanner/service/worldenvelope/internal/DefaultWorldEnvelopeService.java similarity index 100% rename from src/main/java/org/opentripplanner/service/worldenvelope/internal/DefaultWorldEnvelopeService.java rename to application/src/main/java/org/opentripplanner/service/worldenvelope/internal/DefaultWorldEnvelopeService.java diff --git a/src/main/java/org/opentripplanner/service/worldenvelope/model/MedianCalcForDoubles.java b/application/src/main/java/org/opentripplanner/service/worldenvelope/model/MedianCalcForDoubles.java similarity index 100% rename from src/main/java/org/opentripplanner/service/worldenvelope/model/MedianCalcForDoubles.java rename to application/src/main/java/org/opentripplanner/service/worldenvelope/model/MedianCalcForDoubles.java diff --git a/src/main/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelope.java b/application/src/main/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelope.java similarity index 97% rename from src/main/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelope.java rename to application/src/main/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelope.java index 27a1fb4d30f..55024b63982 100644 --- a/src/main/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelope.java +++ b/application/src/main/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelope.java @@ -3,7 +3,7 @@ import java.io.Serializable; import java.util.Optional; import org.opentripplanner.framework.geometry.WgsCoordinate; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This class calculates borders of envelopes that can be also on 180th meridian. diff --git a/src/main/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelopeBuilder.java b/application/src/main/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelopeBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelopeBuilder.java rename to application/src/main/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelopeBuilder.java diff --git a/src/main/java/org/opentripplanner/standalone/OTPMain.java b/application/src/main/java/org/opentripplanner/standalone/OTPMain.java similarity index 94% rename from src/main/java/org/opentripplanner/standalone/OTPMain.java rename to application/src/main/java/org/opentripplanner/standalone/OTPMain.java index d865f8fa28c..ade5067a981 100644 --- a/src/main/java/org/opentripplanner/standalone/OTPMain.java +++ b/application/src/main/java/org/opentripplanner/standalone/OTPMain.java @@ -17,7 +17,7 @@ import org.opentripplanner.standalone.configure.ConstructApplication; import org.opentripplanner.standalone.configure.LoadApplication; import org.opentripplanner.standalone.server.GrizzlyServer; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.updater.configure.UpdaterConfigurator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,7 +52,7 @@ public static void main(String[] args) { try { Thread.currentThread().setName("main"); CommandLineParameters params = parseAndValidateCmdLine(args); - OtpStartupInfo.logInfo(); + OtpStartupInfo.logInfo(params.logTaskInfo()); startOTPServer(params); } catch (OtpAppException ae) { LOG.error(ae.getMessage(), ae); @@ -150,8 +150,9 @@ private static void startOTPServer(CommandLineParameters cli) { // with using the embedded router config. new SerializedGraphObject( app.graph(), - app.transitModel(), + app.timetableRepository(), app.worldEnvelopeRepository(), + app.vehicleParkingRepository(), config.buildConfig(), config.routerConfig(), DataImportIssueSummary.combine(graphBuilder.issueSummary(), app.dataImportIssueSummary()), @@ -187,8 +188,8 @@ private static void detectUnusedConfigParams(CommandLineParameters cli, ConfigMo private static void startOtpWebServer(CommandLineParameters params, ConstructApplication app) { // Index graph for travel search - app.transitModel().index(); - app.graph().index(app.transitModel().getStopModel()); + app.timetableRepository().index(); + app.graph().index(app.timetableRepository().getSiteRepository()); // publishing the config version info make it available to the APIs setOtpConfigVersionsOnServerInfo(app); @@ -205,7 +206,7 @@ private static void startOtpWebServer(CommandLineParameters params, ConstructApp if (params.doServe()) { GrizzlyServer grizzlyServer = app.createGrizzlyServer(); - registerShutdownHookToGracefullyShutDownServer(app.transitModel(), app.raptorConfig()); + registerShutdownHookToGracefullyShutDownServer(app.timetableRepository(), app.raptorConfig()); // Loop to restart server on uncaught fatal exceptions. while (true) { @@ -232,14 +233,14 @@ private static void startOtpWebServer(CommandLineParameters params, ConstructApp * */ private static void registerShutdownHookToGracefullyShutDownServer( - TransitModel transitModel, + TimetableRepository timetableRepository, RaptorConfig raptorConfig ) { ApplicationShutdownSupport.addShutdownHook( "server-shutdown", () -> { LOG.info("OTP shutdown started..."); - UpdaterConfigurator.shutdownGraph(transitModel); + UpdaterConfigurator.shutdownGraph(timetableRepository); raptorConfig.shutdown(); WeakCollectionCleaner.DEFAULT.exit(); DeferredAuthorityFactory.exit(); diff --git a/src/main/java/org/opentripplanner/standalone/OtpStartupInfo.java b/application/src/main/java/org/opentripplanner/standalone/OtpStartupInfo.java similarity index 88% rename from src/main/java/org/opentripplanner/standalone/OtpStartupInfo.java rename to application/src/main/java/org/opentripplanner/standalone/OtpStartupInfo.java index c601846d889..ddcc2c60212 100644 --- a/src/main/java/org/opentripplanner/standalone/OtpStartupInfo.java +++ b/application/src/main/java/org/opentripplanner/standalone/OtpStartupInfo.java @@ -34,13 +34,18 @@ private static String info() { ); } - public static void logInfo() { + public static void logInfo(String cliTaskInfo) { // This is good when aggregating logs across multiple load balanced instances of OTP // Hint: a regexp filter like "^OTP (START|SHUTTING)" will list nodes going up/down - LOG.info("OTP STARTING UP ({}) using Java {}", projectInfo().getVersionString(), javaVersion()); + LOG.info( + "OTP STARTING UP - {} - {} - Java {}", + cliTaskInfo, + projectInfo().getVersionString(), + javaVersion() + ); ApplicationShutdownSupport.addShutdownHook( "server-shutdown-info", - () -> LOG.info("OTP SHUTTING DOWN ({})", projectInfo().getVersionString()) + () -> LOG.info("OTP SHUTTING DOWN - {} - {}", cliTaskInfo, projectInfo().getVersionString()) ); LOG.info(NEW_LINE + "{}", info()); } diff --git a/src/main/java/org/opentripplanner/standalone/api/HttpRequestScoped.java b/application/src/main/java/org/opentripplanner/standalone/api/HttpRequestScoped.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/api/HttpRequestScoped.java rename to application/src/main/java/org/opentripplanner/standalone/api/HttpRequestScoped.java diff --git a/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java b/application/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java similarity index 93% rename from src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java rename to application/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java index 3a577611617..f088a3de60e 100644 --- a/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java +++ b/application/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java @@ -10,6 +10,7 @@ import org.opentripplanner.ext.flex.FlexParameters; import org.opentripplanner.ext.geocoder.LuceneIndex; import org.opentripplanner.ext.ridehailing.RideHailingService; +import org.opentripplanner.ext.sorlandsbanen.SorlandsbanenNorwayService; import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.inspector.raster.TileRendererManager; @@ -22,8 +23,10 @@ import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.graphfinder.GraphFinder; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleService; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; import org.opentripplanner.service.vehiclerental.VehicleRentalService; import org.opentripplanner.service.worldenvelope.WorldEnvelopeService; +import org.opentripplanner.standalone.config.DebugUiConfig; import org.opentripplanner.standalone.config.routerconfig.VectorTileConfig; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.search.state.State; @@ -95,22 +98,18 @@ public interface OtpServerRequestContext { VehicleRentalService vehicleRentalService(); + VehicleParkingService vehicleParkingService(); + TransitTuningParameters transitTuningParameters(); RaptorTuningParameters raptorTuningParameters(); List rideHailingServices(); - @Nullable - StopConsolidationService stopConsolidationService(); - StreetLimitationParametersService streetLimitationParametersService(); MeterRegistry meterRegistry(); - @Nullable - EmissionsService emissionsService(); - /** Inspector/debug services */ TileRendererManager tileRendererManager(); @@ -129,6 +128,11 @@ default GraphFinder graphFinder() { VectorTileConfig vectorTileConfig(); + DebugUiConfig debugUiConfig(); + + /* Sandbox modules */ + + @Nullable default DataOverlayContext dataOverlayContext(RouteRequest request) { return OTPFeature.DataOverlay.isOnElseNull(() -> new DataOverlayContext( @@ -138,6 +142,15 @@ default DataOverlayContext dataOverlayContext(RouteRequest request) { ); } + @Nullable + EmissionsService emissionsService(); + @Nullable LuceneIndex lucenceIndex(); + + @Nullable + StopConsolidationService stopConsolidationService(); + + @Nullable + SorlandsbanenNorwayService sorlandsbanenService(); } diff --git a/src/main/java/org/opentripplanner/standalone/config/BuildConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/BuildConfig.java similarity index 95% rename from src/main/java/org/opentripplanner/standalone/config/BuildConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/BuildConfig.java index a3c6f313799..16c6f1e722c 100644 --- a/src/main/java/org/opentripplanner/standalone/config/BuildConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/BuildConfig.java @@ -6,6 +6,7 @@ import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_1; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_2; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_5; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_7; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.MissingNode; @@ -16,14 +17,12 @@ import java.util.List; import java.util.Set; import java.util.regex.Pattern; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.datastore.api.OtpDataStoreConfig; import org.opentripplanner.ext.dataoverlay.configuration.DataOverlayConfig; import org.opentripplanner.ext.emissions.EmissionsConfig; import org.opentripplanner.ext.fares.FaresConfiguration; import org.opentripplanner.framework.geometry.CompactElevationProfile; -import org.opentripplanner.framework.lang.ObjectUtils; import org.opentripplanner.graph_builder.module.ned.parameter.DemExtractParameters; import org.opentripplanner.graph_builder.module.ned.parameter.DemExtractParametersList; import org.opentripplanner.graph_builder.module.osm.parameters.OsmExtractParameters; @@ -45,6 +44,8 @@ import org.opentripplanner.standalone.config.buildconfig.TransitFeeds; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; import org.opentripplanner.standalone.config.sandbox.DataOverlayConfigMapper; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.lang.ObjectUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -173,16 +174,12 @@ public class BuildConfig implements OtpDataStoreConfig { public final double maxElevationPropagationMeters; public final boolean readCachedElevations; public final boolean writeCachedElevations; - public final boolean includeEllipsoidToGeoidDifference; - public final boolean multiThreadElevationCalculations; - public final LocalDate transitServiceStart; - public final LocalDate transitServiceEnd; public final ZoneId transitModelTimeZone; - + private final List transitRouteToStationCentroid; public final URI stopConsolidation; /** @@ -438,6 +435,28 @@ to check in to a flight (2-3 hours for international flights) than to alight and .asDateOrRelativePeriod("P3Y", confZone); } + transitRouteToStationCentroid = + root + .of("transitRouteToStationCentroid") + .since(V2_7) + .summary("List stations that should route to centroid.") + .description( + """ +This field contains a list of station ids for which street legs will start/end at the station +centroid instead of the child stops. + +When searching from/to a station the default behaviour is to route from/to any of the stations child +stops. This can cause strange results for stations that have stops spread over a large area. + +For some stations you might instead wish to use the centroid of the station as the +origin/destination. In this case the centroid will be used both for direct street search and for +access/egress street search where the station is used as the start/end of the access/egress. But +transit that starts/ends at the station will work as usual without any additional street leg from/to +the centroid. +""" + ) + .asFeedScopedIds(List.of()); + writeCachedElevations = root .of("writeCachedElevations") @@ -655,13 +674,11 @@ public List demFiles() { return dem.demFiles(); } - @Nonnull @Override public List gtfsFiles() { return transitFeeds.gtfsFiles(); } - @Nonnull @Override public List netexFiles() { return transitFeeds.netexFiles(); @@ -718,6 +735,10 @@ public ServiceDateInterval getTransitServicePeriod() { return new ServiceDateInterval(transitServiceStart, transitServiceEnd); } + public List transitRouteToStationCentroid() { + return transitRouteToStationCentroid; + } + public int getSubwayAccessTimeSeconds() { // Convert access time in minutes to seconds return (int) (subwayAccessTime * 60.0); diff --git a/src/main/java/org/opentripplanner/standalone/config/CommandLineParameters.java b/application/src/main/java/org/opentripplanner/standalone/config/CommandLineParameters.java similarity index 95% rename from src/main/java/org/opentripplanner/standalone/config/CommandLineParameters.java rename to application/src/main/java/org/opentripplanner/standalone/config/CommandLineParameters.java index 3513ec252ea..2324ce325d9 100644 --- a/src/main/java/org/opentripplanner/standalone/config/CommandLineParameters.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/CommandLineParameters.java @@ -201,6 +201,21 @@ public boolean doServe() { return load || (serve && doBuildTransit()); } + public String logTaskInfo() { + var mainCommands = new ArrayList(); + if (doBuildStreet() & doBuildTransit()) { + mainCommands.add("Build Street & Transit Graph"); + } else if (doBuildStreet()) { + mainCommands.add("Build Street Graph"); + } else if (doBuildTransit()) { + mainCommands.add("Build Transit Graph"); + } + if (doServe()) { + mainCommands.add("Run Server"); + } + return String.join(", ", mainCommands); + } + /** * @param port a port that we plan to bind to * @throws ParameterException if that port is not available diff --git a/src/main/java/org/opentripplanner/standalone/config/ConfigModel.java b/application/src/main/java/org/opentripplanner/standalone/config/ConfigModel.java similarity index 88% rename from src/main/java/org/opentripplanner/standalone/config/ConfigModel.java rename to application/src/main/java/org/opentripplanner/standalone/config/ConfigModel.java index c82dd33ddbf..390333f1374 100644 --- a/src/main/java/org/opentripplanner/standalone/config/ConfigModel.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/ConfigModel.java @@ -49,16 +49,29 @@ public class ConfigModel { */ private RouterConfig routerConfig; - public ConfigModel(OtpConfig otpConfig, BuildConfig buildConfig, RouterConfig routerConfig) { + private final DebugUiConfig debugUiConfig; + + public ConfigModel( + OtpConfig otpConfig, + BuildConfig buildConfig, + RouterConfig routerConfig, + DebugUiConfig debugUiConfig + ) { this.otpConfig = otpConfig; this.buildConfig = buildConfig; this.routerConfig = routerConfig; + this.debugUiConfig = debugUiConfig; initializeOtpFeatures(otpConfig); } public ConfigModel(OtpConfigLoader loader) { - this(loader.loadOtpConfig(), loader.loadBuildConfig(), loader.loadRouterConfig()); + this( + loader.loadOtpConfig(), + loader.loadBuildConfig(), + loader.loadRouterConfig(), + loader.loadDebugUiConfig() + ); } public void updateConfigFromSerializedGraph(BuildConfig buildConfig, RouterConfig routerConfig) { @@ -102,6 +115,10 @@ public RouterConfig routerConfig() { return routerConfig; } + public DebugUiConfig debugUiConfig() { + return debugUiConfig; + } + public static void initializeOtpFeatures(OtpConfig otpConfig) { OTPFeature.enableFeatures(otpConfig.otpFeatures); OTPFeature.logFeatureSetup(); @@ -117,7 +134,8 @@ public void abortOnUnknownParameters() { ( otpConfig.hasUnknownParameters() || buildConfig.hasUnknownParameters() || - routerConfig.hasUnknownParameters() + routerConfig.hasUnknownParameters() || + debugUiConfig.hasUnknownParameters() ) ) { throw new OtpAppException( diff --git a/application/src/main/java/org/opentripplanner/standalone/config/DebugUiConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/DebugUiConfig.java new file mode 100644 index 00000000000..cca6d2359be --- /dev/null +++ b/application/src/main/java/org/opentripplanner/standalone/config/DebugUiConfig.java @@ -0,0 +1,106 @@ +package org.opentripplanner.standalone.config; + +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_7; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.MissingNode; +import java.util.List; +import org.opentripplanner.standalone.config.debuguiconfig.BackgroundTileLayer; +import org.opentripplanner.standalone.config.framework.json.NodeAdapter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is an object representation of the 'debug-ui-config.json'. + */ +public class DebugUiConfig { + + private static final Logger LOG = LoggerFactory.getLogger(DebugUiConfig.class); + + public static final DebugUiConfig DEFAULT = new DebugUiConfig( + MissingNode.getInstance(), + "DEFAULT", + false + ); + + /** + * The node adaptor kept for reference and (de)serialization. + */ + private final NodeAdapter root; + private final List additionalBackgroundLayers; + + public DebugUiConfig(JsonNode node, String source, boolean logUnusedParams) { + this(new NodeAdapter(node, source), logUnusedParams); + } + + /** protected to give unit-test access */ + DebugUiConfig(NodeAdapter root, boolean logUnusedParams) { + this.root = root; + + this.additionalBackgroundLayers = + root + .of("additionalBackgroundLayers") + .since(V2_7) + .summary("Additional background raster map layers.") + .description( + """ + Add additional background layers that will appear in the Debug UI as one of the choices. + + Currently only raster tile layers are supported. + """ + ) + .asObjects( + List.of(), + node -> + new BackgroundTileLayer( + node + .of("name") + .since(V2_7) + .summary("Name to appear in the layer selector.") + .asString(), + node + .of("templateUrl") + .since(V2_7) + .summary( + """ + The [Maplibre-compatible template URL](https://maplibre.org/maplibre-native/ios/api/tile-url-templates.html) + for the raster layer, for example `https://examples.com/tiles/{z}/{x}/{y}.png`. + """ + ) + .asString(), + node.of("tileSize").since(V2_7).summary("Size of the tile in pixels.").asInt(256), + node + .of("attribution") + .since(V2_7) + .summary("Attribution for the map data.") + .asString("© OpenTripPlanner") + ) + ); + + if (logUnusedParams) { + root.logAllWarnings(LOG::warn); + } + } + + public NodeAdapter asNodeAdapter() { + return root; + } + + public List additionalBackgroundLayers() { + return additionalBackgroundLayers; + } + + /** + * If {@code true} the config is loaded from file, in not the DEFAULT config is used. + */ + public boolean isDefault() { + return root.isEmpty(); + } + + /** + * Checks if any unknown or invalid parameters were encountered while loading the configuration. + */ + public boolean hasUnknownParameters() { + return root.hasUnknownParameters(); + } +} diff --git a/src/main/java/org/opentripplanner/standalone/config/OtpConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/OtpConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/OtpConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/OtpConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/OtpConfigLoader.java b/application/src/main/java/org/opentripplanner/standalone/config/OtpConfigLoader.java similarity index 91% rename from src/main/java/org/opentripplanner/standalone/config/OtpConfigLoader.java rename to application/src/main/java/org/opentripplanner/standalone/config/OtpConfigLoader.java index d5c452b3da7..9e24e56ca12 100644 --- a/src/main/java/org/opentripplanner/standalone/config/OtpConfigLoader.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/OtpConfigLoader.java @@ -1,6 +1,7 @@ package org.opentripplanner.standalone.config; import static org.opentripplanner.framework.application.OtpFileNames.BUILD_CONFIG_FILENAME; +import static org.opentripplanner.framework.application.OtpFileNames.DEBUG_UI_CONFIG_FILENAME; import static org.opentripplanner.framework.application.OtpFileNames.OTP_CONFIG_FILENAME; import static org.opentripplanner.framework.application.OtpFileNames.ROUTER_CONFIG_FILENAME; @@ -105,6 +106,14 @@ public RouterConfig loadRouterConfig() { return new RouterConfig(node, ROUTER_CONFIG_FILENAME, true); } + public DebugUiConfig loadDebugUiConfig() { + JsonNode node = loadFromFile(DEBUG_UI_CONFIG_FILENAME); + if (node.isMissingNode()) { + return DebugUiConfig.DEFAULT; + } + return new DebugUiConfig(node, DEBUG_UI_CONFIG_FILENAME, true); + } + private static void logConfigVersion(String configVersion, String filename) { if (configVersion != null) { LOG.info("{} config-version is {}.", filename, configVersion); diff --git a/src/main/java/org/opentripplanner/standalone/config/RouterConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/RouterConfig.java similarity index 98% rename from src/main/java/org/opentripplanner/standalone/config/RouterConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/RouterConfig.java index 55128af5659..cb00428284b 100644 --- a/src/main/java/org/opentripplanner/standalone/config/RouterConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/RouterConfig.java @@ -69,7 +69,7 @@ public RouterConfig(JsonNode node, String source, boolean logUnusedParams) { this.transmodelApi = new TransmodelAPIConfig("transmodelApi", root); this.routingRequestDefaults = mapDefaultRouteRequest("routingDefaults", root); this.transitConfig = new TransitRoutingConfig("transit", root, routingRequestDefaults); - this.routingRequestDefaults.setMaxSearchWindow(transitConfig.maxSearchWindow()); + this.routingRequestDefaults.initMaxSearchWindow(transitConfig.maxSearchWindow()); this.updatersParameters = new UpdatersConfig(root); this.rideHailingConfig = new RideHailingServicesConfig(root); this.vectorTileConfig = VectorTileConfig.mapVectorTilesParameters(root, "vectorTiles"); diff --git a/src/main/java/org/opentripplanner/standalone/config/api/TransitServicePeriod.java b/application/src/main/java/org/opentripplanner/standalone/config/api/TransitServicePeriod.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/api/TransitServicePeriod.java rename to application/src/main/java/org/opentripplanner/standalone/config/api/TransitServicePeriod.java diff --git a/src/main/java/org/opentripplanner/standalone/config/buildconfig/DemConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/DemConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/buildconfig/DemConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/buildconfig/DemConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/buildconfig/GtfsConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/GtfsConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/buildconfig/GtfsConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/buildconfig/GtfsConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/buildconfig/IslandPruningConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/IslandPruningConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/buildconfig/IslandPruningConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/buildconfig/IslandPruningConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/buildconfig/NetexConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/NetexConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/buildconfig/NetexConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/buildconfig/NetexConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/buildconfig/OsmConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/OsmConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/buildconfig/OsmConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/buildconfig/OsmConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/buildconfig/S3BucketConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/S3BucketConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/buildconfig/S3BucketConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/buildconfig/S3BucketConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/buildconfig/TransferRequestConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/TransferRequestConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/buildconfig/TransferRequestConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/buildconfig/TransferRequestConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/buildconfig/TransitFeedConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/TransitFeedConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/buildconfig/TransitFeedConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/buildconfig/TransitFeedConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/buildconfig/TransitFeeds.java b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/TransitFeeds.java similarity index 84% rename from src/main/java/org/opentripplanner/standalone/config/buildconfig/TransitFeeds.java rename to application/src/main/java/org/opentripplanner/standalone/config/buildconfig/TransitFeeds.java index 91485f09e05..c4a57213afa 100644 --- a/src/main/java/org/opentripplanner/standalone/config/buildconfig/TransitFeeds.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/TransitFeeds.java @@ -2,14 +2,13 @@ import java.net.URI; import java.util.List; -import javax.annotation.Nonnull; import org.opentripplanner.graph_builder.model.DataSourceConfig; import org.opentripplanner.gtfs.graphbuilder.GtfsFeedParameters; import org.opentripplanner.netex.config.NetexFeedParameters; public record TransitFeeds( - @Nonnull List gtfsFeeds, - @Nonnull List netexFeeds + List gtfsFeeds, + List netexFeeds ) { public TransitFeeds(List gtfsFeeds, List netexFeeds) { this.netexFeeds = netexFeeds; diff --git a/src/main/java/org/opentripplanner/standalone/config/configure/ConfigModule.java b/application/src/main/java/org/opentripplanner/standalone/config/configure/ConfigModule.java similarity index 56% rename from src/main/java/org/opentripplanner/standalone/config/configure/ConfigModule.java rename to application/src/main/java/org/opentripplanner/standalone/config/configure/ConfigModule.java index b7d7084f7ba..9a4de91f2ab 100644 --- a/src/main/java/org/opentripplanner/standalone/config/configure/ConfigModule.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/configure/ConfigModule.java @@ -3,12 +3,15 @@ import dagger.Module; import dagger.Provides; import jakarta.inject.Singleton; +import org.opentripplanner.raptor.api.request.RaptorEnvironment; import org.opentripplanner.raptor.configure.RaptorConfig; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripSchedule; import org.opentripplanner.standalone.config.BuildConfig; import org.opentripplanner.standalone.config.ConfigModel; +import org.opentripplanner.standalone.config.DebugUiConfig; import org.opentripplanner.standalone.config.OtpConfig; import org.opentripplanner.standalone.config.RouterConfig; +import org.opentripplanner.standalone.config.routerconfig.RaptorEnvironmentFactory; /** * Map {@link ConfigModel} into more specific types like {@link BuildConfig} to simplify @@ -32,9 +35,24 @@ static RouterConfig provideRouterConfig(ConfigModel model) { return model.routerConfig(); } + @Provides + static DebugUiConfig provideDebugUiConfig(ConfigModel model) { + return model.debugUiConfig(); + } + + @Provides + @Singleton + static RaptorConfig providesRaptorConfig( + RouterConfig routerConfig, + RaptorEnvironment environment + ) { + return new RaptorConfig<>(routerConfig.transitTuningConfig(), environment); + } + @Provides @Singleton - static RaptorConfig providesRaptorConfig(ConfigModel config) { - return new RaptorConfig<>(config.routerConfig().transitTuningConfig()); + static RaptorEnvironment providesRaptorEnvironment(RouterConfig routerConfig) { + int searchThreadPoolSize = routerConfig.transitTuningConfig().searchThreadPoolSize(); + return RaptorEnvironmentFactory.create(searchThreadPoolSize); } } diff --git a/src/main/java/org/opentripplanner/standalone/config/configure/LoadConfigModule.java b/application/src/main/java/org/opentripplanner/standalone/config/configure/LoadConfigModule.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/configure/LoadConfigModule.java rename to application/src/main/java/org/opentripplanner/standalone/config/configure/LoadConfigModule.java diff --git a/application/src/main/java/org/opentripplanner/standalone/config/debuguiconfig/BackgroundTileLayer.java b/application/src/main/java/org/opentripplanner/standalone/config/debuguiconfig/BackgroundTileLayer.java new file mode 100644 index 00000000000..121debcb40e --- /dev/null +++ b/application/src/main/java/org/opentripplanner/standalone/config/debuguiconfig/BackgroundTileLayer.java @@ -0,0 +1,8 @@ +package org.opentripplanner.standalone.config.debuguiconfig; + +public record BackgroundTileLayer( + String name, + String templateUrl, + int tileSize, + String attribution +) {} diff --git a/src/main/java/org/opentripplanner/standalone/config/framework/file/ConfigFileLoader.java b/application/src/main/java/org/opentripplanner/standalone/config/framework/file/ConfigFileLoader.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/framework/file/ConfigFileLoader.java rename to application/src/main/java/org/opentripplanner/standalone/config/framework/file/ConfigFileLoader.java diff --git a/src/main/java/org/opentripplanner/standalone/config/framework/file/IncludeFileDirective.java b/application/src/main/java/org/opentripplanner/standalone/config/framework/file/IncludeFileDirective.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/framework/file/IncludeFileDirective.java rename to application/src/main/java/org/opentripplanner/standalone/config/framework/file/IncludeFileDirective.java diff --git a/src/main/java/org/opentripplanner/standalone/config/framework/json/ConfigType.java b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/ConfigType.java similarity index 96% rename from src/main/java/org/opentripplanner/standalone/config/framework/json/ConfigType.java rename to application/src/main/java/org/opentripplanner/standalone/config/framework/json/ConfigType.java index f62ec56dbfc..3796fcac645 100644 --- a/src/main/java/org/opentripplanner/standalone/config/framework/json/ConfigType.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/ConfigType.java @@ -5,11 +5,10 @@ import java.util.Arrays; import java.util.EnumSet; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opentripplanner.framework.lang.StringUtils; -import org.opentripplanner.framework.text.MarkdownFormatter; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.utils.lang.StringUtils; +import org.opentripplanner.utils.text.MarkdownFormatter; +import org.opentripplanner.utils.time.DurationUtils; /** * These are the types we support in the NodeAdaptor @@ -157,7 +156,7 @@ public String docName() { /** * Quote the given {@code value} is the JSON type is a {@code string}. */ - public String quote(@Nonnull Object value) { + public String quote(Object value) { return type == JsonType.string ? quoteText(value) : value.toString(); } diff --git a/src/main/java/org/opentripplanner/standalone/config/framework/json/EnumMapper.java b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/EnumMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/standalone/config/framework/json/EnumMapper.java rename to application/src/main/java/org/opentripplanner/standalone/config/framework/json/EnumMapper.java index c57220c41d5..c39c2ef7377 100644 --- a/src/main/java/org/opentripplanner/standalone/config/framework/json/EnumMapper.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/EnumMapper.java @@ -3,7 +3,7 @@ import java.util.Arrays; import java.util.Optional; import org.opentripplanner.framework.doc.DocumentedEnum; -import org.opentripplanner.framework.lang.StringUtils; +import org.opentripplanner.utils.lang.StringUtils; /** * This converts strings appearing in configuration files into enum values. diff --git a/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeAdapter.java b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeAdapter.java similarity index 97% rename from src/main/java/org/opentripplanner/standalone/config/framework/json/NodeAdapter.java rename to application/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeAdapter.java index 51303ea4fc5..273c630d2bf 100644 --- a/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeAdapter.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeAdapter.java @@ -12,7 +12,6 @@ import java.util.Set; import java.util.function.Consumer; import java.util.stream.Stream; -import javax.annotation.Nonnull; import org.opentripplanner.framework.application.OtpAppException; /** @@ -63,21 +62,21 @@ public class NodeAdapter { private final int level; - private NodeAdapter(@Nonnull JsonNode node, String source, String contextPath, int level) { + private NodeAdapter(JsonNode node, String source, String contextPath, int level) { this.json = node; this.source = source; this.contextPath = contextPath; this.level = level; } - public NodeAdapter(@Nonnull JsonNode node, String source) { + public NodeAdapter(JsonNode node, String source) { this(node, source, null, 0); } /** * Constructor for nested configuration nodes. */ - private NodeAdapter(@Nonnull JsonNode node, @Nonnull NodeAdapter parent, String paramName) { + private NodeAdapter(JsonNode node, NodeAdapter parent, String paramName) { this(node, parent.source, parent.fullPath(paramName), parent.level + 1); parent.childrenByName.put(paramName, this); } diff --git a/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeInfo.java b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeInfo.java similarity index 96% rename from src/main/java/org/opentripplanner/standalone/config/framework/json/NodeInfo.java rename to application/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeInfo.java index 06675475fd1..b9db7fb75c8 100644 --- a/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeInfo.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeInfo.java @@ -5,10 +5,9 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opentripplanner.framework.lang.StringUtils; -import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; +import org.opentripplanner.utils.lang.StringUtils; +import org.opentripplanner.utils.tostring.ValueObjectToStringBuilder; /** * Information about a configuration parameter. @@ -187,7 +186,7 @@ public String toString() { * */ @Override - public int compareTo(@Nonnull NodeInfo other) { + public int compareTo(NodeInfo other) { // Put type qualifier first if (isTypeQualifier()) { return -1; diff --git a/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeInfoBuilder.java b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeInfoBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/framework/json/NodeInfoBuilder.java rename to application/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeInfoBuilder.java diff --git a/src/main/java/org/opentripplanner/standalone/config/framework/json/OtpVersion.java b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/OtpVersion.java similarity index 93% rename from src/main/java/org/opentripplanner/standalone/config/framework/json/OtpVersion.java rename to application/src/main/java/org/opentripplanner/standalone/config/framework/json/OtpVersion.java index 70b8e261ee4..ea9dbb4d6ba 100644 --- a/src/main/java/org/opentripplanner/standalone/config/framework/json/OtpVersion.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/OtpVersion.java @@ -11,7 +11,8 @@ public enum OtpVersion { V2_3("2.3"), V2_4("2.4"), V2_5("2.5"), - V2_6("2.6"); + V2_6("2.6"), + V2_7("2.7"); private final String text; diff --git a/src/main/java/org/opentripplanner/standalone/config/framework/json/ParameterBuilder.java b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/ParameterBuilder.java similarity index 99% rename from src/main/java/org/opentripplanner/standalone/config/framework/json/ParameterBuilder.java rename to application/src/main/java/org/opentripplanner/standalone/config/framework/json/ParameterBuilder.java index 0afca602872..784d381a2e6 100644 --- a/src/main/java/org/opentripplanner/standalone/config/framework/json/ParameterBuilder.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/framework/json/ParameterBuilder.java @@ -36,11 +36,11 @@ import java.util.function.Function; import java.util.regex.Pattern; import org.opentripplanner.framework.application.OtpAppException; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.LocalDateUtils; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.framework.TimePenalty; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.LocalDateUtils; /** * TODO RT_AB: add Javadoc to clarify whether this is building a declarative representation of the diff --git a/src/main/java/org/opentripplanner/standalone/config/framework/project/EnvironmentVariableReplacer.java b/application/src/main/java/org/opentripplanner/standalone/config/framework/project/EnvironmentVariableReplacer.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/framework/project/EnvironmentVariableReplacer.java rename to application/src/main/java/org/opentripplanner/standalone/config/framework/project/EnvironmentVariableReplacer.java diff --git a/src/main/java/org/opentripplanner/standalone/config/package.md b/application/src/main/java/org/opentripplanner/standalone/config/package.md similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/package.md rename to application/src/main/java/org/opentripplanner/standalone/config/package.md diff --git a/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/RaptorEnvironmentFactory.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/RaptorEnvironmentFactory.java new file mode 100644 index 00000000000..e2cd5d6dee7 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/RaptorEnvironmentFactory.java @@ -0,0 +1,41 @@ +package org.opentripplanner.standalone.config.routerconfig; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import javax.annotation.Nullable; +import org.opentripplanner.framework.application.OTPRequestTimeoutException; +import org.opentripplanner.framework.concurrent.OtpRequestThreadFactory; +import org.opentripplanner.raptor.api.request.RaptorEnvironment; + +/** + * Create {@link RaptorEnvironment} from config and adapt it to the OTP application. + */ +public class RaptorEnvironmentFactory { + + public static RaptorEnvironment create(final int threadPoolSize) { + return new RaptorEnvironment() { + @Override + public Runnable timeoutHook() { + return OTPRequestTimeoutException::checkForTimeout; + } + + /** + * OTP web server will interrupt all request threads in case of a timeout. In OTP + * such events should be mapped to {@link OTPRequestTimeoutException}, witch will + * later be mapped to the right API response. + */ + @Override + public RuntimeException mapInterruptedException(InterruptedException e) { + return new OTPRequestTimeoutException(); + } + + @Nullable + @Override + public ExecutorService threadPool() { + return threadPoolSize > 0 + ? Executors.newFixedThreadPool(threadPoolSize, OtpRequestThreadFactory.of("raptor-%d")) + : null; + } + }; + } +} diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/RideHailingServicesConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/RideHailingServicesConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/RideHailingServicesConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/RideHailingServicesConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/ServerConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/ServerConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/ServerConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/ServerConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/TransitRoutingConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/TransitRoutingConfig.java similarity index 96% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/TransitRoutingConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/TransitRoutingConfig.java index 34465cff27a..e6602a188f4 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/TransitRoutingConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/TransitRoutingConfig.java @@ -62,8 +62,8 @@ public TransitRoutingConfig( .summary("This parameter is used to allocate enough memory space for Raptor.") .description( """ -Set it to the maximum number of transfers for any given itinerary expected to be found within the -entire transit network. The memory overhead of setting this higher than the maximum number of +Set it to the maximum number of transfers for any given itinerary expected to be found within the +entire transit network. The memory overhead of setting this higher than the maximum number of transfers is very little so it is better to set it too high than to low. """ ) @@ -78,8 +78,8 @@ public TransitRoutingConfig( .description( """ This reduce the number of trips departure time lookups and comparisons. When testing with data from -Entur and all of Norway as a Graph, the optimal value was about 50. If you calculate the departure -time every time or want to fine tune the performance, changing this may improve the performance a +Entur and all of Norway as a Graph, the optimal value was about 50. If you calculate the departure +time every time or want to fine tune the performance, changing this may improve the performance a few percents. """ ) @@ -108,11 +108,11 @@ public TransitRoutingConfig( .description( """ Use this parameter to set the total number of executable threads available across all searches. -Multiple searches can run in parallel - this parameter have no effect with regard to that. If 0, +Multiple searches can run in parallel - this parameter has no effect with regard to that. If 0, no extra threads are started and the search is done in one thread. """ ) - .asInt(dft.searchThreadPoolSize()); + .asInt(0); // Dynamic Search Window this.stopBoardAlightDuringTransferCost = c @@ -142,7 +142,7 @@ public TransitRoutingConfig( | `recommended` | Use a small cost penalty like `60`. | int | | `preferred` | The best place to do transfers. Should be set to `0`(zero). | int | -Use values in a range from `0` to `100 000`. **All key/value pairs are required if the +Use values in a range from `0` to `100 000`. **All key/value pairs are required if the `stopBoardAlightDuringTransferCost` is listed.** """ ) @@ -166,7 +166,7 @@ public TransitRoutingConfig( .summary("Routing requests to use for pre-filling the stop-to-stop transfer cache.") .description( """ -If not set, the default behavior is to cache stop-to-stop transfers using the default route request +If not set, the default behavior is to cache stop-to-stop transfers using the default route request (`routingDefaults`). Use this to change the default or specify more than one `RouteRequest`. **Example** @@ -175,7 +175,7 @@ public TransitRoutingConfig( // router-config.json { "transit": { - "transferCacheRequests": [ + "transferCacheRequests": [ { "modes": "WALK" }, { "modes": "WALK", "wheelchairAccessibility": { "enabled": true } } ] @@ -201,7 +201,7 @@ public TransitRoutingConfig( """ The search window is expanded when the current page return few options. If ZERO result is returned the first duration in the list is used, if ONE result is returned then the second duration is used -and so on. The duration is added to the existing search-window and inserted into the next and +and so on. The duration is added to the existing search-window and inserted into the next and previous page cursor. See JavaDoc for [TransitTuningParameters#pagingSearchWindowAdjustments](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/routing/algorithm/raptor/transit/TransitTuningParameters.java)" + for more info." """ @@ -244,7 +244,6 @@ public int iterationDepartureStepInSeconds() { return iterationDepartureStepInSeconds; } - @Override public int searchThreadPoolSize() { return searchThreadPoolSize; } @@ -367,7 +366,7 @@ heuristics perform a Raptor search (one-iteration) to find a trip which we use t .summary("Upper limit for the search-window calculation.") .description( """ -Long search windows consumes a lot of resources and may take a long time. Use this parameter to +Long search windows consume a lot of resources and may take a long time. Use this parameter to tune the desired maximum search time. This is the parameter that affects the response time most, the downside is that a search is only @@ -382,12 +381,12 @@ heuristics perform a Raptor search (one-iteration) to find a trip which we use t .summary("Used to set the steps the search-window is rounded to.") .description( """ -The search window is rounded off to the closest multiplication of `stepMinutes`. If `stepMinutes` = +The search window is rounded off to the closest multiplication of `stepMinutes`. If `stepMinutes` = 10 minutes, the search-window can be 10, 20, 30 ... minutes. It the computed search-window is 5 minutes and 17 seconds it will be rounded up to 10 minutes. -Use a value between `1` and `60`. This should be less than the `min-raptor-search-window` +Use a value between `1` and `60`. This should be less than the `min-raptor-search-window` coefficient. """ ) diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/UpdatersConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/UpdatersConfig.java similarity index 97% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/UpdatersConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/UpdatersConfig.java index b60b389f788..ac69b43e275 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/UpdatersConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/UpdatersConfig.java @@ -21,11 +21,8 @@ import java.util.List; import java.util.function.BiFunction; import javax.annotation.Nullable; -import org.opentripplanner.ext.siri.updater.SiriETUpdaterParameters; -import org.opentripplanner.ext.siri.updater.SiriSXUpdaterParameters; import org.opentripplanner.ext.siri.updater.azure.SiriAzureETUpdaterParameters; import org.opentripplanner.ext.siri.updater.azure.SiriAzureSXUpdaterParameters; -import org.opentripplanner.ext.siri.updater.google.SiriETGooglePubsubUpdaterParameters; import org.opentripplanner.ext.vehiclerentalservicedirectory.VehicleRentalServiceDirectoryFetcher; import org.opentripplanner.ext.vehiclerentalservicedirectory.api.VehicleRentalServiceDirectoryFetcherParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; @@ -44,6 +41,9 @@ import org.opentripplanner.updater.TimetableSnapshotSourceParameters; import org.opentripplanner.updater.UpdatersParameters; import org.opentripplanner.updater.alert.GtfsRealtimeAlertsUpdaterParameters; +import org.opentripplanner.updater.siri.updater.SiriETUpdaterParameters; +import org.opentripplanner.updater.siri.updater.SiriSXUpdaterParameters; +import org.opentripplanner.updater.siri.updater.google.SiriETGooglePubsubUpdaterParameters; import org.opentripplanner.updater.trip.MqttGtfsRealtimeUpdaterParameters; import org.opentripplanner.updater.trip.PollingTripUpdaterParameters; import org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters; diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java similarity index 85% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index 96cd49b72bb..26d56dc0dba 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -6,20 +6,22 @@ import static org.opentripplanner.inspector.vector.LayerParameters.MIN_ZOOM; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_0; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_5; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_6; import java.util.Collection; import java.util.List; import java.util.Optional; import javax.annotation.Nullable; import org.opentripplanner.ext.vectortiles.VectorTilesResource; +import org.opentripplanner.ext.vectortiles.VectorTilesResource.LayerType; +import org.opentripplanner.ext.vectortiles.layers.LayerFilters; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; -public class VectorTileConfig - implements VectorTilesResource.LayersParameters { +public class VectorTileConfig implements VectorTilesResource.LayersParameters { public static final VectorTileConfig DEFAULT = new VectorTileConfig(List.of(), null, null); - private final List> layers; + private final List> layers; @Nullable private final String basePath; @@ -28,7 +30,7 @@ public class VectorTileConfig private final String attribution; VectorTileConfig( - Collection> layers, + Collection> layers, @Nullable String basePath, @Nullable String attribution ) { @@ -38,7 +40,7 @@ public class VectorTileConfig } @Override - public List> layers() { + public List> layers() { return layers; } @@ -144,7 +146,18 @@ public static Layer mapLayer(NodeAdapter node) { "The value is a fraction of the tile size. If you are having problem with icons and " + "shapes being clipped at tile edges, then increase this number." ) - .asDouble(EXPANSION_FACTOR) + .asDouble(EXPANSION_FACTOR), + node + .of("filter") + .since(V2_6) + .summary("Reduce the result set of a layer further by a specific filter.") + .description( + """ + This is useful for when the schema of a layer, say stops, should remain unchanged but some + elements should not be included in the result. + """ + ) + .asEnum(LayerFilters.FilterType.NONE) ); } @@ -155,7 +168,8 @@ record Layer( int maxZoom, int minZoom, int cacheMaxSeconds, - double expansionFactor + double expansionFactor, + LayerFilters.FilterType filterType ) implements LayerParameters {} } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/services/UberConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/services/UberConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/services/UberConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/services/UberConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/GtfsRealtimeAlertsUpdaterConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/GtfsRealtimeAlertsUpdaterConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/GtfsRealtimeAlertsUpdaterConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/GtfsRealtimeAlertsUpdaterConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/HttpHeadersConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/HttpHeadersConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/HttpHeadersConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/HttpHeadersConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/MqttGtfsRealtimeUpdaterConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/MqttGtfsRealtimeUpdaterConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/MqttGtfsRealtimeUpdaterConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/MqttGtfsRealtimeUpdaterConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/PollingTripUpdaterConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/PollingTripUpdaterConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/PollingTripUpdaterConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/PollingTripUpdaterConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriETGooglePubsubUpdaterConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriETGooglePubsubUpdaterConfig.java similarity index 83% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriETGooglePubsubUpdaterConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriETGooglePubsubUpdaterConfig.java index 75ade008070..3396e56f6e3 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriETGooglePubsubUpdaterConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriETGooglePubsubUpdaterConfig.java @@ -1,11 +1,12 @@ package org.opentripplanner.standalone.config.routerconfig.updaters; -import static org.opentripplanner.ext.siri.updater.google.SiriETGooglePubsubUpdaterParameters.INITIAL_GET_DATA_TIMEOUT; -import static org.opentripplanner.ext.siri.updater.google.SiriETGooglePubsubUpdaterParameters.RECONNECT_PERIOD; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_1; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_7; +import static org.opentripplanner.updater.siri.updater.google.SiriETGooglePubsubUpdaterParameters.INITIAL_GET_DATA_TIMEOUT; +import static org.opentripplanner.updater.siri.updater.google.SiriETGooglePubsubUpdaterParameters.RECONNECT_PERIOD; -import org.opentripplanner.ext.siri.updater.google.SiriETGooglePubsubUpdaterParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; +import org.opentripplanner.updater.siri.updater.google.SiriETGooglePubsubUpdaterParameters; public class SiriETGooglePubsubUpdaterConfig { @@ -79,6 +80,11 @@ If this parameter is set, the updater will be marked as initialized (primed) onl .of("fuzzyTripMatching") .since(V2_1) .summary("If the trips should be matched fuzzily.") + .asBoolean(false), + c + .of("producerMetrics") + .since(V2_7) + .summary("If failure, success, and warning metrics should be collected per producer.") .asBoolean(false) ); } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriETUpdaterConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriETUpdaterConfig.java similarity index 81% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriETUpdaterConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriETUpdaterConfig.java index 5d04dd9c2a0..1b0eb2e4420 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriETUpdaterConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriETUpdaterConfig.java @@ -2,10 +2,11 @@ import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_0; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_3; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_7; import java.time.Duration; -import org.opentripplanner.ext.siri.updater.SiriETUpdaterParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; +import org.opentripplanner.updater.siri.updater.SiriETUpdaterParameters; public class SiriETUpdaterConfig { @@ -43,7 +44,12 @@ public static SiriETUpdaterParameters create(String configRef, NodeAdapter c) { .since(V2_0) .summary("If the fuzzy trip matcher should be used to match trips.") .asBoolean(false), - HttpHeadersConfig.headers(c, V2_3) + HttpHeadersConfig.headers(c, V2_3), + c + .of("producerMetrics") + .since(V2_7) + .summary("If failure, success, and warning metrics should be collected per producer.") + .asBoolean(false) ); } } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriSXUpdaterConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriSXUpdaterConfig.java similarity index 97% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriSXUpdaterConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriSXUpdaterConfig.java index dd0be8bc449..984ef4625e6 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriSXUpdaterConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/SiriSXUpdaterConfig.java @@ -4,8 +4,8 @@ import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_3; import java.time.Duration; -import org.opentripplanner.ext.siri.updater.SiriSXUpdaterParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; +import org.opentripplanner.updater.siri.updater.SiriSXUpdaterParameters; public class SiriSXUpdaterConfig { diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java similarity index 91% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java index 88b47aac4eb..cbfae0c061b 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java @@ -11,7 +11,6 @@ import org.opentripplanner.ext.vehicleparking.bikeep.BikeepUpdaterParameters; import org.opentripplanner.ext.vehicleparking.bikely.BikelyUpdaterParameters; import org.opentripplanner.ext.vehicleparking.hslpark.HslParkUpdaterParameters; -import org.opentripplanner.ext.vehicleparking.noi.NoiUpdaterParameters; import org.opentripplanner.ext.vehicleparking.parkapi.ParkAPIUpdaterParameters; import org.opentripplanner.ext.vehicleparking.sirifm.SiriFmUpdaterParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; @@ -79,17 +78,6 @@ public static VehicleParkingUpdaterParameters create(String updaterRef, NodeAdap .asDuration(Duration.ofMinutes(1)), HttpHeadersConfig.headers(c, V2_3) ); - case NOI_OPEN_DATA_HUB -> new NoiUpdaterParameters( - updaterRef, - c.of("url").since(V2_6).summary("URL of the locations endpoint.").asUri(), - feedId, - c - .of("frequency") - .since(V2_6) - .summary("How often to update the source.") - .asDuration(Duration.ofMinutes(1)), - HttpHeadersConfig.headers(c, V2_6) - ); case BIKEEP -> new BikeepUpdaterParameters( updaterRef, c.of("url").since(V2_6).summary("URL of the locations endpoint.").asUri(), diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehiclePositionsUpdaterConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehiclePositionsUpdaterConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehiclePositionsUpdaterConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehiclePositionsUpdaterConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleRentalUpdaterConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleRentalUpdaterConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleRentalUpdaterConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleRentalUpdaterConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureETUpdaterConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureETUpdaterConfig.java similarity index 95% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureETUpdaterConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureETUpdaterConfig.java index 791f9a9dadc..61c5d93b902 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureETUpdaterConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureETUpdaterConfig.java @@ -1,6 +1,5 @@ package org.opentripplanner.standalone.config.routerconfig.updaters.azure; -import static org.opentripplanner.standalone.config.framework.json.OtpVersion.NA; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_2; import org.opentripplanner.ext.siri.updater.azure.SiriAzureETUpdaterParameters; diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureSXUpdaterConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureSXUpdaterConfig.java similarity index 95% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureSXUpdaterConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureSXUpdaterConfig.java index cf5dacb5976..c1b3b0351a3 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureSXUpdaterConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureSXUpdaterConfig.java @@ -1,6 +1,5 @@ package org.opentripplanner.standalone.config.routerconfig.updaters.azure; -import static org.opentripplanner.standalone.config.framework.json.OtpVersion.NA; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_2; import org.opentripplanner.ext.siri.updater.azure.SiriAzureSXUpdaterParameters; diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureUpdaterConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureUpdaterConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureUpdaterConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/azure/SiriAzureUpdaterConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/sources/VehicleRentalSourceFactory.java b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/sources/VehicleRentalSourceFactory.java similarity index 87% rename from src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/sources/VehicleRentalSourceFactory.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/sources/VehicleRentalSourceFactory.java index aa548977c7e..e58b5e96ae8 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/sources/VehicleRentalSourceFactory.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/sources/VehicleRentalSourceFactory.java @@ -1,16 +1,20 @@ package org.opentripplanner.standalone.config.routerconfig.updaters.sources; +import static org.opentripplanner.standalone.config.framework.json.EnumMapper.docEnumValueList; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V1_5; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_1; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_2; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_3; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_7; +import java.util.Set; import org.opentripplanner.ext.smoovebikerental.SmooveBikeRentalDataSourceParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; import org.opentripplanner.standalone.config.routerconfig.updaters.HttpHeadersConfig; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.vehicle_rental.VehicleRentalSourceType; import org.opentripplanner.updater.vehicle_rental.datasources.params.GbfsVehicleRentalDataSourceParameters; +import org.opentripplanner.updater.vehicle_rental.datasources.params.RentalPickupType; import org.opentripplanner.updater.vehicle_rental.datasources.params.VehicleRentalDataSourceParameters; /** @@ -43,13 +47,15 @@ public VehicleRentalDataSourceParameters create() { headers(), network(), geofencingZones(), - overloadingAllowed() + overloadingAllowed(), + rentalPickupTypes() ); case SMOOVE -> new SmooveBikeRentalDataSourceParameters( url(), network(), overloadingAllowed(), - headers() + headers(), + rentalPickupTypes() ); }; } @@ -121,4 +127,13 @@ private boolean geofencingZones() { ) .asBoolean(false); } + + private Set rentalPickupTypes() { + return c + .of("rentalPickupTypes") + .since(V2_7) + .summary(RentalPickupType.STATION.typeDescription()) + .description(docEnumValueList(RentalPickupType.values())) + .asEnumSet(RentalPickupType.class, RentalPickupType.ALL); + } } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/ItineraryFiltersConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerequest/ItineraryFiltersConfig.java similarity index 93% rename from src/main/java/org/opentripplanner/standalone/config/routerequest/ItineraryFiltersConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerequest/ItineraryFiltersConfig.java index 82e2c0839f9..c021de88a8e 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/ItineraryFiltersConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerequest/ItineraryFiltersConfig.java @@ -6,18 +6,15 @@ import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_2; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_3; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_4; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_7; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; import org.opentripplanner.routing.api.request.preference.ItineraryFilterPreferences; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class ItineraryFiltersConfig { - private static final Logger LOG = LoggerFactory.getLogger(ItineraryFiltersConfig.class); - public static void mapItineraryFilterParams( String parameterName, NodeAdapter root, @@ -265,6 +262,28 @@ public static void mapItineraryFilterParams( ) .asDouble(dft.minBikeParkingDistance()) ) + .withFilterDirectFlexBySearchWindow( + c + .of("filterDirectFlexBySearchWindow") + .since(V2_7) + .summary( + """ + Filter direct flex results by the search window. The search-window is not used + during flex routing, but we use one end to align it with transit results.""" + ) + .description( + """ + When direct flex is mixed with a transit search in the same request, then the direct + flex results are filtered by the search window of the transit results. + + Depart-at searches are filtered by latest-arrival-time and arrive-by searches are + filtered by earliest-departure-time. + + Use this configuration to turn this feature off. + """ + ) + .asBoolean(true) + ) .build(); } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java similarity index 99% rename from src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index dc91388458a..d05aee96ccf 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -18,7 +18,6 @@ import java.util.stream.Collectors; import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.routing.api.request.RequestModes; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.StreetMode; @@ -35,6 +34,7 @@ import org.opentripplanner.standalone.config.framework.json.NodeAdapter; import org.opentripplanner.standalone.config.sandbox.DataOverlayParametersMapper; import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.utils.lang.StringUtils; public class RouteRequestConfig { diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/TimeAndCostPenaltyMapper.java b/application/src/main/java/org/opentripplanner/standalone/config/routerequest/TimeAndCostPenaltyMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerequest/TimeAndCostPenaltyMapper.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerequest/TimeAndCostPenaltyMapper.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/TransferConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerequest/TransferConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerequest/TransferConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerequest/TransferConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/TransitGroupPriorityConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerequest/TransitGroupPriorityConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerequest/TransitGroupPriorityConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerequest/TransitGroupPriorityConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/WheelchairConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/routerequest/WheelchairConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/routerequest/WheelchairConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/routerequest/WheelchairConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/sandbox/DataOverlayConfigMapper.java b/application/src/main/java/org/opentripplanner/standalone/config/sandbox/DataOverlayConfigMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/sandbox/DataOverlayConfigMapper.java rename to application/src/main/java/org/opentripplanner/standalone/config/sandbox/DataOverlayConfigMapper.java diff --git a/src/main/java/org/opentripplanner/standalone/config/sandbox/DataOverlayParametersMapper.java b/application/src/main/java/org/opentripplanner/standalone/config/sandbox/DataOverlayParametersMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/sandbox/DataOverlayParametersMapper.java rename to application/src/main/java/org/opentripplanner/standalone/config/sandbox/DataOverlayParametersMapper.java diff --git a/src/main/java/org/opentripplanner/standalone/config/sandbox/FlexConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/sandbox/FlexConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/sandbox/FlexConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/sandbox/FlexConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/sandbox/TransmodelAPIConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/sandbox/TransmodelAPIConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/sandbox/TransmodelAPIConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/sandbox/TransmodelAPIConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/config/sandbox/VehicleRentalServiceDirectoryFetcherConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/sandbox/VehicleRentalServiceDirectoryFetcherConfig.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/config/sandbox/VehicleRentalServiceDirectoryFetcherConfig.java rename to application/src/main/java/org/opentripplanner/standalone/config/sandbox/VehicleRentalServiceDirectoryFetcherConfig.java diff --git a/src/main/java/org/opentripplanner/standalone/configure/ConstructApplication.java b/application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplication.java similarity index 84% rename from src/main/java/org/opentripplanner/standalone/configure/ConstructApplication.java rename to application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplication.java index 52f7970ccd7..b4edbb36299 100644 --- a/src/main/java/org/opentripplanner/standalone/configure/ConstructApplication.java +++ b/application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplication.java @@ -8,7 +8,6 @@ import org.opentripplanner.ext.stopconsolidation.StopConsolidationRepository; import org.opentripplanner.framework.application.LogMDCSupport; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.framework.logging.ProgressTracker; import org.opentripplanner.graph_builder.GraphBuilder; import org.opentripplanner.graph_builder.GraphBuilderDataSources; import org.opentripplanner.graph_builder.issue.api.DataImportIssueSummary; @@ -20,12 +19,15 @@ import org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers.TransitLayerUpdater; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleRepository; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; import org.opentripplanner.service.vehiclerental.VehicleRentalRepository; import org.opentripplanner.service.worldenvelope.WorldEnvelopeRepository; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.standalone.config.BuildConfig; import org.opentripplanner.standalone.config.CommandLineParameters; import org.opentripplanner.standalone.config.ConfigModel; +import org.opentripplanner.standalone.config.DebugUiConfig; import org.opentripplanner.standalone.config.OtpConfig; import org.opentripplanner.standalone.config.RouterConfig; import org.opentripplanner.standalone.server.GrizzlyServer; @@ -33,8 +35,9 @@ import org.opentripplanner.street.model.StreetLimitationParameters; import org.opentripplanner.street.model.elevation.ElevationUtils; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.updater.configure.UpdaterConfigurator; +import org.opentripplanner.utils.logging.ProgressTracker; import org.opentripplanner.visualizer.GraphVisualizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,12 +72,13 @@ public class ConstructApplication { ConstructApplication( CommandLineParameters cli, Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, WorldEnvelopeRepository worldEnvelopeRepository, ConfigModel config, GraphBuilderDataSources graphBuilderDataSources, DataImportIssueSummary issueSummary, EmissionsDataModel emissionsDataModel, + VehicleParkingRepository vehicleParkingRepository, @Nullable StopConsolidationRepository stopConsolidationRepository, StreetLimitationParameters streetLimitationParameters ) { @@ -90,9 +94,10 @@ public class ConstructApplication { .builder() .configModel(config) .graph(graph) - .transitModel(transitModel) + .timetableRepository(timetableRepository) .graphVisualizer(graphVisualizer) .worldEnvelopeRepository(worldEnvelopeRepository) + .vehicleParkingRepository(vehicleParkingRepository) .emissionsDataModel(emissionsDataModel) .dataImportIssueSummary(issueSummary) .stopConsolidationRepository(stopConsolidationRepository) @@ -125,8 +130,9 @@ public GraphBuilder createGraphBuilder() { buildConfig(), graphBuilderDataSources, graph(), - transitModel(), + timetableRepository(), factory.worldEnvelopeRepository(), + factory.vehicleParkingRepository(), factory.emissionsDataModel(), factory.stopConsolidationRepository(), factory.streetLimitationParameters(), @@ -156,26 +162,28 @@ private void setupTransitRoutingServer() { enableRequestTraceLogging(); createMetricsLogging(); - creatTransitLayerForRaptor(transitModel(), routerConfig().transitTuningConfig()); + creatTransitLayerForRaptor(timetableRepository(), routerConfig().transitTuningConfig()); /* Create updater modules from JSON config. */ UpdaterConfigurator.configure( graph(), realtimeVehicleRepository(), vehicleRentalRepository(), - transitModel(), + vehicleParkingRepository(), + timetableRepository(), routerConfig().updaterConfig() ); initEllipsoidToGeoidDifference(); - initializeTransferCache(routerConfig().transitTuningConfig(), transitModel()); + initializeTransferCache(routerConfig().transitTuningConfig(), timetableRepository()); if (OTPFeature.TransmodelGraphQlApi.isOn()) { TransmodelAPI.setUp( routerConfig().transmodelApi(), - transitModel(), - routerConfig().routingRequestDefaults() + timetableRepository(), + routerConfig().routingRequestDefaults(), + routerConfig().transitTuningConfig() ); } @@ -200,25 +208,29 @@ private void initEllipsoidToGeoidDifference() { * Create transit layer for Raptor routing. Here we map the scheduled timetables. */ public static void creatTransitLayerForRaptor( - TransitModel transitModel, + TimetableRepository timetableRepository, TransitTuningParameters tuningParameters ) { - if (!transitModel.hasTransit() || !transitModel.isIndexed()) { + if (!timetableRepository.hasTransit() || !timetableRepository.isIndexed()) { LOG.warn( "Cannot create Raptor data, that requires the graph to have transit data and be indexed." ); } LOG.info("Creating transit layer for Raptor routing."); - transitModel.setTransitLayer(TransitLayerMapper.map(tuningParameters, transitModel)); - transitModel.setRealtimeTransitLayer(new TransitLayer(transitModel.getTransitLayer())); - transitModel.setTransitLayerUpdater( - new TransitLayerUpdater(new DefaultTransitService(transitModel)) + timetableRepository.setTransitLayer( + TransitLayerMapper.map(tuningParameters, timetableRepository) + ); + timetableRepository.setRealtimeTransitLayer( + new TransitLayer(timetableRepository.getTransitLayer()) + ); + timetableRepository.setTransitLayerUpdater( + new TransitLayerUpdater(new DefaultTransitService(timetableRepository)) ); } public static void initializeTransferCache( TransitTuningParameters transitTuningConfig, - TransitModel transitModel + TimetableRepository timetableRepository ) { var transferCacheRequests = transitTuningConfig.transferCacheRequests(); if (!transferCacheRequests.isEmpty()) { @@ -231,7 +243,7 @@ public static void initializeTransferCache( LOG.info(progress.startMessage()); transferCacheRequests.forEach(request -> { - transitModel.getTransitLayer().initTransferCacheForRequest(request); + timetableRepository.getTransitLayer().initTransferCacheForRequest(request); //noinspection Convert2MethodRef progress.step(s -> LOG.info(s)); @@ -241,8 +253,8 @@ public static void initializeTransferCache( } } - public TransitModel transitModel() { - return factory.transitModel(); + public TimetableRepository timetableRepository() { + return factory.timetableRepository(); } public DataImportIssueSummary dataImportIssueSummary() { @@ -261,6 +273,14 @@ public VehicleRentalRepository vehicleRentalRepository() { return factory.vehicleRentalRepository(); } + public VehicleParkingService vehicleParkingService() { + return factory.vehicleParkingService(); + } + + public VehicleParkingRepository vehicleParkingRepository() { + return factory.vehicleParkingRepository(); + } + public Graph graph() { return factory.graph(); } @@ -281,6 +301,10 @@ public BuildConfig buildConfig() { return factory.config().buildConfig(); } + public DebugUiConfig debugUiConfig() { + return factory.config().debugUiConfig(); + } + public RaptorConfig raptorConfig() { return factory.raptorConfig(); } diff --git a/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationFactory.java b/application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationFactory.java similarity index 84% rename from src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationFactory.java rename to application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationFactory.java index b307776ef52..d6310c0c616 100644 --- a/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationFactory.java +++ b/application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationFactory.java @@ -10,6 +10,8 @@ import org.opentripplanner.ext.geocoder.configure.GeocoderModule; import org.opentripplanner.ext.interactivelauncher.configuration.InteractiveLauncherModule; import org.opentripplanner.ext.ridehailing.configure.RideHailingServicesModule; +import org.opentripplanner.ext.sorlandsbanen.SorlandsbanenNorwayService; +import org.opentripplanner.ext.sorlandsbanen.configure.SorlandsbanenNorwayModule; import org.opentripplanner.ext.stopconsolidation.StopConsolidationRepository; import org.opentripplanner.ext.stopconsolidation.configure.StopConsolidationServiceModule; import org.opentripplanner.graph_builder.issue.api.DataImportIssueSummary; @@ -20,6 +22,9 @@ import org.opentripplanner.service.realtimevehicles.RealtimeVehicleService; import org.opentripplanner.service.realtimevehicles.configure.RealtimeVehicleRepositoryModule; import org.opentripplanner.service.realtimevehicles.configure.RealtimeVehicleServiceModule; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; +import org.opentripplanner.service.vehicleparking.configure.VehicleParkingServiceModule; import org.opentripplanner.service.vehiclerental.VehicleRentalRepository; import org.opentripplanner.service.vehiclerental.VehicleRentalService; import org.opentripplanner.service.vehiclerental.configure.VehicleRentalRepositoryModule; @@ -34,7 +39,7 @@ import org.opentripplanner.street.model.StreetLimitationParameters; import org.opentripplanner.street.service.StreetLimitationParametersServiceModule; import org.opentripplanner.transit.configure.TransitModule; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.transit.service.TransitService; import org.opentripplanner.visualizer.GraphVisualizer; @@ -52,9 +57,11 @@ RealtimeVehicleRepositoryModule.class, VehicleRentalServiceModule.class, VehicleRentalRepositoryModule.class, + VehicleParkingServiceModule.class, ConstructApplicationModule.class, RideHailingServicesModule.class, EmissionsServiceModule.class, + SorlandsbanenNorwayModule.class, StopConsolidationServiceModule.class, InteractiveLauncherModule.class, StreetLimitationParametersServiceModule.class, @@ -65,13 +72,15 @@ public interface ConstructApplicationFactory { ConfigModel config(); RaptorConfig raptorConfig(); Graph graph(); - TransitModel transitModel(); + TimetableRepository timetableRepository(); WorldEnvelopeRepository worldEnvelopeRepository(); WorldEnvelopeService worldEnvelopeService(); RealtimeVehicleRepository realtimeVehicleRepository(); RealtimeVehicleService realtimeVehicleService(); VehicleRentalRepository vehicleRentalRepository(); VehicleRentalService vehicleRentalService(); + VehicleParkingRepository vehicleParkingRepository(); + VehicleParkingService vehicleParkingService(); DataImportIssueSummary dataImportIssueSummary(); @Nullable @@ -90,6 +99,9 @@ public interface ConstructApplicationFactory { StreetLimitationParameters streetLimitationParameters(); + @Nullable + SorlandsbanenNorwayService enturSorlandsbanenService(); + @Nullable LuceneIndex luceneIndex(); @@ -102,7 +114,7 @@ interface Builder { Builder graph(Graph graph); @BindsInstance - Builder transitModel(TransitModel transitModel); + Builder timetableRepository(TimetableRepository timetableRepository); @BindsInstance Builder graphVisualizer(@Nullable GraphVisualizer graphVisualizer); @@ -115,6 +127,9 @@ Builder stopConsolidationRepository( @Nullable StopConsolidationRepository stopConsolidationRepository ); + @BindsInstance + Builder vehicleParkingRepository(VehicleParkingRepository parkingRepository); + @BindsInstance Builder dataImportIssueSummary(DataImportIssueSummary issueSummary); diff --git a/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationModule.java b/application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationModule.java similarity index 86% rename from src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationModule.java rename to application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationModule.java index 6c830054c49..42bd8ee4d87 100644 --- a/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationModule.java +++ b/application/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationModule.java @@ -10,14 +10,17 @@ import org.opentripplanner.ext.geocoder.LuceneIndex; import org.opentripplanner.ext.interactivelauncher.api.LauncherRequestDecorator; import org.opentripplanner.ext.ridehailing.RideHailingService; +import org.opentripplanner.ext.sorlandsbanen.SorlandsbanenNorwayService; import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; import org.opentripplanner.raptor.configure.RaptorConfig; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripSchedule; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleService; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; import org.opentripplanner.service.vehiclerental.VehicleRentalService; import org.opentripplanner.service.worldenvelope.WorldEnvelopeService; import org.opentripplanner.standalone.api.OtpServerRequestContext; +import org.opentripplanner.standalone.config.DebugUiConfig; import org.opentripplanner.standalone.config.RouterConfig; import org.opentripplanner.standalone.server.DefaultServerRequestContext; import org.opentripplanner.street.service.StreetLimitationParametersService; @@ -30,17 +33,20 @@ public class ConstructApplicationModule { @Provides OtpServerRequestContext providesServerContext( RouterConfig routerConfig, + DebugUiConfig debugUiConfig, RaptorConfig raptorConfig, Graph graph, TransitService transitService, WorldEnvelopeService worldEnvelopeService, RealtimeVehicleService realtimeVehicleService, VehicleRentalService vehicleRentalService, + VehicleParkingService vehicleParkingService, List rideHailingServices, @Nullable StopConsolidationService stopConsolidationService, StreetLimitationParametersService streetLimitationParametersService, @Nullable TraverseVisitor traverseVisitor, EmissionsService emissionsService, + @Nullable SorlandsbanenNorwayService sorlandsbanenService, LauncherRequestDecorator launcherRequestDecorator, @Nullable LuceneIndex luceneIndex ) { @@ -57,13 +63,16 @@ OtpServerRequestContext providesServerContext( worldEnvelopeService, realtimeVehicleService, vehicleRentalService, + vehicleParkingService, emissionsService, + sorlandsbanenService, routerConfig.flexParameters(), rideHailingServices, stopConsolidationService, streetLimitationParametersService, traverseVisitor, - luceneIndex + luceneIndex, + debugUiConfig ); } diff --git a/src/main/java/org/opentripplanner/standalone/configure/LoadApplication.java b/application/src/main/java/org/opentripplanner/standalone/configure/LoadApplication.java similarity index 89% rename from src/main/java/org/opentripplanner/standalone/configure/LoadApplication.java rename to application/src/main/java/org/opentripplanner/standalone/configure/LoadApplication.java index 19415e489b4..021af778345 100644 --- a/src/main/java/org/opentripplanner/standalone/configure/LoadApplication.java +++ b/application/src/main/java/org/opentripplanner/standalone/configure/LoadApplication.java @@ -8,11 +8,12 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssueSummary; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.graph.SerializedGraphObject; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; import org.opentripplanner.service.worldenvelope.WorldEnvelopeRepository; import org.opentripplanner.standalone.config.CommandLineParameters; import org.opentripplanner.standalone.config.ConfigModel; import org.opentripplanner.street.model.StreetLimitationParameters; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; /** * This class is responsible for loading configuration and setting up the OTP data store. @@ -54,8 +55,9 @@ public DataSource getInputGraphDataStore() { public ConstructApplication appConstruction(SerializedGraphObject obj) { return createAppConstruction( obj.graph, - obj.transitModel, + obj.timetableRepository, obj.worldEnvelopeRepository, + obj.parkingRepository, obj.issueSummary, obj.emissionsDataModel, obj.stopConsolidationRepository, @@ -67,8 +69,9 @@ public ConstructApplication appConstruction(SerializedGraphObject obj) { public ConstructApplication appConstruction() { return createAppConstruction( factory.emptyGraph(), - factory.emptyTransitModel(), + factory.emptyTimetableRepository(), factory.emptyWorldEnvelopeRepository(), + factory.emptyVehicleParkingRepository(), DataImportIssueSummary.empty(), factory.emptyEmissionsDataModel(), factory.emptyStopConsolidationRepository(), @@ -89,8 +92,9 @@ public ConfigModel config() { private ConstructApplication createAppConstruction( Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, WorldEnvelopeRepository worldEnvelopeRepository, + VehicleParkingRepository parkingRepository, DataImportIssueSummary issueSummary, @Nullable EmissionsDataModel emissionsDataModel, @Nullable StopConsolidationRepository stopConsolidationRepository, @@ -99,12 +103,13 @@ private ConstructApplication createAppConstruction( return new ConstructApplication( cli, graph, - transitModel, + timetableRepository, worldEnvelopeRepository, config(), graphBuilderDataSources(), issueSummary, emissionsDataModel, + parkingRepository, stopConsolidationRepository, streetLimitationParameters ); diff --git a/src/main/java/org/opentripplanner/standalone/configure/LoadApplicationFactory.java b/application/src/main/java/org/opentripplanner/standalone/configure/LoadApplicationFactory.java similarity index 84% rename from src/main/java/org/opentripplanner/standalone/configure/LoadApplicationFactory.java rename to application/src/main/java/org/opentripplanner/standalone/configure/LoadApplicationFactory.java index aacb42c4336..b054fac3ca5 100644 --- a/src/main/java/org/opentripplanner/standalone/configure/LoadApplicationFactory.java +++ b/application/src/main/java/org/opentripplanner/standalone/configure/LoadApplicationFactory.java @@ -11,13 +11,15 @@ import org.opentripplanner.ext.stopconsolidation.configure.StopConsolidationRepositoryModule; import org.opentripplanner.graph_builder.GraphBuilderDataSources; import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.configure.VehicleParkingRepositoryModule; import org.opentripplanner.service.worldenvelope.WorldEnvelopeRepository; import org.opentripplanner.service.worldenvelope.configure.WorldEnvelopeRepositoryModule; import org.opentripplanner.standalone.config.CommandLineParameters; import org.opentripplanner.standalone.config.ConfigModel; import org.opentripplanner.standalone.config.configure.LoadConfigModule; import org.opentripplanner.street.model.StreetLimitationParameters; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; /** * Dagger dependency injection Factory to create components for the OTP load application phase. @@ -30,6 +32,7 @@ GsDataSourceModule.class, WorldEnvelopeRepositoryModule.class, StopConsolidationRepositoryModule.class, + VehicleParkingRepositoryModule.class, } ) public interface LoadApplicationFactory { @@ -41,7 +44,7 @@ public interface LoadApplicationFactory { Graph emptyGraph(); @Singleton - TransitModel emptyTransitModel(); + TimetableRepository emptyTimetableRepository(); @Singleton WorldEnvelopeRepository emptyWorldEnvelopeRepository(); @@ -58,6 +61,9 @@ public interface LoadApplicationFactory { @Singleton StreetLimitationParameters emptyStreetLimitationParameters(); + @Singleton + VehicleParkingRepository emptyVehicleParkingRepository(); + @Component.Builder interface Builder { @BindsInstance diff --git a/src/main/java/org/opentripplanner/standalone/server/CorsFilter.java b/application/src/main/java/org/opentripplanner/standalone/server/CorsFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/server/CorsFilter.java rename to application/src/main/java/org/opentripplanner/standalone/server/CorsFilter.java diff --git a/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java b/application/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java similarity index 82% rename from src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java rename to application/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java index 0e81193d787..450b6986cb5 100644 --- a/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java +++ b/application/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java @@ -9,6 +9,7 @@ import org.opentripplanner.ext.flex.FlexParameters; import org.opentripplanner.ext.geocoder.LuceneIndex; import org.opentripplanner.ext.ridehailing.RideHailingService; +import org.opentripplanner.ext.sorlandsbanen.SorlandsbanenNorwayService; import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; import org.opentripplanner.inspector.raster.TileRendererManager; import org.opentripplanner.raptor.api.request.RaptorTuningParameters; @@ -20,10 +21,12 @@ import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.service.DefaultRoutingService; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleService; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; import org.opentripplanner.service.vehiclerental.VehicleRentalService; import org.opentripplanner.service.worldenvelope.WorldEnvelopeService; import org.opentripplanner.standalone.api.HttpRequestScoped; import org.opentripplanner.standalone.api.OtpServerRequestContext; +import org.opentripplanner.standalone.config.DebugUiConfig; import org.opentripplanner.standalone.config.routerconfig.TransitRoutingConfig; import org.opentripplanner.standalone.config.routerconfig.VectorTileConfig; import org.opentripplanner.street.service.StreetLimitationParametersService; @@ -33,7 +36,6 @@ public class DefaultServerRequestContext implements OtpServerRequestContext { private final List rideHailingServices; - private RouteRequest routeRequest = null; private final Graph graph; private final TransitService transitService; private final TransitRoutingConfig transitRoutingConfig; @@ -47,10 +49,18 @@ public class DefaultServerRequestContext implements OtpServerRequestContext { private final WorldEnvelopeService worldEnvelopeService; private final RealtimeVehicleService realtimeVehicleService; private final VehicleRentalService vehicleRentalService; + private final VehicleParkingService vehicleParkingService; private final EmissionsService emissionsService; + + @Nullable + private final SorlandsbanenNorwayService sorlandsbanenService; + private final StopConsolidationService stopConsolidationService; private final StreetLimitationParametersService streetLimitationParametersService; private final LuceneIndex luceneIndex; + private final DebugUiConfig debugUiConfig; + + private RouteRequest defaultRouteRequestWithTimeSet = null; /** * Make sure all mutable components are copied/cloned before calling this constructor. @@ -67,13 +77,16 @@ private DefaultServerRequestContext( WorldEnvelopeService worldEnvelopeService, RealtimeVehicleService realtimeVehicleService, VehicleRentalService vehicleRentalService, - EmissionsService emissionsService, + VehicleParkingService vehicleParkingService, + @Nullable EmissionsService emissionsService, + @Nullable SorlandsbanenNorwayService sorlandsbanenService, List rideHailingServices, - StopConsolidationService stopConsolidationService, + @Nullable StopConsolidationService stopConsolidationService, StreetLimitationParametersService streetLimitationParametersService, FlexParameters flexParameters, - TraverseVisitor traverseVisitor, - @Nullable LuceneIndex luceneIndex + @Nullable TraverseVisitor traverseVisitor, + @Nullable LuceneIndex luceneIndex, + DebugUiConfig debugUiConfig ) { this.graph = graph; this.transitService = transitService; @@ -83,6 +96,7 @@ private DefaultServerRequestContext( this.tileRendererManager = tileRendererManager; this.vectorTileConfig = vectorTileConfig; this.vehicleRentalService = vehicleRentalService; + this.vehicleParkingService = vehicleParkingService; this.flexParameters = flexParameters; this.traverseVisitor = traverseVisitor; this.routeRequestDefaults = routeRequestDefaults; @@ -90,9 +104,11 @@ private DefaultServerRequestContext( this.realtimeVehicleService = realtimeVehicleService; this.rideHailingServices = rideHailingServices; this.emissionsService = emissionsService; + this.sorlandsbanenService = sorlandsbanenService; this.stopConsolidationService = stopConsolidationService; this.streetLimitationParametersService = streetLimitationParametersService; this.luceneIndex = luceneIndex; + this.debugUiConfig = debugUiConfig; } /** @@ -109,13 +125,16 @@ public static DefaultServerRequestContext create( WorldEnvelopeService worldEnvelopeService, RealtimeVehicleService realtimeVehicleService, VehicleRentalService vehicleRentalService, + VehicleParkingService vehicleParkingService, @Nullable EmissionsService emissionsService, + @Nullable SorlandsbanenNorwayService sorlandsbanenService, FlexParameters flexParameters, List rideHailingServices, @Nullable StopConsolidationService stopConsolidationService, StreetLimitationParametersService streetLimitationParametersService, @Nullable TraverseVisitor traverseVisitor, - @Nullable LuceneIndex luceneIndex + @Nullable LuceneIndex luceneIndex, + DebugUiConfig debugUiConfig ) { return new DefaultServerRequestContext( graph, @@ -129,23 +148,26 @@ public static DefaultServerRequestContext create( worldEnvelopeService, realtimeVehicleService, vehicleRentalService, + vehicleParkingService, emissionsService, + sorlandsbanenService, rideHailingServices, stopConsolidationService, streetLimitationParametersService, flexParameters, traverseVisitor, - luceneIndex + luceneIndex, + debugUiConfig ); } @Override public RouteRequest defaultRouteRequest() { // Lazy initialize request-scoped request to avoid doing this when not needed - if (routeRequest == null) { - routeRequest = routeRequestDefaults.copyWithDateTimeNow(); + if (defaultRouteRequestWithTimeSet == null) { + defaultRouteRequestWithTimeSet = routeRequestDefaults.copyWithDateTimeNow(); } - return routeRequest; + return defaultRouteRequestWithTimeSet; } /** @@ -191,6 +213,11 @@ public VehicleRentalService vehicleRentalService() { return vehicleRentalService; } + @Override + public VehicleParkingService vehicleParkingService() { + return vehicleParkingService; + } + @Override public TransitTuningParameters transitTuningParameters() { return transitRoutingConfig; @@ -241,6 +268,11 @@ public VectorTileConfig vectorTileConfig() { return vectorTileConfig; } + @Override + public DebugUiConfig debugUiConfig() { + return debugUiConfig; + } + @Nullable @Override public LuceneIndex lucenceIndex() { @@ -251,4 +283,9 @@ public LuceneIndex lucenceIndex() { public EmissionsService emissionsService() { return emissionsService; } + + @Nullable + public SorlandsbanenNorwayService sorlandsbanenService() { + return sorlandsbanenService; + } } diff --git a/src/main/java/org/opentripplanner/standalone/server/EtagRequestFilter.java b/application/src/main/java/org/opentripplanner/standalone/server/EtagRequestFilter.java similarity index 98% rename from src/main/java/org/opentripplanner/standalone/server/EtagRequestFilter.java rename to application/src/main/java/org/opentripplanner/standalone/server/EtagRequestFilter.java index 65cdec32a7d..b53739084ae 100644 --- a/src/main/java/org/opentripplanner/standalone/server/EtagRequestFilter.java +++ b/application/src/main/java/org/opentripplanner/standalone/server/EtagRequestFilter.java @@ -10,7 +10,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import org.apache.hc.core5.http.HttpStatus; -import org.opentripplanner.framework.text.HexString; +import org.opentripplanner.utils.text.HexString; public class EtagRequestFilter implements ContainerResponseFilter { diff --git a/src/main/java/org/opentripplanner/standalone/server/GrizzlyServer.java b/application/src/main/java/org/opentripplanner/standalone/server/GrizzlyServer.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/server/GrizzlyServer.java rename to application/src/main/java/org/opentripplanner/standalone/server/GrizzlyServer.java diff --git a/src/main/java/org/opentripplanner/standalone/server/MetricsLogging.java b/application/src/main/java/org/opentripplanner/standalone/server/MetricsLogging.java similarity index 87% rename from src/main/java/org/opentripplanner/standalone/server/MetricsLogging.java rename to application/src/main/java/org/opentripplanner/standalone/server/MetricsLogging.java index 3ed5685015b..c9161c7588a 100644 --- a/src/main/java/org/opentripplanner/standalone/server/MetricsLogging.java +++ b/application/src/main/java/org/opentripplanner/standalone/server/MetricsLogging.java @@ -22,7 +22,7 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssueSummary; import org.opentripplanner.raptor.configure.RaptorConfig; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripSchedule; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; /** * This class is responsible for wiring up various metrics to micrometer, which we use for @@ -32,7 +32,7 @@ public class MetricsLogging { @Inject public MetricsLogging( - TransitModel transitModel, + TimetableRepository timetableRepository, RaptorConfig raptorConfig, DataImportIssueSummary issueSummary ) { @@ -48,9 +48,9 @@ public MetricsLogging( new ProcessorMetrics().bindTo(Metrics.globalRegistry); new UptimeMetrics().bindTo(Metrics.globalRegistry); - if (transitModel.getTransitLayer() != null) { + if (timetableRepository.getTransitLayer() != null) { new GuavaCacheMetrics( - transitModel.getTransitLayer().getTransferCache().getTransferCache(), + timetableRepository.getTransitLayer().getTransferCache().getTransferCache(), "raptorTransfersCache", List.of(Tag.of("cache", "raptorTransfers")) ) @@ -63,23 +63,23 @@ public MetricsLogging( ) .bindTo(Metrics.globalRegistry); - if (transitModel.getUpdaterManager() != null) { + if (timetableRepository.getUpdaterManager() != null) { new ExecutorServiceMetrics( - transitModel.getUpdaterManager().getPollingUpdaterPool(), + timetableRepository.getUpdaterManager().getPollingUpdaterPool(), "pollingGraphUpdaters", List.of(Tag.of("pool", "pollingGraphUpdaters")) ) .bindTo(Metrics.globalRegistry); new ExecutorServiceMetrics( - transitModel.getUpdaterManager().getNonPollingUpdaterPool(), + timetableRepository.getUpdaterManager().getNonPollingUpdaterPool(), "nonPollingGraphUpdaters", List.of(Tag.of("pool", "nonPollingGraphUpdaters")) ) .bindTo(Metrics.globalRegistry); new ExecutorServiceMetrics( - transitModel.getUpdaterManager().getScheduler(), + timetableRepository.getUpdaterManager().getScheduler(), "graphUpdateScheduler", List.of(Tag.of("pool", "graphUpdateScheduler")) ) diff --git a/src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java b/application/src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java rename to application/src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java diff --git a/src/main/java/org/opentripplanner/standalone/server/OTPWebApplicationParameters.java b/application/src/main/java/org/opentripplanner/standalone/server/OTPWebApplicationParameters.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/server/OTPWebApplicationParameters.java rename to application/src/main/java/org/opentripplanner/standalone/server/OTPWebApplicationParameters.java diff --git a/src/main/java/org/opentripplanner/standalone/server/RequestTraceFilter.java b/application/src/main/java/org/opentripplanner/standalone/server/RequestTraceFilter.java similarity index 99% rename from src/main/java/org/opentripplanner/standalone/server/RequestTraceFilter.java rename to application/src/main/java/org/opentripplanner/standalone/server/RequestTraceFilter.java index 8ee2e6bbd27..31d2745913b 100644 --- a/src/main/java/org/opentripplanner/standalone/server/RequestTraceFilter.java +++ b/application/src/main/java/org/opentripplanner/standalone/server/RequestTraceFilter.java @@ -12,7 +12,7 @@ import java.util.Random; import java.util.regex.Pattern; import org.opentripplanner.framework.application.LogMDCSupport; -import org.opentripplanner.framework.lang.StringUtils; +import org.opentripplanner.utils.lang.StringUtils; /** * This filter manages OTP request trace parameters. A trace parameter can be read from the diff --git a/src/main/java/org/opentripplanner/standalone/server/RequestTraceParameter.java b/application/src/main/java/org/opentripplanner/standalone/server/RequestTraceParameter.java similarity index 97% rename from src/main/java/org/opentripplanner/standalone/server/RequestTraceParameter.java rename to application/src/main/java/org/opentripplanner/standalone/server/RequestTraceParameter.java index 98abe8c8091..6e1b3286dcc 100644 --- a/src/main/java/org/opentripplanner/standalone/server/RequestTraceParameter.java +++ b/application/src/main/java/org/opentripplanner/standalone/server/RequestTraceParameter.java @@ -1,6 +1,6 @@ package org.opentripplanner.standalone.server; -import org.opentripplanner.framework.lang.StringUtils; +import org.opentripplanner.utils.lang.StringUtils; /** * OTP supports tracing user requests across log events and "outside" services. It does so by diff --git a/src/main/java/org/opentripplanner/standalone/server/VaryRequestFilter.java b/application/src/main/java/org/opentripplanner/standalone/server/VaryRequestFilter.java similarity index 100% rename from src/main/java/org/opentripplanner/standalone/server/VaryRequestFilter.java rename to application/src/main/java/org/opentripplanner/standalone/server/VaryRequestFilter.java diff --git a/src/main/java/org/opentripplanner/street/model/RentalFormFactor.java b/application/src/main/java/org/opentripplanner/street/model/RentalFormFactor.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/RentalFormFactor.java rename to application/src/main/java/org/opentripplanner/street/model/RentalFormFactor.java diff --git a/src/main/java/org/opentripplanner/street/model/RentalRestrictionExtension.java b/application/src/main/java/org/opentripplanner/street/model/RentalRestrictionExtension.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/RentalRestrictionExtension.java rename to application/src/main/java/org/opentripplanner/street/model/RentalRestrictionExtension.java diff --git a/src/main/java/org/opentripplanner/street/model/RepeatingTimePeriod.java b/application/src/main/java/org/opentripplanner/street/model/RepeatingTimePeriod.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/RepeatingTimePeriod.java rename to application/src/main/java/org/opentripplanner/street/model/RepeatingTimePeriod.java diff --git a/src/main/java/org/opentripplanner/street/model/StreetConstants.java b/application/src/main/java/org/opentripplanner/street/model/StreetConstants.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/StreetConstants.java rename to application/src/main/java/org/opentripplanner/street/model/StreetConstants.java diff --git a/src/main/java/org/opentripplanner/street/model/StreetLimitationParameters.java b/application/src/main/java/org/opentripplanner/street/model/StreetLimitationParameters.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/StreetLimitationParameters.java rename to application/src/main/java/org/opentripplanner/street/model/StreetLimitationParameters.java diff --git a/src/main/java/org/opentripplanner/street/model/StreetTraversalPermission.java b/application/src/main/java/org/opentripplanner/street/model/StreetTraversalPermission.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/StreetTraversalPermission.java rename to application/src/main/java/org/opentripplanner/street/model/StreetTraversalPermission.java diff --git a/src/main/java/org/opentripplanner/street/model/TurnRestriction.java b/application/src/main/java/org/opentripplanner/street/model/TurnRestriction.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/TurnRestriction.java rename to application/src/main/java/org/opentripplanner/street/model/TurnRestriction.java diff --git a/src/main/java/org/opentripplanner/street/model/TurnRestrictionType.java b/application/src/main/java/org/opentripplanner/street/model/TurnRestrictionType.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/TurnRestrictionType.java rename to application/src/main/java/org/opentripplanner/street/model/TurnRestrictionType.java diff --git a/src/main/java/org/opentripplanner/street/model/edge/AreaEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/AreaEdge.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/edge/AreaEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/AreaEdge.java diff --git a/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeBuilder.java b/application/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/edge/AreaEdgeBuilder.java rename to application/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeBuilder.java diff --git a/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeList.java b/application/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeList.java similarity index 94% rename from src/main/java/org/opentripplanner/street/model/edge/AreaEdgeList.java rename to application/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeList.java index 09eb347ac5d..1f8d286995b 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeList.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeList.java @@ -7,7 +7,6 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Polygon; import org.opentripplanner.street.model.vertex.IntersectionVertex; @@ -60,7 +59,6 @@ public Geometry getGeometry() { /** * Returns the list of visibility vertices. */ - @Nonnull public Set visibilityVertices() { return visibilityVertices; } @@ -68,7 +66,7 @@ public Set visibilityVertices() { /** * Add a visibility vertex to this edge. */ - public void addVisibilityVertex(@Nonnull IntersectionVertex toBeAdded) { + public void addVisibilityVertex(IntersectionVertex toBeAdded) { Objects.requireNonNull(toBeAdded); synchronized (this) { if (visibilityVertices == EMPTY_SET) { diff --git a/src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java diff --git a/src/main/java/org/opentripplanner/street/model/edge/BoardingLocationToStopLink.java b/application/src/main/java/org/opentripplanner/street/model/edge/BoardingLocationToStopLink.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/edge/BoardingLocationToStopLink.java rename to application/src/main/java/org/opentripplanner/street/model/edge/BoardingLocationToStopLink.java diff --git a/src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java diff --git a/src/main/java/org/opentripplanner/street/model/edge/Edge.java b/application/src/main/java/org/opentripplanner/street/model/edge/Edge.java similarity index 87% rename from src/main/java/org/opentripplanner/street/model/edge/Edge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/Edge.java index 00130265cf4..31bff5b1e15 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/Edge.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/Edge.java @@ -5,6 +5,8 @@ import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Objects; +import java.util.function.Consumer; +import javax.annotation.Nullable; import org.locationtech.jts.geom.LineString; import org.opentripplanner.astar.spi.AStarEdge; import org.opentripplanner.framework.i18n.I18NString; @@ -99,8 +101,28 @@ public int hashCode() { return Objects.hash(fromv, tov); } + @Override public String toString() { - return String.format("%s (%s -> %s)", getClass().getName(), fromv, tov); + return buildToString(null, b -> {}); + } + + /** + * Use this to construct a {@code toString()} in derived classes. The result will be: + * {@code "%simple-class-name%(%name%, %fromv% -> %tov%" + body + ")"}. Note! There is no space + * between {@code tov} and {@code body}. Both name and body are optional. + * + * @param name Will add name to the string if not null. + * @param body Use this callback to add local content. + */ + protected String buildToString(@Nullable String name, Consumer body) { + var buf = new StringBuilder(); + buf.append(getClass().getSimpleName()).append("("); + if (name != null) { + buf.append(name).append(", "); + } + buf.append(fromv).append(" -> ").append(tov); + body.accept(buf); + return buf.append(')').toString(); } /** diff --git a/src/main/java/org/opentripplanner/street/model/edge/ElevatorAlightEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/ElevatorAlightEdge.java similarity index 94% rename from src/main/java/org/opentripplanner/street/model/edge/ElevatorAlightEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/ElevatorAlightEdge.java index 26b2fc622ba..ca3b0b4b0f7 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/ElevatorAlightEdge.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/ElevatorAlightEdge.java @@ -1,6 +1,5 @@ package org.opentripplanner.street.model.edge; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.LineString; import org.opentripplanner.framework.geometry.GeometryUtils; @@ -56,12 +55,7 @@ public static ElevatorAlightEdge createElevatorAlightEdge( return connectToGraph(new ElevatorAlightEdge(from, to, level)); } - public String toString() { - return "ElevatorAlightEdge(" + fromv + " -> " + tov + ")"; - } - @Override - @Nonnull public State[] traverse(State s0) { StateEditor s1 = createEditorForDrivingOrWalking(s0, this); s1.incrementWeight(1); diff --git a/src/main/java/org/opentripplanner/street/model/edge/ElevatorBoardEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/ElevatorBoardEdge.java similarity index 90% rename from src/main/java/org/opentripplanner/street/model/edge/ElevatorBoardEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/ElevatorBoardEdge.java index 624867fa4eb..9bf0d67afa5 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/ElevatorBoardEdge.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/ElevatorBoardEdge.java @@ -1,13 +1,11 @@ package org.opentripplanner.street.model.edge; import java.util.List; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.LineString; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.street.model.vertex.ElevatorOffboardVertex; import org.opentripplanner.street.model.vertex.ElevatorOnboardVertex; import org.opentripplanner.street.search.state.State; @@ -42,12 +40,6 @@ public static ElevatorBoardEdge createElevatorBoardEdge( } @Override - public String toString() { - return ToStringBuilder.of(this.getClass()).addObj("from", fromv).addObj("to", tov).toString(); - } - - @Override - @Nonnull public State[] traverse(State s0) { StateEditor s1 = createEditorForDrivingOrWalking(s0, this); if (s1 == null) { diff --git a/src/main/java/org/opentripplanner/street/model/edge/ElevatorEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/ElevatorEdge.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/edge/ElevatorEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/ElevatorEdge.java diff --git a/src/main/java/org/opentripplanner/street/model/edge/ElevatorHopEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/ElevatorHopEdge.java similarity index 94% rename from src/main/java/org/opentripplanner/street/model/edge/ElevatorHopEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/ElevatorHopEdge.java index 0029b31f117..75eddb53777 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/ElevatorHopEdge.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/ElevatorHopEdge.java @@ -1,8 +1,6 @@ package org.opentripplanner.street.model.edge; -import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.api.request.preference.RoutingPreferences; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model.vertex.Vertex; @@ -101,12 +99,6 @@ public StreetTraversalPermission getPermission() { } @Override - public String toString() { - return ToStringBuilder.of(this.getClass()).addObj("from", fromv).addObj("to", tov).toString(); - } - - @Override - @Nonnull public State[] traverse(State s0) { RoutingPreferences preferences = s0.getPreferences(); diff --git a/src/main/java/org/opentripplanner/street/model/edge/EscalatorEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/EscalatorEdge.java similarity index 87% rename from src/main/java/org/opentripplanner/street/model/edge/EscalatorEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/EscalatorEdge.java index 11a31aeb86d..20fae657c78 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/EscalatorEdge.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/EscalatorEdge.java @@ -1,6 +1,7 @@ package org.opentripplanner.street.model.edge; -import javax.annotation.Nonnull; +import org.locationtech.jts.geom.LineString; +import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.LocalizedString; import org.opentripplanner.street.model.vertex.Vertex; @@ -22,7 +23,6 @@ private EscalatorEdge(Vertex v1, Vertex v2, double length) { this.length = length; } - @Nonnull @Override public State[] traverse(State s0) { // Only allow traversal by walking @@ -36,6 +36,11 @@ public State[] traverse(State s0) { } else return State.empty(); } + @Override + public LineString getGeometry() { + return GeometryUtils.makeLineString(fromv.getCoordinate(), tov.getCoordinate()); + } + @Override public double getDistanceMeters() { return length; diff --git a/src/main/java/org/opentripplanner/street/model/edge/FreeEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/FreeEdge.java similarity index 87% rename from src/main/java/org/opentripplanner/street/model/edge/FreeEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/FreeEdge.java index 9fbc69af126..3b1631211ff 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/FreeEdge.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/FreeEdge.java @@ -1,6 +1,5 @@ package org.opentripplanner.street.model.edge; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.LineString; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.street.model.vertex.Vertex; @@ -23,12 +22,7 @@ public static FreeEdge createFreeEdge(Vertex from, Vertex to) { return connectToGraph(new FreeEdge(from, to)); } - public String toString() { - return "FreeEdge(" + fromv + " -> " + tov + ")"; - } - @Override - @Nonnull public State[] traverse(State s0) { StateEditor s1 = s0.edit(this); s1.incrementWeight(1); diff --git a/src/main/java/org/opentripplanner/street/model/edge/NamedArea.java b/application/src/main/java/org/opentripplanner/street/model/edge/NamedArea.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/edge/NamedArea.java rename to application/src/main/java/org/opentripplanner/street/model/edge/NamedArea.java diff --git a/src/main/java/org/opentripplanner/street/model/edge/PathwayEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/PathwayEdge.java similarity index 99% rename from src/main/java/org/opentripplanner/street/model/edge/PathwayEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/PathwayEdge.java index 587b25a6704..703658fdda4 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/PathwayEdge.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/PathwayEdge.java @@ -2,7 +2,6 @@ import java.util.Objects; import java.util.Optional; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.LineString; @@ -103,7 +102,6 @@ public static PathwayEdge createPathwayEdge( } @Override - @Nonnull public State[] traverse(State s0) { StateEditor s1 = createEditorForWalking(s0, this); if (s1 == null) { diff --git a/src/main/java/org/opentripplanner/street/model/edge/SplitStreetEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/SplitStreetEdge.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/edge/SplitStreetEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/SplitStreetEdge.java diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java similarity index 93% rename from src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java index ca33396b0a3..ee24e87f07c 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java @@ -2,14 +2,16 @@ import java.io.IOException; import java.io.ObjectOutputStream; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.stream.Stream; -import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.locationtech.jts.geom.LineString; import org.locationtech.jts.geom.impl.PackedCoordinateSequence; import org.opentripplanner.framework.geometry.CompactLineStringUtils; @@ -18,8 +20,6 @@ import org.opentripplanner.framework.geometry.SphericalDistanceLibrary; import org.opentripplanner.framework.geometry.SplitLineString; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.lang.BitSetUtils; -import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.routing.api.request.preference.RoutingPreferences; import org.opentripplanner.routing.linking.DisposableEdgeCollection; import org.opentripplanner.routing.linking.LinkingDirection; @@ -37,6 +37,8 @@ import org.opentripplanner.street.search.state.State; import org.opentripplanner.street.search.state.StateEditor; import org.opentripplanner.street.search.state.VehicleRentalState; +import org.opentripplanner.utils.lang.BitSetUtils; +import org.opentripplanner.utils.lang.IntUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -308,20 +310,17 @@ public double getEffectiveWalkSafetyDistance() { } public String toString() { - return ( - "StreetEdge(" + - name + - ", " + - fromv + - " -> " + - tov + - " length=" + - this.getDistanceMeters() + - " carSpeed=" + - this.getCarSpeed() + - " permission=" + - this.getPermission() + - ")" + var nameString = name != null ? name.toString() : null; + return buildToString( + nameString, + b -> + b + .append(", length=") + .append(this.getDistanceMeters()) + .append(", carSpeed=") + .append(this.getCarSpeed()) + .append(", permission=") + .append(this.getPermission()) ); } @@ -330,7 +329,6 @@ public boolean isRoundabout() { } @Override - @Nonnull public State[] traverse(State s0) { final StateEditor editor; @@ -858,7 +856,6 @@ public void removeTurnRestrictionsTo(Edge other) { * This method is thread-safe, even if {@link StreetEdge#addTurnRestriction} or * {@link StreetEdge#removeTurnRestriction} is called concurrently. */ - @Nonnull public List getTurnRestrictions() { // this can be safely returned as it's unmodifiable return turnRestrictions; @@ -982,6 +979,47 @@ static int defaultMillimeterLength(LineString geometry) { return (int) (SphericalDistanceLibrary.length(geometry) * 1000); } + /** + * Helper method for {@link #splitStatesAfterHavingExitedNoDropOffZoneWhenReverseSearching}. + * Create a single new state, exiting a no-drop-off zone, in reverse, and continuing + * on a rental vehicle in the known network, or an unknown network if network is null, + * unless the known network is not accepted by the provided {@link RoutingPreferences}. + * @param s0 The parent state (i.e. the following state, as we are in reverse) + * @param network Network id, or null if unknown + * @param preferences Active {@link RoutingPreferences} + * @return Newly generated {@link State}, or null if the state would have been forbidden. + */ + private State createStateAfterHavingExitedNoDropOffZoneWhenReverseSearching( + State s0, + String network, + RoutingPreferences preferences + ) { + var edit = doTraverse(s0, TraverseMode.WALK, false); + if (edit != null) { + edit.dropFloatingVehicle(s0.vehicleRentalFormFactor(), network, s0.getRequest().arriveBy()); + if (network != null) { + edit.resetStartedInNoDropOffZone(); + } + State state = edit.makeState(); + if (state != null && network != null) { + var rentalPreferences = preferences.rental(state.currentMode()); + var allowedNetworks = rentalPreferences.allowedNetworks(); + var bannedNetworks = rentalPreferences.bannedNetworks(); + if (allowedNetworks.isEmpty()) { + if (bannedNetworks.contains(network)) { + return null; + } + } else { + if (!allowedNetworks.contains(network)) { + return null; + } + } + } + return state; + } + return null; + } + /** * A very special case: an arriveBy rental search has started in a no-drop-off zone * we don't know yet which rental network we will end up using. @@ -992,27 +1030,39 @@ static int defaultMillimeterLength(LineString geometry) { * When we then leave the no drop off zone on foot we generate a state for each network that the * zone applies to where we pick up a vehicle with a specific network. */ - @Nonnull private State[] splitStatesAfterHavingExitedNoDropOffZoneWhenReverseSearching(State s0) { - var networks = Stream.concat( - // null is a special rental network that speculatively assumes that you can take any vehicle - // you have to check in the rental edge if this has search has been started in a no-drop off zone - Stream.of((String) null), - tov.rentalRestrictions().noDropOffNetworks().stream() - ); + var preferences = s0.getRequest().preferences(); + var states = new ArrayList(); + + // Also include a state which continues walking, because the vehicle rental states are + // speculation. It is possible that the rental states don't end up at the target at all + // due to mode limitations or not finding a place to pick up the rental vehicle, or that + // the rental possibility is simply more expensive than walking. + StateEditor walking = doTraverse(s0, TraverseMode.WALK, false); + if (walking != null) { + states.add(walking.makeState()); + } - var states = networks.map(network -> { - var edit = doTraverse(s0, TraverseMode.WALK, false); - if (edit != null) { - edit.dropFloatingVehicle(s0.vehicleRentalFormFactor(), network, s0.getRequest().arriveBy()); - if (network != null) { - edit.resetStartedInNoDropOffZone(); - } - return edit.makeState(); + boolean hasNetworkStates = false; + for (var network : tov.rentalRestrictions().noDropOffNetworks()) { + var state = createStateAfterHavingExitedNoDropOffZoneWhenReverseSearching( + s0, + network, + preferences + ); + if (state != null) { + states.add(state); + hasNetworkStates = true; } - return null; - }); - return State.ofStream(states); + } + if (hasNetworkStates) { + // null is a special rental network that speculatively assumes that you can take any vehicle + // you have to check in the rental edge if this has search has been started in a no-drop off zone + states.add( + createStateAfterHavingExitedNoDropOffZoneWhenReverseSearching(s0, null, preferences) + ); + } + return states.toArray(State[]::new); } /** @@ -1194,7 +1244,6 @@ private StateEditor doTraverse(State s0, TraverseMode traverseMode, boolean walk return s1; } - @Nonnull private TraversalCosts otherTraversalCosts( RoutingPreferences preferences, TraverseMode traverseMode, @@ -1213,7 +1262,6 @@ private TraversalCosts otherTraversalCosts( return new TraversalCosts(time, weight); } - @Nonnull private TraversalCosts bicycleOrScooterTraversalCost( RoutingPreferences pref, TraverseMode mode, @@ -1258,7 +1306,6 @@ private TraversalCosts bicycleOrScooterTraversalCost( return new TraversalCosts(time, weight); } - @Nonnull private TraversalCosts walkingTraversalCosts( RoutingPreferences preferences, TraverseMode traverseMode, diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeBuilder.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeBuilder.java similarity index 99% rename from src/main/java/org/opentripplanner/street/model/edge/StreetEdgeBuilder.java rename to application/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeBuilder.java index b3173b7bed5..99a02205eb6 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeBuilder.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeBuilder.java @@ -14,10 +14,10 @@ import org.locationtech.jts.geom.LineString; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.framework.lang.BitSetUtils; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.street.search.TraverseMode; +import org.opentripplanner.utils.lang.BitSetUtils; public class StreetEdgeBuilder> { diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeCostExtension.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeCostExtension.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/edge/StreetEdgeCostExtension.java rename to application/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeCostExtension.java diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java rename to application/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetElevationExtension.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetElevationExtension.java similarity index 98% rename from src/main/java/org/opentripplanner/street/model/edge/StreetElevationExtension.java rename to application/src/main/java/org/opentripplanner/street/model/edge/StreetElevationExtension.java index 65ab72093ef..d741fb0a763 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetElevationExtension.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/StreetElevationExtension.java @@ -3,7 +3,7 @@ import java.io.Serializable; import org.locationtech.jts.geom.impl.PackedCoordinateSequence; import org.opentripplanner.framework.geometry.CompactElevationProfile; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; public class StreetElevationExtension implements Serializable { diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetElevationExtensionBuilder.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetElevationExtensionBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/edge/StreetElevationExtensionBuilder.java rename to application/src/main/java/org/opentripplanner/street/model/edge/StreetElevationExtensionBuilder.java diff --git a/application/src/main/java/org/opentripplanner/street/model/edge/StreetStationCentroidLink.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetStationCentroidLink.java new file mode 100644 index 00000000000..6b336907db5 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/street/model/edge/StreetStationCentroidLink.java @@ -0,0 +1,32 @@ +package org.opentripplanner.street.model.edge; + +import org.opentripplanner.street.model.vertex.StationCentroidVertex; +import org.opentripplanner.street.model.vertex.StreetVertex; + +/** + * This represents the connection between a street vertex and a transit station centroid vertex + */ +public class StreetStationCentroidLink extends FreeEdge { + + private StreetStationCentroidLink(StreetVertex fromv, StationCentroidVertex tov) { + super(fromv, tov); + } + + private StreetStationCentroidLink(StationCentroidVertex fromv, StreetVertex tov) { + super(fromv, tov); + } + + public static StreetStationCentroidLink createStreetStationLink( + StreetVertex fromv, + StationCentroidVertex tov + ) { + return connectToGraph(new StreetStationCentroidLink(fromv, tov)); + } + + public static StreetStationCentroidLink createStreetStationLink( + StationCentroidVertex fromv, + StreetVertex tov + ) { + return connectToGraph(new StreetStationCentroidLink(fromv, tov)); + } +} diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java similarity index 96% rename from src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java rename to application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java index dabd70bf28d..5a62eda0f90 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java @@ -1,11 +1,9 @@ package org.opentripplanner.street.model.edge; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.LineString; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.api.request.preference.RoutingPreferences; import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.street.model.vertex.Vertex; @@ -46,12 +44,7 @@ protected StreetTransitEntityLink( this.wheelchairAccessibility = wheelchairAccessibility; } - public String toString() { - return ToStringBuilder.of(this.getClass()).addObj("from", fromv).addObj("to", tov).toString(); - } - @Override - @Nonnull public State[] traverse(State s0) { // Forbid taking shortcuts composed of two street-transit links associated with the same stop in a row. Also // avoids spurious leg transitions. As noted in https://github.com/opentripplanner/OpenTripPlanner/issues/2815, @@ -135,7 +128,6 @@ else if ( }; } - @Nonnull private State[] buildState(State s0, StateEditor s1, RoutingPreferences pref) { if (s0.isRentingVehicleFromStation() && s0.mayKeepRentedVehicleAtDestination()) { var rentalPreferences = s0.getRequest().preferences().rental(s0.getRequest().mode()); diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntranceLink.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntranceLink.java similarity index 92% rename from src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntranceLink.java rename to application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntranceLink.java index 07b918159a7..7145f6183e4 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntranceLink.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntranceLink.java @@ -43,10 +43,6 @@ public boolean isExit() { return !isEntrance; } - public String toString() { - return "StreetTransitEntranceLink(" + fromv + " -> " + tov + ")"; - } - protected int getStreetToStopTime() { return 0; } diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetTransitStopLink.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitStopLink.java similarity index 92% rename from src/main/java/org/opentripplanner/street/model/edge/StreetTransitStopLink.java rename to application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitStopLink.java index 41605be4ccc..a7ce1c0e2df 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetTransitStopLink.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitStopLink.java @@ -36,8 +36,4 @@ protected int getStreetToStopTime() { ? 0 : getTransitEntityVertex().getStreetToStopTime(); } - - public String toString() { - return "StreetTransitStopLink(" + fromv + " -> " + tov + ")"; - } } diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLink.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLink.java similarity index 90% rename from src/main/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLink.java rename to application/src/main/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLink.java index 2ad9d0f39c4..ac046dd45df 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLink.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLink.java @@ -1,12 +1,10 @@ package org.opentripplanner.street.model.edge; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.LineString; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex; import org.opentripplanner.street.search.TraverseMode; @@ -45,12 +43,6 @@ public static StreetVehicleParkingLink createStreetVehicleParkingLink( } @Override - public String toString() { - return ToStringBuilder.of(this.getClass()).addObj("fromv", fromv).addObj("tov", tov).toString(); - } - - @Override - @Nonnull public State[] traverse(State s0) { // Disallow traversing two StreetBikeParkLinks in a row. // Prevents router using bike rental stations as shortcuts to get around diff --git a/src/main/java/org/opentripplanner/street/model/edge/TemporaryEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/TemporaryEdge.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/edge/TemporaryEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/TemporaryEdge.java diff --git a/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java similarity index 92% rename from src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java index e93c6523d89..7b114cfeade 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java @@ -1,6 +1,5 @@ package org.opentripplanner.street.model.edge; -import javax.annotation.Nonnull; import org.opentripplanner.street.model.vertex.TemporaryVertex; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.search.state.State; @@ -31,12 +30,6 @@ public static TemporaryFreeEdge createTemporaryFreeEdge(Vertex from, TemporaryVe } @Override - public String toString() { - return "Temporary" + super.toString(); - } - - @Override - @Nonnull public State[] traverse(State s0) { StateEditor s1 = s0.edit(this); s1.incrementWeight(1); diff --git a/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdge.java similarity index 87% rename from src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdge.java index 8c797f1f492..31792614cde 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdge.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdge.java @@ -55,20 +55,10 @@ public StreetEdge getParentEdge() { @Override public String toString() { - return ( - "TemporaryPartialStreetEdge(" + - this.getDefaultName() + - ", " + - this.getFromVertex() + - " -> " + - this.getToVertex() + - " length=" + - this.getDistanceMeters() + - " carSpeed=" + - this.getCarSpeed() + - " parentEdge=" + - parentEdge + - ")" + return buildToString( + this.getDefaultName(), + b -> + b.append(", length=").append(this.getCarSpeed()).append(", parentEdge=").append(parentEdge) ); } diff --git a/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeBuilder.java b/application/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeBuilder.java rename to application/src/main/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeBuilder.java diff --git a/src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java similarity index 96% rename from src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java rename to application/src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java index d32f13d6ea4..a7aa7bb2535 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java @@ -1,7 +1,6 @@ package org.opentripplanner.street.model.edge; import java.time.Duration; -import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.routing.api.request.StreetMode; @@ -9,7 +8,7 @@ import org.opentripplanner.routing.api.request.preference.CarPreferences; import org.opentripplanner.routing.api.request.preference.RoutingPreferences; import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.request.StreetSearchRequest; @@ -62,12 +61,7 @@ public boolean equals(Object o) { return false; } - public String toString() { - return "VehicleParkingEdge(" + fromv + " -> " + tov + ")"; - } - @Override - @Nonnull public State[] traverse(State s0) { if (!s0.getRequest().mode().includesParking()) { return State.empty(); diff --git a/src/main/java/org/opentripplanner/street/model/edge/WheelchairTraversalInformation.java b/application/src/main/java/org/opentripplanner/street/model/edge/WheelchairTraversalInformation.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/edge/WheelchairTraversalInformation.java rename to application/src/main/java/org/opentripplanner/street/model/edge/WheelchairTraversalInformation.java diff --git a/src/main/java/org/opentripplanner/street/model/elevation/ElevationUtils.java b/application/src/main/java/org/opentripplanner/street/model/elevation/ElevationUtils.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/elevation/ElevationUtils.java rename to application/src/main/java/org/opentripplanner/street/model/elevation/ElevationUtils.java diff --git a/src/main/java/org/opentripplanner/street/model/note/StreetNote.java b/application/src/main/java/org/opentripplanner/street/model/note/StreetNote.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/note/StreetNote.java rename to application/src/main/java/org/opentripplanner/street/model/note/StreetNote.java diff --git a/src/main/java/org/opentripplanner/street/model/note/StreetNoteAndMatcher.java b/application/src/main/java/org/opentripplanner/street/model/note/StreetNoteAndMatcher.java similarity index 94% rename from src/main/java/org/opentripplanner/street/model/note/StreetNoteAndMatcher.java rename to application/src/main/java/org/opentripplanner/street/model/note/StreetNoteAndMatcher.java index 84d775aca3b..953645c46bc 100644 --- a/src/main/java/org/opentripplanner/street/model/note/StreetNoteAndMatcher.java +++ b/application/src/main/java/org/opentripplanner/street/model/note/StreetNoteAndMatcher.java @@ -2,7 +2,7 @@ import java.io.Serializable; import java.util.Objects; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A container for a pair (note and note matcher). diff --git a/src/main/java/org/opentripplanner/street/model/note/StreetNoteMatcher.java b/application/src/main/java/org/opentripplanner/street/model/note/StreetNoteMatcher.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/note/StreetNoteMatcher.java rename to application/src/main/java/org/opentripplanner/street/model/note/StreetNoteMatcher.java diff --git a/src/main/java/org/opentripplanner/street/model/vertex/BarrierVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/BarrierVertex.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/vertex/BarrierVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/BarrierVertex.java diff --git a/src/main/java/org/opentripplanner/street/model/vertex/ElevatorOffboardVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/ElevatorOffboardVertex.java similarity index 94% rename from src/main/java/org/opentripplanner/street/model/vertex/ElevatorOffboardVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/ElevatorOffboardVertex.java index 7fd66d8a759..89148bc6ace 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/ElevatorOffboardVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/ElevatorOffboardVertex.java @@ -1,6 +1,5 @@ package org.opentripplanner.street.model.vertex; -import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; public class ElevatorOffboardVertex extends StreetVertex { @@ -20,7 +19,6 @@ public VertexLabel getLabel() { return VertexLabel.string(LABEL_TEMPLATE.formatted(label, level)); } - @Nonnull @Override public I18NString getName() { return I18NString.of(label); diff --git a/src/main/java/org/opentripplanner/street/model/vertex/ElevatorOnboardVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/ElevatorOnboardVertex.java similarity index 94% rename from src/main/java/org/opentripplanner/street/model/vertex/ElevatorOnboardVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/ElevatorOnboardVertex.java index 5999b293ce7..5f6f19e2dab 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/ElevatorOnboardVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/ElevatorOnboardVertex.java @@ -1,6 +1,5 @@ package org.opentripplanner.street.model.vertex; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.framework.i18n.I18NString; @@ -21,7 +20,6 @@ public VertexLabel getLabel() { return VertexLabel.string(LABEL_TEMPLATE.formatted(label, level)); } - @Nonnull @Override public I18NString getName() { return I18NString.of(label); diff --git a/src/main/java/org/opentripplanner/street/model/vertex/ExitVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/ExitVertex.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/vertex/ExitVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/ExitVertex.java diff --git a/src/main/java/org/opentripplanner/street/model/vertex/IntersectionVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/IntersectionVertex.java similarity index 97% rename from src/main/java/org/opentripplanner/street/model/vertex/IntersectionVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/IntersectionVertex.java index baea576a85f..2a8582cbaab 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/IntersectionVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/IntersectionVertex.java @@ -1,6 +1,6 @@ package org.opentripplanner.street.model.vertex; -import org.opentripplanner.framework.lang.BitSetUtils; +import org.opentripplanner.utils.lang.BitSetUtils; /** * Represents an ordinary location in space, typically an intersection. diff --git a/src/main/java/org/opentripplanner/street/model/vertex/LabelledIntersectionVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/LabelledIntersectionVertex.java similarity index 91% rename from src/main/java/org/opentripplanner/street/model/vertex/LabelledIntersectionVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/LabelledIntersectionVertex.java index c32ac19fd89..ecb82b43008 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/LabelledIntersectionVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/LabelledIntersectionVertex.java @@ -1,6 +1,5 @@ package org.opentripplanner.street.model.vertex; -import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; /** @@ -12,7 +11,7 @@ public class LabelledIntersectionVertex extends IntersectionVertex { private final String label; public LabelledIntersectionVertex( - @Nonnull String label, + String label, double x, double y, boolean hasHighwayTrafficLight, @@ -27,7 +26,6 @@ public VertexLabel getLabel() { return VertexLabel.string(label); } - @Nonnull @Override public I18NString getName() { return I18NString.of(label); diff --git a/src/main/java/org/opentripplanner/street/model/vertex/OsmBoardingLocationVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/OsmBoardingLocationVertex.java similarity index 92% rename from src/main/java/org/opentripplanner/street/model/vertex/OsmBoardingLocationVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/OsmBoardingLocationVertex.java index 606c27ef4b2..8d89ebbe8e0 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/OsmBoardingLocationVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/OsmBoardingLocationVertex.java @@ -3,10 +3,9 @@ import java.util.Collection; import java.util.Objects; import java.util.Set; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A vertex for an OSM node that represents a transit stop and has a tag to cross-reference this to @@ -44,7 +43,6 @@ public boolean isConnectedToStreetNetwork() { return (getOutgoing().size() + getIncoming().size()) > 0; } - @Nonnull @Override public I18NString getName() { return name; diff --git a/src/main/java/org/opentripplanner/street/model/vertex/OsmVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/OsmVertex.java similarity index 95% rename from src/main/java/org/opentripplanner/street/model/vertex/OsmVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/OsmVertex.java index e4784e6edb9..39d195f695e 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/OsmVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/OsmVertex.java @@ -1,6 +1,5 @@ package org.opentripplanner.street.model.vertex; -import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; /** @@ -29,7 +28,6 @@ public OsmVertex( this.nodeId = nodeId; } - @Nonnull @Override public I18NString getName() { return NO_NAME; diff --git a/src/main/java/org/opentripplanner/street/model/vertex/OsmVertexOnLevel.java b/application/src/main/java/org/opentripplanner/street/model/vertex/OsmVertexOnLevel.java similarity index 83% rename from src/main/java/org/opentripplanner/street/model/vertex/OsmVertexOnLevel.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/OsmVertexOnLevel.java index 35457c4eb04..c96878e228a 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/OsmVertexOnLevel.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/OsmVertexOnLevel.java @@ -1,6 +1,6 @@ package org.opentripplanner.street.model.vertex; -import org.opentripplanner.openstreetmap.model.OSMNode; +import org.opentripplanner.osm.model.OsmNode; /** * A vertex that represents an OSM node in conjunction with its level tag like both ends of an @@ -12,7 +12,7 @@ public class OsmVertexOnLevel extends OsmVertex { private final String level; - public OsmVertexOnLevel(OSMNode node, String level) { + public OsmVertexOnLevel(OsmNode node, String level) { super(node.getCoordinate().x, node.getCoordinate().y, node.getId()); this.level = level; } diff --git a/src/main/java/org/opentripplanner/street/model/vertex/SplitterVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/SplitterVertex.java similarity index 95% rename from src/main/java/org/opentripplanner/street/model/vertex/SplitterVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/SplitterVertex.java index 0362f6e1766..c1fc60983e4 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/SplitterVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/SplitterVertex.java @@ -1,6 +1,5 @@ package org.opentripplanner.street.model.vertex; -import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; /** @@ -31,7 +30,6 @@ public boolean inferredFreeFlowing() { return true; } - @Nonnull @Override public I18NString getName() { return name; diff --git a/application/src/main/java/org/opentripplanner/street/model/vertex/StationCentroidVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/StationCentroidVertex.java new file mode 100644 index 00000000000..f6f3b00191d --- /dev/null +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/StationCentroidVertex.java @@ -0,0 +1,33 @@ +package org.opentripplanner.street.model.vertex; + +import javax.annotation.Nonnull; +import org.opentripplanner.framework.i18n.I18NString; +import org.opentripplanner.transit.model.site.Station; + +/** + * A vertex representing a station centroid. This can be used as a source/destination for routing. + */ +public class StationCentroidVertex extends Vertex { + + private final Station station; + + public StationCentroidVertex(Station station) { + super(station.getLon(), station.getLat()); + this.station = station; + } + + public Station getStation() { + return this.station; + } + + @Nonnull + @Override + public I18NString getName() { + return station.getName(); + } + + @Override + public VertexLabel getLabel() { + return VertexLabel.feedScopedId(station.getId()); + } +} diff --git a/src/main/java/org/opentripplanner/street/model/vertex/StationElementVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/StationElementVertex.java similarity index 93% rename from src/main/java/org/opentripplanner/street/model/vertex/StationElementVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/StationElementVertex.java index 0873ca64fc5..63595803300 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/StationElementVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/StationElementVertex.java @@ -1,6 +1,5 @@ package org.opentripplanner.street.model.vertex; -import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.StationElement; @@ -22,12 +21,14 @@ public final VertexLabel getLabel() { } /** Get the corresponding StationElement */ - @Nonnull public abstract StationElement getStationElement(); - @Nonnull @Override public I18NString getName() { return name; } + + public FeedScopedId getId() { + return id; + } } diff --git a/src/main/java/org/opentripplanner/street/model/vertex/StreetLocation.java b/application/src/main/java/org/opentripplanner/street/model/vertex/StreetLocation.java similarity index 97% rename from src/main/java/org/opentripplanner/street/model/vertex/StreetLocation.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/StreetLocation.java index 31b25ec7b7d..44ca1f4db32 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/StreetLocation.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/StreetLocation.java @@ -1,6 +1,5 @@ package org.opentripplanner.street.model.vertex; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.Coordinate; import org.opentripplanner.framework.i18n.I18NString; @@ -42,7 +41,6 @@ public I18NString getIntersectionName() { return getName(); } - @Nonnull @Override public I18NString getName() { return name; diff --git a/src/main/java/org/opentripplanner/street/model/vertex/StreetVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/StreetVertex.java similarity index 96% rename from src/main/java/org/opentripplanner/street/model/vertex/StreetVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/StreetVertex.java index 64438667af8..8b58466a33c 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/StreetVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/StreetVertex.java @@ -8,7 +8,6 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.LocalizedString; import org.opentripplanner.street.model.edge.Edge; @@ -84,7 +83,6 @@ public boolean isEligibleForCarPickupDropoff() { /** * Returns the list of area stops that this vertex is inside of. */ - @Nonnull public Set areaStops() { return areaStops; } @@ -92,7 +90,7 @@ public Set areaStops() { /** * Add a collection of area stops to this vertex. */ - public void addAreaStops(@Nonnull Collection toBeAdded) { + public void addAreaStops(Collection toBeAdded) { Objects.requireNonNull(toBeAdded); synchronized (this) { if (areaStops == EMPTY_SET) { diff --git a/src/main/java/org/opentripplanner/street/model/vertex/TemporarySplitterVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/TemporarySplitterVertex.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/vertex/TemporarySplitterVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/TemporarySplitterVertex.java diff --git a/src/main/java/org/opentripplanner/street/model/vertex/TemporaryStreetLocation.java b/application/src/main/java/org/opentripplanner/street/model/vertex/TemporaryStreetLocation.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/vertex/TemporaryStreetLocation.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/TemporaryStreetLocation.java diff --git a/src/main/java/org/opentripplanner/street/model/vertex/TemporaryVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/TemporaryVertex.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/vertex/TemporaryVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/TemporaryVertex.java diff --git a/src/main/java/org/opentripplanner/street/model/vertex/TemporaryVertexDispose.java b/application/src/main/java/org/opentripplanner/street/model/vertex/TemporaryVertexDispose.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/vertex/TemporaryVertexDispose.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/TemporaryVertexDispose.java diff --git a/src/main/java/org/opentripplanner/street/model/vertex/TransitBoardingAreaVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/TransitBoardingAreaVertex.java similarity index 95% rename from src/main/java/org/opentripplanner/street/model/vertex/TransitBoardingAreaVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/TransitBoardingAreaVertex.java index 3221934c2f6..5654185440a 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/TransitBoardingAreaVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/TransitBoardingAreaVertex.java @@ -1,6 +1,5 @@ package org.opentripplanner.street.model.vertex; -import javax.annotation.Nonnull; import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.site.BoardingArea; import org.opentripplanner.transit.model.site.StationElement; @@ -30,7 +29,6 @@ public boolean isWheelchairAccessible() { return wheelchairAccessible; } - @Nonnull @Override public StationElement getStationElement() { return this.boardingArea; diff --git a/src/main/java/org/opentripplanner/street/model/vertex/TransitEntranceVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/TransitEntranceVertex.java similarity index 95% rename from src/main/java/org/opentripplanner/street/model/vertex/TransitEntranceVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/TransitEntranceVertex.java index 54de400dedb..81b89ad3dfb 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/TransitEntranceVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/TransitEntranceVertex.java @@ -1,6 +1,5 @@ package org.opentripplanner.street.model.vertex; -import javax.annotation.Nonnull; import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.site.Entrance; import org.opentripplanner.transit.model.site.StationElement; @@ -33,7 +32,6 @@ public Entrance getEntrance() { return this.entrance; } - @Nonnull @Override public StationElement getStationElement() { return this.entrance; diff --git a/src/main/java/org/opentripplanner/street/model/vertex/TransitPathwayNodeVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/TransitPathwayNodeVertex.java similarity index 95% rename from src/main/java/org/opentripplanner/street/model/vertex/TransitPathwayNodeVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/TransitPathwayNodeVertex.java index b8cec0ec37c..645ec96b5ea 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/TransitPathwayNodeVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/TransitPathwayNodeVertex.java @@ -1,6 +1,5 @@ package org.opentripplanner.street.model.vertex; -import javax.annotation.Nonnull; import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.site.PathwayNode; import org.opentripplanner.transit.model.site.StationElement; @@ -33,7 +32,6 @@ public PathwayNode getNode() { return this.node; } - @Nonnull @Override public StationElement getStationElement() { return this.node; diff --git a/src/main/java/org/opentripplanner/street/model/vertex/TransitStopVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/TransitStopVertex.java similarity index 98% rename from src/main/java/org/opentripplanner/street/model/vertex/TransitStopVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/TransitStopVertex.java index a9d7d221d44..82c977902b0 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/TransitStopVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/TransitStopVertex.java @@ -2,7 +2,6 @@ import java.util.HashSet; import java.util.Set; -import javax.annotation.Nonnull; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.edge.PathwayEdge; import org.opentripplanner.transit.model.basic.Accessibility; @@ -84,7 +83,6 @@ public RegularStop getStop() { return this.stop; } - @Nonnull @Override public StationElement getStationElement() { return this.stop; diff --git a/src/main/java/org/opentripplanner/street/model/vertex/TransitStopVertexBuilder.java b/application/src/main/java/org/opentripplanner/street/model/vertex/TransitStopVertexBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/vertex/TransitStopVertexBuilder.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/TransitStopVertexBuilder.java diff --git a/src/main/java/org/opentripplanner/street/model/vertex/VehicleParkingEntranceVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/VehicleParkingEntranceVertex.java similarity index 90% rename from src/main/java/org/opentripplanner/street/model/vertex/VehicleParkingEntranceVertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/VehicleParkingEntranceVertex.java index ba7a1540715..9a4e64dc2d6 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/VehicleParkingEntranceVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/VehicleParkingEntranceVertex.java @@ -2,10 +2,9 @@ import java.util.Collection; import java.util.Objects; -import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingEntrance; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingEntrance; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.edge.StreetVehicleParkingLink; import org.opentripplanner.street.model.edge.VehicleParkingEdge; @@ -25,7 +24,6 @@ public VehicleParkingEntranceVertex(VehicleParkingEntrance parkingEntrance) { this.parkingEntrance = parkingEntrance; } - @Nonnull @Override public I18NString getName() { return Objects.requireNonNullElse(parkingEntrance.getName(), NO_NAME); diff --git a/src/main/java/org/opentripplanner/street/model/vertex/Vertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/Vertex.java similarity index 98% rename from src/main/java/org/opentripplanner/street/model/vertex/Vertex.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/Vertex.java index 59407f93ea9..75fd5b7218e 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/Vertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/Vertex.java @@ -8,7 +8,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.Coordinate; import org.opentripplanner.astar.spi.AStarVertex; import org.opentripplanner.framework.geometry.WgsCoordinate; @@ -137,7 +136,6 @@ public final double getLat() { /** * Longer human-readable name for the client */ - @Nonnull public abstract I18NString getName(); /** @@ -163,6 +161,13 @@ public String getLabelString() { return getLabel().toString(); } + /** + * Return the position of the vertex as a WgsCoordinate. + */ + public WgsCoordinate toWgsCoordinate() { + return new WgsCoordinate(y, x); + } + public Coordinate getCoordinate() { return new Coordinate(getX(), getY()); } diff --git a/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java b/application/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java similarity index 90% rename from src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java index c7e38ca0032..422fc16c837 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java @@ -1,20 +1,20 @@ package org.opentripplanner.street.model.vertex; import java.util.Set; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.locationtech.jts.geom.Coordinate; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.openstreetmap.model.OSMNode; +import org.opentripplanner.osm.model.OsmNode; import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingEntrance; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingEntrance; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.transit.model.site.BoardingArea; import org.opentripplanner.transit.model.site.Entrance; import org.opentripplanner.transit.model.site.PathwayNode; +import org.opentripplanner.transit.model.site.Station; /** * This class is the central point where all vertices that are supposed to be permanently part @@ -32,12 +32,10 @@ public VertexFactory(Graph graph) { this.graph = graph; } - @Nonnull public TransitBoardingAreaVertex transitBoardingArea(BoardingArea boardingArea) { return addToGraph(new TransitBoardingAreaVertex(boardingArea)); } - @Nonnull public ElevatorOnboardVertex elevatorOnboard( Vertex sourceVertex, String label, @@ -46,7 +44,6 @@ public ElevatorOnboardVertex elevatorOnboard( return addToGraph(new ElevatorOnboardVertex(sourceVertex, label, levelName)); } - @Nonnull public ElevatorOffboardVertex elevatorOffboard( Vertex sourceVertex, String label, @@ -55,7 +52,6 @@ public ElevatorOffboardVertex elevatorOffboard( return addToGraph(new ElevatorOffboardVertex(sourceVertex, label, levelName)); } - @Nonnull public IntersectionVertex intersection(Coordinate edgeCoordinate) { return addToGraph( new LabelledIntersectionVertex( @@ -68,12 +64,10 @@ public IntersectionVertex intersection(Coordinate edgeCoordinate) { ); } - @Nonnull public IntersectionVertex intersection(String label, double longitude, double latitude) { return addToGraph(new LabelledIntersectionVertex(label, longitude, latitude, false, false)); } - @Nonnull public OsmBoardingLocationVertex osmBoardingLocation( Coordinate coordinate, String label, @@ -83,7 +77,6 @@ public OsmBoardingLocationVertex osmBoardingLocation( return addToGraph(new OsmBoardingLocationVertex(label, coordinate.x, coordinate.y, name, refs)); } - @Nonnull public SplitterVertex splitter( StreetEdge originalEdge, double x, @@ -93,20 +86,17 @@ public SplitterVertex splitter( return addToGraph(new SplitterVertex(uniqueSplitLabel, x, y, originalEdge.getName())); } - @Nonnull public BarrierVertex barrier(long nid, Coordinate coordinate) { return addToGraph(new BarrierVertex(coordinate.x, coordinate.y, nid)); } - @Nonnull public ExitVertex exit(long nid, Coordinate coordinate, String exitName) { return addToGraph(new ExitVertex(coordinate.x, coordinate.y, nid, exitName)); } - @Nonnull public OsmVertex osm( Coordinate coordinate, - OSMNode node, + OsmNode node, boolean highwayTrafficLight, boolean crossingTrafficLight ) { @@ -121,12 +111,14 @@ public OsmVertex osm( ); } - @Nonnull public TransitStopVertex transitStop(TransitStopVertexBuilder transitStopVertexBuilder) { return addToGraph(transitStopVertexBuilder.build()); } - @Nonnull + public StationCentroidVertex stationCentroid(Station station) { + return addToGraph(new StationCentroidVertex(station)); + } + public VehicleParkingEntranceVertex vehicleParkingEntrance(VehicleParking vehicleParking) { return vehicleParkingEntrance(vehicleParking.getEntrances().get(0)); } @@ -135,22 +127,19 @@ public VehicleParkingEntranceVertex vehicleParkingEntrance(VehicleParkingEntranc return addToGraph(new VehicleParkingEntranceVertex(entrance)); } - @Nonnull public VehicleRentalPlaceVertex vehicleRentalPlace(VehicleRentalPlace station) { return addToGraph(new VehicleRentalPlaceVertex(station)); } - @Nonnull public TransitPathwayNodeVertex transitPathwayNode(PathwayNode node) { return addToGraph(new TransitPathwayNodeVertex(node)); } - @Nonnull public TransitEntranceVertex transitEntrance(Entrance entrance) { return addToGraph(new TransitEntranceVertex(entrance)); } - public OsmVertex levelledOsm(OSMNode node, String level) { + public OsmVertex levelledOsm(OsmNode node, String level) { return addToGraph(new OsmVertexOnLevel(node, level)); } diff --git a/src/main/java/org/opentripplanner/street/model/vertex/VertexLabel.java b/application/src/main/java/org/opentripplanner/street/model/vertex/VertexLabel.java similarity index 100% rename from src/main/java/org/opentripplanner/street/model/vertex/VertexLabel.java rename to application/src/main/java/org/opentripplanner/street/model/vertex/VertexLabel.java diff --git a/src/main/java/org/opentripplanner/street/search/StreetSearchBuilder.java b/application/src/main/java/org/opentripplanner/street/search/StreetSearchBuilder.java similarity index 99% rename from src/main/java/org/opentripplanner/street/search/StreetSearchBuilder.java rename to application/src/main/java/org/opentripplanner/street/search/StreetSearchBuilder.java index 079cd29706f..68a71aef0a7 100644 --- a/src/main/java/org/opentripplanner/street/search/StreetSearchBuilder.java +++ b/application/src/main/java/org/opentripplanner/street/search/StreetSearchBuilder.java @@ -3,7 +3,6 @@ import java.time.Duration; import java.util.Collection; import java.util.Set; -import javax.annotation.Nonnull; import org.opentripplanner.astar.AStarBuilder; import org.opentripplanner.astar.spi.DominanceFunction; import org.opentripplanner.astar.spi.RemainingWeightHeuristic; @@ -65,7 +64,6 @@ public StreetSearchBuilder setDataOverlayContext(DataOverlayContext dataOverlayC return this; } - @Nonnull @Override protected Duration streetRoutingTimeout() { return routeRequest.preferences().street().routingTimeout(); diff --git a/src/main/java/org/opentripplanner/street/search/TemporaryVerticesContainer.java b/application/src/main/java/org/opentripplanner/street/search/TemporaryVerticesContainer.java similarity index 74% rename from src/main/java/org/opentripplanner/street/search/TemporaryVerticesContainer.java rename to application/src/main/java/org/opentripplanner/street/search/TemporaryVerticesContainer.java index 3e7ecd2c237..1c6394bfd2f 100644 --- a/src/main/java/org/opentripplanner/street/search/TemporaryVerticesContainer.java +++ b/application/src/main/java/org/opentripplanner/street/search/TemporaryVerticesContainer.java @@ -10,7 +10,6 @@ import org.locationtech.jts.geom.GeometryFactory; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.model.GenericLocation; -import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.api.response.InputField; import org.opentripplanner.routing.api.response.RoutingError; @@ -32,14 +31,16 @@ public class TemporaryVerticesContainer implements AutoCloseable { private final Graph graph; - private final RouteRequest opt; private final Set tempEdges; private final Set fromVertices; private final Set toVertices; + private final GenericLocation from; + private final GenericLocation to; public TemporaryVerticesContainer( Graph graph, - RouteRequest opt, + GenericLocation from, + GenericLocation to, StreetMode accessMode, StreetMode egressMode ) { @@ -47,9 +48,10 @@ public TemporaryVerticesContainer( this.graph = graph; StreetIndex index = this.graph.getStreetIndex(); - this.opt = opt; - fromVertices = index.getVerticesForLocation(opt.from(), accessMode, false, tempEdges); - toVertices = index.getVerticesForLocation(opt.to(), egressMode, true, tempEdges); + this.from = from; + this.to = to; + fromVertices = index.getStreetVerticesForLocation(from, accessMode, false, tempEdges); + toVertices = index.getStreetVerticesForLocation(to, egressMode, true, tempEdges); checkIfVerticesFound(); @@ -80,22 +82,48 @@ public Set getToVertices() { return toVertices; } + /** + * Get the stop vertices that corresponds to the from location. If the from location only contains + * coordinates, this will return an empty set. If the from location is a station id this will + * return the child stops of that station. + */ + public Set getFromStopVertices() { + StreetIndex index = this.graph.getStreetIndex(); + if (from.stopId == null) { + return Set.of(); + } + return index.getStopOrChildStopsVertices(from.stopId); + } + + /** + * Get the stop vertices that corresponds to the to location. If the to location only contains + * coordinates, this will return an empty set. If the to location is a station id this will + * return the child stops of that station. + */ + public Set getToStopVertices() { + StreetIndex index = this.graph.getStreetIndex(); + if (to.stopId == null) { + return Set.of(); + } + return index.getStopOrChildStopsVertices(to.stopId); + } + /* PRIVATE METHODS */ private void checkIfVerticesFound() { List routingErrors = new ArrayList<>(); // check that vertices where found if from-location was specified - if (opt.from().isSpecified() && isDisconnected(fromVertices, true)) { + if (from.isSpecified() && isDisconnected(fromVertices, true)) { routingErrors.add( - new RoutingError(getRoutingErrorCodeForDisconnected(opt.from()), InputField.FROM_PLACE) + new RoutingError(getRoutingErrorCodeForDisconnected(from), InputField.FROM_PLACE) ); } // check that vertices where found if to-location was specified - if (opt.to().isSpecified() && isDisconnected(toVertices, false)) { + if (to.isSpecified() && isDisconnected(toVertices, false)) { routingErrors.add( - new RoutingError(getRoutingErrorCodeForDisconnected(opt.to()), InputField.TO_PLACE) + new RoutingError(getRoutingErrorCodeForDisconnected(to), InputField.TO_PLACE) ); } diff --git a/src/main/java/org/opentripplanner/street/search/TraverseMode.java b/application/src/main/java/org/opentripplanner/street/search/TraverseMode.java similarity index 100% rename from src/main/java/org/opentripplanner/street/search/TraverseMode.java rename to application/src/main/java/org/opentripplanner/street/search/TraverseMode.java diff --git a/src/main/java/org/opentripplanner/street/search/TraverseModeSet.java b/application/src/main/java/org/opentripplanner/street/search/TraverseModeSet.java similarity index 100% rename from src/main/java/org/opentripplanner/street/search/TraverseModeSet.java rename to application/src/main/java/org/opentripplanner/street/search/TraverseModeSet.java diff --git a/src/main/java/org/opentripplanner/street/search/intersection_model/AbstractIntersectionTraversalCalculator.java b/application/src/main/java/org/opentripplanner/street/search/intersection_model/AbstractIntersectionTraversalCalculator.java similarity index 100% rename from src/main/java/org/opentripplanner/street/search/intersection_model/AbstractIntersectionTraversalCalculator.java rename to application/src/main/java/org/opentripplanner/street/search/intersection_model/AbstractIntersectionTraversalCalculator.java diff --git a/src/main/java/org/opentripplanner/street/search/intersection_model/ConstantIntersectionTraversalCalculator.java b/application/src/main/java/org/opentripplanner/street/search/intersection_model/ConstantIntersectionTraversalCalculator.java similarity index 100% rename from src/main/java/org/opentripplanner/street/search/intersection_model/ConstantIntersectionTraversalCalculator.java rename to application/src/main/java/org/opentripplanner/street/search/intersection_model/ConstantIntersectionTraversalCalculator.java diff --git a/src/main/java/org/opentripplanner/street/search/intersection_model/DrivingDirection.java b/application/src/main/java/org/opentripplanner/street/search/intersection_model/DrivingDirection.java similarity index 100% rename from src/main/java/org/opentripplanner/street/search/intersection_model/DrivingDirection.java rename to application/src/main/java/org/opentripplanner/street/search/intersection_model/DrivingDirection.java diff --git a/src/main/java/org/opentripplanner/street/search/intersection_model/IntersectionTraversalCalculator.java b/application/src/main/java/org/opentripplanner/street/search/intersection_model/IntersectionTraversalCalculator.java similarity index 100% rename from src/main/java/org/opentripplanner/street/search/intersection_model/IntersectionTraversalCalculator.java rename to application/src/main/java/org/opentripplanner/street/search/intersection_model/IntersectionTraversalCalculator.java diff --git a/src/main/java/org/opentripplanner/street/search/intersection_model/IntersectionTraversalModel.java b/application/src/main/java/org/opentripplanner/street/search/intersection_model/IntersectionTraversalModel.java similarity index 100% rename from src/main/java/org/opentripplanner/street/search/intersection_model/IntersectionTraversalModel.java rename to application/src/main/java/org/opentripplanner/street/search/intersection_model/IntersectionTraversalModel.java diff --git a/src/main/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculator.java b/application/src/main/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculator.java similarity index 100% rename from src/main/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculator.java rename to application/src/main/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculator.java diff --git a/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequest.java b/application/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequest.java similarity index 98% rename from src/main/java/org/opentripplanner/street/search/request/StreetSearchRequest.java rename to application/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequest.java index c33ed6a35e9..df8933cd22d 100644 --- a/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequest.java +++ b/application/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequest.java @@ -1,7 +1,6 @@ package org.opentripplanner.street.search.request; import java.time.Instant; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Envelope; @@ -76,12 +75,10 @@ private StreetSearchRequest() { this.toEnvelope = createEnvelope(to); } - @Nonnull public static StreetSearchRequestBuilder of() { return new StreetSearchRequestBuilder(DEFAULT).withStartTime(Instant.now()); } - @Nonnull public static StreetSearchRequestBuilder copyOf(StreetSearchRequest original) { return new StreetSearchRequestBuilder(original); } @@ -127,6 +124,10 @@ public DataOverlayContext dataOverlayContext() { return dataOverlayContext; } + public StreetSearchRequestBuilder copyOf(Instant time) { + return copyOf(this).withStartTime(time); + } + public StreetSearchRequestBuilder copyOfReversed(Instant time) { return copyOf(this).withStartTime(time).withArriveBy(!arriveBy); } diff --git a/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestBuilder.java b/application/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestBuilder.java rename to application/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestBuilder.java diff --git a/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestMapper.java b/application/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestMapper.java rename to application/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestMapper.java diff --git a/src/main/java/org/opentripplanner/street/search/state/CarPickupState.java b/application/src/main/java/org/opentripplanner/street/search/state/CarPickupState.java similarity index 100% rename from src/main/java/org/opentripplanner/street/search/state/CarPickupState.java rename to application/src/main/java/org/opentripplanner/street/search/state/CarPickupState.java diff --git a/application/src/main/java/org/opentripplanner/street/search/state/EdgeTraverser.java b/application/src/main/java/org/opentripplanner/street/search/state/EdgeTraverser.java new file mode 100644 index 00000000000..502d014e358 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/street/search/state/EdgeTraverser.java @@ -0,0 +1,65 @@ +package org.opentripplanner.street.search.state; + +import java.util.Collection; +import java.util.Optional; +import org.opentripplanner.astar.model.ShortestPathTree; +import org.opentripplanner.street.model.edge.Edge; +import org.opentripplanner.street.model.vertex.Vertex; +import org.opentripplanner.street.search.strategy.DominanceFunctions; + +/** + * This is a very reduced version of the A* algorithm: from an initial state a number of edges are + * traversed in sequential order. It doesn't take into account the potential other paths that are + * possible. + *

    + * This is not a general search algorithm! It's only useful for calculating cost and time of + * traversing a predetermined set of edges. + */ +public class EdgeTraverser { + + public static Optional traverseEdges( + final Collection initialStates, + final Collection edges + ) { + return traverseEdges(initialStates.toArray(new State[0]), edges); + } + + public static Optional traverseEdges( + final State[] initialStates, + final Collection edges + ) { + if (edges.isEmpty()) { + return Optional.of(initialStates[0]); + } + + // The shortest path tree is used to prune dominated parallel states. For example, + // CAR_PICKUP can return both a CAR/WALK state after each traversal of which only + // the optimal states need to be continued. + var dominanceFunction = new DominanceFunctions.MinimumWeight(); + var spt = new ShortestPathTree<>(dominanceFunction); + for (State initialState : initialStates) { + spt.add(initialState); + } + + Vertex lastVertex = null; + var isArriveBy = initialStates[0].getRequest().arriveBy(); + for (Edge e : edges) { + var vertex = isArriveBy ? e.getToVertex() : e.getFromVertex(); + var fromStates = spt.getStates(vertex); + if (fromStates == null || fromStates.isEmpty()) { + return Optional.empty(); + } + + for (State fromState : fromStates) { + var newToStates = e.traverse(fromState); + for (State newToState : newToStates) { + spt.add(newToState); + } + } + + lastVertex = isArriveBy ? e.getFromVertex() : e.getToVertex(); + } + + return Optional.ofNullable(lastVertex).map(spt::getState); + } +} diff --git a/src/main/java/org/opentripplanner/street/search/state/State.java b/application/src/main/java/org/opentripplanner/street/search/state/State.java similarity index 97% rename from src/main/java/org/opentripplanner/street/search/state/State.java rename to application/src/main/java/org/opentripplanner/street/search/state/State.java index deef516a674..9413cbcbd57 100644 --- a/src/main/java/org/opentripplanner/street/search/state/State.java +++ b/application/src/main/java/org/opentripplanner/street/search/state/State.java @@ -1,6 +1,6 @@ package org.opentripplanner.street.search.state; -import static org.opentripplanner.framework.lang.ObjectUtils.requireNotInitialized; +import static org.opentripplanner.utils.lang.ObjectUtils.requireNotInitialized; import java.time.Instant; import java.util.ArrayList; @@ -8,11 +8,9 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Stream; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.astar.spi.AStarState; import org.opentripplanner.ext.dataoverlay.routing.DataOverlayContext; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.api.request.preference.RoutingPreferences; import org.opentripplanner.service.vehiclerental.street.VehicleRentalEdge; import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex; @@ -22,6 +20,7 @@ import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.intersection_model.IntersectionTraversalCalculator; import org.opentripplanner.street.search.request.StreetSearchRequest; +import org.opentripplanner.utils.tostring.ToStringBuilder; public class State implements AStarState, Cloneable { @@ -57,7 +56,7 @@ public class State implements AStarState, Cloneable { /** * Create an initial state, forcing vertex to the specified value. Useful for tests, etc. */ - public State(@Nonnull Vertex vertex, @Nonnull StreetSearchRequest streetSearchRequest) { + public State(Vertex vertex, StreetSearchRequest streetSearchRequest) { this( vertex, streetSearchRequest.startTime(), @@ -66,12 +65,7 @@ public State(@Nonnull Vertex vertex, @Nonnull StreetSearchRequest streetSearchRe ); } - public State( - @Nonnull Vertex vertex, - @Nonnull Instant startTime, - @Nonnull StateData stateData, - @Nonnull StreetSearchRequest request - ) { + public State(Vertex vertex, Instant startTime, StateData stateData, StreetSearchRequest request) { this.request = request; this.weight = 0; this.vertex = vertex; diff --git a/src/main/java/org/opentripplanner/street/search/state/StateData.java b/application/src/main/java/org/opentripplanner/street/search/state/StateData.java similarity index 100% rename from src/main/java/org/opentripplanner/street/search/state/StateData.java rename to application/src/main/java/org/opentripplanner/street/search/state/StateData.java diff --git a/src/main/java/org/opentripplanner/street/search/state/StateEditor.java b/application/src/main/java/org/opentripplanner/street/search/state/StateEditor.java similarity index 99% rename from src/main/java/org/opentripplanner/street/search/state/StateEditor.java rename to application/src/main/java/org/opentripplanner/street/search/state/StateEditor.java index 40c44a16488..271b6e78030 100644 --- a/src/main/java/org/opentripplanner/street/search/state/StateEditor.java +++ b/application/src/main/java/org/opentripplanner/street/search/state/StateEditor.java @@ -1,7 +1,6 @@ package org.opentripplanner.street.search.state; import java.util.Set; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.street.model.RentalFormFactor; import org.opentripplanner.street.model.edge.Edge; @@ -135,7 +134,6 @@ public State makeState() { * Calls {@link StateEditor#makeState()} and wraps the result in an array of {@link State}. * If the state is null, then a zero-length array is returned. */ - @Nonnull public State[] makeStateArray() { return State.ofNullable(makeState()); } diff --git a/src/main/java/org/opentripplanner/street/search/state/VehicleRentalState.java b/application/src/main/java/org/opentripplanner/street/search/state/VehicleRentalState.java similarity index 100% rename from src/main/java/org/opentripplanner/street/search/state/VehicleRentalState.java rename to application/src/main/java/org/opentripplanner/street/search/state/VehicleRentalState.java diff --git a/src/main/java/org/opentripplanner/street/search/strategy/DominanceFunctions.java b/application/src/main/java/org/opentripplanner/street/search/strategy/DominanceFunctions.java similarity index 100% rename from src/main/java/org/opentripplanner/street/search/strategy/DominanceFunctions.java rename to application/src/main/java/org/opentripplanner/street/search/strategy/DominanceFunctions.java diff --git a/src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java b/application/src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java similarity index 100% rename from src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java rename to application/src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java diff --git a/src/main/java/org/opentripplanner/street/service/DefaultStreetLimitationParametersService.java b/application/src/main/java/org/opentripplanner/street/service/DefaultStreetLimitationParametersService.java similarity index 100% rename from src/main/java/org/opentripplanner/street/service/DefaultStreetLimitationParametersService.java rename to application/src/main/java/org/opentripplanner/street/service/DefaultStreetLimitationParametersService.java diff --git a/src/main/java/org/opentripplanner/street/service/StreetLimitationParametersService.java b/application/src/main/java/org/opentripplanner/street/service/StreetLimitationParametersService.java similarity index 100% rename from src/main/java/org/opentripplanner/street/service/StreetLimitationParametersService.java rename to application/src/main/java/org/opentripplanner/street/service/StreetLimitationParametersService.java diff --git a/src/main/java/org/opentripplanner/street/service/StreetLimitationParametersServiceModule.java b/application/src/main/java/org/opentripplanner/street/service/StreetLimitationParametersServiceModule.java similarity index 100% rename from src/main/java/org/opentripplanner/street/service/StreetLimitationParametersServiceModule.java rename to application/src/main/java/org/opentripplanner/street/service/StreetLimitationParametersServiceModule.java diff --git a/application/src/main/java/org/opentripplanner/transit/api/model/FilterValues.java b/application/src/main/java/org/opentripplanner/transit/api/model/FilterValues.java new file mode 100644 index 00000000000..391b2531231 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/api/model/FilterValues.java @@ -0,0 +1,86 @@ +package org.opentripplanner.transit.api.model; + +import com.beust.jcommander.internal.Nullable; +import java.util.Collection; +import java.util.NoSuchElementException; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.service.TransitService; + +/** + * {@link FilterValues} is meant to be used when filtering results from {@link TransitService}. + *

    + * This abstraction over the Collection type lets us keep filter specific functionality separate + * from interpretation of various states of a collection. For instance in which case the filter values + * should match all entities they are meant to filter. + *

    + * @param - The type of the filter values. Typically, String or {@link FeedScopedId}. + */ +public abstract class FilterValues { + + @Nullable + protected final Collection values; + + private final String name; + + FilterValues(String name, @Nullable Collection values) { + this.name = name; + this.values = values; + } + + /** + * Returns a {@link FilterValues} that matches everything if there are no filter values. + *

    + * @param name - The name of the filter. + * @param - The type of the filter values. Typically, String or {@link FeedScopedId}. + * @param values - The {@link Collection} of filter values. + * @return FilterValues + */ + public static FilterValues ofEmptyIsEverything( + String name, + @Nullable Collection values + ) { + return new FilterValuesEmptyIsEverything<>(name, values); + } + + /** + * Returns a {@link RequiredFilterValues} that throws an exception at creation time if the filter + * values is null or empty. + *

    + * @param name - The name of the filter. + * @param - The type of the filter values. Typically, String or {@link FeedScopedId}. + * @param values - The {@link Collection} of filter values. + * @return RequiredFilterValues + */ + public static RequiredFilterValues ofRequired( + String name, + @Nullable Collection values + ) { + return new RequiredFilterValues<>(name, values); + } + + /** + * Returns True if the collection of filter values matches everything that it could filter. If this + * is the case, then the filter values should not be used to filter anything and filtering logic can + * safely ignore it. + *

    + * @return boolean + */ + public abstract boolean includeEverything(); + + /** + * Returns the collection of filter values. If the filter values effectively don't filter anything, + * an exception is thrown. + *

    + * @return Collection - The values of the filter. + */ + public Collection get() { + if (includeEverything()) { + throw new NoSuchElementException( + "Filter values for filter %s effectively don't filter, use includeEverything() before calling this method.".formatted( + name + ) + ); + } + return values; + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/api/model/FilterValuesEmptyIsEverything.java b/application/src/main/java/org/opentripplanner/transit/api/model/FilterValuesEmptyIsEverything.java new file mode 100644 index 00000000000..ebe0af7bccb --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/api/model/FilterValuesEmptyIsEverything.java @@ -0,0 +1,19 @@ +package org.opentripplanner.transit.api.model; + +import java.util.Collection; + +/** + * {@link FilterValuesEmptyIsEverything} is a subclass of {@link FilterValues} that includes + * everything if the values are null or empty. + */ +public class FilterValuesEmptyIsEverything extends FilterValues { + + FilterValuesEmptyIsEverything(String name, Collection values) { + super(name, values); + } + + @Override + public boolean includeEverything() { + return values == null || values.isEmpty(); + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/api/model/RequiredFilterValues.java b/application/src/main/java/org/opentripplanner/transit/api/model/RequiredFilterValues.java new file mode 100644 index 00000000000..f4456dcce75 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/api/model/RequiredFilterValues.java @@ -0,0 +1,24 @@ +package org.opentripplanner.transit.api.model; + +import java.util.Collection; + +/** + * {@link RequiredFilterValues} is a subclass of {@link FilterValues} that requires at least one + * value to be included. + */ +public class RequiredFilterValues extends FilterValues { + + RequiredFilterValues(String name, Collection values) { + super(name, values); + if (values == null || values.isEmpty()) { + throw new IllegalArgumentException("Filter %s values must not be empty.".formatted(name)); + } + } + + @Override + public boolean includeEverything() { + // RequiredFilterValues should never include everything. In theory the filter values could be + // exhaustive, but there is no check for that currently. + return false; + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequest.java b/application/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequest.java new file mode 100644 index 00000000000..c61bb8ad107 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequest.java @@ -0,0 +1,75 @@ +package org.opentripplanner.transit.api.request; + +import java.time.LocalDate; +import org.opentripplanner.transit.api.model.FilterValues; +import org.opentripplanner.transit.api.model.RequiredFilterValues; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.timetable.TripAlteration; +import org.opentripplanner.transit.model.timetable.TripOnServiceDate; + +/** + * A request for trips on a specific service date. + *

    + * This request is used to retrieve {@link TripOnServiceDate}s that match the provided filter values. + * At least one operatingDay must be provided. + */ +public class TripOnServiceDateRequest { + + private final FilterValues serviceDates; + private final FilterValues agencies; + private final FilterValues routes; + private final FilterValues serviceJourneys; + private final FilterValues replacementFor; + private final FilterValues netexInternalPlanningCodes; + private final FilterValues alterations; + + protected TripOnServiceDateRequest( + RequiredFilterValues serviceDates, + FilterValues agencies, + FilterValues routes, + FilterValues serviceJourneys, + FilterValues replacementFor, + FilterValues netexInternalPlanningCodes, + FilterValues alterations + ) { + this.serviceDates = serviceDates; + this.agencies = agencies; + this.routes = routes; + this.serviceJourneys = serviceJourneys; + this.replacementFor = replacementFor; + this.netexInternalPlanningCodes = netexInternalPlanningCodes; + this.alterations = alterations; + } + + public static TripOnServiceDateRequestBuilder of(RequiredFilterValues serviceDates) { + return new TripOnServiceDateRequestBuilder(serviceDates); + } + + public FilterValues agencies() { + return agencies; + } + + public FilterValues routes() { + return routes; + } + + public FilterValues serviceJourneys() { + return serviceJourneys; + } + + public FilterValues replacementFor() { + return replacementFor; + } + + public FilterValues netexInternalPlanningCodes() { + return netexInternalPlanningCodes; + } + + public FilterValues alterations() { + return alterations; + } + + public FilterValues serviceDates() { + return serviceDates; + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequestBuilder.java b/application/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequestBuilder.java new file mode 100644 index 00000000000..534557c15d8 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequestBuilder.java @@ -0,0 +1,86 @@ +package org.opentripplanner.transit.api.request; + +import java.time.LocalDate; +import java.util.List; +import org.opentripplanner.transit.api.model.FilterValues; +import org.opentripplanner.transit.api.model.RequiredFilterValues; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.timetable.TripAlteration; + +public class TripOnServiceDateRequestBuilder { + + private FilterValues agencies = FilterValues.ofEmptyIsEverything( + "agencies", + List.of() + ); + private FilterValues routes = FilterValues.ofEmptyIsEverything("routes", List.of()); + private FilterValues serviceJourneys = FilterValues.ofEmptyIsEverything( + "serviceJourneys", + List.of() + ); + private FilterValues replacementFor = FilterValues.ofEmptyIsEverything( + "replacementFor", + List.of() + ); + private FilterValues netexInternalPlanningCodes = FilterValues.ofEmptyIsEverything( + "netexInternalPlanningCodes", + List.of() + ); + private FilterValues alterations = FilterValues.ofEmptyIsEverything( + "alterations", + List.of() + ); + private RequiredFilterValues serviceDates; + + protected TripOnServiceDateRequestBuilder(RequiredFilterValues serviceDates) { + this.serviceDates = serviceDates; + } + + public TripOnServiceDateRequestBuilder withAgencies(FilterValues agencies) { + this.agencies = agencies; + return this; + } + + public TripOnServiceDateRequestBuilder withRoutes(FilterValues routes) { + this.routes = routes; + return this; + } + + public TripOnServiceDateRequestBuilder withServiceJourneys( + FilterValues serviceJourneys + ) { + this.serviceJourneys = serviceJourneys; + return this; + } + + public TripOnServiceDateRequestBuilder withReplacementFor( + FilterValues replacementFor + ) { + this.replacementFor = replacementFor; + return this; + } + + public TripOnServiceDateRequestBuilder withNetexInternalPlanningCodes( + FilterValues netexInternalPlanningCodes + ) { + this.netexInternalPlanningCodes = netexInternalPlanningCodes; + return this; + } + + public TripOnServiceDateRequestBuilder withAlterations(FilterValues alterations) { + this.alterations = alterations; + return this; + } + + public TripOnServiceDateRequest build() { + return new TripOnServiceDateRequest( + serviceDates, + agencies, + routes, + serviceJourneys, + replacementFor, + netexInternalPlanningCodes, + alterations + ); + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/api/request/TripRequest.java b/application/src/main/java/org/opentripplanner/transit/api/request/TripRequest.java new file mode 100644 index 00000000000..c73e800582b --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/api/request/TripRequest.java @@ -0,0 +1,51 @@ +package org.opentripplanner.transit.api.request; + +import java.time.LocalDate; +import org.opentripplanner.transit.api.model.FilterValues; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.timetable.Trip; + +/** + * A request for {@link Trip}s. + *

    + * This request is used to retrieve {@link Trip}s that match the provided filter values. + */ +public class TripRequest { + + private final FilterValues agencies; + private final FilterValues routes; + private final FilterValues netexInternalPlanningCodes; + private final FilterValues serviceDates; + + protected TripRequest( + FilterValues agencies, + FilterValues routes, + FilterValues netexInternalPlanningCodes, + FilterValues serviceDates + ) { + this.agencies = agencies; + this.routes = routes; + this.netexInternalPlanningCodes = netexInternalPlanningCodes; + this.serviceDates = serviceDates; + } + + public static TripRequestBuilder of() { + return new TripRequestBuilder(); + } + + public FilterValues agencies() { + return agencies; + } + + public FilterValues routes() { + return routes; + } + + public FilterValues netexInternalPlanningCodes() { + return netexInternalPlanningCodes; + } + + public FilterValues serviceDates() { + return serviceDates; + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/api/request/TripRequestBuilder.java b/application/src/main/java/org/opentripplanner/transit/api/request/TripRequestBuilder.java new file mode 100644 index 00000000000..3a2f80a3e34 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/api/request/TripRequestBuilder.java @@ -0,0 +1,51 @@ +package org.opentripplanner.transit.api.request; + +import java.time.LocalDate; +import java.util.List; +import org.opentripplanner.transit.api.model.FilterValues; +import org.opentripplanner.transit.model.framework.FeedScopedId; + +public class TripRequestBuilder { + + private FilterValues agencies = FilterValues.ofEmptyIsEverything( + "agencies", + List.of() + ); + private FilterValues routes = FilterValues.ofEmptyIsEverything("routes", List.of()); + private FilterValues netexInternalPlanningCodes = FilterValues.ofEmptyIsEverything( + "netexInternalPlanningCodes", + List.of() + ); + private FilterValues serviceDates = FilterValues.ofEmptyIsEverything( + "serviceDates", + List.of() + ); + + protected TripRequestBuilder() {} + + public TripRequestBuilder withAgencies(FilterValues agencies) { + this.agencies = agencies; + return this; + } + + public TripRequestBuilder withRoutes(FilterValues routes) { + this.routes = routes; + return this; + } + + public TripRequestBuilder withNetexInternalPlanningCodes( + FilterValues netexInternalPlanningCodes + ) { + this.netexInternalPlanningCodes = netexInternalPlanningCodes; + return this; + } + + public TripRequestBuilder withServiceDates(FilterValues serviceDates) { + this.serviceDates = serviceDates; + return this; + } + + public TripRequest build() { + return new TripRequest(agencies, routes, netexInternalPlanningCodes, serviceDates); + } +} diff --git a/src/main/java/org/opentripplanner/transit/configure/TransitModule.java b/application/src/main/java/org/opentripplanner/transit/configure/TransitModule.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/configure/TransitModule.java rename to application/src/main/java/org/opentripplanner/transit/configure/TransitModule.java diff --git a/src/main/java/org/opentripplanner/transit/model/basic/Accessibility.java b/application/src/main/java/org/opentripplanner/transit/model/basic/Accessibility.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/basic/Accessibility.java rename to application/src/main/java/org/opentripplanner/transit/model/basic/Accessibility.java diff --git a/src/main/java/org/opentripplanner/transit/model/basic/Locales.java b/application/src/main/java/org/opentripplanner/transit/model/basic/Locales.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/basic/Locales.java rename to application/src/main/java/org/opentripplanner/transit/model/basic/Locales.java diff --git a/src/main/java/org/opentripplanner/transit/model/basic/LocalizedMoney.java b/application/src/main/java/org/opentripplanner/transit/model/basic/LocalizedMoney.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/basic/LocalizedMoney.java rename to application/src/main/java/org/opentripplanner/transit/model/basic/LocalizedMoney.java diff --git a/src/main/java/org/opentripplanner/transit/model/basic/MainAndSubMode.java b/application/src/main/java/org/opentripplanner/transit/model/basic/MainAndSubMode.java similarity index 93% rename from src/main/java/org/opentripplanner/transit/model/basic/MainAndSubMode.java rename to application/src/main/java/org/opentripplanner/transit/model/basic/MainAndSubMode.java index 571584700e9..030e5b5ac63 100644 --- a/src/main/java/org/opentripplanner/transit/model/basic/MainAndSubMode.java +++ b/application/src/main/java/org/opentripplanner/transit/model/basic/MainAndSubMode.java @@ -4,13 +4,12 @@ import java.util.List; import java.util.function.Predicate; import java.util.stream.Stream; -import javax.annotation.Nonnull; import javax.annotation.Nullable; /** * Tupple of main- and sub-mode. */ -public record MainAndSubMode(@Nonnull TransitMode mainMode, @Nullable SubMode subMode) { +public record MainAndSubMode(TransitMode mainMode, @Nullable SubMode subMode) { private static final List ALL = Stream .of(TransitMode.values()) .map(MainAndSubMode::new) diff --git a/src/main/java/org/opentripplanner/transit/model/basic/Money.java b/application/src/main/java/org/opentripplanner/transit/model/basic/Money.java similarity index 95% rename from src/main/java/org/opentripplanner/transit/model/basic/Money.java rename to application/src/main/java/org/opentripplanner/transit/model/basic/Money.java index 35278d8fbd8..97d6f91be5a 100644 --- a/src/main/java/org/opentripplanner/transit/model/basic/Money.java +++ b/application/src/main/java/org/opentripplanner/transit/model/basic/Money.java @@ -8,8 +8,7 @@ import java.util.Locale; import java.util.Objects; import java.util.function.Function; -import javax.annotation.Nonnull; -import org.opentripplanner.framework.lang.IntUtils; +import org.opentripplanner.utils.lang.IntUtils; /** * Represents an amount of money. @@ -26,7 +25,7 @@ public class Money implements Comparable, Serializable { * @param currency The currency of the money amount * @param minorUnitAmount The amount in the smaller currency unit, so for 1.50 EUR pass 150. */ - private Money(@Nonnull Currency currency, int minorUnitAmount) { + private Money(Currency currency, int minorUnitAmount) { this.currency = Objects.requireNonNull(currency); this.amount = minorUnitAmount; } @@ -65,7 +64,7 @@ public static Money max(Money first, Money second) { * Take a fractional amount of money, ie 1.5 and convert it to amount using the number of default * fraction digits of the currency. */ - public static Money ofFractionalAmount(@Nonnull Currency currency, float fractionalAmount) { + public static Money ofFractionalAmount(Currency currency, float fractionalAmount) { Objects.requireNonNull(currency); var fractionDigits = currency.getDefaultFractionDigits(); int amount = IntUtils.round(fractionalAmount * Math.pow(10, fractionDigits)); @@ -181,7 +180,6 @@ private boolean booleanOp(Money other, boolean result) { return result; } - @Nonnull private Money op(Money other, Function op) { checkCurrencyOrThrow(other); return op.apply(other); diff --git a/src/main/java/org/opentripplanner/transit/model/basic/Notice.java b/application/src/main/java/org/opentripplanner/transit/model/basic/Notice.java similarity index 92% rename from src/main/java/org/opentripplanner/transit/model/basic/Notice.java rename to application/src/main/java/org/opentripplanner/transit/model/basic/Notice.java index f9713417805..660a44c680f 100644 --- a/src/main/java/org/opentripplanner/transit/model/basic/Notice.java +++ b/application/src/main/java/org/opentripplanner/transit/model/basic/Notice.java @@ -1,7 +1,6 @@ package org.opentripplanner.transit.model.basic; import java.util.Objects; -import javax.annotation.Nonnull; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -34,7 +33,7 @@ public String publicCode() { } @Override - public boolean sameAs(@Nonnull Notice other) { + public boolean sameAs(Notice other) { return ( getId().equals(other.getId()) && Objects.equals(publicCode, other.publicCode) && @@ -43,7 +42,6 @@ public boolean sameAs(@Nonnull Notice other) { } @Override - @Nonnull public NoticeBuilder copy() { return new NoticeBuilder(this); } diff --git a/src/main/java/org/opentripplanner/transit/model/basic/NoticeBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/basic/NoticeBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/basic/NoticeBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/basic/NoticeBuilder.java diff --git a/src/main/java/org/opentripplanner/transit/model/basic/SubMode.java b/application/src/main/java/org/opentripplanner/transit/model/basic/SubMode.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/basic/SubMode.java rename to application/src/main/java/org/opentripplanner/transit/model/basic/SubMode.java diff --git a/src/main/java/org/opentripplanner/transit/model/basic/TransitMode.java b/application/src/main/java/org/opentripplanner/transit/model/basic/TransitMode.java similarity index 96% rename from src/main/java/org/opentripplanner/transit/model/basic/TransitMode.java rename to application/src/main/java/org/opentripplanner/transit/model/basic/TransitMode.java index e25cb435887..507b033f645 100644 --- a/src/main/java/org/opentripplanner/transit/model/basic/TransitMode.java +++ b/application/src/main/java/org/opentripplanner/transit/model/basic/TransitMode.java @@ -69,7 +69,7 @@ public String enumValueDescription() { case TRAM -> "Tram, streetcar or light rail. Used for any light rail or street level system within a metropolitan area."; case FERRY -> "Used for short- and long-distance boat service."; case AIRPLANE -> "Taking an airplane"; - case CABLE_CAR -> "Used for street-level cable cars where the cable runs beneath the car."; + case CABLE_CAR -> "Used for street-level rail cars where the cable runs beneath the vehicle."; case GONDOLA -> "Gondola or suspended cable car. Typically used for aerial cable cars where the car is suspended from the cable."; case FUNICULAR -> "Used for any rail system that moves on steep inclines with a cable traction system."; case TROLLEYBUS -> "Used for trolleybus systems which draw power from overhead wires using poles on the roof of the vehicle."; diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/expr/AndMatcher.java b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/AndMatcher.java new file mode 100644 index 00000000000..74f38efa8b7 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/AndMatcher.java @@ -0,0 +1,43 @@ +package org.opentripplanner.transit.model.filter.expr; + +import static org.opentripplanner.transit.model.filter.expr.BinaryOperator.AND; + +import java.util.List; + +/** + * Takes a list of matchers and provides a single interface. All matchers in the list must match for + * the composite matcher to return a match. + * + * @param The entity type the AndMatcher matches. + */ +public final class AndMatcher implements Matcher { + + private final Matcher[] matchers; + + private AndMatcher(List> matchers) { + this.matchers = matchers.toArray(Matcher[]::new); + } + + public static Matcher of(List> matchers) { + // simplify a list of one element + if (matchers.size() == 1) { + return matchers.get(0); + } + return new AndMatcher<>(matchers); + } + + @Override + public boolean match(T entity) { + for (var m : matchers) { + if (!m.match(entity)) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "(" + AND.arrayToString(matchers) + ')'; + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/expr/BinaryOperator.java b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/BinaryOperator.java new file mode 100644 index 00000000000..62f3fa30f27 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/BinaryOperator.java @@ -0,0 +1,37 @@ +package org.opentripplanner.transit.model.filter.expr; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * Used to concatenate matches with either the logical "AND" or "OR" operator. + */ +enum BinaryOperator { + AND("&"), + OR("|"); + + private final String token; + + BinaryOperator(String token) { + this.token = token; + } + + @Override + public String toString() { + return token; + } + + String arrayToString(T[] values) { + return colToString(Arrays.asList(values)); + } + + String colToString(Collection values) { + return values.stream().map(Objects::toString).collect(Collectors.joining(" " + token + " ")); + } + + String toString(T a, T b) { + return a.toString() + " " + token + " " + b.toString(); + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/expr/ContainsMatcher.java b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/ContainsMatcher.java new file mode 100644 index 00000000000..1be81ba9e7f --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/ContainsMatcher.java @@ -0,0 +1,55 @@ +package org.opentripplanner.transit.model.filter.expr; + +import java.util.function.Function; + +/** + * A matcher that applies a provided matcher to an iterable of child entities returned from the main + * entity that this matcher is for. + *

    + * If any of the iterable entities match the valueMatcher, then the match method returns true. In + * this way it is similar to an OR. + *

    + * @param The main entity type this matcher is applied to. + * @param The type of the child entities, for which there is a mapping from S to T. + */ +public class ContainsMatcher implements Matcher { + + private final String relationshipName; + private final Function> valuesProvider; + private final Matcher valueMatcher; + + /** + * @param relationshipName The name of the type of relationship between the main entity and the + * entity matched by the valueMatcher. + * @param valuesProvider The function that maps the entity being matched by this matcher (S) to + * the iterable of items being matched by valueMatcher. + * @param valueMatcher The matcher that is applied each of the iterable entities returned from the + * valuesProvider function. + */ + public ContainsMatcher( + String relationshipName, + Function> valuesProvider, + Matcher valueMatcher + ) { + this.relationshipName = relationshipName; + this.valuesProvider = valuesProvider; + this.valueMatcher = valueMatcher; + } + + public boolean match(S entity) { + if (valuesProvider.apply(entity) == null) { + return false; + } + for (T it : valuesProvider.apply(entity)) { + if (valueMatcher.match(it)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + return "ContainsMatcher: " + relationshipName + ": " + valueMatcher; + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/expr/EqualityMatcher.java b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/EqualityMatcher.java new file mode 100644 index 00000000000..1380131e07a --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/EqualityMatcher.java @@ -0,0 +1,40 @@ +package org.opentripplanner.transit.model.filter.expr; + +import java.util.function.Function; + +/** + * A matcher that checks if a value is equal to another value derived from the matched entities. + *

    + * The derived entity value is provided by a function that takes the entity being matched as an argument. + *

    + * @param The type of the entity being matched. + * @param The type of the value that the matcher will test equality for. + */ +public class EqualityMatcher implements Matcher { + + private final String typeName; + private final V value; + private final Function valueProvider; + + /** + * @param typeName The typeName appears in the toString for easier debugging. + * @param value The value that this matcher will check equality for. + * @param valueProvider The function that maps the entity being matched by this matcher (T) to + * the value being matched by this matcher. + */ + public EqualityMatcher(String typeName, V value, Function valueProvider) { + this.typeName = typeName; + this.value = value; + this.valueProvider = valueProvider; + } + + @Override + public boolean match(T entity) { + return value.equals(valueProvider.apply(entity)); + } + + @Override + public String toString() { + return typeName + "==" + value; + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/expr/ExpressionBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/ExpressionBuilder.java new file mode 100644 index 00000000000..f2910a4c8d2 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/ExpressionBuilder.java @@ -0,0 +1,40 @@ +package org.opentripplanner.transit.model.filter.expr; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; +import org.opentripplanner.transit.api.model.FilterValues; + +/** + * A builder for creating complex matchers composed of other matchers. + *

    + * This builder contains convenience methods for creating complex matchers from simpler ones. The + * resulting matcher "ands" together all the matchers it has built up. This supports the common + * pattern of narrowing results with multiple filters. + * + * @param The type of entity to match in the expression. + */ +public class ExpressionBuilder { + + private final List> matchers = new ArrayList<>(); + + public static ExpressionBuilder of() { + return new ExpressionBuilder<>(); + } + + public ExpressionBuilder atLeastOneMatch( + FilterValues filterValues, + Function> matcherProvider + ) { + if (filterValues.includeEverything()) { + return this; + } + + matchers.add(OrMatcher.of(filterValues.get().stream().map(matcherProvider).toList())); + return this; + } + + public Matcher build() { + return AndMatcher.of(matchers); + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/expr/Matcher.java b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/Matcher.java new file mode 100644 index 00000000000..db3c02296b9 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/Matcher.java @@ -0,0 +1,19 @@ +package org.opentripplanner.transit.model.filter.expr; + +/** + * Generic matcher interface - this is the root of the matcher type hierarchy. + *

    + * @param Domain type to match. + */ +@FunctionalInterface +public interface Matcher { + boolean match(T entity); + + static Matcher everything() { + return e -> true; + } + + static Matcher nothing() { + return e -> false; + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/expr/OrMatcher.java b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/OrMatcher.java new file mode 100644 index 00000000000..62da7af63f4 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/expr/OrMatcher.java @@ -0,0 +1,58 @@ +package org.opentripplanner.transit.model.filter.expr; + +import static org.opentripplanner.transit.model.filter.expr.BinaryOperator.OR; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Takes a list of matchers and provides a single interface. At least one of the matchers in the + * list must match for the composite matcher to return a match. + *

    + * @param The entity type the OrMatcher matches. + */ +public final class OrMatcher implements Matcher { + + private final Matcher[] matchers; + + private OrMatcher(List> matchers) { + this.matchers = matchers.toArray(Matcher[]::new); + } + + public static Matcher of(Matcher a, Matcher b) { + return of(List.of(a, b)); + } + + public static Matcher of(List> matchers) { + // Simplify if there is just one matcher in the list + if (matchers.size() == 1) { + return matchers.get(0); + } + // Collapse nested or matchers + var expr = new ArrayList>(); + for (Matcher it : matchers) { + if (it instanceof OrMatcher orMatcher) { + expr.addAll(Arrays.asList(orMatcher.matchers)); + } else { + expr.add(it); + } + } + return new OrMatcher<>(expr); + } + + @Override + public boolean match(T entity) { + for (var m : matchers) { + if (m.match(entity)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + return "(" + OR.arrayToString(matchers) + ')'; + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripMatcherFactory.java b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripMatcherFactory.java new file mode 100644 index 00000000000..1ff33d9928d --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripMatcherFactory.java @@ -0,0 +1,75 @@ +package org.opentripplanner.transit.model.filter.transit; + +import java.time.LocalDate; +import java.util.Set; +import java.util.function.Function; +import org.opentripplanner.transit.api.request.TripRequest; +import org.opentripplanner.transit.model.filter.expr.ContainsMatcher; +import org.opentripplanner.transit.model.filter.expr.EqualityMatcher; +import org.opentripplanner.transit.model.filter.expr.ExpressionBuilder; +import org.opentripplanner.transit.model.filter.expr.Matcher; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.timetable.Trip; + +/** + * A factory for creating matchers for {@link Trip} objects. + *

    + * This factory is used to create matchers for {@link Trip} objects based on a request. The + * resulting matcher can be used to filter a list of {@link Trip} objects. + */ +public class TripMatcherFactory { + + /** + * Creates a matcher for {@link Trip} objects based on the given request. + * + * @param request - a {@link TripRequest} object that contains the criteria for the matcher. + * @param serviceDateProvider a function that provides the service dates for a given {@link FeedScopedId} of a {@link Trip}. + * @return a {@link Matcher} to be used for filtering {@link Trip} objects. + */ + public static Matcher of( + TripRequest request, + Function> serviceDateProvider + ) { + ExpressionBuilder expr = ExpressionBuilder.of(); + + expr.atLeastOneMatch(request.agencies(), TripMatcherFactory::agencyId); + expr.atLeastOneMatch(request.routes(), TripMatcherFactory::routeId); + expr.atLeastOneMatch( + request.netexInternalPlanningCodes(), + TripMatcherFactory::netexInternalPlanningCode + ); + expr.atLeastOneMatch( + request.serviceDates(), + TripMatcherFactory.serviceDate(serviceDateProvider) + ); + + return expr.build(); + } + + static Matcher agencyId(FeedScopedId id) { + return new EqualityMatcher<>("agency", id, t -> t.getRoute().getAgency().getId()); + } + + static Matcher routeId(FeedScopedId id) { + return new EqualityMatcher<>("route", id, t -> t.getRoute().getId()); + } + + static Matcher netexInternalPlanningCode(String code) { + return new EqualityMatcher<>( + "netexInternalPlanningCode", + code, + Trip::getNetexInternalPlanningCode + ); + } + + static Function> serviceDate( + Function> serviceDateProvider + ) { + return date -> + new ContainsMatcher<>( + "serviceDates", + t -> serviceDateProvider.apply(t.getServiceId()), + new EqualityMatcher<>("serviceDate", date, (dateToMatch -> dateToMatch)) + ); + } +} diff --git a/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactory.java b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactory.java new file mode 100644 index 00000000000..7442e2874eb --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactory.java @@ -0,0 +1,76 @@ +package org.opentripplanner.transit.model.filter.transit; + +import java.time.LocalDate; +import org.opentripplanner.transit.api.request.TripOnServiceDateRequest; +import org.opentripplanner.transit.model.filter.expr.ContainsMatcher; +import org.opentripplanner.transit.model.filter.expr.EqualityMatcher; +import org.opentripplanner.transit.model.filter.expr.ExpressionBuilder; +import org.opentripplanner.transit.model.filter.expr.Matcher; +import org.opentripplanner.transit.model.framework.AbstractTransitEntity; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.timetable.TripAlteration; +import org.opentripplanner.transit.model.timetable.TripOnServiceDate; + +/** + * A factory for creating matchers for {@link TripOnServiceDate} objects. + *

    + * This factory is used to create matchers for {@link TripOnServiceDate} objects based on a request. The + * resulting matcher can be used to filter a list of {@link TripOnServiceDate} objects. + */ +public class TripOnServiceDateMatcherFactory { + + public static Matcher of(TripOnServiceDateRequest request) { + ExpressionBuilder expr = ExpressionBuilder.of(); + + expr.atLeastOneMatch(request.serviceDates(), TripOnServiceDateMatcherFactory::serviceDate); + expr.atLeastOneMatch(request.agencies(), TripOnServiceDateMatcherFactory::agencyId); + expr.atLeastOneMatch(request.routes(), TripOnServiceDateMatcherFactory::routeId); + expr.atLeastOneMatch( + request.serviceJourneys(), + TripOnServiceDateMatcherFactory::serviceJourneyId + ); + expr.atLeastOneMatch(request.replacementFor(), TripOnServiceDateMatcherFactory::replacementFor); + expr.atLeastOneMatch( + request.netexInternalPlanningCodes(), + TripOnServiceDateMatcherFactory::netexInternalPlanningCode + ); + expr.atLeastOneMatch(request.alterations(), TripOnServiceDateMatcherFactory::alteration); + return expr.build(); + } + + static Matcher agencyId(FeedScopedId id) { + return new EqualityMatcher<>("agency", id, t -> t.getTrip().getRoute().getAgency().getId()); + } + + static Matcher routeId(FeedScopedId id) { + return new EqualityMatcher<>("route", id, t -> t.getTrip().getRoute().getId()); + } + + static Matcher serviceJourneyId(FeedScopedId id) { + return new EqualityMatcher<>("serviceJourney", id, t -> t.getTrip().getId()); + } + + static Matcher replacementFor(FeedScopedId id) { + return new ContainsMatcher<>( + "replacementForContains", + t -> t.getReplacementFor().stream().map(AbstractTransitEntity::getId).toList(), + new EqualityMatcher<>("replacementForIdEquals", id, (idToMatch -> idToMatch)) + ); + } + + static Matcher netexInternalPlanningCode(String code) { + return new EqualityMatcher<>( + "netexInternalPlanningCode", + code, + t -> t.getTrip().getNetexInternalPlanningCode() + ); + } + + static Matcher serviceDate(LocalDate date) { + return new EqualityMatcher<>("serviceDate", date, TripOnServiceDate::getServiceDate); + } + + static Matcher alteration(TripAlteration alteration) { + return new EqualityMatcher<>("alteration", alteration, TripOnServiceDate::getTripAlteration); + } +} diff --git a/src/main/java/org/opentripplanner/transit/model/framework/AbstractBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractBuilder.java similarity index 93% rename from src/main/java/org/opentripplanner/transit/model/framework/AbstractBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/AbstractBuilder.java index de20445a7ba..60a970a0521 100644 --- a/src/main/java/org/opentripplanner/transit/model/framework/AbstractBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractBuilder.java @@ -1,6 +1,5 @@ package org.opentripplanner.transit.model.framework; -import javax.annotation.Nonnull; import javax.annotation.Nullable; public abstract class AbstractBuilder< @@ -29,7 +28,7 @@ E original() { protected abstract E buildFromValues(); @Override - public final @Nonnull E build() { + public final E build() { var b = buildFromValues(); if (original == null) { diff --git a/src/main/java/org/opentripplanner/transit/model/framework/AbstractEntityBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractEntityBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/framework/AbstractEntityBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/AbstractEntityBuilder.java diff --git a/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java b/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java similarity index 96% rename from src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java index 4053a4860f2..258d505b53c 100644 --- a/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java +++ b/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java @@ -5,7 +5,6 @@ import java.util.List; import java.util.Objects; import java.util.Set; -import javax.annotation.Nonnull; /** * All OTP Transit entities should extend this class. The purpose of the class is to enforce a @@ -30,7 +29,7 @@ public abstract class AbstractTransitEntity< private final FeedScopedId id; - public AbstractTransitEntity(@Nonnull FeedScopedId id) { + public AbstractTransitEntity(FeedScopedId id) { this.id = Objects.requireNonNull(id); } diff --git a/src/main/java/org/opentripplanner/transit/model/framework/DataValidationException.java b/application/src/main/java/org/opentripplanner/transit/model/framework/DataValidationException.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/framework/DataValidationException.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/DataValidationException.java diff --git a/src/main/java/org/opentripplanner/transit/model/framework/Deduplicator.java b/application/src/main/java/org/opentripplanner/transit/model/framework/Deduplicator.java similarity index 99% rename from src/main/java/org/opentripplanner/transit/model/framework/Deduplicator.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/Deduplicator.java index 587ad2871cd..69b5385ad86 100644 --- a/src/main/java/org/opentripplanner/transit/model/framework/Deduplicator.java +++ b/application/src/main/java/org/opentripplanner/transit/model/framework/Deduplicator.java @@ -14,7 +14,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Does the same thing as String.intern, but for several different types. Java's String.intern uses diff --git a/src/main/java/org/opentripplanner/transit/model/framework/DeduplicatorNoop.java b/application/src/main/java/org/opentripplanner/transit/model/framework/DeduplicatorNoop.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/framework/DeduplicatorNoop.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/DeduplicatorNoop.java diff --git a/src/main/java/org/opentripplanner/transit/model/framework/DeduplicatorService.java b/application/src/main/java/org/opentripplanner/transit/model/framework/DeduplicatorService.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/framework/DeduplicatorService.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/DeduplicatorService.java diff --git a/src/main/java/org/opentripplanner/transit/model/framework/DefaultEntityById.java b/application/src/main/java/org/opentripplanner/transit/model/framework/DefaultEntityById.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/framework/DefaultEntityById.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/DefaultEntityById.java diff --git a/src/main/java/org/opentripplanner/transit/model/framework/DefaultEntityContext.java b/application/src/main/java/org/opentripplanner/transit/model/framework/DefaultEntityContext.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/framework/DefaultEntityContext.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/DefaultEntityContext.java diff --git a/src/main/java/org/opentripplanner/transit/model/framework/EntityById.java b/application/src/main/java/org/opentripplanner/transit/model/framework/EntityById.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/framework/EntityById.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/EntityById.java diff --git a/src/main/java/org/opentripplanner/transit/model/framework/EntityContext.java b/application/src/main/java/org/opentripplanner/transit/model/framework/EntityContext.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/framework/EntityContext.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/EntityContext.java diff --git a/application/src/main/java/org/opentripplanner/transit/model/framework/EntityNotFoundException.java b/application/src/main/java/org/opentripplanner/transit/model/framework/EntityNotFoundException.java new file mode 100644 index 00000000000..362dad1b80b --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/model/framework/EntityNotFoundException.java @@ -0,0 +1,34 @@ +package org.opentripplanner.transit.model.framework; + +/** + * This exception is used by the main OTP business logic to signal that one of the + * ids passed in is not found. This exception should be handled in a generic way in each + * API. + *

    + * When an entity is not found, it indicates that there is a system integration error. This + * should not be used if the user type in the id, then the client should validate the id + * before it is passed into OTP. + */ +public class EntityNotFoundException extends RuntimeException { + + private final String entityName; + private final FeedScopedId id; + + /** + * Use this if the id can be of more than one type, or you would like to provide an + * alternative name. + */ + public EntityNotFoundException(String entityName, FeedScopedId id) { + this.entityName = entityName; + this.id = id; + } + + public EntityNotFoundException(Class entityType, FeedScopedId id) { + this(entityType.getSimpleName(), id); + } + + @Override + public String getMessage() { + return entityName + " entity not found: " + id; + } +} diff --git a/src/main/java/org/opentripplanner/transit/model/framework/FeedScopedId.java b/application/src/main/java/org/opentripplanner/transit/model/framework/FeedScopedId.java similarity index 89% rename from src/main/java/org/opentripplanner/transit/model/framework/FeedScopedId.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/FeedScopedId.java index b48ff040c28..0b269220ae1 100644 --- a/src/main/java/org/opentripplanner/transit/model/framework/FeedScopedId.java +++ b/application/src/main/java/org/opentripplanner/transit/model/framework/FeedScopedId.java @@ -1,13 +1,12 @@ package org.opentripplanner.transit.model.framework; -import static org.opentripplanner.framework.lang.StringUtils.assertHasValue; +import static org.opentripplanner.utils.lang.StringUtils.assertHasValue; import java.io.Serializable; import java.util.Arrays; import java.util.List; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opentripplanner.framework.lang.StringUtils; +import org.opentripplanner.utils.lang.StringUtils; public final class FeedScopedId implements Serializable, Comparable { @@ -22,7 +21,7 @@ public final class FeedScopedId implements Serializable, Comparable { private Result() {} - public static Result failure(@Nonnull E failure) { + public static Result failure(E failure) { return new Failure<>(failure); } - public static Result success(@Nonnull T success) { + public static Result success(T success) { return new Success<>(success); } diff --git a/src/main/java/org/opentripplanner/transit/model/framework/TransitBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/framework/TransitBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/framework/TransitBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/TransitBuilder.java diff --git a/src/main/java/org/opentripplanner/transit/model/framework/TransitEntity.java b/application/src/main/java/org/opentripplanner/transit/model/framework/TransitEntity.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/framework/TransitEntity.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/TransitEntity.java diff --git a/src/main/java/org/opentripplanner/transit/model/framework/TransitEntityBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/framework/TransitEntityBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/framework/TransitEntityBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/TransitEntityBuilder.java diff --git a/src/main/java/org/opentripplanner/transit/model/framework/TransitObject.java b/application/src/main/java/org/opentripplanner/transit/model/framework/TransitObject.java similarity index 93% rename from src/main/java/org/opentripplanner/transit/model/framework/TransitObject.java rename to application/src/main/java/org/opentripplanner/transit/model/framework/TransitObject.java index ad09a40db07..60d261fee00 100644 --- a/src/main/java/org/opentripplanner/transit/model/framework/TransitObject.java +++ b/application/src/main/java/org/opentripplanner/transit/model/framework/TransitObject.java @@ -1,7 +1,6 @@ package org.opentripplanner.transit.model.framework; import java.io.Serializable; -import javax.annotation.Nonnull; public interface TransitObject, T extends TransitBuilder> extends Serializable { @@ -10,7 +9,7 @@ public interface TransitObject, T extends TransitB * the same value. This is used to avoid creating new objects during transit model construction * and during RealTime updates. */ - boolean sameAs(@Nonnull E other); + boolean sameAs(E other); /** * The copy method is used to mutate the existing object by creating a builder and setting @@ -25,6 +24,5 @@ public interface TransitObject, T extends TransitB *

    * TODO RTM - Document design "rules" in a package readme, when the design is set. */ - @Nonnull TransitBuilder copy(); } diff --git a/src/main/java/org/opentripplanner/transit/model/network/BikeAccess.java b/application/src/main/java/org/opentripplanner/transit/model/network/BikeAccess.java similarity index 69% rename from src/main/java/org/opentripplanner/transit/model/network/BikeAccess.java rename to application/src/main/java/org/opentripplanner/transit/model/network/BikeAccess.java index 536a01a9b14..c0d850e9ce7 100644 --- a/src/main/java/org/opentripplanner/transit/model/network/BikeAccess.java +++ b/application/src/main/java/org/opentripplanner/transit/model/network/BikeAccess.java @@ -1,6 +1,8 @@ package org.opentripplanner.transit.model.network; /** + * This represents the state of whether bikes are allowed on board trips (or routes). + *

    * GTFS codes: * 0 = unknown / unspecified, 1 = bikes allowed, 2 = bikes NOT allowed */ diff --git a/application/src/main/java/org/opentripplanner/transit/model/network/CarAccess.java b/application/src/main/java/org/opentripplanner/transit/model/network/CarAccess.java new file mode 100644 index 00000000000..2fca43cfb32 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/transit/model/network/CarAccess.java @@ -0,0 +1,13 @@ +package org.opentripplanner.transit.model.network; + +/** + * This represents the state of whether cars are allowed on board trips. + *

    + * GTFS codes: + * 0 = unknown / unspecified, 1 = cars allowed, 2 = cars NOT allowed + */ +public enum CarAccess { + UNKNOWN, + NOT_ALLOWED, + ALLOWED, +} diff --git a/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutes.java b/application/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutes.java similarity index 94% rename from src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutes.java rename to application/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutes.java index c52e7ffe3e6..66cf57788c6 100644 --- a/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutes.java +++ b/application/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutes.java @@ -1,7 +1,6 @@ package org.opentripplanner.transit.model.network; import java.util.Objects; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -34,13 +33,11 @@ public static GroupOfRoutesBuilder of(FeedScopedId id) { return new GroupOfRoutesBuilder(id); } - @Nonnull public String getName() { return logName(); } @Override - @Nonnull public String logName() { return name; } @@ -66,7 +63,7 @@ public GroupOfRoutesBuilder copy() { } @Override - public boolean sameAs(@Nonnull GroupOfRoutes other) { + public boolean sameAs(GroupOfRoutes other) { return ( getId().equals(other.getId()) && Objects.equals(name, other.name) && diff --git a/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutesBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutesBuilder.java similarity index 95% rename from src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutesBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutesBuilder.java index 1080209f33c..c4fb7967a55 100644 --- a/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutesBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/network/GroupOfRoutesBuilder.java @@ -1,6 +1,5 @@ package org.opentripplanner.transit.model.network; -import javax.annotation.Nonnull; import org.opentripplanner.transit.model.framework.AbstractEntityBuilder; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -21,7 +20,7 @@ public class GroupOfRoutesBuilder super(id); } - GroupOfRoutesBuilder(@Nonnull GroupOfRoutes original) { + GroupOfRoutesBuilder(GroupOfRoutes original) { super(original); this.privateCode = original.getPrivateCode(); this.shortName = original.getShortName(); diff --git a/src/main/java/org/opentripplanner/transit/model/network/Route.java b/application/src/main/java/org/opentripplanner/transit/model/network/Route.java similarity index 95% rename from src/main/java/org/opentripplanner/transit/model/network/Route.java rename to application/src/main/java/org/opentripplanner/transit/model/network/Route.java index 721c6098ac8..1daae1e6209 100644 --- a/src/main/java/org/opentripplanner/transit/model/network/Route.java +++ b/application/src/main/java/org/opentripplanner/transit/model/network/Route.java @@ -7,10 +7,8 @@ import java.util.List; import java.util.Locale; import java.util.Objects; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.transit.model.basic.SubMode; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; @@ -19,6 +17,7 @@ import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.organization.Branding; import org.opentripplanner.transit.model.organization.Operator; +import org.opentripplanner.utils.lang.IntUtils; public final class Route extends AbstractTransitEntity implements LogInfo { @@ -65,12 +64,12 @@ public final class Route extends AbstractTransitEntity impl this.textColor = builder.getTextColor(); } - public static RouteBuilder of(@Nonnull FeedScopedId id) { + public static RouteBuilder of(FeedScopedId id) { return new RouteBuilder(id); } @Override - public boolean sameAs(@Nonnull Route other) { + public boolean sameAs(Route other) { return ( getId().equals(other.getId()) && Objects.equals(this.agency, other.agency) && @@ -101,7 +100,6 @@ public RouteBuilder copy() { * The 'agency' property represent a GTFS Agency and NeTEx the Authority. Note that Agency does * NOT map 1-1 to Authority, it is rather a mix between Authority and Operator. */ - @Nonnull public Agency getAgency() { return agency; } @@ -119,7 +117,6 @@ public Branding getBranding() { return branding; } - @Nonnull public List getGroupsOfRoutes() { return groupsOfRoutes; } @@ -134,7 +131,6 @@ public I18NString getLongName() { return longName; } - @Nonnull public TransitMode getMode() { return mode; } @@ -160,7 +156,9 @@ public Integer getGtfsSortOrder() { return gtfsSortOrder; } - @Nonnull + /** + * Returns the NeTEx submode for the route. Will return UNKNOWN by default. + */ public SubMode getNetexSubmode() { return netexSubmode; } @@ -180,7 +178,6 @@ public String getTextColor() { return textColor; } - @Nonnull public BikeAccess getBikesAllowed() { return bikesAllowed; } @@ -194,13 +191,11 @@ public String getFlexibleLineType() { } /** @return the route's short name, or the long name if the short name is null. */ - @Nonnull public String getName(Locale locale) { return shortName == null ? longName.toString(locale) : shortName; } /** @return the route's short name, or the long name if the short name is null. */ - @Nonnull public String getName() { return shortName == null ? longName.toString() : shortName; } diff --git a/src/main/java/org/opentripplanner/transit/model/network/RouteBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/network/RouteBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/network/RouteBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/network/RouteBuilder.java diff --git a/src/main/java/org/opentripplanner/transit/model/network/RoutingTripPattern.java b/application/src/main/java/org/opentripplanner/transit/model/network/RoutingTripPattern.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/network/RoutingTripPattern.java rename to application/src/main/java/org/opentripplanner/transit/model/network/RoutingTripPattern.java diff --git a/src/main/java/org/opentripplanner/transit/model/network/StopPattern.java b/application/src/main/java/org/opentripplanner/transit/model/network/StopPattern.java similarity index 98% rename from src/main/java/org/opentripplanner/transit/model/network/StopPattern.java rename to application/src/main/java/org/opentripplanner/transit/model/network/StopPattern.java index 3fc51cea0c6..9df095d5170 100644 --- a/src/main/java/org/opentripplanner/transit/model/network/StopPattern.java +++ b/application/src/main/java/org/opentripplanner/transit/model/network/StopPattern.java @@ -8,15 +8,14 @@ import java.util.Objects; import java.util.Optional; import java.util.function.Predicate; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opentripplanner.framework.lang.MemEfficientArrayBuilder; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.StopTime; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.utils.lang.MemEfficientArrayBuilder; /** * This class represents what is called a JourneyPattern in Transmodel: the sequence of stops at @@ -272,7 +271,7 @@ private int findStopPosition( * @param index Given index for stop * @return true if stop and next stop are equal on both stop patterns, else false */ - boolean sameStops(@Nonnull StopPattern other, int index) { + boolean sameStops(StopPattern other, int index) { var otherOrigin = other.getStop(index); var otherDestination = other.getStop(index + 1); var origin = getStop(index); @@ -289,7 +288,7 @@ boolean sameStops(@Nonnull StopPattern other, int index) { * @return true if the stops have the same stations, else false. If any station is null then * false. */ - boolean sameStations(@Nonnull StopPattern other, int index) { + boolean sameStations(StopPattern other, int index) { var otherOrigin = other.getStop(index).getParentStation(); var otherDestination = other.getStop(index + 1).getParentStation(); var origin = getStop(index).getParentStation(); diff --git a/src/main/java/org/opentripplanner/transit/model/network/TripPattern.java b/application/src/main/java/org/opentripplanner/transit/model/network/TripPattern.java similarity index 86% rename from src/main/java/org/opentripplanner/transit/model/network/TripPattern.java rename to application/src/main/java/org/opentripplanner/transit/model/network/TripPattern.java index 57c71d06113..88d48d741f3 100644 --- a/src/main/java/org/opentripplanner/transit/model/network/TripPattern.java +++ b/application/src/main/java/org/opentripplanner/transit/model/network/TripPattern.java @@ -1,17 +1,14 @@ package org.opentripplanner.transit.model.network; import static java.util.Objects.requireNonNull; -import static java.util.Objects.requireNonNullElseGet; -import static org.opentripplanner.framework.lang.ObjectUtils.requireNotInitialized; +import static org.opentripplanner.utils.lang.ObjectUtils.requireNotInitialized; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Objects; -import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.LineString; import org.opentripplanner.framework.geometry.CompactLineStringUtils; @@ -28,7 +25,6 @@ import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.Direction; -import org.opentripplanner.transit.model.timetable.FrequencyEntry; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; import org.slf4j.Logger; @@ -122,20 +118,27 @@ public final class TripPattern private final RoutingTripPattern routingTripPattern; - public TripPattern(TripPatternBuilder builder) { + TripPattern(TripPatternBuilder builder) { super(builder.getId()); this.name = builder.getName(); this.route = builder.getRoute(); this.stopPattern = requireNonNull(builder.getStopPattern()); this.createdByRealtimeUpdater = builder.isCreatedByRealtimeUpdate(); - this.mode = requireNonNullElseGet(builder.getMode(), route::getMode); - this.netexSubMode = requireNonNullElseGet(builder.getNetexSubmode(), route::getNetexSubmode); + this.mode = requireNonNull(builder.getMode()); + this.netexSubMode = requireNonNull(builder.getNetexSubmode()); this.containsMultipleModes = builder.getContainsMultipleModes(); - this.scheduledTimetable = - builder.getScheduledTimetable() != null - ? builder.getScheduledTimetable() - : new Timetable(this); + if (builder.getScheduledTimetable() != null) { + if (builder.getScheduledTimetableBuilder() != null) { + throw new IllegalArgumentException( + "Cannot provide both scheduled timetable and scheduled timetable builder" + ); + } + this.scheduledTimetable = builder.getScheduledTimetable(); + } else { + this.scheduledTimetable = + builder.getScheduledTimetableBuilder().withTripPattern(this).build(); + } this.originalTripPattern = builder.getOriginalTripPattern(); @@ -143,7 +146,7 @@ public TripPattern(TripPatternBuilder builder) { this.routingTripPattern = new RoutingTripPattern(this, builder); } - public static TripPatternBuilder of(@Nonnull FeedScopedId id) { + public static TripPatternBuilder of(FeedScopedId id) { return new TripPatternBuilder(id); } @@ -331,56 +334,6 @@ public boolean isBoardAndAlightAt(int stopIndex, PickDrop value) { /* METHODS THAT DELEGATE TO THE SCHEDULED TIMETABLE */ - // TODO OTP2 this method modifies the state, it will be refactored in a subsequent step - /** - * Add the given tripTimes to this pattern's scheduled timetable, recording the corresponding trip - * as one of the scheduled trips on this pattern. - */ - public void add(TripTimes tt) { - // Only scheduled trips (added at graph build time, rather than directly to the timetable - // via updates) are in this list. - scheduledTimetable.addTripTimes(tt); - - // Check that all trips added to this pattern are on the initially declared route. - // Identity equality is valid on GTFS entity objects. - if (this.route != tt.getTrip().getRoute()) { - LOG.warn( - "The trip {} is on route {} but its stop pattern is on route {}.", - tt.getTrip(), - tt.getTrip().getRoute(), - route - ); - } - } - - // TODO OTP2 this method modifies the state, it will be refactored in a subsequent step - /** - * Add the given FrequencyEntry to this pattern's scheduled timetable, recording the corresponding - * trip as one of the scheduled trips on this pattern. - * TODO possible improvements: combine freq entries and TripTimes. Do not keep trips list in TripPattern - * since it is redundant. - */ - public void add(FrequencyEntry freq) { - scheduledTimetable.addFrequencyEntry(freq); - if (this.getRoute() != freq.tripTimes.getTrip().getRoute()) { - LOG.warn( - "The trip {} is on a different route than its stop pattern, which is on {}.", - freq.tripTimes.getTrip(), - route - ); - } - } - - // TODO OTP2 this method modifies the state, it will be refactored in a subsequent step - /** - * Remove all trips matching the given predicate. - * - * @param removeTrip it the predicate returns true - */ - public void removeTrips(Predicate removeTrip) { - scheduledTimetable.getTripTimes().removeIf(tt -> removeTrip.test(tt.getTrip())); - } - /** * Checks that this is TripPattern is based of the provided TripPattern and contains same stops * (but not necessarily with same pickup and dropoff values). @@ -394,7 +347,11 @@ public boolean isModifiedFromTripPatternWithEqualStops(TripPattern other) { } /** - * The direction for all the trips in this pattern. + * Return the direction for all the trips in this pattern. + * By construction, all trips in a pattern have the same direction: + * - trips derived from NeTEx data belong to a ServiceJourney that belongs to a JourneyPattern + * that belongs to a NeTEx Route that specifies a single direction. + * - trips derived from GTFS data are grouped by direction in a trip pattern, during graph build. */ public Direction getDirection() { return scheduledTimetable.getDirection(); @@ -503,7 +460,7 @@ private static Coordinate coordinate(StopLocation s) { } @Override - public boolean sameAs(@Nonnull TripPattern other) { + public boolean sameAs(TripPattern other) { return ( getId().equals(other.getId()) && Objects.equals(this.route, other.route) && diff --git a/src/main/java/org/opentripplanner/transit/model/network/TripPatternBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/network/TripPatternBuilder.java similarity index 80% rename from src/main/java/org/opentripplanner/transit/model/network/TripPatternBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/network/TripPatternBuilder.java index f34d206922b..66f695521c0 100644 --- a/src/main/java/org/opentripplanner/transit/model/network/TripPatternBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/network/TripPatternBuilder.java @@ -2,17 +2,20 @@ import java.util.ArrayList; import java.util.List; +import java.util.function.UnaryOperator; import java.util.stream.IntStream; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.LineString; import org.opentripplanner.framework.geometry.CompactLineStringUtils; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.model.Timetable; +import org.opentripplanner.model.TimetableBuilder; import org.opentripplanner.routing.algorithm.raptoradapter.api.SlackProvider; import org.opentripplanner.transit.model.basic.SubMode; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.AbstractEntityBuilder; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.timetable.Direction; @SuppressWarnings("UnusedReturnValue") public final class TripPatternBuilder @@ -24,6 +27,7 @@ public final class TripPatternBuilder private boolean containsMultipleModes; private StopPattern stopPattern; private Timetable scheduledTimetable; + private TimetableBuilder scheduledTimetableBuilder; private String name; private boolean createdByRealtimeUpdate; @@ -33,6 +37,7 @@ public final class TripPatternBuilder TripPatternBuilder(FeedScopedId id) { super(id); + this.scheduledTimetableBuilder = Timetable.of(); } TripPatternBuilder(TripPattern original) { @@ -86,10 +91,28 @@ public TripPatternBuilder withStopPattern(StopPattern stopPattern) { } public TripPatternBuilder withScheduledTimeTable(Timetable scheduledTimetable) { + if (scheduledTimetableBuilder != null) { + throw new IllegalStateException( + "Cannot set scheduled Timetable after scheduled Timetable builder is created" + ); + } this.scheduledTimetable = scheduledTimetable; return this; } + public TripPatternBuilder withScheduledTimeTableBuilder( + UnaryOperator producer + ) { + // create a builder for the scheduled timetable only if it needs to be modified. + // otherwise reuse the existing timetable + if (scheduledTimetableBuilder == null) { + scheduledTimetableBuilder = scheduledTimetable.copyOf(); + scheduledTimetable = null; + } + producer.apply(scheduledTimetableBuilder); + return this; + } + public TripPatternBuilder withCreatedByRealtimeUpdater(boolean createdByRealtimeUpdate) { this.createdByRealtimeUpdate = createdByRealtimeUpdate; return this; @@ -115,6 +138,13 @@ public int transitReluctanceFactorIndex() { return route.getMode().ordinal(); } + public Direction getDirection() { + if (scheduledTimetable != null) { + return scheduledTimetable.getDirection(); + } + return scheduledTimetableBuilder.getDirection(); + } + @Override protected TripPattern buildFromValues() { return new TripPattern(this); @@ -125,11 +155,11 @@ public Route getRoute() { } public TransitMode getMode() { - return mode; + return mode != null ? mode : route.getMode(); } public SubMode getNetexSubmode() { - return netexSubMode; + return netexSubMode != null ? netexSubMode : route.getNetexSubmode(); } public boolean getContainsMultipleModes() { @@ -144,6 +174,10 @@ public Timetable getScheduledTimetable() { return scheduledTimetable; } + public TimetableBuilder getScheduledTimetableBuilder() { + return scheduledTimetableBuilder; + } + public String getName() { return name; } @@ -183,15 +217,12 @@ private List generateHopGeometriesFromOriginalTripPattern() { // being replaced having a different number of stops. In that case the geometry will be // preserved up until the first mismatching stop, and a straight line will be used for // all segments after that. - int sizeOfShortestPattern = Math.min( - stopPattern.getSize(), - originalTripPattern.numberOfStops() - ); - List hopGeometries = new ArrayList<>(); - for (int i = 0; i < sizeOfShortestPattern - 1; i++) { - LineString hopGeometry = originalTripPattern.getHopGeometry(i); + for (int i = 0; i < stopPattern.getSize() - 1; i++) { + LineString hopGeometry = i < originalTripPattern.numberOfStops() - 1 + ? originalTripPattern.getHopGeometry(i) + : null; if (hopGeometry != null && stopPattern.sameStops(originalTripPattern.getStopPattern(), i)) { // Copy hop geometry from previous pattern @@ -200,15 +231,8 @@ private List generateHopGeometriesFromOriginalTripPattern() { hopGeometry != null && stopPattern.sameStations(originalTripPattern.getStopPattern(), i) ) { // Use old geometry but patch first and last point with new stops - var newStart = new Coordinate( - stopPattern.getStop(i).getCoordinate().longitude(), - stopPattern.getStop(i).getCoordinate().latitude() - ); - - var newEnd = new Coordinate( - stopPattern.getStop(i + 1).getCoordinate().longitude(), - stopPattern.getStop(i + 1).getCoordinate().latitude() - ); + var newStart = stopPattern.getStop(i).getCoordinate().asJtsCoordinate(); + var newEnd = stopPattern.getStop(i + 1).getCoordinate().asJtsCoordinate(); Coordinate[] coordinates = originalTripPattern.getHopGeometry(i).getCoordinates().clone(); coordinates[0].setCoordinate(newStart); diff --git a/src/main/java/org/opentripplanner/transit/model/network/grouppriority/BinarySetOperator.java b/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/BinarySetOperator.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/network/grouppriority/BinarySetOperator.java rename to application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/BinarySetOperator.java diff --git a/src/main/java/org/opentripplanner/transit/model/network/grouppriority/DefaultTransitGroupPriorityCalculator.java b/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/DefaultTransitGroupPriorityCalculator.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/network/grouppriority/DefaultTransitGroupPriorityCalculator.java rename to application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/DefaultTransitGroupPriorityCalculator.java diff --git a/src/main/java/org/opentripplanner/transit/model/network/grouppriority/EntityAdapter.java b/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/EntityAdapter.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/network/grouppriority/EntityAdapter.java rename to application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/EntityAdapter.java diff --git a/src/main/java/org/opentripplanner/transit/model/network/grouppriority/Matcher.java b/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/Matcher.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/network/grouppriority/Matcher.java rename to application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/Matcher.java diff --git a/src/main/java/org/opentripplanner/transit/model/network/grouppriority/Matchers.java b/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/Matchers.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/network/grouppriority/Matchers.java rename to application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/Matchers.java diff --git a/src/main/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriority32n.java b/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriority32n.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriority32n.java rename to application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriority32n.java diff --git a/src/main/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriorityService.java b/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriorityService.java similarity index 99% rename from src/main/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriorityService.java rename to application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriorityService.java index 048b2279a88..e8172cdf546 100644 --- a/src/main/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriorityService.java +++ b/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriorityService.java @@ -7,12 +7,12 @@ import java.util.Collection; import java.util.List; import java.util.stream.Stream; -import org.opentripplanner.framework.lang.ArrayUtils; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.request.filter.TransitGroupSelect; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.utils.lang.ArrayUtils; /** * This class dynamically builds an index of transit-group-ids from the provided diff --git a/src/main/java/org/opentripplanner/transit/model/network/grouppriority/TripAdapter.java b/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/TripAdapter.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/network/grouppriority/TripAdapter.java rename to application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/TripAdapter.java diff --git a/src/main/java/org/opentripplanner/transit/model/network/grouppriority/TripPatternAdapter.java b/application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/TripPatternAdapter.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/network/grouppriority/TripPatternAdapter.java rename to application/src/main/java/org/opentripplanner/transit/model/network/grouppriority/TripPatternAdapter.java diff --git a/src/main/java/org/opentripplanner/transit/model/organization/Agency.java b/application/src/main/java/org/opentripplanner/transit/model/organization/Agency.java similarity index 80% rename from src/main/java/org/opentripplanner/transit/model/organization/Agency.java rename to application/src/main/java/org/opentripplanner/transit/model/organization/Agency.java index d72aa6588f3..978cf0ca416 100644 --- a/src/main/java/org/opentripplanner/transit/model/organization/Agency.java +++ b/application/src/main/java/org/opentripplanner/transit/model/organization/Agency.java @@ -1,11 +1,10 @@ /* This file is based on code copied from project OneBusAway, see the LICENSE file for further information. */ package org.opentripplanner.transit.model.organization; -import static org.opentripplanner.framework.lang.StringUtils.assertHasValue; +import static org.opentripplanner.utils.lang.StringUtils.assertHasValue; import java.time.ZoneId; import java.util.Objects; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -22,7 +21,6 @@ public final class Agency extends AbstractTransitEntity i private final String lang; private final String phone; private final String fareUrl; - private final String brandingUrl; Agency(AgencyBuilder builder) { super(builder.getId()); @@ -44,19 +42,16 @@ public final class Agency extends AbstractTransitEntity i this.lang = builder.getLang(); this.phone = builder.getPhone(); this.fareUrl = builder.getFareUrl(); - this.brandingUrl = builder.getBrandingUrl(); } - public static AgencyBuilder of(@Nonnull FeedScopedId id) { + public static AgencyBuilder of(FeedScopedId id) { return new AgencyBuilder(id); } - @Nonnull public String getName() { return logName(); } - @Nonnull public ZoneId getTimezone() { return timezone; } @@ -81,25 +76,18 @@ public String getFareUrl() { return fareUrl; } - @Nullable - public String getBrandingUrl() { - return brandingUrl; - } - @Override - @Nonnull public AgencyBuilder copy() { return new AgencyBuilder(this); } @Override - @Nonnull public String logName() { return name; } @Override - public boolean sameAs(@Nonnull Agency other) { + public boolean sameAs(Agency other) { return ( getId().equals(other.getId()) && Objects.equals(name, other.name) && @@ -107,8 +95,7 @@ public boolean sameAs(@Nonnull Agency other) { Objects.equals(url, other.url) && Objects.equals(lang, other.lang) && Objects.equals(phone, other.phone) && - Objects.equals(fareUrl, other.fareUrl) && - Objects.equals(brandingUrl, other.brandingUrl) + Objects.equals(fareUrl, other.fareUrl) ); } } diff --git a/src/main/java/org/opentripplanner/transit/model/organization/AgencyBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/organization/AgencyBuilder.java similarity index 83% rename from src/main/java/org/opentripplanner/transit/model/organization/AgencyBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/organization/AgencyBuilder.java index 8411797f888..f985a953d9e 100644 --- a/src/main/java/org/opentripplanner/transit/model/organization/AgencyBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/organization/AgencyBuilder.java @@ -1,6 +1,5 @@ package org.opentripplanner.transit.model.organization; -import javax.annotation.Nonnull; import org.opentripplanner.transit.model.framework.AbstractEntityBuilder; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -12,13 +11,12 @@ public class AgencyBuilder extends AbstractEntityBuilder private String lang; private String phone; private String fareUrl; - private String brandingUrl; AgencyBuilder(FeedScopedId id) { super(id); } - AgencyBuilder(@Nonnull Agency original) { + AgencyBuilder(Agency original) { super(original); this.name = original.getName(); this.timezone = original.getTimezone().getId(); @@ -26,7 +24,6 @@ public class AgencyBuilder extends AbstractEntityBuilder this.lang = original.getLang(); this.phone = original.getPhone(); this.fareUrl = original.getFareUrl(); - this.brandingUrl = original.getBrandingUrl(); } public String getName() { @@ -83,15 +80,6 @@ public AgencyBuilder withFareUrl(String fareUrl) { return this; } - public String getBrandingUrl() { - return brandingUrl; - } - - public AgencyBuilder withBrandingUrl(String brandingUrl) { - this.brandingUrl = brandingUrl; - return this; - } - @Override protected Agency buildFromValues() { return new Agency(this); diff --git a/src/main/java/org/opentripplanner/transit/model/organization/Branding.java b/application/src/main/java/org/opentripplanner/transit/model/organization/Branding.java similarity index 92% rename from src/main/java/org/opentripplanner/transit/model/organization/Branding.java rename to application/src/main/java/org/opentripplanner/transit/model/organization/Branding.java index b0599d31341..502c4a27cc7 100644 --- a/src/main/java/org/opentripplanner/transit/model/organization/Branding.java +++ b/application/src/main/java/org/opentripplanner/transit/model/organization/Branding.java @@ -1,7 +1,6 @@ package org.opentripplanner.transit.model.organization; import java.util.Objects; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -30,7 +29,7 @@ public class Branding extends AbstractTransitEntity i this.image = builder.getImage(); } - public static BrandingBuilder of(@Nonnull FeedScopedId id) { + public static BrandingBuilder of(FeedScopedId id) { return new BrandingBuilder(id); } @@ -66,13 +65,12 @@ public String getDescription() { } @Override - @Nonnull public BrandingBuilder copy() { return new BrandingBuilder(this); } @Override - public boolean sameAs(@Nonnull Branding other) { + public boolean sameAs(Branding other) { return ( getId().equals(other.getId()) && Objects.equals(name, other.name) && diff --git a/src/main/java/org/opentripplanner/transit/model/organization/BrandingBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/organization/BrandingBuilder.java similarity index 94% rename from src/main/java/org/opentripplanner/transit/model/organization/BrandingBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/organization/BrandingBuilder.java index 1367d683058..77f35d86fa1 100644 --- a/src/main/java/org/opentripplanner/transit/model/organization/BrandingBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/organization/BrandingBuilder.java @@ -1,6 +1,5 @@ package org.opentripplanner.transit.model.organization; -import javax.annotation.Nonnull; import org.opentripplanner.transit.model.framework.AbstractEntityBuilder; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -16,7 +15,7 @@ public class BrandingBuilder extends AbstractEntityBuilder { @@ -28,7 +27,6 @@ public class ContactInfo implements TransitObject i this.phone = builder.getPhone(); } - public static OperatorBuilder of(@Nonnull FeedScopedId id) { + public static OperatorBuilder of(FeedScopedId id) { return new OperatorBuilder(id); } - @Nonnull public String getName() { return logName(); } @Override - @Nonnull public String logName() { return name; } @@ -60,13 +57,12 @@ public String getPhone() { } @Override - @Nonnull public OperatorBuilder copy() { return new OperatorBuilder(this); } @Override - public boolean sameAs(@Nonnull Operator other) { + public boolean sameAs(Operator other) { return ( getId().equals(other.getId()) && Objects.equals(name, other.name) && diff --git a/src/main/java/org/opentripplanner/transit/model/organization/OperatorBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/organization/OperatorBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/organization/OperatorBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/organization/OperatorBuilder.java diff --git a/src/main/java/org/opentripplanner/transit/model/package.md b/application/src/main/java/org/opentripplanner/transit/model/package.md similarity index 92% rename from src/main/java/org/opentripplanner/transit/model/package.md rename to application/src/main/java/org/opentripplanner/transit/model/package.md index 9c10c88828c..26ed7facde3 100644 --- a/src/main/java/org/opentripplanner/transit/model/package.md +++ b/application/src/main/java/org/opentripplanner/transit/model/package.md @@ -23,10 +23,9 @@ All transit entities must have an ID. Transit entities ar "root" level are consi roots_. -#### @Nonnull and @Nullable entity fields +#### Non-null and nullable entity fields -All fields getters(except primitive types) should be annotated with `@Nullable` or `@Nonnull`. None -null field should be enforced in the Entity constructor by using `Objects.requireNonNull`, +Non-nullability of fields should be enforced in the Entity constructor by using `Objects.requireNonNull`, `Objects.requireNonNullElse` or `ObjectUtils.ifNotNull`. We should enforce this for all fields required in both GTFS and in the Nordic NeTEx Profile. For enumeration types using a special value like `UNKNOWN` is preferred over making the field optional. diff --git a/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java b/application/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java similarity index 96% rename from src/main/java/org/opentripplanner/transit/model/site/AreaStop.java rename to application/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java index 35576e0c42f..03844c80b77 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java @@ -3,7 +3,6 @@ import java.util.Objects; import java.util.Optional; import java.util.function.IntSupplier; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.locationtech.jts.geom.Geometry; import org.opentripplanner.framework.geometry.WgsCoordinate; @@ -69,7 +68,6 @@ public int getIndex() { * communication, eg. the name of the village where the service stops. */ @Override - @Nonnull public I18NString getName() { return name; } @@ -85,7 +83,6 @@ public I18NString getUrl() { return url; } - @Nonnull @Override public StopType getStopType() { return StopType.FLEXIBLE_AREA; @@ -97,7 +94,6 @@ public String getFirstZoneAsString() { } @Override - @Nonnull public WgsCoordinate getCoordinate() { return centroid; } @@ -137,7 +133,7 @@ public boolean hasFallbackName() { } @Override - public boolean sameAs(@Nonnull AreaStop other) { + public boolean sameAs(AreaStop other) { return ( getId().equals(other.getId()) && Objects.equals(name, other.getName()) && @@ -149,7 +145,6 @@ public boolean sameAs(@Nonnull AreaStop other) { } @Override - @Nonnull public AreaStopBuilder copy() { return new AreaStopBuilder(this); } diff --git a/src/main/java/org/opentripplanner/transit/model/site/AreaStopBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/site/AreaStopBuilder.java similarity index 96% rename from src/main/java/org/opentripplanner/transit/model/site/AreaStopBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/site/AreaStopBuilder.java index 8e29ad4acbf..51bbc06f427 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/AreaStopBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/AreaStopBuilder.java @@ -2,7 +2,6 @@ import java.util.Objects; import java.util.function.IntSupplier; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.Geometry; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; @@ -26,7 +25,7 @@ public class AreaStopBuilder extends AbstractEntityBuilder getChildStops() { return this.childStations.stream().flatMap(s -> s.getChildStops().stream()).toList(); } - @Nonnull public Collection getChildStations() { return this.childStations; } @@ -70,7 +66,7 @@ public GroupOfStationsPurpose getPurposeOfGrouping() { } @Override - public boolean sameAs(@Nonnull GroupOfStations other) { + public boolean sameAs(GroupOfStations other) { return ( getId().equals(other.getId()) && Objects.equals(name, other.getName()) && @@ -80,7 +76,6 @@ public boolean sameAs(@Nonnull GroupOfStations other) { ); } - @Nonnull @Override public GroupOfStationsBuilder copy() { return new GroupOfStationsBuilder(this); diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupOfStationsBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/site/GroupOfStationsBuilder.java similarity index 95% rename from src/main/java/org/opentripplanner/transit/model/site/GroupOfStationsBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/site/GroupOfStationsBuilder.java index 72da8921446..a9e87c4c022 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupOfStationsBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/GroupOfStationsBuilder.java @@ -2,7 +2,6 @@ import java.util.HashSet; import java.util.Set; -import javax.annotation.Nonnull; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.transit.model.framework.AbstractEntityBuilder; @@ -20,7 +19,7 @@ public class GroupOfStationsBuilder super(id); } - GroupOfStationsBuilder(@Nonnull GroupOfStations original) { + GroupOfStationsBuilder(GroupOfStations original) { super(original); // Required fields this.name = I18NString.assertHasValue(original.getName()); diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupOfStationsPurpose.java b/application/src/main/java/org/opentripplanner/transit/model/site/GroupOfStationsPurpose.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/site/GroupOfStationsPurpose.java rename to application/src/main/java/org/opentripplanner/transit/model/site/GroupOfStationsPurpose.java diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java b/application/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java similarity index 96% rename from src/main/java/org/opentripplanner/transit/model/site/GroupStop.java rename to application/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java index c674d588238..40618e60ace 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java @@ -4,7 +4,6 @@ import java.util.Objects; import java.util.Optional; import java.util.function.IntSupplier; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryCollection; @@ -65,7 +64,6 @@ public I18NString getUrl() { } @Override - @Nonnull public StopType getStopType() { return StopType.FLEXIBLE_GROUP; } @@ -79,7 +77,6 @@ public String getFirstZoneAsString() { * Returns the centroid of all stops and areas belonging to this location group. */ @Override - @Nonnull public WgsCoordinate getCoordinate() { return centroid; } @@ -116,13 +113,12 @@ public boolean isPartOfSameStationAs(StopLocation alternativeStop) { * Returns all the locations belonging to this location group. */ @Override - @Nonnull public List getChildLocations() { return stopLocations; } @Override - public boolean sameAs(@Nonnull GroupStop other) { + public boolean sameAs(GroupStop other) { return ( getId().equals(other.getId()) && Objects.equals(name, other.getName()) && @@ -131,7 +127,6 @@ public boolean sameAs(@Nonnull GroupStop other) { } @Override - @Nonnull public GroupStopBuilder copy() { return new GroupStopBuilder(this); } diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java similarity index 97% rename from src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java index 64cad9325d1..c51b704aa33 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java @@ -3,7 +3,6 @@ import java.util.ArrayList; import java.util.List; import java.util.function.IntSupplier; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryCollection; import org.opentripplanner.framework.geometry.GeometryUtils; @@ -34,7 +33,7 @@ public class GroupStopBuilder extends AbstractEntityBuilder getFareZones() { return fareZones; } - @Nonnull public Collection getBoardingAreas() { return boardingAreas; } @Override - @Nonnull public RegularStopBuilder copy() { return new RegularStopBuilder(this); } @Override - public boolean sameAs(@Nonnull RegularStop other) { + public boolean sameAs(RegularStop other) { return ( super.sameAs(other) && Objects.equals(platformCode, other.platformCode) && Objects.equals(url, other.url) && Objects.equals(timeZone, other.timeZone) && - Objects.equals(gtfsVehicleType, other.gtfsVehicleType) && + Objects.equals(vehicleType, other.vehicleType) && Objects.equals(netexVehicleSubmode, other.netexVehicleSubmode) && Objects.equals(boardingAreas, other.boardingAreas) && Objects.equals(fareZones, other.fareZones) diff --git a/src/main/java/org/opentripplanner/transit/model/site/RegularStopBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/site/RegularStopBuilder.java similarity index 94% rename from src/main/java/org/opentripplanner/transit/model/site/RegularStopBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/site/RegularStopBuilder.java index 3b37a709078..5e6cd01618b 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/RegularStopBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/RegularStopBuilder.java @@ -26,7 +26,7 @@ public final class RegularStopBuilder private ZoneId timeZone; - private TransitMode gtfsVehicleType; + private TransitMode vehicleType; private String netexVehicleSubmode; @@ -45,7 +45,7 @@ public final class RegularStopBuilder this.platformCode = original.getPlatformCode(); this.url = original.getUrl(); this.timeZone = original.getTimeZone(); - this.gtfsVehicleType = original.getGtfsVehicleType(); + this.vehicleType = original.getVehicleType(); this.netexVehicleSubmode = original.getNetexVehicleSubmode().name(); } @@ -68,11 +68,11 @@ public RegularStopBuilder withUrl(I18NString url) { } public TransitMode vehicleType() { - return gtfsVehicleType; + return vehicleType; } public RegularStopBuilder withVehicleType(TransitMode vehicleType) { - this.gtfsVehicleType = vehicleType; + this.vehicleType = vehicleType; return this; } diff --git a/src/main/java/org/opentripplanner/transit/model/site/Station.java b/application/src/main/java/org/opentripplanner/transit/model/site/Station.java similarity index 92% rename from src/main/java/org/opentripplanner/transit/model/site/Station.java rename to application/src/main/java/org/opentripplanner/transit/model/site/Station.java index 68ce2d6d5a2..c8d2558a5cd 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/Station.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/Station.java @@ -9,7 +9,6 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.locationtech.jts.algorithm.ConvexHull; import org.locationtech.jts.geom.Geometry; @@ -34,6 +33,7 @@ public class Station private final String code; private final I18NString description; private final WgsCoordinate coordinate; + private final boolean shouldRouteToCentroid; private final StopTransferPriority priority; private final I18NString url; private final ZoneId timezone; @@ -50,6 +50,7 @@ public class Station // Required fields this.name = Objects.requireNonNull(builder.getName()); this.coordinate = Objects.requireNonNull(builder.getCoordinate()); + this.shouldRouteToCentroid = builder.shouldRouteToCentroid(); this.priority = Objects.requireNonNullElse(builder.getPriority(), StopTransferPriority.defaultValue()); this.transfersNotAllowed = builder.isTransfersNotAllowed(); @@ -77,12 +78,10 @@ public boolean includes(StopLocation stop) { return childStops.contains(stop); } - @Nonnull public I18NString getName() { return name; } - @Nonnull public Collection getChildStops() { return childStops; } @@ -97,11 +96,18 @@ public double getLon() { return coordinate.longitude(); } - @Nonnull public WgsCoordinate getCoordinate() { return coordinate; } + /** + * When doing a street search from/to the station, we can either route to the centroid of the station + * or from/to any child stop. This feature is inactive unless configured. + */ + public boolean shouldRouteToCentroid() { + return shouldRouteToCentroid; + } + /** Public facing station code (short text or number) */ @Nullable public String getCode() { @@ -132,7 +138,6 @@ public I18NString getUrl() { * that the {@link StopTransferPriority#ALLOWED} (which is default) should a nett-effect of adding * 0 - zero cost. */ - @Nonnull public StopTransferPriority getPriority() { return priority; } @@ -153,7 +158,6 @@ public boolean isTransfersNotAllowed() { * A geometry collection that contains the center point and the convex hull of all the child * stops. */ - @Nonnull public GeometryCollection getGeometry() { return geometry; } @@ -165,19 +169,19 @@ public String logName() { } @Override - @Nonnull public StationBuilder copy() { return new StationBuilder(this); } @Override - public boolean sameAs(@Nonnull Station other) { + public boolean sameAs(Station other) { return ( getId().equals(other.getId()) && Objects.equals(name, other.name) && Objects.equals(code, other.code) && Objects.equals(description, other.description) && Objects.equals(coordinate, other.coordinate) && + Objects.equals(shouldRouteToCentroid, other.shouldRouteToCentroid) && Objects.equals(priority, other.priority) && Objects.equals(url, other.url) && Objects.equals(timezone, other.timezone) diff --git a/src/main/java/org/opentripplanner/transit/model/site/StationBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/site/StationBuilder.java similarity index 88% rename from src/main/java/org/opentripplanner/transit/model/site/StationBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/site/StationBuilder.java index 8d74f36fb73..79b3b529146 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/StationBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/StationBuilder.java @@ -16,6 +16,7 @@ public class StationBuilder extends AbstractEntityBuilder getFareZones() { return List.of(); } - @Nonnull default Accessibility getWheelchairAccessibility() { return Accessibility.NO_INFORMATION; } @@ -112,7 +107,6 @@ default String getFirstZoneAsString() { * Representative location for the StopLocation. Can either be the actual location of the stop, or * the centroid of an area or line. */ - @Nonnull WgsCoordinate getCoordinate(); /** @@ -140,7 +134,6 @@ default ZoneId getTimeZone() { boolean isPartOfStation(); - @Nonnull default StopTransferPriority getPriority() { return StopTransferPriority.defaultValue(); } diff --git a/src/main/java/org/opentripplanner/transit/model/site/StopLocationsGroup.java b/application/src/main/java/org/opentripplanner/transit/model/site/StopLocationsGroup.java similarity index 95% rename from src/main/java/org/opentripplanner/transit/model/site/StopLocationsGroup.java rename to application/src/main/java/org/opentripplanner/transit/model/site/StopLocationsGroup.java index 3536f59e9b6..4158828e9a4 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/StopLocationsGroup.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/StopLocationsGroup.java @@ -3,9 +3,9 @@ import java.util.Collection; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.lang.ObjectUtils; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.framework.LogInfo; +import org.opentripplanner.utils.lang.ObjectUtils; /** * A grouping of Stops referred to by the same name. No actual boarding or alighting happens at this diff --git a/src/main/java/org/opentripplanner/transit/model/site/StopTransferPriority.java b/application/src/main/java/org/opentripplanner/transit/model/site/StopTransferPriority.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/site/StopTransferPriority.java rename to application/src/main/java/org/opentripplanner/transit/model/site/StopTransferPriority.java diff --git a/src/main/java/org/opentripplanner/transit/model/site/StopType.java b/application/src/main/java/org/opentripplanner/transit/model/site/StopType.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/site/StopType.java rename to application/src/main/java/org/opentripplanner/transit/model/site/StopType.java diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/Direction.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/Direction.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/timetable/Direction.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/Direction.java diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/FrequencyEntry.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/FrequencyEntry.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/timetable/FrequencyEntry.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/FrequencyEntry.java diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/OccupancyStatus.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/OccupancyStatus.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/timetable/OccupancyStatus.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/OccupancyStatus.java diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/RealTimeState.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/RealTimeState.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/timetable/RealTimeState.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/RealTimeState.java diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimes.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimes.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimes.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimes.java diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimes.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimes.java similarity index 98% rename from src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimes.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimes.java index 3cae0c1678b..9a7298cd15e 100644 --- a/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimes.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimes.java @@ -13,14 +13,14 @@ 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.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.framework.DataValidationException; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.DeduplicatorService; import org.opentripplanner.transit.model.timetable.booking.BookingInfo; +import org.opentripplanner.utils.lang.IntUtils; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; /** * Regular/planed/scheduled read-only version of {@link TripTimes}. The set of static diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesBuilder.java similarity index 99% rename from src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesBuilder.java index 200afc27e8d..acca4a6a526 100644 --- a/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesBuilder.java @@ -4,9 +4,9 @@ import java.util.List; import javax.annotation.Nullable; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.transit.model.framework.DeduplicatorService; import org.opentripplanner.transit.model.timetable.booking.BookingInfo; +import org.opentripplanner.utils.time.TimeUtils; public class ScheduledTripTimesBuilder { diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/StopRealTimeState.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/StopRealTimeState.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/timetable/StopRealTimeState.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/StopRealTimeState.java diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/StopTimeKey.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/StopTimeKey.java similarity index 84% rename from src/main/java/org/opentripplanner/transit/model/timetable/StopTimeKey.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/StopTimeKey.java index d110778a267..d3267804f70 100644 --- a/src/main/java/org/opentripplanner/transit/model/timetable/StopTimeKey.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/StopTimeKey.java @@ -1,6 +1,5 @@ package org.opentripplanner.transit.model.timetable; -import javax.annotation.Nonnull; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -16,18 +15,17 @@ public class StopTimeKey extends AbstractTransitEntityA scheduled Trip can run at most once per service date, + * while a frequency-based Trip runs several times on a given service date. + *

    A Trip can run on multiple service dates. + *

    The service dates on which a trip is running are identified + * by its service id and can be looked up with + * {@link org.opentripplanner.model.calendar.CalendarService}. + *

    Trips that follow the same sequence of stops are grouped under a {@link org.opentripplanner.transit.model.network.TripPattern} + * via a {@link org.opentripplanner.model.Timetable} + *

    A Trip is equivalent to the TransModel concept of SERVICE JOURNEY. + */ public final class Trip extends AbstractTransitEntity implements LogInfo { - private final Operator operator; private final Route route; - private final FeedScopedId serviceId; - private final String shortName; private final TransitMode mode; - private final SubMode netexSubmode; - private final I18NString headsign; - private final FeedScopedId shapeId; - private final Direction direction; private final BikeAccess bikesAllowed; + private final CarAccess carsAllowed; private final Accessibility wheelchairBoarding; + private final SubMode netexSubmode; + private final TripAlteration netexAlteration; + + @Nullable + private final Operator operator; + + @Nullable + private final FeedScopedId serviceId; + + @Nullable + private final String shortName; + + @Nullable + private final I18NString headsign; + + @Nullable + private final FeedScopedId shapeId; + + @Nullable private final String gtfsBlockId; + @Nullable private final String netexInternalPlanningCode; - private final TripAlteration netexAlteration; Trip(TripBuilder builder) { super(builder.getId()); @@ -52,6 +78,7 @@ public final class Trip extends AbstractTransitEntity impleme : route.getNetexSubmode(); this.direction = requireNonNullElse(builder.getDirection(), Direction.UNKNOWN); this.bikesAllowed = requireNonNullElse(builder.getBikesAllowed(), route.getBikesAllowed()); + this.carsAllowed = requireNonNullElse(builder.getCarsAllowed(), CarAccess.UNKNOWN); this.wheelchairBoarding = requireNonNullElse(builder.getWheelchairBoarding(), Accessibility.NO_INFORMATION); this.netexAlteration = requireNonNullElse(builder.getNetexAlteration(), TripAlteration.PLANNED); @@ -67,7 +94,7 @@ public final class Trip extends AbstractTransitEntity impleme this.netexInternalPlanningCode = builder.getNetexInternalPlanningCode(); } - public static TripBuilder of(@Nonnull FeedScopedId id) { + public static TripBuilder of(FeedScopedId id) { return new TripBuilder(id); } @@ -80,7 +107,6 @@ public Operator getOperator() { return operator; } - @Nonnull public Route getRoute() { return route; } @@ -104,12 +130,10 @@ public String getShortName() { return shortName; } - @Nonnull public TransitMode getMode() { return mode; } - @Nonnull public SubMode getNetexSubMode() { return netexSubmode; } @@ -127,17 +151,18 @@ public FeedScopedId getShapeId() { /** * The direction for this Trip (and all other Trips in this TripPattern). */ - @Nonnull public Direction getDirection() { return direction; } - @Nonnull public BikeAccess getBikesAllowed() { return bikesAllowed; } - @Nonnull + public CarAccess getCarsAllowed() { + return carsAllowed; + } + public Accessibility getWheelchairBoarding() { return wheelchairBoarding; } @@ -162,7 +187,6 @@ public String getNetexInternalPlanningCode() { *

    * This is planned, by default (e.g. GTFS and if not set explicit). */ - @Nonnull public TripAlteration getNetexAlteration() { return netexAlteration; } @@ -185,7 +209,7 @@ public String logName() { } @Override - public boolean sameAs(@Nonnull Trip other) { + public boolean sameAs(Trip other) { return ( getId().equals(other.getId()) && Objects.equals(this.operator, other.operator) && @@ -200,6 +224,7 @@ public boolean sameAs(@Nonnull Trip other) { Objects.equals(this.shapeId, other.shapeId) && Objects.equals(this.direction, other.direction) && Objects.equals(this.bikesAllowed, other.bikesAllowed) && + Objects.equals(this.carsAllowed, other.carsAllowed) && Objects.equals(this.wheelchairBoarding, other.wheelchairBoarding) && Objects.equals(this.netexAlteration, other.netexAlteration) ); diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/TripAlteration.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripAlteration.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/timetable/TripAlteration.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/TripAlteration.java diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/TripBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripBuilder.java similarity index 93% rename from src/main/java/org/opentripplanner/transit/model/timetable/TripBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/TripBuilder.java index 063dfe10da2..5ed0616831d 100644 --- a/src/main/java/org/opentripplanner/transit/model/timetable/TripBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripBuilder.java @@ -6,6 +6,7 @@ import org.opentripplanner.transit.model.framework.AbstractEntityBuilder; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.BikeAccess; +import org.opentripplanner.transit.model.network.CarAccess; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Operator; @@ -21,6 +22,7 @@ public class TripBuilder extends AbstractEntityBuilder { private FeedScopedId shapeId; private Direction direction; private BikeAccess bikesAllowed; + private CarAccess carsAllowed; private Accessibility wheelchairBoarding; private String gtfsBlockId; private String netexInternalPlanningCode; @@ -44,6 +46,7 @@ public class TripBuilder extends AbstractEntityBuilder { this.shapeId = original.getShapeId(); this.direction = original.getDirection(); this.bikesAllowed = original.getBikesAllowed(); + this.carsAllowed = original.getCarsAllowed(); this.wheelchairBoarding = original.getWheelchairBoarding(); this.netexInternalPlanningCode = original.getNetexInternalPlanningCode(); } @@ -151,11 +154,20 @@ public BikeAccess getBikesAllowed() { return bikesAllowed; } + public CarAccess getCarsAllowed() { + return carsAllowed; + } + public TripBuilder withBikesAllowed(BikeAccess bikesAllowed) { this.bikesAllowed = bikesAllowed; return this; } + public TripBuilder withCarsAllowed(CarAccess carsAllowed) { + this.carsAllowed = carsAllowed; + return this; + } + public Accessibility getWheelchairBoarding() { return wheelchairBoarding; } diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/TripIdAndServiceDate.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripIdAndServiceDate.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/timetable/TripIdAndServiceDate.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/TripIdAndServiceDate.java diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDate.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDate.java similarity index 84% rename from src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDate.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDate.java index 1b4ecc964cf..1a22ec70000 100644 --- a/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDate.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDate.java @@ -3,7 +3,6 @@ import java.time.LocalDate; import java.util.List; import java.util.Objects; -import javax.annotation.Nonnull; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -26,7 +25,7 @@ public class TripOnServiceDate this.replacementFor = builder.getReplacementFor(); } - public static TripOnServiceDateBuilder of(@Nonnull FeedScopedId id) { + public static TripOnServiceDateBuilder of(FeedScopedId id) { return new TripOnServiceDateBuilder(id); } @@ -46,12 +45,8 @@ public List getReplacementFor() { return replacementFor; } - public TripIdAndServiceDate getTripIdAndServiceDate() { - return new TripIdAndServiceDate(trip.getId(), serviceDate); - } - @Override - public boolean sameAs(@Nonnull TripOnServiceDate other) { + public boolean sameAs(TripOnServiceDate other) { return ( getId().equals(other.getId()) && Objects.equals(this.trip, other.trip) && @@ -61,7 +56,6 @@ public boolean sameAs(@Nonnull TripOnServiceDate other) { ); } - @Nonnull @Override public TripOnServiceDateBuilder copy() { return new TripOnServiceDateBuilder(this); diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDateBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDateBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDateBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/TripOnServiceDateBuilder.java diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/TripTimes.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripTimes.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/timetable/TripTimes.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/TripTimes.java diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/TripTimesFactory.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripTimesFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/timetable/TripTimesFactory.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/TripTimesFactory.java diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/TripTimesStringBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripTimesStringBuilder.java similarity index 97% rename from src/main/java/org/opentripplanner/transit/model/timetable/TripTimesStringBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/TripTimesStringBuilder.java index a5e77037dea..143cb59ff31 100644 --- a/src/main/java/org/opentripplanner/transit/model/timetable/TripTimesStringBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/TripTimesStringBuilder.java @@ -1,8 +1,8 @@ package org.opentripplanner.transit.model.timetable; import java.util.ArrayList; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.utils.time.TimeUtils; public class TripTimesStringBuilder { diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingInfo.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingInfo.java similarity index 92% rename from src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingInfo.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingInfo.java index 3e23696b65a..8b48a61ffbe 100644 --- a/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingInfo.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingInfo.java @@ -3,9 +3,10 @@ import java.io.Serializable; import java.time.Duration; import java.util.EnumSet; +import java.util.Optional; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.transit.model.organization.ContactInfo; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Info about how a trip might be booked at a particular stop. All of this is pass-through @@ -99,14 +100,12 @@ public BookingTime getLatestBookingTime() { return latestBookingTime; } - @Nullable - public Duration getMinimumBookingNotice() { - return minimumBookingNotice; + public Optional getMinimumBookingNotice() { + return Optional.ofNullable(minimumBookingNotice); } - @Nullable - public Duration getMaximumBookingNotice() { - return maximumBookingNotice; + public Optional getMaximumBookingNotice() { + return Optional.ofNullable(maximumBookingNotice); } @Nullable diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingInfoBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingInfoBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingInfoBuilder.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingInfoBuilder.java diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingMethod.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingMethod.java similarity index 100% rename from src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingMethod.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingMethod.java diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingTime.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingTime.java similarity index 96% rename from src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingTime.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingTime.java index 8034fe07388..d0f1558e0d4 100644 --- a/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingTime.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/booking/BookingTime.java @@ -3,7 +3,7 @@ import java.io.Serializable; import java.time.LocalTime; import java.util.Objects; -import org.opentripplanner.framework.time.TimeUtils; +import org.opentripplanner.utils.time.TimeUtils; /** * Represents either the earliest or latest time a trip can be booked relative to the departure day diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfo.java b/application/src/main/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfo.java similarity index 95% rename from src/main/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfo.java rename to application/src/main/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfo.java index 8dad53a0bde..11ea27d48aa 100644 --- a/src/main/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfo.java +++ b/application/src/main/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfo.java @@ -3,7 +3,7 @@ import java.time.Duration; import java.util.Objects; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This is the contract between booking info and the router. The router will enforce @@ -151,17 +151,17 @@ Builder withBookingInfo(@Nullable BookingInfo bookingInfo) { return this; } withLatestBookingTime(bookingInfo.getLatestBookingTime()); - withMinimumBookingNotice(bookingInfo.getMinimumBookingNotice()); + withMinimumBookingNotice(bookingInfo.getMinimumBookingNotice().orElse(null)); return this; } - public Builder withLatestBookingTime(BookingTime latestBookingTime) { + public Builder withLatestBookingTime(@Nullable BookingTime latestBookingTime) { this.latestBookingTime = latestBookingTime == null ? NOT_SET : latestBookingTime.relativeTimeSeconds(); return this; } - public Builder withMinimumBookingNotice(Duration minimumBookingNotice) { + public Builder withMinimumBookingNotice(@Nullable Duration minimumBookingNotice) { this.minimumBookingNotice = minimumBookingNotice == null ? NOT_SET : (int) minimumBookingNotice.toSeconds(); return this; diff --git a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java b/application/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java similarity index 61% rename from src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java rename to application/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java index 8fa18443bab..d35977cae74 100644 --- a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java +++ b/application/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java @@ -22,7 +22,6 @@ import org.locationtech.jts.geom.Envelope; import org.opentripplanner.ext.flex.FlexIndex; import org.opentripplanner.framework.application.OTPRequestTimeoutException; -import org.opentripplanner.framework.collection.CollectionsView; import org.opentripplanner.model.FeedInfo; import org.opentripplanner.model.PathTransfer; import org.opentripplanner.model.StopTimesInPattern; @@ -35,8 +34,13 @@ import org.opentripplanner.routing.services.TransitAlertService; import org.opentripplanner.routing.stoptimes.ArrivalDeparture; import org.opentripplanner.routing.stoptimes.StopTimesHelper; +import org.opentripplanner.transit.api.request.TripOnServiceDateRequest; +import org.opentripplanner.transit.api.request.TripRequest; import org.opentripplanner.transit.model.basic.Notice; import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.transit.model.filter.expr.Matcher; +import org.opentripplanner.transit.model.filter.transit.TripMatcherFactory; +import org.opentripplanner.transit.model.filter.transit.TripOnServiceDateMatcherFactory; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -56,6 +60,7 @@ import org.opentripplanner.transit.model.timetable.TripIdAndServiceDate; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.updater.GraphUpdaterStatus; +import org.opentripplanner.utils.collection.CollectionsView; /** * Default implementation of the Transit Service and Transit Editor Service. @@ -65,9 +70,9 @@ */ public class DefaultTransitService implements TransitEditorService { - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; - private final TransitModelIndex transitModelIndex; + private final TimetableRepositoryIndex timetableRepositoryIndex; /** * This should only be accessed through the getTimetableSnapshot method. @@ -75,122 +80,106 @@ public class DefaultTransitService implements TransitEditorService { private TimetableSnapshot timetableSnapshot; @Inject - public DefaultTransitService(TransitModel transitModel) { - this.transitModel = transitModel; - this.transitModelIndex = transitModel.getTransitModelIndex(); + public DefaultTransitService(TimetableRepository timetableRepository) { + this.timetableRepository = timetableRepository; + this.timetableRepositoryIndex = timetableRepository.getTimetableRepositoryIndex(); } public DefaultTransitService( - TransitModel transitModel, + TimetableRepository timetableRepository, TimetableSnapshot timetableSnapshotBuffer ) { - this(transitModel); + this(timetableRepository); this.timetableSnapshot = timetableSnapshotBuffer; } @Override - public Collection getFeedIds() { - return this.transitModel.getFeedIds(); + public Collection listFeedIds() { + return this.timetableRepository.getFeedIds(); } @Override - public Collection getAgencies() { + public Collection listAgencies() { OTPRequestTimeoutException.checkForTimeout(); - return this.transitModel.getAgencies(); + return this.timetableRepository.getAgencies(); } @Override - public Optional findAgencyById(FeedScopedId id) { - return this.transitModel.findAgencyById(id); + public Optional findAgency(FeedScopedId id) { + return this.timetableRepository.findAgencyById(id); } @Override public FeedInfo getFeedInfo(String feedId) { - return this.transitModel.getFeedInfo(feedId); + return this.timetableRepository.getFeedInfo(feedId); } @Override public void addAgency(Agency agency) { - this.transitModel.addAgency(agency); + this.timetableRepository.addAgency(agency); } @Override public void addFeedInfo(FeedInfo info) { - this.transitModel.addFeedInfo(info); + this.timetableRepository.addFeedInfo(info); } @Override - public Collection getOperators() { - return this.transitModel.getOperators(); + public Collection findNotices(AbstractTransitEntity entity) { + return this.timetableRepository.getNoticesByElement().get(entity); } @Override - public Collection getNoticesByEntity(AbstractTransitEntity entity) { - return this.transitModel.getNoticesByElement().get(entity); + public TripPattern getTripPattern(FeedScopedId id) { + return this.timetableRepository.getTripPatternForId(id); } @Override - public TripPattern getTripPatternForId(FeedScopedId id) { - return this.transitModel.getTripPatternForId(id); - } - - @Override - public Collection getAllTripPatterns() { - OTPRequestTimeoutException.checkForTimeout(); - return this.transitModel.getAllTripPatterns(); - } - - @Override - public Collection getNotices() { + public Collection listTripPatterns() { OTPRequestTimeoutException.checkForTimeout(); - return this.transitModel.getNoticesByElement().values(); + return this.timetableRepository.getAllTripPatterns(); } @Override - public Station getStationById(FeedScopedId id) { - return this.transitModel.getStopModel().getStationById(id); + public Station getStation(FeedScopedId id) { + return this.timetableRepository.getSiteRepository().getStationById(id); } @Override public MultiModalStation getMultiModalStation(FeedScopedId id) { - return this.transitModel.getStopModel().getMultiModalStation(id); + return this.timetableRepository.getSiteRepository().getMultiModalStation(id); } @Override - public Collection getStations() { + public Collection listStations() { OTPRequestTimeoutException.checkForTimeout(); - return this.transitModel.getStopModel().listStations(); + return this.timetableRepository.getSiteRepository().listStations(); } @Override - public Integer getServiceCodeForId(FeedScopedId id) { - return this.transitModel.getServiceCodes().get(id); + public Integer getServiceCode(FeedScopedId id) { + return this.timetableRepository.getServiceCodes().get(id); } @Override public TIntSet getServiceCodesRunningForDate(LocalDate serviceDate) { - return transitModelIndex + return timetableRepositoryIndex .getServiceCodesRunningForDate() .getOrDefault(serviceDate, new TIntHashSet()); } @Override - public AreaStop getAreaStop(FeedScopedId id) { - return this.transitModel.getStopModel().getAreaStop(id); - } - - @Override - public Agency getAgencyForId(FeedScopedId id) { - return this.transitModelIndex.getAgencyForId(id); + public Agency getAgency(FeedScopedId id) { + return this.timetableRepositoryIndex.getAgencyForId(id); } @Override public RegularStop getRegularStop(FeedScopedId id) { - return this.transitModel.getStopModel().getRegularStop(id); + return this.timetableRepository.getSiteRepository().getRegularStop(id); } @Override - public Route getRouteForId(FeedScopedId id) { + public Route getRoute(FeedScopedId id) { TimetableSnapshot currentSnapshot = lazyGetTimeTableSnapShot(); if (currentSnapshot != null) { Route realtimeAddedRoute = currentSnapshot.getRealtimeAddedRoute(id); @@ -198,7 +187,7 @@ public Route getRouteForId(FeedScopedId id) { return realtimeAddedRoute; } } - return transitModelIndex.getRouteForId(id); + return timetableRepositoryIndex.getRouteForId(id); } /** @@ -207,79 +196,67 @@ public Route getRouteForId(FeedScopedId id) { */ @Override public void addRoutes(Route route) { - this.transitModelIndex.addRoutes(route); + this.timetableRepositoryIndex.addRoutes(route); } @Override - public Set getRoutesForStop(StopLocation stop) { + public Set findRoutes(StopLocation stop) { OTPRequestTimeoutException.checkForTimeout(); - return this.transitModelIndex.getRoutesForStop(stop); + return this.timetableRepositoryIndex.getRoutesForStop(stop); } @Override - public Collection getPatternsForStop(StopLocation stop) { + public Collection findPatterns(StopLocation stop) { OTPRequestTimeoutException.checkForTimeout(); - return this.transitModelIndex.getPatternsForStop(stop); + return this.timetableRepositoryIndex.getPatternsForStop(stop); } @Override - public Collection getTripsForStop(StopLocation stop) { + public Collection listOperators() { OTPRequestTimeoutException.checkForTimeout(); - return this.transitModelIndex.getTripsForStop(stop); + return this.timetableRepository.getOperators(); } @Override - public Collection getAllOperators() { - OTPRequestTimeoutException.checkForTimeout(); - return this.transitModelIndex.getAllOperators(); - } - - @Override - public Operator getOperatorForId(FeedScopedId id) { - return this.transitModelIndex.getOperatorForId().get(id); + public Operator getOperator(FeedScopedId id) { + return this.timetableRepositoryIndex.getOperatorForId(id); } @Override public Collection listStopLocations() { OTPRequestTimeoutException.checkForTimeout(); - return transitModel.getStopModel().listStopLocations(); - } - - @Override - public Collection listRegularStops() { - OTPRequestTimeoutException.checkForTimeout(); - return transitModel.getStopModel().listRegularStops(); + return timetableRepository.getSiteRepository().listStopLocations(); } @Override public Collection listGroupStops() { OTPRequestTimeoutException.checkForTimeout(); - return transitModel.getStopModel().listGroupStops(); + return timetableRepository.getSiteRepository().listGroupStops(); } @Override public StopLocation getStopLocation(FeedScopedId id) { - return transitModel.getStopModel().getStopLocation(id); + return timetableRepository.getSiteRepository().getStopLocation(id); } @Override - public Collection getStopOrChildStops(FeedScopedId id) { - return transitModel.getStopModel().findStopOrChildStops(id); + public Collection findStopOrChildStops(FeedScopedId id) { + return timetableRepository.getSiteRepository().findStopOrChildStops(id); } @Override public Collection listStopLocationGroups() { OTPRequestTimeoutException.checkForTimeout(); - return transitModel.getStopModel().listStopLocationGroups(); + return timetableRepository.getSiteRepository().listStopLocationGroups(); } @Override public StopLocationsGroup getStopLocationsGroup(FeedScopedId id) { - return transitModel.getStopModel().getStopLocationsGroup(id); + return timetableRepository.getSiteRepository().getStopLocationsGroup(id); } @Override - public Trip getTripForId(FeedScopedId id) { + public Trip getTrip(FeedScopedId id) { TimetableSnapshot currentSnapshot = lazyGetTimeTableSnapShot(); if (currentSnapshot != null) { Trip trip = currentSnapshot.getRealTimeAddedTrip(id); @@ -287,43 +264,43 @@ public Trip getTripForId(FeedScopedId id) { return trip; } } - return getScheduledTripForId(id); + return getScheduledTrip(id); } @Nullable @Override - public Trip getScheduledTripForId(FeedScopedId id) { - return this.transitModelIndex.getTripForId().get(id); + public Trip getScheduledTrip(FeedScopedId id) { + return this.timetableRepositoryIndex.getTripForId(id); } @Override - public Collection getAllTrips() { + public Collection listTrips() { OTPRequestTimeoutException.checkForTimeout(); TimetableSnapshot currentSnapshot = lazyGetTimeTableSnapShot(); if (currentSnapshot != null) { return new CollectionsView<>( - transitModelIndex.getTripForId().values(), - currentSnapshot.getAllRealTimeAddedTrips() + timetableRepositoryIndex.getAllTrips(), + currentSnapshot.listRealTimeAddedTrips() ); } - return Collections.unmodifiableCollection(transitModelIndex.getTripForId().values()); + return Collections.unmodifiableCollection(timetableRepositoryIndex.getAllTrips()); } @Override - public Collection getAllRoutes() { + public Collection listRoutes() { OTPRequestTimeoutException.checkForTimeout(); TimetableSnapshot currentSnapshot = lazyGetTimeTableSnapShot(); if (currentSnapshot != null) { return new CollectionsView<>( - transitModelIndex.getAllRoutes(), - currentSnapshot.getAllRealTimeAddedRoutes() + timetableRepositoryIndex.getAllRoutes(), + currentSnapshot.listRealTimeAddedRoutes() ); } - return Collections.unmodifiableCollection(transitModelIndex.getAllRoutes()); + return timetableRepositoryIndex.getAllRoutes(); } @Override - public TripPattern getPatternForTrip(Trip trip) { + public TripPattern findPattern(Trip trip) { TimetableSnapshot currentSnapshot = lazyGetTimeTableSnapShot(); if (currentSnapshot != null) { TripPattern realtimeAddedTripPattern = currentSnapshot.getRealTimeAddedPatternForTrip(trip); @@ -331,23 +308,23 @@ public TripPattern getPatternForTrip(Trip trip) { return realtimeAddedTripPattern; } } - return this.transitModelIndex.getPatternForTrip().get(trip); + return this.timetableRepositoryIndex.getPatternForTrip(trip); } @Override - public TripPattern getPatternForTrip(Trip trip, LocalDate serviceDate) { - TripPattern realtimePattern = getRealtimeAddedTripPattern(trip.getId(), serviceDate); + public TripPattern findPattern(Trip trip, LocalDate serviceDate) { + TripPattern realtimePattern = findNewTripPatternForModifiedTrip(trip.getId(), serviceDate); if (realtimePattern != null) { return realtimePattern; } - return getPatternForTrip(trip); + return findPattern(trip); } @Override - public Collection getPatternsForRoute(Route route) { + public Collection findPatterns(Route route) { OTPRequestTimeoutException.checkForTimeout(); Collection tripPatterns = new HashSet<>( - transitModelIndex.getPatternsForRoute().get(route) + timetableRepositoryIndex.getPatternsForRoute(route) ); TimetableSnapshot currentSnapshot = lazyGetTimeTableSnapShot(); if (currentSnapshot != null) { @@ -360,8 +337,8 @@ public Collection getPatternsForRoute(Route route) { } @Override - public MultiModalStation getMultiModalStationForStation(Station station) { - return this.transitModel.getStopModel().getMultiModalStationForStation(station); + public MultiModalStation findMultiModalStation(Station station) { + return this.timetableRepository.getSiteRepository().getMultiModalStationForStation(station); } /** @@ -381,7 +358,7 @@ public MultiModalStation getMultiModalStationForStation(Station station) { * @param includeCancelledTrips If true, cancelled trips will also be included in result. */ @Override - public List stopTimesForStop( + public List findStopTimesInPattern( StopLocation stop, Instant startTime, Duration timeRange, @@ -409,7 +386,7 @@ public List stopTimesForStop( * @param serviceDate Return all departures for the specified date */ @Override - public List getStopTimesForStop( + public List findStopTimesInPattern( StopLocation stop, LocalDate serviceDate, ArrivalDeparture arrivalDeparture, @@ -441,7 +418,7 @@ public List getStopTimesForStop( * @param arrivalDeparture Filter by arrivals, departures, or both */ @Override - public List stopTimesForPatternAtStop( + public List findTripTimeOnDate( StopLocation stop, TripPattern pattern, Instant startTime, @@ -467,14 +444,11 @@ public List stopTimesForPatternAtStop( * Returns all the patterns for a specific stop. If includeRealtimeUpdates is set, new patterns * added by realtime updates are added to the collection. * A set is used here because trip patterns - * that were updated by realtime data is both part of the TransitModelIndex and the TimetableSnapshot + * that were updated by realtime data is both part of the TimetableRepositoryIndex and the TimetableSnapshot */ @Override - public Collection getPatternsForStop( - StopLocation stop, - boolean includeRealtimeUpdates - ) { - Set tripPatterns = new HashSet<>(getPatternsForStop(stop)); + public Collection findPatterns(StopLocation stop, boolean includeRealtimeUpdates) { + Set tripPatterns = new HashSet<>(findPatterns(stop)); if (includeRealtimeUpdates) { TimetableSnapshot currentSnapshot = lazyGetTimeTableSnapShot(); @@ -486,20 +460,20 @@ public Collection getPatternsForStop( } @Override - public Collection getGroupsOfRoutes() { + public Collection listGroupsOfRoutes() { OTPRequestTimeoutException.checkForTimeout(); - return transitModelIndex.getRoutesForGroupOfRoutes().keySet(); + return timetableRepositoryIndex.getAllGroupOfRoutes(); } @Override - public Collection getRoutesForGroupOfRoutes(GroupOfRoutes groupOfRoutes) { + public Collection findRoutes(GroupOfRoutes groupOfRoutes) { OTPRequestTimeoutException.checkForTimeout(); - return transitModelIndex.getRoutesForGroupOfRoutes().get(groupOfRoutes); + return timetableRepositoryIndex.getRoutesForGroupOfRoutes(groupOfRoutes); } @Override - public GroupOfRoutes getGroupOfRoutesForId(FeedScopedId id) { - return transitModelIndex.getGroupOfRoutesForId().get(id); + public GroupOfRoutes getGroupOfRoutes(FeedScopedId id) { + return timetableRepositoryIndex.getGroupOfRoutesForId(id); } /** @@ -508,7 +482,7 @@ public GroupOfRoutes getGroupOfRoutesForId(FeedScopedId id) { * without making a fake routing request. */ @Override - public Timetable getTimetableForTripPattern(TripPattern tripPattern, LocalDate serviceDate) { + public Timetable findTimetable(TripPattern tripPattern, LocalDate serviceDate) { OTPRequestTimeoutException.checkForTimeout(); TimetableSnapshot currentSnapshot = lazyGetTimeTableSnapShot(); return currentSnapshot != null @@ -517,21 +491,21 @@ public Timetable getTimetableForTripPattern(TripPattern tripPattern, LocalDate s } @Override - public TripPattern getRealtimeAddedTripPattern(FeedScopedId tripId, LocalDate serviceDate) { + public TripPattern findNewTripPatternForModifiedTrip(FeedScopedId tripId, LocalDate serviceDate) { TimetableSnapshot currentSnapshot = lazyGetTimeTableSnapShot(); if (currentSnapshot == null) { return null; } - return currentSnapshot.getRealtimeAddedTripPattern(tripId, serviceDate); + return currentSnapshot.getNewTripPatternForModifiedTrip(tripId, serviceDate); } @Override - public boolean hasRealtimeAddedTripPatterns() { + public boolean hasNewTripPatternsForModifiedTrips() { TimetableSnapshot currentSnapshot = lazyGetTimeTableSnapShot(); if (currentSnapshot == null) { return false; } - return currentSnapshot.hasRealtimeAddedTripPatterns(); + return currentSnapshot.hasNewTripPatternsForModifiedTrips(); } /** @@ -542,43 +516,39 @@ public boolean hasRealtimeAddedTripPatterns() { @Nullable private TimetableSnapshot lazyGetTimeTableSnapShot() { if (this.timetableSnapshot == null) { - timetableSnapshot = transitModel.getTimetableSnapshot(); + timetableSnapshot = timetableRepository.getTimetableSnapshot(); } return this.timetableSnapshot; } @Override - public TripOnServiceDate getTripOnServiceDateById(FeedScopedId datedServiceJourneyId) { + public TripOnServiceDate getTripOnServiceDate(FeedScopedId id) { TimetableSnapshot currentSnapshot = lazyGetTimeTableSnapShot(); if (currentSnapshot != null) { TripOnServiceDate tripOnServiceDate = currentSnapshot.getRealTimeAddedTripOnServiceDateById( - datedServiceJourneyId + id ); if (tripOnServiceDate != null) { return tripOnServiceDate; } } - return transitModelIndex.getTripOnServiceDateById().get(datedServiceJourneyId); + return timetableRepository.getTripOnServiceDateById(id); } @Override - public Collection getAllTripOnServiceDates() { + public Collection listTripsOnServiceDate() { TimetableSnapshot currentSnapshot = lazyGetTimeTableSnapShot(); if (currentSnapshot != null) { return new CollectionsView<>( - transitModelIndex.getTripOnServiceDateForTripAndDay().values(), - currentSnapshot.getAllRealTimeAddedTripOnServiceDate() + timetableRepository.getAllTripsOnServiceDates(), + currentSnapshot.listRealTimeAddedTripOnServiceDate() ); } - return Collections.unmodifiableCollection( - transitModelIndex.getTripOnServiceDateForTripAndDay().values() - ); + return timetableRepository.getAllTripsOnServiceDates(); } @Override - public TripOnServiceDate getTripOnServiceDateForTripAndDay( - TripIdAndServiceDate tripIdAndServiceDate - ) { + public TripOnServiceDate getTripOnServiceDate(TripIdAndServiceDate tripIdAndServiceDate) { TimetableSnapshot currentSnapshot = lazyGetTimeTableSnapShot(); if (currentSnapshot != null) { TripOnServiceDate tripOnServiceDate = currentSnapshot.getRealTimeAddedTripOnServiceDateForTripAndDay( @@ -588,7 +558,46 @@ public TripOnServiceDate getTripOnServiceDateForTripAndDay( return tripOnServiceDate; } } - return transitModelIndex.getTripOnServiceDateForTripAndDay().get(tripIdAndServiceDate); + return timetableRepositoryIndex.getTripOnServiceDateForTripAndDay(tripIdAndServiceDate); + } + + /** + * Returns a list of TripOnServiceDates that match the filtering defined in the request. + * + * @param request - A TripOnServiceDateRequest object with filtering defined. + * @return - A list of TripOnServiceDates + */ + @Override + public List findTripsOnServiceDate(TripOnServiceDateRequest request) { + Matcher matcher = TripOnServiceDateMatcherFactory.of(request); + return listTripsOnServiceDate().stream().filter(matcher::match).toList(); + } + + @Override + public boolean containsTrip(FeedScopedId id) { + TimetableSnapshot currentSnapshot = lazyGetTimeTableSnapShot(); + if (currentSnapshot != null) { + Trip trip = currentSnapshot.getRealTimeAddedTrip(id); + if (trip != null) { + return true; + } + } + return this.timetableRepositoryIndex.containsTrip(id); + } + + /** + * Returns a list of Trips that match the filtering defined in the request. + * + * @param request - A TripRequest object with filtering defined. + * @return - A list Trips + */ + @Override + public List getTrips(TripRequest request) { + Matcher matcher = TripMatcherFactory.of( + request, + this.getCalendarService()::getServiceDatesForServiceId + ); + return listTrips().stream().filter(matcher::match).toList(); } /** @@ -597,100 +606,100 @@ public TripOnServiceDate getTripOnServiceDateForTripAndDay( */ @Override public FeedScopedId getOrCreateServiceIdForDate(LocalDate serviceDate) { - return transitModel.getOrCreateServiceIdForDate(serviceDate); + return timetableRepository.getOrCreateServiceIdForDate(serviceDate); } @Override public void addTransitMode(TransitMode mode) { - this.transitModel.addTransitMode(mode); + this.timetableRepository.addTransitMode(mode); } @Override - public Set getTransitModes() { - return this.transitModel.getTransitModes(); + public Set listTransitModes() { + return this.timetableRepository.getTransitModes(); } @Override - public Collection getTransfersByStop(StopLocation stop) { - return this.transitModel.getTransfersByStop(stop); + public Collection findPathTransfers(StopLocation stop) { + return this.timetableRepository.getTransfersByStop(stop); } @Override public TransitLayer getTransitLayer() { OTPRequestTimeoutException.checkForTimeout(); - return this.transitModel.getTransitLayer(); + return this.timetableRepository.getTransitLayer(); } @Override public TransitLayer getRealtimeTransitLayer() { OTPRequestTimeoutException.checkForTimeout(); - return this.transitModel.getRealtimeTransitLayer(); + return this.timetableRepository.getRealtimeTransitLayer(); } @Override public void setTransitLayer(TransitLayer transitLayer) { - this.transitModel.setTransitLayer(transitLayer); + this.timetableRepository.setTransitLayer(transitLayer); } @Override public void setRealtimeTransitLayer(TransitLayer realtimeTransitLayer) { - transitModel.setRealtimeTransitLayer(realtimeTransitLayer); + timetableRepository.setRealtimeTransitLayer(realtimeTransitLayer); } @Override public boolean hasRealtimeTransitLayer() { - return transitModel.hasRealtimeTransitLayer(); + return timetableRepository.hasRealtimeTransitLayer(); } @Override public CalendarService getCalendarService() { - return this.transitModel.getCalendarService(); + return this.timetableRepository.getCalendarService(); } @Override public ZoneId getTimeZone() { - return this.transitModel.getTimeZone(); + return this.timetableRepository.getTimeZone(); } @Override public TransitAlertService getTransitAlertService() { - return this.transitModel.getTransitAlertService(); + return this.timetableRepository.getTransitAlertService(); } @Override public FlexIndex getFlexIndex() { - return this.transitModelIndex.getFlexIndex(); + return this.timetableRepositoryIndex.getFlexIndex(); } @Override public ZonedDateTime getTransitServiceEnds() { - return transitModel.getTransitServiceEnds(); + return timetableRepository.getTransitServiceEnds(); } @Override public ZonedDateTime getTransitServiceStarts() { - return transitModel.getTransitServiceStarts(); + return timetableRepository.getTransitServiceStarts(); } @Override public Collection findRegularStops(Envelope envelope) { OTPRequestTimeoutException.checkForTimeout(); - return transitModel.getStopModel().findRegularStops(envelope); + return timetableRepository.getSiteRepository().findRegularStops(envelope); } @Override public Collection findAreaStops(Envelope envelope) { OTPRequestTimeoutException.checkForTimeout(); - return transitModel.getStopModel().findAreaStops(envelope); + return timetableRepository.getSiteRepository().findAreaStops(envelope); } @Override public GraphUpdaterStatus getUpdaterStatus() { - return transitModel.getUpdaterManager(); + return timetableRepository.getUpdaterManager(); } @Override - public List getModesOfStopLocationsGroup(StopLocationsGroup station) { + public List findTransitModes(StopLocationsGroup station) { return sortByOccurrenceAndReduce( station.getChildStops().stream().flatMap(this::getPatternModesOfStop) ) @@ -698,44 +707,46 @@ public List getModesOfStopLocationsGroup(StopLocationsGroup station } @Override - public List getModesOfStopLocation(StopLocation stop) { + public List findTransitModes(StopLocation stop) { return sortByOccurrenceAndReduce(getPatternModesOfStop(stop)).toList(); } @Override public Deduplicator getDeduplicator() { - return transitModel.getDeduplicator(); + return timetableRepository.getDeduplicator(); } @Override - public Set getAllServiceCodes() { - return Collections.unmodifiableSet(transitModelIndex.getServiceCodesRunningForDate().keySet()); + public Set listServiceDates() { + return Collections.unmodifiableSet( + timetableRepositoryIndex.getServiceCodesRunningForDate().keySet() + ); } @Override public Map getServiceCodesRunningForDate() { - return Collections.unmodifiableMap(transitModelIndex.getServiceCodesRunningForDate()); + return Collections.unmodifiableMap(timetableRepositoryIndex.getServiceCodesRunningForDate()); } /** * For each pattern visiting this {@link StopLocation} return its {@link TransitMode} */ private Stream getPatternModesOfStop(StopLocation stop) { - if (stop.getGtfsVehicleType() != null) { - return Stream.of(stop.getGtfsVehicleType()); + if (stop.getVehicleType() != null) { + return Stream.of(stop.getVehicleType()); } else { - return getPatternsForStop(stop).stream().map(TripPattern::getMode); + return findPatterns(stop).stream().map(TripPattern::getMode); } } @Override public TransferService getTransferService() { - return transitModel.getTransferService(); + return timetableRepository.getTransferService(); } @Override public boolean transitFeedCovers(Instant dateTime) { - return transitModel.transitFeedCovers(dateTime); + return timetableRepository.transitFeedCovers(dateTime); } /** diff --git a/src/main/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilter.java b/application/src/main/java/org/opentripplanner/transit/service/PatternByServiceDatesFilter.java similarity index 79% rename from src/main/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilter.java rename to application/src/main/java/org/opentripplanner/transit/service/PatternByServiceDatesFilter.java index 8eecfe6273b..21890975acf 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilter.java +++ b/application/src/main/java/org/opentripplanner/transit/service/PatternByServiceDatesFilter.java @@ -1,16 +1,13 @@ -package org.opentripplanner.apis.gtfs; +package org.opentripplanner.transit.service; import java.time.LocalDate; import java.util.Collection; import java.util.Objects; import java.util.function.Function; -import java.util.stream.Stream; -import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.model.LocalDateRange; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.Trip; -import org.opentripplanner.transit.service.TransitService; /** * Encapsulates the logic to filter patterns by the service dates that they operate on. It also @@ -29,7 +26,7 @@ public class PatternByServiceDatesFilter { * This method is not private to enable unit testing. *

    */ - PatternByServiceDatesFilter( + public PatternByServiceDatesFilter( LocalDateRange range, Function> getPatternsForRoute, Function> getServiceDatesForTrip @@ -45,17 +42,6 @@ public class PatternByServiceDatesFilter { } } - public PatternByServiceDatesFilter( - GraphQLTypes.GraphQLLocalDateRangeInput filterInput, - TransitService transitService - ) { - this( - new LocalDateRange(filterInput.getGraphQLStart(), filterInput.getGraphQLEnd()), - transitService::getPatternsForRoute, - trip -> transitService.getCalendarService().getServiceDatesForServiceId(trip.getServiceId()) - ); - } - /** * Filter the patterns by the service dates that it operates on. */ @@ -67,8 +53,9 @@ public Collection filterPatterns(Collection tripPatter * Filter the routes by listing all their patterns' service dates and checking if they * operate on the specified dates. */ - public Collection filterRoutes(Stream routeStream) { + public Collection filterRoutes(Collection routeStream) { return routeStream + .stream() .filter(r -> { var patterns = getPatternsForRoute.apply(r); return !this.filterPatterns(patterns).isEmpty(); diff --git a/src/main/java/org/opentripplanner/transit/service/StopModel.java b/application/src/main/java/org/opentripplanner/transit/service/SiteRepository.java similarity index 87% rename from src/main/java/org/opentripplanner/transit/service/StopModel.java rename to application/src/main/java/org/opentripplanner/transit/service/SiteRepository.java index 4f55ca25b5b..a2a4adea931 100644 --- a/src/main/java/org/opentripplanner/transit/service/StopModel.java +++ b/application/src/main/java/org/opentripplanner/transit/service/SiteRepository.java @@ -8,8 +8,6 @@ import java.util.concurrent.atomic.AtomicInteger; import javax.annotation.Nullable; import org.locationtech.jts.geom.Envelope; -import org.opentripplanner.framework.collection.CollectionsView; -import org.opentripplanner.framework.collection.MapUtils; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.AreaStop; @@ -20,15 +18,17 @@ import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.site.StopLocationsGroup; +import org.opentripplanner.utils.collection.CollectionsView; +import org.opentripplanner.utils.collection.MapUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Repository for Stop entities. */ -public class StopModel implements Serializable { +public class SiteRepository implements Serializable { - private static final Logger LOG = LoggerFactory.getLogger(StopModel.class); + private static final Logger LOG = LoggerFactory.getLogger(SiteRepository.class); private final AtomicInteger stopIndexCounter; private final Map regularStopById; @@ -37,10 +37,10 @@ public class StopModel implements Serializable { private final Map groupOfStationsById; private final Map areaStopById; private final Map groupStopById; - private transient StopModelIndex index; + private transient SiteRepositoryIndex index; @Inject - public StopModel() { + public SiteRepository() { this.stopIndexCounter = new AtomicInteger(0); this.regularStopById = Map.of(); this.stationById = Map.of(); @@ -51,7 +51,7 @@ public StopModel() { this.index = createIndex(); } - StopModel(StopModelBuilder builder) { + SiteRepository(SiteRepositoryBuilder builder) { this.stopIndexCounter = builder.stopIndexCounter(); this.regularStopById = builder.regularStopsById().asImmutableMap(); this.stationById = builder.stationById().asImmutableMap(); @@ -67,7 +67,7 @@ public StopModel() { * method, if not this method will fail! If a duplicate key exist, then child value is kept - * this feature is normally not allowed, but not enforced here. */ - private StopModel(StopModel main, StopModel child) { + private SiteRepository(SiteRepository main, SiteRepository child) { this.stopIndexCounter = assertSameStopIndexCounterIsUsedToCreateBothModels(main, child); this.areaStopById = MapUtils.combine(main.areaStopById, child.areaStopById); this.regularStopById = MapUtils.combine(main.regularStopById, child.regularStopById); @@ -83,28 +83,28 @@ private StopModel(StopModel main, StopModel child) { /** * Create a new builder based on an empty model. This is useful in unit-tests, but should * NOT be used in the main code. It is not possible to merge the result with another - * {@link StopModel}, because they do not share the same context(stopIndexCounter). + * {@link SiteRepository}, because they do not share the same context(stopIndexCounter). *

    * In the application code the correct way is to retrieve a model instance and then use the * {@link #withContext()} method to create a builder. */ - public static StopModelBuilder of() { - return new StopModelBuilder(new AtomicInteger(0)); + public static SiteRepositoryBuilder of() { + return new SiteRepositoryBuilder(new AtomicInteger(0)); } /** * Create a new builder attached to the existing model. The entities of the existing model are * NOT copied into the builder, but the builder has access to the model - allowing it to check * for duplicates and injecting information from the model(indexing). The changes in the - * StopModelBuilder can then be merged into the original model - this is for now left to the + * SiteRepositoryBuilder can then be merged into the original model - this is for now left to the * caller. *

    * USE THIS TO CREATE A SAFE BUILDER IN PRODUCTION CODE. You MAY use this method in unit-tests, * the alternative is the {@link #of()} method. This method should be used if the test have a - * StopModel and the {@link #of()} method should be used if a stop-model in not needed. + * SiteRepository and the {@link #of()} method should be used if a stop-model in not needed. */ - public StopModelBuilder withContext() { - return new StopModelBuilder(this.stopIndexCounter); + public SiteRepositoryBuilder withContext() { + return new SiteRepositoryBuilder(this.stopIndexCounter); } /** @@ -282,24 +282,24 @@ public Collection findStopOrChildStops(FeedScopedId id) { } /** - * Call this method after deserializing this class. This will reindex the StopModel. + * Call this method after deserializing this class. This will reindex the SiteRepository. */ public void reindexAfterDeserialization() { reindex(); } - public StopModel merge(StopModel child) { - return new StopModel(this, child); + public SiteRepository merge(SiteRepository child) { + return new SiteRepository(this, child); } private void reindex() { - LOG.info("Index stop model..."); + LOG.info("Index site repository..."); index = createIndex(); - LOG.info("Index stop model complete."); + LOG.info("Index site repository complete."); } - private StopModelIndex createIndex() { - return new StopModelIndex( + private SiteRepositoryIndex createIndex() { + return new SiteRepositoryIndex( regularStopById.values(), areaStopById.values(), groupStopById.values(), @@ -328,13 +328,13 @@ private static V getById(FeedScopedId id, Map... */ @SuppressWarnings("NumberEquality") private static AtomicInteger assertSameStopIndexCounterIsUsedToCreateBothModels( - StopModel main, - StopModel child + SiteRepository main, + SiteRepository child ) { if (main.stopIndexCounter != child.stopIndexCounter) { throw new IllegalArgumentException( - "Two Stop models can only be merged if they are created with the same stopIndexCounter. " + - "This is archived by using the 'StopModel.withContext()' method. We do this to avoid " + + "Two Stop repositories can only be merged if they are created with the same stopIndexCounter. " + + "This is archived by using the 'SiteRepository.withContext()' method. We do this to avoid " + "duplicates/gaps in the stopIndex." ); } diff --git a/src/main/java/org/opentripplanner/transit/service/StopModelBuilder.java b/application/src/main/java/org/opentripplanner/transit/service/SiteRepositoryBuilder.java similarity index 78% rename from src/main/java/org/opentripplanner/transit/service/StopModelBuilder.java rename to application/src/main/java/org/opentripplanner/transit/service/SiteRepositoryBuilder.java index 52ac778c559..a5c89c2a741 100644 --- a/src/main/java/org/opentripplanner/transit/service/StopModelBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/service/SiteRepositoryBuilder.java @@ -17,7 +17,7 @@ import org.opentripplanner.transit.model.site.RegularStopBuilder; import org.opentripplanner.transit.model.site.Station; -public class StopModelBuilder { +public class SiteRepositoryBuilder { private final AtomicInteger stopIndexCounter; @@ -28,7 +28,7 @@ public class StopModelBuilder { private final EntityById multiModalStationById = new DefaultEntityById<>(); private final EntityById groupOfStationById = new DefaultEntityById<>(); - StopModelBuilder(AtomicInteger stopIndexCounter) { + SiteRepositoryBuilder(AtomicInteger stopIndexCounter) { this.stopIndexCounter = stopIndexCounter; } @@ -47,12 +47,12 @@ public RegularStop computeRegularStopIfAbsent( return regularStopById.computeIfAbsent(id, factory); } - public StopModelBuilder withRegularStop(RegularStop stop) { + public SiteRepositoryBuilder withRegularStop(RegularStop stop) { regularStopById.add(stop); return this; } - public StopModelBuilder withRegularStops(Collection stops) { + public SiteRepositoryBuilder withRegularStops(Collection stops) { regularStopById.addAll(stops); return this; } @@ -61,7 +61,7 @@ public ImmutableEntityById stationById() { return stationById; } - public StopModelBuilder withStation(Station station) { + public SiteRepositoryBuilder withStation(Station station) { stationById.add(station); return this; } @@ -70,7 +70,7 @@ public Station computeStationIfAbsent(FeedScopedId id, Function stations) { + public SiteRepositoryBuilder withStations(Collection stations) { stationById.addAll(stations); return this; } @@ -79,7 +79,7 @@ public ImmutableEntityById multiModalStationById() { return multiModalStationById; } - public StopModelBuilder withMultiModalStation(MultiModalStation station) { + public SiteRepositoryBuilder withMultiModalStation(MultiModalStation station) { multiModalStationById.add(station); return this; } @@ -88,7 +88,7 @@ public ImmutableEntityById groupOfStationById() { return groupOfStationById; } - public StopModelBuilder withGroupOfStation(GroupOfStations station) { + public SiteRepositoryBuilder withGroupOfStation(GroupOfStations station) { groupOfStationById.add(station); return this; } @@ -101,12 +101,12 @@ public ImmutableEntityById areaStopById() { return areaStopById; } - public StopModelBuilder withAreaStop(AreaStop stop) { + public SiteRepositoryBuilder withAreaStop(AreaStop stop) { areaStopById.add(stop); return this; } - public StopModelBuilder withAreaStops(Collection stops) { + public SiteRepositoryBuilder withAreaStops(Collection stops) { areaStopById.addAll(stops); return this; } @@ -119,21 +119,21 @@ public ImmutableEntityById groupStopById() { return groupStopById; } - public StopModelBuilder withGroupStop(GroupStop group) { + public SiteRepositoryBuilder withGroupStop(GroupStop group) { groupStopById.add(group); return this; } - public StopModelBuilder withGroupStops(Collection groups) { + public SiteRepositoryBuilder withGroupStops(Collection groups) { groupStopById.addAll(groups); return this; } /** - * Add the content of another stop model. There are no collision check, entities in the given + * Add the content of another site repository. There are no collision check, entities in the given * {@code other} model, will replace existing entities. */ - public StopModelBuilder addAll(StopModel other) { + public SiteRepositoryBuilder addAll(SiteRepository other) { regularStopById.addAll(other.listRegularStops()); stationById.addAll(other.listStations()); multiModalStationById.addAll(other.listMultiModalStations()); @@ -143,8 +143,8 @@ public StopModelBuilder addAll(StopModel other) { return this; } - public StopModel build() { - return new StopModel(this); + public SiteRepository build() { + return new SiteRepository(this); } AtomicInteger stopIndexCounter() { diff --git a/src/main/java/org/opentripplanner/transit/service/StopModelIndex.java b/application/src/main/java/org/opentripplanner/transit/service/StopModelIndex.java similarity index 94% rename from src/main/java/org/opentripplanner/transit/service/StopModelIndex.java rename to application/src/main/java/org/opentripplanner/transit/service/StopModelIndex.java index c12c6f715f7..13a8c0d278d 100644 --- a/src/main/java/org/opentripplanner/transit/service/StopModelIndex.java +++ b/application/src/main/java/org/opentripplanner/transit/service/StopModelIndex.java @@ -7,7 +7,6 @@ import java.util.Objects; import javax.annotation.Nullable; import org.locationtech.jts.geom.Envelope; -import org.opentripplanner.framework.collection.CollectionsView; import org.opentripplanner.framework.geometry.HashGridSpatialIndex; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.model.site.GroupStop; @@ -15,6 +14,7 @@ import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.utils.collection.CollectionsView; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.event.Level; @@ -24,9 +24,9 @@ * For performance reasons these indexes are not part of the serialized state of the graph. * They are rebuilt at runtime after graph deserialization. */ -class StopModelIndex { +class SiteRepositoryIndex { - private static final Logger LOG = LoggerFactory.getLogger(StopModelIndex.class); + private static final Logger LOG = LoggerFactory.getLogger(SiteRepositoryIndex.class); private final HashGridSpatialIndex regularStopSpatialIndex = new HashGridSpatialIndex<>(); private final Map multiModalStationForStations = new HashMap<>(); @@ -36,7 +36,7 @@ class StopModelIndex { /** * @param stops All stops including regular transit and flex */ - StopModelIndex( + SiteRepositoryIndex( Collection stops, Collection flexStops, Collection groupStops, diff --git a/src/main/java/org/opentripplanner/transit/service/TransitModel.java b/application/src/main/java/org/opentripplanner/transit/service/TimetableRepository.java similarity index 83% rename from src/main/java/org/opentripplanner/transit/service/TransitModel.java rename to application/src/main/java/org/opentripplanner/transit/service/TimetableRepository.java index 84c7597d562..b81dd7d4f14 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitModel.java +++ b/application/src/main/java/org/opentripplanner/transit/service/TimetableRepository.java @@ -13,17 +13,16 @@ import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; -import javax.annotation.Nonnull; +import java.util.stream.Collectors; import javax.annotation.Nullable; import org.opentripplanner.ext.flex.trip.FlexTrip; -import org.opentripplanner.framework.lang.ObjectUtils; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issues.NoFutureDates; import org.opentripplanner.model.FeedInfo; @@ -44,43 +43,48 @@ import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.network.CarAccess; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.organization.Operator; +import org.opentripplanner.transit.model.site.GroupStop; +import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.updater.GraphUpdaterManager; import org.opentripplanner.updater.configure.UpdaterConfigurator; +import org.opentripplanner.utils.lang.ObjectUtils; +import org.opentripplanner.utils.time.ServiceDateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * The TransitModel groups together all instances making up OTP's primary internal representation + * The TimetableRepository groups together all instances making up OTP's primary internal representation * of the public transportation network. Although the names of many entities are derived from * GTFS concepts, these are actually independent of the data source from which they are loaded. * Both GTFS and NeTEx entities are mapped to these same internal OTP entities. If a concept exists * in both GTFS and NeTEx, the GTFS name is used in the internal model. For concepts that exist * only in NeTEx, the NeTEx name is used in the internal model. * - * A TransitModel instance also includes references to some transient indexes of its contents, to + * A TimetableRepository instance also includes references to some transient indexes of its contents, to * the TransitLayer derived from it, and to some other services and utilities that operate upon * its contents. * - * The TransitModel stands in opposition to two other aggregates: the Graph (representing the - * street network) and the TransitLayer (representing many of the same things in the TransitModel + * The TimetableRepository stands in opposition to two other aggregates: the Graph (representing the + * street network) and the TransitLayer (representing many of the same things in the TimetableRepository * but rearranged to be more efficient for Raptor routing). * - * At this point the TransitModel is not often read directly. Many requests will look at the - * TransitLayer rather than the TransitModel it's derived from. Both are often accessed via the - * TransitService rather than directly reading the fields of TransitModel or TransitLayer. + * At this point the TimetableRepository is not often read directly. Many requests will look at the + * TransitLayer rather than the TimetableRepository it's derived from. Both are often accessed via the + * TransitService rather than directly reading the fields of TimetableRepository or TransitLayer. * * TODO RT_AB: consider renaming. By some definitions this is not really the model, but a top-level * object grouping together instances of model classes with things that operate on and map those * instances. */ -public class TransitModel implements Serializable { +public class TimetableRepository implements Serializable { - private static final Logger LOG = LoggerFactory.getLogger(TransitModel.class); + private static final Logger LOG = LoggerFactory.getLogger(TimetableRepository.class); private final Collection agencies = new ArrayList<>(); private final Collection operators = new ArrayList<>(); @@ -96,27 +100,27 @@ public class TransitModel implements Serializable { private final Multimap transfersByStop = HashMultimap.create(); - private StopModel stopModel; + private SiteRepository siteRepository; private ZonedDateTime transitServiceStarts = LocalDate.MAX.atStartOfDay(ZoneId.systemDefault()); private ZonedDateTime transitServiceEnds = LocalDate.MIN.atStartOfDay(ZoneId.systemDefault()); /** - * The TransitLayer representation (optimized and rearranged for Raptor) of this TransitModel's + * The TransitLayer representation (optimized and rearranged for Raptor) of this TimetableRepository's * scheduled (non-realtime) contents. */ private transient TransitLayer transitLayer; /** * This updater applies realtime changes queued up for the next TimetableSnapshot such that - * this TransitModel.realtimeSnapshot remains aligned with the service represented in - * (this TransitModel instance + that next TimetableSnapshot). This is a way of keeping the + * this TimetableRepository.realtimeSnapshot remains aligned with the service represented in + * (this TimetableRepository instance + that next TimetableSnapshot). This is a way of keeping the * TransitLayer up to date without repeatedly deriving it from scratch every few seconds. The * same incremental changes are applied to both sets of data and they are published together. */ private transient TransitLayerUpdater transitLayerUpdater; /** - * An optionally present second TransitLayer representing the contents of this TransitModel plus + * An optionally present second TransitLayer representing the contents of this TimetableRepository plus * the results of realtime updates in the latest TimetableSnapshot. */ private final transient ConcurrentPublished realtimeTransitLayer = new ConcurrentPublished<>(); @@ -125,7 +129,7 @@ public class TransitModel implements Serializable { private final CalendarServiceData calendarServiceData = new CalendarServiceData(); - private transient TransitModelIndex index; + private transient TimetableRepositoryIndex index; private transient TimetableSnapshotProvider timetableSnapshotProvider = null; private ZoneId timeZone = null; private boolean timeZoneExplicitlySet = false; @@ -145,14 +149,14 @@ public class TransitModel implements Serializable { private transient TransitAlertService transitAlertService; @Inject - public TransitModel(StopModel stopModel, Deduplicator deduplicator) { - this.stopModel = Objects.requireNonNull(stopModel); + public TimetableRepository(SiteRepository siteRepository, Deduplicator deduplicator) { + this.siteRepository = Objects.requireNonNull(siteRepository); this.deduplicator = deduplicator; } /** No-argument constructor, required for deserialization. */ - public TransitModel() { - this(new StopModel(), new Deduplicator()); + public TimetableRepository() { + this(new SiteRepository(), new Deduplicator()); } /** @@ -162,10 +166,9 @@ public TransitModel() { */ public void index() { if (index == null) { - LOG.info("Index transit model..."); - // the transit model indexing updates the stop model index (flex stops added to the stop index) - this.index = new TransitModelIndex(this); - LOG.info("Index transit model complete."); + LOG.info("Index timetable repository..."); + this.index = new TimetableRepositoryIndex(this); + LOG.info("Index timetable repository complete."); } } @@ -261,7 +264,7 @@ public void updateCalendarServiceData( * service period {@code null} is returned. */ @Nullable - public FeedScopedId getOrCreateServiceIdForDate(@Nonnull LocalDate serviceDate) { + public FeedScopedId getOrCreateServiceIdForDate(LocalDate serviceDate) { // Start of day ZonedDateTime time = ServiceDateUtils.asStartOfService(serviceDate, getTimeZone()); @@ -350,7 +353,11 @@ public Set getAgencyTimeZones() { } public Collection getOperators() { - return operators; + return Collections.unmodifiableCollection(operators); + } + + public void addOperators(Collection operators) { + this.operators.addAll(operators); } /** @@ -407,9 +414,9 @@ public TripPattern getTripPatternForId(FeedScopedId id) { return tripPatternForId.get(id); } - public void addTripOnServiceDate(FeedScopedId id, TripOnServiceDate tripOnServiceDate) { + public void addTripOnServiceDate(TripOnServiceDate tripOnServiceDate) { invalidateIndex(); - tripOnServiceDates.put(id, tripOnServiceDate); + tripOnServiceDates.put(tripOnServiceDate.getId(), tripOnServiceDate); } /** @@ -426,8 +433,8 @@ public Collection getTransfersByStop(StopLocation stop) { return transfersByStop.get(stop); } - public StopModel getStopModel() { - return stopModel; + public SiteRepository getSiteRepository() { + return siteRepository; } public void addTripPattern(FeedScopedId id, TripPattern tripPattern) { @@ -443,8 +450,12 @@ public Collection getAllTripPatterns() { return tripPatternForId.values(); } - public Collection getAllTripOnServiceDates() { - return tripOnServiceDates.values(); + public TripOnServiceDate getTripOnServiceDateById(FeedScopedId tripOnServiceDateId) { + return tripOnServiceDates.get(tripOnServiceDateId); + } + + public Collection getAllTripsOnServiceDates() { + return Collections.unmodifiableCollection(tripOnServiceDates.values()); } /** @@ -491,11 +502,11 @@ public void setTransitLayerUpdater(TransitLayerUpdater transitLayerUpdater) { } /** - * Updating the stop model is only allowed during graph build + * Updating the site repository is only allowed during graph build */ - public void mergeStopModels(StopModel childStopModel) { + public void mergeSiteRepositories(SiteRepository childSiteRepository) { invalidateIndex(); - this.stopModel = this.stopModel.merge(childStopModel); + this.siteRepository = this.siteRepository.merge(childSiteRepository); } public void addFlexTrip(FeedScopedId id, FlexTrip flexTrip) { @@ -540,7 +551,7 @@ public void setHasScheduledService(boolean hasScheduledService) { * possibility that the index is not initialized (during graph build). */ @Nullable - TransitModelIndex getTransitModelIndex() { + TimetableRepositoryIndex getTimetableRepositoryIndex() { return index; } @@ -556,6 +567,36 @@ public FlexTrip getFlexTrip(FeedScopedId tripId) { return flexTripsById.get(tripId); } + /** + * The stops that are used by transit capable of transporting cars need to be + * connected to the road network (e.g. car ferries). This method returns the + * stops that are used by trips that allow cars. + * @return set of stop locations that are used for trips that allow cars + */ + public Set getStopLocationsUsedForCarsAllowedTrips() { + Set stopLocations = getAllTripPatterns() + .stream() + .filter(t -> + t + .getScheduledTimetable() + .getTripTimes() + .stream() + .anyMatch(tt -> tt.getTrip().getCarsAllowed() == CarAccess.ALLOWED) + ) + .flatMap(t -> t.getStops().stream()) + .collect(Collectors.toSet()); + + stopLocations.addAll( + stopLocations + .stream() + .filter(GroupStop.class::isInstance) + .map(GroupStop.class::cast) + .flatMap(g -> g.getChildLocations().stream().filter(RegularStop.class::isInstance)) + .toList() + ); + return stopLocations; + } + private void invalidateIndex() { this.index = null; } diff --git a/src/main/java/org/opentripplanner/transit/service/TransitModelIndex.java b/application/src/main/java/org/opentripplanner/transit/service/TimetableRepositoryIndex.java similarity index 70% rename from src/main/java/org/opentripplanner/transit/service/TransitModelIndex.java rename to application/src/main/java/org/opentripplanner/transit/service/TimetableRepositoryIndex.java index 36ab937416c..ca52b710957 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitModelIndex.java +++ b/application/src/main/java/org/opentripplanner/transit/service/TimetableRepositoryIndex.java @@ -7,6 +7,7 @@ import gnu.trove.set.hash.TIntHashSet; import java.time.LocalDate; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -34,9 +35,9 @@ * For performance reasons these indexes are not part of the serialized state of the graph. * They are rebuilt at runtime after graph deserialization. */ -class TransitModelIndex { +class TimetableRepositoryIndex { - private static final Logger LOG = LoggerFactory.getLogger(TransitModelIndex.class); + private static final Logger LOG = LoggerFactory.getLogger(TimetableRepositoryIndex.class); // TODO: consistently key on model object or id string private final Map agencyForId = new HashMap<>(); @@ -47,10 +48,9 @@ class TransitModelIndex { private final Map patternForTrip = new HashMap<>(); private final Multimap patternsForRoute = ArrayListMultimap.create(); - private final Multimap patternsForStopId = ArrayListMultimap.create(); + private final Multimap patternsForStop = ArrayListMultimap.create(); private final Map serviceCodesRunningForDate = new HashMap<>(); - private final Map tripOnServiceDateById = new HashMap<>(); private final Map tripOnServiceDateForTripAndDay = new HashMap<>(); private final Multimap routesForGroupOfRoutes = ArrayListMultimap.create(); @@ -58,18 +58,18 @@ class TransitModelIndex { private final Map groupOfRoutesForId = new HashMap<>(); private FlexIndex flexIndex = null; - TransitModelIndex(TransitModel transitModel) { - LOG.info("Transit model index init..."); + TimetableRepositoryIndex(TimetableRepository timetableRepository) { + LOG.info("Timetable repository index init..."); - for (Agency agency : transitModel.getAgencies()) { + for (Agency agency : timetableRepository.getAgencies()) { this.agencyForId.put(agency.getId(), agency); } - for (Operator operator : transitModel.getOperators()) { + for (Operator operator : timetableRepository.getOperators()) { this.operatorForId.put(operator.getId(), operator); } - for (TripPattern pattern : transitModel.getAllTripPatterns()) { + for (TripPattern pattern : timetableRepository.getAllTripPatterns()) { patternsForRoute.put(pattern.getRoute(), pattern); pattern .scheduledTripsAsStream() @@ -78,7 +78,7 @@ class TransitModelIndex { tripForId.put(trip.getId(), trip); }); for (StopLocation stop : pattern.getStops()) { - patternsForStopId.put(stop, pattern); + patternsForStop.put(stop, pattern); } } for (Route route : patternsForRoute.asMap().keySet()) { @@ -91,8 +91,7 @@ class TransitModelIndex { groupOfRoutesForId.put(groupOfRoutes.getId(), groupOfRoutes); } - for (TripOnServiceDate tripOnServiceDate : transitModel.getAllTripOnServiceDates()) { - tripOnServiceDateById.put(tripOnServiceDate.getId(), tripOnServiceDate); + for (TripOnServiceDate tripOnServiceDate : timetableRepository.getAllTripsOnServiceDates()) { tripOnServiceDateForTripAndDay.put( new TripIdAndServiceDate( tripOnServiceDate.getTrip().getId(), @@ -102,10 +101,10 @@ class TransitModelIndex { ); } - initalizeServiceCodesForDate(transitModel); + initalizeServiceCodesForDate(timetableRepository); if (OTPFeature.FlexRouting.isOn()) { - flexIndex = new FlexIndex(transitModel); + flexIndex = new FlexIndex(timetableRepository); for (Route route : flexIndex.getAllFlexRoutes()) { routeForId.put(route.getId(), route); } @@ -114,7 +113,7 @@ class TransitModelIndex { } } - LOG.info("Transit Model index init complete."); + LOG.info("Timetable repository index init complete."); } Agency getAgencyForId(FeedScopedId id) { @@ -132,56 +131,60 @@ void addRoutes(Route route) { /** Dynamically generate the set of Routes passing though a Stop on demand. */ Set getRoutesForStop(StopLocation stop) { Set routes = new HashSet<>(); - for (TripPattern p : getPatternsForStop(stop)) { + for (TripPattern p : patternsForStop.get(stop)) { routes.add(p.getRoute()); } return routes; } Collection getPatternsForStop(StopLocation stop) { - return patternsForStopId.get(stop); + return Collections.unmodifiableCollection(patternsForStop.get(stop)); } Collection getTripsForStop(StopLocation stop) { - return getPatternsForStop(stop) + return patternsForStop + .get(stop) .stream() .flatMap(TripPattern::scheduledTripsAsStream) .collect(Collectors.toList()); } - /** - * Get a list of all operators spanning across all feeds. - */ - Collection getAllOperators() { - return getOperatorForId().values(); + Operator getOperatorForId(FeedScopedId operatorId) { + return operatorForId.get(operatorId); } - Map getOperatorForId() { - return operatorForId; + Collection getAllTrips() { + return Collections.unmodifiableCollection(tripForId.values()); } - Map getTripForId() { - return tripForId; + Trip getTripForId(FeedScopedId tripId) { + return tripForId.get(tripId); } - Map getTripOnServiceDateById() { - return tripOnServiceDateById; + /** + * Checks if the specified trip is contained within the index. + * + * @param tripId the {@link FeedScopedId} of the trip to check + * @return true if the trip exists in the index map, false otherwise + */ + boolean containsTrip(FeedScopedId tripId) { + return tripForId.containsKey(tripId); } - Map getTripOnServiceDateForTripAndDay() { - return tripOnServiceDateForTripAndDay; + TripOnServiceDate getTripOnServiceDateForTripAndDay(TripIdAndServiceDate tripIdAndServiceDate) { + return tripOnServiceDateForTripAndDay.get(tripIdAndServiceDate); } Collection getAllRoutes() { - return routeForId.values(); + return Collections.unmodifiableCollection(routeForId.values()); } - Map getPatternForTrip() { - return patternForTrip; + TripPattern getPatternForTrip(Trip trip) { + return patternForTrip.get(trip); } - Multimap getPatternsForRoute() { - return patternsForRoute; + Collection getPatternsForRoute(Route route) { + return Collections.unmodifiableCollection(patternsForRoute.get(route)); } Map getServiceCodesRunningForDate() { @@ -192,8 +195,8 @@ FlexIndex getFlexIndex() { return flexIndex; } - private void initalizeServiceCodesForDate(TransitModel transitModel) { - CalendarService calendarService = transitModel.getCalendarService(); + private void initalizeServiceCodesForDate(TimetableRepository timetableRepository) { + CalendarService calendarService = timetableRepository.getCalendarService(); if (calendarService == null) { return; @@ -223,17 +226,21 @@ private void initalizeServiceCodesForDate(TransitModel transitModel) { for (LocalDate serviceDate : serviceIdsForServiceDate.keySet()) { TIntSet serviceCodesRunning = new TIntHashSet(); for (FeedScopedId serviceId : serviceIdsForServiceDate.get(serviceDate)) { - serviceCodesRunning.add(transitModel.getServiceCodes().get(serviceId)); + serviceCodesRunning.add(timetableRepository.getServiceCodes().get(serviceId)); } serviceCodesRunningForDate.put(serviceDate, serviceCodesRunning); } } - Multimap getRoutesForGroupOfRoutes() { - return routesForGroupOfRoutes; + Collection getAllGroupOfRoutes() { + return Collections.unmodifiableCollection(groupOfRoutesForId.values()); + } + + Collection getRoutesForGroupOfRoutes(GroupOfRoutes groupOfRoutes) { + return Collections.unmodifiableCollection(routesForGroupOfRoutes.get(groupOfRoutes)); } - Map getGroupOfRoutesForId() { - return groupOfRoutesForId; + GroupOfRoutes getGroupOfRoutesForId(FeedScopedId id) { + return groupOfRoutesForId.get(id); } } diff --git a/src/main/java/org/opentripplanner/transit/service/TransitEditorService.java b/application/src/main/java/org/opentripplanner/transit/service/TransitEditorService.java similarity index 90% rename from src/main/java/org/opentripplanner/transit/service/TransitEditorService.java rename to application/src/main/java/org/opentripplanner/transit/service/TransitEditorService.java index 567cb245af5..411ab3d652b 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitEditorService.java +++ b/application/src/main/java/org/opentripplanner/transit/service/TransitEditorService.java @@ -1,6 +1,7 @@ package org.opentripplanner.transit.service; import java.time.LocalDate; +import javax.annotation.Nullable; import org.opentripplanner.model.FeedInfo; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitLayer; import org.opentripplanner.transit.model.basic.TransitMode; @@ -26,6 +27,12 @@ public interface TransitEditorService extends TransitService { FeedScopedId getOrCreateServiceIdForDate(LocalDate serviceDate); + /** + * Return the trip for the given id, not including trips created in real time. + */ + @Nullable + Trip getScheduledTrip(FeedScopedId id); + /** * Set the original, immutable, transit layer, * based on scheduled data (not real-time data). diff --git a/src/main/java/org/opentripplanner/transit/service/TransitService.java b/application/src/main/java/org/opentripplanner/transit/service/TransitService.java similarity index 66% rename from src/main/java/org/opentripplanner/transit/service/TransitService.java rename to application/src/main/java/org/opentripplanner/transit/service/TransitService.java index 1836b5612d2..c1bba355cdf 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitService.java +++ b/application/src/main/java/org/opentripplanner/transit/service/TransitService.java @@ -24,6 +24,8 @@ import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitLayer; import org.opentripplanner.routing.services.TransitAlertService; import org.opentripplanner.routing.stoptimes.ArrivalDeparture; +import org.opentripplanner.transit.api.request.TripOnServiceDateRequest; +import org.opentripplanner.transit.api.request.TripRequest; import org.opentripplanner.transit.model.basic.Notice; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; @@ -53,142 +55,132 @@ * fetching tables of specific information like the routes passing through a particular stop, or for * gaining access to the entirety of the data to perform routing. *

    - * TODO RT_AB: this interface seems to provide direct access to TransitLayer but not TransitModel. - * Is this intentional, because TransitLayer is meant to be read-only and TransitModel is not? + * TODO RT_AB: this interface seems to provide direct access to TransitLayer but not TimetableRepository. + * Is this intentional, because TransitLayer is meant to be read-only and TimetableRepository is not? * Should this be renamed TransitDataService since it seems to provide access to the data but * not to transit routing functionality (which is provided by the RoutingService)? - * The DefaultTransitService implementation has a TransitModel instance and many of its methods - * read through to that TransitModel instance. But that field itself is not exposed, while the + * The DefaultTransitService implementation has a TimetableRepository instance and many of its methods + * read through to that TimetableRepository instance. But that field itself is not exposed, while the * TransitLayer is here. It seems like exposing the raw TransitLayer is still a risk since it's * copy-on-write and shares a lot of objects with any other TransitLayer instances. */ public interface TransitService { - Collection getFeedIds(); + Collection listFeedIds(); - Collection getAgencies(); - Optional findAgencyById(FeedScopedId id); + Collection listAgencies(); + Optional findAgency(FeedScopedId id); FeedInfo getFeedInfo(String feedId); - Collection getOperators(); - - Collection getNoticesByEntity(AbstractTransitEntity entity); + Collection findNotices(AbstractTransitEntity entity); /** * Return a trip pattern by id, not including patterns created by real-time updates. */ - TripPattern getTripPatternForId(FeedScopedId id); + TripPattern getTripPattern(FeedScopedId id); /** * Return all scheduled trip patterns, not including real-time created trip patterns. * TODO: verify this is the intended behavior and possibly change the method name to * getAllScheduledTripPatterns */ - Collection getAllTripPatterns(); - - Collection getNotices(); + Collection listTripPatterns(); - Station getStationById(FeedScopedId id); + Station getStation(FeedScopedId id); MultiModalStation getMultiModalStation(FeedScopedId id); - Collection getStations(); + Collection listStations(); - Integer getServiceCodeForId(FeedScopedId id); + Integer getServiceCode(FeedScopedId id); TIntSet getServiceCodesRunningForDate(LocalDate date); - Agency getAgencyForId(FeedScopedId id); + Agency getAgency(FeedScopedId id); /** * Return a route for a given id, including routes created by real-time updates. * */ - Route getRouteForId(FeedScopedId id); + Route getRoute(FeedScopedId id); /** * Return the routes using the given stop, not including real-time updates. */ - Set getRoutesForStop(StopLocation stop); + Set findRoutes(StopLocation stop); /** * Return all the scheduled trip patterns for a specific stop * (not taking into account real-time updates). */ - Collection getPatternsForStop(StopLocation stop); + Collection findPatterns(StopLocation stop); /** * Returns all the patterns for a specific stop. If includeRealtimeUpdates is set, new patterns * added by realtime updates are added to the collection. */ - Collection getPatternsForStop(StopLocation stop, boolean includeRealtimeUpdates); - - Collection getTripsForStop(StopLocation stop); + Collection findPatterns(StopLocation stop, boolean includeRealtimeUpdates); - Collection getAllOperators(); + Collection listOperators(); - Operator getOperatorForId(FeedScopedId id); + Operator getOperator(FeedScopedId id); RegularStop getRegularStop(FeedScopedId id); Collection listStopLocations(); - Collection listRegularStops(); - Collection listGroupStops(); StopLocation getStopLocation(FeedScopedId parseId); - Collection getStopOrChildStops(FeedScopedId id); + /** + * Return all stops associated with the given id. If a Station, a MultiModalStation, or a + * GroupOfStations matches the id, then all child stops are returned. If the id matches a regular + * stop, area stop or stop group, then a list with one item is returned. + * An empty list is if nothing is found. + */ + Collection findStopOrChildStops(FeedScopedId id); Collection listStopLocationGroups(); StopLocationsGroup getStopLocationsGroup(FeedScopedId id); - AreaStop getAreaStop(FeedScopedId id); - /** * Return the trip for the given id, including trips created in real time. */ @Nullable - Trip getTripForId(FeedScopedId id); - - /** - * Return the trip for the given id, not including trips created in real time. - */ - @Nullable - Trip getScheduledTripForId(FeedScopedId id); + Trip getTrip(FeedScopedId id); /** * Return all trips, including those created by real-time updates. */ - Collection getAllTrips(); + Collection listTrips(); /** * Return all routes, including those created by real-time updates. */ - Collection getAllRoutes(); + Collection listRoutes(); /** * Return the scheduled trip pattern for a given trip. * If the trip is an added trip (extra journey), return the initial trip pattern for this trip. */ - TripPattern getPatternForTrip(Trip trip); + TripPattern findPattern(Trip trip); /** * Return the trip pattern for a given trip on a service date. The real-time updated version * is returned if it exists, otherwise the scheduled trip pattern is returned. */ - TripPattern getPatternForTrip(Trip trip, LocalDate serviceDate); + TripPattern findPattern(Trip trip, LocalDate serviceDate); /** * Return all the trip patterns used in the given route, including those added by real-time updates */ - Collection getPatternsForRoute(Route route); + Collection findPatterns(Route route); - MultiModalStation getMultiModalStationForStation(Station station); + MultiModalStation findMultiModalStation(Station station); - List stopTimesForStop( + List findStopTimesInPattern( StopLocation stop, Instant startTime, Duration timeRange, @@ -197,14 +189,14 @@ List stopTimesForStop( boolean includeCancelledTrips ); - List getStopTimesForStop( + List findStopTimesInPattern( StopLocation stop, LocalDate serviceDate, ArrivalDeparture arrivalDeparture, boolean includeCancellations ); - List stopTimesForPatternAtStop( + List findTripTimeOnDate( StopLocation stop, TripPattern pattern, Instant startTime, @@ -214,18 +206,19 @@ List stopTimesForPatternAtStop( boolean includeCancellations ); - Collection getGroupsOfRoutes(); + Collection listGroupsOfRoutes(); - Collection getRoutesForGroupOfRoutes(GroupOfRoutes groupOfRoutes); + Collection findRoutes(GroupOfRoutes groupOfRoutes); - GroupOfRoutes getGroupOfRoutesForId(FeedScopedId id); + @Nullable + GroupOfRoutes getGroupOfRoutes(FeedScopedId id); /** * Return the timetable for a given trip pattern and date, taking into account real-time updates. * If no real-times update are applied, fall back to scheduled data. */ @Nullable - Timetable getTimetableForTripPattern(TripPattern tripPattern, LocalDate serviceDate); + Timetable findTimetable(TripPattern tripPattern, LocalDate serviceDate); /** * Return the real-time added pattern for a given tripId and a given service date. @@ -233,25 +226,25 @@ List stopTimesForPatternAtStop( * this date (that is: it is still using its scheduled trip pattern for this date). */ @Nullable - TripPattern getRealtimeAddedTripPattern(FeedScopedId tripId, LocalDate serviceDate); + TripPattern findNewTripPatternForModifiedTrip(FeedScopedId tripId, LocalDate serviceDate); /** - * Return true if at least one trip pattern has been created by a real-time update. + * Return true if at least one trip pattern has been modified by a real-time update. */ - boolean hasRealtimeAddedTripPatterns(); + boolean hasNewTripPatternsForModifiedTrips(); - TripOnServiceDate getTripOnServiceDateForTripAndDay(TripIdAndServiceDate tripIdAndServiceDate); + TripOnServiceDate getTripOnServiceDate(TripIdAndServiceDate tripIdAndServiceDate); /** * Return the TripOnServiceDate for a given id, including real-time updates. */ - TripOnServiceDate getTripOnServiceDateById(FeedScopedId datedServiceJourneyId); + TripOnServiceDate getTripOnServiceDate(FeedScopedId id); - Collection getAllTripOnServiceDates(); + Collection listTripsOnServiceDate(); - Set getTransitModes(); + Set listTransitModes(); - Collection getTransfersByStop(StopLocation stop); + Collection findPathTransfers(StopLocation stop); TransitLayer getTransitLayer(); @@ -282,29 +275,53 @@ List stopTimesForPatternAtStop( /** * For a {@link StopLocationsGroup} get all child stops and get their modes. *

    - * The mode is either taken from {@link StopLocation#getGtfsVehicleType()} (if non-null) + * The mode is either taken from {@link StopLocation#getVehicleType()} (if non-null) * or from the list of patterns that use the stop location. *

    * The returning stream is ordered by the number of occurrences of the mode in the child stops. * So, if more patterns of mode BUS than RAIL visit the group, the result will be [BUS,RAIL]. */ - List getModesOfStopLocationsGroup(StopLocationsGroup station); + List findTransitModes(StopLocationsGroup station); /** * For a {@link StopLocation} return its modes. *

    - * The mode is either taken from {@link StopLocation#getGtfsVehicleType()} (if non-null) + * The mode is either taken from {@link StopLocation#getVehicleType()} (if non-null) * or from the list of patterns that use the stop location. *

    - * If {@link StopLocation#getGtfsVehicleType()} is null the returning stream is ordered by the number + * If {@link StopLocation#getVehicleType()} is null the returning stream is ordered by the number * of occurrences of the mode in the stop. *

    * So, if more patterns of mode BUS than RAIL visit the stop, the result will be [BUS,RAIL]. */ - List getModesOfStopLocation(StopLocation stop); + List findTransitModes(StopLocation stop); Deduplicator getDeduplicator(); - Set getAllServiceCodes(); + Set listServiceDates(); Map getServiceCodesRunningForDate(); + + /** + * Returns a list of TripOnServiceDates that match the filtering defined in the request. + * + * @param request - A TripOnServiceDateRequest object with filtering defined. + * @return - A list of TripOnServiceDates + */ + List findTripsOnServiceDate(TripOnServiceDateRequest request); + + /** + * Returns a list of Trips that match the filtering defined in the request. + * + * @param request - A TripRequest object with filtering defined. + * @return - A list of Trips + */ + List getTrips(TripRequest request); + + /** + * Checks if a trip with the given ID exists in the model. + * + * @param id the {@link FeedScopedId} of the trip to check + * @return true if the trip exists, false otherwise + */ + boolean containsTrip(FeedScopedId id); } diff --git a/src/main/java/org/opentripplanner/updater/DefaultRealTimeUpdateContext.java b/application/src/main/java/org/opentripplanner/updater/DefaultRealTimeUpdateContext.java similarity index 74% rename from src/main/java/org/opentripplanner/updater/DefaultRealTimeUpdateContext.java rename to application/src/main/java/org/opentripplanner/updater/DefaultRealTimeUpdateContext.java index 0921ed5a30d..f30111608cc 100644 --- a/src/main/java/org/opentripplanner/updater/DefaultRealTimeUpdateContext.java +++ b/application/src/main/java/org/opentripplanner/updater/DefaultRealTimeUpdateContext.java @@ -1,12 +1,12 @@ package org.opentripplanner.updater; -import org.opentripplanner.ext.siri.EntityResolver; -import org.opentripplanner.ext.siri.SiriFuzzyTripMatcher; import org.opentripplanner.model.TimetableSnapshot; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.updater.siri.EntityResolver; +import org.opentripplanner.updater.siri.SiriFuzzyTripMatcher; public class DefaultRealTimeUpdateContext implements RealTimeUpdateContext { @@ -16,18 +16,18 @@ public class DefaultRealTimeUpdateContext implements RealTimeUpdateContext { public DefaultRealTimeUpdateContext( Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, TimetableSnapshot timetableSnapshotBuffer ) { this.graph = graph; - this.transitService = new DefaultTransitService(transitModel, timetableSnapshotBuffer); + this.transitService = new DefaultTransitService(timetableRepository, timetableSnapshotBuffer); } /** * Constructor for unit tests only. */ - public DefaultRealTimeUpdateContext(Graph graph, TransitModel transitModel) { - this(graph, transitModel, null); + public DefaultRealTimeUpdateContext(Graph graph, TimetableRepository timetableRepository) { + this(graph, timetableRepository, null); } @Override diff --git a/src/main/java/org/opentripplanner/updater/GraphUpdaterManager.java b/application/src/main/java/org/opentripplanner/updater/GraphUpdaterManager.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/GraphUpdaterManager.java rename to application/src/main/java/org/opentripplanner/updater/GraphUpdaterManager.java diff --git a/src/main/java/org/opentripplanner/updater/GraphUpdaterStatus.java b/application/src/main/java/org/opentripplanner/updater/GraphUpdaterStatus.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/GraphUpdaterStatus.java rename to application/src/main/java/org/opentripplanner/updater/GraphUpdaterStatus.java diff --git a/src/main/java/org/opentripplanner/updater/GraphWriterRunnable.java b/application/src/main/java/org/opentripplanner/updater/GraphWriterRunnable.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/GraphWriterRunnable.java rename to application/src/main/java/org/opentripplanner/updater/GraphWriterRunnable.java diff --git a/src/main/java/org/opentripplanner/updater/GtfsRealtimeFuzzyTripMatcher.java b/application/src/main/java/org/opentripplanner/updater/GtfsRealtimeFuzzyTripMatcher.java similarity index 90% rename from src/main/java/org/opentripplanner/updater/GtfsRealtimeFuzzyTripMatcher.java rename to application/src/main/java/org/opentripplanner/updater/GtfsRealtimeFuzzyTripMatcher.java index 6972bfb6208..749b7c0e5af 100644 --- a/src/main/java/org/opentripplanner/updater/GtfsRealtimeFuzzyTripMatcher.java +++ b/application/src/main/java/org/opentripplanner/updater/GtfsRealtimeFuzzyTripMatcher.java @@ -4,8 +4,6 @@ import gnu.trove.set.TIntSet; import java.text.ParseException; import java.time.LocalDate; -import org.opentripplanner.framework.time.ServiceDateUtils; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.gtfs.mapping.DirectionMapper; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -15,6 +13,8 @@ import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.time.ServiceDateUtils; +import org.opentripplanner.utils.time.TimeUtils; /** * This class is used for matching TripDescriptors without trip_ids to scheduled GTFS data and to @@ -35,7 +35,9 @@ public GtfsRealtimeFuzzyTripMatcher(TransitService transitService) { } public TripDescriptor match(String feedId, TripDescriptor trip) { - if (trip.hasTripId()) { + if ( + trip.hasTripId() && transitService.containsTrip(new FeedScopedId(feedId, trip.getTripId())) + ) { // trip_id already exists return trip; } @@ -55,7 +57,7 @@ public TripDescriptor match(String feedId, TripDescriptor trip) { } catch (ParseException e) { return trip; } - Route route = transitService.getRouteForId(routeId); + Route route = transitService.getRoute(routeId); if (route == null) { return trip; } @@ -85,7 +87,7 @@ public synchronized Trip getTrip( LocalDate date ) { TIntSet servicesRunningForDate = transitService.getServiceCodesRunningForDate(date); - for (TripPattern pattern : transitService.getPatternsForRoute(route)) { + for (TripPattern pattern : transitService.findPatterns(route)) { if (pattern.getDirection() != direction) continue; for (TripTimes times : pattern.getScheduledTimetable().getTripTimes()) { if ( diff --git a/src/main/java/org/opentripplanner/updater/GtfsRealtimeMapper.java b/application/src/main/java/org/opentripplanner/updater/GtfsRealtimeMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/GtfsRealtimeMapper.java rename to application/src/main/java/org/opentripplanner/updater/GtfsRealtimeMapper.java diff --git a/src/main/java/org/opentripplanner/updater/RealTimeUpdateContext.java b/application/src/main/java/org/opentripplanner/updater/RealTimeUpdateContext.java similarity index 93% rename from src/main/java/org/opentripplanner/updater/RealTimeUpdateContext.java rename to application/src/main/java/org/opentripplanner/updater/RealTimeUpdateContext.java index 5a95d01562d..b3190b2ff00 100644 --- a/src/main/java/org/opentripplanner/updater/RealTimeUpdateContext.java +++ b/application/src/main/java/org/opentripplanner/updater/RealTimeUpdateContext.java @@ -1,9 +1,9 @@ package org.opentripplanner.updater; -import org.opentripplanner.ext.siri.EntityResolver; -import org.opentripplanner.ext.siri.SiriFuzzyTripMatcher; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.updater.siri.EntityResolver; +import org.opentripplanner.updater.siri.SiriFuzzyTripMatcher; /** * Give access to the transit data and street model in the context of a real-time updater. diff --git a/src/main/java/org/opentripplanner/updater/TimetableSnapshotSourceParameters.java b/application/src/main/java/org/opentripplanner/updater/TimetableSnapshotSourceParameters.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/TimetableSnapshotSourceParameters.java rename to application/src/main/java/org/opentripplanner/updater/TimetableSnapshotSourceParameters.java diff --git a/src/main/java/org/opentripplanner/updater/UpdatersParameters.java b/application/src/main/java/org/opentripplanner/updater/UpdatersParameters.java similarity index 88% rename from src/main/java/org/opentripplanner/updater/UpdatersParameters.java rename to application/src/main/java/org/opentripplanner/updater/UpdatersParameters.java index 5f27f9dbd45..312fa3e2fbc 100644 --- a/src/main/java/org/opentripplanner/updater/UpdatersParameters.java +++ b/application/src/main/java/org/opentripplanner/updater/UpdatersParameters.java @@ -1,13 +1,13 @@ package org.opentripplanner.updater; import java.util.List; -import org.opentripplanner.ext.siri.updater.SiriETUpdaterParameters; -import org.opentripplanner.ext.siri.updater.SiriSXUpdaterParameters; import org.opentripplanner.ext.siri.updater.azure.SiriAzureETUpdaterParameters; import org.opentripplanner.ext.siri.updater.azure.SiriAzureSXUpdaterParameters; -import org.opentripplanner.ext.siri.updater.google.SiriETGooglePubsubUpdaterParameters; import org.opentripplanner.ext.vehiclerentalservicedirectory.api.VehicleRentalServiceDirectoryFetcherParameters; import org.opentripplanner.updater.alert.GtfsRealtimeAlertsUpdaterParameters; +import org.opentripplanner.updater.siri.updater.SiriETUpdaterParameters; +import org.opentripplanner.updater.siri.updater.SiriSXUpdaterParameters; +import org.opentripplanner.updater.siri.updater.google.SiriETGooglePubsubUpdaterParameters; import org.opentripplanner.updater.trip.MqttGtfsRealtimeUpdaterParameters; import org.opentripplanner.updater.trip.PollingTripUpdaterParameters; import org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters; diff --git a/src/main/java/org/opentripplanner/updater/alert/AlertsUpdateHandler.java b/application/src/main/java/org/opentripplanner/updater/alert/AlertsUpdateHandler.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/alert/AlertsUpdateHandler.java rename to application/src/main/java/org/opentripplanner/updater/alert/AlertsUpdateHandler.java diff --git a/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeAlertsUpdater.java b/application/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeAlertsUpdater.java similarity index 91% rename from src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeAlertsUpdater.java rename to application/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeAlertsUpdater.java index 728c07690ab..a5be5ef4185 100644 --- a/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeAlertsUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeAlertsUpdater.java @@ -4,13 +4,13 @@ import java.net.URI; import org.opentripplanner.framework.io.OtpHttpClient; import org.opentripplanner.framework.io.OtpHttpClientFactory; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.impl.TransitAlertServiceImpl; import org.opentripplanner.routing.services.TransitAlertService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.spi.PollingGraphUpdater; import org.opentripplanner.updater.spi.WriteToGraphCallback; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,12 +31,12 @@ public class GtfsRealtimeAlertsUpdater extends PollingGraphUpdater implements Tr public GtfsRealtimeAlertsUpdater( GtfsRealtimeAlertsUpdaterParameters config, - TransitModel transitModel + TimetableRepository timetableRepository ) { super(config); this.url = config.url(); this.headers = HttpHeaders.of().acceptProtobuf().add(config.headers()).build(); - TransitAlertService transitAlertService = new TransitAlertServiceImpl(transitModel); + TransitAlertService transitAlertService = new TransitAlertServiceImpl(timetableRepository); this.transitAlertService = transitAlertService; @@ -88,7 +88,7 @@ protected void runPolling() { lastTimestamp = feedTimestamp; } catch (Exception e) { - LOG.error("Error reading gtfs-realtime feed from " + url, e); + LOG.error("Failed to process GTFS-RT Alerts feed from {}", url, e); } } } diff --git a/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeAlertsUpdaterParameters.java b/application/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeAlertsUpdaterParameters.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeAlertsUpdaterParameters.java rename to application/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeAlertsUpdaterParameters.java diff --git a/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeCauseMapper.java b/application/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeCauseMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeCauseMapper.java rename to application/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeCauseMapper.java diff --git a/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeEffectMapper.java b/application/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeEffectMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeEffectMapper.java rename to application/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeEffectMapper.java diff --git a/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeSeverityMapper.java b/application/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeSeverityMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeSeverityMapper.java rename to application/src/main/java/org/opentripplanner/updater/alert/GtfsRealtimeSeverityMapper.java diff --git a/src/main/java/org/opentripplanner/updater/alert/TransitAlertProvider.java b/application/src/main/java/org/opentripplanner/updater/alert/TransitAlertProvider.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/alert/TransitAlertProvider.java rename to application/src/main/java/org/opentripplanner/updater/alert/TransitAlertProvider.java diff --git a/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java b/application/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java similarity index 83% rename from src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java rename to application/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java index aed4ef13ece..1106d621873 100644 --- a/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java +++ b/application/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java @@ -3,12 +3,8 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import org.opentripplanner.ext.siri.SiriTimetableSnapshotSource; -import org.opentripplanner.ext.siri.updater.SiriETUpdater; -import org.opentripplanner.ext.siri.updater.SiriSXUpdater; import org.opentripplanner.ext.siri.updater.azure.SiriAzureETUpdater; import org.opentripplanner.ext.siri.updater.azure.SiriAzureSXUpdater; -import org.opentripplanner.ext.siri.updater.google.SiriETGooglePubsubUpdater; import org.opentripplanner.ext.vehiclerentalservicedirectory.VehicleRentalServiceDirectoryFetcher; import org.opentripplanner.ext.vehiclerentalservicedirectory.api.VehicleRentalServiceDirectoryFetcherParameters; import org.opentripplanner.framework.io.OtpHttpClientFactory; @@ -16,12 +12,17 @@ import org.opentripplanner.model.calendar.openinghours.OpeningHoursCalendarService; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleRepository; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; import org.opentripplanner.service.vehiclerental.VehicleRentalRepository; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.updater.DefaultRealTimeUpdateContext; import org.opentripplanner.updater.GraphUpdaterManager; import org.opentripplanner.updater.UpdatersParameters; import org.opentripplanner.updater.alert.GtfsRealtimeAlertsUpdater; +import org.opentripplanner.updater.siri.SiriTimetableSnapshotSource; +import org.opentripplanner.updater.siri.updater.SiriETUpdater; +import org.opentripplanner.updater.siri.updater.SiriSXUpdater; +import org.opentripplanner.updater.siri.updater.google.SiriETGooglePubsubUpdater; import org.opentripplanner.updater.spi.GraphUpdater; import org.opentripplanner.updater.spi.TimetableSnapshotFlush; import org.opentripplanner.updater.trip.MqttGtfsRealtimeUpdater; @@ -45,10 +46,11 @@ public class UpdaterConfigurator { private final Graph graph; - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; private final UpdatersParameters updatersParameters; private final RealtimeVehicleRepository realtimeVehicleRepository; private final VehicleRentalRepository vehicleRentalRepository; + private final VehicleParkingRepository parkingRepository; private SiriTimetableSnapshotSource siriTimetableSnapshotSource = null; private TimetableSnapshotSource gtfsTimetableSnapshotSource = null; @@ -56,28 +58,32 @@ private UpdaterConfigurator( Graph graph, RealtimeVehicleRepository realtimeVehicleRepository, VehicleRentalRepository vehicleRentalRepository, - TransitModel transitModel, + VehicleParkingRepository parkingRepository, + TimetableRepository timetableRepository, UpdatersParameters updatersParameters ) { this.graph = graph; this.realtimeVehicleRepository = realtimeVehicleRepository; this.vehicleRentalRepository = vehicleRentalRepository; - this.transitModel = transitModel; + this.timetableRepository = timetableRepository; this.updatersParameters = updatersParameters; + this.parkingRepository = parkingRepository; } public static void configure( Graph graph, RealtimeVehicleRepository realtimeVehicleRepository, VehicleRentalRepository vehicleRentalRepository, - TransitModel transitModel, + VehicleParkingRepository parkingRepository, + TimetableRepository timetableRepository, UpdatersParameters updatersParameters ) { new UpdaterConfigurator( graph, realtimeVehicleRepository, vehicleRentalRepository, - transitModel, + parkingRepository, + timetableRepository, updatersParameters ) .configure(); @@ -102,7 +108,7 @@ private void configure() { timetableSnapshotBuffer = gtfsTimetableSnapshotSource.getTimetableSnapshotBuffer(); } GraphUpdaterManager updaterManager = new GraphUpdaterManager( - new DefaultRealTimeUpdateContext(graph, transitModel, timetableSnapshotBuffer), + new DefaultRealTimeUpdateContext(graph, timetableRepository, timetableSnapshotBuffer), updaters ); @@ -116,12 +122,12 @@ private void configure() { } // Otherwise add it to the graph else { - transitModel.setUpdaterManager(updaterManager); + timetableRepository.setUpdaterManager(updaterManager); } } - public static void shutdownGraph(TransitModel transitModel) { - GraphUpdaterManager updaterManager = transitModel.getUpdaterManager(); + public static void shutdownGraph(TimetableRepository timetableRepository) { + GraphUpdaterManager updaterManager = timetableRepository.getUpdaterManager(); if (updaterManager != null) { updaterManager.stop(); } @@ -167,7 +173,7 @@ private List createUpdatersFromConfig() { } } for (var configItem : updatersParameters.getGtfsRealtimeAlertsUpdaterParameters()) { - updaters.add(new GtfsRealtimeAlertsUpdater(configItem, transitModel)); + updaters.add(new GtfsRealtimeAlertsUpdater(configItem, timetableRepository)); } for (var configItem : updatersParameters.getPollingStoptimeUpdaterParameters()) { updaters.add(new PollingTripUpdater(configItem, provideGtfsTimetableSnapshot())); @@ -182,7 +188,7 @@ private List createUpdatersFromConfig() { updaters.add(new SiriETGooglePubsubUpdater(configItem, provideSiriTimetableSnapshot())); } for (var configItem : updatersParameters.getSiriSXUpdaterParameters()) { - updaters.add(new SiriSXUpdater(configItem, transitModel)); + updaters.add(new SiriSXUpdater(configItem, timetableRepository)); } for (var configItem : updatersParameters.getMqttGtfsRealtimeUpdaterParameters()) { updaters.add(new MqttGtfsRealtimeUpdater(configItem, provideGtfsTimetableSnapshot())); @@ -195,22 +201,13 @@ private List createUpdatersFromConfig() { openingHoursCalendarService ); updaters.add( - new VehicleParkingUpdater( - configItem, - source, - graph.getLinker(), - graph.getVehicleParkingService() - ) + new VehicleParkingUpdater(configItem, source, graph.getLinker(), parkingRepository) ); } case AVAILABILITY_ONLY -> { var source = AvailabilityDatasourceFactory.create(configItem); updaters.add( - new VehicleParkingAvailabilityUpdater( - configItem, - source, - graph.getVehicleParkingService() - ) + new VehicleParkingAvailabilityUpdater(configItem, source, parkingRepository) ); } } @@ -219,7 +216,7 @@ private List createUpdatersFromConfig() { updaters.add(new SiriAzureETUpdater(configItem, provideSiriTimetableSnapshot())); } for (var configItem : updatersParameters.getSiriAzureSXUpdaterParameters()) { - updaters.add(new SiriAzureSXUpdater(configItem, transitModel)); + updaters.add(new SiriAzureSXUpdater(configItem, timetableRepository)); } return updaters; @@ -230,7 +227,7 @@ private SiriTimetableSnapshotSource provideSiriTimetableSnapshot() { this.siriTimetableSnapshotSource = new SiriTimetableSnapshotSource( updatersParameters.timetableSnapshotParameters(), - transitModel + timetableRepository ); } @@ -240,7 +237,10 @@ private SiriTimetableSnapshotSource provideSiriTimetableSnapshot() { private TimetableSnapshotSource provideGtfsTimetableSnapshot() { if (gtfsTimetableSnapshotSource == null) { this.gtfsTimetableSnapshotSource = - new TimetableSnapshotSource(updatersParameters.timetableSnapshotParameters(), transitModel); + new TimetableSnapshotSource( + updatersParameters.timetableSnapshotParameters(), + timetableRepository + ); } return gtfsTimetableSnapshotSource; } diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-1.excalidraw b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-1.excalidraw similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-1.excalidraw rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-1.excalidraw diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-1.svg b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-1.svg similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-1.svg rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-1.svg diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-2.excalidraw b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-2.excalidraw similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-2.excalidraw rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-2.excalidraw diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-2.svg b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-2.svg similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-2.svg rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-2.svg diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-3.excalidraw b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-3.excalidraw similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-3.excalidraw rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-3.excalidraw diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-3.svg b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-3.svg similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-3.svg rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-3.svg diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-4.excalidraw b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-4.excalidraw similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-4.excalidraw rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-4.excalidraw diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-4.svg b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-4.svg similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-4.svg rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-4.svg diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-5.excalidraw b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-5.excalidraw similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-5.excalidraw rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-5.excalidraw diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-5.svg b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-5.svg similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-5.svg rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-5.svg diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-6.excalidraw b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-6.excalidraw similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-6.excalidraw rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-6.excalidraw diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-6.svg b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-6.svg similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-6.svg rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-6.svg diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-7.excalidraw b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-7.excalidraw similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-7.excalidraw rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-7.excalidraw diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-7.svg b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-7.svg similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-7.svg rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-7.svg diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-8.excalidraw b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-8.excalidraw similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-8.excalidraw rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-8.excalidraw diff --git a/src/main/java/org/opentripplanner/updater/images/snapshot-manager-8.svg b/application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-8.svg similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/snapshot-manager-8.svg rename to application/src/main/java/org/opentripplanner/updater/images/snapshot-manager-8.svg diff --git a/src/main/java/org/opentripplanner/updater/images/timetable-lookup.excalidraw b/application/src/main/java/org/opentripplanner/updater/images/timetable-lookup.excalidraw similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/timetable-lookup.excalidraw rename to application/src/main/java/org/opentripplanner/updater/images/timetable-lookup.excalidraw diff --git a/src/main/java/org/opentripplanner/updater/images/timetable-lookup.svg b/application/src/main/java/org/opentripplanner/updater/images/timetable-lookup.svg similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/timetable-lookup.svg rename to application/src/main/java/org/opentripplanner/updater/images/timetable-lookup.svg diff --git a/src/main/java/org/opentripplanner/updater/images/updater-threads-queues.excalidraw b/application/src/main/java/org/opentripplanner/updater/images/updater-threads-queues.excalidraw similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/updater-threads-queues.excalidraw rename to application/src/main/java/org/opentripplanner/updater/images/updater-threads-queues.excalidraw diff --git a/src/main/java/org/opentripplanner/updater/images/updater-threads-queues.svg b/application/src/main/java/org/opentripplanner/updater/images/updater-threads-queues.svg similarity index 100% rename from src/main/java/org/opentripplanner/updater/images/updater-threads-queues.svg rename to application/src/main/java/org/opentripplanner/updater/images/updater-threads-queues.svg diff --git a/src/main/java/org/opentripplanner/updater/package.md b/application/src/main/java/org/opentripplanner/updater/package.md similarity index 100% rename from src/main/java/org/opentripplanner/updater/package.md rename to application/src/main/java/org/opentripplanner/updater/package.md diff --git a/src/ext/java/org/opentripplanner/ext/siri/AddedTripBuilder.java b/application/src/main/java/org/opentripplanner/updater/siri/AddedTripBuilder.java similarity index 92% rename from src/ext/java/org/opentripplanner/ext/siri/AddedTripBuilder.java rename to application/src/main/java/org/opentripplanner/updater/siri/AddedTripBuilder.java index cdbaa8f3d4c..d5f68c4d153 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/AddedTripBuilder.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/AddedTripBuilder.java @@ -1,7 +1,7 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import static java.lang.Boolean.TRUE; -import static org.opentripplanner.ext.siri.mapper.SiriTransportModeMapper.mapTransitMainMode; +import static org.opentripplanner.updater.siri.mapper.SiriTransportModeMapper.mapTransitMainMode; import static org.opentripplanner.updater.spi.UpdateError.UpdateErrorType.CANNOT_RESOLVE_AGENCY; import static org.opentripplanner.updater.spi.UpdateError.UpdateErrorType.NO_START_DATE; import static org.opentripplanner.updater.spi.UpdateError.UpdateErrorType.NO_VALID_STOPS; @@ -14,11 +14,8 @@ import java.util.List; import java.util.Objects; import java.util.function.Function; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opentripplanner.ext.siri.mapper.PickDropMapper; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.StopTime; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.DataValidationException; @@ -36,8 +33,10 @@ import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.model.timetable.TripTimesFactory; import org.opentripplanner.transit.service.TransitEditorService; +import org.opentripplanner.updater.siri.mapper.PickDropMapper; import org.opentripplanner.updater.spi.DataValidationExceptionMapper; import org.opentripplanner.updater.spi.UpdateError; +import org.opentripplanner.utils.time.ServiceDateUtils; import org.rutebanken.netex.model.BusSubmodeEnumeration; import org.rutebanken.netex.model.RailSubmodeEnumeration; import org.slf4j.Logger; @@ -57,6 +56,7 @@ class AddedTripBuilder { private final Function getTripPatternId; private final FeedScopedId tripId; private final Operator operator; + private final String dataSource; private final String lineRef; private final Route replacedRoute; private final LocalDate serviceDate; @@ -82,11 +82,14 @@ class AddedTripBuilder { Objects.requireNonNull(newServiceJourneyRef, "EstimatedVehicleJourneyCode is required"); tripId = entityResolver.resolveId(newServiceJourneyRef); - //OperatorRef of added trip + // OperatorRef of added trip Objects.requireNonNull(estimatedVehicleJourney.getOperatorRef(), "OperatorRef is required"); String operatorRef = estimatedVehicleJourney.getOperatorRef().getValue(); operator = entityResolver.resolveOperator(operatorRef); + // DataSource of added trip + dataSource = estimatedVehicleJourney.getDataSource(); + // LineRef of added trip Objects.requireNonNull(estimatedVehicleJourney.getLineRef(), "LineRef is required"); lineRef = estimatedVehicleJourney.getLineRef().getValue(); @@ -136,7 +139,8 @@ class AddedTripBuilder { boolean cancellation, String shortName, String headsign, - List replacedTrips + List replacedTrips, + String dataSource ) { this.transitService = transitService; this.entityResolver = entityResolver; @@ -156,20 +160,21 @@ class AddedTripBuilder { this.shortName = shortName; this.headsign = headsign; this.replacedTrips = replacedTrips; + this.dataSource = dataSource; } Result build() { if (calls.size() < 2) { - return UpdateError.result(tripId, TOO_FEW_STOPS); + return UpdateError.result(tripId, TOO_FEW_STOPS, dataSource); } if (serviceDate == null) { - return UpdateError.result(tripId, NO_START_DATE); + return UpdateError.result(tripId, NO_START_DATE, dataSource); } FeedScopedId calServiceId = transitService.getOrCreateServiceIdForDate(serviceDate); if (calServiceId == null) { - return UpdateError.result(tripId, NO_START_DATE); + return UpdateError.result(tripId, NO_START_DATE, dataSource); } boolean isAddedRoute = false; @@ -177,11 +182,11 @@ Result build() { if (route == null) { Agency agency = resolveAgency(); if (agency == null) { - return UpdateError.result(tripId, CANNOT_RESOLVE_AGENCY); + return UpdateError.result(tripId, CANNOT_RESOLVE_AGENCY, dataSource); } route = createRoute(agency); isAddedRoute = true; - LOG.info("Adding route {} to transitModel.", route); + LOG.info("Adding route {} to timetableRepository.", route); } Trip trip = createTrip(route, calServiceId); @@ -200,9 +205,9 @@ Result build() { stopSequence == (calls.size() - 1) ); - // Drop this update if the call refers to an unknown stop (not present in the stop model). + // Drop this update if the call refers to an unknown stop (not present in the site repository). if (stopTime == null) { - return UpdateError.result(tripId, NO_VALID_STOPS); + return UpdateError.result(tripId, NO_VALID_STOPS, dataSource); } aimedStopTimes.add(stopTime); @@ -210,13 +215,6 @@ Result build() { // TODO: We always create a new TripPattern to be able to modify its scheduled timetable StopPattern stopPattern = new StopPattern(aimedStopTimes); - TripPattern pattern = TripPattern - .of(getTripPatternId.apply(trip)) - .withRoute(trip.getRoute()) - .withMode(trip.getMode()) - .withNetexSubmode(trip.getNetexSubMode()) - .withStopPattern(stopPattern) - .build(); RealTimeTripTimes tripTimes = TripTimesFactory.tripTimes( trip, @@ -228,8 +226,17 @@ Result build() { // but in case of trip cancellation, OTP will fall back to scheduled trip times // therefore they must be valid tripTimes.validateNonIncreasingTimes(); - tripTimes.setServiceCode(transitService.getServiceCodeForId(trip.getServiceId())); - pattern.add(tripTimes); + tripTimes.setServiceCode(transitService.getServiceCode(trip.getServiceId())); + + TripPattern pattern = TripPattern + .of(getTripPatternId.apply(trip)) + .withRoute(trip.getRoute()) + .withMode(trip.getMode()) + .withNetexSubmode(trip.getNetexSubMode()) + .withStopPattern(stopPattern) + .withScheduledTimeTableBuilder(builder -> builder.addTripTimes(tripTimes)) + .build(); + RealTimeTripTimes updatedTripTimes = tripTimes.copyScheduledTimes(); // Loop through calls again and apply updates @@ -255,7 +262,7 @@ Result build() { try { updatedTripTimes.validateNonIncreasingTimes(); } catch (DataValidationException e) { - return DataValidationExceptionMapper.toResult(e); + return DataValidationExceptionMapper.toResult(e, dataSource); } var tripOnServiceDate = TripOnServiceDate @@ -272,7 +279,8 @@ Result build() { serviceDate, tripOnServiceDate, pattern, - isAddedRoute + isAddedRoute, + dataSource ) ); } @@ -284,7 +292,6 @@ Result build() { * * @return a new Route */ - @Nonnull private Route createRoute(Agency agency) { var routeBuilder = Route.of(entityResolver.resolveId(lineRef)); @@ -308,7 +315,7 @@ private Route createRoute(Agency agency) { @Nullable private Agency resolveAgency() { return transitService - .getAllRoutes() + .listRoutes() .stream() .filter(r -> r != null && r.getOperator() != null && r.getOperator().equals(operator)) .findFirst() @@ -335,7 +342,7 @@ private Trip createTrip(Route route, FeedScopedId calServiceId) { } /** - * Map the call to a StopTime or return null if the stop cannot be found in the stop model. + * Map the call to a StopTime or return null if the stop cannot be found in the site repository. */ private StopTime createStopTime( Trip trip, diff --git a/src/ext/java/org/opentripplanner/ext/siri/CallWrapper.java b/application/src/main/java/org/opentripplanner/updater/siri/CallWrapper.java similarity index 99% rename from src/ext/java/org/opentripplanner/ext/siri/CallWrapper.java rename to application/src/main/java/org/opentripplanner/updater/siri/CallWrapper.java index 82649e08afb..5b89e6cc50e 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/CallWrapper.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/CallWrapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import java.time.ZonedDateTime; import java.util.ArrayList; diff --git a/src/ext/java/org/opentripplanner/ext/siri/DebugString.java b/application/src/main/java/org/opentripplanner/updater/siri/DebugString.java similarity index 94% rename from src/ext/java/org/opentripplanner/ext/siri/DebugString.java rename to application/src/main/java/org/opentripplanner/updater/siri/DebugString.java index d6b1e573599..fa5d45544e0 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/DebugString.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/DebugString.java @@ -1,6 +1,6 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; import uk.org.siri.siri20.DataFrameRefStructure; import uk.org.siri.siri20.DatedVehicleJourneyRef; import uk.org.siri.siri20.EstimatedVehicleJourney; diff --git a/src/ext/java/org/opentripplanner/ext/siri/EntityResolver.java b/application/src/main/java/org/opentripplanner/updater/siri/EntityResolver.java similarity index 91% rename from src/ext/java/org/opentripplanner/ext/siri/EntityResolver.java rename to application/src/main/java/org/opentripplanner/updater/siri/EntityResolver.java index 3c142ac693d..47eb45ad287 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/EntityResolver.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/EntityResolver.java @@ -1,12 +1,9 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import java.time.Duration; import java.time.LocalDate; import java.time.ZonedDateTime; import java.time.format.DateTimeParseException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; import javax.annotation.Nullable; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; @@ -15,7 +12,6 @@ import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripIdAndServiceDate; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; -import org.opentripplanner.transit.model.timetable.TripOnServiceDateBuilder; import org.opentripplanner.transit.service.TransitService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,7 +19,6 @@ import uk.org.siri.siri20.EstimatedVehicleJourney; import uk.org.siri.siri20.FramedVehicleJourneyRefStructure; import uk.org.siri.siri20.MonitoredVehicleJourneyStructure; -import uk.org.siri.siri20.VehicleJourneyRef; /** * This class is responsible for resolving references to various entities in the transit model for @@ -59,7 +54,7 @@ public Trip resolveTrip(EstimatedVehicleJourney journey) { if (journey.getDatedVehicleJourneyRef() != null) { String datedServiceJourneyId = journey.getDatedVehicleJourneyRef().getValue(); - TripOnServiceDate tripOnServiceDate = transitService.getTripOnServiceDateById( + TripOnServiceDate tripOnServiceDate = transitService.getTripOnServiceDate( resolveId(datedServiceJourneyId) ); @@ -70,9 +65,7 @@ public Trip resolveTrip(EstimatedVehicleJourney journey) { // It is possible that the trip has previously been added, resolve the added trip if (journey.getEstimatedVehicleJourneyCode() != null) { - var addedTrip = transitService.getTripForId( - resolveId(journey.getEstimatedVehicleJourneyCode()) - ); + var addedTrip = transitService.getTrip(resolveId(journey.getEstimatedVehicleJourneyCode())); if (addedTrip != null) { return addedTrip; } @@ -120,13 +113,13 @@ public TripOnServiceDate resolveTripOnServiceDate( return null; } - return transitService.getTripOnServiceDateForTripAndDay( + return transitService.getTripOnServiceDate( new TripIdAndServiceDate(resolveId(serviceJourneyId), serviceDate) ); } public TripOnServiceDate resolveTripOnServiceDate(FeedScopedId datedServiceJourneyId) { - return transitService.getTripOnServiceDateById(datedServiceJourneyId); + return transitService.getTripOnServiceDate(datedServiceJourneyId); } public FeedScopedId resolveDatedServiceJourneyId( @@ -187,7 +180,7 @@ public Trip resolveTrip(FramedVehicleJourneyRefStructure journey) { } public Trip resolveTrip(String serviceJourneyId) { - return transitService.getTripForId(resolveId(serviceJourneyId)); + return transitService.getTrip(resolveId(serviceJourneyId)); } /** @@ -201,11 +194,11 @@ public RegularStop resolveQuay(String quayRef) { * Resolve a {@link Route} from a line id. */ public Route resolveRoute(String lineRef) { - return transitService.getRouteForId(resolveId(lineRef)); + return transitService.getRoute(resolveId(lineRef)); } public Operator resolveOperator(String operatorRef) { - return transitService.getOperatorForId(resolveId(operatorRef)); + return transitService.getOperator(resolveId(operatorRef)); } @Nullable @@ -251,7 +244,7 @@ private int calculateDayOffset(EstimatedVehicleJourney vehicleJourney) { if (trip == null) { return 0; } - var pattern = transitService.getPatternForTrip(trip); + var pattern = transitService.findPattern(trip); if (pattern == null) { return 0; } diff --git a/src/ext/java/org/opentripplanner/ext/siri/ModifiedTripBuilder.java b/application/src/main/java/org/opentripplanner/updater/siri/ModifiedTripBuilder.java similarity index 93% rename from src/ext/java/org/opentripplanner/ext/siri/ModifiedTripBuilder.java rename to application/src/main/java/org/opentripplanner/updater/siri/ModifiedTripBuilder.java index 5c21be364a5..06768087c74 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/ModifiedTripBuilder.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/ModifiedTripBuilder.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import static java.lang.Boolean.TRUE; import static org.opentripplanner.model.PickDrop.NONE; @@ -10,8 +10,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import org.opentripplanner.ext.siri.mapper.PickDropMapper; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.transit.model.framework.DataValidationException; import org.opentripplanner.transit.model.framework.Result; import org.opentripplanner.transit.model.network.StopPattern; @@ -21,8 +19,10 @@ import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.transit.model.timetable.RealTimeTripTimes; import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.updater.siri.mapper.PickDropMapper; import org.opentripplanner.updater.spi.DataValidationExceptionMapper; import org.opentripplanner.updater.spi.UpdateError; +import org.opentripplanner.utils.time.ServiceDateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.org.siri.siri20.EstimatedVehicleJourney; @@ -45,6 +45,7 @@ public class ModifiedTripBuilder { private final boolean cancellation; private final OccupancyEnumeration occupancy; private final boolean predictionInaccurate; + private final String dataSource; public ModifiedTripBuilder( TripTimes existingTripTimes, @@ -64,6 +65,7 @@ public ModifiedTripBuilder( cancellation = TRUE.equals(journey.isCancellation()); predictionInaccurate = TRUE.equals(journey.isPredictionInaccurate()); occupancy = journey.getOccupancy(); + dataSource = journey.getDataSource(); } /** @@ -78,7 +80,8 @@ public ModifiedTripBuilder( List calls, boolean cancellation, OccupancyEnumeration occupancy, - boolean predictionInaccurate + boolean predictionInaccurate, + String dataSource ) { this.existingTripTimes = existingTripTimes; this.pattern = pattern; @@ -89,6 +92,7 @@ public ModifiedTripBuilder( this.cancellation = cancellation; this.occupancy = occupancy; this.predictionInaccurate = predictionInaccurate; + this.dataSource = dataSource; } /** @@ -103,7 +107,9 @@ public Result build() { if (cancellation || stopPattern.isAllStopsNonRoutable()) { LOG.debug("Trip is cancelled"); newTimes.cancelTrip(); - return Result.success(new TripUpdate(pattern.getStopPattern(), newTimes, serviceDate)); + return Result.success( + new TripUpdate(pattern.getStopPattern(), newTimes, serviceDate, dataSource) + ); } applyUpdates(newTimes); @@ -116,7 +122,7 @@ public Result build() { newTimes.setRealTimeState(RealTimeState.MODIFIED); } - // TODO - Handle DataValidationException at the outemost level(pr trip) + // TODO - Handle DataValidationException at the outermost level (pr trip) try { newTimes.validateNonIncreasingTimes(); } catch (DataValidationException e) { @@ -125,7 +131,7 @@ public Result build() { newTimes.getTrip().getId(), e.getMessage() ); - return DataValidationExceptionMapper.toResult(e); + return DataValidationExceptionMapper.toResult(e, dataSource); } int numStopsInUpdate = newTimes.getNumStops(); @@ -137,11 +143,11 @@ public Result build() { numStopsInUpdate, numStopsInPattern ); - return UpdateError.result(existingTripTimes.getTrip().getId(), TOO_FEW_STOPS); + return UpdateError.result(existingTripTimes.getTrip().getId(), TOO_FEW_STOPS, dataSource); } LOG.debug("A valid TripUpdate object was applied using the Timetable class update method."); - return Result.success(new TripUpdate(stopPattern, newTimes, serviceDate)); + return Result.success(new TripUpdate(stopPattern, newTimes, serviceDate, dataSource)); } /** diff --git a/src/ext/java/org/opentripplanner/ext/siri/SiriAlertsUpdateHandler.java b/application/src/main/java/org/opentripplanner/updater/siri/SiriAlertsUpdateHandler.java similarity index 87% rename from src/ext/java/org/opentripplanner/ext/siri/SiriAlertsUpdateHandler.java rename to application/src/main/java/org/opentripplanner/updater/siri/SiriAlertsUpdateHandler.java index 1a2d82df843..9656d1a0b01 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/SiriAlertsUpdateHandler.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/SiriAlertsUpdateHandler.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import java.time.Duration; import java.time.ZonedDateTime; @@ -8,8 +8,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.opentripplanner.ext.siri.mapper.AffectsMapper; -import org.opentripplanner.ext.siri.mapper.SiriSeverityMapper; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.framework.i18n.TranslatedString; @@ -21,6 +19,8 @@ import org.opentripplanner.routing.services.TransitAlertService; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.updater.RealTimeUpdateContext; +import org.opentripplanner.updater.siri.mapper.AffectsMapper; +import org.opentripplanner.updater.siri.mapper.SiriSeverityMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.org.siri.siri20.DefaultedTextStructure; @@ -135,9 +135,9 @@ private TransitAlert mapSituationToAlert( TransitAlertBuilder alert = createAlertWithTexts(situation); if ( - (alert.headerText() == null || alert.headerText().toString().isEmpty()) && - (alert.descriptionText() == null || alert.descriptionText().toString().isEmpty()) && - (alert.detailText() == null || alert.detailText().toString().isEmpty()) + I18NString.hasNoValue(alert.headerText()) && + I18NString.hasNoValue(alert.descriptionText()) && + I18NString.hasNoValue(alert.detailText()) ) { LOG.debug( "Empty Alert - ignoring situationNumber: {}", @@ -221,18 +221,18 @@ private long getEpochSecond(ZonedDateTime startTime) { private TransitAlertBuilder createAlertWithTexts(PtSituationElement situation) { return TransitAlert .of(new FeedScopedId(feedId, situation.getSituationNumber().getValue())) - .withDescriptionText(getTranslatedString(situation.getDescriptions())) - .withDetailText(getTranslatedString(situation.getDetails())) - .withAdviceText(getTranslatedString(situation.getAdvices())) - .withHeaderText(getTranslatedString(situation.getSummaries())) - .withUrl(getInfoLinkAsString(situation.getInfoLinks())) - .addSiriUrls(getInfoLinks(situation.getInfoLinks())); + .withDescriptionText(mapTranslatedString(situation.getDescriptions())) + .withDetailText(mapTranslatedString(situation.getDetails())) + .withAdviceText(mapTranslatedString(situation.getAdvices())) + .withHeaderText(mapTranslatedString(situation.getSummaries())) + .withUrl(mapInfoLinkToI18NString(situation.getInfoLinks())) + .addSiriUrls(mapInfoLinks(situation)); } /* * Returns first InfoLink-uri as a String */ - private I18NString getInfoLinkAsString(PtSituationElement.InfoLinks infoLinks) { + private I18NString mapInfoLinkToI18NString(PtSituationElement.InfoLinks infoLinks) { if (infoLinks != null) { if (isNotEmpty(infoLinks.getInfoLinks())) { InfoLinkStructure infoLinkStructure = infoLinks.getInfoLinks().get(0); @@ -247,21 +247,32 @@ private I18NString getInfoLinkAsString(PtSituationElement.InfoLinks infoLinks) { /* * Returns all InfoLinks */ - private List getInfoLinks(PtSituationElement.InfoLinks infoLinks) { + private List mapInfoLinks(PtSituationElement situation) { + PtSituationElement.InfoLinks infoLinks = situation.getInfoLinks(); List alertUrls = new ArrayList<>(); if (infoLinks != null) { if (isNotEmpty(infoLinks.getInfoLinks())) { for (InfoLinkStructure infoLink : infoLinks.getInfoLinks()) { - AlertUrl alertUrl = new AlertUrl(); - + String label = null; List labels = infoLink.getLabels(); if (labels != null && !labels.isEmpty()) { - NaturalLanguageStringStructure label = labels.get(0); - alertUrl.label = label.getValue(); + NaturalLanguageStringStructure lbl = labels.get(0); + label = lbl.getValue(); } - alertUrl.uri = infoLink.getUri(); - alertUrls.add(alertUrl); + var uri = infoLink.getUri(); + if (uri != null) { + alertUrls.add(new AlertUrl(uri, label)); + } else { + if (LOG.isDebugEnabled()) { + LOG.debug( + "URI missing in info-link - ignoring info-link in situation: {}", + situation.getSituationNumber() != null + ? situation.getSituationNumber().getValue() + : null + ); + } + } } } } @@ -281,7 +292,7 @@ private boolean isNotEmpty(List list) { * * @return A TranslatedString containing the same information as the input */ - private I18NString getTranslatedString(List input) { + private I18NString mapTranslatedString(List input) { Map translations = new HashMap<>(); if (input != null && input.size() > 0) { for (DefaultedTextStructure textStructure : input) { diff --git a/src/ext/java/org/opentripplanner/ext/siri/SiriFuzzyTripMatcher.java b/application/src/main/java/org/opentripplanner/updater/siri/SiriFuzzyTripMatcher.java similarity index 94% rename from src/ext/java/org/opentripplanner/ext/siri/SiriFuzzyTripMatcher.java rename to application/src/main/java/org/opentripplanner/updater/siri/SiriFuzzyTripMatcher.java index ed5e9818b32..2cffc81b440 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/SiriFuzzyTripMatcher.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/SiriFuzzyTripMatcher.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import java.time.LocalDate; import java.time.ZonedDateTime; @@ -10,9 +10,7 @@ import java.util.Set; import java.util.function.BiFunction; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.Timetable; import org.opentripplanner.model.calendar.CalendarService; import org.opentripplanner.transit.model.basic.TransitMode; @@ -22,6 +20,7 @@ import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.time.ServiceDateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.org.siri.siri20.EstimatedVehicleJourney; @@ -88,7 +87,7 @@ public TripAndPattern match( EstimatedVehicleJourney journey, EntityResolver entityResolver, BiFunction getCurrentTimetable, - BiFunction getRealtimeAddedTripPattern + BiFunction getNewTripPatternForModifiedTrip ) { List calls = CallWrapper.of(journey); @@ -137,7 +136,7 @@ public TripAndPattern match( calls, entityResolver, getCurrentTimetable, - getRealtimeAddedTripPattern + getNewTripPatternForModifiedTrip ); } @@ -162,8 +161,8 @@ public List getTripIdForInternalPlanningCodeServiceDate( } private void initCache(TransitService index) { - for (Trip trip : index.getAllTrips()) { - TripPattern tripPattern = index.getPatternForTrip(trip); + for (Trip trip : index.listTrips()) { + TripPattern tripPattern = index.findPattern(trip); if (tripPattern == null) { continue; @@ -196,7 +195,6 @@ private static String createStartStopKey(String lastStopId, int lastStopArrivalT return lastStopId + ":" + lastStopArrivalTime; } - @Nonnull private Set getMatchingTripsOnStopOrSiblings( String lastStopPoint, ZonedDateTime arrivalTime, @@ -261,7 +259,7 @@ TripAndPattern getTripAndPatternForJourney( List calls, EntityResolver entityResolver, BiFunction getCurrentTimetable, - BiFunction getRealtimeAddedTripPattern + BiFunction getNewTripPatternForModifiedTrip ) { var journeyFirstStop = entityResolver.resolveQuay(calls.getFirst().getStopPointRef()); var journeyLastStop = entityResolver.resolveQuay(calls.getLast().getStopPointRef()); @@ -284,10 +282,13 @@ TripAndPattern getTripAndPatternForJourney( continue; } - var realTimeAddedTripPattern = getRealtimeAddedTripPattern.apply(trip.getId(), serviceDate); - TripPattern tripPattern = realTimeAddedTripPattern != null - ? realTimeAddedTripPattern - : transitService.getPatternForTrip(trip); + var newTripPatternForModifiedTrip = getNewTripPatternForModifiedTrip.apply( + trip.getId(), + serviceDate + ); + TripPattern tripPattern = newTripPatternForModifiedTrip != null + ? newTripPatternForModifiedTrip + : transitService.findPattern(trip); var firstStop = tripPattern.firstStop(); var lastStop = tripPattern.lastStop(); diff --git a/src/ext/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSource.java b/application/src/main/java/org/opentripplanner/updater/siri/SiriTimetableSnapshotSource.java similarity index 89% rename from src/ext/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSource.java rename to application/src/main/java/org/opentripplanner/updater/siri/SiriTimetableSnapshotSource.java index 7746df7d02f..73e4c711269 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSource.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/SiriTimetableSnapshotSource.java @@ -1,6 +1,7 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import static java.lang.Boolean.TRUE; +import static org.opentripplanner.updater.spi.UpdateError.UpdateErrorType.EMPTY_STOP_POINT_REF; import static org.opentripplanner.updater.spi.UpdateError.UpdateErrorType.NOT_MONITORED; import static org.opentripplanner.updater.spi.UpdateError.UpdateErrorType.NO_FUZZY_TRIP_MATCH; import static org.opentripplanner.updater.spi.UpdateError.UpdateErrorType.NO_START_DATE; @@ -24,8 +25,8 @@ import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.service.DefaultTransitService; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.transit.service.TransitEditorService; -import org.opentripplanner.transit.service.TransitModel; import org.opentripplanner.updater.TimetableSnapshotSourceParameters; import org.opentripplanner.updater.spi.DataValidationExceptionMapper; import org.opentripplanner.updater.spi.UpdateError; @@ -33,6 +34,7 @@ import org.opentripplanner.updater.spi.UpdateSuccess; import org.opentripplanner.updater.trip.TimetableSnapshotManager; import org.opentripplanner.updater.trip.UpdateIncrementality; +import org.opentripplanner.utils.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.org.siri.siri20.EstimatedTimetableDeliveryStructure; @@ -69,20 +71,20 @@ public class SiriTimetableSnapshotSource implements TimetableSnapshotProvider { public SiriTimetableSnapshotSource( TimetableSnapshotSourceParameters parameters, - TransitModel transitModel + TimetableRepository timetableRepository ) { this.snapshotManager = new TimetableSnapshotManager( - transitModel.getTransitLayerUpdater(), + timetableRepository.getTransitLayerUpdater(), parameters, - () -> LocalDate.now(transitModel.getTimeZone()) + () -> LocalDate.now(timetableRepository.getTimeZone()) ); this.transitEditorService = - new DefaultTransitService(transitModel, getTimetableSnapshotBuffer()); + new DefaultTransitService(timetableRepository, getTimetableSnapshotBuffer()); this.tripPatternCache = - new SiriTripPatternCache(tripPatternIdGenerator, transitEditorService::getPatternForTrip); + new SiriTripPatternCache(tripPatternIdGenerator, transitEditorService::findPattern); - transitModel.initTimetableSnapshotProvider(this); + timetableRepository.initTimetableSnapshotProvider(this); } /** @@ -150,6 +152,11 @@ private Result apply( @Nullable SiriFuzzyTripMatcher fuzzyTripMatcher, EntityResolver entityResolver ) { + for (var call : CallWrapper.of(journey)) { + if (StringUtils.hasNoValueOrNullAsString(call.getStopPointRef())) { + return UpdateError.result(null, EMPTY_STOP_POINT_REF, journey.getDataSource()); + } + } boolean shouldAddNewTrip = false; try { shouldAddNewTrip = shouldAddNewTrip(journey, entityResolver); @@ -174,7 +181,7 @@ private Result apply( /* commit */ return addTripToGraphAndBuffer(result.successValue()); } catch (DataValidationException e) { - return DataValidationExceptionMapper.toResult(e); + return DataValidationExceptionMapper.toResult(e, journey.getDataSource()); } catch (Exception e) { LOG.warn( "{} EstimatedJourney {} failed.", @@ -217,6 +224,7 @@ private Result handleModifiedTrip( EstimatedVehicleJourney estimatedVehicleJourney ) { Trip trip = entityResolver.resolveTrip(estimatedVehicleJourney); + String dataSource = estimatedVehicleJourney.getDataSource(); // Check if EstimatedVehicleJourney is reported as NOT monitored, ignore the notMonitored-flag // if the journey is NOT monitored because it has been cancelled @@ -224,27 +232,27 @@ private Result handleModifiedTrip( !TRUE.equals(estimatedVehicleJourney.isMonitored()) && !TRUE.equals(estimatedVehicleJourney.isCancellation()) ) { - return UpdateError.result(trip != null ? trip.getId() : null, NOT_MONITORED); + return UpdateError.result(trip != null ? trip.getId() : null, NOT_MONITORED, dataSource); } LocalDate serviceDate = entityResolver.resolveServiceDate(estimatedVehicleJourney); if (serviceDate == null) { - return UpdateError.result(trip != null ? trip.getId() : null, NO_START_DATE); + return UpdateError.result(trip != null ? trip.getId() : null, NO_START_DATE, dataSource); } TripPattern pattern; if (trip != null) { // Found exact match - pattern = transitEditorService.getPatternForTrip(trip); + pattern = transitEditorService.findPattern(trip); } else if (fuzzyTripMatcher != null) { // No exact match found - search for trips based on arrival-times/stop-patterns TripAndPattern tripAndPattern = fuzzyTripMatcher.match( estimatedVehicleJourney, entityResolver, this::getCurrentTimetable, - snapshotManager::getRealtimeAddedTripPattern + snapshotManager::getNewTripPatternForModifiedTrip ); if (tripAndPattern == null) { @@ -252,20 +260,20 @@ private Result handleModifiedTrip( "No trips found for EstimatedVehicleJourney. {}", DebugString.of(estimatedVehicleJourney) ); - return UpdateError.result(null, NO_FUZZY_TRIP_MATCH); + return UpdateError.result(null, NO_FUZZY_TRIP_MATCH, dataSource); } trip = tripAndPattern.trip(); pattern = tripAndPattern.tripPattern(); } else { - return UpdateError.result(null, TRIP_NOT_FOUND); + return UpdateError.result(null, TRIP_NOT_FOUND, dataSource); } Timetable currentTimetable = getCurrentTimetable(pattern, serviceDate); TripTimes existingTripTimes = currentTimetable.getTripTimes(trip); if (existingTripTimes == null) { LOG.debug("tripId {} not found in pattern.", trip.getId()); - return UpdateError.result(trip.getId(), TRIP_NOT_FOUND_IN_PATTERN); + return UpdateError.result(trip.getId(), TRIP_NOT_FOUND_IN_PATTERN, dataSource); } var updateResult = new ModifiedTripBuilder( existingTripTimes, @@ -293,7 +301,7 @@ private Result handleModifiedTrip( } /** - * Add a (new) trip to the transitModel and the buffer + * Add a (new) trip to the timetableRepository and the buffer */ private Result addTripToGraphAndBuffer(TripUpdate tripUpdate) { Trip trip = tripUpdate.tripTimes().getTrip(); @@ -315,7 +323,8 @@ private Result addTripToGraphAndBuffer(TripUpdate tr serviceDate, tripUpdate.addedTripOnServiceDate(), tripUpdate.tripCreation(), - tripUpdate.routeCreation() + tripUpdate.routeCreation(), + tripUpdate.dataSource() ); var result = snapshotManager.updateBuffer(realTimeTripUpdate); LOG.debug("Applied real-time data for trip {} on {}", trip, serviceDate); @@ -330,7 +339,7 @@ private Result addTripToGraphAndBuffer(TripUpdate tr private boolean markScheduledTripAsDeleted(Trip trip, final LocalDate serviceDate) { boolean success = false; - final TripPattern pattern = transitEditorService.getPatternForTrip(trip); + final TripPattern pattern = transitEditorService.findPattern(trip); if (pattern != null) { // Mark scheduled trip times for this trip in this pattern as deleted diff --git a/src/ext/java/org/opentripplanner/ext/siri/SiriTripPatternCache.java b/application/src/main/java/org/opentripplanner/updater/siri/SiriTripPatternCache.java similarity index 96% rename from src/ext/java/org/opentripplanner/ext/siri/SiriTripPatternCache.java rename to application/src/main/java/org/opentripplanner/updater/siri/SiriTripPatternCache.java index 40c008d0004..19816bd085f 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/SiriTripPatternCache.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/SiriTripPatternCache.java @@ -1,10 +1,9 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import java.time.LocalDate; import java.util.HashMap; import java.util.Map; import java.util.function.Function; -import javax.annotation.Nonnull; import org.opentripplanner.transit.model.network.StopPattern; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.Trip; @@ -71,9 +70,9 @@ public SiriTripPatternCache( * @return cached or newly created trip pattern */ public synchronized TripPattern getOrCreateTripPattern( - @Nonnull final StopPattern stopPattern, - @Nonnull final Trip trip, - @Nonnull LocalDate serviceDate + final StopPattern stopPattern, + final Trip trip, + LocalDate serviceDate ) { TripPattern originalTripPattern = getPatternForTrip.apply(trip); @@ -101,7 +100,7 @@ public synchronized TripPattern getOrCreateTripPattern( .withCreatedByRealtimeUpdater(true) .withOriginalTripPattern(originalTripPattern) .build(); - // TODO: Add pattern to transitModel index? + // TODO: Add pattern to timetableRepository index? // Add pattern to cache cache.put(key, tripPattern); diff --git a/src/ext/java/org/opentripplanner/ext/siri/SiriTripPatternIdGenerator.java b/application/src/main/java/org/opentripplanner/updater/siri/SiriTripPatternIdGenerator.java similarity index 97% rename from src/ext/java/org/opentripplanner/ext/siri/SiriTripPatternIdGenerator.java rename to application/src/main/java/org/opentripplanner/updater/siri/SiriTripPatternIdGenerator.java index 1b56938d712..c8ecc5e86a1 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/SiriTripPatternIdGenerator.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/SiriTripPatternIdGenerator.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import java.util.concurrent.atomic.AtomicInteger; import org.opentripplanner.gtfs.GenerateTripPatternsOperation; diff --git a/src/ext/java/org/opentripplanner/ext/siri/TimetableHelper.java b/application/src/main/java/org/opentripplanner/updater/siri/TimetableHelper.java similarity index 96% rename from src/ext/java/org/opentripplanner/ext/siri/TimetableHelper.java rename to application/src/main/java/org/opentripplanner/updater/siri/TimetableHelper.java index fea8bda686f..dad1bc9a243 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/TimetableHelper.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/TimetableHelper.java @@ -1,13 +1,13 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import static java.lang.Boolean.TRUE; import java.time.ZonedDateTime; import java.util.function.Supplier; -import org.opentripplanner.ext.siri.mapper.OccupancyMapper; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.transit.model.timetable.RealTimeTripTimes; +import org.opentripplanner.updater.siri.mapper.OccupancyMapper; +import org.opentripplanner.utils.time.ServiceDateUtils; import uk.org.siri.siri20.NaturalLanguageStringStructure; import uk.org.siri.siri20.OccupancyEnumeration; diff --git a/src/ext/java/org/opentripplanner/ext/siri/TripAndPattern.java b/application/src/main/java/org/opentripplanner/updater/siri/TripAndPattern.java similarity index 81% rename from src/ext/java/org/opentripplanner/ext/siri/TripAndPattern.java rename to application/src/main/java/org/opentripplanner/updater/siri/TripAndPattern.java index e8d700d8c72..2d3b547c356 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/TripAndPattern.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/TripAndPattern.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.Trip; diff --git a/src/ext/java/org/opentripplanner/ext/siri/TripUpdate.java b/application/src/main/java/org/opentripplanner/updater/siri/TripUpdate.java similarity index 59% rename from src/ext/java/org/opentripplanner/ext/siri/TripUpdate.java rename to application/src/main/java/org/opentripplanner/updater/siri/TripUpdate.java index 9874e9d0825..8432ed06d54 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/TripUpdate.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/TripUpdate.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import java.time.LocalDate; import java.util.Objects; @@ -11,12 +11,18 @@ /** * Represents the SIRI real-time update of a single trip. - * @param stopPattern the stop pattern to which belongs the updated trip. - * @param tripTimes the new trip times for the updated trip. - * @param serviceDate the service date for which this update applies (updates are valid only for one service date) - * @param addedTripOnServiceDate optionally if this trip update adds a new trip, the TripOnServiceDate corresponding to this new trip. - * @param addedTripPattern optionally if this trip update adds a new trip pattern , the new trip pattern to this new trip. - * @param routeCreation true if an added trip cannot be registered under an existing route and a new route must be created. + * + * @param stopPattern the stop pattern to which belongs the updated trip. + * @param tripTimes the new trip times for the updated trip. + * @param serviceDate the service date for which this update applies (updates are valid + * only for one service date) + * @param addedTripOnServiceDate optionally if this trip update adds a new trip, the + * TripOnServiceDate corresponding to this new trip. + * @param addedTripPattern optionally if this trip update adds a new trip pattern , the new + * trip pattern to this new trip. + * @param routeCreation true if an added trip cannot be registered under an existing route + * and a new route must be created. + * @param dataSource the dataSource of the real-time update. */ record TripUpdate( StopPattern stopPattern, @@ -24,7 +30,8 @@ record TripUpdate( LocalDate serviceDate, @Nullable TripOnServiceDate addedTripOnServiceDate, @Nullable TripPattern addedTripPattern, - boolean routeCreation + boolean routeCreation, + @Nullable String dataSource ) { public TripUpdate { Objects.requireNonNull(stopPattern); @@ -38,9 +45,10 @@ record TripUpdate( public TripUpdate( StopPattern stopPattern, RealTimeTripTimes updatedTripTimes, - LocalDate serviceDate + LocalDate serviceDate, + String dataSource ) { - this(stopPattern, updatedTripTimes, serviceDate, null, null, false); + this(stopPattern, updatedTripTimes, serviceDate, null, null, false, dataSource); } /** diff --git a/src/ext/java/org/opentripplanner/ext/siri/mapper/AffectsMapper.java b/application/src/main/java/org/opentripplanner/updater/siri/mapper/AffectsMapper.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/siri/mapper/AffectsMapper.java rename to application/src/main/java/org/opentripplanner/updater/siri/mapper/AffectsMapper.java index a1fb943f60c..1f1c8c0b907 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/mapper/AffectsMapper.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/mapper/AffectsMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.mapper; +package org.opentripplanner.updater.siri.mapper; import java.io.Serializable; import java.time.LocalDate; @@ -6,14 +6,14 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import org.opentripplanner.ext.siri.EntityResolver; -import org.opentripplanner.ext.siri.SiriFuzzyTripMatcher; import org.opentripplanner.routing.alertpatch.EntitySelector; import org.opentripplanner.routing.alertpatch.StopCondition; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.updater.siri.EntityResolver; +import org.opentripplanner.updater.siri.SiriFuzzyTripMatcher; import uk.org.ifopt.siri20.StopPlaceRef; import uk.org.siri.siri20.AffectedLineStructure; import uk.org.siri.siri20.AffectedOperatorStructure; @@ -375,7 +375,7 @@ private static FeedScopedId getStop( FeedScopedId id = new FeedScopedId(feedId, siriStopId); if (transitService.getRegularStop(id) != null) { return id; - } else if (transitService.getStationById(id) != null) { + } else if (transitService.getStation(id) != null) { return id; } diff --git a/src/ext/java/org/opentripplanner/ext/siri/mapper/OccupancyMapper.java b/application/src/main/java/org/opentripplanner/updater/siri/mapper/OccupancyMapper.java similarity index 92% rename from src/ext/java/org/opentripplanner/ext/siri/mapper/OccupancyMapper.java rename to application/src/main/java/org/opentripplanner/updater/siri/mapper/OccupancyMapper.java index 61b7a15798a..310846ebf9a 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/mapper/OccupancyMapper.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/mapper/OccupancyMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.mapper; +package org.opentripplanner.updater.siri.mapper; import org.opentripplanner.transit.model.timetable.OccupancyStatus; import uk.org.siri.siri20.OccupancyEnumeration; diff --git a/src/ext/java/org/opentripplanner/ext/siri/mapper/PickDropMapper.java b/application/src/main/java/org/opentripplanner/updater/siri/mapper/PickDropMapper.java similarity index 96% rename from src/ext/java/org/opentripplanner/ext/siri/mapper/PickDropMapper.java rename to application/src/main/java/org/opentripplanner/updater/siri/mapper/PickDropMapper.java index d35696ec35e..a82000fa08f 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/mapper/PickDropMapper.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/mapper/PickDropMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.mapper; +package org.opentripplanner.updater.siri.mapper; import static java.lang.Boolean.TRUE; import static org.opentripplanner.model.PickDrop.CANCELLED; @@ -6,8 +6,8 @@ import static org.opentripplanner.model.PickDrop.SCHEDULED; import java.util.Optional; -import org.opentripplanner.ext.siri.CallWrapper; import org.opentripplanner.model.PickDrop; +import org.opentripplanner.updater.siri.CallWrapper; import uk.org.siri.siri20.CallStatusEnumeration; public class PickDropMapper { diff --git a/src/ext/java/org/opentripplanner/ext/siri/mapper/SiriSeverityMapper.java b/application/src/main/java/org/opentripplanner/updater/siri/mapper/SiriSeverityMapper.java similarity index 95% rename from src/ext/java/org/opentripplanner/ext/siri/mapper/SiriSeverityMapper.java rename to application/src/main/java/org/opentripplanner/updater/siri/mapper/SiriSeverityMapper.java index 3b4b315aeb9..26962c62bb8 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/mapper/SiriSeverityMapper.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/mapper/SiriSeverityMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.mapper; +package org.opentripplanner.updater.siri.mapper; import org.opentripplanner.routing.alertpatch.AlertSeverity; import uk.org.siri.siri20.SeverityEnumeration; diff --git a/src/ext/java/org/opentripplanner/ext/siri/mapper/SiriTransportModeMapper.java b/application/src/main/java/org/opentripplanner/updater/siri/mapper/SiriTransportModeMapper.java similarity index 93% rename from src/ext/java/org/opentripplanner/ext/siri/mapper/SiriTransportModeMapper.java rename to application/src/main/java/org/opentripplanner/updater/siri/mapper/SiriTransportModeMapper.java index 02be6682140..7bae9d83436 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/mapper/SiriTransportModeMapper.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/mapper/SiriTransportModeMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.mapper; +package org.opentripplanner.updater.siri.mapper; import java.util.List; import org.opentripplanner.transit.model.basic.TransitMode; diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/AsyncEstimatedTimetableProcessor.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/AsyncEstimatedTimetableProcessor.java similarity index 96% rename from src/ext/java/org/opentripplanner/ext/siri/updater/AsyncEstimatedTimetableProcessor.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/AsyncEstimatedTimetableProcessor.java index db36936afd9..efcfab77a46 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/AsyncEstimatedTimetableProcessor.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/AsyncEstimatedTimetableProcessor.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.updater; +package org.opentripplanner.updater.siri.updater; import java.util.concurrent.Future; import java.util.function.Consumer; diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/AsyncEstimatedTimetableSource.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/AsyncEstimatedTimetableSource.java similarity index 95% rename from src/ext/java/org/opentripplanner/ext/siri/updater/AsyncEstimatedTimetableSource.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/AsyncEstimatedTimetableSource.java index 9a70c9d5615..b2fe96ba80f 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/AsyncEstimatedTimetableSource.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/AsyncEstimatedTimetableSource.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.updater; +package org.opentripplanner.updater.siri.updater; import java.util.concurrent.Future; import java.util.function.Function; diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/EstimatedTimetableHandler.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/EstimatedTimetableHandler.java similarity index 91% rename from src/ext/java/org/opentripplanner/ext/siri/updater/EstimatedTimetableHandler.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/EstimatedTimetableHandler.java index aa2882d8fe2..367055c6f66 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/EstimatedTimetableHandler.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/EstimatedTimetableHandler.java @@ -1,8 +1,8 @@ -package org.opentripplanner.ext.siri.updater; +package org.opentripplanner.updater.siri.updater; import java.util.List; -import org.opentripplanner.ext.siri.SiriTimetableSnapshotSource; import org.opentripplanner.updater.RealTimeUpdateContext; +import org.opentripplanner.updater.siri.SiriTimetableSnapshotSource; import org.opentripplanner.updater.spi.UpdateResult; import org.opentripplanner.updater.trip.UpdateIncrementality; import uk.org.siri.siri20.EstimatedTimetableDeliveryStructure; diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/EstimatedTimetableSource.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/EstimatedTimetableSource.java similarity index 94% rename from src/ext/java/org/opentripplanner/ext/siri/updater/EstimatedTimetableSource.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/EstimatedTimetableSource.java index c86be9629d2..f8a1b549c96 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/EstimatedTimetableSource.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/EstimatedTimetableSource.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.updater; +package org.opentripplanner.updater.siri.updater; import java.util.Optional; import org.opentripplanner.updater.trip.UpdateIncrementality; diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriETHttpTripUpdateSource.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriETHttpTripUpdateSource.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/siri/updater/SiriETHttpTripUpdateSource.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/SiriETHttpTripUpdateSource.java index 534539ead57..fec6e2885a7 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriETHttpTripUpdateSource.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriETHttpTripUpdateSource.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.updater; +package org.opentripplanner.updater.siri.updater; import static org.opentripplanner.updater.trip.UpdateIncrementality.DIFFERENTIAL; import static org.opentripplanner.updater.trip.UpdateIncrementality.FULL_DATASET; diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriETUpdater.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriETUpdater.java similarity index 96% rename from src/ext/java/org/opentripplanner/ext/siri/updater/SiriETUpdater.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/SiriETUpdater.java index 3b2ec5984d3..087bf28e875 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriETUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriETUpdater.java @@ -1,8 +1,8 @@ -package org.opentripplanner.ext.siri.updater; +package org.opentripplanner.updater.siri.updater; import java.util.List; import java.util.function.Consumer; -import org.opentripplanner.ext.siri.SiriTimetableSnapshotSource; +import org.opentripplanner.updater.siri.SiriTimetableSnapshotSource; import org.opentripplanner.updater.spi.PollingGraphUpdater; import org.opentripplanner.updater.spi.ResultLogger; import org.opentripplanner.updater.spi.UpdateResult; diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriETUpdaterParameters.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriETUpdaterParameters.java similarity index 85% rename from src/ext/java/org/opentripplanner/ext/siri/updater/SiriETUpdaterParameters.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/SiriETUpdaterParameters.java index 8e2bf7dedf2..dc479c034e1 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriETUpdaterParameters.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriETUpdaterParameters.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.updater; +package org.opentripplanner.updater.siri.updater; import java.time.Duration; import org.opentripplanner.updater.spi.HttpHeaders; @@ -15,7 +15,8 @@ public record SiriETUpdaterParameters( Duration timeout, Duration previewInterval, boolean fuzzyTripMatching, - HttpHeaders httpRequestHeaders + HttpHeaders httpRequestHeaders, + boolean producerMetrics ) implements PollingGraphUpdaterParameters, UrlUpdaterParameters, SiriETHttpTripUpdateSource.Parameters { diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriFileLoader.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriFileLoader.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/siri/updater/SiriFileLoader.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/SiriFileLoader.java index 84da542ef47..dea656f46ff 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriFileLoader.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriFileLoader.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.updater; +package org.opentripplanner.updater.siri.updater; import java.io.File; import java.io.FileInputStream; diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriHelper.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriHelper.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/siri/updater/SiriHelper.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/SiriHelper.java index 0f1bd449075..0b9c7c61413 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriHelper.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriHelper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.updater; +package org.opentripplanner.updater.siri.updater; import jakarta.xml.bind.JAXBException; import java.io.InputStream; diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriHttpLoader.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriHttpLoader.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/siri/updater/SiriHttpLoader.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/SiriHttpLoader.java index daf3d0397cc..0ad9309e354 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriHttpLoader.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriHttpLoader.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.updater; +package org.opentripplanner.updater.siri.updater; import jakarta.xml.bind.JAXBException; import java.time.Duration; diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriLoader.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriLoader.java similarity index 90% rename from src/ext/java/org/opentripplanner/ext/siri/updater/SiriLoader.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/SiriLoader.java index 785bcbaa826..953aa555ca5 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriLoader.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriLoader.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.updater; +package org.opentripplanner.updater.siri.updater; import jakarta.xml.bind.JAXBException; import java.util.Optional; diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriSXUpdater.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriSXUpdater.java similarity index 94% rename from src/ext/java/org/opentripplanner/ext/siri/updater/SiriSXUpdater.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/SiriSXUpdater.java index 6ef7f504e85..83200db30d3 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriSXUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriSXUpdater.java @@ -1,17 +1,17 @@ -package org.opentripplanner.ext.siri.updater; +package org.opentripplanner.updater.siri.updater; import java.time.Duration; import java.time.ZonedDateTime; import java.util.Optional; import java.util.UUID; -import org.opentripplanner.ext.siri.SiriAlertsUpdateHandler; import org.opentripplanner.framework.io.OtpHttpClientException; import org.opentripplanner.framework.retry.OtpRetry; import org.opentripplanner.framework.retry.OtpRetryBuilder; import org.opentripplanner.routing.impl.TransitAlertServiceImpl; import org.opentripplanner.routing.services.TransitAlertService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.updater.alert.TransitAlertProvider; +import org.opentripplanner.updater.siri.SiriAlertsUpdateHandler; import org.opentripplanner.updater.spi.PollingGraphUpdater; import org.opentripplanner.updater.spi.WriteToGraphCallback; import org.slf4j.Logger; @@ -43,7 +43,7 @@ public class SiriSXUpdater extends PollingGraphUpdater implements TransitAlertPr private final SiriHttpLoader siriHttpLoader; private final OtpRetry retry; - public SiriSXUpdater(SiriSXUpdaterParameters config, TransitModel transitModel) { + public SiriSXUpdater(SiriSXUpdaterParameters config, TimetableRepository timetableRepository) { super(config); // TODO: add options to choose different patch services this.url = config.url(); @@ -56,7 +56,7 @@ public SiriSXUpdater(SiriSXUpdaterParameters config, TransitModel transitModel) //Keeping original requestorRef use as base for updated requestorRef to be used in retries this.originalRequestorRef = requestorRef; this.blockReadinessUntilInitialized = config.blockReadinessUntilInitialized(); - this.transitAlertService = new TransitAlertServiceImpl(transitModel); + this.transitAlertService = new TransitAlertServiceImpl(timetableRepository); this.updateHandler = new SiriAlertsUpdateHandler(config.feedId(), transitAlertService, config.earlyStart()); siriHttpLoader = new SiriHttpLoader(url, config.timeout(), config.requestHeaders()); @@ -120,11 +120,11 @@ private void updateSiri() { // Such runnables should be illustrated in documentation as e.g. a little box labeled // "change trip ABC123 by making stop 53 late by 2 minutes." // Also clarify how this runnable works without even using the supplied - // (graph, transitModel) parameters. There are multiple TransitAlertServices and they + // (graph, timetableRepository) parameters. There are multiple TransitAlertServices and they // are not versioned along with the Graph, they are attached to updaters. // // This is submitting a runnable to an executor, but that runnable only writes back to - // objects referenced by updateHandler itself, rather than the graph or transitModel + // objects referenced by updateHandler itself, rather than the graph or timetableRepository // supplied for writing, and apparently with no versioning. This seems like a // misinterpretation of the realtime design. // If this is an intentional choice to live-patch a single server-wide instance of an diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriSXUpdaterParameters.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriSXUpdaterParameters.java similarity index 89% rename from src/ext/java/org/opentripplanner/ext/siri/updater/SiriSXUpdaterParameters.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/SiriSXUpdaterParameters.java index 183e296a98c..f51584f86f5 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/SiriSXUpdaterParameters.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/SiriSXUpdaterParameters.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.updater; +package org.opentripplanner.updater.siri.updater; import java.time.Duration; import org.opentripplanner.updater.spi.HttpHeaders; diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/google/GooglePubsubEstimatedTimetableSource.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/google/GooglePubsubEstimatedTimetableSource.java similarity index 98% rename from src/ext/java/org/opentripplanner/ext/siri/updater/google/GooglePubsubEstimatedTimetableSource.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/google/GooglePubsubEstimatedTimetableSource.java index 88b04feb9c5..b9812576fd8 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/google/GooglePubsubEstimatedTimetableSource.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/google/GooglePubsubEstimatedTimetableSource.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.updater.google; +package org.opentripplanner.updater.siri.updater.google; import com.google.api.gax.rpc.NotFoundException; import com.google.cloud.pubsub.v1.AckReplyConsumer; @@ -25,13 +25,13 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.function.Function; import org.entur.protobuf.mapper.SiriMapper; -import org.opentripplanner.ext.siri.updater.AsyncEstimatedTimetableSource; import org.opentripplanner.framework.application.ApplicationShutdownSupport; import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.framework.retry.OtpRetry; import org.opentripplanner.framework.retry.OtpRetryBuilder; -import org.opentripplanner.framework.text.FileSizeToTextConverter; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.updater.siri.updater.AsyncEstimatedTimetableSource; +import org.opentripplanner.utils.text.FileSizeToTextConverter; +import org.opentripplanner.utils.time.DurationUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.org.siri.siri20.ServiceDelivery; diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/google/SiriETGooglePubsubUpdater.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/google/SiriETGooglePubsubUpdater.java similarity index 86% rename from src/ext/java/org/opentripplanner/ext/siri/updater/google/SiriETGooglePubsubUpdater.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/google/SiriETGooglePubsubUpdater.java index 7680e535bfa..ae97c14b5b1 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/google/SiriETGooglePubsubUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/google/SiriETGooglePubsubUpdater.java @@ -1,10 +1,10 @@ -package org.opentripplanner.ext.siri.updater.google; +package org.opentripplanner.updater.siri.updater.google; import java.util.function.Consumer; -import org.opentripplanner.ext.siri.SiriTimetableSnapshotSource; -import org.opentripplanner.ext.siri.updater.AsyncEstimatedTimetableProcessor; -import org.opentripplanner.ext.siri.updater.AsyncEstimatedTimetableSource; -import org.opentripplanner.ext.siri.updater.EstimatedTimetableHandler; +import org.opentripplanner.updater.siri.SiriTimetableSnapshotSource; +import org.opentripplanner.updater.siri.updater.AsyncEstimatedTimetableProcessor; +import org.opentripplanner.updater.siri.updater.AsyncEstimatedTimetableSource; +import org.opentripplanner.updater.siri.updater.EstimatedTimetableHandler; import org.opentripplanner.updater.spi.GraphUpdater; import org.opentripplanner.updater.spi.UpdateResult; import org.opentripplanner.updater.spi.WriteToGraphCallback; diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/google/SiriETGooglePubsubUpdaterParameters.java b/application/src/main/java/org/opentripplanner/updater/siri/updater/google/SiriETGooglePubsubUpdaterParameters.java similarity index 89% rename from src/ext/java/org/opentripplanner/ext/siri/updater/google/SiriETGooglePubsubUpdaterParameters.java rename to application/src/main/java/org/opentripplanner/updater/siri/updater/google/SiriETGooglePubsubUpdaterParameters.java index c9e070311c6..d7fb064966a 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/google/SiriETGooglePubsubUpdaterParameters.java +++ b/application/src/main/java/org/opentripplanner/updater/siri/updater/google/SiriETGooglePubsubUpdaterParameters.java @@ -1,14 +1,13 @@ -package org.opentripplanner.ext.siri.updater.google; +package org.opentripplanner.updater.siri.updater.google; import java.time.Duration; import java.util.Objects; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.updater.trip.UrlUpdaterParameters; +import org.opentripplanner.utils.tostring.ToStringBuilder; public record SiriETGooglePubsubUpdaterParameters( - @Nonnull String configRef, + String configRef, @Nullable String feedId, String subscriptionProjectName, String topicProjectName, @@ -16,7 +15,8 @@ public record SiriETGooglePubsubUpdaterParameters( @Nullable String dataInitializationUrl, Duration reconnectPeriod, Duration initialGetDataTimeout, - boolean fuzzyTripMatching + boolean fuzzyTripMatching, + boolean producerMetrics ) implements UrlUpdaterParameters { public static Duration RECONNECT_PERIOD = Duration.ofSeconds(30); diff --git a/src/main/java/org/opentripplanner/updater/spi/DataSource.java b/application/src/main/java/org/opentripplanner/updater/spi/DataSource.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/spi/DataSource.java rename to application/src/main/java/org/opentripplanner/updater/spi/DataSource.java diff --git a/src/main/java/org/opentripplanner/updater/spi/DataValidationExceptionMapper.java b/application/src/main/java/org/opentripplanner/updater/spi/DataValidationExceptionMapper.java similarity index 80% rename from src/main/java/org/opentripplanner/updater/spi/DataValidationExceptionMapper.java rename to application/src/main/java/org/opentripplanner/updater/spi/DataValidationExceptionMapper.java index dee103bc385..2a650f684f9 100644 --- a/src/main/java/org/opentripplanner/updater/spi/DataValidationExceptionMapper.java +++ b/application/src/main/java/org/opentripplanner/updater/spi/DataValidationExceptionMapper.java @@ -1,5 +1,6 @@ package org.opentripplanner.updater.spi; +import com.beust.jcommander.internal.Nullable; import org.opentripplanner.transit.model.framework.DataValidationException; import org.opentripplanner.transit.model.framework.Result; import org.opentripplanner.transit.model.timetable.TimetableValidationError; @@ -15,13 +16,20 @@ public class DataValidationExceptionMapper { private static final Logger LOG = LoggerFactory.getLogger(DataValidationExceptionMapper.class); public static Result toResult(DataValidationException error) { + return toResult(error, null); + } + + public static Result toResult( + DataValidationException error, + @Nullable String producer + ) { if (error.error() instanceof TimetableValidationError tt) { return Result.failure( - new UpdateError(tt.trip().getId(), mapTimeTableError(tt.code()), tt.stopIndex()) + new UpdateError(tt.trip().getId(), mapTimeTableError(tt.code()), tt.stopIndex(), producer) ); } // The mapper should handle all possible errors - LOG.error("Unhandled error: " + error.getMessage(), error); + LOG.error("Unhandled error: {}", error.getMessage(), error); return Result.failure(UpdateError.noTripId(UpdateError.UpdateErrorType.UNKNOWN)); } diff --git a/src/main/java/org/opentripplanner/updater/spi/GenericJsonDataSource.java b/application/src/main/java/org/opentripplanner/updater/spi/GenericJsonDataSource.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/spi/GenericJsonDataSource.java rename to application/src/main/java/org/opentripplanner/updater/spi/GenericJsonDataSource.java diff --git a/src/main/java/org/opentripplanner/updater/spi/GraphUpdater.java b/application/src/main/java/org/opentripplanner/updater/spi/GraphUpdater.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/spi/GraphUpdater.java rename to application/src/main/java/org/opentripplanner/updater/spi/GraphUpdater.java diff --git a/src/main/java/org/opentripplanner/updater/spi/HttpHeaders.java b/application/src/main/java/org/opentripplanner/updater/spi/HttpHeaders.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/spi/HttpHeaders.java rename to application/src/main/java/org/opentripplanner/updater/spi/HttpHeaders.java diff --git a/src/main/java/org/opentripplanner/updater/spi/PollingGraphUpdater.java b/application/src/main/java/org/opentripplanner/updater/spi/PollingGraphUpdater.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/spi/PollingGraphUpdater.java rename to application/src/main/java/org/opentripplanner/updater/spi/PollingGraphUpdater.java diff --git a/src/main/java/org/opentripplanner/updater/spi/PollingGraphUpdaterParameters.java b/application/src/main/java/org/opentripplanner/updater/spi/PollingGraphUpdaterParameters.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/spi/PollingGraphUpdaterParameters.java rename to application/src/main/java/org/opentripplanner/updater/spi/PollingGraphUpdaterParameters.java diff --git a/src/main/java/org/opentripplanner/updater/spi/ResultLogger.java b/application/src/main/java/org/opentripplanner/updater/spi/ResultLogger.java similarity index 96% rename from src/main/java/org/opentripplanner/updater/spi/ResultLogger.java rename to application/src/main/java/org/opentripplanner/updater/spi/ResultLogger.java index 97af8d650bb..9ea737fa0e7 100644 --- a/src/main/java/org/opentripplanner/updater/spi/ResultLogger.java +++ b/application/src/main/java/org/opentripplanner/updater/spi/ResultLogger.java @@ -3,7 +3,7 @@ import static net.logstash.logback.argument.StructuredArguments.keyValue; import java.util.stream.Collectors; -import org.opentripplanner.framework.lang.DoubleUtils; +import org.opentripplanner.utils.lang.DoubleUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/updater/spi/TimetableSnapshotFlush.java b/application/src/main/java/org/opentripplanner/updater/spi/TimetableSnapshotFlush.java similarity index 95% rename from src/main/java/org/opentripplanner/updater/spi/TimetableSnapshotFlush.java rename to application/src/main/java/org/opentripplanner/updater/spi/TimetableSnapshotFlush.java index 3f5c8f4d23d..89dbeb23302 100644 --- a/src/main/java/org/opentripplanner/updater/spi/TimetableSnapshotFlush.java +++ b/application/src/main/java/org/opentripplanner/updater/spi/TimetableSnapshotFlush.java @@ -1,6 +1,6 @@ package org.opentripplanner.updater.spi; -import org.opentripplanner.ext.siri.SiriTimetableSnapshotSource; +import org.opentripplanner.updater.siri.SiriTimetableSnapshotSource; import org.opentripplanner.updater.trip.TimetableSnapshotSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/updater/spi/UpdateError.java b/application/src/main/java/org/opentripplanner/updater/spi/UpdateError.java similarity index 71% rename from src/main/java/org/opentripplanner/updater/spi/UpdateError.java rename to application/src/main/java/org/opentripplanner/updater/spi/UpdateError.java index 1f568ba99a4..945139e2457 100644 --- a/src/main/java/org/opentripplanner/updater/spi/UpdateError.java +++ b/application/src/main/java/org/opentripplanner/updater/spi/UpdateError.java @@ -11,10 +11,18 @@ public record UpdateError( @Nullable FeedScopedId tripId, UpdateErrorType errorType, - @Nullable Integer stopIndex + @Nullable Integer stopIndex, + @Nullable String producer ) { public UpdateError(@Nullable FeedScopedId tripId, UpdateErrorType errorType) { - this(tripId, errorType, null); + this(tripId, errorType, null, null); + } + + public UpdateError(@Nullable FeedScopedId tripId, UpdateErrorType errorType, Integer stopIndex) { + this(tripId, errorType, stopIndex, null); + } + public UpdateError(@Nullable FeedScopedId tripId, UpdateErrorType errorType, String producer) { + this(tripId, errorType, null, producer); } public String debugId() { @@ -33,6 +41,7 @@ public enum UpdateErrorType { TRIP_NOT_FOUND, TRIP_NOT_FOUND_IN_PATTERN, NO_FUZZY_TRIP_MATCH, + EMPTY_STOP_POINT_REF, NO_TRIP_FOR_CANCELLATION_FOUND, TRIP_ALREADY_EXISTS, NO_START_DATE, @@ -56,6 +65,14 @@ public static Result result(FeedScopedId tripId, UpdateError return Result.failure(new UpdateError(tripId, errorType)); } + public static Result result( + FeedScopedId tripId, + UpdateErrorType errorType, + String producer + ) { + return Result.failure(new UpdateError(tripId, errorType, producer)); + } + public static UpdateError noTripId(UpdateErrorType errorType) { return new UpdateError(null, errorType); } diff --git a/src/main/java/org/opentripplanner/updater/spi/UpdateResult.java b/application/src/main/java/org/opentripplanner/updater/spi/UpdateResult.java similarity index 52% rename from src/main/java/org/opentripplanner/updater/spi/UpdateResult.java rename to application/src/main/java/org/opentripplanner/updater/spi/UpdateResult.java index 643703f2252..0e47d8d202f 100644 --- a/src/main/java/org/opentripplanner/updater/spi/UpdateResult.java +++ b/application/src/main/java/org/opentripplanner/updater/spi/UpdateResult.java @@ -1,6 +1,7 @@ package org.opentripplanner.updater.spi; import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import java.util.List; @@ -15,23 +16,43 @@ public record UpdateResult( int successful, int failed, Multimap failures, - List warnings + List warnings, + List successes, + List errors ) { /** * Create an empty result. */ public static UpdateResult empty() { - return new UpdateResult(0, 0, ArrayListMultimap.create(), List.of()); + return new UpdateResult(0, 0, ArrayListMultimap.create(), List.of(), List.of(), List.of()); } /** * Aggregate a list of results into an instance of {@link UpdateResult}. */ public static UpdateResult ofResults(List> results) { - var errors = results.stream().filter(Result::isFailure).map(Result::failureValue).toList(); - var successes = results.stream().filter(Result::isSuccess).map(Result::successValue).toList(); - var warnings = successes.stream().flatMap(s -> s.warnings().stream()).toList(); - var errorIndex = Multimaps.index(errors, UpdateError::errorType); - return new UpdateResult(successes.size(), errors.size(), errorIndex, warnings); + List errors = results + .stream() + .filter(Result::isFailure) + .map(Result::failureValue) + .toList(); + List successes = results + .stream() + .filter(Result::isSuccess) + .map(Result::successValue) + .toList(); + List warnings = successes + .stream() + .flatMap(s -> s.warnings().stream()) + .toList(); + ImmutableListMultimap errorIndex = Multimaps.index(errors, UpdateError::errorType); + return new UpdateResult( + successes.size(), + errors.size(), + errorIndex, + warnings, + successes, + errors + ); } } diff --git a/src/main/java/org/opentripplanner/updater/spi/UpdateSuccess.java b/application/src/main/java/org/opentripplanner/updater/spi/UpdateSuccess.java similarity index 57% rename from src/main/java/org/opentripplanner/updater/spi/UpdateSuccess.java rename to application/src/main/java/org/opentripplanner/updater/spi/UpdateSuccess.java index 3e6135d88c0..861f4c5edff 100644 --- a/src/main/java/org/opentripplanner/updater/spi/UpdateSuccess.java +++ b/application/src/main/java/org/opentripplanner/updater/spi/UpdateSuccess.java @@ -1,34 +1,35 @@ package org.opentripplanner.updater.spi; -import java.util.Arrays; import java.util.Collection; import java.util.List; -import org.opentripplanner.framework.collection.ListUtils; +import org.opentripplanner.utils.collection.ListUtils; /** * The result of a successful application of a realtime update, for example for trips or - * vehicle positions. Its only extra information is a collection of possible warnings that - * ought to be looked at but didn't prevent the application of the update. + * vehicle positions. Its extra information is a collection of possible warnings that + * ought to be looked at but didn't prevent the application of the update and the provider of the + * update. */ -public record UpdateSuccess(List warnings) { +public record UpdateSuccess(List warnings, String producer) { /** - * Create an instance with no warnings. + * Create an instance with no warnings and no provider. */ public static UpdateSuccess noWarnings() { - return new UpdateSuccess(List.of()); + return new UpdateSuccess(List.of(), null); } + /** - * Create an instance with the provided warnings. + * Create an instance with no warnings, but a provider. */ - public static UpdateSuccess ofWarnings(WarningType... warnings) { - return new UpdateSuccess(Arrays.asList(warnings)); + public static UpdateSuccess noWarnings(String producer) { + return new UpdateSuccess(List.of(), producer); } /** * Return a copy of the instance with the provided warnings added. */ public UpdateSuccess addWarnings(Collection addedWarnings) { - return new UpdateSuccess(ListUtils.combine(this.warnings, addedWarnings)); + return new UpdateSuccess(ListUtils.combine(this.warnings, addedWarnings), this.producer); } public enum WarningType { diff --git a/src/main/java/org/opentripplanner/updater/spi/UpdaterConstructionException.java b/application/src/main/java/org/opentripplanner/updater/spi/UpdaterConstructionException.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/spi/UpdaterConstructionException.java rename to application/src/main/java/org/opentripplanner/updater/spi/UpdaterConstructionException.java diff --git a/src/main/java/org/opentripplanner/updater/spi/WriteToGraphCallback.java b/application/src/main/java/org/opentripplanner/updater/spi/WriteToGraphCallback.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/spi/WriteToGraphCallback.java rename to application/src/main/java/org/opentripplanner/updater/spi/WriteToGraphCallback.java diff --git a/src/main/java/org/opentripplanner/updater/trip/AddedRoute.java b/application/src/main/java/org/opentripplanner/updater/trip/AddedRoute.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/trip/AddedRoute.java rename to application/src/main/java/org/opentripplanner/updater/trip/AddedRoute.java diff --git a/src/main/java/org/opentripplanner/updater/trip/AddedStopTime.java b/application/src/main/java/org/opentripplanner/updater/trip/AddedStopTime.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/trip/AddedStopTime.java rename to application/src/main/java/org/opentripplanner/updater/trip/AddedStopTime.java diff --git a/src/main/java/org/opentripplanner/updater/trip/BackwardsDelayPropagationType.java b/application/src/main/java/org/opentripplanner/updater/trip/BackwardsDelayPropagationType.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/trip/BackwardsDelayPropagationType.java rename to application/src/main/java/org/opentripplanner/updater/trip/BackwardsDelayPropagationType.java diff --git a/src/main/java/org/opentripplanner/updater/trip/GtfsRealtimeTripUpdateSource.java b/application/src/main/java/org/opentripplanner/updater/trip/GtfsRealtimeTripUpdateSource.java similarity index 95% rename from src/main/java/org/opentripplanner/updater/trip/GtfsRealtimeTripUpdateSource.java rename to application/src/main/java/org/opentripplanner/updater/trip/GtfsRealtimeTripUpdateSource.java index 48f2d39ccc4..f3d3c62d6ea 100644 --- a/src/main/java/org/opentripplanner/updater/trip/GtfsRealtimeTripUpdateSource.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/GtfsRealtimeTripUpdateSource.java @@ -14,8 +14,8 @@ import java.util.List; import org.opentripplanner.framework.io.OtpHttpClient; import org.opentripplanner.framework.io.OtpHttpClientFactory; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.updater.spi.HttpHeaders; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -73,7 +73,7 @@ public List getUpdates() { if (feedEntity.hasTripUpdate()) updates.add(feedEntity.getTripUpdate()); } } catch (Exception e) { - LOG.error("Failed to parse GTFS-RT feed from {}", url, e); + LOG.error("Failed to process GTFS-RT TripUpdates feed from {}", url, e); } return updates; } diff --git a/src/main/java/org/opentripplanner/updater/trip/MqttGtfsRealtimeUpdater.java b/application/src/main/java/org/opentripplanner/updater/trip/MqttGtfsRealtimeUpdater.java similarity index 99% rename from src/main/java/org/opentripplanner/updater/trip/MqttGtfsRealtimeUpdater.java rename to application/src/main/java/org/opentripplanner/updater/trip/MqttGtfsRealtimeUpdater.java index e1c8bf4ea83..20b49ed022f 100644 --- a/src/main/java/org/opentripplanner/updater/trip/MqttGtfsRealtimeUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/MqttGtfsRealtimeUpdater.java @@ -16,11 +16,11 @@ import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttMessage; import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.updater.spi.GraphUpdater; import org.opentripplanner.updater.spi.UpdateResult; import org.opentripplanner.updater.spi.WriteToGraphCallback; import org.opentripplanner.updater.trip.metrics.TripUpdateMetrics; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/updater/trip/MqttGtfsRealtimeUpdaterParameters.java b/application/src/main/java/org/opentripplanner/updater/trip/MqttGtfsRealtimeUpdaterParameters.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/trip/MqttGtfsRealtimeUpdaterParameters.java rename to application/src/main/java/org/opentripplanner/updater/trip/MqttGtfsRealtimeUpdaterParameters.java diff --git a/src/main/java/org/opentripplanner/updater/trip/PollingTripUpdater.java b/application/src/main/java/org/opentripplanner/updater/trip/PollingTripUpdater.java similarity index 98% rename from src/main/java/org/opentripplanner/updater/trip/PollingTripUpdater.java rename to application/src/main/java/org/opentripplanner/updater/trip/PollingTripUpdater.java index 71f93235e01..c725c8b1088 100644 --- a/src/main/java/org/opentripplanner/updater/trip/PollingTripUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/PollingTripUpdater.java @@ -3,11 +3,11 @@ import com.google.transit.realtime.GtfsRealtime.TripUpdate; import java.util.List; import java.util.function.Consumer; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.updater.spi.PollingGraphUpdater; import org.opentripplanner.updater.spi.UpdateResult; import org.opentripplanner.updater.spi.WriteToGraphCallback; import org.opentripplanner.updater.trip.metrics.BatchTripUpdateMetrics; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/updater/trip/PollingTripUpdaterParameters.java b/application/src/main/java/org/opentripplanner/updater/trip/PollingTripUpdaterParameters.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/trip/PollingTripUpdaterParameters.java rename to application/src/main/java/org/opentripplanner/updater/trip/PollingTripUpdaterParameters.java diff --git a/src/main/java/org/opentripplanner/updater/trip/TimetableSnapshotManager.java b/application/src/main/java/org/opentripplanner/updater/trip/TimetableSnapshotManager.java similarity index 97% rename from src/main/java/org/opentripplanner/updater/trip/TimetableSnapshotManager.java rename to application/src/main/java/org/opentripplanner/updater/trip/TimetableSnapshotManager.java index fc762347aec..e95afe399ab 100644 --- a/src/main/java/org/opentripplanner/updater/trip/TimetableSnapshotManager.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/TimetableSnapshotManager.java @@ -118,8 +118,8 @@ void commitTimetableSnapshot(final boolean force) { * @return trip pattern created by the updater; null if pattern has not been changed for this trip. */ @Nullable - public TripPattern getRealtimeAddedTripPattern(FeedScopedId tripId, LocalDate serviceDate) { - return buffer.getRealtimeAddedTripPattern(tripId, serviceDate); + public TripPattern getNewTripPatternForModifiedTrip(FeedScopedId tripId, LocalDate serviceDate) { + return buffer.getNewTripPatternForModifiedTrip(tripId, serviceDate); } /** diff --git a/src/main/java/org/opentripplanner/updater/trip/TimetableSnapshotSource.java b/application/src/main/java/org/opentripplanner/updater/trip/TimetableSnapshotSource.java similarity index 84% rename from src/main/java/org/opentripplanner/updater/trip/TimetableSnapshotSource.java rename to application/src/main/java/org/opentripplanner/updater/trip/TimetableSnapshotSource.java index 03ce9052331..e3ec690237e 100644 --- a/src/main/java/org/opentripplanner/updater/trip/TimetableSnapshotSource.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/TimetableSnapshotSource.java @@ -35,11 +35,9 @@ import java.util.Objects; import java.util.Set; import java.util.function.Supplier; -import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.framework.lang.StringUtils; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.gtfs.mapping.TransitModeMapper; import org.opentripplanner.model.RealTimeTripUpdate; import org.opentripplanner.model.StopTime; @@ -61,8 +59,8 @@ import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimesFactory; import org.opentripplanner.transit.service.DefaultTransitService; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.transit.service.TransitEditorService; -import org.opentripplanner.transit.service.TransitModel; import org.opentripplanner.updater.GtfsRealtimeFuzzyTripMatcher; import org.opentripplanner.updater.GtfsRealtimeMapper; import org.opentripplanner.updater.TimetableSnapshotSourceParameters; @@ -71,8 +69,11 @@ import org.opentripplanner.updater.spi.UpdateError; import org.opentripplanner.updater.spi.UpdateResult; import org.opentripplanner.updater.spi.UpdateSuccess; +import org.opentripplanner.utils.lang.StringUtils; +import org.opentripplanner.utils.time.ServiceDateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.event.Level; /** * This class should be used to create snapshots of lookup tables of realtime data. This is @@ -109,9 +110,9 @@ public class TimetableSnapshotSource implements TimetableSnapshotProvider { public TimetableSnapshotSource( TimetableSnapshotSourceParameters parameters, - TransitModel transitModel + TimetableRepository timetableRepository ) { - this(parameters, transitModel, () -> LocalDate.now(transitModel.getTimeZone())); + this(parameters, timetableRepository, () -> LocalDate.now(timetableRepository.getTimeZone())); } /** @@ -120,20 +121,24 @@ public TimetableSnapshotSource( */ TimetableSnapshotSource( TimetableSnapshotSourceParameters parameters, - TransitModel transitModel, + TimetableRepository timetableRepository, Supplier localDateNow ) { this.snapshotManager = - new TimetableSnapshotManager(transitModel.getTransitLayerUpdater(), parameters, localDateNow); - this.timeZone = transitModel.getTimeZone(); + new TimetableSnapshotManager( + timetableRepository.getTransitLayerUpdater(), + parameters, + localDateNow + ); + this.timeZone = timetableRepository.getTimeZone(); this.transitEditorService = - new DefaultTransitService(transitModel, snapshotManager.getTimetableSnapshotBuffer()); - this.deduplicator = transitModel.getDeduplicator(); - this.serviceCodes = transitModel.getServiceCodes(); + new DefaultTransitService(timetableRepository, snapshotManager.getTimetableSnapshotBuffer()); + this.deduplicator = timetableRepository.getDeduplicator(); + this.serviceCodes = timetableRepository.getServiceCodes(); this.localDateNow = localDateNow; // Inject this into the transit model - transitModel.initTimetableSnapshotProvider(this); + timetableRepository.initTimetableSnapshotProvider(this); } /** @@ -150,17 +155,12 @@ public TimetableSnapshotSource( * @param updates GTFS-RT TripUpdate's that should be applied atomically */ public UpdateResult applyTripUpdates( - GtfsRealtimeFuzzyTripMatcher fuzzyTripMatcher, + @Nullable GtfsRealtimeFuzzyTripMatcher fuzzyTripMatcher, BackwardsDelayPropagationType backwardsDelayPropagationType, UpdateIncrementality updateIncrementality, List updates, String feedId ) { - if (updates == null) { - LOG.warn("updates is null"); - return UpdateResult.empty(); - } - Map failuresByRelationship = new HashMap<>(); List> results = new ArrayList<>(); @@ -169,11 +169,11 @@ public UpdateResult applyTripUpdates( snapshotManager.clearBuffer(feedId); } - LOG.debug("message contains {} trip updates", updates.size()); + debug(feedId, "message contains {} trip updates", updates.size()); int uIndex = 0; for (TripUpdate tripUpdate : updates) { if (!tripUpdate.hasTrip()) { - debug(feedId, "", "Missing TripDescriptor in gtfs-rt trip update: \n{}", tripUpdate); + debug(feedId, "Missing TripDescriptor in gtfs-rt trip update: \n{}", tripUpdate); continue; } @@ -185,7 +185,7 @@ public UpdateResult applyTripUpdates( final TripDescriptor tripDescriptor = tripUpdate.getTrip(); if (!tripDescriptor.hasTripId() || tripDescriptor.getTripId().isBlank()) { - debug(feedId, "", "No trip id found for gtfs-rt trip update: \n{}", tripUpdate); + debug(feedId, "No trip id found for gtfs-rt trip update: \n{}", tripUpdate); results.add(Result.failure(UpdateError.noTripId(INVALID_INPUT_STRUCTURE))); continue; } @@ -199,6 +199,7 @@ public UpdateResult applyTripUpdates( } catch (final ParseException e) { debug( tripId, + null, "Failed to parse start date in gtfs-rt trip update: {}", tripDescriptor.getStartDate() ); @@ -219,8 +220,24 @@ public UpdateResult applyTripUpdates( } uIndex += 1; - LOG.debug("trip update #{} ({} updates) :", uIndex, tripUpdate.getStopTimeUpdateCount()); - LOG.trace("{}", tripUpdate); + if (LOG.isTraceEnabled()) { + trace( + tripId, + serviceDate, + "trip update #{} ({} updates): {}", + uIndex, + tripUpdate.getStopTimeUpdateCount(), + tripUpdate + ); + } else { + debug( + tripId, + serviceDate, + "trip update #{} ({} updates)", + uIndex, + tripUpdate.getStopTimeUpdateCount() + ); + } Result result; try { @@ -265,8 +282,7 @@ public UpdateResult applyTripUpdates( results.add(result); if (result.isFailure()) { - debug(tripId, "Failed to apply TripUpdate."); - LOG.trace(" Contents: {}", tripUpdate); + debug(tripId, serviceDate, "Failed to apply TripUpdate."); if (failuresByRelationship.containsKey(scheduleRelationship)) { var c = failuresByRelationship.get(scheduleRelationship); failuresByRelationship.put(scheduleRelationship, ++c); @@ -295,7 +311,10 @@ private void purgePatternModifications( FeedScopedId tripId, LocalDate serviceDate ) { - final TripPattern pattern = snapshotManager.getRealtimeAddedTripPattern(tripId, serviceDate); + final TripPattern pattern = snapshotManager.getNewTripPatternForModifiedTrip( + tripId, + serviceDate + ); if ( !isPreviouslyAddedTrip(tripId, pattern, serviceDate) || ( @@ -351,7 +370,7 @@ private static void logUpdateResult( ResultLogger.logUpdateResult(feedId, "gtfs-rt-trip-updates", updateResult); if (!failuresByRelationship.isEmpty()) { - LOG.info("[feedId: {}] Failures by scheduleRelationship {}", feedId, failuresByRelationship); + info(feedId, "Failures by scheduleRelationship {}", failuresByRelationship); } var warnings = Multimaps.index(updateResult.warnings(), w -> w); @@ -359,7 +378,7 @@ private static void logUpdateResult( .keySet() .forEach(key -> { var count = warnings.get(key).size(); - LOG.info("[feedId: {}] {} warnings of type {}", feedId, count, key); + info(feedId, "{} warnings of type {}", count, key); }); } @@ -372,22 +391,23 @@ private Result handleScheduledTrip( final TripPattern pattern = getPatternForTripId(tripId); if (pattern == null) { - debug(tripId, "No pattern found for tripId, skipping TripUpdate."); + debug(tripId, serviceDate, "No pattern found for tripId, skipping TripUpdate."); return UpdateError.result(tripId, TRIP_NOT_FOUND); } if (tripUpdate.getStopTimeUpdateCount() < 1) { - debug(tripId, "TripUpdate contains no updates, skipping."); + debug(tripId, serviceDate, "TripUpdate contains no updates, skipping."); return UpdateError.result(tripId, NO_UPDATES); } - final FeedScopedId serviceId = transitEditorService.getTripForId(tripId).getServiceId(); + final FeedScopedId serviceId = transitEditorService.getTrip(tripId).getServiceId(); final Set serviceDates = transitEditorService .getCalendarService() .getServiceDatesForServiceId(serviceId); if (!serviceDates.contains(serviceDate)) { debug( tripId, + serviceDate, "SCHEDULED trip has service date {} for which trip's service is not valid, skipping.", serviceDate.toString() ); @@ -425,7 +445,7 @@ private Result handleScheduledTrip( .cancelStops(skippedStopIndices) .build(); - final Trip trip = transitEditorService.getTripForId(tripId); + final Trip trip = transitEditorService.getTrip(tripId); // Get cached trip pattern or create one if it doesn't exist yet final TripPattern newPattern = tripPatternCache.getOrCreateTripPattern( newStopPattern, @@ -467,23 +487,31 @@ private Result validateAndHandleAddedTrip( // // Check whether trip id already exists in graph - final Trip trip = transitEditorService.getScheduledTripForId(tripId); + final Trip trip = transitEditorService.getScheduledTrip(tripId); if (trip != null) { // TODO: should we support this and add a new instantiation of this trip (making it // frequency based)? - debug(tripId, "Graph already contains trip id of ADDED trip, skipping."); + debug(tripId, serviceDate, "Graph already contains trip id of ADDED trip, skipping."); return UpdateError.result(tripId, TRIP_ALREADY_EXISTS); } // Check whether a start date exists if (!tripDescriptor.hasStartDate()) { // TODO: should we support this and apply update to all days? - debug(tripId, "ADDED trip doesn't have a start date in TripDescriptor, skipping."); + debug( + tripId, + serviceDate, + "ADDED trip doesn't have a start date in TripDescriptor, skipping." + ); return UpdateError.result(tripId, NO_START_DATE); } - final List stopTimeUpdates = removeUnknownStops(tripUpdate, tripId); + final List stopTimeUpdates = removeUnknownStops( + tripUpdate, + tripId, + serviceDate + ); var warnings = new ArrayList(0); @@ -493,12 +521,12 @@ private Result validateAndHandleAddedTrip( // check if after filtering the stops we still have at least 2 if (stopTimeUpdates.size() < 2) { - debug(tripId, "ADDED trip has fewer than two known stops, skipping."); + debug(tripId, serviceDate, "ADDED trip has fewer than two known stops, skipping."); return UpdateError.result(tripId, TOO_FEW_STOPS); } // Check whether all stop times are available and all stops exist - final var stops = checkNewStopTimeUpdatesAndFindStops(tripId, stopTimeUpdates); + final var stops = checkNewStopTimeUpdatesAndFindStops(tripId, serviceDate, stopTimeUpdates); if (stops == null) { return UpdateError.result(tripId, NO_VALID_STOPS); } @@ -513,8 +541,11 @@ private Result validateAndHandleAddedTrip( /** * Remove any stop that is not know in the static transit data. */ - @Nonnull - private List removeUnknownStops(TripUpdate tripUpdate, FeedScopedId tripId) { + private List removeUnknownStops( + TripUpdate tripUpdate, + FeedScopedId tripId, + LocalDate serviceDate + ) { return tripUpdate .getStopTimeUpdateList() .stream() @@ -523,7 +554,12 @@ private List removeUnknownStops(TripUpdate tripUpdate, FeedScope var stopId = new FeedScopedId(tripId.getFeedId(), st.getStopId()); var stopFound = transitEditorService.getRegularStop(stopId) != null; if (!stopFound) { - debug(tripId, "Stop '{}' not found in graph. Removing from ADDED trip.", st.getStopId()); + debug( + tripId, + serviceDate, + "Stop '{}' not found in graph. Removing from ADDED trip.", + st.getStopId() + ); } return stopFound; }) @@ -538,6 +574,7 @@ private List removeUnknownStops(TripUpdate tripUpdate, FeedScope */ private List checkNewStopTimeUpdatesAndFindStops( final FeedScopedId tripId, + LocalDate serviceDate, final List stopTimeUpdates ) { Integer previousStopSequence = null; @@ -553,13 +590,13 @@ private List checkNewStopTimeUpdatesAndFindStops( // Check non-negative if (stopSequence < 0) { - debug(tripId, "Trip update contains negative stop sequence, skipping."); + debug(tripId, serviceDate, "Trip update contains negative stop sequence, skipping."); return null; } // Check whether sequence is increasing if (previousStopSequence != null && previousStopSequence > stopSequence) { - debug(tripId, "Trip update contains decreasing stop sequence, skipping."); + debug(tripId, serviceDate, "Trip update contains decreasing stop sequence, skipping."); return null; } previousStopSequence = stopSequence; @@ -579,13 +616,19 @@ private List checkNewStopTimeUpdatesAndFindStops( } else { debug( tripId, + serviceDate, "Graph doesn't contain stop id '{}' of trip update, skipping.", stopTimeUpdate.getStopId() ); return null; } } else { - debug(tripId, "Trip update misses a stop id at stop time list index {}, skipping.", index); + debug( + tripId, + serviceDate, + "Trip update misses a stop id at stop time list index {}, skipping.", + index + ); return null; } @@ -594,12 +637,12 @@ private List checkNewStopTimeUpdatesAndFindStops( // Check for increasing time final Long time = stopTimeUpdate.getArrival().getTime(); if (previousTime != null && previousTime > time) { - debug(tripId, "Trip update contains decreasing times, skipping."); + debug(tripId, serviceDate, "Trip update contains decreasing times, skipping."); return null; } previousTime = time; } else { - debug(tripId, "Trip update misses arrival time, skipping."); + debug(tripId, serviceDate, "Trip update misses arrival time, skipping."); return null; } @@ -608,12 +651,12 @@ private List checkNewStopTimeUpdatesAndFindStops( // Check for increasing time final Long time = stopTimeUpdate.getDeparture().getTime(); if (previousTime != null && previousTime > time) { - debug(tripId, "Trip update contains decreasing times, skipping."); + debug(tripId, serviceDate, "Trip update contains decreasing times, skipping."); return null; } previousTime = time; } else { - debug(tripId, "Trip update misses departure time, skipping."); + debug(tripId, serviceDate, "Trip update misses departure time, skipping."); return null; } } @@ -648,7 +691,7 @@ private Result handleAddedTrip( boolean routeExists = routeExists(tripId.getFeedId(), tripDescriptor); if (routeExists) { route = - transitEditorService.getRouteForId( + transitEditorService.getRoute( new FeedScopedId(tripId.getFeedId(), tripDescriptor.getRouteId()) ); } else { @@ -669,6 +712,7 @@ private Result handleAddedTrip( // No service id exists: return error for now debug( tripId, + serviceDate, "ADDED trip has service date {} for which no service id is available, skipping.", serviceDate.toString() ); @@ -701,7 +745,7 @@ private Route createRoute(TripDescriptor tripDescriptor, FeedScopedId tripId) { var addedRouteExtension = AddedRoute.ofTripDescriptor(tripDescriptor); var agency = transitEditorService - .findAgencyById(new FeedScopedId(tripId.getFeedId(), addedRouteExtension.agencyId())) + .findAgency(new FeedScopedId(tripId.getFeedId(), addedRouteExtension.agencyId())) .orElseGet(() -> fallbackAgency(tripId.getFeedId())); builder.withAgency(agency); @@ -746,7 +790,7 @@ private Agency fallbackAgency(String feedId) { private boolean routeExists(String feedId, TripDescriptor tripDescriptor) { if (tripDescriptor.hasRouteId() && StringUtils.hasValue(tripDescriptor.getRouteId())) { var routeId = new FeedScopedId(feedId, tripDescriptor.getRouteId()); - return Objects.nonNull(transitEditorService.getRouteForId(routeId)); + return Objects.nonNull(transitEditorService.getRoute(routeId)); } else { return false; } @@ -799,6 +843,7 @@ private Result addTripToGraphAndBuffer( if (arrivalTime < 0 || arrivalTime > MAX_ARRIVAL_DEPARTURE_TIME) { debug( trip.getId(), + serviceDate, "ADDED trip has invalid arrival time (compared to start date in " + "TripDescriptor), skipping." ); @@ -813,6 +858,7 @@ private Result addTripToGraphAndBuffer( if (departureTime < 0 || departureTime > MAX_ARRIVAL_DEPARTURE_TIME) { debug( trip.getId(), + serviceDate, "ADDED trip has invalid departure time (compared to start date in " + "TripDescriptor), skipping." ); @@ -836,7 +882,7 @@ private Result addTripToGraphAndBuffer( // Create StopPattern final StopPattern stopPattern = new StopPattern(stopTimes); - final TripPattern originalTripPattern = transitEditorService.getPatternForTrip(trip); + final TripPattern originalTripPattern = transitEditorService.findPattern(trip); // Get cached trip pattern or create one if it doesn't exist yet final TripPattern pattern = tripPatternCache.getOrCreateTripPattern( stopPattern, @@ -875,7 +921,9 @@ private Result addTripToGraphAndBuffer( .ifPresent(newTripTimes::updateWheelchairAccessibility); } } - LOG.trace( + trace( + trip.getId(), + serviceDate, "Trip pattern added with mode {} on {} from {} to {}", trip.getRoute().getMode(), serviceDate, @@ -915,7 +963,11 @@ private boolean cancelScheduledTrip( final Timetable timetable = pattern.getScheduledTimetable(); final int tripIndex = timetable.getTripIndex(tripId); if (tripIndex == -1) { - debug(tripId, "Could not cancel scheduled trip because it's not in the timetable"); + debug( + tripId, + serviceDate, + "Could not cancel scheduled trip because it's not in the timetable" + ); } else { final RealTimeTripTimes newTripTimes = timetable .getTripTimes(tripIndex) @@ -948,13 +1000,16 @@ private boolean cancelPreviouslyAddedTrip( ) { boolean cancelledAddedTrip = false; - final TripPattern pattern = snapshotManager.getRealtimeAddedTripPattern(tripId, serviceDate); + final TripPattern pattern = snapshotManager.getNewTripPatternForModifiedTrip( + tripId, + serviceDate + ); if (isPreviouslyAddedTrip(tripId, pattern, serviceDate)) { // Cancel trip times for this trip in this pattern final Timetable timetable = snapshotManager.resolve(pattern, serviceDate); final int tripIndex = timetable.getTripIndex(tripId); if (tripIndex == -1) { - debug(tripId, "Could not cancel previously added trip on {}", serviceDate); + debug(tripId, serviceDate, "Could not cancel previously added trip on {}", serviceDate); } else { final RealTimeTripTimes newTripTimes = timetable .getTripTimes(tripIndex) @@ -992,18 +1047,22 @@ private Result validateAndHandleModifiedTrip( // // Check whether trip id already exists in graph - Trip trip = transitEditorService.getTripForId(tripId); + Trip trip = transitEditorService.getTrip(tripId); if (trip == null) { // TODO: should we support this and consider it an ADDED trip? - debug(tripId, "Feed does not contain trip id of MODIFIED trip, skipping."); + debug(tripId, serviceDate, "Feed does not contain trip id of MODIFIED trip, skipping."); return UpdateError.result(tripId, TRIP_NOT_FOUND); } // Check whether a start date exists if (!tripDescriptor.hasStartDate()) { // TODO: should we support this and apply update to all days? - debug(tripId, "REPLACEMENT trip doesn't have a start date in TripDescriptor, skipping."); + debug( + tripId, + serviceDate, + "REPLACEMENT trip doesn't have a start date in TripDescriptor, skipping." + ); return UpdateError.result(tripId, NO_START_DATE); } else { // Check whether service date is served by trip @@ -1012,19 +1071,27 @@ private Result validateAndHandleModifiedTrip( .getServiceIdsOnDate(serviceDate); if (!serviceIds.contains(trip.getServiceId())) { // TODO: should we support this and change service id of trip? - debug(tripId, "REPLACEMENT trip has a service date that is not served by trip, skipping."); + debug( + tripId, + serviceDate, + "REPLACEMENT trip has a service date that is not served by trip, skipping." + ); return UpdateError.result(tripId, NO_SERVICE_ON_DATE); } } // Check whether at least two stop updates exist if (tripUpdate.getStopTimeUpdateCount() < 2) { - debug(tripId, "REPLACEMENT trip has less then two stops, skipping."); + debug(tripId, serviceDate, "REPLACEMENT trip has less then two stops, skipping."); return UpdateError.result(tripId, TOO_FEW_STOPS); } // Check whether all stop times are available and all stops exist - var stops = checkNewStopTimeUpdatesAndFindStops(tripId, tripUpdate.getStopTimeUpdateList()); + var stops = checkNewStopTimeUpdatesAndFindStops( + tripId, + serviceDate, + tripUpdate.getStopTimeUpdateList() + ); if (stops == null) { return UpdateError.result(tripId, NO_VALID_STOPS); } @@ -1096,9 +1163,12 @@ private Result handleCanceledTrip( ); if (!cancelScheduledSuccess) { - debug(tripId, "No pattern found for tripId. Skipping cancellation."); + debug(tripId, serviceDate, "No pattern found for tripId. Skipping cancellation."); return UpdateError.result(tripId, NO_TRIP_FOR_CANCELLATION_FOUND); } + + debug(tripId, serviceDate, "Canceled trip"); + return Result.success(UpdateSuccess.noWarnings()); } @@ -1109,17 +1179,62 @@ private Result handleCanceledTrip( * @return trip pattern or null if no trip pattern was found */ private TripPattern getPatternForTripId(FeedScopedId tripId) { - Trip trip = transitEditorService.getTripForId(tripId); - return transitEditorService.getPatternForTrip(trip); + Trip trip = transitEditorService.getTrip(tripId); + return transitEditorService.findPattern(trip); } - private static void debug(FeedScopedId id, String message, Object... params) { - debug(id.getFeedId(), id.getId(), message, params); + private static void debug( + FeedScopedId id, + @Nullable LocalDate serviceDate, + String message, + Object... params + ) { + log(Level.DEBUG, id.getFeedId(), id.getId(), serviceDate, message, params); } - private static void debug(String feedId, String tripId, String message, Object... params) { - String m = "[feedId: %s, tripId: %s] %s".formatted(feedId, tripId, message); - LOG.debug(m, params); + private static void debug(String feedId, String message, Object... params) { + log(Level.DEBUG, feedId, null, null, message, params); + } + + private static void trace( + FeedScopedId id, + @Nullable LocalDate serviceDate, + String message, + Object... params + ) { + log(Level.TRACE, id.getFeedId(), id.getId(), serviceDate, message, params); + } + + private static void info(String feedId, String message, Object... params) { + log(Level.INFO, feedId, null, null, message, params); + } + + /** + * This adds detailed per-update logging to allow tracking what feeds and updates were applied to + * a given trip. + *

    + * The INFO level is used for aggregated statistics, while DEBUG/TRACE is used to link specific + * messages to a trip. + */ + private static void log( + Level logLevel, + String feedId, + @Nullable String tripId, + @Nullable LocalDate serviceDate, + String message, + Object... params + ) { + if (LOG.isEnabledForLevel(logLevel)) { + String m = tripId != null || serviceDate != null + ? "[feedId: %s, tripId: %s, serviceDate: %s] %s".formatted( + feedId, + tripId, + serviceDate, + message + ) + : "[feedId: %s] %s".formatted(feedId, message); + LOG.makeLoggingEventBuilder(logLevel).log(m, params); + } } private enum CancelationType { diff --git a/src/main/java/org/opentripplanner/updater/trip/TripPatternCache.java b/application/src/main/java/org/opentripplanner/updater/trip/TripPatternCache.java similarity index 97% rename from src/main/java/org/opentripplanner/updater/trip/TripPatternCache.java rename to application/src/main/java/org/opentripplanner/updater/trip/TripPatternCache.java index bf8e75418ae..f94d023c560 100644 --- a/src/main/java/org/opentripplanner/updater/trip/TripPatternCache.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/TripPatternCache.java @@ -2,7 +2,6 @@ import java.util.HashMap; import java.util.Map; -import javax.annotation.Nonnull; import org.opentripplanner.gtfs.GenerateTripPatternsOperation; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; @@ -47,8 +46,8 @@ public class TripPatternCache { * @return cached or newly created trip pattern */ public synchronized TripPattern getOrCreateTripPattern( - @Nonnull final StopPattern stopPattern, - @Nonnull final Trip trip, + final StopPattern stopPattern, + final Trip trip, final TripPattern originalTripPattern ) { Route route = trip.getRoute(); diff --git a/src/main/java/org/opentripplanner/updater/trip/TripUpdateGraphWriterRunnable.java b/application/src/main/java/org/opentripplanner/updater/trip/TripUpdateGraphWriterRunnable.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/trip/TripUpdateGraphWriterRunnable.java rename to application/src/main/java/org/opentripplanner/updater/trip/TripUpdateGraphWriterRunnable.java diff --git a/src/main/java/org/opentripplanner/updater/trip/UpdateIncrementality.java b/application/src/main/java/org/opentripplanner/updater/trip/UpdateIncrementality.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/trip/UpdateIncrementality.java rename to application/src/main/java/org/opentripplanner/updater/trip/UpdateIncrementality.java diff --git a/src/main/java/org/opentripplanner/updater/trip/UrlUpdaterParameters.java b/application/src/main/java/org/opentripplanner/updater/trip/UrlUpdaterParameters.java similarity index 69% rename from src/main/java/org/opentripplanner/updater/trip/UrlUpdaterParameters.java rename to application/src/main/java/org/opentripplanner/updater/trip/UrlUpdaterParameters.java index 2070aedbbd6..4918be84e45 100644 --- a/src/main/java/org/opentripplanner/updater/trip/UrlUpdaterParameters.java +++ b/application/src/main/java/org/opentripplanner/updater/trip/UrlUpdaterParameters.java @@ -4,4 +4,8 @@ public interface UrlUpdaterParameters { String url(); String configRef(); String feedId(); + + default boolean producerMetrics() { + return false; + } } diff --git a/src/main/java/org/opentripplanner/updater/trip/metrics/BatchTripUpdateMetrics.java b/application/src/main/java/org/opentripplanner/updater/trip/metrics/BatchTripUpdateMetrics.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/trip/metrics/BatchTripUpdateMetrics.java rename to application/src/main/java/org/opentripplanner/updater/trip/metrics/BatchTripUpdateMetrics.java diff --git a/application/src/main/java/org/opentripplanner/updater/trip/metrics/StreamingTripUpdateMetrics.java b/application/src/main/java/org/opentripplanner/updater/trip/metrics/StreamingTripUpdateMetrics.java new file mode 100644 index 00000000000..0660f8d801b --- /dev/null +++ b/application/src/main/java/org/opentripplanner/updater/trip/metrics/StreamingTripUpdateMetrics.java @@ -0,0 +1,80 @@ +package org.opentripplanner.updater.trip.metrics; + +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.Metrics; +import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.Tags; +import java.util.Arrays; +import java.util.List; +import org.opentripplanner.updater.spi.UpdateError; +import org.opentripplanner.updater.spi.UpdateResult; +import org.opentripplanner.updater.spi.UpdateSuccess; +import org.opentripplanner.updater.trip.UrlUpdaterParameters; + +/** + * Records micrometer metrics for trip updaters that stream trip updates into the system, for + * example GTFS-RT via MQTT. + *

    + * It records the trip update as counters (continuously increasing numbers) since the concept of + * "latest update" doesn't exist for them. + *

    + * Use your metrics database to convert the counters to rates. + */ +public class StreamingTripUpdateMetrics extends TripUpdateMetrics { + + protected static final String METRICS_PREFIX = "streaming_trip_updates"; + private final boolean producerMetrics; + + public StreamingTripUpdateMetrics(UrlUpdaterParameters parameters) { + super(parameters); + this.producerMetrics = parameters.producerMetrics(); + } + + public void setCounters(UpdateResult result) { + incrementWarningCounts(result); + incrementFailureCounts(result); + incrementSuccessCounts(result); + } + + private void incrementWarningCounts(UpdateResult result) { + for (var warningType : result.warnings()) { + Tags tags = Tags.concat(baseTags, Tags.of("warningType", warningType.name())); + Counter + .builder(METRICS_PREFIX + "." + "warnings") + .description("Total warnings by type generated by successful trip updates") + .tags(tags) + .register(Metrics.globalRegistry) + .increment(); + } + } + + private void incrementFailureCounts(UpdateResult result) { + for (UpdateError error : result.errors()) { + Tags tags = Tags.concat(baseTags, Tags.of("errorType", error.errorType().name())); + if (producerMetrics && error.producer() != null) { + tags = tags.and(Tag.of("producer", error.producer())); + } + Counter + .builder(METRICS_PREFIX + "." + "failed") + .description("Total failed trip updates") + .tags(tags) + .register(Metrics.globalRegistry) + .increment(); + } + } + + private void incrementSuccessCounts(UpdateResult result) { + for (UpdateSuccess success : result.successes()) { + Tags tags = Tags.of(baseTags); + if (producerMetrics && success.producer() != null) { + tags = tags.and(Tag.of("producer", success.producer())); + } + Counter + .builder(METRICS_PREFIX + "." + "successful") + .description("Total successfully applied trip updates") + .tags(tags) + .register(Metrics.globalRegistry) + .increment(); + } + } +} diff --git a/src/main/java/org/opentripplanner/updater/trip/metrics/TripUpdateMetrics.java b/application/src/main/java/org/opentripplanner/updater/trip/metrics/TripUpdateMetrics.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/trip/metrics/TripUpdateMetrics.java rename to application/src/main/java/org/opentripplanner/updater/trip/metrics/TripUpdateMetrics.java diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabilityDatasourceFactory.java b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabilityDatasourceFactory.java similarity index 96% rename from src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabilityDatasourceFactory.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabilityDatasourceFactory.java index 876cd303c78..66c01b4b33b 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabilityDatasourceFactory.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabilityDatasourceFactory.java @@ -16,7 +16,6 @@ public static DataSource create(VehicleParkingUpdaterParamete BICYCLE_PARK_API, HSL_PARK, BIKEEP, - NOI_OPEN_DATA_HUB, BIKELY -> throw new IllegalArgumentException("Cannot instantiate SIRI-FM data source"); }; } diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java similarity index 87% rename from src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java index a9d352cbaf2..414a62938ba 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java @@ -1,8 +1,8 @@ package org.opentripplanner.updater.vehicle_parking; import java.util.Objects; -import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.lang.IntUtils; public record AvailabiltyUpdate(FeedScopedId vehicleParkingId, int spacesAvailable) { public AvailabiltyUpdate { diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java similarity index 85% rename from src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java index 96544321735..e548d5d75be 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java @@ -4,16 +4,16 @@ import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; -import org.opentripplanner.framework.tostring.ToStringBuilder; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.updater.GraphWriterRunnable; import org.opentripplanner.updater.RealTimeUpdateContext; import org.opentripplanner.updater.spi.DataSource; import org.opentripplanner.updater.spi.PollingGraphUpdater; import org.opentripplanner.updater.spi.WriteToGraphCallback; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,16 +29,16 @@ public class VehicleParkingAvailabilityUpdater extends PollingGraphUpdater { private final DataSource source; private WriteToGraphCallback saveResultOnGraph; - private final VehicleParkingService vehicleParkingService; + private final VehicleParkingRepository repository; public VehicleParkingAvailabilityUpdater( VehicleParkingUpdaterParameters parameters, DataSource source, - VehicleParkingService vehicleParkingService + VehicleParkingRepository parkingRepository ) { super(parameters); this.source = source; - this.vehicleParkingService = vehicleParkingService; + this.repository = parkingRepository; LOG.info("Creating vehicle-parking updater running every {}: {}", pollingPeriod(), source); } @@ -66,8 +66,9 @@ private class AvailabilityUpdater implements GraphWriterRunnable { private AvailabilityUpdater(List updates) { this.updates = List.copyOf(updates); this.parkingById = - vehicleParkingService - .getVehicleParkings() + repository + .listVehicleParkings() + .stream() .collect(Collectors.toUnmodifiableMap(VehicleParking::getId, Function.identity())); } diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingDataSourceFactory.java b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingDataSourceFactory.java similarity index 87% rename from src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingDataSourceFactory.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingDataSourceFactory.java index 09ecb67a54d..d7dd8f23c5f 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingDataSourceFactory.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingDataSourceFactory.java @@ -6,13 +6,11 @@ import org.opentripplanner.ext.vehicleparking.bikely.BikelyUpdaterParameters; import org.opentripplanner.ext.vehicleparking.hslpark.HslParkUpdater; import org.opentripplanner.ext.vehicleparking.hslpark.HslParkUpdaterParameters; -import org.opentripplanner.ext.vehicleparking.noi.NoiUpdater; -import org.opentripplanner.ext.vehicleparking.noi.NoiUpdaterParameters; import org.opentripplanner.ext.vehicleparking.parkapi.BicycleParkAPIUpdater; import org.opentripplanner.ext.vehicleparking.parkapi.CarParkAPIUpdater; import org.opentripplanner.ext.vehicleparking.parkapi.ParkAPIUpdaterParameters; import org.opentripplanner.model.calendar.openinghours.OpeningHoursCalendarService; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; import org.opentripplanner.updater.spi.DataSource; /** @@ -40,7 +38,6 @@ public static DataSource create( openingHoursCalendarService ); case BIKELY -> new BikelyUpdater((BikelyUpdaterParameters) parameters); - case NOI_OPEN_DATA_HUB -> new NoiUpdater((NoiUpdaterParameters) parameters); case BIKEEP -> new BikeepUpdater((BikeepUpdaterParameters) parameters); case SIRI_FM -> throw new IllegalArgumentException("Cannot instantiate SIRI-FM data source"); }; diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingSourceType.java b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingSourceType.java similarity index 89% rename from src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingSourceType.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingSourceType.java index 1601245b16c..f146bb7dcf2 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingSourceType.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingSourceType.java @@ -5,7 +5,6 @@ public enum VehicleParkingSourceType { BICYCLE_PARK_API, HSL_PARK, BIKELY, - NOI_OPEN_DATA_HUB, BIKEEP, SIRI_FM, } diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdater.java b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdater.java similarity index 94% rename from src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdater.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdater.java index 59aea16e928..8e4cf8a862b 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdater.java @@ -8,15 +8,14 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.linking.DisposableEdgeCollection; import org.opentripplanner.routing.linking.LinkingDirection; import org.opentripplanner.routing.linking.VertexLinker; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingHelper; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingState; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingHelper; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingState; import org.opentripplanner.street.model.edge.StreetVehicleParkingLink; import org.opentripplanner.street.model.edge.VehicleParkingEdge; import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex; @@ -28,6 +27,7 @@ import org.opentripplanner.updater.spi.DataSource; import org.opentripplanner.updater.spi.PollingGraphUpdater; import org.opentripplanner.updater.spi.WriteToGraphCallback; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,20 +45,20 @@ public class VehicleParkingUpdater extends PollingGraphUpdater { private WriteToGraphCallback saveResultOnGraph; private final VertexLinker linker; - private final VehicleParkingService vehicleParkingService; + private final VehicleParkingRepository parkingRepository; public VehicleParkingUpdater( VehicleParkingUpdaterParameters parameters, DataSource source, VertexLinker vertexLinker, - VehicleParkingService vehicleParkingService + VehicleParkingRepository parkingRepository ) { super(parameters); this.source = source; // Creation of network linker library will not modify the graph this.linker = vertexLinker; // Adding a vehicle parking station service needs a graph writer runnable - this.vehicleParkingService = vehicleParkingService; + this.parkingRepository = parkingRepository; LOG.info("Creating vehicle-parking updater running every {}: {}", pollingPeriod(), source); } @@ -155,7 +155,7 @@ public void run(RealTimeUpdateContext context) { tempEdgesByPark.put(updatedVehicleParking, disposableEdgeCollectionsForVertex); } - vehicleParkingService.updateVehicleParking(toAdd, toRemove); + parkingRepository.updateVehicleParking(toAdd, toRemove); oldVehicleParkings.removeAll(toRemove); oldVehicleParkings.addAll(toAdd); diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterParameters.java b/application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterParameters.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterParameters.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterParameters.java diff --git a/src/main/java/org/opentripplanner/updater/vehicle_position/GtfsRealtimeHttpVehiclePositionSource.java b/application/src/main/java/org/opentripplanner/updater/vehicle_position/GtfsRealtimeHttpVehiclePositionSource.java similarity index 97% rename from src/main/java/org/opentripplanner/updater/vehicle_position/GtfsRealtimeHttpVehiclePositionSource.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_position/GtfsRealtimeHttpVehiclePositionSource.java index ec0be6822e7..31ae9a32faf 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_position/GtfsRealtimeHttpVehiclePositionSource.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_position/GtfsRealtimeHttpVehiclePositionSource.java @@ -10,8 +10,8 @@ import org.opentripplanner.framework.io.OtpHttpClient; import org.opentripplanner.framework.io.OtpHttpClientException; import org.opentripplanner.framework.io.OtpHttpClientFactory; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.updater.spi.HttpHeaders; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/updater/vehicle_position/PollingVehiclePositionUpdater.java b/application/src/main/java/org/opentripplanner/updater/vehicle_position/PollingVehiclePositionUpdater.java similarity index 97% rename from src/main/java/org/opentripplanner/updater/vehicle_position/PollingVehiclePositionUpdater.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_position/PollingVehiclePositionUpdater.java index c2860d1d091..4c487ac997b 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_position/PollingVehiclePositionUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_position/PollingVehiclePositionUpdater.java @@ -3,12 +3,12 @@ import com.google.transit.realtime.GtfsRealtime.VehiclePosition; import java.util.List; import java.util.Set; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleRepository; import org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle; import org.opentripplanner.standalone.config.routerconfig.updaters.VehiclePositionsUpdaterConfig; import org.opentripplanner.updater.spi.PollingGraphUpdater; import org.opentripplanner.updater.spi.WriteToGraphCallback; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java b/application/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java similarity index 98% rename from src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java index fe29ef35b97..27ee0d479ab 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java @@ -29,10 +29,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.annotation.Nonnull; import org.opentripplanner.framework.geometry.WgsCoordinate; -import org.opentripplanner.framework.lang.StringUtils; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleRepository; import org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle; import org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle.StopStatus; @@ -49,6 +46,8 @@ import org.opentripplanner.updater.spi.UpdateError; import org.opentripplanner.updater.spi.UpdateResult; import org.opentripplanner.updater.spi.UpdateSuccess; +import org.opentripplanner.utils.lang.StringUtils; +import org.opentripplanner.utils.time.ServiceDateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -206,8 +205,8 @@ protected static LocalDate inferServiceDate( private RealtimeVehicle mapRealtimeVehicle( VehiclePosition vehiclePosition, List stopsOnVehicleTrip, - @Nonnull Trip trip, - @Nonnull Function stopIndexOfGtfsSequence + Trip trip, + Function stopIndexOfGtfsSequence ) { var newVehicle = RealtimeVehicle.builder(); diff --git a/src/main/java/org/opentripplanner/updater/vehicle_position/VehiclePositionUpdaterRunnable.java b/application/src/main/java/org/opentripplanner/updater/vehicle_position/VehiclePositionUpdaterRunnable.java similarity index 92% rename from src/main/java/org/opentripplanner/updater/vehicle_position/VehiclePositionUpdaterRunnable.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_position/VehiclePositionUpdaterRunnable.java index 3165221a5fc..9ab2915f566 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_position/VehiclePositionUpdaterRunnable.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_position/VehiclePositionUpdaterRunnable.java @@ -35,9 +35,9 @@ public VehiclePositionUpdaterRunnable( public void run(RealTimeUpdateContext context) { RealtimeVehiclePatternMatcher matcher = new RealtimeVehiclePatternMatcher( feedId, - context.transitService()::getTripForId, - context.transitService()::getPatternForTrip, - context.transitService()::getPatternForTrip, + context.transitService()::getTrip, + context.transitService()::findPattern, + context.transitService()::findPattern, realtimeVehicleRepository, context.transitService().getTimeZone(), fuzzyTripMatching ? context.gtfsRealtimeFuzzyTripMatcher() : null, diff --git a/src/main/java/org/opentripplanner/updater/vehicle_position/VehiclePositionsUpdaterParameters.java b/application/src/main/java/org/opentripplanner/updater/vehicle_position/VehiclePositionsUpdaterParameters.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/vehicle_position/VehiclePositionsUpdaterParameters.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_position/VehiclePositionsUpdaterParameters.java diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/GeofencingVertexUpdater.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/GeofencingVertexUpdater.java similarity index 99% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/GeofencingVertexUpdater.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/GeofencingVertexUpdater.java index a024bac9629..60eaae3a8ed 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_rental/GeofencingVertexUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/GeofencingVertexUpdater.java @@ -7,7 +7,6 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LineString; @@ -142,7 +141,6 @@ private Map applyExtension( * When finding the edges near the business area border in Oslo this speeds up the computation * from ~25 seconds to ~3 seconds (on 2021 hardware). */ - @Nonnull private Set getEdgesAlongLineStrings(Collection lineStrings) { return lineStrings .stream() diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalSourceType.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalSourceType.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalSourceType.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalSourceType.java diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdater.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdater.java similarity index 97% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdater.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdater.java index 77c3c8d01c6..24686edce6c 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdater.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdater.java @@ -10,11 +10,6 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.opentripplanner.framework.lang.ObjectUtils; -import org.opentripplanner.framework.logging.Throttle; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.linking.DisposableEdgeCollection; import org.opentripplanner.routing.linking.LinkingDirection; import org.opentripplanner.routing.linking.VertexLinker; @@ -37,6 +32,11 @@ import org.opentripplanner.updater.spi.UpdaterConstructionException; import org.opentripplanner.updater.spi.WriteToGraphCallback; import org.opentripplanner.updater.vehicle_rental.datasources.VehicleRentalDatasource; +import org.opentripplanner.utils.lang.ObjectUtils; +import org.opentripplanner.utils.logging.Throttle; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdaterParameters.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdaterParameters.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdaterParameters.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdaterParameters.java diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoader.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoader.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoader.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoader.java diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFreeVehicleStatusMapper.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFreeVehicleStatusMapper.java similarity index 98% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFreeVehicleStatusMapper.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFreeVehicleStatusMapper.java index 7fd884b7ab8..959521e017e 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFreeVehicleStatusMapper.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFreeVehicleStatusMapper.java @@ -5,7 +5,6 @@ import java.time.Instant; import java.util.HashMap; import java.util.Map; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.mobilitydata.gbfs.v2_3.free_bike_status.GBFSBike; import org.mobilitydata.gbfs.v2_3.free_bike_status.GBFSRentalUris; @@ -20,7 +19,6 @@ public class GbfsFreeVehicleStatusMapper { private final VehicleRentalSystem system; - @Nonnull private final Map vehicleTypes; public GbfsFreeVehicleStatusMapper( diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsGeofencingZoneMapper.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsGeofencingZoneMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsGeofencingZoneMapper.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsGeofencingZoneMapper.java index 22a4131f338..934243a1e76 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsGeofencingZoneMapper.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsGeofencingZoneMapper.java @@ -10,9 +10,9 @@ import org.mobilitydata.gbfs.v2_3.geofencing_zones.GBFSGeofencingZones; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.geometry.UnsupportedGeometryException; -import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.service.vehiclerental.model.GeofencingZone; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsStationInformationMapper.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsStationInformationMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsStationInformationMapper.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsStationInformationMapper.java diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsStationStatusMapper.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsStationStatusMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsStationStatusMapper.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsStationStatusMapper.java diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsSystemInformationMapper.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsSystemInformationMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsSystemInformationMapper.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsSystemInformationMapper.java diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSource.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSource.java similarity index 77% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSource.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSource.java index c441efb974a..331c4a15a70 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSource.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSource.java @@ -17,12 +17,13 @@ import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.io.OtpHttpClient; import org.opentripplanner.framework.io.OtpHttpClientFactory; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.service.vehiclerental.model.GeofencingZone; import org.opentripplanner.service.vehiclerental.model.RentalVehicleType; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.service.vehiclerental.model.VehicleRentalSystem; import org.opentripplanner.updater.vehicle_rental.datasources.params.GbfsVehicleRentalDataSourceParameters; +import org.opentripplanner.updater.vehicle_rental.datasources.params.RentalPickupType; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -75,43 +76,44 @@ public List getUpdates() { final Map vehicleTypes = getVehicleTypes(system); List stations = new LinkedList<>(); - - // Both station information and status are required for all systems using stations - GBFSStationInformation stationInformation = loader.getFeed(GBFSStationInformation.class); - GBFSStationStatus stationStatus = loader.getFeed(GBFSStationStatus.class); - if (stationInformation != null && stationStatus != null) { - // Index all the station status entries on their station ID. - Map statusLookup = stationStatus - .getData() - .getStations() - .stream() - .collect(Collectors.toMap(GBFSStation::getStationId, Function.identity())); - GbfsStationStatusMapper stationStatusMapper = new GbfsStationStatusMapper( - statusLookup, - vehicleTypes - ); - GbfsStationInformationMapper stationInformationMapper = new GbfsStationInformationMapper( - system, - vehicleTypes, - params.allowKeepingRentedVehicleAtDestination(), - params.overloadingAllowed() - ); - - // Iterate over all known stations, and if we have any status information add it to those station objects. - stations.addAll( - stationInformation + if (params.allowRentalType(RentalPickupType.STATION)) { + // Both station information and status are required for all systems using stations + GBFSStationInformation stationInformation = loader.getFeed(GBFSStationInformation.class); + GBFSStationStatus stationStatus = loader.getFeed(GBFSStationStatus.class); + if (stationInformation != null && stationStatus != null) { + // Index all the station status entries on their station ID. + Map statusLookup = stationStatus .getData() .getStations() .stream() - .map(stationInformationMapper::mapStationInformation) - .filter(Objects::nonNull) - .peek(stationStatusMapper::fillStationStatus) - .toList() - ); + .collect(Collectors.toMap(GBFSStation::getStationId, Function.identity())); + GbfsStationStatusMapper stationStatusMapper = new GbfsStationStatusMapper( + statusLookup, + vehicleTypes + ); + GbfsStationInformationMapper stationInformationMapper = new GbfsStationInformationMapper( + system, + vehicleTypes, + params.allowKeepingRentedVehicleAtDestination(), + params.overloadingAllowed() + ); + + // Iterate over all known stations, and if we have any status information add it to those station objects. + stations.addAll( + stationInformation + .getData() + .getStations() + .stream() + .map(stationInformationMapper::mapStationInformation) + .filter(Objects::nonNull) + .peek(stationStatusMapper::fillStationStatus) + .toList() + ); + } } // Append the floating bike stations. - if (OTPFeature.FloatingBike.isOn()) { + if (OTPFeature.FloatingBike.isOn() && params.allowRentalType(RentalPickupType.FREE_FLOATING)) { GBFSFreeBikeStatus freeBikeStatus = loader.getFeed(GBFSFreeBikeStatus.class); if (freeBikeStatus != null) { GbfsFreeVehicleStatusMapper freeVehicleStatusMapper = new GbfsFreeVehicleStatusMapper( diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleTypeMapper.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleTypeMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleTypeMapper.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleTypeMapper.java diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/VehicleRentalDataSourceFactory.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/VehicleRentalDataSourceFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/VehicleRentalDataSourceFactory.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/VehicleRentalDataSourceFactory.java diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/VehicleRentalDatasource.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/VehicleRentalDatasource.java similarity index 100% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/VehicleRentalDatasource.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/VehicleRentalDatasource.java diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/GbfsVehicleRentalDataSourceParameters.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/GbfsVehicleRentalDataSourceParameters.java similarity index 60% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/GbfsVehicleRentalDataSourceParameters.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/GbfsVehicleRentalDataSourceParameters.java index 99a5b48772c..31c81079046 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/GbfsVehicleRentalDataSourceParameters.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/GbfsVehicleRentalDataSourceParameters.java @@ -1,6 +1,7 @@ package org.opentripplanner.updater.vehicle_rental.datasources.params; -import javax.annotation.Nonnull; +import java.util.Objects; +import java.util.Set; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.vehicle_rental.VehicleRentalSourceType; @@ -11,12 +12,20 @@ public record GbfsVehicleRentalDataSourceParameters( HttpHeaders httpHeaders, String network, boolean geofencingZones, - boolean overloadingAllowed + boolean overloadingAllowed, + Set rentalPickupTypes ) implements VehicleRentalDataSourceParameters { - @Nonnull + public GbfsVehicleRentalDataSourceParameters { + Objects.requireNonNull(rentalPickupTypes); + } @Override public VehicleRentalSourceType sourceType() { return VehicleRentalSourceType.GBFS; } + + @Override + public boolean allowRentalType(RentalPickupType rentalPickupType) { + return rentalPickupTypes.contains(rentalPickupType); + } } diff --git a/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/RentalPickupType.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/RentalPickupType.java new file mode 100644 index 00000000000..e117f59d9c1 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/RentalPickupType.java @@ -0,0 +1,38 @@ +package org.opentripplanner.updater.vehicle_rental.datasources.params; + +import java.util.Collections; +import java.util.EnumSet; +import java.util.Set; +import org.opentripplanner.framework.doc.DocumentedEnum; + +/** + * This is temporary and will be removed in a future version of OTP. + * + * Enum to specify the type of rental data that is allowed to be read from the data source. + */ +public enum RentalPickupType implements DocumentedEnum { + STATION("Stations are imported."), + FREE_FLOATING("Free-floating vehicles are imported."); + + public static final Set ALL = Collections.unmodifiableSet( + EnumSet.allOf(RentalPickupType.class) + ); + + private final String description; + + RentalPickupType(String description) { + this.description = description.stripIndent().trim(); + } + + @Override + public String typeDescription() { + return ( + "This is temporary and will be removed in a future version of OTP. Use this to specify the type of rental data that is allowed to be read from the data source." + ); + } + + @Override + public String enumValueDescription() { + return description; + } +} diff --git a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/VehicleRentalDataSourceParameters.java b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/VehicleRentalDataSourceParameters.java similarity index 86% rename from src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/VehicleRentalDataSourceParameters.java rename to application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/VehicleRentalDataSourceParameters.java index abf7aa805cd..e87e7909bc5 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/VehicleRentalDataSourceParameters.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_rental/datasources/params/VehicleRentalDataSourceParameters.java @@ -1,20 +1,18 @@ package org.opentripplanner.updater.vehicle_rental.datasources.params; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.vehicle_rental.VehicleRentalSourceType; public interface VehicleRentalDataSourceParameters { - @Nonnull String url(); @Nullable String network(); - @Nonnull VehicleRentalSourceType sourceType(); - @Nonnull HttpHeaders httpHeaders(); + + boolean allowRentalType(RentalPickupType rentalPickupType); } diff --git a/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java b/application/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java similarity index 99% rename from src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java rename to application/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java index 6ab7d86917c..5ca8e55fc14 100644 --- a/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java +++ b/application/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java @@ -514,7 +514,8 @@ protected void route(String from, String to) { try ( var temporaryVertices = new TemporaryVerticesContainer( graph, - options, + options.from(), + options.to(), options.journey().direct().mode(), options.journey().direct().mode() ) diff --git a/src/main/java/org/opentripplanner/visualizer/RouteDialog.java b/application/src/main/java/org/opentripplanner/visualizer/RouteDialog.java similarity index 100% rename from src/main/java/org/opentripplanner/visualizer/RouteDialog.java rename to application/src/main/java/org/opentripplanner/visualizer/RouteDialog.java diff --git a/src/main/java/org/opentripplanner/visualizer/ShowGraph.java b/application/src/main/java/org/opentripplanner/visualizer/ShowGraph.java similarity index 100% rename from src/main/java/org/opentripplanner/visualizer/ShowGraph.java rename to application/src/main/java/org/opentripplanner/visualizer/ShowGraph.java diff --git a/src/main/java/org/opentripplanner/visualizer/VertexSelectionListener.java b/application/src/main/java/org/opentripplanner/visualizer/VertexSelectionListener.java similarity index 100% rename from src/main/java/org/opentripplanner/visualizer/VertexSelectionListener.java rename to application/src/main/java/org/opentripplanner/visualizer/VertexSelectionListener.java diff --git a/src/main/java/org/opentripplanner/visualizer/VisualTraverseVisitor.java b/application/src/main/java/org/opentripplanner/visualizer/VisualTraverseVisitor.java similarity index 100% rename from src/main/java/org/opentripplanner/visualizer/VisualTraverseVisitor.java rename to application/src/main/java/org/opentripplanner/visualizer/VisualTraverseVisitor.java diff --git a/application/src/main/java/org/opentripplanner/visualizer/package-info.md b/application/src/main/java/org/opentripplanner/visualizer/package-info.md new file mode 100644 index 00000000000..f1b60dde32f --- /dev/null +++ b/application/src/main/java/org/opentripplanner/visualizer/package-info.md @@ -0,0 +1,5 @@ +# Graph visualizer + +This package contains classes used for visualizing OpenTripPlanner graphs. This graph visualizer +is intended for debugging purposes and may therefore have arcane developer-oriented features and +grow new UI components as needed. diff --git a/src/main/jib/docker-entrypoint.sh b/application/src/main/jib/docker-entrypoint.sh similarity index 100% rename from src/main/jib/docker-entrypoint.sh rename to application/src/main/jib/docker-entrypoint.sh diff --git a/src/main/resources/Message.properties b/application/src/main/resources/Message.properties similarity index 100% rename from src/main/resources/Message.properties rename to application/src/main/resources/Message.properties diff --git a/src/main/resources/Message_de.properties b/application/src/main/resources/Message_de.properties similarity index 100% rename from src/main/resources/Message_de.properties rename to application/src/main/resources/Message_de.properties diff --git a/src/main/resources/Message_es.properties b/application/src/main/resources/Message_es.properties similarity index 100% rename from src/main/resources/Message_es.properties rename to application/src/main/resources/Message_es.properties diff --git a/src/main/resources/Message_fr.properties b/application/src/main/resources/Message_fr.properties similarity index 100% rename from src/main/resources/Message_fr.properties rename to application/src/main/resources/Message_fr.properties diff --git a/src/main/resources/Message_hu.properties b/application/src/main/resources/Message_hu.properties similarity index 100% rename from src/main/resources/Message_hu.properties rename to application/src/main/resources/Message_hu.properties diff --git a/src/main/resources/Message_nl.properties b/application/src/main/resources/Message_nl.properties similarity index 100% rename from src/main/resources/Message_nl.properties rename to application/src/main/resources/Message_nl.properties diff --git a/src/main/resources/WayProperties.properties b/application/src/main/resources/WayProperties.properties similarity index 100% rename from src/main/resources/WayProperties.properties rename to application/src/main/resources/WayProperties.properties diff --git a/src/main/resources/WayProperties_de.properties b/application/src/main/resources/WayProperties_de.properties similarity index 100% rename from src/main/resources/WayProperties_de.properties rename to application/src/main/resources/WayProperties_de.properties diff --git a/src/main/resources/WayProperties_fi.properties b/application/src/main/resources/WayProperties_fi.properties similarity index 100% rename from src/main/resources/WayProperties_fi.properties rename to application/src/main/resources/WayProperties_fi.properties diff --git a/src/main/resources/WayProperties_fr.properties b/application/src/main/resources/WayProperties_fr.properties similarity index 100% rename from src/main/resources/WayProperties_fr.properties rename to application/src/main/resources/WayProperties_fr.properties diff --git a/src/main/resources/WayProperties_hu.properties b/application/src/main/resources/WayProperties_hu.properties similarity index 100% rename from src/main/resources/WayProperties_hu.properties rename to application/src/main/resources/WayProperties_hu.properties diff --git a/src/main/resources/WayProperties_nl.properties b/application/src/main/resources/WayProperties_nl.properties similarity index 100% rename from src/main/resources/WayProperties_nl.properties rename to application/src/main/resources/WayProperties_nl.properties diff --git a/src/main/resources/WayProperties_no.properties b/application/src/main/resources/WayProperties_no.properties similarity index 100% rename from src/main/resources/WayProperties_no.properties rename to application/src/main/resources/WayProperties_no.properties diff --git a/src/main/resources/WayProperties_sv.properties b/application/src/main/resources/WayProperties_sv.properties similarity index 100% rename from src/main/resources/WayProperties_sv.properties rename to application/src/main/resources/WayProperties_sv.properties diff --git a/src/main/resources/internals.properties b/application/src/main/resources/internals.properties similarity index 100% rename from src/main/resources/internals.properties rename to application/src/main/resources/internals.properties diff --git a/src/main/resources/internals_de.properties b/application/src/main/resources/internals_de.properties similarity index 100% rename from src/main/resources/internals_de.properties rename to application/src/main/resources/internals_de.properties diff --git a/src/main/resources/internals_fi.properties b/application/src/main/resources/internals_fi.properties similarity index 100% rename from src/main/resources/internals_fi.properties rename to application/src/main/resources/internals_fi.properties diff --git a/src/main/resources/internals_fr.properties b/application/src/main/resources/internals_fr.properties similarity index 100% rename from src/main/resources/internals_fr.properties rename to application/src/main/resources/internals_fr.properties diff --git a/src/main/resources/internals_hu.properties b/application/src/main/resources/internals_hu.properties similarity index 100% rename from src/main/resources/internals_hu.properties rename to application/src/main/resources/internals_hu.properties diff --git a/src/main/resources/internals_no.properties b/application/src/main/resources/internals_no.properties similarity index 100% rename from src/main/resources/internals_no.properties rename to application/src/main/resources/internals_no.properties diff --git a/src/main/resources/internals_sv.properties b/application/src/main/resources/internals_sv.properties similarity index 100% rename from src/main/resources/internals_sv.properties rename to application/src/main/resources/internals_sv.properties diff --git a/src/main/resources/logback.xml b/application/src/main/resources/logback.xml similarity index 96% rename from src/main/resources/logback.xml rename to application/src/main/resources/logback.xml index 7ff48379a7d..8e01f9aef01 100644 --- a/src/main/resources/logback.xml +++ b/application/src/main/resources/logback.xml @@ -102,8 +102,8 @@ - - + + diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls similarity index 95% rename from src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls rename to application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 927af19f8b1..a131b95fc8e 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -73,6 +73,9 @@ interface PlaceInterface { "Entity related to an alert" union AlertEntity = Agency | Pattern | Route | RouteType | Stop | StopOnRoute | StopOnTrip | Trip | Unknown +"Rental place union that represents either a VehicleRentalStation or a RentalVehicle" +union RentalPlace = RentalVehicle | VehicleRentalStation + union StopPosition = PositionAtStop | PositionBetweenStops "A public transport agency" @@ -117,23 +120,32 @@ type Alert implements Node { "Alert cause" alertCause: AlertCauseType "Long description of the alert" - alertDescriptionText: String! + alertDescriptionText( + "Returns description with the specified language, if found, otherwise returns the value with some default language." + language: String + ): String! "Long descriptions of the alert in all different available languages" - alertDescriptionTextTranslations: [TranslatedString!]! + alertDescriptionTextTranslations: [TranslatedString!]! @deprecated(reason : "Use `alertDescriptionText` instead. `accept-language` header can be used for translations or the `language` parameter on the `alertDescriptionText` field.") "Alert effect" alertEffect: AlertEffectType "hashcode from the original GTFS-RT alert" alertHash: Int "Header of the alert, if available" - alertHeaderText: String + alertHeaderText( + "Returns header with the specified language, if found, otherwise returns the value with some default language." + language: String + ): String "Header of the alert in all different available languages" - alertHeaderTextTranslations: [TranslatedString!]! + alertHeaderTextTranslations: [TranslatedString!]! @deprecated(reason : "Use `alertHeaderText` instead. `accept-language` header can be used for translations or the `language` parameter on the `alertHeaderText` field.") "Alert severity level" alertSeverityLevel: AlertSeverityLevelType "Url with more information" - alertUrl: String + alertUrl( + "Returns URL with the specified language, if found, otherwise returns the value with some default language." + language: String + ): String "Url with more information in all different available languages" - alertUrlTranslations: [TranslatedString!]! + alertUrlTranslations: [TranslatedString!]! @deprecated(reason : "Use `alertUrl` instead. `accept-language` header can be used for translations or the `language` parameter on the `alertUrl` field.") "Time when this alert is not in effect anymore. Format: Unix timestamp in seconds" effectiveEndDate: Long "Time when this alert comes into effect. Format: Unix timestamp in seconds" @@ -670,6 +682,13 @@ type Leg { """ headsign: String """ + An identifier for the leg, which can be used to re-fetch transit leg information, except leg's fare products. + Re-fetching fails when the underlying transit data no longer exists. + **Note:** when both id and fare products are queried with [Relay](https://relay.dev/), id should be queried using a suitable GraphQL alias + such as `legId: id`. Relay does not accept different fare product ids in otherwise identical legs. + """ + id: String + """ Interlines with previous leg. This is true when the same vehicle is used for the previous leg as for this leg and passenger can stay inside the vehicle. @@ -717,6 +736,24 @@ type Leg { pickupBookingInfo: BookingInfo "This is used to indicate if boarding this leg is possible only with special arrangements." pickupType: PickupDropoffType + "Previous legs with same origin and destination stops or stations" + previousLegs( + """ + Transportation modes for which all stops in the parent station are used as possible destination stops + for the previous legs. For modes not listed, only the exact destination stop of the leg is considered. + """ + destinationModesWithParentStation: [TransitMode!], + """ + The number of alternative legs searched. If fewer than the requested number are found, + then only the found legs are returned. + """ + numberOfLegs: Int!, + """ + Transportation modes for which all stops in the parent station are used as possible origin stops + for the previous legs. For modes not listed, only the exact origin stop of the leg is considered. + """ + originModesWithParentStation: [TransitMode!] + ): [Leg!] "Whether there is real-time data about this Leg" realTime: Boolean "State of real-time data" @@ -1166,6 +1203,12 @@ type QueryType { time: Int! ): Trip """ + Try refetching the current state of a transit leg using its id. + This fails when the underlying transit data (mostly IDs) has changed or are no longer available. + Fare products cannot be refetched using this query. + """ + leg(id: String!): Leg + """ Get all places (stops, stations, etc. with coordinates) within the specified radius from a location. The returned type is a Relay connection (see https://facebook.github.io/relay/graphql/connections.htm). The placeAtDistance @@ -1473,6 +1516,11 @@ type QueryType { "List of routes and agencies which are given lower preference when planning the itinerary" unpreferred: InputUnpreferred, """ + The list of points the itinerary required to pass through. + All locations are visited in the order they are listed. + """ + via: [PlanViaLocationInput!], + """ How much less bad is waiting at the beginning of the trip (replaces `waitReluctance` on the first boarding). Default value: 0.4 """ @@ -1512,7 +1560,7 @@ type QueryType { walkSpeed: Float, "Whether the itinerary must be wheelchair accessible. Default value: false" wheelchair: Boolean - ): Plan @async + ): Plan @async @deprecated(reason : "Use `planConnection` instead.") """ Plan (itinerary) search that follows [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm). @@ -1596,8 +1644,10 @@ type QueryType { is in combination of using paging can lead to better performance and to getting a more consistent number of itineraries in each search. """ - searchWindow: Duration - ): PlanConnection @async @deprecated(reason : "Experimental and can include breaking changes, use plan instead") + searchWindow: Duration, + "The list of points the itinerary is required to pass through." + via: [PlanViaLocationInput!] + ): PlanConnection @async "Get a single rental vehicle based on its ID, i.e. value of field `vehicleId`" rentalVehicle(id: String!): RentalVehicle "Get all rental vehicles" @@ -1721,6 +1771,17 @@ type QueryType { """ ids: [String] ): [VehicleRentalStation] + "Get all rental vehicles within the specified bounding box" + vehicleRentalsByBbox( + "Northern bound of the bounding box" + maximumLatitude: CoordinateValue!, + "Eastern bound of the bounding box" + maximumLongitude: CoordinateValue!, + "Southern bound of the bounding box" + minimumLatitude: CoordinateValue!, + "Western bound of the bounding box" + minimumLongitude: CoordinateValue! + ): [RentalPlace!]! "Needed until https://github.com/facebook/relay/issues/112 is resolved" viewer: QueryType } @@ -2001,7 +2062,16 @@ type Stop implements Node & PlaceInterface { "Identifier of the platform, usually a number. This value is only present for stops that are part of a station" platformCode: String "Routes which pass through this stop" - routes: [Route!] + routes( + """ + Only include routes which are operational on at least one service date specified by this filter. + + **Note**: A service date is a technical term useful for transit planning purposes and might not + correspond to a how a passenger thinks of a calendar date. For example, a night bus running + on Sunday morning at 1am to 3am, might have the previous Saturday's service date. + """ + serviceDates: LocalDateRangeInput + ): [Route!] "Returns timetable of the specified pattern at this stop" stopTimesForPattern( "Id of the pattern" @@ -2176,10 +2246,10 @@ type Stoptime { "The stop where this arrival/departure happens" stop: Stop """ - The sequence of the stop in the pattern. This is not required to start from 0 or be consecutive - any + The sequence of the stop in the trip. This is not required to start from 0 or be consecutive - any increasing integer sequence along the stops is valid. - The purpose of this field is to identify the stop within the pattern so it can be cross-referenced + The purpose of this field is to identify the stop within the trip so it can be cross-referenced between it and the itinerary. It is safe to cross-reference when done quickly, i.e. within seconds. However, it should be noted that real-time updates can change the values, so don't store it for longer amounts of time. @@ -2188,6 +2258,15 @@ type Stoptime { even generated. """ stopPosition: Int + """ + The position of the stop in the pattern. This is required to start from 0 and be consecutive along + the pattern, up to n-1 for a pattern with n stops. + + The purpose of this field is to identify the position of the stop within the pattern so it can be + cross-referenced between different trips on the same pattern, as stopPosition can be different + between trips even within the same pattern. + """ + stopPositionInPattern: Int! "true, if this stop is used as a time equalization stop. false otherwise." timepoint: Boolean "Trip which this stoptime is for" @@ -3062,6 +3141,12 @@ enum PlanAccessMode { """ BICYCLE_RENTAL """ + Driving to a stop and boarding a vehicle with the car. + Access can use driving only if the mode used for transfers + and egress is also `CAR`. + """ + CAR + """ Getting dropped off by a car to a location that is accessible with a car. Note, this can include walking after the drop-off. """ @@ -3171,6 +3256,11 @@ enum PlanEgressMode { """ BICYCLE_RENTAL """ + Driving from a stop to the destination. Egress can use driving only if the mode + used for access and transfers is also `CAR`. + """ + CAR + """ Getting picked up by a car from a location that is accessible with a car. Note, this can include walking before the pickup. """ @@ -3208,6 +3298,11 @@ enum PlanTransferMode { cycling if the mode used for access and egress is also `BICYCLE`. """ BICYCLE + """ + Driving between transit vehicles. Transfers can only use driving if the mode + used for access and egress is also `CAR`. + """ + CAR "Walking between transit vehicles (typically between stops)." WALK } @@ -3819,18 +3914,28 @@ input InputModeWeight { BUS: Float "The weight of CABLE_CAR traverse mode. Values over 1 add cost to cable car travel and values under 1 decrease cost" CABLE_CAR: Float + "The weight of CARPOOL traverse mode. Values over 1 add cost to carpool travel and values under 1 decrease cost" + CARPOOL: Float + "The weight of COACH traverse mode. Values over 1 add cost to coach travel and values under 1 decrease cost" + COACH: Float "The weight of FERRY traverse mode. Values over 1 add cost to ferry travel and values under 1 decrease cost" FERRY: Float "The weight of FUNICULAR traverse mode. Values over 1 add cost to funicular travel and values under 1 decrease cost" FUNICULAR: Float "The weight of GONDOLA traverse mode. Values over 1 add cost to gondola travel and values under 1 decrease cost" GONDOLA: Float + "The weight of MONORAIL traverse mode. Values over 1 add cost to monorail travel and values under 1 decrease cost" + MONORAIL: Float "The weight of RAIL traverse mode. Values over 1 add cost to rail travel and values under 1 decrease cost" RAIL: Float "The weight of SUBWAY traverse mode. Values over 1 add cost to subway travel and values under 1 decrease cost" SUBWAY: Float + "The weight of TAXI traverse mode. Values over 1 add cost to taxi travel and values under 1 decrease cost" + TAXI: Float "The weight of TRAM traverse mode. Values over 1 add cost to tram travel and values under 1 decrease cost" TRAM: Float + "The weight of TROLLEYBUS traverse mode. Values over 1 add cost to trolleybus travel and values under 1 decrease cost" + TROLLEYBUS: Float } input InputPreferred { @@ -4044,6 +4149,20 @@ input PlanModesInput { transitOnly: Boolean = false } +""" +One of the listed stop locations must be visited on-board a transit vehicle or the journey must +alight or board at the location. +""" +input PlanPassThroughViaLocationInput { + "The label/name of the location. This is pass-through information and is not used in routing." + label: String + """ + A list of stop locations. A stop location can be a stop or a station. + It is enough to visit ONE of the locations listed. + """ + stopLocationIds: [String!]! +} + "Wrapper type for different types of preferences related to plan query." input PlanPreferencesInput { "Accessibility preferences that affect both the street and transit routing." @@ -4137,6 +4256,40 @@ input PlanTransitModesInput { transit: [PlanTransitModePreferenceInput!] } +""" +A via-location is used to specifying a location as an intermediate place the router must +route through. The via-location is either a pass-through-location or a visit-via-location. +""" +input PlanViaLocationInput @oneOf { + "Board, alight or pass-through(on-board) at the stop location." + passThrough: PlanPassThroughViaLocationInput + "Board or alight at a stop location or visit a coordinate." + visit: PlanVisitViaLocationInput +} + +""" +A visit-via-location is a physical visit to one of the stop locations or coordinates listed. An +on-board visit does not count, the traveler must alight or board at the given stop for it to to +be accepted. To visit a coordinate, the traveler must walk(bike or drive) to the closest point +in the street network from a stop and back to another stop to join the transit network. + +NOTE! Coordinates are NOT supported yet. +""" +input PlanVisitViaLocationInput { + "The label/name of the location. This is pass-through information and is not used in routing." + label: String + """ + The minimum wait time is used to force the trip to stay the given duration at the + via-location before the itinerary is continued. + """ + minimumWaitTime: Duration = "PT0S" + """ + A list of stop locations. A stop location can be a stop or a station. + It is enough to visit ONE of the locations listed. + """ + stopLocationIds: [String!] +} + "What criteria should be used when optimizing a scooter route." input ScooterOptimizationInput @oneOf { "Define optimization by weighing three criteria." diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/application/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql similarity index 94% rename from src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql rename to application/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index 0d2bf71dcc6..783cc3e7948 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/application/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -325,7 +325,7 @@ type Leg { fromPlace: Place! "Generalized cost or weight of the leg. Used for debugging." generalizedCost: Int - "An identifier for the leg, which can be used to re-fetch the information." + "An identifier for the leg, which can be used to re-fetch transit leg information." id: ID interchangeFrom: Interchange interchangeTo: Interchange @@ -647,7 +647,7 @@ type QueryType { groupOfLines(id: String!): GroupOfLines "Get all groups of lines" groupsOfLines: [GroupOfLines!]! - "Refetch a single leg based on its id" + "Refetch a single transit leg based on its id" leg(id: ID!): Leg @timingData "Get a single line based on its id" line(id: ID!): Line @timingData @@ -730,19 +730,19 @@ type QueryType { ): quayAtDistanceConnection @timingData "Get default routing parameters." routingParameters: RoutingParameters @timingData - "Get OTP server information" + "Get OTP deployment information. This is only useful for developers of OTP itself not regular API users." serverInfo: ServerInfo! @timingData "Get a single service journey based on its id" serviceJourney(id: String!): ServiceJourney @timingData - "Get all service journeys" + "Get all _service journeys_" serviceJourneys( - "Set of ids of active dates to fetch serviceJourneys for." + "Set of _operating days_ to fetch _service journeys_ for." activeDates: [Date], - "Set of ids of authorities to fetch serviceJourneys for." + "Set of ids of _authorities_ to fetch _service journeys_ for." authorities: [String], - "Set of ids of lines to fetch serviceJourneys for." + "Set of ids of _lines_ to fetch _service journeys_ for." lines: [ID], - "Set of ids of private codes to fetch serviceJourneys for." + "Set of ids of _private codes_ to fetch _service journeys_ for." privateCodes: [String] ): [ServiceJourney]! @timingData "Get a single situation based on its situationNumber" @@ -831,10 +831,15 @@ type QueryType { modes: Modes, "The maximum number of trip patterns to return. Note! This reduce the number of trip patterns AFTER the OTP travel search is done in a post-filtering process. There is little/no performance gain in reducing the number of trip patterns returned. See also the trip meta-data on how to implement paging." numTripPatterns: Int = 50, - "Use the cursor to go to the next \"page\" of itineraries. Copy the cursor from the last response and keep the original request as is. This will enable you to search for itineraries in the next or previous time-window." + """ + Use the cursor to go to the next "page" of itineraries. Copy the cursor from the last + response and keep the original request as is. This will enable you to search for + itineraries in the next or previous search-window. The paging will automatically scale + up/down the search-window to fit the `numTripPatterns`. + """ pageCursor: String, "The list of points the journey is required to pass through." - passThroughPoints: [PassThroughPoint!], + passThroughPoints: [PassThroughPoint!] @deprecated(reason : "Use via instead"), """ Relax generalized-cost when comparing trips with a different set of transit-group-priorities. The groups are set server side for service-journey and @@ -868,13 +873,35 @@ type QueryType { """ The length of the search-window in minutes. This parameter is optional. - The search-window is defined as the duration between the earliest-departure-time(EDT) and the latest-departure-time(LDT). OTP will search for all itineraries in this departure window. If `arriveBy=true` the `dateTime` parameter is the latest-arrival-time, so OTP will dynamically calculate the EDT. Using a short search-window is faster than using a longer one, but the search duration is not linear. Using a "too" short search-window will waste resources server side, while using a search-window that is too long will be slow. + The search-window is defined as the duration between the earliest-departure-time(EDT) and + the latest-departure-time(LDT). OTP will search for all itineraries in this departure + window. If `arriveBy=true` the `dateTime` parameter is the latest-arrival-time, so OTP + will dynamically calculate the EDT. Using a short search-window is faster than using a + longer one, but the search duration is not linear. Using a "too" short search-window will + waste resources server side, while using a search-window that is too long will be slow. - OTP will dynamically calculate a reasonable value for the search-window, if not provided. The calculation comes with a significant overhead (10-20% extra). Whether you should use the dynamic calculated value or pass in a value depends on your use-case. For a travel planner in a small geographical area, with a dense network of public transportation, a fixed value between 40 minutes and 2 hours makes sense. To find the appropriate search-window, adjust it so that the number of itineraries on average is around the wanted `numItineraries`. Make sure you set the `numItineraries` to a high number while testing. For a country wide area like Norway, using the dynamic search-window is the best. + OTP will dynamically calculate a reasonable value for the search-window, if not provided. The + calculation comes with a significant overhead (10-20% extra). Whether you should use the + dynamic calculated value or pass in a value depends on your use-case. For a travel planner + in a small geographical area, with a dense network of public transportation, a fixed value + between 40 minutes and 2 hours makes sense. To find the appropriate search-window, adjust it + so that the number of itineraries on average is around the wanted `numTripPatterns`. Make + sure you set the `numTripPatterns` to a high number while testing. For a country wide area like + Norway, using the dynamic search-window is the best. - When paginating, the search-window is calculated using the `numItineraries` in the original search together with statistics from the search for the last page. This behaviour is configured server side, and can not be overridden from the client. + When paginating, the search-window is calculated using the `numTripPatterns` in the original + search together with statistics from the search for the last page. This behaviour is + configured server side, and can not be overridden from the client. The paging may even + exceed the maximum value. - The search-window used is returned to the response metadata as `searchWindowUsed` for debugging purposes. + The search-window used is returned to the response metadata as `searchWindowUsed`. + This can be used by the client to calculate the when the next page start/end. + + Note! In some cases you may have to page many times to get all the results you want. + This is intended. Increasing the search-window beyond the max value is NOT going to be + much faster. Instead the client can inform the user about the progress. + + Maximum value: 1440 minutes (24h) """ searchWindow: Int, """ @@ -900,6 +927,11 @@ type QueryType { triangleFactors: TriangleFactors, "Whether or not bike rental availability information will be used to plan bike rental trips." useBikeRentalAvailabilityInformation: Boolean = false, + """ + The list of via locations the journey is required to visit. All locations are + visited in the order they are listed. + """ + via: [TripViaLocationInput!], "Wait cost is multiplied by this value. Setting this to a value lower than 1 indicates that waiting is better than staying on a vehicle. This should never be set higher than walkReluctance, since that would lead to walking down a line to avoid waiting." waitReluctance: Float = 1.0, "Walk cost is multiplied by this value. This is the main parameter to use for limiting walking." @@ -943,7 +975,7 @@ type QueryType { via: [ViaLocationInput!]!, "Whether the trip must be wheelchair accessible. Supported for the street part to the search, not implemented for the transit yet." wheelchairAccessible: Boolean = false - ): ViaTrip! @timingData + ): ViaTrip! @deprecated(reason : "Use the regular trip query with via stop instead.") @timingData } type RentalVehicle implements PlaceInterface { @@ -1067,6 +1099,11 @@ type RoutingParameters { wheelChairAccessible: Boolean } +""" +Information about the deployment. This is only useful to developers of OTP itself. +It is not recommended for regular API consumers to use this type as it has no +stability guarantees. +""" type ServerInfo { "The 'configVersion' of the build-config.json file." buildConfigVersion: String @@ -1075,6 +1112,12 @@ type ServerInfo { gitBranch: String gitCommit: String gitCommitTime: String + """ + The internal time zone of the transit data. + + Note: The input data can be in several time zones, but OTP internally operates on a single one. + """ + internalTransitModelTimeZone: String "The 'configVersion' of the otp-config.json file." otpConfigVersion: String "The otp-serialization-version-id used to check graphs for compatibility with current version of OTP." @@ -1366,7 +1409,7 @@ type TripSearchData { nextDateTime: DateTime @deprecated(reason : "Use pageCursor instead") "This is the suggested search time for the \"previous page\" or time-window. Insert it together with the 'searchWindowUsed' in the request to get a new set of trips preceding in the time-window BEFORE the current search." prevDateTime: DateTime @deprecated(reason : "Use pageCursor instead") - "This is the time window used by the raptor search. The input searchWindow is an optional parameter and is dynamically assigned if not set. OTP might override the value if it is too small or too large. When paging OTP adjusts it to the appropriate size, depending on the number of itineraries found in the current search window. The scaling of the search window ensures faster paging and limits resource usage. The unit is seconds." + "This is the time window used by the raptor search. The input searchWindow is an optional parameter and is dynamically assigned if not set. OTP might override the value if it is too small or too large. When paging OTP adjusts it to the appropriate size, depending on the number of itineraries found in the current search window. The scaling of the search window ensures faster paging and limits resource usage. The unit is minutes." searchWindowUsed: Int! } @@ -2176,6 +2219,56 @@ input TripFilterSelectInput { transportModes: [TransportModes!] } +""" +One of the listed stop locations must be visited on-board a transit vehicle or the journey must +alight or board at the location. +""" +input TripPassThroughViaLocationInput { + "The label/name of the location. This is pass-through information and is not used in routing." + label: String + """ + A list of stop locations. A stop location can be a quay, a stop place, a multimodal + stop place or a group of stop places. It is enough to visit ONE of the locations + listed. + """ + stopLocationIds: [String!]! +} + +""" +A via-location is used to specifying a location as an intermediate place the router must +route through. The via-location is either a pass-through-location or a visit-via-location. +""" +input TripViaLocationInput @oneOf { + "Board, alight or pass-through(on-board) at the stop location." + passThrough: TripPassThroughViaLocationInput + "Board or alight at a stop location or visit a coordinate." + visit: TripVisitViaLocationInput +} + +""" +A visit-via-location is a physical visit to one of the stop locations or coordinates listed. An +on-board visit does not count, the traveler must alight or board at the given stop for it to to +be accepted. To visit a coordinate, the traveler must walk(bike or drive) to the closest point +in the street network from a stop and back to another stop to join the transit network. + +NOTE! Coordinates are NOT supported yet. +""" +input TripVisitViaLocationInput { + "The label/name of the location. This is pass-through information and is not used in routing." + label: String + """ + The minimum wait time is used to force the trip to stay the given duration at the + via-location before the trip is continued. + """ + minimumWaitTime: Duration = "PT0S" + """ + A list of stop locations. A stop location can be a quay, a stop place, a multimodal + stop place or a group of stop places. It is enough to visit ONE of the locations + listed. + """ + stopLocationIds: [String!]! +} + "Input format for specifying a location through either a place reference (id), coordinates or both. If both place and coordinates are provided the place ref will be used if found, coordinates will only be used if place is not known. The location also contain information about the minimum and maximum time the user is willing to stay at the via location." input ViaLocationInput { "Coordinates for the location. This can be used alone or as fallback if the place id is not found." diff --git a/src/main/resources/otp-project-info.properties b/application/src/main/resources/otp-project-info.properties similarity index 100% rename from src/main/resources/otp-project-info.properties rename to application/src/main/resources/otp-project-info.properties diff --git a/src/test/java/org/opentripplanner/ConstantsForTests.java b/application/src/test/java/org/opentripplanner/ConstantsForTests.java similarity index 79% rename from src/test/java/org/opentripplanner/ConstantsForTests.java rename to application/src/test/java/org/opentripplanner/ConstantsForTests.java index e74c66e527b..e5ab48cee54 100644 --- a/src/test/java/org/opentripplanner/ConstantsForTests.java +++ b/application/src/test/java/org/opentripplanner/ConstantsForTests.java @@ -4,6 +4,7 @@ import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.time.Duration; import java.util.List; import java.util.Map; import javax.annotation.Nullable; @@ -15,6 +16,7 @@ import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.graph_builder.ConfiguredDataSource; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; +import org.opentripplanner.graph_builder.module.DirectTransferGenerator; import org.opentripplanner.graph_builder.module.GtfsFeedId; import org.opentripplanner.graph_builder.module.TestStreetLinkerModule; import org.opentripplanner.graph_builder.module.ned.ElevationModule; @@ -26,11 +28,13 @@ import org.opentripplanner.model.impl.OtpTransitServiceBuilder; import org.opentripplanner.netex.NetexBundle; import org.opentripplanner.netex.configure.NetexConfigure; -import org.opentripplanner.openstreetmap.OsmProvider; +import org.opentripplanner.osm.OsmProvider; +import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.fares.FareServiceFactory; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.linking.LinkingDirection; import org.opentripplanner.routing.linking.VertexLinker; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; import org.opentripplanner.service.vehiclerental.model.RentalVehicleType; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; import org.opentripplanner.service.vehiclerental.street.StreetVehicleRentalLink; @@ -43,8 +47,8 @@ import org.opentripplanner.test.support.ResourceLoader; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; public class ConstantsForTests { @@ -100,7 +104,10 @@ public static NetexBundle createMinimalNetexNordicBundle() { var dataSource = new ZipFileDataSource(netexZipFile, FileType.NETEX); var configuredDataSource = new ConfiguredDataSource<>(dataSource, buildConfig.netexDefaults); - var transitService = new OtpTransitServiceBuilder(new StopModel(), DataImportIssueStore.NOOP); + var transitService = new OtpTransitServiceBuilder( + new SiteRepository(), + DataImportIssueStore.NOOP + ); return new NetexConfigure(buildConfig).netexBundle(transitService, configuredDataSource); } @@ -112,7 +119,10 @@ public static NetexBundle createMinimalNetexEpipBundle() { var dataSource = new DirectoryDataSource(netexZipFile, FileType.NETEX); var configuredDataSource = new ConfiguredDataSource<>(dataSource, buildConfig.netexDefaults); - var transitService = new OtpTransitServiceBuilder(new StopModel(), DataImportIssueStore.NOOP); + var transitService = new OtpTransitServiceBuilder( + new SiteRepository(), + DataImportIssueStore.NOOP + ); return new NetexConfigure(buildConfig).netexBundle(transitService, configuredDataSource); } @@ -124,12 +134,12 @@ public static TestOtpModel buildNewPortlandGraph(boolean withElevation) { try { var deduplicator = new Deduplicator(); var graph = new Graph(deduplicator); - var transitModel = new TransitModel(new StopModel(), deduplicator); + var timetableRepository = new TimetableRepository(new SiteRepository(), deduplicator); // Add street data from OSM { OsmProvider osmProvider = new OsmProvider(PORTLAND_CENTRAL_OSM, false); OsmModule osmModule = OsmModule - .of(osmProvider, graph) + .of(osmProvider, graph, new DefaultVehicleParkingRepository()) .withStaticParkAndRide(true) .withStaticBikeParkAndRide(true) .build(); @@ -137,10 +147,16 @@ public static TestOtpModel buildNewPortlandGraph(boolean withElevation) { } // Add transit data from GTFS { - addGtfsToGraph(graph, transitModel, PORTLAND_GTFS, new DefaultFareServiceFactory(), "prt"); + addGtfsToGraph( + graph, + timetableRepository, + PORTLAND_GTFS, + new DefaultFareServiceFactory(), + "prt" + ); } // Link transit stops to streets - TestStreetLinkerModule.link(graph, transitModel); + TestStreetLinkerModule.link(graph, timetableRepository); // Add elevation data if (withElevation) { @@ -155,10 +171,18 @@ public static TestOtpModel buildNewPortlandGraph(boolean withElevation) { addPortlandVehicleRentals(graph); - transitModel.index(); - graph.index(transitModel.getStopModel()); + new DirectTransferGenerator( + graph, + timetableRepository, + DataImportIssueStore.NOOP, + Duration.ofMinutes(30), + List.of(new RouteRequest()) + ) + .buildGraph(); + + graph.index(timetableRepository.getSiteRepository()); - return new TestOtpModel(graph, transitModel); + return new TestOtpModel(graph, timetableRepository); } catch (Exception e) { throw new RuntimeException(e); } @@ -167,14 +191,16 @@ public static TestOtpModel buildNewPortlandGraph(boolean withElevation) { public static TestOtpModel buildOsmGraph(File osmFile) { try { var deduplicator = new Deduplicator(); - var stopModel = new StopModel(); + var siteRepository = new SiteRepository(); var graph = new Graph(deduplicator); - var transitModel = new TransitModel(stopModel, deduplicator); + var timetableRepository = new TimetableRepository(siteRepository, deduplicator); // Add street data from OSM OsmProvider osmProvider = new OsmProvider(osmFile, true); - OsmModule osmModule = OsmModule.of(osmProvider, graph).build(); + OsmModule osmModule = OsmModule + .of(osmProvider, graph, new DefaultVehicleParkingRepository()) + .build(); osmModule.buildGraph(); - return new TestOtpModel(graph, transitModel); + return new TestOtpModel(graph, timetableRepository); } catch (Exception e) { throw new RuntimeException(e); } @@ -185,14 +211,14 @@ public static TestOtpModel buildOsmAndGtfsGraph(File osmPath, File gtfsPath) { addGtfsToGraph( otpModel.graph(), - otpModel.transitModel(), + otpModel.timetableRepository(), gtfsPath, new DefaultFareServiceFactory(), null ); // Link transit stops to streets - TestStreetLinkerModule.link(otpModel.graph(), otpModel.transitModel()); + TestStreetLinkerModule.link(otpModel.graph(), otpModel.timetableRepository()); return otpModel; } @@ -203,23 +229,24 @@ public static TestOtpModel buildGtfsGraph(File gtfsPath) { public static TestOtpModel buildGtfsGraph(File gtfsFile, FareServiceFactory fareServiceFactory) { var deduplicator = new Deduplicator(); - var stopModel = new StopModel(); + var siteRepository = new SiteRepository(); var graph = new Graph(deduplicator); - var transitModel = new TransitModel(stopModel, deduplicator); - addGtfsToGraph(graph, transitModel, gtfsFile, fareServiceFactory, null); - return new TestOtpModel(graph, transitModel); + var timetableRepository = new TimetableRepository(siteRepository, deduplicator); + addGtfsToGraph(graph, timetableRepository, gtfsFile, fareServiceFactory, null); + return new TestOtpModel(graph, timetableRepository); } public static TestOtpModel buildNewMinimalNetexGraph() { try { var deduplicator = new Deduplicator(); - var stopModel = new StopModel(); + var siteRepository = new SiteRepository(); + var parkingService = new DefaultVehicleParkingRepository(); var graph = new Graph(deduplicator); - var transitModel = new TransitModel(stopModel, deduplicator); + var timetableRepository = new TimetableRepository(siteRepository, deduplicator); // Add street data from OSM { OsmProvider osmProvider = new OsmProvider(OSLO_EAST_OSM, false); - OsmModule osmModule = OsmModule.of(osmProvider, graph).build(); + OsmModule osmModule = OsmModule.of(osmProvider, graph, parkingService).build(); osmModule.buildGraph(); } // Add transit data from Netex @@ -232,13 +259,19 @@ public static TestOtpModel buildNewMinimalNetexGraph() { var sources = List.of(new ConfiguredDataSource<>(NETEX_MINIMAL_DATA_SOURCE, netexConfig)); new NetexConfigure(buildConfig) - .createNetexModule(sources, transitModel, graph, DataImportIssueStore.NOOP) + .createNetexModule( + sources, + timetableRepository, + parkingService, + graph, + DataImportIssueStore.NOOP + ) .buildGraph(); } // Link transit stops to streets - TestStreetLinkerModule.link(graph, transitModel); + TestStreetLinkerModule.link(graph, timetableRepository); - return new TestOtpModel(graph, transitModel); + return new TestOtpModel(graph, timetableRepository); } catch (Exception e) { throw new RuntimeException(e); } @@ -266,7 +299,7 @@ public synchronized TestOtpModel getCachedPortlandGraphWithElevation() { public static void addGtfsToGraph( Graph graph, - TransitModel transitModel, + TimetableRepository timetableRepository, File file, FareServiceFactory fareServiceFactory, @Nullable String feedId @@ -276,7 +309,7 @@ public static void addGtfsToGraph( var module = new GtfsModule( List.of(bundle), - transitModel, + timetableRepository, graph, DataImportIssueStore.NOOP, ServiceDateInterval.unbounded(), @@ -285,8 +318,8 @@ public static void addGtfsToGraph( module.buildGraph(); - transitModel.index(); - graph.index(transitModel.getStopModel()); + timetableRepository.index(); + graph.index(timetableRepository.getSiteRepository()); } private static void addPortlandVehicleRentals(Graph graph) { diff --git a/src/test/java/org/opentripplanner/DateTimeHelper.java b/application/src/test/java/org/opentripplanner/DateTimeHelper.java similarity index 93% rename from src/test/java/org/opentripplanner/DateTimeHelper.java rename to application/src/test/java/org/opentripplanner/DateTimeHelper.java index 6a058118d1b..2751af48daf 100644 --- a/src/test/java/org/opentripplanner/DateTimeHelper.java +++ b/application/src/test/java/org/opentripplanner/DateTimeHelper.java @@ -3,7 +3,7 @@ import java.time.LocalDate; import java.time.ZoneId; import java.time.ZonedDateTime; -import org.opentripplanner.framework.time.DateUtils; +import org.opentripplanner.utils.time.DateUtils; public class DateTimeHelper { diff --git a/src/test/java/org/opentripplanner/GtfsTest.java b/application/src/test/java/org/opentripplanner/GtfsTest.java similarity index 93% rename from src/test/java/org/opentripplanner/GtfsTest.java rename to application/src/test/java/org/opentripplanner/GtfsTest.java index 9b37c488b8e..5d548e4012c 100644 --- a/src/test/java/org/opentripplanner/GtfsTest.java +++ b/application/src/test/java/org/opentripplanner/GtfsTest.java @@ -1,5 +1,6 @@ package org.opentripplanner; +import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -39,8 +40,8 @@ import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.updater.TimetableSnapshotSourceParameters; import org.opentripplanner.updater.alert.AlertsUpdateHandler; import org.opentripplanner.updater.trip.TimetableSnapshotSource; @@ -50,7 +51,7 @@ public abstract class GtfsTest { public Graph graph; - public TransitModel transitModel; + public TimetableRepository timetableRepository; AlertsUpdateHandler alertsUpdateHandler; TimetableSnapshotSource timetableSnapshotSource; @@ -178,7 +179,7 @@ public void validateLeg( assertEquals(1, leg.getStreetNotes().size()); assertEquals(alert, leg.getStreetNotes().iterator().next().note.toString()); } else { - assertNull(leg.getStreetNotes()); + assertThat(leg.getStreetNotes()).isEmpty(); } } @@ -194,27 +195,27 @@ protected void setUp() throws Exception { alertsUpdateHandler = new AlertsUpdateHandler(false); var deduplicator = new Deduplicator(); graph = new Graph(deduplicator); - transitModel = new TransitModel(new StopModel(), deduplicator); + timetableRepository = new TimetableRepository(new SiteRepository(), deduplicator); GtfsModule gtfsGraphBuilderImpl = new GtfsModule( gtfsBundleList, - transitModel, + timetableRepository, graph, ServiceDateInterval.unbounded() ); gtfsGraphBuilderImpl.buildGraph(); - transitModel.index(); - graph.index(transitModel.getStopModel()); - serverContext = TestServerContext.createServerContext(graph, transitModel); + timetableRepository.index(); + graph.index(timetableRepository.getSiteRepository()); + serverContext = TestServerContext.createServerContext(graph, timetableRepository); timetableSnapshotSource = new TimetableSnapshotSource( TimetableSnapshotSourceParameters.DEFAULT .withPurgeExpiredData(true) .withMaxSnapshotFrequency(Duration.ZERO), - transitModel + timetableRepository ); - alertPatchServiceImpl = new TransitAlertServiceImpl(transitModel); + alertPatchServiceImpl = new TransitAlertServiceImpl(timetableRepository); alertsUpdateHandler.setTransitAlertService(alertPatchServiceImpl); alertsUpdateHandler.setFeedId(feedId.getId()); diff --git a/src/test/java/org/opentripplanner/OtpArchitectureModules.java b/application/src/test/java/org/opentripplanner/OtpArchitectureModules.java similarity index 83% rename from src/test/java/org/opentripplanner/OtpArchitectureModules.java rename to application/src/test/java/org/opentripplanner/OtpArchitectureModules.java index 72520acaa1c..8d6fc431f50 100644 --- a/src/test/java/org/opentripplanner/OtpArchitectureModules.java +++ b/application/src/test/java/org/opentripplanner/OtpArchitectureModules.java @@ -18,6 +18,9 @@ public interface OtpArchitectureModules { /* OTP Modules */ Package OTP_ROOT = Package.of("org.opentripplanner"); + + Package UTILS_PACKAGE = OTP_ROOT.subPackage("utils"); + Package DATASTORE = OTP_ROOT.subPackage("datastore"); Package FRAMEWORK = OTP_ROOT.subPackage("framework"); Module GEO_UTILS = Module.of(JTS_GEOM, FRAMEWORK.subPackage("geometry")); @@ -37,15 +40,20 @@ public interface OtpArchitectureModules { * This is a bag of TRUE util classes - no dependencies to other OTP classes or frameworks * (except true utilities like slf4j). */ + Module OTP_UTILS = Module.of( + UTILS_PACKAGE.subPackage("collection"), + UTILS_PACKAGE.subPackage("lang"), + UTILS_PACKAGE.subPackage("logging"), + UTILS_PACKAGE.subPackage("text"), + UTILS_PACKAGE.subPackage("time"), + UTILS_PACKAGE.subPackage("tostring") + ); + Module FRAMEWORK_UTILS = Module.of( + OTP_UTILS, FRAMEWORK.subPackage("application"), FRAMEWORK.subPackage("error"), FRAMEWORK.subPackage("i18n"), - FRAMEWORK.subPackage("lang"), - FRAMEWORK.subPackage("logging"), - FRAMEWORK.subPackage("text"), - FRAMEWORK.subPackage("time"), - FRAMEWORK.subPackage("tostring"), FRAMEWORK.subPackage("concurrent"), FRAMEWORK.subPackage("doc") ); diff --git a/application/src/test/java/org/opentripplanner/TestOtpModel.java b/application/src/test/java/org/opentripplanner/TestOtpModel.java new file mode 100644 index 00000000000..62b5fce3416 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/TestOtpModel.java @@ -0,0 +1,12 @@ +package org.opentripplanner; + +import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.transit.service.TimetableRepository; + +public record TestOtpModel(Graph graph, TimetableRepository timetableRepository) { + public TestOtpModel index() { + timetableRepository.index(); + graph.index(timetableRepository.getSiteRepository()); + return this; + } +} diff --git a/src/test/java/org/opentripplanner/TestServerContext.java b/application/src/test/java/org/opentripplanner/TestServerContext.java similarity index 75% rename from src/test/java/org/opentripplanner/TestServerContext.java rename to application/src/test/java/org/opentripplanner/TestServerContext.java index 90dca6ff840..ca818a64a58 100644 --- a/src/test/java/org/opentripplanner/TestServerContext.java +++ b/application/src/test/java/org/opentripplanner/TestServerContext.java @@ -11,6 +11,9 @@ import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleService; import org.opentripplanner.service.realtimevehicles.internal.DefaultRealtimeVehicleService; +import org.opentripplanner.service.vehicleparking.VehicleParkingService; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingService; import org.opentripplanner.service.vehiclerental.VehicleRentalService; import org.opentripplanner.service.vehiclerental.internal.DefaultVehicleRentalService; import org.opentripplanner.service.worldenvelope.WorldEnvelopeService; @@ -18,13 +21,15 @@ import org.opentripplanner.service.worldenvelope.internal.DefaultWorldEnvelopeService; import org.opentripplanner.service.worldenvelope.model.WorldEnvelope; import org.opentripplanner.standalone.api.OtpServerRequestContext; +import org.opentripplanner.standalone.config.DebugUiConfig; import org.opentripplanner.standalone.config.RouterConfig; +import org.opentripplanner.standalone.config.routerconfig.RaptorEnvironmentFactory; import org.opentripplanner.standalone.server.DefaultServerRequestContext; import org.opentripplanner.street.model.StreetLimitationParameters; import org.opentripplanner.street.service.DefaultStreetLimitationParametersService; import org.opentripplanner.street.service.StreetLimitationParametersService; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.transit.service.TransitService; public class TestServerContext { @@ -34,31 +39,37 @@ private TestServerContext() {} /** Create a context for unit testing, using the default RouteRequest. */ public static OtpServerRequestContext createServerContext( Graph graph, - TransitModel transitModel + TimetableRepository timetableRepository ) { - transitModel.index(); + timetableRepository.index(); final RouterConfig routerConfig = RouterConfig.DEFAULT; - var transitService = new DefaultTransitService(transitModel); + var transitService = new DefaultTransitService(timetableRepository); DefaultServerRequestContext context = DefaultServerRequestContext.create( routerConfig.transitTuningConfig(), routerConfig.routingRequestDefaults(), - new RaptorConfig<>(routerConfig.transitTuningConfig()), + new RaptorConfig<>( + routerConfig.transitTuningConfig(), + RaptorEnvironmentFactory.create(routerConfig.transitTuningConfig().searchThreadPoolSize()) + ), graph, - new DefaultTransitService(transitModel), + new DefaultTransitService(timetableRepository), Metrics.globalRegistry, routerConfig.vectorTileConfig(), createWorldEnvelopeService(), createRealtimeVehicleService(transitService), createVehicleRentalService(), + createVehicleParkingService(), createEmissionsService(), + null, routerConfig.flexParameters(), List.of(), null, createStreetLimitationParametersService(), null, - null + null, + DebugUiConfig.DEFAULT ); - creatTransitLayerForRaptor(transitModel, routerConfig.transitTuningConfig()); + creatTransitLayerForRaptor(timetableRepository, routerConfig.transitTuningConfig()); return context; } @@ -82,6 +93,10 @@ public static VehicleRentalService createVehicleRentalService() { return new DefaultVehicleRentalService(); } + public static VehicleParkingService createVehicleParkingService() { + return new DefaultVehicleParkingService(new DefaultVehicleParkingRepository()); + } + public static EmissionsService createEmissionsService() { return new DefaultEmissionsService(new EmissionsDataModel()); } diff --git a/src/test/java/org/opentripplanner/_support/arch/ArchComponent.java b/application/src/test/java/org/opentripplanner/_support/arch/ArchComponent.java similarity index 100% rename from src/test/java/org/opentripplanner/_support/arch/ArchComponent.java rename to application/src/test/java/org/opentripplanner/_support/arch/ArchComponent.java diff --git a/src/test/java/org/opentripplanner/_support/arch/Module.java b/application/src/test/java/org/opentripplanner/_support/arch/Module.java similarity index 100% rename from src/test/java/org/opentripplanner/_support/arch/Module.java rename to application/src/test/java/org/opentripplanner/_support/arch/Module.java diff --git a/src/test/java/org/opentripplanner/_support/arch/Package.java b/application/src/test/java/org/opentripplanner/_support/arch/Package.java similarity index 100% rename from src/test/java/org/opentripplanner/_support/arch/Package.java rename to application/src/test/java/org/opentripplanner/_support/arch/Package.java diff --git a/application/src/test/java/org/opentripplanner/_support/asserts/AssertEqualsAndHashCode.java b/application/src/test/java/org/opentripplanner/_support/asserts/AssertEqualsAndHashCode.java new file mode 100644 index 00000000000..7e4fbe91676 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/_support/asserts/AssertEqualsAndHashCode.java @@ -0,0 +1,33 @@ +package org.opentripplanner._support.asserts; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +public class AssertEqualsAndHashCode { + + private final Object subject; + + @SuppressWarnings("EqualsWithItself") + public AssertEqualsAndHashCode(Object subject) { + this.subject = subject; + assertEquals(subject, subject); + } + + public static AssertEqualsAndHashCode verify(Object subject) { + return new AssertEqualsAndHashCode(subject); + } + + public AssertEqualsAndHashCode sameAs(Object same) { + assertEquals(subject, same); + assertEquals(subject.hashCode(), same.hashCode()); + return this; + } + + public AssertEqualsAndHashCode differentFrom(Object... others) { + for (Object other : others) { + assertNotEquals(subject, other); + assertNotEquals(subject.hashCode(), other.hashCode()); + } + return this; + } +} diff --git a/src/test/java/org/opentripplanner/_support/debug/TestDebug.java b/application/src/test/java/org/opentripplanner/_support/debug/TestDebug.java similarity index 100% rename from src/test/java/org/opentripplanner/_support/debug/TestDebug.java rename to application/src/test/java/org/opentripplanner/_support/debug/TestDebug.java diff --git a/src/test/java/org/opentripplanner/_support/geometry/Coordinates.java b/application/src/test/java/org/opentripplanner/_support/geometry/Coordinates.java similarity index 83% rename from src/test/java/org/opentripplanner/_support/geometry/Coordinates.java rename to application/src/test/java/org/opentripplanner/_support/geometry/Coordinates.java index 5a4526012c9..33569a34b2e 100644 --- a/src/test/java/org/opentripplanner/_support/geometry/Coordinates.java +++ b/application/src/test/java/org/opentripplanner/_support/geometry/Coordinates.java @@ -6,6 +6,8 @@ public class Coordinates { public static final Coordinate BERLIN = of(52.5212, 13.4105); public static final Coordinate BERLIN_BRANDENBURG_GATE = of(52.51627, 13.37770); + public static final Coordinate BERLIN_FERNSEHTURM = of(52.52084, 13.40934); + public static final Coordinate BERLIN_ADMIRALBRUCKE = of(52.49526, 13.415093); public static final Coordinate HAMBURG = of(53.5566, 10.0003); public static final Coordinate KONGSBERG_PLATFORM_1 = of(59.67216, 9.65107); public static final Coordinate BOSTON = of(42.36541, -71.06129); diff --git a/src/test/java/org/opentripplanner/_support/geometry/LineStrings.java b/application/src/test/java/org/opentripplanner/_support/geometry/LineStrings.java similarity index 100% rename from src/test/java/org/opentripplanner/_support/geometry/LineStrings.java rename to application/src/test/java/org/opentripplanner/_support/geometry/LineStrings.java diff --git a/src/test/java/org/opentripplanner/_support/geometry/Polygons.java b/application/src/test/java/org/opentripplanner/_support/geometry/Polygons.java similarity index 100% rename from src/test/java/org/opentripplanner/_support/geometry/Polygons.java rename to application/src/test/java/org/opentripplanner/_support/geometry/Polygons.java diff --git a/src/test/java/org/opentripplanner/_support/text/I18NStrings.java b/application/src/test/java/org/opentripplanner/_support/text/I18NStrings.java similarity index 100% rename from src/test/java/org/opentripplanner/_support/text/I18NStrings.java rename to application/src/test/java/org/opentripplanner/_support/text/I18NStrings.java diff --git a/src/test/java/org/opentripplanner/_support/time/ZoneIds.java b/application/src/test/java/org/opentripplanner/_support/time/ZoneIds.java similarity index 100% rename from src/test/java/org/opentripplanner/_support/time/ZoneIds.java rename to application/src/test/java/org/opentripplanner/_support/time/ZoneIds.java diff --git a/src/test/java/org/opentripplanner/api/common/LocationStringParserTest.java b/application/src/test/java/org/opentripplanner/api/common/LocationStringParserTest.java similarity index 100% rename from src/test/java/org/opentripplanner/api/common/LocationStringParserTest.java rename to application/src/test/java/org/opentripplanner/api/common/LocationStringParserTest.java diff --git a/src/test/java/org/opentripplanner/api/resource/MessageTest.java b/application/src/test/java/org/opentripplanner/api/resource/MessageTest.java similarity index 100% rename from src/test/java/org/opentripplanner/api/resource/MessageTest.java rename to application/src/test/java/org/opentripplanner/api/resource/MessageTest.java diff --git a/src/test/java/org/opentripplanner/api/resource/WebMercatorTileTest.java b/application/src/test/java/org/opentripplanner/api/resource/WebMercatorTileTest.java similarity index 100% rename from src/test/java/org/opentripplanner/api/resource/WebMercatorTileTest.java rename to application/src/test/java/org/opentripplanner/api/resource/WebMercatorTileTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/CoordinateValueScalarTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/CoordinateValueScalarTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/CoordinateValueScalarTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/CoordinateValueScalarTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/CostScalarTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/CostScalarTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/CostScalarTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/CostScalarTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/DurationScalarTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/DurationScalarTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/DurationScalarTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/DurationScalarTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/GeoJsonScalarTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/GeoJsonScalarTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/GeoJsonScalarTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/GeoJsonScalarTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/GraphQLFormattingTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLFormattingTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/GraphQLFormattingTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLFormattingTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIndexTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIndexTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/GraphQLIndexTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIndexTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java similarity index 84% rename from src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java index 79590ca2775..12e68c2d453 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java @@ -11,7 +11,7 @@ import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; import static org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle.StopStatus.IN_TRANSIT_TO; import static org.opentripplanner.test.support.JsonAssertions.assertEqualJson; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import static org.opentripplanner.transit.model.basic.TransitMode.BUS; import static org.opentripplanner.transit.model.basic.TransitMode.FERRY; import static org.opentripplanner.transit.model.timetable.OccupancyStatus.FEW_SEATS_AVAILABLE; @@ -28,8 +28,8 @@ import java.util.Comparator; import java.util.List; import java.util.Locale; +import java.util.Set; import java.util.stream.Stream; -import javax.annotation.Nonnull; import org.glassfish.jersey.message.internal.OutboundJaxrsResponse; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; @@ -38,7 +38,6 @@ import org.opentripplanner._support.time.ZoneIds; import org.opentripplanner.ext.fares.FaresToItineraryMapper; import org.opentripplanner.ext.fares.impl.DefaultFareService; -import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; @@ -69,9 +68,12 @@ import org.opentripplanner.routing.graphfinder.PlaceType; import org.opentripplanner.routing.impl.TransitAlertServiceImpl; import org.opentripplanner.routing.services.TransitAlertService; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; import org.opentripplanner.service.realtimevehicles.internal.DefaultRealtimeVehicleService; import org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingService; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; import org.opentripplanner.service.vehiclerental.internal.DefaultVehicleRentalService; import org.opentripplanner.service.vehiclerental.model.TestFreeFloatingRentalVehicleBuilder; import org.opentripplanner.service.vehiclerental.model.TestVehicleRentalStationBuilder; @@ -79,13 +81,14 @@ import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle; import org.opentripplanner.standalone.config.framework.json.JsonSupport; import org.opentripplanner.test.support.FilePatternSource; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.AbstractBuilder; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.BikeAccess; +import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.RegularStop; @@ -93,13 +96,14 @@ import org.opentripplanner.transit.model.timetable.RealTimeTripTimes; import org.opentripplanner.transit.model.timetable.TripTimesFactory; import org.opentripplanner.transit.service.DefaultTransitService; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.transit.service.TransitEditorService; -import org.opentripplanner.transit.service.TransitModel; import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.utils.collection.ListUtils; class GraphQLIntegrationTest { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final Place A = TEST_MODEL.place("A", 5.0, 8.0); private static final Place B = TEST_MODEL.place("B", 6.0, 8.5); @@ -114,8 +118,9 @@ class GraphQLIntegrationTest { .of(A, B, C, D, E, F, G, H) .map(p -> (RegularStop) p.stop) .toList(); + private static final Route ROUTE = TimetableRepositoryForTest.route("a-route").build(); - private static VehicleRentalStation VEHICLE_RENTAL_STATION = new TestVehicleRentalStationBuilder() + private static final VehicleRentalStation VEHICLE_RENTAL_STATION = new TestVehicleRentalStationBuilder() .withVehicles(10) .withSpaces(10) .withVehicleTypeBicycle(5, 7) @@ -123,7 +128,7 @@ class GraphQLIntegrationTest { .withSystem("Network-1", "https://foo.bar") .build(); - private static VehicleRentalVehicle RENTAL_VEHICLE = new TestFreeFloatingRentalVehicleBuilder() + private static final VehicleRentalVehicle RENTAL_VEHICLE = new TestFreeFloatingRentalVehicleBuilder() .withSystem("Network-1", "https://foo.bar") .build(); @@ -138,39 +143,43 @@ class GraphQLIntegrationTest { private static GraphQLRequestContext context; private static final Deduplicator DEDUPLICATOR = new Deduplicator(); + private static final VehicleParkingRepository parkingRepository = new DefaultVehicleParkingRepository(); @BeforeAll static void setup() { - GRAPH - .getVehicleParkingService() - .updateVehicleParking( - List.of( - VehicleParking - .builder() - .id(id("parking-1")) - .coordinate(WgsCoordinate.GREENWICH) - .name(NonLocalizedString.ofNullable("parking")) - .build() - ), - List.of() - ); + parkingRepository.updateVehicleParking( + List.of( + VehicleParking + .builder() + .id(id("parking-1")) + .coordinate(WgsCoordinate.GREENWICH) + .name(NonLocalizedString.ofNullable("parking")) + .build() + ), + List.of() + ); - var stopModel = TEST_MODEL.stopModelBuilder(); - STOP_LOCATIONS.forEach(stopModel::withRegularStop); - var model = stopModel.build(); - var transitModel = new TransitModel(model, DEDUPLICATOR); + var siteRepository = TEST_MODEL.siteRepositoryBuilder(); + STOP_LOCATIONS.forEach(siteRepository::withRegularStop); + var model = siteRepository.build(); + var timetableRepository = new TimetableRepository(model, DEDUPLICATOR); - final TripPattern pattern = TEST_MODEL.pattern(BUS).build(); - var trip = TransitModelForTest.trip("123").withHeadsign(I18NString.of("Trip Headsign")).build(); - var stopTimes = TEST_MODEL.stopTimesEvery5Minutes(3, trip, T11_00); + var trip = TimetableRepositoryForTest + .trip("123") + .withHeadsign(I18NString.of("Trip Headsign")) + .build(); + var stopTimes = TEST_MODEL.stopTimesEvery5Minutes(3, trip, "11:00"); var tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, DEDUPLICATOR); - pattern.add(tripTimes); + final TripPattern pattern = TEST_MODEL + .pattern(BUS) + .withScheduledTimeTableBuilder(builder -> builder.addTripTimes(tripTimes)) + .build(); - transitModel.addTripPattern(id("pattern-1"), pattern); + timetableRepository.addTripPattern(id("pattern-1"), pattern); var feedId = "testfeed"; var feedInfo = FeedInfo.dummyForTest(feedId); - transitModel.addFeedInfo(feedInfo); + timetableRepository.addFeedInfo(feedInfo); var agency = Agency .of(new FeedScopedId(feedId, "agency-xx")) @@ -178,15 +187,15 @@ static void setup() { .withUrl("www.otp-foo.bar") .withTimezone("Europe/Berlin") .build(); - transitModel.addAgency(agency); + timetableRepository.addAgency(agency); - transitModel.initTimeZone(ZoneIds.BERLIN); - transitModel.index(); + timetableRepository.initTimeZone(ZoneIds.BERLIN); + timetableRepository.index(); var routes = Arrays .stream(TransitMode.values()) .sorted(Comparator.comparing(Enum::name)) .map(m -> - TransitModelForTest + TimetableRepositoryForTest .route(m.name()) .withMode(m) .withLongName(I18NString.of("Long name for %s".formatted(m))) @@ -197,11 +206,13 @@ static void setup() { .toList(); var busRoute = routes.stream().filter(r -> r.getMode().equals(BUS)).findFirst().get(); - TransitEditorService transitService = new DefaultTransitService(transitModel) { - private final TransitAlertService alertService = new TransitAlertServiceImpl(transitModel); + TransitEditorService transitService = new DefaultTransitService(timetableRepository) { + private final TransitAlertService alertService = new TransitAlertServiceImpl( + timetableRepository + ); @Override - public List getModesOfStopLocation(StopLocation stop) { + public List findTransitModes(StopLocation stop) { return List.of(BUS, FERRY); } @@ -209,6 +220,11 @@ public List getModesOfStopLocation(StopLocation stop) { public TransitAlertService getTransitAlertService() { return alertService; } + + @Override + public Set findRoutes(StopLocation stop) { + return Set.of(ROUTE); + } }; routes.forEach(transitService::addRoutes); @@ -301,8 +317,8 @@ public TransitAlertService getTransitAlertService() { new TestRoutingService(List.of(i1)), transitService, new DefaultFareService(), - GRAPH.getVehicleParkingService(), defaultVehicleRentalService, + new DefaultVehicleParkingService(parkingRepository), realtimeVehicleService, finder, new RouteRequest() @@ -342,7 +358,9 @@ private static void add10MinuteDelay(Itinerary i1) { }); } - @FilePatternSource(pattern = "src/test/resources/org/opentripplanner/apis/gtfs/queries/*.graphql") + @FilePatternSource( + pattern = "application/src/test/resources/org/opentripplanner/apis/gtfs/queries/*.graphql" + ) @ParameterizedTest(name = "Check GraphQL query in {0}") void graphQL(Path path) throws IOException { var query = Files.readString(path); @@ -375,7 +393,6 @@ void graphQL(Path path) throws IOException { assertEqualJson(expectedJson, actualJson); } - @Nonnull private static List getTransitAlert(EntitySelector.Stop entitySelector) { var alertWithoutDescription = TransitAlert .of(id("no-description")) @@ -396,7 +413,6 @@ private static List getTransitAlert(EntitySelector.Stop entitySele .toList(); } - @Nonnull private static WalkStepBuilder walkStep(String name) { return WalkStep .builder() @@ -405,7 +421,6 @@ private static WalkStepBuilder walkStep(String name) { .withAngle(10); } - @Nonnull private static FareProduct fareProduct(String name) { return new FareProduct( id(name), @@ -421,7 +436,6 @@ private static FareProduct fareProduct(String name) { * Locate 'expectations' relative to the given query input file. The 'expectations' and 'queries' * subdirectories are expected to be in the same directory. */ - @Nonnull private static Path getExpectation(Path path) { return path .getParent() @@ -459,7 +473,7 @@ public List findClosestPlaces( List filterByNetwork, TransitService transitService ) { - var stop = TransitModelForTest.of().stop("A").build(); + var stop = TimetableRepositoryForTest.of().stop("A").build(); return List.of( new PlaceAtDistance(stop, 0), new PlaceAtDistance(VEHICLE_RENTAL_STATION, 30), diff --git a/src/test/java/org/opentripplanner/apis/gtfs/OffsetDateTimeScalarTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/OffsetDateTimeScalarTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/OffsetDateTimeScalarTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/OffsetDateTimeScalarTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/RatioScalarTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/RatioScalarTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/RatioScalarTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/RatioScalarTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/ReluctanceScalarTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/ReluctanceScalarTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/ReluctanceScalarTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/ReluctanceScalarTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/TestRoutingService.java b/application/src/test/java/org/opentripplanner/apis/gtfs/TestRoutingService.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/TestRoutingService.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/TestRoutingService.java diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/datafetchers/BookingInfoImplTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/datafetchers/BookingInfoImplTest.java new file mode 100644 index 00000000000..1103024aa61 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/datafetchers/BookingInfoImplTest.java @@ -0,0 +1,48 @@ +package org.opentripplanner.apis.gtfs.datafetchers; + +import static graphql.execution.ExecutionContextBuilder.newExecutionContextBuilder; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import graphql.execution.ExecutionId; +import graphql.schema.DataFetchingEnvironment; +import graphql.schema.DataFetchingEnvironmentImpl; +import java.time.Duration; +import org.junit.jupiter.api.Test; +import org.opentripplanner.transit.model.timetable.booking.BookingInfo; + +class BookingInfoImplTest { + + private static final BookingInfoImpl SUBJECT = new BookingInfoImpl(); + private static final Duration TEN_MINUTES = Duration.ofMinutes(10); + + @Test + void emptyDurations() throws Exception { + var env = dataFetchingEnvironment(BookingInfo.of().build()); + assertNull(SUBJECT.minimumBookingNoticeSeconds().get(env)); + assertNull(SUBJECT.maximumBookingNoticeSeconds().get(env)); + } + + @Test + void durations() throws Exception { + var env = dataFetchingEnvironment( + BookingInfo + .of() + .withMinimumBookingNotice(TEN_MINUTES) + .withMaximumBookingNotice(TEN_MINUTES) + .build() + ); + assertEquals(600, SUBJECT.minimumBookingNoticeSeconds().get(env)); + assertEquals(600, SUBJECT.maximumBookingNoticeSeconds().get(env)); + } + + private DataFetchingEnvironment dataFetchingEnvironment(BookingInfo bookingInfo) { + var executionContext = newExecutionContextBuilder() + .executionId(ExecutionId.from(this.getClass().getName())) + .build(); + return DataFetchingEnvironmentImpl + .newDataFetchingEnvironment(executionContext) + .source(bookingInfo) + .build(); + } +} diff --git a/src/test/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImplTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImplTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImplTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImplTest.java diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/BikesAllowedMapperTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/BikesAllowedMapperTest.java new file mode 100644 index 00000000000..035d3605a21 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/BikesAllowedMapperTest.java @@ -0,0 +1,17 @@ +package org.opentripplanner.apis.gtfs.mapping; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLBikesAllowed; +import org.opentripplanner.transit.model.network.BikeAccess; + +class BikesAllowedMapperTest { + + @Test + void mapping() { + assertEquals(GraphQLBikesAllowed.NO_INFORMATION, BikesAllowedMapper.map(BikeAccess.UNKNOWN)); + assertEquals(GraphQLBikesAllowed.NOT_ALLOWED, BikesAllowedMapper.map(BikeAccess.NOT_ALLOWED)); + assertEquals(GraphQLBikesAllowed.ALLOWED, BikesAllowedMapper.map(BikeAccess.ALLOWED)); + } +} diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapperTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapperTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapperTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/LocalDateRangeMapperTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/LocalDateRangeMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/mapping/LocalDateRangeMapperTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/mapping/LocalDateRangeMapperTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapperTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapperTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapperTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapperTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapperTest.java similarity index 85% rename from src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapperTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapperTest.java index f2992a30d92..43dd10dbdce 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapperTest.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/LegacyRouteRequestMapperTest.java @@ -35,10 +35,14 @@ import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.graphfinder.GraphFinder; import org.opentripplanner.service.realtimevehicles.internal.DefaultRealtimeVehicleService; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingService; import org.opentripplanner.service.vehiclerental.internal.DefaultVehicleRentalService; import org.opentripplanner.street.search.TraverseMode; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; class LegacyRouteRequestMapperTest implements PlanTestConstants { @@ -46,16 +50,20 @@ class LegacyRouteRequestMapperTest implements PlanTestConstants { static { Graph graph = new Graph(); - var transitModel = new TransitModel(); - transitModel.initTimeZone(ZoneIds.BERLIN); - final DefaultTransitService transitService = new DefaultTransitService(transitModel); + var testModel = TimetableRepositoryForTest.of(); + var stopModelBuilder = testModel + .siteRepositoryBuilder() + .withRegularStop(testModel.stop("stop1").build()); + var timetableRepository = new TimetableRepository(stopModelBuilder.build(), new Deduplicator()); + timetableRepository.initTimeZone(ZoneIds.BERLIN); + final DefaultTransitService transitService = new DefaultTransitService(timetableRepository); context = new GraphQLRequestContext( new TestRoutingService(List.of()), transitService, new DefaultFareService(), - graph.getVehicleParkingService(), new DefaultVehicleRentalService(), + new DefaultVehicleParkingService(new DefaultVehicleParkingRepository()), new DefaultRealtimeVehicleService(transitService), GraphFinder.getInstance(graph, transitService::findRegularStops), new RouteRequest() @@ -135,11 +143,15 @@ static Stream transportModesCases() { of(List.of(mode("BICYCLE")), "[ExcludeAllTransitFilter{}]"), of( List.of(mode("BUS")), + "[TransitFilterRequest{select: [SelectRequest{transportModes: [BUS]}]}]" + ), + of( + List.of(mode("BUS"), mode("COACH")), "[TransitFilterRequest{select: [SelectRequest{transportModes: [BUS, COACH]}]}]" ), of( List.of(mode("BUS"), mode("MONORAIL")), - "[TransitFilterRequest{select: [SelectRequest{transportModes: [BUS, COACH, MONORAIL]}]}]" + "[TransitFilterRequest{select: [SelectRequest{transportModes: [BUS, MONORAIL]}]}]" ) ); } @@ -242,7 +254,7 @@ void walkReluctance() { @Test void transferSlack() { - var seconds = 119L; + var seconds = 119; Map arguments = Map.of("minTransferTime", seconds); var routeRequest = LegacyRouteRequestMapper.toRouteRequest( @@ -255,6 +267,28 @@ void transferSlack() { assertEquals(TransferPreferences.DEFAULT.slack(), noParamsReq.preferences().transfer().slack()); } + @Test + void via() { + Map arguments = Map.of( + "via", + List.of( + Map.of("passThrough", Map.of("stopLocationIds", List.of("F:stop1"), "label", "a label")) + ) + ); + + var routeRequest = LegacyRouteRequestMapper.toRouteRequest( + executionContext(arguments), + context + ); + assertEquals( + "[PassThroughViaLocation{label: a label, stopLocationIds: [F:stop1]}]", + routeRequest.getViaLocations().toString() + ); + + var noParamsReq = LegacyRouteRequestMapper.toRouteRequest(executionContext(Map.of()), context); + assertEquals(List.of(), noParamsReq.getViaLocations()); + } + private DataFetchingEnvironment executionContext(Map arguments) { ExecutionInput executionInput = ExecutionInput .newExecutionInput() diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperAccessibilityTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperAccessibilityTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperAccessibilityTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperAccessibilityTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperBicycleTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperBicycleTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperBicycleTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperBicycleTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperCarTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperCarTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperCarTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperCarTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperModesTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperModesTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperModesTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperModesTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperScooterTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperScooterTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperScooterTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperScooterTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperTest.java similarity index 91% rename from src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperTest.java index f47f7a7004a..34cb865c81a 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperTest.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperTest.java @@ -31,10 +31,12 @@ import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.graphfinder.GraphFinder; import org.opentripplanner.service.realtimevehicles.internal.DefaultRealtimeVehicleService; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingService; import org.opentripplanner.service.vehiclerental.internal.DefaultVehicleRentalService; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; class RouteRequestMapperTest { @@ -62,16 +64,16 @@ class RouteRequestMapperTest { static { Graph graph = new Graph(); - var transitModel = new TransitModel(); - transitModel.initTimeZone(ZoneIds.BERLIN); - final DefaultTransitService transitService = new DefaultTransitService(transitModel); + var timetableRepository = new TimetableRepository(); + timetableRepository.initTimeZone(ZoneIds.BERLIN); + final DefaultTransitService transitService = new DefaultTransitService(timetableRepository); CONTEXT = new GraphQLRequestContext( new TestRoutingService(List.of()), transitService, new DefaultFareService(), - graph.getVehicleParkingService(), new DefaultVehicleRentalService(), + new DefaultVehicleParkingService(new DefaultVehicleParkingRepository()), new DefaultRealtimeVehicleService(transitService), GraphFinder.getInstance(graph, transitService::findRegularStops), new RouteRequest() @@ -288,6 +290,32 @@ void testItineraryFilters() { assertEquals(multiplier, itinFilter.groupedOtherThanSameLegsMaxCostMultiplier()); } + @Test + void via() { + Map arguments = createArgsCopy(ARGS); + arguments.put( + "via", + List.of( + Map.of("passThrough", Map.of("stopLocationIds", List.of("F:stop1"), "label", "a label")) + ) + ); + + var routeRequest = RouteRequestMapper.toRouteRequest( + executionContext(arguments, LOCALE, CONTEXT), + CONTEXT + ); + assertEquals( + "[PassThroughViaLocation{label: a label, stopLocationIds: [F:stop1]}]", + routeRequest.getViaLocations().toString() + ); + + var noParamsReq = RouteRequestMapper.toRouteRequest( + executionContext(ARGS, LOCALE, CONTEXT), + CONTEXT + ); + assertEquals(List.of(), noParamsReq.getViaLocations()); + } + static Map createArgsCopy(Map arguments) { Map newArgs = new HashMap<>(); newArgs.putAll(arguments); diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperTransitTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperTransitTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperTransitTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperTransitTest.java diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperWalkTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperWalkTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperWalkTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/RouteRequestMapperWalkTest.java diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ViaLocationMapperTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ViaLocationMapperTest.java new file mode 100644 index 00000000000..a3eb74a5d43 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/routerequest/ViaLocationMapperTest.java @@ -0,0 +1,103 @@ +package org.opentripplanner.apis.gtfs.mapping.routerequest; + +import static java.util.Map.entry; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.apis.gtfs.mapping.routerequest.ViaLocationMapper.FIELD_LABEL; +import static org.opentripplanner.apis.gtfs.mapping.routerequest.ViaLocationMapper.FIELD_MINIMUM_WAIT_TIME; +import static org.opentripplanner.apis.gtfs.mapping.routerequest.ViaLocationMapper.FIELD_PASS_THROUGH; +import static org.opentripplanner.apis.gtfs.mapping.routerequest.ViaLocationMapper.FIELD_STOP_LOCATION_IDS; +import static org.opentripplanner.apis.gtfs.mapping.routerequest.ViaLocationMapper.FIELD_VISIT; +import static org.opentripplanner.apis.gtfs.mapping.routerequest.ViaLocationMapper.mapToViaLocations; + +import java.time.Duration; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class ViaLocationMapperTest { + + public static final String LABEL = "TestLabel"; + public static final Duration MIN_WAIT_TIME = Duration.ofMinutes(5); + public static final List LIST_IDS_INPUT = List.of("F:ID1", "F:ID2"); + public static final String EXPECTED_IDS_AS_STRING = "[F:ID1, F:ID2]"; + + @Test + void mapToVisitViaLocations() { + Map> args = Map.of( + FIELD_VISIT, + Map.ofEntries( + entry(FIELD_LABEL, LABEL), + entry(FIELD_MINIMUM_WAIT_TIME, MIN_WAIT_TIME), + entry(FIELD_STOP_LOCATION_IDS, LIST_IDS_INPUT) + ) + ); + + var inputs = List.of(args); + var result = mapToViaLocations(inputs); + + var via = result.getFirst(); + + assertEquals(LABEL, via.label()); + assertEquals(MIN_WAIT_TIME, via.minimumWaitTime()); + assertEquals(EXPECTED_IDS_AS_STRING, via.stopLocationIds().toString()); + assertFalse(via.isPassThroughLocation()); + assertEquals( + "[VisitViaLocation{label: TestLabel, minimumWaitTime: 5m, stopLocationIds: [F:ID1, F:ID2], coordinates: []}]", + result.toString() + ); + } + + @Test + void mapToVisitViaLocationsWithBareMinimum() { + Map> args = Map.of( + FIELD_VISIT, + Map.of(FIELD_STOP_LOCATION_IDS, List.of("F:1")) + ); + var inputs = List.of(args); + var result = mapToViaLocations(inputs); + + var via = result.getFirst(); + + assertNull(via.label()); + assertEquals(Duration.ZERO, via.minimumWaitTime()); + assertEquals("[F:1]", via.stopLocationIds().toString()); + assertFalse(via.isPassThroughLocation()); + } + + @Test + void mapToPassThrough() { + final Map> args = Map.of( + FIELD_PASS_THROUGH, + Map.ofEntries(entry(FIELD_LABEL, LABEL), entry(FIELD_STOP_LOCATION_IDS, LIST_IDS_INPUT)) + ); + var inputs = List.of(args); + var result = mapToViaLocations(inputs); + var via = result.getFirst(); + + assertEquals(LABEL, via.label()); + assertEquals(EXPECTED_IDS_AS_STRING, via.stopLocationIds().toString()); + assertTrue(via.isPassThroughLocation()); + assertEquals( + "PassThroughViaLocation{label: TestLabel, stopLocationIds: [F:ID1, F:ID2]}", + via.toString() + ); + } + + @Test + void mapToPassThroughWithBareMinimum() { + Map> args = Map.of( + FIELD_PASS_THROUGH, + Map.of(FIELD_STOP_LOCATION_IDS, List.of("F:1")) + ); + var inputs = List.of(args); + var result = mapToViaLocations(inputs); + var via = result.getFirst(); + + assertNull(via.label()); + assertEquals("[F:1]", via.stopLocationIds().toString()); + assertTrue(via.isPassThroughLocation()); + } +} diff --git a/src/test/java/org/opentripplanner/apis/gtfs/model/LocalDateRangeTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/model/LocalDateRangeTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/gtfs/model/LocalDateRangeTest.java rename to application/src/test/java/org/opentripplanner/apis/gtfs/model/LocalDateRangeTest.java diff --git a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java b/application/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/support/TileJsonTest.java rename to application/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java diff --git a/src/test/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchemaTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchemaTest.java similarity index 80% rename from src/test/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchemaTest.java rename to application/src/test/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchemaTest.java index d762d784d3f..4cdb0586aa7 100644 --- a/src/test/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchemaTest.java +++ b/application/src/test/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchemaTest.java @@ -9,7 +9,7 @@ import java.io.File; import org.junit.jupiter.api.Test; import org.opentripplanner._support.time.ZoneIds; -import org.opentripplanner.apis.transmodel.support.GqlUtil; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitTuningParameters; import org.opentripplanner.routing.api.request.RouteRequest; class TransmodelGraphQLSchemaTest { @@ -20,8 +20,11 @@ class TransmodelGraphQLSchemaTest { @Test void testSchemaBuild() { - GqlUtil gqlUtil = new GqlUtil(ZoneIds.OSLO); - var schema = TransmodelGraphQLSchema.create(new RouteRequest(), gqlUtil); + var schema = TransmodelGraphQLSchema.create( + new RouteRequest(), + ZoneIds.OSLO, + TransitTuningParameters.FOR_TEST + ); assertNotNull(schema); String original = readFile(SCHEMA_FILE); diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapperTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapperTest.java rename to application/src/test/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapperTest.java diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/TransitIdMapperTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TransitIdMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/transmodel/mapping/TransitIdMapperTest.java rename to application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TransitIdMapperTest.java diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java similarity index 88% rename from src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java rename to application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java index ab7e2b62b7c..dc96a094812 100644 --- a/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java +++ b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java @@ -5,8 +5,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.opentripplanner.framework.time.TimeUtils.time; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; +import static org.opentripplanner.utils.time.TimeUtils.time; import graphql.ExecutionInput; import graphql.execution.ExecutionId; @@ -39,40 +39,43 @@ import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.model.plan.ScheduledTransitLeg; import org.opentripplanner.raptor.configure.RaptorConfig; -import org.opentripplanner.routing.api.request.PassThroughPoint; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.api.request.preference.StreetPreferences; import org.opentripplanner.routing.api.request.preference.TimeSlopeSafetyTriangle; +import org.opentripplanner.routing.api.request.via.ViaLocation; import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.service.realtimevehicles.internal.DefaultRealtimeVehicleService; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingService; import org.opentripplanner.service.vehiclerental.internal.DefaultVehicleRentalService; import org.opentripplanner.service.worldenvelope.internal.DefaultWorldEnvelopeRepository; import org.opentripplanner.service.worldenvelope.internal.DefaultWorldEnvelopeService; +import org.opentripplanner.standalone.config.DebugUiConfig; import org.opentripplanner.standalone.config.RouterConfig; import org.opentripplanner.standalone.server.DefaultServerRequestContext; import org.opentripplanner.street.model.StreetLimitationParameters; import org.opentripplanner.street.service.DefaultStreetLimitationParametersService; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; public class TripRequestMapperTest implements PlanTestConstants { - private static TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final Duration MAX_FLEXIBLE = Duration.ofMinutes(20); private static final Function STOP_TO_ID = s -> s.getId().toString(); - private static final Route route1 = TransitModelForTest.route("route1").build(); - private static final Route route2 = TransitModelForTest.route("route2").build(); + private static final Route route1 = TimetableRepositoryForTest.route("route1").build(); + private static final Route route2 = TimetableRepositoryForTest.route("route2").build(); private static final RegularStop stop1 = TEST_MODEL.stop("ST:stop1", 1, 1).build(); private static final RegularStop stop2 = TEST_MODEL.stop("ST:stop2", 2, 1).build(); @@ -89,27 +92,31 @@ public class TripRequestMapperTest implements PlanTestConstants { .bus(route2, 2, time("11:20"), time("11:40"), Place.forStop(stop3)) .build(); var patterns = itineraryPatterns(itinerary); - var stopModel = TEST_MODEL - .stopModelBuilder() + var siteRepository = TEST_MODEL + .siteRepositoryBuilder() .withRegularStop(stop1) .withRegularStop(stop2) .withRegularStop(stop3) .build(); - var transitModel = new TransitModel(stopModel, new Deduplicator()); - transitModel.initTimeZone(ZoneIds.STOCKHOLM); + var timetableRepository = new TimetableRepository(siteRepository, new Deduplicator()); + timetableRepository.initTimeZone(ZoneIds.STOCKHOLM); var calendarServiceData = new CalendarServiceData(); LocalDate serviceDate = itinerary.startTime().toLocalDate(); patterns.forEach(pattern -> { - transitModel.addTripPattern(pattern.getId(), pattern); + timetableRepository.addTripPattern(pattern.getId(), pattern); final int serviceCode = pattern.getScheduledTimetable().getTripTimes(0).getServiceCode(); - transitModel.getServiceCodes().put(pattern.getId(), serviceCode); + timetableRepository.getServiceCodes().put(pattern.getId(), serviceCode); calendarServiceData.putServiceDatesForServiceId(pattern.getId(), List.of(serviceDate)); }); - transitModel.updateCalendarServiceData(true, calendarServiceData, DataImportIssueStore.NOOP); - transitModel.index(); - transitService = new DefaultTransitService(transitModel); + timetableRepository.updateCalendarServiceData( + true, + calendarServiceData, + DataImportIssueStore.NOOP + ); + timetableRepository.index(); + transitService = new DefaultTransitService(timetableRepository); } @BeforeEach @@ -140,13 +147,16 @@ void setup() { new DefaultWorldEnvelopeService(new DefaultWorldEnvelopeRepository()), new DefaultRealtimeVehicleService(transitService), new DefaultVehicleRentalService(), + new DefaultVehicleParkingService(new DefaultVehicleParkingRepository()), new DefaultEmissionsService(new EmissionsDataModel()), + null, RouterConfig.DEFAULT.flexParameters(), List.of(), null, new DefaultStreetLimitationParametersService(new StreetLimitationParameters()), null, - null + null, + DebugUiConfig.DEFAULT ), null, transitService @@ -311,39 +321,29 @@ public void testBikeTriangleFactorsHasNoEffect(VehicleRoutingOptimizeType bot) { } @Test - void testPassThroughPoints() { + void testViaLocations() { TransitIdMapper.clearFixedFeedId(); - final List PTP1 = List.of(stop1, stop2, stop3).stream().map(STOP_TO_ID).toList(); - final List PTP2 = List.of(stop2, stop3, stop1).stream().map(STOP_TO_ID).toList(); + final List PTP1 = Stream.of(stop1, stop2, stop3).map(STOP_TO_ID).toList(); + final List PTP2 = Stream.of(stop3, stop2).map(STOP_TO_ID).toList(); final Map arguments = Map.of( "passThroughPoints", List.of(Map.of("name", "PTP1", "placeIds", PTP1), Map.of("placeIds", PTP2, "name", "PTP2")) ); - final List points = TripRequestMapper + final List viaLocations = TripRequestMapper .createRequest(executionContext(arguments)) - .getPassThroughPoints(); - assertEquals(PTP1, points.get(0).stopLocations().stream().map(STOP_TO_ID).toList()); - assertEquals("PTP1", points.get(0).name()); - assertEquals(PTP2, points.get(1).stopLocations().stream().map(STOP_TO_ID).toList()); - assertEquals("PTP2", points.get(1).name()); - } - - @Test - void testPassThroughPointsNoMatch() { - TransitIdMapper.clearFixedFeedId(); - - final Map arguments = Map.of( - "passThroughPoints", - List.of(Map.of("placeIds", List.of("F:XX:NonExisting"))) + .getViaLocations(); + assertEquals( + "PassThroughViaLocation{label: PTP1, stopLocationIds: [F:ST:stop1, F:ST:stop2, F:ST:stop3]}", + viaLocations.get(0).toString() ); - - final RuntimeException ex = assertThrows( - RuntimeException.class, - () -> TripRequestMapper.createRequest(executionContext(arguments)) + assertEquals("PTP1", viaLocations.get(0).label()); + assertEquals( + "PassThroughViaLocation{label: PTP2, stopLocationIds: [F:ST:stop3, F:ST:stop2]}", + viaLocations.get(1).toString() ); - assertEquals("No match for F:XX:NonExisting.", ex.getMessage()); + assertEquals("PTP2", viaLocations.get(1).label()); } @Test diff --git a/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripViaLocationMapperTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripViaLocationMapperTest.java new file mode 100644 index 00000000000..4e6cf067fb8 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripViaLocationMapperTest.java @@ -0,0 +1,244 @@ +package org.opentripplanner.apis.transmodel.mapping; + +import static java.util.Map.entry; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.apis.transmodel.model.plan.ViaLocationInputType.FIELD_LABEL; +import static org.opentripplanner.apis.transmodel.model.plan.ViaLocationInputType.FIELD_MINIMUM_WAIT_TIME; +import static org.opentripplanner.apis.transmodel.model.plan.ViaLocationInputType.FIELD_PASS_THROUGH; +import static org.opentripplanner.apis.transmodel.model.plan.ViaLocationInputType.FIELD_STOP_LOCATION_IDS; +import static org.opentripplanner.apis.transmodel.model.plan.ViaLocationInputType.FIELD_VISIT; + +import java.time.Duration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class TripViaLocationMapperTest { + + private static final String LABEL = "TestLabel"; + private static final Duration MIN_WAIT_TIME = Duration.ofMinutes(5); + private static final List LIST_IDS_INPUT = List.of("F:ID1", "F:ID2"); + private static final String EXPECTED_IDS_AS_STRING = "[F:ID1, F:ID2]"; + private static final String REASON_EMPTY_IDS_ALLOWED_PASS_THROUGH = + """ + Unfortunately the 'placeIds' is not required. Making it required would be a breaking change, + so wee just ignore it." + """; + + @BeforeEach + void setup() { + TransitIdMapper.clearFixedFeedId(); + } + + @Test + void testMapToVisitViaLocations() { + Map input = Map.ofEntries( + entry(FIELD_VISIT, visitInput(LABEL, MIN_WAIT_TIME, LIST_IDS_INPUT)) + ); + var result = TripViaLocationMapper.mapToViaLocations(List.of(input)); + + var via = result.getFirst(); + + assertEquals(LABEL, via.label()); + assertEquals(MIN_WAIT_TIME, via.minimumWaitTime()); + assertEquals(EXPECTED_IDS_AS_STRING, via.stopLocationIds().toString()); + assertFalse(via.isPassThroughLocation()); + assertEquals( + "[VisitViaLocation{label: TestLabel, minimumWaitTime: 5m, stopLocationIds: [F:ID1, F:ID2], coordinates: []}]", + result.toString() + ); + } + + @Test + void testMapToVisitViaLocationsWithBareMinimum() { + Map input = mapOf(FIELD_VISIT, mapOf(FIELD_STOP_LOCATION_IDS, List.of("F:1"))); + var result = TripViaLocationMapper.mapToViaLocations(List.of(input)); + + var via = result.getFirst(); + + assertNull(via.label()); + assertEquals(Duration.ZERO, via.minimumWaitTime()); + assertEquals("[F:1]", via.stopLocationIds().toString()); + assertFalse(via.isPassThroughLocation()); + } + + @Test + void testMapToVisitViaLocationsWithoutIds() { + Map input = mapOf(FIELD_VISIT, mapOf(FIELD_STOP_LOCATION_IDS, null)); + var ex = assertThrows( + IllegalArgumentException.class, + () -> TripViaLocationMapper.mapToViaLocations(List.of(input)) + ); + assertEquals("'stopLocationIds' is not set!", ex.getMessage()); + } + + @Test + void testMapToVisitViaLocationsWithAnEmptyListOfIds() { + Map input = mapOf(FIELD_VISIT, mapOf(FIELD_STOP_LOCATION_IDS, List.of())); + var ex = assertThrows( + IllegalArgumentException.class, + () -> TripViaLocationMapper.mapToViaLocations(List.of(input)) + ); + assertEquals( + "A via location must have at least one stop location or a coordinate.", + ex.getMessage() + ); + } + + @Test + void tetMapToPassThrough() { + Map input = mapOf(FIELD_PASS_THROUGH, passThroughInput(LABEL, LIST_IDS_INPUT)); + var result = TripViaLocationMapper.mapToViaLocations(List.of(input)); + var via = result.getFirst(); + + assertEquals(LABEL, via.label()); + assertEquals(EXPECTED_IDS_AS_STRING, via.stopLocationIds().toString()); + assertTrue(via.isPassThroughLocation()); + assertEquals( + "PassThroughViaLocation{label: TestLabel, stopLocationIds: [F:ID1, F:ID2]}", + via.toString() + ); + } + + @Test + void tetMapToPassThroughWithBareMinimum() { + Map input = mapOf( + FIELD_PASS_THROUGH, + mapOf(FIELD_STOP_LOCATION_IDS, List.of("F:1")) + ); + var result = TripViaLocationMapper.mapToViaLocations(List.of(input)); + var via = result.getFirst(); + + assertNull(via.label()); + assertEquals("[F:1]", via.stopLocationIds().toString()); + assertTrue(via.isPassThroughLocation()); + } + + @Test + void tetMapToPassThroughWithoutIds() { + Map input = mapOf(FIELD_PASS_THROUGH, mapOf(FIELD_STOP_LOCATION_IDS, null)); + var ex = assertThrows( + IllegalArgumentException.class, + () -> TripViaLocationMapper.mapToViaLocations(List.of(input)) + ); + assertEquals("'stopLocationIds' is not set!", ex.getMessage()); + } + + @Test + void testMapToPassThroughWithAnEmptyListOfIds() { + Map input = mapOf( + FIELD_PASS_THROUGH, + mapOf(FIELD_STOP_LOCATION_IDS, List.of()) + ); + var ex = assertThrows( + IllegalArgumentException.class, + () -> TripViaLocationMapper.mapToViaLocations(List.of(input)) + ); + assertEquals( + "A pass through via location must have at least one stop location.", + ex.getMessage() + ); + } + + @Test + void testOneOf() { + Map input = Map.ofEntries( + entry(FIELD_VISIT, visitInput("A", Duration.ofMinutes(1), List.of("F:99"))), + entry(FIELD_PASS_THROUGH, passThroughInput(LABEL, LIST_IDS_INPUT)) + ); + var ex = assertThrows( + IllegalArgumentException.class, + () -> TripViaLocationMapper.mapToViaLocations(List.of(input)) + ); + assertEquals( + "Only one entry in 'via @oneOf' is allowed. Set: 'visit', 'passThrough'", + ex.getMessage() + ); + + ex = + assertThrows( + IllegalArgumentException.class, + () -> TripViaLocationMapper.mapToViaLocations(List.of(Map.of())) + ); + assertEquals( + "No entries in 'via @oneOf'. One of 'visit', 'passThrough' must be set.", + ex.getMessage() + ); + } + + @Test + void testToLegacyPassThroughLocations() { + Map input = Map.of("name", LABEL, "placeIds", LIST_IDS_INPUT); + var result = TripViaLocationMapper.toLegacyPassThroughLocations(List.of(input)); + var via = result.getFirst(); + + assertEquals(LABEL, via.label()); + assertEquals(EXPECTED_IDS_AS_STRING, via.stopLocationIds().toString()); + assertTrue(via.isPassThroughLocation()); + assertEquals( + "PassThroughViaLocation{label: TestLabel, stopLocationIds: [F:ID1, F:ID2]}", + via.toString() + ); + } + + @Test + void testToLegacyPassThroughLocationsWithBareMinimum() { + Map input = mapOf("placeIds", LIST_IDS_INPUT); + var result = TripViaLocationMapper.toLegacyPassThroughLocations(List.of(input)); + var via = result.getFirst(); + + assertNull(via.label()); + assertEquals(EXPECTED_IDS_AS_STRING, via.stopLocationIds().toString()); + assertTrue(via.isPassThroughLocation()); + assertEquals("PassThroughViaLocation{stopLocationIds: [F:ID1, F:ID2]}", via.toString()); + } + + @Test + void testToLegacyPassThroughLocationsWithoutIds() { + var result = TripViaLocationMapper.toLegacyPassThroughLocations( + List.of(mapOf("placeIds", null)) + ); + assertTrue(result.isEmpty(), REASON_EMPTY_IDS_ALLOWED_PASS_THROUGH); + } + + @Test + void testToLegacyPassThroughLocationsWithEmptyList() { + Map input = Map.ofEntries(entry("name", LABEL), entry("placeIds", List.of())); + var result = TripViaLocationMapper.toLegacyPassThroughLocations(List.of(input)); + assertTrue(result.isEmpty(), REASON_EMPTY_IDS_ALLOWED_PASS_THROUGH); + } + + private Map visitInput(String label, Duration minWaitTime, List ids) { + var map = new HashMap(); + if (label != null) { + map.put(FIELD_LABEL, label); + } + if (minWaitTime != null) { + map.put(FIELD_MINIMUM_WAIT_TIME, minWaitTime); + } + if (ids != null) { + map.put(FIELD_STOP_LOCATION_IDS, ids); + } + return map; + } + + private Map passThroughInput(String label, List ids) { + return visitInput(label, null, ids); + } + + /** + * Create a new HashMap with the {@code key} and {@code value}, the value may be {@code null}. + * The {@link Map#of(Object, Object)} does not support {@code null} values. + */ + private static Map mapOf(String key, Object value) { + var map = new HashMap(); + map.put(key, value); + return map; + } +} diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java rename to application/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/CarPreferencesMapperTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/CarPreferencesMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/CarPreferencesMapperTest.java rename to application/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/CarPreferencesMapperTest.java diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapperTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapperTest.java rename to application/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapperTest.java diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/WalkPreferencesMapperTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/WalkPreferencesMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/WalkPreferencesMapperTest.java rename to application/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/WalkPreferencesMapperTest.java diff --git a/src/test/java/org/opentripplanner/apis/transmodel/model/EnumTypesTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/model/EnumTypesTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/transmodel/model/EnumTypesTest.java rename to application/src/test/java/org/opentripplanner/apis/transmodel/model/EnumTypesTest.java diff --git a/src/test/java/org/opentripplanner/apis/transmodel/model/TransportModeSlackTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/model/TransportModeSlackTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/transmodel/model/TransportModeSlackTest.java rename to application/src/test/java/org/opentripplanner/apis/transmodel/model/TransportModeSlackTest.java diff --git a/src/test/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostTypeTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostTypeTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostTypeTest.java rename to application/src/test/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostTypeTest.java diff --git a/src/test/java/org/opentripplanner/apis/transmodel/model/plan/TripPlanTimePenaltyDtoTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/model/plan/TripPlanTimePenaltyDtoTest.java similarity index 89% rename from src/test/java/org/opentripplanner/apis/transmodel/model/plan/TripPlanTimePenaltyDtoTest.java rename to application/src/test/java/org/opentripplanner/apis/transmodel/model/plan/TripPlanTimePenaltyDtoTest.java index 579f9b73761..0548bde0612 100644 --- a/src/test/java/org/opentripplanner/apis/transmodel/model/plan/TripPlanTimePenaltyDtoTest.java +++ b/application/src/test/java/org/opentripplanner/apis/transmodel/model/plan/TripPlanTimePenaltyDtoTest.java @@ -7,11 +7,11 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.framework.model.TimeAndCost; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.TestItineraryBuilder; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.utils.time.DurationUtils; class TripPlanTimePenaltyDtoTest { @@ -20,7 +20,7 @@ class TripPlanTimePenaltyDtoTest { Cost.costOfSeconds(21) ); - private final TransitModelForTest testModel = TransitModelForTest.of(); + private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of(); private final Place placeA = Place.forStop(testModel.stop("A").build()); private final Place placeB = Place.forStop(testModel.stop("B").build()); diff --git a/src/test/java/org/opentripplanner/apis/transmodel/model/scalars/DateTimeScalarFactoryTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/model/scalars/DateTimeScalarFactoryTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/transmodel/model/scalars/DateTimeScalarFactoryTest.java rename to application/src/test/java/org/opentripplanner/apis/transmodel/model/scalars/DateTimeScalarFactoryTest.java diff --git a/src/test/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapperTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapperTest.java similarity index 97% rename from src/test/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapperTest.java rename to application/src/test/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapperTest.java index b697adc9288..7cc373e5145 100644 --- a/src/test/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapperTest.java +++ b/application/src/test/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapperTest.java @@ -1,7 +1,7 @@ package org.opentripplanner.apis.transmodel.support; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.lang.StringUtils.quoteReplace; +import static org.opentripplanner.utils.lang.StringUtils.quoteReplace; import graphql.ExecutionResult; import graphql.GraphQLError; diff --git a/src/test/java/org/opentripplanner/apis/transmodel/support/GqlUtilTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/support/GqlUtilTest.java similarity index 100% rename from src/test/java/org/opentripplanner/apis/transmodel/support/GqlUtilTest.java rename to application/src/test/java/org/opentripplanner/apis/transmodel/support/GqlUtilTest.java diff --git a/application/src/test/java/org/opentripplanner/apis/transmodel/support/OneOfInputValidatorTest.java b/application/src/test/java/org/opentripplanner/apis/transmodel/support/OneOfInputValidatorTest.java new file mode 100644 index 00000000000..e641a1cc855 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/apis/transmodel/support/OneOfInputValidatorTest.java @@ -0,0 +1,53 @@ +package org.opentripplanner.apis.transmodel.support; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class OneOfInputValidatorTest { + + @Test + void testValidateOneReturnsTheFieldName() { + assertEquals( + "two", + OneOfInputValidator.validateOneOf(Map.of("two", "X"), "parent", "one", "two") + ); + } + + @Test + void testValidateOneOfWithEmptySetOfArguments() { + var ex = assertThrows( + IllegalArgumentException.class, + () -> OneOfInputValidator.validateOneOf(Map.of(), "parent", "one", "two") + ); + assertEquals( + "No entries in 'parent @oneOf'. One of 'one', 'two' must be set.", + ex.getMessage() + ); + } + + @Test + void testValidateOneOfWithTooManyArguments() { + var ex = assertThrows( + IllegalArgumentException.class, + () -> + OneOfInputValidator.validateOneOf(Map.of("one", "X", "two", "Y"), "parent", "one", "two") + ); + assertEquals( + "Only one entry in 'parent @oneOf' is allowed. Set: 'one', 'two'", + ex.getMessage() + ); + } + + @Test + void testValidateOneOfWithEmptyCollection() { + var ex = assertThrows( + IllegalArgumentException.class, + () -> OneOfInputValidator.validateOneOf(Map.of("one", List.of()), "parent", "one", "two") + ); + assertEquals("'one' can not be empty in 'parent @oneOf'.", ex.getMessage()); + } +} diff --git a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java b/application/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java similarity index 86% rename from src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java rename to application/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java index 6a60490a07f..26d1044047e 100644 --- a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java +++ b/application/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java @@ -5,6 +5,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner.apis.vectortiles.model.TileSource.VectorSource; import org.opentripplanner.apis.vectortiles.model.VectorSourceLayer; @@ -16,6 +17,9 @@ class DebugStyleSpecTest { private final ResourceLoader RESOURCES = ResourceLoader.of(this); + /** + * Remove the style.json file and re-run this test in order to regenerate the file. + */ @Test void spec() throws IOException { var vectorSource = new VectorSource("vectorSource", "https://example.com"); @@ -24,7 +28,14 @@ void spec() throws IOException { var groupStops = new VectorSourceLayer(vectorSource, "stops"); var edges = new VectorSourceLayer(vectorSource, "edges"); var vertices = new VectorSourceLayer(vectorSource, "vertices"); - var spec = DebugStyleSpec.build(regularStops, areaStops, groupStops, edges, vertices); + var spec = DebugStyleSpec.build( + regularStops, + areaStops, + groupStops, + edges, + vertices, + List.of() + ); var json = ObjectMappers.ignoringExtraFields().valueToTree(spec); try { diff --git a/src/test/java/org/opentripplanner/astar/AStarArchitectureTest.java b/application/src/test/java/org/opentripplanner/astar/AStarArchitectureTest.java similarity index 100% rename from src/test/java/org/opentripplanner/astar/AStarArchitectureTest.java rename to application/src/test/java/org/opentripplanner/astar/AStarArchitectureTest.java diff --git a/src/test/java/org/opentripplanner/astar/AStarTest.java b/application/src/test/java/org/opentripplanner/astar/AStarTest.java similarity index 100% rename from src/test/java/org/opentripplanner/astar/AStarTest.java rename to application/src/test/java/org/opentripplanner/astar/AStarTest.java diff --git a/src/test/java/org/opentripplanner/astar/model/BinHeapTest.java b/application/src/test/java/org/opentripplanner/astar/model/BinHeapTest.java similarity index 100% rename from src/test/java/org/opentripplanner/astar/model/BinHeapTest.java rename to application/src/test/java/org/opentripplanner/astar/model/BinHeapTest.java diff --git a/application/src/test/java/org/opentripplanner/astar/strategy/MaxCountTerminationStrategyTest.java b/application/src/test/java/org/opentripplanner/astar/strategy/MaxCountTerminationStrategyTest.java new file mode 100644 index 00000000000..50a920f1252 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/astar/strategy/MaxCountTerminationStrategyTest.java @@ -0,0 +1,29 @@ +package org.opentripplanner.astar.strategy; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class MaxCountTerminationStrategyTest { + + @Test + void countStates() { + var countAllStatesStrategy = new MaxCountTerminationStrategy<>(3, state -> true); + + assertFalse(countAllStatesStrategy.shouldSearchTerminate(null)); + assertFalse(countAllStatesStrategy.shouldSearchTerminate(null)); + assertTrue(countAllStatesStrategy.shouldSearchTerminate(null)); + assertTrue(countAllStatesStrategy.shouldSearchTerminate(null)); + } + + @Test + void countNoStates() { + var countNoStatesStrategy = new MaxCountTerminationStrategy<>(1, state -> false); + + assertFalse(countNoStatesStrategy.shouldSearchTerminate(null)); + assertFalse(countNoStatesStrategy.shouldSearchTerminate(null)); + assertFalse(countNoStatesStrategy.shouldSearchTerminate(null)); + assertFalse(countNoStatesStrategy.shouldSearchTerminate(null)); + } +} diff --git a/src/test/java/org/opentripplanner/astar/strategy/PathComparatorTest.java b/application/src/test/java/org/opentripplanner/astar/strategy/PathComparatorTest.java similarity index 100% rename from src/test/java/org/opentripplanner/astar/strategy/PathComparatorTest.java rename to application/src/test/java/org/opentripplanner/astar/strategy/PathComparatorTest.java diff --git a/src/test/java/org/opentripplanner/datastore/DataStoreArchitectureTest.java b/application/src/test/java/org/opentripplanner/datastore/DataStoreArchitectureTest.java similarity index 100% rename from src/test/java/org/opentripplanner/datastore/DataStoreArchitectureTest.java rename to application/src/test/java/org/opentripplanner/datastore/DataStoreArchitectureTest.java diff --git a/src/test/java/org/opentripplanner/datastore/OtpDataStoreTest.java b/application/src/test/java/org/opentripplanner/datastore/OtpDataStoreTest.java similarity index 99% rename from src/test/java/org/opentripplanner/datastore/OtpDataStoreTest.java rename to application/src/test/java/org/opentripplanner/datastore/OtpDataStoreTest.java index 1733a97777b..d7afc55a556 100644 --- a/src/test/java/org/opentripplanner/datastore/OtpDataStoreTest.java +++ b/application/src/test/java/org/opentripplanner/datastore/OtpDataStoreTest.java @@ -34,8 +34,8 @@ import org.opentripplanner.datastore.api.FileType; import org.opentripplanner.datastore.api.OtpDataStoreConfig; import org.opentripplanner.datastore.configure.DataStoreModule; -import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.standalone.config.OtpConfigLoader; +import org.opentripplanner.utils.lang.StringUtils; public class OtpDataStoreTest { diff --git a/src/test/java/org/opentripplanner/datastore/base/ByteArrayDataSourceTest.java b/application/src/test/java/org/opentripplanner/datastore/base/ByteArrayDataSourceTest.java similarity index 100% rename from src/test/java/org/opentripplanner/datastore/base/ByteArrayDataSourceTest.java rename to application/src/test/java/org/opentripplanner/datastore/base/ByteArrayDataSourceTest.java diff --git a/src/test/java/org/opentripplanner/datastore/file/DirectoryDataSourceTest.java b/application/src/test/java/org/opentripplanner/datastore/file/DirectoryDataSourceTest.java similarity index 100% rename from src/test/java/org/opentripplanner/datastore/file/DirectoryDataSourceTest.java rename to application/src/test/java/org/opentripplanner/datastore/file/DirectoryDataSourceTest.java diff --git a/src/test/java/org/opentripplanner/datastore/file/FileDataSourceTest.java b/application/src/test/java/org/opentripplanner/datastore/file/FileDataSourceTest.java similarity index 100% rename from src/test/java/org/opentripplanner/datastore/file/FileDataSourceTest.java rename to application/src/test/java/org/opentripplanner/datastore/file/FileDataSourceTest.java diff --git a/src/test/java/org/opentripplanner/datastore/file/ZipFileDataSourceTest.java b/application/src/test/java/org/opentripplanner/datastore/file/ZipFileDataSourceTest.java similarity index 100% rename from src/test/java/org/opentripplanner/datastore/file/ZipFileDataSourceTest.java rename to application/src/test/java/org/opentripplanner/datastore/file/ZipFileDataSourceTest.java diff --git a/src/test/java/org/opentripplanner/datastore/file/ZipStreamDataSourceDecoratorTest.java b/application/src/test/java/org/opentripplanner/datastore/file/ZipStreamDataSourceDecoratorTest.java similarity index 100% rename from src/test/java/org/opentripplanner/datastore/file/ZipStreamDataSourceDecoratorTest.java rename to application/src/test/java/org/opentripplanner/datastore/file/ZipStreamDataSourceDecoratorTest.java diff --git a/src/test/java/org/opentripplanner/datastore/https/HttpsDataSourceRepositoryTest.java b/application/src/test/java/org/opentripplanner/datastore/https/HttpsDataSourceRepositoryTest.java similarity index 100% rename from src/test/java/org/opentripplanner/datastore/https/HttpsDataSourceRepositoryTest.java rename to application/src/test/java/org/opentripplanner/datastore/https/HttpsDataSourceRepositoryTest.java diff --git a/src/test/java/org/opentripplanner/datastore/https/HttpsFileDataSourceTest.java b/application/src/test/java/org/opentripplanner/datastore/https/HttpsFileDataSourceTest.java similarity index 100% rename from src/test/java/org/opentripplanner/datastore/https/HttpsFileDataSourceTest.java rename to application/src/test/java/org/opentripplanner/datastore/https/HttpsFileDataSourceTest.java diff --git a/src/test/java/org/opentripplanner/ext/restapi/resources/PlannerResourceTest.java b/application/src/test/java/org/opentripplanner/ext/restapi/resources/PlannerResourceTest.java similarity index 87% rename from src/test/java/org/opentripplanner/ext/restapi/resources/PlannerResourceTest.java rename to application/src/test/java/org/opentripplanner/ext/restapi/resources/PlannerResourceTest.java index a86e270a2af..dc924ac765a 100644 --- a/src/test/java/org/opentripplanner/ext/restapi/resources/PlannerResourceTest.java +++ b/application/src/test/java/org/opentripplanner/ext/restapi/resources/PlannerResourceTest.java @@ -15,14 +15,14 @@ import org.opentripplanner.routing.api.request.RequestModes; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.standalone.api.OtpServerRequestContext; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; class PlannerResourceTest { static OtpServerRequestContext context() { - var transitModel = new TransitModel(); - transitModel.initTimeZone(ZoneIds.BERLIN); - return TestServerContext.createServerContext(new Graph(), transitModel); + var timetableRepository = new TimetableRepository(); + timetableRepository.initTimeZone(ZoneIds.BERLIN); + return TestServerContext.createServerContext(new Graph(), timetableRepository); } @Test diff --git a/src/test/java/org/opentripplanner/ext/transmodelapi/_support/TestDataFetcherDecorator.java b/application/src/test/java/org/opentripplanner/ext/transmodelapi/_support/TestDataFetcherDecorator.java similarity index 100% rename from src/test/java/org/opentripplanner/ext/transmodelapi/_support/TestDataFetcherDecorator.java rename to application/src/test/java/org/opentripplanner/ext/transmodelapi/_support/TestDataFetcherDecorator.java diff --git a/src/test/java/org/opentripplanner/framework/FrameworkArchitectureTest.java b/application/src/test/java/org/opentripplanner/framework/FrameworkArchitectureTest.java similarity index 75% rename from src/test/java/org/opentripplanner/framework/FrameworkArchitectureTest.java rename to application/src/test/java/org/opentripplanner/framework/FrameworkArchitectureTest.java index 9e44dd05dda..1bfc576d822 100644 --- a/src/test/java/org/opentripplanner/framework/FrameworkArchitectureTest.java +++ b/application/src/test/java/org/opentripplanner/framework/FrameworkArchitectureTest.java @@ -6,6 +6,7 @@ import static org.opentripplanner.OtpArchitectureModules.GNU_TROVE; import static org.opentripplanner.OtpArchitectureModules.JTS_GEOM; import static org.opentripplanner.OtpArchitectureModules.OPEN_GIS; +import static org.opentripplanner.OtpArchitectureModules.OTP_UTILS; import org.junit.jupiter.api.Test; import org.opentripplanner._support.arch.Module; @@ -27,16 +28,13 @@ public class FrameworkArchitectureTest { private static final Package GEOMETRY = FRAMEWORK.subPackage("geometry"); private static final Package I18N = FRAMEWORK.subPackage("i18n"); private static final Package IO = FRAMEWORK.subPackage("io"); - private static final Package LANG = FRAMEWORK.subPackage("lang"); private static final Package LOGGING = FRAMEWORK.subPackage("logging"); private static final Package RESOURCES = FRAMEWORK.subPackage("resources"); - private static final Package TEXT = FRAMEWORK.subPackage("text"); private static final Package TIME = FRAMEWORK.subPackage("time"); - private static final Package TO_STRING = FRAMEWORK.subPackage("tostring"); @Test void enforceApplicationPackageDependencies() { - APPLICATION.dependsOn(LANG).verify(); + APPLICATION.dependsOn(OTP_UTILS).verify(); } @Test @@ -52,16 +50,7 @@ void enforceFunctionalPackageDependencies() { @Test void enforceGeometryPackageDependencies() { GEOMETRY - .dependsOn( - GEO_JSON, - GEO_TOOLS, - GNU_TROVE, - JTS_GEOM, - OPEN_GIS, - LANG, - TO_STRING, - GUAVA_COLLECTIONS - ) + .dependsOn(GEO_JSON, GEO_TOOLS, GNU_TROVE, JTS_GEOM, OPEN_GIS, GUAVA_COLLECTIONS, OTP_UTILS) .verify(); } @@ -75,14 +64,9 @@ void enforceIoPackageDependencies() { IO.dependsOn(APACHE_HTTP, XML_MODULES).verify(); } - @Test - void enforceLangPackageDependencies() { - LANG.verify(); - } - @Test void enforceLoggingPackageDependencies() { - LOGGING.dependsOn(TEXT, TIME).verify(); + LOGGING.dependsOn(OTP_UTILS).verify(); } @Test @@ -90,18 +74,8 @@ void enforceResourcesPackageDependencies() { RESOURCES.verify(); } - @Test - void enforceTextPackageDependencies() { - TEXT.dependsOn(LANG).verify(); - } - @Test void enforceTimePackageDependencies() { - TIME.dependsOn(LOGGING).verify(); - } - - @Test - void enforceToStingPackageDependencies() { - TO_STRING.dependsOn(LANG, TIME).verify(); + TIME.dependsOn(OTP_UTILS).verify(); } } diff --git a/src/test/java/org/opentripplanner/framework/application/OTPFeatureTest.java b/application/src/test/java/org/opentripplanner/framework/application/OTPFeatureTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/application/OTPFeatureTest.java rename to application/src/test/java/org/opentripplanner/framework/application/OTPFeatureTest.java diff --git a/src/test/java/org/opentripplanner/framework/application/OtpAppExceptionTest.java b/application/src/test/java/org/opentripplanner/framework/application/OtpAppExceptionTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/application/OtpAppExceptionTest.java rename to application/src/test/java/org/opentripplanner/framework/application/OtpAppExceptionTest.java diff --git a/src/test/java/org/opentripplanner/framework/application/OtpFileNamesTest.java b/application/src/test/java/org/opentripplanner/framework/application/OtpFileNamesTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/application/OtpFileNamesTest.java rename to application/src/test/java/org/opentripplanner/framework/application/OtpFileNamesTest.java diff --git a/src/test/java/org/opentripplanner/framework/doc/DocumentedEnumTestHelper.java b/application/src/test/java/org/opentripplanner/framework/doc/DocumentedEnumTestHelper.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/doc/DocumentedEnumTestHelper.java rename to application/src/test/java/org/opentripplanner/framework/doc/DocumentedEnumTestHelper.java diff --git a/src/test/java/org/opentripplanner/framework/geometry/CompactElevationProfileTest.java b/application/src/test/java/org/opentripplanner/framework/geometry/CompactElevationProfileTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/geometry/CompactElevationProfileTest.java rename to application/src/test/java/org/opentripplanner/framework/geometry/CompactElevationProfileTest.java diff --git a/src/test/java/org/opentripplanner/framework/geometry/CompactLineStringUtilsTest.java b/application/src/test/java/org/opentripplanner/framework/geometry/CompactLineStringUtilsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/geometry/CompactLineStringUtilsTest.java rename to application/src/test/java/org/opentripplanner/framework/geometry/CompactLineStringUtilsTest.java diff --git a/src/test/java/org/opentripplanner/framework/geometry/DirectionUtilsTest.java b/application/src/test/java/org/opentripplanner/framework/geometry/DirectionUtilsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/geometry/DirectionUtilsTest.java rename to application/src/test/java/org/opentripplanner/framework/geometry/DirectionUtilsTest.java diff --git a/src/test/java/org/opentripplanner/framework/geometry/DistanceLibTest.java b/application/src/test/java/org/opentripplanner/framework/geometry/DistanceLibTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/geometry/DistanceLibTest.java rename to application/src/test/java/org/opentripplanner/framework/geometry/DistanceLibTest.java diff --git a/src/test/java/org/opentripplanner/framework/geometry/GeometryUtilsTest.java b/application/src/test/java/org/opentripplanner/framework/geometry/GeometryUtilsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/geometry/GeometryUtilsTest.java rename to application/src/test/java/org/opentripplanner/framework/geometry/GeometryUtilsTest.java diff --git a/src/test/java/org/opentripplanner/framework/geometry/HashGridTest.java b/application/src/test/java/org/opentripplanner/framework/geometry/HashGridTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/geometry/HashGridTest.java rename to application/src/test/java/org/opentripplanner/framework/geometry/HashGridTest.java diff --git a/src/test/java/org/opentripplanner/framework/geometry/PolylineEncoderTest.java b/application/src/test/java/org/opentripplanner/framework/geometry/PolylineEncoderTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/geometry/PolylineEncoderTest.java rename to application/src/test/java/org/opentripplanner/framework/geometry/PolylineEncoderTest.java diff --git a/src/test/java/org/opentripplanner/framework/geometry/SphericalDistanceLibraryTest.java b/application/src/test/java/org/opentripplanner/framework/geometry/SphericalDistanceLibraryTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/geometry/SphericalDistanceLibraryTest.java rename to application/src/test/java/org/opentripplanner/framework/geometry/SphericalDistanceLibraryTest.java diff --git a/src/test/java/org/opentripplanner/framework/geometry/WgsCoordinateTest.java b/application/src/test/java/org/opentripplanner/framework/geometry/WgsCoordinateTest.java similarity index 89% rename from src/test/java/org/opentripplanner/framework/geometry/WgsCoordinateTest.java rename to application/src/test/java/org/opentripplanner/framework/geometry/WgsCoordinateTest.java index 5cd7ac66123..d9da08044a5 100644 --- a/src/test/java/org/opentripplanner/framework/geometry/WgsCoordinateTest.java +++ b/application/src/test/java/org/opentripplanner/framework/geometry/WgsCoordinateTest.java @@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.framework.geometry.WgsCoordinate.GREENWICH; import java.util.List; import org.junit.jupiter.api.Test; @@ -99,10 +100,17 @@ void add() { assertEquals(new WgsCoordinate(12d, 5d), new WgsCoordinate(9d, 1d).add(3d, 4d)); } + @Test + void testIsNorthOf() { + var c = new WgsCoordinate(10.0, 30.0); + assertTrue(c.isNorthOf(9.9)); + assertFalse(c.isNorthOf(10.1)); + } + @Test void testGreenwich() { - assertEquals(51.48d, WgsCoordinate.GREENWICH.latitude()); - assertEquals(0d, WgsCoordinate.GREENWICH.longitude()); + assertEquals(51.48d, GREENWICH.latitude()); + assertEquals(0d, GREENWICH.longitude()); } @Test @@ -120,4 +128,9 @@ void roundingTo100m() { assertEquals(10, rounded.longitude()); assertEquals(53.557, rounded.latitude()); } + + @Test + void testDistanceTo() { + assertEquals(131_394, (int) GREENWICH.distanceTo(GREENWICH.add(-1.0, 1.0))); + } } diff --git a/src/test/java/org/opentripplanner/framework/graphql/GraphQLUtilsTest.java b/application/src/test/java/org/opentripplanner/framework/graphql/GraphQLUtilsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/graphql/GraphQLUtilsTest.java rename to application/src/test/java/org/opentripplanner/framework/graphql/GraphQLUtilsTest.java diff --git a/src/test/java/org/opentripplanner/framework/graphql/scalar/DateScalarFactoryTest.java b/application/src/test/java/org/opentripplanner/framework/graphql/scalar/DateScalarFactoryTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/graphql/scalar/DateScalarFactoryTest.java rename to application/src/test/java/org/opentripplanner/framework/graphql/scalar/DateScalarFactoryTest.java diff --git a/application/src/test/java/org/opentripplanner/framework/i18n/I18NStringTest.java b/application/src/test/java/org/opentripplanner/framework/i18n/I18NStringTest.java new file mode 100644 index 00000000000..101da6edc91 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/framework/i18n/I18NStringTest.java @@ -0,0 +1,32 @@ +package org.opentripplanner.framework.i18n; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class I18NStringTest { + + private final I18NString noValue = I18NString.of(" \t\n\r\f"); + private final I18NString hasValue = I18NString.of("A value"); + + @Test + void hasValue() { + assertTrue(I18NString.hasValue(hasValue)); + assertFalse(I18NString.hasValue(noValue)); + } + + @Test + void hasNoValue() { + assertFalse(I18NString.hasNoValue(hasValue)); + assertTrue(I18NString.hasNoValue(noValue)); + } + + @Test + void assertHasValue() { + var ex = assertThrows(IllegalArgumentException.class, () -> I18NString.assertHasValue(noValue)); + assertEquals("Value can not be null, empty or just whitespace: ' \t\n\r\f'", ex.getMessage()); + } +} diff --git a/src/test/java/org/opentripplanner/framework/i18n/LocalizedStringTest.java b/application/src/test/java/org/opentripplanner/framework/i18n/LocalizedStringTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/i18n/LocalizedStringTest.java rename to application/src/test/java/org/opentripplanner/framework/i18n/LocalizedStringTest.java diff --git a/src/test/java/org/opentripplanner/framework/i18n/TranslatedStringTest.java b/application/src/test/java/org/opentripplanner/framework/i18n/TranslatedStringTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/i18n/TranslatedStringTest.java rename to application/src/test/java/org/opentripplanner/framework/i18n/TranslatedStringTest.java diff --git a/src/test/java/org/opentripplanner/framework/io/HttpUtilsTest.java b/application/src/test/java/org/opentripplanner/framework/io/HttpUtilsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/io/HttpUtilsTest.java rename to application/src/test/java/org/opentripplanner/framework/io/HttpUtilsTest.java diff --git a/src/test/java/org/opentripplanner/framework/json/JsonUtilsTest.java b/application/src/test/java/org/opentripplanner/framework/json/JsonUtilsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/json/JsonUtilsTest.java rename to application/src/test/java/org/opentripplanner/framework/json/JsonUtilsTest.java diff --git a/src/test/java/org/opentripplanner/framework/model/CostTest.java b/application/src/test/java/org/opentripplanner/framework/model/CostTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/model/CostTest.java rename to application/src/test/java/org/opentripplanner/framework/model/CostTest.java diff --git a/src/test/java/org/opentripplanner/framework/model/TimeAndCostTest.java b/application/src/test/java/org/opentripplanner/framework/model/TimeAndCostTest.java similarity index 95% rename from src/test/java/org/opentripplanner/framework/model/TimeAndCostTest.java rename to application/src/test/java/org/opentripplanner/framework/model/TimeAndCostTest.java index 4660da480b2..5eca02043ef 100644 --- a/src/test/java/org/opentripplanner/framework/model/TimeAndCostTest.java +++ b/application/src/test/java/org/opentripplanner/framework/model/TimeAndCostTest.java @@ -6,7 +6,7 @@ import java.time.Duration; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.utils.time.DurationUtils; class TimeAndCostTest { diff --git a/src/test/java/org/opentripplanner/framework/model/UnitsTest.java b/application/src/test/java/org/opentripplanner/framework/model/UnitsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/model/UnitsTest.java rename to application/src/test/java/org/opentripplanner/framework/model/UnitsTest.java diff --git a/src/test/java/org/opentripplanner/framework/resources/ResourceBundleSingletonTest.java b/application/src/test/java/org/opentripplanner/framework/resources/ResourceBundleSingletonTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/resources/ResourceBundleSingletonTest.java rename to application/src/test/java/org/opentripplanner/framework/resources/ResourceBundleSingletonTest.java diff --git a/src/test/java/org/opentripplanner/framework/retry/OtpRetryTest.java b/application/src/test/java/org/opentripplanner/framework/retry/OtpRetryTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/retry/OtpRetryTest.java rename to application/src/test/java/org/opentripplanner/framework/retry/OtpRetryTest.java diff --git a/src/test/java/org/opentripplanner/framework/time/ZoneIdFallbackTest.java b/application/src/test/java/org/opentripplanner/framework/time/ZoneIdFallbackTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/time/ZoneIdFallbackTest.java rename to application/src/test/java/org/opentripplanner/framework/time/ZoneIdFallbackTest.java diff --git a/src/test/java/org/opentripplanner/framework/token/AdvancedTokenSchemaTest.java b/application/src/test/java/org/opentripplanner/framework/token/AdvancedTokenSchemaTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/token/AdvancedTokenSchemaTest.java rename to application/src/test/java/org/opentripplanner/framework/token/AdvancedTokenSchemaTest.java diff --git a/src/test/java/org/opentripplanner/framework/token/FieldDefinitionTest.java b/application/src/test/java/org/opentripplanner/framework/token/FieldDefinitionTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/token/FieldDefinitionTest.java rename to application/src/test/java/org/opentripplanner/framework/token/FieldDefinitionTest.java diff --git a/src/test/java/org/opentripplanner/framework/token/TestTokenSchemaConstants.java b/application/src/test/java/org/opentripplanner/framework/token/TestTokenSchemaConstants.java similarity index 95% rename from src/test/java/org/opentripplanner/framework/token/TestTokenSchemaConstants.java rename to application/src/test/java/org/opentripplanner/framework/token/TestTokenSchemaConstants.java index 09ac58a0d2d..94303a28e14 100644 --- a/src/test/java/org/opentripplanner/framework/token/TestTokenSchemaConstants.java +++ b/application/src/test/java/org/opentripplanner/framework/token/TestTokenSchemaConstants.java @@ -3,7 +3,7 @@ import java.time.Duration; import java.time.Instant; import java.time.Month; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.utils.time.DurationUtils; public interface TestTokenSchemaConstants { // Token field names. These are used to reference a specific field value in theString BYTE_FIELD = "AByte"; diff --git a/src/test/java/org/opentripplanner/framework/token/TokenSchemaTest.java b/application/src/test/java/org/opentripplanner/framework/token/TokenSchemaTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/token/TokenSchemaTest.java rename to application/src/test/java/org/opentripplanner/framework/token/TokenSchemaTest.java diff --git a/src/test/java/org/opentripplanner/framework/token/TokenTypeTest.java b/application/src/test/java/org/opentripplanner/framework/token/TokenTypeTest.java similarity index 100% rename from src/test/java/org/opentripplanner/framework/token/TokenTypeTest.java rename to application/src/test/java/org/opentripplanner/framework/token/TokenTypeTest.java diff --git a/src/test/java/org/opentripplanner/generate/doc/BuildConfigurationDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/BuildConfigurationDocTest.java similarity index 97% rename from src/test/java/org/opentripplanner/generate/doc/BuildConfigurationDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/BuildConfigurationDocTest.java index 8189f18f20e..a44d013fd03 100644 --- a/src/test/java/org/opentripplanner/generate/doc/BuildConfigurationDocTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/BuildConfigurationDocTest.java @@ -3,13 +3,13 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_3; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceJsonExample; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersDetails; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersTable; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; +import static org.opentripplanner.utils.text.MarkdownFormatter.HEADER_3; import java.io.File; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/generate/doc/ConfigurationDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/ConfigurationDocTest.java similarity index 100% rename from src/test/java/org/opentripplanner/generate/doc/ConfigurationDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/ConfigurationDocTest.java diff --git a/application/src/test/java/org/opentripplanner/generate/doc/DebugUiConfigurationDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/DebugUiConfigurationDocTest.java new file mode 100644 index 00000000000..a5124c0d3e0 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/generate/doc/DebugUiConfigurationDocTest.java @@ -0,0 +1,67 @@ +package org.opentripplanner.generate.doc; + +import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; +import static org.opentripplanner.framework.io.FileUtils.readFile; +import static org.opentripplanner.framework.io.FileUtils.writeFile; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; +import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceJsonExample; +import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersDetails; +import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersTable; +import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; +import static org.opentripplanner.utils.text.MarkdownFormatter.HEADER_3; + +import java.io.File; +import org.junit.jupiter.api.Test; +import org.opentripplanner.framework.application.OtpFileNames; +import org.opentripplanner.generate.doc.framework.GeneratesDocumentation; +import org.opentripplanner.generate.doc.framework.ParameterDetailsList; +import org.opentripplanner.generate.doc.framework.ParameterSummaryTable; +import org.opentripplanner.generate.doc.framework.SkipNodes; +import org.opentripplanner.standalone.config.DebugUiConfig; +import org.opentripplanner.standalone.config.framework.json.NodeAdapter; + +@GeneratesDocumentation +public class DebugUiConfigurationDocTest { + + private static final String CONFIG_JSON = OtpFileNames.DEBUG_UI_CONFIG_FILENAME; + private static final File TEMPLATE = new File(TEMPLATE_PATH, "DebugUiConfiguration.md"); + private static final File OUT_FILE = new File(USER_DOC_PATH, "DebugUiConfiguration.md"); + + private static final String CONFIG_PATH = "standalone/config/" + CONFIG_JSON; + + /** + * NOTE! This test updates the {@code doc/user/Configuration.md} document based on the latest + * version of the code. + */ + @Test + public void updateDoc() { + NodeAdapter node = readConfig(); + + // Read and close input file (same as output file) + String doc = readFile(TEMPLATE); + String original = readFile(OUT_FILE); + + doc = replaceParametersTable(doc, getParameterSummaryTable(node)); + doc = replaceParametersDetails(doc, getParameterDetailsTable(node)); + doc = replaceJsonExample(doc, node, CONFIG_JSON); + + writeFile(OUT_FILE, doc); + + assertFileEquals(original, OUT_FILE); + } + + private NodeAdapter readConfig() { + var json = jsonNodeFromResource(CONFIG_PATH); + var conf = new DebugUiConfig(json, CONFIG_PATH, true); + return conf.asNodeAdapter(); + } + + private String getParameterSummaryTable(NodeAdapter node) { + return new ParameterSummaryTable(SkipNodes.of().build()).createTable(node).toMarkdownTable(); + } + + private String getParameterDetailsTable(NodeAdapter node) { + return ParameterDetailsList.listParametersWithDetails(node, SkipNodes.of().build(), HEADER_3); + } +} diff --git a/src/test/java/org/opentripplanner/generate/doc/EmissionsConfigurationDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/EmissionsConfigurationDocTest.java similarity index 97% rename from src/test/java/org/opentripplanner/generate/doc/EmissionsConfigurationDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/EmissionsConfigurationDocTest.java index 5010c78d527..94f0679cdfc 100644 --- a/src/test/java/org/opentripplanner/generate/doc/EmissionsConfigurationDocTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/EmissionsConfigurationDocTest.java @@ -3,11 +3,11 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; +import static org.opentripplanner.utils.text.MarkdownFormatter.HEADER_4; import java.io.File; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/generate/doc/FlexConfigurationDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/FlexConfigurationDocTest.java similarity index 97% rename from src/test/java/org/opentripplanner/generate/doc/FlexConfigurationDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/FlexConfigurationDocTest.java index e18090466b9..1958d200ca3 100644 --- a/src/test/java/org/opentripplanner/generate/doc/FlexConfigurationDocTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/FlexConfigurationDocTest.java @@ -3,11 +3,11 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; +import static org.opentripplanner.utils.text.MarkdownFormatter.HEADER_4; import java.io.File; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java similarity index 95% rename from src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java index 7eb6a685cca..3353d901f98 100644 --- a/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java @@ -12,7 +12,6 @@ import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; -import javax.annotation.Nonnull; import org.junit.jupiter.api.Test; import org.opentripplanner.generate.doc.framework.GeneratesDocumentation; import org.opentripplanner.generate.doc.framework.TemplateUtil; @@ -38,7 +37,7 @@ public void updateTutorialDoc() throws IOException { String original = readFile(OUT_FILE); var routeQuery = getGraphQlQuery("routes-tutorial.graphql"); - var planQuery = getGraphQlQuery("plan-tutorial.graphql"); + var planQuery = getGraphQlQuery("planConnection-tutorial.graphql"); doc = replaceSection(doc, "route-query", routeQuery); doc = replaceSection(doc, "plan-query", planQuery); @@ -47,7 +46,6 @@ public void updateTutorialDoc() throws IOException { assertFileEquals(original, OUT_FILE); } - @Nonnull private static String getGraphQlQuery(String resourceName) throws IOException { var url = Resources.getResource("org/opentripplanner/apis/gtfs/queries/" + resourceName); var query = TemplateUtil.graphQlExample(Resources.toString(url, StandardCharsets.UTF_8)); diff --git a/application/src/test/java/org/opentripplanner/generate/doc/NetexTutorialDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/NetexTutorialDocTest.java new file mode 100644 index 00000000000..5a953c1d21c --- /dev/null +++ b/application/src/test/java/org/opentripplanner/generate/doc/NetexTutorialDocTest.java @@ -0,0 +1,55 @@ +package org.opentripplanner.generate.doc; + +import static org.opentripplanner.framework.application.OtpFileNames.BUILD_CONFIG_FILENAME; +import static org.opentripplanner.framework.application.OtpFileNames.ROUTER_CONFIG_FILENAME; +import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; +import static org.opentripplanner.framework.io.FileUtils.readFile; +import static org.opentripplanner.framework.io.FileUtils.writeFile; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; +import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; +import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; + +import java.io.File; +import org.junit.jupiter.api.Test; +import org.opentripplanner.generate.doc.framework.DocBuilder; +import org.opentripplanner.generate.doc.framework.GeneratesDocumentation; +import org.opentripplanner.standalone.config.RouterConfig; +import org.opentripplanner.standalone.config.framework.json.NodeAdapter; + +@GeneratesDocumentation +class NetexTutorialDocTest { + + private static final String NETEX_TUTORIAL_MD = "Netex-Tutorial.md"; + private static final File TEMPLATE = new File(TEMPLATE_PATH, NETEX_TUTORIAL_MD); + private static final File OUT_FILE = new File(USER_DOC_PATH, NETEX_TUTORIAL_MD); + + private static final String TUTORIAL_PATH = "standalone/config/netex-tutorial/"; + + @Test + void updateTutorialDoc() { + // Read and close input file (same as output file) + String template = readFile(TEMPLATE); + String original = readFile(OUT_FILE); + + template = replaceSection(template, "build-config", toJson(BUILD_CONFIG_FILENAME)); + template = replaceSection(template, "router-config", toJson(ROUTER_CONFIG_FILENAME)); + + writeFile(OUT_FILE, template); + assertFileEquals(original, OUT_FILE); + } + + private static String toJson(String fileName) { + var path = TUTORIAL_PATH + fileName; + var nodeAdapter = loadBuildConfig(path); + var buf = new DocBuilder(); + buf.addExample(fileName, nodeAdapter.rawNode()); + return buf.toString(); + } + + private static NodeAdapter loadBuildConfig(String buildConfigPath) { + var json = jsonNodeFromResource(buildConfigPath); + var conf = new RouterConfig(json, buildConfigPath, false); + return conf.asNodeAdapter(); + } +} diff --git a/src/test/java/org/opentripplanner/generate/doc/OsmMapperDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/OsmMapperDocTest.java similarity index 79% rename from src/test/java/org/opentripplanner/generate/doc/OsmMapperDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/OsmMapperDocTest.java index d3eb0a44122..e2844437ca5 100644 --- a/src/test/java/org/opentripplanner/generate/doc/OsmMapperDocTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/OsmMapperDocTest.java @@ -6,11 +6,11 @@ import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; -import static org.opentripplanner.openstreetmap.tagmapping.OsmTagMapperSource.ATLANTA; -import static org.opentripplanner.openstreetmap.tagmapping.OsmTagMapperSource.CONSTANT_SPEED_FINLAND; -import static org.opentripplanner.openstreetmap.tagmapping.OsmTagMapperSource.HAMBURG; -import static org.opentripplanner.openstreetmap.tagmapping.OsmTagMapperSource.HOUSTON; -import static org.opentripplanner.openstreetmap.tagmapping.OsmTagMapperSource.PORTLAND; +import static org.opentripplanner.osm.tagmapping.OsmTagMapperSource.ATLANTA; +import static org.opentripplanner.osm.tagmapping.OsmTagMapperSource.CONSTANT_SPEED_FINLAND; +import static org.opentripplanner.osm.tagmapping.OsmTagMapperSource.HAMBURG; +import static org.opentripplanner.osm.tagmapping.OsmTagMapperSource.HOUSTON; +import static org.opentripplanner.osm.tagmapping.OsmTagMapperSource.PORTLAND; import java.io.File; import java.util.Arrays; @@ -18,14 +18,13 @@ import java.util.Set; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.framework.text.Table; -import org.opentripplanner.framework.text.TableBuilder; -import org.opentripplanner.generate.doc.framework.DocsTestConstants; import org.opentripplanner.generate.doc.framework.GeneratesDocumentation; -import org.opentripplanner.openstreetmap.tagmapping.OsmTagMapper; -import org.opentripplanner.openstreetmap.tagmapping.OsmTagMapperSource; -import org.opentripplanner.openstreetmap.wayproperty.SafetyFeatures; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; +import org.opentripplanner.osm.tagmapping.OsmTagMapper; +import org.opentripplanner.osm.tagmapping.OsmTagMapperSource; +import org.opentripplanner.osm.wayproperty.SafetyFeatures; +import org.opentripplanner.osm.wayproperty.WayPropertySet; +import org.opentripplanner.utils.text.Table; +import org.opentripplanner.utils.text.TableBuilder; @GeneratesDocumentation public class OsmMapperDocTest { diff --git a/src/test/java/org/opentripplanner/generate/doc/RideHailingDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/RideHailingDocTest.java similarity index 97% rename from src/test/java/org/opentripplanner/generate/doc/RideHailingDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/RideHailingDocTest.java index 2d04e002413..fe959d9138d 100644 --- a/src/test/java/org/opentripplanner/generate/doc/RideHailingDocTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/RideHailingDocTest.java @@ -4,11 +4,11 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; +import static org.opentripplanner.utils.text.MarkdownFormatter.HEADER_4; import java.io.File; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java similarity index 97% rename from src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java index b4725c5e2a1..c51660a9a60 100644 --- a/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java @@ -4,13 +4,13 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_3; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceJsonExample; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersDetails; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersTable; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; +import static org.opentripplanner.utils.text.MarkdownFormatter.HEADER_3; import java.io.File; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java similarity index 97% rename from src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java index 77490c506fd..cdb10e28c6a 100644 --- a/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java @@ -4,13 +4,13 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_3; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceJsonExample; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersDetails; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersTable; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; +import static org.opentripplanner.utils.text.MarkdownFormatter.HEADER_3; import java.io.File; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/generate/doc/RoutingModeDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/RoutingModeDocTest.java similarity index 100% rename from src/test/java/org/opentripplanner/generate/doc/RoutingModeDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/RoutingModeDocTest.java diff --git a/src/test/java/org/opentripplanner/generate/doc/SiriAzureConfigDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/SiriAzureConfigDocTest.java similarity index 98% rename from src/test/java/org/opentripplanner/generate/doc/SiriAzureConfigDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/SiriAzureConfigDocTest.java index fcf93770f38..003b29ebcbb 100644 --- a/src/test/java/org/opentripplanner/generate/doc/SiriAzureConfigDocTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/SiriAzureConfigDocTest.java @@ -4,11 +4,11 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; +import static org.opentripplanner.utils.text.MarkdownFormatter.HEADER_4; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.File; diff --git a/src/test/java/org/opentripplanner/generate/doc/SiriConfigDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/SiriConfigDocTest.java similarity index 98% rename from src/test/java/org/opentripplanner/generate/doc/SiriConfigDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/SiriConfigDocTest.java index 71df3027c7d..b53c5370b53 100644 --- a/src/test/java/org/opentripplanner/generate/doc/SiriConfigDocTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/SiriConfigDocTest.java @@ -4,11 +4,11 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; +import static org.opentripplanner.utils.text.MarkdownFormatter.HEADER_4; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.File; diff --git a/src/test/java/org/opentripplanner/generate/doc/SiriGooglePubSubConfigDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/SiriGooglePubSubConfigDocTest.java similarity index 98% rename from src/test/java/org/opentripplanner/generate/doc/SiriGooglePubSubConfigDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/SiriGooglePubSubConfigDocTest.java index ce414b298d0..c6daed2e4b0 100644 --- a/src/test/java/org/opentripplanner/generate/doc/SiriGooglePubSubConfigDocTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/SiriGooglePubSubConfigDocTest.java @@ -4,11 +4,11 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; +import static org.opentripplanner.utils.text.MarkdownFormatter.HEADER_4; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.File; diff --git a/src/test/java/org/opentripplanner/generate/doc/StopConsolidationDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/StopConsolidationDocTest.java similarity index 100% rename from src/test/java/org/opentripplanner/generate/doc/StopConsolidationDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/StopConsolidationDocTest.java diff --git a/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java similarity index 98% rename from src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java index 7a3f2969c4d..234d4c68b33 100644 --- a/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java @@ -4,11 +4,11 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; +import static org.opentripplanner.utils.text.MarkdownFormatter.HEADER_4; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.File; diff --git a/src/test/java/org/opentripplanner/generate/doc/VehicleParkingDocTest.java b/application/src/test/java/org/opentripplanner/generate/doc/VehicleParkingDocTest.java similarity index 97% rename from src/test/java/org/opentripplanner/generate/doc/VehicleParkingDocTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/VehicleParkingDocTest.java index caffafdf72b..cca0d45d0f5 100644 --- a/src/test/java/org/opentripplanner/generate/doc/VehicleParkingDocTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/VehicleParkingDocTest.java @@ -4,11 +4,11 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; +import static org.opentripplanner.utils.text.MarkdownFormatter.HEADER_4; import java.io.File; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/generate/doc/framework/AbstractTable.java b/application/src/test/java/org/opentripplanner/generate/doc/framework/AbstractTable.java similarity index 91% rename from src/test/java/org/opentripplanner/generate/doc/framework/AbstractTable.java rename to application/src/test/java/org/opentripplanner/generate/doc/framework/AbstractTable.java index 1805b8e6dde..0af3cc938cf 100644 --- a/src/test/java/org/opentripplanner/generate/doc/framework/AbstractTable.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/framework/AbstractTable.java @@ -1,18 +1,18 @@ package org.opentripplanner.generate.doc.framework; -import static org.opentripplanner.framework.text.MarkdownFormatter.code; -import static org.opentripplanner.framework.text.MarkdownFormatter.escapeInTable; import static org.opentripplanner.generate.doc.framework.NodeAdapterHelper.anchor; import static org.opentripplanner.standalone.config.framework.json.ConfigType.ENUM_MAP; import static org.opentripplanner.standalone.config.framework.json.ConfigType.ENUM_SET; +import static org.opentripplanner.utils.text.MarkdownFormatter.code; +import static org.opentripplanner.utils.text.MarkdownFormatter.escapeInTable; import java.util.List; -import org.opentripplanner.framework.text.MarkdownFormatter; -import org.opentripplanner.framework.text.Table; -import org.opentripplanner.framework.text.TableBuilder; import org.opentripplanner.standalone.config.framework.json.ConfigType; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; import org.opentripplanner.standalone.config.framework.json.NodeInfo; +import org.opentripplanner.utils.text.MarkdownFormatter; +import org.opentripplanner.utils.text.Table; +import org.opentripplanner.utils.text.TableBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/test/java/org/opentripplanner/generate/doc/framework/DocBuilder.java b/application/src/test/java/org/opentripplanner/generate/doc/framework/DocBuilder.java similarity index 94% rename from src/test/java/org/opentripplanner/generate/doc/framework/DocBuilder.java rename to application/src/test/java/org/opentripplanner/generate/doc/framework/DocBuilder.java index a105adb62d6..ea62f3a052c 100644 --- a/src/test/java/org/opentripplanner/generate/doc/framework/DocBuilder.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/framework/DocBuilder.java @@ -1,12 +1,12 @@ package org.opentripplanner.generate.doc.framework; -import static org.opentripplanner.framework.text.MarkdownFormatter.NEW_LINE; +import static org.opentripplanner.utils.text.MarkdownFormatter.NEW_LINE; import com.fasterxml.jackson.databind.JsonNode; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.framework.text.MarkdownFormatter; import org.opentripplanner.standalone.config.framework.json.EnumMapper; +import org.opentripplanner.utils.text.MarkdownFormatter; /** * Builder for creating a new document @@ -99,6 +99,9 @@ public DocBuilder addSection(String text) { return endParagraph(); } + /** + * Adds a JSON snippet which is formatted as a fenced code block. + */ public void addExample(String comment, JsonNode body) { buffer.append(TemplateUtil.jsonExample(body, comment)); } diff --git a/src/test/java/org/opentripplanner/generate/doc/framework/DocBuilderTest.java b/application/src/test/java/org/opentripplanner/generate/doc/framework/DocBuilderTest.java similarity index 92% rename from src/test/java/org/opentripplanner/generate/doc/framework/DocBuilderTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/framework/DocBuilderTest.java index 8885a400af8..1a9796e9aac 100644 --- a/src/test/java/org/opentripplanner/generate/doc/framework/DocBuilderTest.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/framework/DocBuilderTest.java @@ -1,7 +1,7 @@ package org.opentripplanner.generate.doc.framework; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_1; +import static org.opentripplanner.utils.text.MarkdownFormatter.HEADER_1; import java.util.Arrays; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/generate/doc/framework/DocsTestConstants.java b/application/src/test/java/org/opentripplanner/generate/doc/framework/DocsTestConstants.java similarity index 68% rename from src/test/java/org/opentripplanner/generate/doc/framework/DocsTestConstants.java rename to application/src/test/java/org/opentripplanner/generate/doc/framework/DocsTestConstants.java index a7f7afa806a..e646625ec24 100644 --- a/src/test/java/org/opentripplanner/generate/doc/framework/DocsTestConstants.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/framework/DocsTestConstants.java @@ -9,24 +9,25 @@ */ public interface DocsTestConstants { Logger LOG = LoggerFactory.getLogger(DocsTestConstants.class); - File DOC_ROOT = new File("doc"); + File DOC_ROOT = new File("../doc"); File TEMPLATE_PATH = new File(DOC_ROOT, "templates"); File USER_DOC_PATH = new File(DOC_ROOT, "user"); /** - * This method return {@code true} if the /docs directory is available. If not, a warning is + * This method return {@code true} if both the /doc/user and /doc/templates directories are available. If not, a warning is * logged and the method returns {@code false}. This is used by the {@link GeneratesDocumentation} * annotation. */ static boolean docsExistOrWarn() { - if (USER_DOC_PATH.exists()) { + if (USER_DOC_PATH.exists() && TEMPLATE_PATH.exists()) { return true; } + LOG.warn( """ - SKIP TEST - '/docs' NOT FOUND + SKIP TEST - '/doc/user' or '/doc/templates' NOT FOUND - The doc/templates directory might not be available if you run the tests outside the + The /doc/user and /doc/templates directories might not be available if you run the tests outside the root of the projects. This may happen if the project root is not the working directory, if you run tests using jar files or in a Maven multi-module project. diff --git a/src/test/java/org/opentripplanner/generate/doc/framework/GeneratesDocumentation.java b/application/src/test/java/org/opentripplanner/generate/doc/framework/GeneratesDocumentation.java similarity index 92% rename from src/test/java/org/opentripplanner/generate/doc/framework/GeneratesDocumentation.java rename to application/src/test/java/org/opentripplanner/generate/doc/framework/GeneratesDocumentation.java index d8ce7a529d2..2dc099b2a0b 100644 --- a/src/test/java/org/opentripplanner/generate/doc/framework/GeneratesDocumentation.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/framework/GeneratesDocumentation.java @@ -8,7 +8,7 @@ import org.junit.jupiter.api.condition.EnabledIf; /** - * Use this annotation on tests that generate(access) the /docs directory outside the + * Use this annotation on tests that generate(access) the /doc directory outside the * source/resource. *

    * All tests annotated with this annotation is tagged with "docs". You may include or exclude diff --git a/src/test/java/org/opentripplanner/generate/doc/framework/JsonExampleBuilder.java b/application/src/test/java/org/opentripplanner/generate/doc/framework/JsonExampleBuilder.java similarity index 100% rename from src/test/java/org/opentripplanner/generate/doc/framework/JsonExampleBuilder.java rename to application/src/test/java/org/opentripplanner/generate/doc/framework/JsonExampleBuilder.java diff --git a/src/test/java/org/opentripplanner/generate/doc/framework/NodeAdapterHelper.java b/application/src/test/java/org/opentripplanner/generate/doc/framework/NodeAdapterHelper.java similarity index 100% rename from src/test/java/org/opentripplanner/generate/doc/framework/NodeAdapterHelper.java rename to application/src/test/java/org/opentripplanner/generate/doc/framework/NodeAdapterHelper.java diff --git a/src/test/java/org/opentripplanner/generate/doc/framework/ParameterDetailsList.java b/application/src/test/java/org/opentripplanner/generate/doc/framework/ParameterDetailsList.java similarity index 98% rename from src/test/java/org/opentripplanner/generate/doc/framework/ParameterDetailsList.java rename to application/src/test/java/org/opentripplanner/generate/doc/framework/ParameterDetailsList.java index 6593c7c0359..ea165d3dc16 100644 --- a/src/test/java/org/opentripplanner/generate/doc/framework/ParameterDetailsList.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/framework/ParameterDetailsList.java @@ -5,11 +5,11 @@ import static org.opentripplanner.standalone.config.framework.json.ConfigType.ENUM_SET; import java.util.EnumSet; -import org.opentripplanner.framework.text.MarkdownFormatter; import org.opentripplanner.standalone.config.framework.json.ConfigType; import org.opentripplanner.standalone.config.framework.json.EnumMapper; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; import org.opentripplanner.standalone.config.framework.json.NodeInfo; +import org.opentripplanner.utils.text.MarkdownFormatter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/test/java/org/opentripplanner/generate/doc/framework/ParameterSummaryTable.java b/application/src/test/java/org/opentripplanner/generate/doc/framework/ParameterSummaryTable.java similarity index 75% rename from src/test/java/org/opentripplanner/generate/doc/framework/ParameterSummaryTable.java rename to application/src/test/java/org/opentripplanner/generate/doc/framework/ParameterSummaryTable.java index f95b76b8a0f..8712c0fe47d 100644 --- a/src/test/java/org/opentripplanner/generate/doc/framework/ParameterSummaryTable.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/framework/ParameterSummaryTable.java @@ -1,14 +1,14 @@ package org.opentripplanner.generate.doc.framework; -import static org.opentripplanner.framework.text.Table.Align.Center; -import static org.opentripplanner.framework.text.Table.Align.Left; +import static org.opentripplanner.utils.text.Table.Align.Center; +import static org.opentripplanner.utils.text.Table.Align.Left; import java.util.List; -import org.opentripplanner.framework.text.MarkdownFormatter; -import org.opentripplanner.framework.text.Table; -import org.opentripplanner.framework.text.TableBuilder; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; import org.opentripplanner.standalone.config.framework.json.NodeInfo; +import org.opentripplanner.utils.text.MarkdownFormatter; +import org.opentripplanner.utils.text.Table; +import org.opentripplanner.utils.text.TableBuilder; public class ParameterSummaryTable extends AbstractTable { diff --git a/src/test/java/org/opentripplanner/generate/doc/framework/SkipNodes.java b/application/src/test/java/org/opentripplanner/generate/doc/framework/SkipNodes.java similarity index 100% rename from src/test/java/org/opentripplanner/generate/doc/framework/SkipNodes.java rename to application/src/test/java/org/opentripplanner/generate/doc/framework/SkipNodes.java diff --git a/src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtil.java b/application/src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtil.java similarity index 100% rename from src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtil.java rename to application/src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtil.java diff --git a/src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtilTest.java b/application/src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtilTest.java similarity index 100% rename from src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtilTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/framework/TemplateUtilTest.java diff --git a/src/test/java/org/opentripplanner/generate/doc/support/ConfigTypeTable.java b/application/src/test/java/org/opentripplanner/generate/doc/support/ConfigTypeTable.java similarity index 86% rename from src/test/java/org/opentripplanner/generate/doc/support/ConfigTypeTable.java rename to application/src/test/java/org/opentripplanner/generate/doc/support/ConfigTypeTable.java index 85c9476549c..e85eee9eedb 100644 --- a/src/test/java/org/opentripplanner/generate/doc/support/ConfigTypeTable.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/support/ConfigTypeTable.java @@ -1,8 +1,8 @@ package org.opentripplanner.generate.doc.support; -import org.opentripplanner.framework.text.MarkdownFormatter; -import org.opentripplanner.framework.text.Table; import org.opentripplanner.standalone.config.framework.json.ConfigType; +import org.opentripplanner.utils.text.MarkdownFormatter; +import org.opentripplanner.utils.text.Table; @SuppressWarnings("NewClassNamingConvention") public class ConfigTypeTable { diff --git a/src/test/java/org/opentripplanner/generate/doc/support/ConfigTypeTableTest.java b/application/src/test/java/org/opentripplanner/generate/doc/support/ConfigTypeTableTest.java similarity index 100% rename from src/test/java/org/opentripplanner/generate/doc/support/ConfigTypeTableTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/support/ConfigTypeTableTest.java diff --git a/src/test/java/org/opentripplanner/generate/doc/support/OTPFeatureTable.java b/application/src/test/java/org/opentripplanner/generate/doc/support/OTPFeatureTable.java similarity index 69% rename from src/test/java/org/opentripplanner/generate/doc/support/OTPFeatureTable.java rename to application/src/test/java/org/opentripplanner/generate/doc/support/OTPFeatureTable.java index 22966028192..ccdc1337b87 100644 --- a/src/test/java/org/opentripplanner/generate/doc/support/OTPFeatureTable.java +++ b/application/src/test/java/org/opentripplanner/generate/doc/support/OTPFeatureTable.java @@ -1,12 +1,12 @@ package org.opentripplanner.generate.doc.support; -import static org.opentripplanner.framework.text.MarkdownFormatter.checkMark; -import static org.opentripplanner.framework.text.Table.Align.Center; -import static org.opentripplanner.framework.text.Table.Align.Left; +import static org.opentripplanner.utils.text.MarkdownFormatter.checkMark; +import static org.opentripplanner.utils.text.Table.Align.Center; +import static org.opentripplanner.utils.text.Table.Align.Left; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.framework.text.MarkdownFormatter; -import org.opentripplanner.framework.text.Table; +import org.opentripplanner.utils.text.MarkdownFormatter; +import org.opentripplanner.utils.text.Table; @SuppressWarnings("NewClassNamingConvention") public class OTPFeatureTable { diff --git a/src/test/java/org/opentripplanner/generate/doc/support/OTPFeatureTableTest.java b/application/src/test/java/org/opentripplanner/generate/doc/support/OTPFeatureTableTest.java similarity index 100% rename from src/test/java/org/opentripplanner/generate/doc/support/OTPFeatureTableTest.java rename to application/src/test/java/org/opentripplanner/generate/doc/support/OTPFeatureTableTest.java diff --git a/src/test/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummaryTest.java b/application/src/test/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummaryTest.java similarity index 94% rename from src/test/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummaryTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummaryTest.java index 6524d53547e..989e2ca2016 100644 --- a/src/test/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummaryTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/issue/api/DataImportIssueSummaryTest.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.collection.ListUtils; +import org.opentripplanner.utils.collection.ListUtils; class DataImportIssueSummaryTest { diff --git a/src/test/java/org/opentripplanner/graph_builder/issue/report/DataImportIssueReporterTest.java b/application/src/test/java/org/opentripplanner/graph_builder/issue/report/DataImportIssueReporterTest.java similarity index 100% rename from src/test/java/org/opentripplanner/graph_builder/issue/report/DataImportIssueReporterTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/issue/report/DataImportIssueReporterTest.java diff --git a/src/test/java/org/opentripplanner/graph_builder/module/DirectTransferGeneratorTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/DirectTransferGeneratorTest.java similarity index 85% rename from src/test/java/org/opentripplanner/graph_builder/module/DirectTransferGeneratorTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/DirectTransferGeneratorTest.java index ebde5cbdfe8..8a17e5258d8 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/DirectTransferGeneratorTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/DirectTransferGeneratorTest.java @@ -16,7 +16,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; import org.opentripplanner.TestOtpModel; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.model.PathTransfer; import org.opentripplanner.routing.algorithm.GraphRoutingTest; @@ -26,11 +25,12 @@ import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.street.model.vertex.TransitStopVertex; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.network.StopPattern; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This creates a graph with trip patterns @@ -54,7 +54,7 @@ class DirectTransferGeneratorTest extends GraphRoutingTest { public void testDirectTransfersWithoutPatterns() { var otpModel = model(false); var graph = otpModel.graph(); - var transitModel = otpModel.transitModel(); + var timetableRepository = otpModel.timetableRepository(); var req = new RouteRequest(); req.journey().transfer().setMode(StreetMode.WALK); var transferRequests = List.of(req); @@ -62,14 +62,14 @@ public void testDirectTransfersWithoutPatterns() { new DirectTransferGenerator( graph, - transitModel, + timetableRepository, DataImportIssueStore.NOOP, MAX_TRANSFER_DURATION, transferRequests ) .buildGraph(); - assertTransfers(transitModel.getAllPathTransfers()); + assertTransfers(timetableRepository.getAllPathTransfers()); } @Test @@ -77,14 +77,14 @@ public void testDirectTransfersWithPatterns() { var otpModel = model(true); var graph = otpModel.graph(); graph.hasStreets = false; - var transitModel = otpModel.transitModel(); + var timetableRepository = otpModel.timetableRepository(); var req = new RouteRequest(); req.journey().transfer().setMode(StreetMode.WALK); var transferRequests = List.of(req); new DirectTransferGenerator( graph, - transitModel, + timetableRepository, DataImportIssueStore.NOOP, MAX_TRANSFER_DURATION, transferRequests @@ -92,7 +92,7 @@ public void testDirectTransfersWithPatterns() { .buildGraph(); assertTransfers( - transitModel.getAllPathTransfers(), + timetableRepository.getAllPathTransfers(), tr(S0, 556, S11), tr(S0, 935, S21), tr(S11, 751, S21), @@ -111,12 +111,12 @@ public void testDirectTransfersWithRestrictedPatterns() { var otpModel = model(true, true); var graph = otpModel.graph(); graph.hasStreets = false; - var transitModel = otpModel.transitModel(); + var timetableRepository = otpModel.timetableRepository(); var transferRequests = List.of(new RouteRequest()); new DirectTransferGenerator( graph, - transitModel, + timetableRepository, DataImportIssueStore.NOOP, MAX_TRANSFER_DURATION, transferRequests @@ -124,7 +124,7 @@ public void testDirectTransfersWithRestrictedPatterns() { .buildGraph(); assertTransfers( - transitModel.getAllPathTransfers(), + timetableRepository.getAllPathTransfers(), tr(S0, 2780, S12), tr(S0, 935, S21), tr(S11, 2224, S12), @@ -148,18 +148,18 @@ public void testSingleRequestWithoutPatterns() { var otpModel = model(false); var graph = otpModel.graph(); graph.hasStreets = true; - var transitModel = otpModel.transitModel(); + var timetableRepository = otpModel.timetableRepository(); new DirectTransferGenerator( graph, - transitModel, + timetableRepository, DataImportIssueStore.NOOP, MAX_TRANSFER_DURATION, transferRequests ) .buildGraph(); - assertTransfers(transitModel.getAllPathTransfers()); + assertTransfers(timetableRepository.getAllPathTransfers()); } @Test @@ -171,11 +171,11 @@ public void testSingleRequestWithPatterns() { var otpModel = model(true); var graph = otpModel.graph(); graph.hasStreets = true; - var transitModel = otpModel.transitModel(); + var timetableRepository = otpModel.timetableRepository(); new DirectTransferGenerator( graph, - transitModel, + timetableRepository, DataImportIssueStore.NOOP, MAX_TRANSFER_DURATION, transferRequests @@ -183,7 +183,7 @@ public void testSingleRequestWithPatterns() { .buildGraph(); assertTransfers( - transitModel.getAllPathTransfers(), + timetableRepository.getAllPathTransfers(), tr(S0, 100, List.of(V0, V11), S11), tr(S0, 100, List.of(V0, V21), S21), tr(S11, 100, List.of(V11, V21), S21) @@ -203,18 +203,18 @@ public void testMultipleRequestsWithoutPatterns() { var otpModel = model(false); var graph = otpModel.graph(); graph.hasStreets = true; - var transitModel = otpModel.transitModel(); + var timetableRepository = otpModel.timetableRepository(); new DirectTransferGenerator( graph, - transitModel, + timetableRepository, DataImportIssueStore.NOOP, MAX_TRANSFER_DURATION, transferRequests ) .buildGraph(); - assertTransfers(transitModel.getAllPathTransfers()); + assertTransfers(timetableRepository.getAllPathTransfers()); } @Test @@ -230,11 +230,11 @@ public void testMultipleRequestsWithPatterns() { TestOtpModel model = model(true); var graph = model.graph(); graph.hasStreets = true; - var transitModel = model.transitModel(); + var timetableRepository = model.timetableRepository(); new DirectTransferGenerator( graph, - transitModel, + timetableRepository, DataImportIssueStore.NOOP, MAX_TRANSFER_DURATION, transferRequests @@ -242,7 +242,7 @@ public void testMultipleRequestsWithPatterns() { .buildGraph(); assertTransfers( - transitModel.getAllPathTransfers(), + timetableRepository.getAllPathTransfers(), tr(S0, 100, List.of(V0, V11), S11), tr(S0, 100, List.of(V0, V21), S21), tr(S11, 100, List.of(V11, V21), S21), @@ -256,21 +256,21 @@ public void testTransferOnIsolatedStations() { var graph = otpModel.graph(); graph.hasStreets = false; - var transitModel = otpModel.transitModel(); + var timetableRepository = otpModel.timetableRepository(); var req = new RouteRequest(); req.journey().transfer().setMode(StreetMode.WALK); var transferRequests = List.of(req); new DirectTransferGenerator( graph, - transitModel, + timetableRepository, DataImportIssueStore.NOOP, MAX_TRANSFER_DURATION, transferRequests ) .buildGraph(); - assertTrue(transitModel.getAllPathTransfers().isEmpty()); + assertTrue(timetableRepository.getAllPathTransfers().isEmpty()); } private TestOtpModel model(boolean addPatterns) { @@ -290,13 +290,18 @@ private TestOtpModel model( new Builder() { @Override public void build() { - S0 = stop("S0", 47.495, 19.001, withNoTransfersOnStations); - S11 = stop("S11", 47.500, 19.001, withNoTransfersOnStations); - S12 = stop("S12", 47.520, 19.001, withNoTransfersOnStations); - S13 = stop("S13", 47.540, 19.001, withNoTransfersOnStations); - S21 = stop("S21", 47.500, 19.011, withNoTransfersOnStations); - S22 = stop("S22", 47.520, 19.011, withNoTransfersOnStations); - S23 = stop("S23", 47.540, 19.011, withNoTransfersOnStations); + var station = stationEntity( + "1", + builder -> builder.withTransfersNotAllowed(withNoTransfersOnStations) + ); + + S0 = stop("S0", 47.495, 19.001, station); + S11 = stop("S11", 47.500, 19.001, station); + S12 = stop("S12", 47.520, 19.001, station); + S13 = stop("S13", 47.540, 19.001, station); + S21 = stop("S21", 47.500, 19.011, station); + S22 = stop("S22", 47.520, 19.011, station); + S23 = stop("S23", 47.540, 19.011, station); V0 = intersection("V0", 47.495, 19.000); V11 = intersection("V11", 47.500, 19.000); @@ -327,11 +332,11 @@ public void build() { street(V11, V22, 110, StreetTraversalPermission.PEDESTRIAN_AND_BICYCLE); if (addPatterns) { - var agency = TransitModelForTest.agency("Agency"); + var agency = TimetableRepositoryForTest.agency("Agency"); tripPattern( TripPattern - .of(TransitModelForTest.id("TP1")) + .of(TimetableRepositoryForTest.id("TP1")) .withRoute(route("R1", TransitMode.BUS, agency)) .withStopPattern( new StopPattern(List.of(st(S11, !withBoardingConstraint, true), st(S12), st(S13))) @@ -341,7 +346,7 @@ public void build() { tripPattern( TripPattern - .of(TransitModelForTest.id("TP2")) + .of(TimetableRepositoryForTest.id("TP2")) .withRoute(route("R2", TransitMode.BUS, agency)) .withStopPattern(new StopPattern(List.of(st(S21), st(S22), st(S23)))) .build() diff --git a/src/test/java/org/opentripplanner/graph_builder/module/ElevationModuleTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/ElevationModuleTest.java similarity index 100% rename from src/test/java/org/opentripplanner/graph_builder/module/ElevationModuleTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/ElevationModuleTest.java diff --git a/src/test/java/org/opentripplanner/graph_builder/module/GtfsFeedIdTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/GtfsFeedIdTest.java similarity index 96% rename from src/test/java/org/opentripplanner/graph_builder/module/GtfsFeedIdTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/GtfsFeedIdTest.java index 133ec71070a..f1d6f2e8e77 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/GtfsFeedIdTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/GtfsFeedIdTest.java @@ -5,7 +5,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.stream.Stream; -import javax.annotation.Nonnull; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -36,7 +35,6 @@ void keepUnderscore() { assertEquals("feed_id_", feedId("feed_id_")); } - @Nonnull private static String feedId(String input) { var id = new GtfsFeedId.Builder().id(input).build().getId(); assertNotNull(id); diff --git a/src/test/java/org/opentripplanner/graph_builder/module/GtfsModuleTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/GtfsModuleTest.java similarity index 81% rename from src/test/java/org/opentripplanner/graph_builder/module/GtfsModuleTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/GtfsModuleTest.java index 8123661990e..75f7077eb7d 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/GtfsModuleTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/GtfsModuleTest.java @@ -18,8 +18,8 @@ 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; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; class GtfsModuleTest { @@ -30,14 +30,14 @@ void addShapesForFrequencyTrips() { var bundle = new GtfsBundle(ConstantsForTests.SIMPLE_GTFS); var module = new GtfsModule( List.of(bundle), - model.transitModel, + model.timetableRepository, model.graph, ServiceDateInterval.unbounded() ); module.buildGraph(); - var frequencyTripPattern = model.transitModel + var frequencyTripPattern = model.timetableRepository .getAllTripPatterns() .stream() .filter(p -> !p.getScheduledTimetable().getFrequencyEntries().isEmpty()) @@ -49,7 +49,7 @@ void addShapesForFrequencyTrips() { assertNotNull(tripPattern.getGeometry()); assertNotNull(tripPattern.getHopGeometry(0)); - var pattern = model.transitModel.getTripPatternForId(tripPattern.getId()); + var pattern = model.timetableRepository.getTripPatternForId(tripPattern.getId()); assertNotNull(pattern.getGeometry()); assertNotNull(pattern.getHopGeometry(0)); } @@ -61,7 +61,7 @@ void duplicateFeedId() { var module = new GtfsModule( bundles, - model.transitModel, + model.timetableRepository, model.graph, ServiceDateInterval.unbounded() ); @@ -70,13 +70,13 @@ void duplicateFeedId() { private static TestModels buildTestModel() { var deduplicator = new Deduplicator(); - var stopModel = new StopModel(); + var siteRepository = new SiteRepository(); var graph = new Graph(deduplicator); - var transitModel = new TransitModel(stopModel, deduplicator); - return new TestModels(graph, transitModel); + var timetableRepository = new TimetableRepository(siteRepository, deduplicator); + return new TestModels(graph, timetableRepository); } - record TestModels(Graph graph, TransitModel transitModel) {} + record TestModels(Graph graph, TimetableRepository timetableRepository) {} static GtfsBundle bundle(String feedId) { var b = new GtfsBundle(ResourceLoader.of(GtfsModuleTest.class).file("/gtfs/interlining")); @@ -109,14 +109,17 @@ void interline(List bundles, int expectedTransfers) { var module = new GtfsModule( bundles, - model.transitModel, + model.timetableRepository, model.graph, ServiceDateInterval.unbounded() ); module.buildGraph(); - assertEquals(expectedTransfers, model.transitModel.getTransferService().listAll().size()); + assertEquals( + expectedTransfers, + model.timetableRepository.getTransferService().listAll().size() + ); } } } diff --git a/src/test/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModuleTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModuleTest.java similarity index 89% rename from src/test/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModuleTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModuleTest.java index 4756608f57d..c55e482e533 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModuleTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModuleTest.java @@ -12,8 +12,9 @@ import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.graph_builder.module.osm.OsmModule; -import org.opentripplanner.openstreetmap.OsmProvider; +import org.opentripplanner.osm.OsmProvider; import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; import org.opentripplanner.street.model.edge.AreaEdge; import org.opentripplanner.street.model.edge.BoardingLocationToStopLink; import org.opentripplanner.street.model.edge.Edge; @@ -24,12 +25,12 @@ import org.opentripplanner.street.model.vertex.VertexFactory; import org.opentripplanner.street.model.vertex.VertexLabel; import org.opentripplanner.test.support.ResourceLoader; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; /** * We test that the platform area at Herrenberg station (https://www.openstreetmap.org/way/27558650) @@ -37,7 +38,7 @@ */ class OsmBoardingLocationsModuleTest { - private final TransitModelForTest testModel = TransitModelForTest.of(); + private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of(); File file = ResourceLoader .of(OsmBoardingLocationsModuleTest.class) @@ -69,7 +70,7 @@ static Stream testCases() { void addAndLinkBoardingLocations(boolean areaVisibility, Set linkedVertices) { var deduplicator = new Deduplicator(); var graph = new Graph(deduplicator); - var transitModel = new TransitModel(new StopModel(), deduplicator); + var timetableRepository = new TimetableRepository(new SiteRepository(), deduplicator); var factory = new VertexFactory(graph); var provider = new OsmProvider(file, false); @@ -83,7 +84,7 @@ void addAndLinkBoardingLocations(boolean areaVisibility, Set linkedVerti new NonLocalizedString("bus stop not connected to street network") ); var osmModule = OsmModule - .of(provider, graph) + .of(provider, graph, new DefaultVehicleParkingRepository()) .withBoardingAreaRefTags(Set.of("ref", "ref:IFOPT")) .withAreaVisibility(areaVisibility) .build(); @@ -97,8 +98,8 @@ void addAndLinkBoardingLocations(boolean areaVisibility, Set linkedVerti TransitStopVertex.of().withStop(busStop).withModes(Set.of(TransitMode.BUS)) ); - transitModel.index(); - graph.index(transitModel.getStopModel()); + timetableRepository.index(); + graph.index(timetableRepository.getSiteRepository()); assertEquals(0, busVertex.getIncoming().size()); assertEquals(0, busVertex.getOutgoing().size()); @@ -106,7 +107,7 @@ void addAndLinkBoardingLocations(boolean areaVisibility, Set linkedVerti assertEquals(0, platformVertex.getIncoming().size()); assertEquals(0, platformVertex.getOutgoing().size()); - new OsmBoardingLocationsModule(graph, transitModel).buildGraph(); + new OsmBoardingLocationsModule(graph, timetableRepository).buildGraph(); var boardingLocations = graph.getVerticesOfType(OsmBoardingLocationVertex.class); assertEquals(5, boardingLocations.size()); // 3 nodes connected to the street network, plus one "floating" and one area centroid created by the module diff --git a/src/test/java/org/opentripplanner/graph_builder/module/StreetLinkerModuleTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/StreetLinkerModuleTest.java similarity index 54% rename from src/test/java/org/opentripplanner/graph_builder/module/StreetLinkerModuleTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/StreetLinkerModuleTest.java index 06b10575ef9..4f54581fdb8 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/StreetLinkerModuleTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/StreetLinkerModuleTest.java @@ -1,31 +1,42 @@ package org.opentripplanner.graph_builder.module; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner._support.geometry.Coordinates.KONGSBERG_PLATFORM_1; import static org.opentripplanner.street.model.StreetTraversalPermission.CAR; import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; +import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner.ext.flex.trip.UnscheduledTrip; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; +import org.opentripplanner.model.StopTime; import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; import org.opentripplanner.street.model._data.StreetModelForTest; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.edge.StreetTransitStopLink; import org.opentripplanner.street.model.vertex.SplitterVertex; import org.opentripplanner.street.model.vertex.TransitStopVertex; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; +import org.opentripplanner.transit.model.network.CarAccess; +import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.transit.model.network.StopPattern; +import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.transit.model.timetable.RealTimeTripTimes; +import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.transit.model.timetable.TripTimesFactory; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; class StreetLinkerModuleTest { @@ -41,7 +52,7 @@ void linkingIsIdempotent() { module.buildGraph(); assertTrue(model.stopVertex().isConnectedToGraph()); - assertEquals(1, model.stopVertex().getOutgoing().size()); + assertThat(model.stopVertex().getOutgoing()).hasSize(1); } @Test @@ -53,7 +64,7 @@ void linkRegularStop() { assertTrue(model.stopVertex().isConnectedToGraph()); - assertEquals(1, model.stopVertex().getOutgoing().size()); + assertThat(model.stopVertex().getOutgoing()).hasSize(1); var outgoing = model.outgoingLinks().getFirst(); assertInstanceOf(StreetTransitStopLink.class, outgoing); @@ -67,7 +78,7 @@ void linkRegularStop() { void linkFlexStop() { OTPFeature.FlexRouting.testOn(() -> { var model = new TestModel(); - var flexTrip = TransitModelForTest.of().unscheduledTrip("flex", model.stop()); + var flexTrip = TimetableRepositoryForTest.of().unscheduledTrip("flex", model.stop()); model.withFlexTrip(flexTrip); var module = model.streetLinkerModule(); @@ -77,7 +88,7 @@ void linkFlexStop() { assertTrue(model.stopVertex().isConnectedToGraph()); // stop is used by a flex trip, needs to be linked to both the walk and car edge - assertEquals(2, model.stopVertex().getOutgoing().size()); + assertThat(model.stopVertex().getOutgoing()).hasSize(2); var linkToWalk = model.outgoingLinks().getFirst(); SplitterVertex walkSplit = (SplitterVertex) linkToWalk.getToVertex(); @@ -92,12 +103,43 @@ void linkFlexStop() { }); } + @Test + void linkCarsAllowedStop() { + var model = new TestModel(); + var carsAllowedTrip = TimetableRepositoryForTest + .of() + .trip("carsAllowedTrip") + .withCarsAllowed(CarAccess.ALLOWED) + .build(); + model.withCarsAllowedTrip(carsAllowedTrip, model.stop()); + + var module = model.streetLinkerModule(); + + module.buildGraph(); + + assertTrue(model.stopVertex().isConnectedToGraph()); + + // Because the stop is used by a carsAllowed trip it needs to be linked to both the walk and car edge + assertThat(model.stopVertex().getOutgoing()).hasSize(2); + var linkToWalk = model.outgoingLinks().getFirst(); + SplitterVertex walkSplit = (SplitterVertex) linkToWalk.getToVertex(); + + assertTrue(walkSplit.isConnectedToWalkingEdge()); + assertFalse(walkSplit.isConnectedToDriveableEdge()); + + var linkToCar = model.outgoingLinks().getLast(); + SplitterVertex carSplit = (SplitterVertex) linkToCar.getToVertex(); + + assertFalse(carSplit.isConnectedToWalkingEdge()); + assertTrue(carSplit.isConnectedToDriveableEdge()); + } + private static class TestModel { private final TransitStopVertex stopVertex; private final StreetLinkerModule module; private final RegularStop stop; - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; public TestModel() { var from = StreetModelForTest.intersectionVertex( @@ -115,7 +157,7 @@ public TestModel() { var walkableEdge = StreetModelForTest.streetEdge(from, to, PEDESTRIAN); var drivableEdge = StreetModelForTest.streetEdge(from, to, CAR); - var builder = StopModel.of(); + var builder = SiteRepository.of(); stop = builder .regularStop(id("platform-1")) @@ -123,13 +165,20 @@ public TestModel() { .build(); builder.withRegularStop(stop); - transitModel = new TransitModel(builder.build(), new Deduplicator()); + timetableRepository = new TimetableRepository(builder.build(), new Deduplicator()); stopVertex = TransitStopVertex.of().withStop(stop).build(); graph.addVertex(stopVertex); graph.hasStreets = true; - module = new StreetLinkerModule(graph, transitModel, DataImportIssueStore.NOOP, false); + module = + new StreetLinkerModule( + graph, + new DefaultVehicleParkingRepository(), + timetableRepository, + DataImportIssueStore.NOOP, + false + ); assertFalse(stopVertex.isConnectedToGraph()); assertTrue(stopVertex.getIncoming().isEmpty()); @@ -153,7 +202,35 @@ public RegularStop stop() { } public void withFlexTrip(UnscheduledTrip flexTrip) { - transitModel.addFlexTrip(flexTrip.getId(), flexTrip); + timetableRepository.addFlexTrip(flexTrip.getId(), flexTrip); + } + + public void withCarsAllowedTrip(Trip trip, StopLocation... stops) { + Route route = TimetableRepositoryForTest.route("carsAllowedRoute").build(); + var stopTimes = Arrays + .stream(stops) + .map(s -> { + var stopTime = new StopTime(); + stopTime.setStop(s); + stopTime.setArrivalTime(30); + stopTime.setDepartureTime(60); + stopTime.setTrip(trip); + return stopTime; + }) + .toList(); + StopPattern stopPattern = new StopPattern(stopTimes); + RealTimeTripTimes tripTimes = TripTimesFactory.tripTimes( + trip, + stopTimes, + timetableRepository.getDeduplicator() + ); + TripPattern tripPattern = TimetableRepositoryForTest + .tripPattern("carsAllowedTripPattern", route) + .withStopPattern(stopPattern) + .withScheduledTimeTableBuilder(builder -> builder.addTripTimes(tripTimes)) + .build(); + + timetableRepository.addTripPattern(tripPattern.getId(), tripPattern); } } } diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/TestStreetLinkerModule.java b/application/src/test/java/org/opentripplanner/graph_builder/module/TestStreetLinkerModule.java new file mode 100644 index 00000000000..551564cbb05 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/TestStreetLinkerModule.java @@ -0,0 +1,30 @@ +package org.opentripplanner.graph_builder.module; + +import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; +import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; +import org.opentripplanner.transit.service.TimetableRepository; + +public class TestStreetLinkerModule { + + /** For test only */ + public static void link(Graph graph, TimetableRepository timetableRepository) { + link(graph, new DefaultVehicleParkingRepository(), timetableRepository); + } + + public static void link( + Graph graph, + VehicleParkingRepository parkingRepository, + TimetableRepository timetableRepository + ) { + new StreetLinkerModule( + graph, + parkingRepository, + timetableRepository, + DataImportIssueStore.NOOP, + false + ) + .buildGraph(); + } +} diff --git a/src/test/java/org/opentripplanner/graph_builder/module/VehicleParkingLinkingTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/VehicleParkingLinkingTest.java similarity index 85% rename from src/test/java/org/opentripplanner/graph_builder/module/VehicleParkingLinkingTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/VehicleParkingLinkingTest.java index 23f4ffc72ca..4f0a20bfb7f 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/VehicleParkingLinkingTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/VehicleParkingLinkingTest.java @@ -2,15 +2,16 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingHelper; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingTestGraphData; +import org.opentripplanner.service.vehicleparking.VehicleParkingTestGraphData; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingHelper; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model._data.StreetModelForTest; import org.opentripplanner.street.model.edge.StreetVehicleParkingLink; @@ -18,12 +19,12 @@ import org.opentripplanner.street.model.vertex.IntersectionVertex; import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex; import org.opentripplanner.street.model.vertex.VertexFactory; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; public class VehicleParkingLinkingTest { private Graph graph; - private TransitModel transitModel; + private TimetableRepository timetableRepository; private IntersectionVertex A; private IntersectionVertex B; @@ -36,7 +37,7 @@ public void setup() { VehicleParkingTestGraphData graphData = new VehicleParkingTestGraphData(); graphData.initGraph(); graph = graphData.getGraph(); - transitModel = graphData.getTransitModel(); + timetableRepository = graphData.getTimetableRepository(); A = graphData.getAVertex(); B = graphData.getBVertex(); vertexFactory = new VertexFactory(graph); @@ -53,7 +54,7 @@ public void entranceWithVertexLinkingTest() { .build(); var parkingVertex = vertexFactory.vehicleParkingEntrance(parking); - TestStreetLinkerModule.link(graph, transitModel); + TestStreetLinkerModule.link(graph, timetableRepository); assertEquals(1, parkingVertex.getOutgoing().size()); parkingVertex.getOutgoing().forEach(e -> assertEquals(e.getToVertex(), A)); @@ -76,7 +77,7 @@ public void entranceWithoutVertexLinkingTest() { .build(); var parkingVertex = vertexFactory.vehicleParkingEntrance(parking.getEntrances().get(0)); - TestStreetLinkerModule.link(graph, transitModel); + TestStreetLinkerModule.link(graph, timetableRepository); var streetLinks = graph.getEdgesOfType(StreetVehicleParkingLink.class); assertEquals(2, streetLinks.size()); @@ -110,7 +111,7 @@ public void carParkingEntranceToAllTraversableStreetLinkingTest() { .build(); var parkingVertex = vertexFactory.vehicleParkingEntrance(parking.getEntrances().get(0)); - TestStreetLinkerModule.link(graph, transitModel); + TestStreetLinkerModule.link(graph, timetableRepository); var streetLinks = graph.getEdgesOfType(StreetVehicleParkingLink.class); assertEquals(4, streetLinks.size()); @@ -145,7 +146,7 @@ public void removeEntranceWithNonExistingVertexTest() { graph.remove(A); - TestStreetLinkerModule.link(graph, transitModel); + TestStreetLinkerModule.link(graph, timetableRepository); assertEquals(1, vehicleParking.getEntrances().size()); @@ -169,13 +170,13 @@ public void removeVehicleParkingWithOneEntranceAndNonExistingVertexTest() { ) .build(); - var vehicleParkingService = graph.getVehicleParkingService(); + var vehicleParkingService = new DefaultVehicleParkingRepository(); vehicleParkingService.updateVehicleParking(List.of(vehicleParking), List.of()); helper.linkVehicleParkingToGraph(vehicleParking); graph.remove(A); - TestStreetLinkerModule.link(graph, transitModel); + TestStreetLinkerModule.link(graph, vehicleParkingService, timetableRepository); assertEquals(0, graph.getVerticesOfType(VehicleParkingEntranceVertex.class).size()); @@ -183,6 +184,6 @@ public void removeVehicleParkingWithOneEntranceAndNonExistingVertexTest() { assertEquals(0, graph.getEdgesOfType(StreetVehicleParkingLink.class).size()); assertEquals(0, graph.getEdgesOfType(StreetVehicleParkingLink.class).size()); - assertEquals(0, vehicleParkingService.getVehicleParkings().count()); + assertEquals(0, vehicleParkingService.listVehicleParkings().size()); } } diff --git a/src/test/java/org/opentripplanner/graph_builder/module/geometry/CalculateWorldEnvelopeModuleTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/geometry/CalculateWorldEnvelopeModuleTest.java similarity index 91% rename from src/test/java/org/opentripplanner/graph_builder/module/geometry/CalculateWorldEnvelopeModuleTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/geometry/CalculateWorldEnvelopeModuleTest.java index fb7ae2b8a10..4f9a837ef6c 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/geometry/CalculateWorldEnvelopeModuleTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/geometry/CalculateWorldEnvelopeModuleTest.java @@ -3,17 +3,16 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.List; -import javax.annotation.Nonnull; import org.junit.jupiter.api.Test; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.model.vertex.VertexLabel; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.site.RegularStop; class CalculateWorldEnvelopeModuleTest { - private final TransitModelForTest testModel = TransitModelForTest.of(); + private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of(); private final List vertexes = List.of(new V(10d, 12d), new V(11d, 13d), new V(14d, 15d)); @@ -63,7 +62,6 @@ public VertexLabel getLabel() { return VertexLabel.string("%s/%s".formatted(getX(), getY())); } - @Nonnull @Override public I18NString getName() { return I18NString.of(getLabel().toString()); diff --git a/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/AdaptivePruningTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/AdaptivePruningTest.java similarity index 100% rename from src/test/java/org/opentripplanner/graph_builder/module/islandpruning/AdaptivePruningTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/AdaptivePruningTest.java diff --git a/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/EscalatorPruningTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/EscalatorPruningTest.java similarity index 100% rename from src/test/java/org/opentripplanner/graph_builder/module/islandpruning/EscalatorPruningTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/EscalatorPruningTest.java diff --git a/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningUtils.java b/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningUtils.java similarity index 68% rename from src/test/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningUtils.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningUtils.java index 59362472771..d71a60a972e 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningUtils.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningUtils.java @@ -3,11 +3,12 @@ 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.osm.OsmProvider; import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; import org.opentripplanner.transit.model.framework.Deduplicator; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; class IslandPruningUtils { @@ -21,20 +22,23 @@ static Graph buildOsmGraph( try { var deduplicator = new Deduplicator(); var graph = new Graph(deduplicator); - var transitModel = new TransitModel(new StopModel(), deduplicator); + var timetableRepository = new TimetableRepository(new SiteRepository(), deduplicator); // Add street data from OSM OsmProvider osmProvider = new OsmProvider(osmFile, true); - OsmModule osmModule = OsmModule.of(osmProvider, graph).withEdgeNamer(new TestNamer()).build(); + OsmModule osmModule = OsmModule + .of(osmProvider, graph, new DefaultVehicleParkingRepository()) + .withEdgeNamer(new TestNamer()) + .build(); osmModule.buildGraph(); - transitModel.index(); - graph.index(transitModel.getStopModel()); + timetableRepository.index(); + graph.index(timetableRepository.getSiteRepository()); // Prune floating islands and set noThru where necessary PruneIslands pruneIslands = new PruneIslands( graph, - transitModel, + timetableRepository, DataImportIssueStore.NOOP, null ); diff --git a/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/PruneNoThruIslandsTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/PruneNoThruIslandsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/graph_builder/module/islandpruning/PruneNoThruIslandsTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/PruneNoThruIslandsTest.java diff --git a/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/SubgraphOnlyFerryTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/SubgraphOnlyFerryTest.java similarity index 95% rename from src/test/java/org/opentripplanner/graph_builder/module/islandpruning/SubgraphOnlyFerryTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/SubgraphOnlyFerryTest.java index f069a518fc0..2085e7a238a 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/SubgraphOnlyFerryTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/SubgraphOnlyFerryTest.java @@ -6,13 +6,13 @@ import java.util.Set; import org.junit.jupiter.api.Test; import org.opentripplanner.street.model.vertex.TransitStopVertex; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.site.RegularStop; class SubgraphOnlyFerryTest { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final RegularStop regularStop1 = TEST_MODEL.stop("TEST-1").build(); private static final RegularStop regularStop2 = TEST_MODEL.stop("TEST-2").build(); diff --git a/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/TestNamer.java b/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/TestNamer.java similarity index 74% rename from src/test/java/org/opentripplanner/graph_builder/module/islandpruning/TestNamer.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/TestNamer.java index 4002da919d8..dc94aba993f 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/TestNamer.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/TestNamer.java @@ -4,17 +4,17 @@ import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; import org.opentripplanner.graph_builder.services.osm.EdgeNamer; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; class TestNamer implements EdgeNamer { @Override - public I18NString name(OSMWithTags way) { + public I18NString name(OsmWithTags way) { return new NonLocalizedString(String.valueOf(way.getId())); } @Override - public void recordEdges(OSMWithTags way, StreetEdgePair edge) {} + public void recordEdges(OsmWithTags way, StreetEdgePair edge) {} @Override public void postprocess() {} diff --git a/src/test/java/org/opentripplanner/graph_builder/module/linking/LinkingTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/linking/LinkingTest.java similarity index 89% rename from src/test/java/org/opentripplanner/graph_builder/module/linking/LinkingTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/linking/LinkingTest.java index 41a74fb2dd3..a6afa89707f 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/linking/LinkingTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/linking/LinkingTest.java @@ -19,8 +19,9 @@ import org.opentripplanner.framework.geometry.SphericalDistanceLibrary; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.graph_builder.module.osm.OsmModule; -import org.opentripplanner.openstreetmap.OsmProvider; +import org.opentripplanner.osm.OsmProvider; import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model._data.StreetModelForTest; import org.opentripplanner.street.model.edge.StreetEdge; @@ -32,8 +33,8 @@ import org.opentripplanner.street.model.vertex.Vertex; 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; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; public class LinkingTest { @@ -114,16 +115,16 @@ public void testStopsLinkedIdentically() { // build the graph without the added stops TestOtpModel model = buildGraphNoTransit(); Graph g1 = model.graph(); - TransitModel transitModel1 = model.transitModel(); + TimetableRepository timetableRepository1 = model.timetableRepository(); addRegularStopGrid(g1); - link(g1, transitModel1); + link(g1, timetableRepository1); TestOtpModel model2 = buildGraphNoTransit(); Graph g2 = model2.graph(); - TransitModel transitModel2 = model2.transitModel(); + TimetableRepository timetableRepository2 = model2.timetableRepository(); addExtraStops(g2); addRegularStopGrid(g2); - link(g2, transitModel2); + link(g2, timetableRepository2); var transitStopVertices = g1.getVerticesOfType(TransitStopVertex.class); assertEquals(1350, transitStopVertices.size()); @@ -150,17 +151,17 @@ public void testStopsLinkedIdentically() { /** Build a graph in Columbus, OH with no transit */ public static TestOtpModel buildGraphNoTransit() { var deduplicator = new Deduplicator(); - var stopModel = new StopModel(); + var siteRepository = new SiteRepository(); var gg = new Graph(deduplicator); - var transitModel = new TransitModel(stopModel, deduplicator); + var timetableRepository = new TimetableRepository(siteRepository, deduplicator); File file = ResourceLoader.of(LinkingTest.class).file("columbus.osm.pbf"); OsmProvider provider = new OsmProvider(file, false); - OsmModule osmModule = OsmModule.of(provider, gg).build(); + OsmModule osmModule = OsmModule.of(provider, gg, new DefaultVehicleParkingRepository()).build(); osmModule.buildGraph(); - return new TestOtpModel(gg, transitModel); + return new TestOtpModel(gg, timetableRepository); } private static List outgoingStls(final TransitStopVertex tsv) { diff --git a/src/test/java/org/opentripplanner/graph_builder/module/linking/TestGraph.java b/application/src/test/java/org/opentripplanner/graph_builder/module/linking/TestGraph.java similarity index 87% rename from src/test/java/org/opentripplanner/graph_builder/module/linking/TestGraph.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/linking/TestGraph.java index a45b8eef239..a21b7aff55a 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/linking/TestGraph.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/linking/TestGraph.java @@ -8,9 +8,9 @@ import org.opentripplanner.street.model.vertex.TransitStopVertex; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.TraverseModeSet; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; /** * Get graphs of Columbus Ohio with real OSM streets and a synthetic transit system for use in @@ -18,7 +18,7 @@ */ class TestGraph { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); /** Add a regular grid of stops to the graph */ public static void addRegularStopGrid(Graph graph) { @@ -60,9 +60,9 @@ public static void addExtraStops(Graph graph) { } /** link the stops in the graph */ - public static void link(Graph graph, TransitModel transitModel) { - transitModel.index(); - graph.index(transitModel.getStopModel()); + public static void link(Graph graph, TimetableRepository timetableRepository) { + timetableRepository.index(); + graph.index(timetableRepository.getSiteRepository()); VertexLinker linker = graph.getLinker(); diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/nearbystops/StreetNearbyStopFinderMultipleLinksTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/nearbystops/StreetNearbyStopFinderMultipleLinksTest.java new file mode 100644 index 00000000000..3466c1bfd8a --- /dev/null +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/nearbystops/StreetNearbyStopFinderMultipleLinksTest.java @@ -0,0 +1,71 @@ +package org.opentripplanner.graph_builder.module.nearbystops; + +import static com.google.common.truth.Truth.assertThat; +import static org.opentripplanner.graph_builder.module.nearbystops.StreetNearbyStopFinderTest.assertStopAtDistance; +import static org.opentripplanner.graph_builder.module.nearbystops.StreetNearbyStopFinderTest.assertZeroDistanceStop; +import static org.opentripplanner.graph_builder.module.nearbystops.StreetNearbyStopFinderTest.sort; + +import java.time.Duration; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.opentripplanner.framework.geometry.WgsCoordinate; +import org.opentripplanner.routing.algorithm.GraphRoutingTest; +import org.opentripplanner.routing.api.request.RouteRequest; +import org.opentripplanner.routing.api.request.request.StreetRequest; +import org.opentripplanner.street.model.vertex.TransitStopVertex; + +class StreetNearbyStopFinderMultipleLinksTest extends GraphRoutingTest { + + private static final WgsCoordinate origin = new WgsCoordinate(0.0, 0.0); + private TransitStopVertex stopA; + private TransitStopVertex stopB; + private TransitStopVertex stopC; + + @BeforeEach + protected void setUp() throws Exception { + modelOf( + new Builder() { + @Override + public void build() { + var A = intersection("A", origin); + var B = intersection("B", origin.moveEastMeters(100)); + var C = intersection("C", origin.moveEastMeters(200)); + + biStreet(A, B, 100); + biStreet(B, C, 100); + + stopA = stop("StopA", A.toWgsCoordinate()); + stopB = stop("StopB", B.toWgsCoordinate()); + stopC = stop("StopC", C.toWgsCoordinate()); + + biLink(A, stopA); + + // B has many links + biLink(B, stopB); + biLink(B, stopB); + biLink(B, stopB); + biLink(B, stopB); + + biLink(C, stopC); + } + } + ); + } + + @Test + void testMaxStopCountRegression() { + // Max-stop-count should work correctly even though there are multiple links B <-> stopB + var durationLimit = Duration.ofMinutes(10); + var maxStopCount = 3; + var finder = new StreetNearbyStopFinder(durationLimit, maxStopCount, null); + + var sortedNearbyStops = sort( + finder.findNearbyStops(stopA, new RouteRequest(), new StreetRequest(), false) + ); + + assertThat(sortedNearbyStops).hasSize(3); + assertZeroDistanceStop(stopA, sortedNearbyStops.get(0)); + assertStopAtDistance(stopB, 100, sortedNearbyStops.get(1)); + assertStopAtDistance(stopC, 200, sortedNearbyStops.get(2)); + } +} diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/nearbystops/StreetNearbyStopFinderTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/nearbystops/StreetNearbyStopFinderTest.java new file mode 100644 index 00000000000..aae02451b33 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/nearbystops/StreetNearbyStopFinderTest.java @@ -0,0 +1,195 @@ +package org.opentripplanner.graph_builder.module.nearbystops; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.time.Duration; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.opentripplanner.framework.geometry.WgsCoordinate; +import org.opentripplanner.routing.algorithm.GraphRoutingTest; +import org.opentripplanner.routing.api.request.RouteRequest; +import org.opentripplanner.routing.api.request.request.StreetRequest; +import org.opentripplanner.routing.graphfinder.NearbyStop; +import org.opentripplanner.street.model.vertex.TransitStopVertex; +import org.opentripplanner.street.model.vertex.Vertex; + +class StreetNearbyStopFinderTest extends GraphRoutingTest { + + private static final WgsCoordinate origin = new WgsCoordinate(0.0, 0.0); + private TransitStopVertex isolatedStop; + private TransitStopVertex stopA; + private TransitStopVertex stopB; + private TransitStopVertex stopC; + private TransitStopVertex stopD; + + @BeforeEach + protected void setUp() throws Exception { + modelOf( + new GraphRoutingTest.Builder() { + @Override + public void build() { + var isolated = intersection("isolated", origin.moveNorthMeters(1000)); + + var A = intersection("A", origin); + var B = intersection("B", origin.moveEastMeters(100)); + var C = intersection("C", origin.moveEastMeters(200)); + var D = intersection("D", origin.moveEastMeters(300)); + + biStreet(A, B, 100); + biStreet(B, C, 100); + biStreet(C, D, 100); + + isolatedStop = stop("IsolatedStop", isolated.toWgsCoordinate()); + stopA = stop("StopA", A.toWgsCoordinate()); + stopB = stop("StopB", B.toWgsCoordinate()); + stopC = stop("StopC", C.toWgsCoordinate()); + stopD = stop("StopD", D.toWgsCoordinate()); + + biLink(A, stopA); + biLink(B, stopB); + biLink(C, stopC); + biLink(D, stopD); + } + } + ); + } + + @Test + void testIsolatedStop() { + var durationLimit = Duration.ofMinutes(10); + var maxStopCount = 0; + var finder = new StreetNearbyStopFinder(durationLimit, maxStopCount, null); + + var nearbyStops = finder.findNearbyStops( + isolatedStop, + new RouteRequest(), + new StreetRequest(), + false + ); + + assertThat(nearbyStops).hasSize(1); + var nearbyStop = nearbyStops.stream().findFirst().get(); + assertZeroDistanceStop(isolatedStop, nearbyStop); + } + + @Test + void testMultipleStops() { + var durationLimit = Duration.ofMinutes(10); + var maxStopCount = 0; + var finder = new StreetNearbyStopFinder(durationLimit, maxStopCount, null); + + var sortedNearbyStops = sort( + finder.findNearbyStops(stopA, new RouteRequest(), new StreetRequest(), false) + ); + + assertThat(sortedNearbyStops).hasSize(4); + assertZeroDistanceStop(stopA, sortedNearbyStops.get(0)); + assertStopAtDistance(stopB, 100, sortedNearbyStops.get(1)); + assertStopAtDistance(stopC, 200, sortedNearbyStops.get(2)); + assertStopAtDistance(stopD, 300, sortedNearbyStops.get(3)); + } + + @Test + void testMaxStopCount() { + var durationLimit = Duration.ofMinutes(10); + var maxStopCount = 2; + var finder = new StreetNearbyStopFinder(durationLimit, maxStopCount, null); + + var sortedNearbyStops = sort( + finder.findNearbyStops(stopA, new RouteRequest(), new StreetRequest(), false) + ); + + assertThat(sortedNearbyStops).hasSize(2); + assertZeroDistanceStop(stopA, sortedNearbyStops.get(0)); + assertStopAtDistance(stopB, 100, sortedNearbyStops.get(1)); + } + + @Test + void testDurationLimit() { + // If we only allow walk for 101 seconds and speed is 1 m/s we should only be able to reach + // one extra stop. + var durationLimit = Duration.ofSeconds(101); + var maxStopCount = 0; + var routeRequest = new RouteRequest() + .withPreferences(b -> b.withWalk(walkPreferences -> walkPreferences.withSpeed(1.0))); + + var finder = new StreetNearbyStopFinder(durationLimit, maxStopCount, null); + var sortedNearbyStops = sort( + finder.findNearbyStops(stopA, routeRequest, new StreetRequest(), false) + ); + + assertThat(sortedNearbyStops).hasSize(2); + assertZeroDistanceStop(stopA, sortedNearbyStops.get(0)); + assertStopAtDistance(stopB, 100, sortedNearbyStops.get(1)); + } + + @Test + void testIgnoreStops() { + var durationLimit = Duration.ofMinutes(10); + var maxStopCount = 0; + Set ignore = Set.of(stopA, stopB); + var finder = new StreetNearbyStopFinder(durationLimit, maxStopCount, null, ignore); + + var sortedNearbyStops = sort( + finder.findNearbyStops(Set.of(stopA), new RouteRequest(), new StreetRequest(), false) + ); + + assertThat(sortedNearbyStops).hasSize(2); + assertStopAtDistance(stopC, 200, sortedNearbyStops.get(0)); + assertStopAtDistance(stopD, 300, sortedNearbyStops.get(1)); + } + + @Test + void testIgnoreStopsWithMaxStops() { + var durationLimit = Duration.ofMinutes(10); + var maxStopCount = 1; + Set ignore = Set.of(stopA, stopB); + var finder = new StreetNearbyStopFinder(durationLimit, maxStopCount, null, ignore); + + var sortedNearbyStops = sort( + finder.findNearbyStops(Set.of(stopA), new RouteRequest(), new StreetRequest(), false) + ); + + assertThat(sortedNearbyStops).hasSize(1); + assertStopAtDistance(stopC, 200, sortedNearbyStops.get(0)); + } + + static List sort(Collection stops) { + return stops.stream().sorted(Comparator.comparing(x -> x.distance)).toList(); + } + + /** + * Verify that the nearby stop is zero distance and corresponds to the expected vertex + */ + static void assertZeroDistanceStop(TransitStopVertex expected, NearbyStop nearbyStop) { + assertEquals(expected.getStop(), nearbyStop.stop); + assertEquals(0, nearbyStop.distance); + assertEquals(0, nearbyStop.edges.size()); + assertEquals(expected, nearbyStop.state.getVertex()); + assertNull(nearbyStop.state.getBackState()); + } + + /** + * Verify that the nearby stop is at a specific distance and corresponds to the expected vertex + */ + static void assertStopAtDistance( + TransitStopVertex expected, + double expectedDistance, + NearbyStop nearbyStop + ) { + assertEquals(expected.getStop(), nearbyStop.stop); + assertEquals(expectedDistance, nearbyStop.distance); + assertEquals(expected, nearbyStop.state.getVertex()); + assertFalse(nearbyStop.edges.isEmpty()); + assertNotNull(nearbyStop.state.getBackState()); + } +} diff --git a/src/test/java/org/opentripplanner/graph_builder/module/ned/MissingElevationHandlerTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/ned/MissingElevationHandlerTest.java similarity index 100% rename from src/test/java/org/opentripplanner/graph_builder/module/ned/MissingElevationHandlerTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/ned/MissingElevationHandlerTest.java diff --git a/src/test/java/org/opentripplanner/graph_builder/module/osm/DisjointSetTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/DisjointSetTest.java similarity index 100% rename from src/test/java/org/opentripplanner/graph_builder/module/osm/DisjointSetTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/DisjointSetTest.java diff --git a/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmDatabaseTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmDatabaseTest.java similarity index 94% rename from src/test/java/org/opentripplanner/graph_builder/module/osm/OsmDatabaseTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmDatabaseTest.java index 8c5671d3bf0..88003e9218f 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmDatabaseTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmDatabaseTest.java @@ -5,7 +5,7 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.openstreetmap.OsmProvider; +import org.opentripplanner.osm.OsmProvider; import org.opentripplanner.test.support.ResourceLoader; public class OsmDatabaseTest { @@ -21,7 +21,7 @@ public class OsmDatabaseTest { void bicycleRouteRelations() { var osmdb = new OsmDatabase(DataImportIssueStore.NOOP); var provider = new OsmProvider(RESOURCE_LOADER.file("ehningen-minimal.osm.pbf"), true); - provider.readOSM(osmdb); + provider.readOsm(osmdb); osmdb.postLoad(); var way = osmdb.getWay(13876983L); @@ -41,7 +41,7 @@ void invalidPublicTransportRelation() { var osmdb = new OsmDatabase(DataImportIssueStore.NOOP); var file = RESOURCE_LOADER.file("brenner-invalid-relation-reference.osm.pbf"); var provider = new OsmProvider(file, true); - provider.readOSM(osmdb); + provider.readOsm(osmdb); osmdb.postLoad(); var way = osmdb.getWay(302732658L); diff --git a/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmModuleTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmModuleTest.java similarity index 85% rename from src/test/java/org/opentripplanner/graph_builder/module/osm/OsmModuleTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmModuleTest.java index 091652a2dbf..833b14ade9d 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmModuleTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmModuleTest.java @@ -5,7 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; -import static org.opentripplanner.openstreetmap.wayproperty.WayPropertiesBuilder.withModes; +import static org.opentripplanner.osm.wayproperty.WayPropertiesBuilder.withModes; import static org.opentripplanner.street.model.StreetTraversalPermission.ALL; import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN; @@ -15,24 +15,26 @@ import java.util.Locale; import java.util.Set; import java.util.stream.Stream; -import javax.annotation.Nonnull; import org.junit.jupiter.api.Test; import org.opentripplanner.astar.model.GraphPath; import org.opentripplanner.framework.i18n.LocalizedString; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.openstreetmap.OsmProvider; -import org.opentripplanner.openstreetmap.model.OSMWay; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.CreativeNamer; -import org.opentripplanner.openstreetmap.wayproperty.MixinPropertiesBuilder; -import org.opentripplanner.openstreetmap.wayproperty.WayProperties; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertiesBuilder; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; -import org.opentripplanner.openstreetmap.wayproperty.specifier.BestMatchSpecifier; -import org.opentripplanner.openstreetmap.wayproperty.specifier.OsmSpecifier; +import org.opentripplanner.osm.OsmProvider; +import org.opentripplanner.osm.model.OsmWay; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.CreativeNamer; +import org.opentripplanner.osm.wayproperty.MixinPropertiesBuilder; +import org.opentripplanner.osm.wayproperty.WayProperties; +import org.opentripplanner.osm.wayproperty.WayPropertiesBuilder; +import org.opentripplanner.osm.wayproperty.WayPropertySet; +import org.opentripplanner.osm.wayproperty.specifier.BestMatchSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.OsmSpecifier; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.impl.GraphPathFinder; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingService; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.vertex.BarrierVertex; @@ -57,7 +59,10 @@ public void testGraphBuilder() { OsmProvider provider = new OsmProvider(file, true); - OsmModule osmModule = OsmModule.of(provider, gg).withAreaVisibility(true).build(); + OsmModule osmModule = OsmModule + .of(provider, gg, new DefaultVehicleParkingRepository()) + .withAreaVisibility(true) + .build(); osmModule.buildGraph(); @@ -113,7 +118,10 @@ public void testBuildGraphDetailed() { File file = RESOURCE_LOADER.file("NYC_small.osm.pbf"); OsmProvider provider = new OsmProvider(file, true); - OsmModule osmModule = OsmModule.of(provider, gg).withAreaVisibility(true).build(); + OsmModule osmModule = OsmModule + .of(provider, gg, new DefaultVehicleParkingRepository()) + .withAreaVisibility(true) + .build(); osmModule.buildGraph(); @@ -160,7 +168,7 @@ public void testBuildAreaWithVisibility() { @Test public void testWayDataSet() { - OSMWithTags way = new OSMWay(); + OsmWithTags way = new OsmWay(); way.addTag("highway", "footway"); way.addTag("cycleway", "lane"); way.addTag("surface", "gravel"); @@ -214,7 +222,7 @@ public void testWayDataSet() { assertEquals(dataForWay.bicycleSafety().forward(), 1.5); // test a left-right distinction - way = new OSMWay(); + way = new OsmWay(); way.addTag("highway", "footway"); way.addTag("cycleway", "lane"); way.addTag("cycleway:right", "track"); @@ -232,7 +240,7 @@ public void testWayDataSet() { // left comes from lane assertEquals(0.75, dataForWay.bicycleSafety().back()); - way = new OSMWay(); + way = new OsmWay(); way.addTag("highway", "footway"); way.addTag("footway", "sidewalk"); way.addTag("RLIS:reviewed", "no"); @@ -249,7 +257,7 @@ public void testWayDataSet() { @Test public void testCreativeNaming() { - OSMWithTags way = new OSMWay(); + OsmWithTags way = new OsmWay(); way.addTag("highway", "footway"); way.addTag("cycleway", "lane"); way.addTag("access", "no"); @@ -276,17 +284,16 @@ public void testLocalizedString() { @Test void addParkingLotsToService() { - Graph graph = buildParkingLots(); + var service = new DefaultVehicleParkingService(buildParkingLots().repository); - var service = graph.getVehicleParkingService(); - assertEquals(11, service.getVehicleParkings().count()); - assertEquals(6, service.getBikeParks().count()); - assertEquals(5, service.getCarParks().count()); + assertEquals(11, service.listVehicleParkings().size()); + assertEquals(6, service.listBikeParks().size()); + assertEquals(5, service.listCarParks().size()); } @Test void createArtificalEntrancesToUnlikedParkingLots() { - Graph graph = buildParkingLots(); + var graph = buildParkingLots().graph; graph .getVerticesOfType(VehicleParkingEntranceVertex.class) @@ -308,7 +315,7 @@ void testBarrierAtEnd() { File file = RESOURCE_LOADER.file("accessno-at-end.pbf"); OsmProvider provider = new OsmProvider(file, false); - OsmModule loader = OsmModule.of(provider, graph).build(); + OsmModule loader = OsmModule.of(provider, graph, new DefaultVehicleParkingRepository()).build(); loader.buildGraph(); Vertex start = graph.getVertex(VertexLabel.osm(1)); @@ -323,23 +330,25 @@ void testBarrierAtEnd() { assertEquals(barrier.getBarrierPermissions(), ALL); } - @Nonnull - private Graph buildParkingLots() { + private BuildResult buildParkingLots() { var graph = new Graph(); + var service = new DefaultVehicleParkingRepository(); var providers = Stream .of("B+R.osm.pbf", "P+R.osm.pbf") .map(RESOURCE_LOADER::file) .map(f -> new OsmProvider(f, false)) .toList(); var module = OsmModule - .of(providers, graph) + .of(providers, graph, service) .withStaticParkAndRide(true) .withStaticBikeParkAndRide(true) .build(); module.buildGraph(); - return graph; + return new BuildResult(graph, service); } + private record BuildResult(Graph graph, VehicleParkingRepository repository) {} + /** * This reads test file with area and tests if it can be routed if visibility is used and if it * isn't @@ -356,7 +365,10 @@ private void testBuildingAreas(boolean skipVisibility) { File file = RESOURCE_LOADER.file("usf_area.osm.pbf"); OsmProvider provider = new OsmProvider(file, false); - OsmModule loader = OsmModule.of(provider, graph).withAreaVisibility(!skipVisibility).build(); + OsmModule loader = OsmModule + .of(provider, graph, new DefaultVehicleParkingRepository()) + .withAreaVisibility(!skipVisibility) + .build(); loader.buildGraph(); diff --git a/src/test/java/org/opentripplanner/graph_builder/module/osm/OpenStreetMapParserTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmParserTest.java similarity index 80% rename from src/test/java/org/opentripplanner/graph_builder/module/osm/OpenStreetMapParserTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmParserTest.java index b0073475699..f477f76fc60 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/osm/OpenStreetMapParserTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/OsmParserTest.java @@ -7,12 +7,12 @@ import java.io.File; import org.junit.jupiter.api.Test; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.openstreetmap.OsmProvider; -import org.opentripplanner.openstreetmap.model.OSMNode; -import org.opentripplanner.openstreetmap.model.OSMWay; +import org.opentripplanner.osm.OsmProvider; +import org.opentripplanner.osm.model.OsmNode; +import org.opentripplanner.osm.model.OsmWay; import org.opentripplanner.test.support.ResourceLoader; -public class OpenStreetMapParserTest { +public class OsmParserTest { @Test public void testBinaryParser() { @@ -20,11 +20,11 @@ public void testBinaryParser() { OsmProvider pr = new OsmProvider(osmFile, true); OsmDatabase osmdb = new OsmDatabase(DataImportIssueStore.NOOP); - pr.readOSM(osmdb); + pr.readOsm(osmdb); assertEquals(2297, osmdb.nodeCount()); - OSMNode nodeA = osmdb.getNode(314192918L); + OsmNode nodeA = osmdb.getNode(314192918L); assertEquals(314192918, nodeA.getId()); assertEquals(52.3750447, nodeA.lat, 0.0000001); assertEquals(16.8431974, nodeA.lon, 0.0000001); @@ -33,7 +33,7 @@ public void testBinaryParser() { assertEquals(545, osmdb.wayCount()); - OSMWay wayA = osmdb.getWay(13490353L); + OsmWay wayA = osmdb.getWay(13490353L); assertEquals(13490353, wayA.getId()); TLongList nodeRefsA = wayA.getNodeRefs(); assertEquals(2, nodeRefsA.size()); diff --git a/application/src/test/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessorTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessorTest.java new file mode 100644 index 00000000000..bfe5992399b --- /dev/null +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessorTest.java @@ -0,0 +1,60 @@ +package org.opentripplanner.graph_builder.module.osm; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import org.junit.jupiter.api.Test; +import org.opentripplanner._support.geometry.Coordinates; +import org.opentripplanner.framework.i18n.I18NString; +import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; +import org.opentripplanner.osm.wayproperty.specifier.WayTestData; +import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.street.model._data.StreetModelForTest; +import org.opentripplanner.street.model.vertex.IntersectionVertex; + +class ParkingProcessorTest { + + private static final IntersectionVertex INTERSECTION_VERTEX = StreetModelForTest.intersectionVertex( + 1, + 1 + ); + private static final ParkingProcessor PROCESSOR = new ParkingProcessor( + new Graph(), + DataImportIssueStore.NOOP, + (n, w) -> INTERSECTION_VERTEX + ); + + @Test + void noWheelchairParking() { + var entity = WayTestData.parkAndRide(); + var parking = PROCESSOR.createVehicleParkingObjectFromOsmEntity( + true, + Coordinates.BERLIN, + entity, + I18NString.of("parking"), + List.of() + ); + + assertFalse(parking.hasWheelchairAccessibleCarPlaces()); + assertNull(parking.getCapacity().getWheelchairAccessibleCarSpaces()); + } + + @Test + void wheelchairParking() { + var entity = WayTestData.parkAndRide(); + entity.addTag("capacity:disabled", "yes"); + var parking = PROCESSOR.createVehicleParkingObjectFromOsmEntity( + true, + Coordinates.BERLIN, + entity, + I18NString.of("parking"), + List.of() + ); + + assertTrue(parking.hasWheelchairAccessibleCarPlaces()); + assertEquals(1, parking.getCapacity().getWheelchairAccessibleCarSpaces()); + } +} diff --git a/src/test/java/org/opentripplanner/graph_builder/module/osm/PlatformLinkerTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/PlatformLinkerTest.java similarity index 82% rename from src/test/java/org/opentripplanner/graph_builder/module/osm/PlatformLinkerTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/PlatformLinkerTest.java index 9d3ea5a1d81..f952bf90710 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/osm/PlatformLinkerTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/PlatformLinkerTest.java @@ -4,8 +4,9 @@ import java.io.File; import org.junit.jupiter.api.Test; -import org.opentripplanner.openstreetmap.OsmProvider; +import org.opentripplanner.osm.OsmProvider; import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; import org.opentripplanner.street.model.edge.AreaEdge; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.model.vertex.VertexLabel; @@ -29,7 +30,10 @@ public void testLinkEntriesToPlatforms() { OsmProvider provider = new OsmProvider(file, false); - OsmModule osmModule = OsmModule.of(provider, gg).withPlatformEntriesLinking(true).build(); + OsmModule osmModule = OsmModule + .of(provider, gg, new DefaultVehicleParkingRepository()) + .withPlatformEntriesLinking(true) + .build(); osmModule.buildGraph(); diff --git a/src/test/java/org/opentripplanner/graph_builder/module/osm/RingTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/RingTest.java similarity index 88% rename from src/test/java/org/opentripplanner/graph_builder/module/osm/RingTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/RingTest.java index ea47bed8842..e851de66046 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/osm/RingTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/RingTest.java @@ -6,25 +6,25 @@ import java.util.List; import org.junit.jupiter.api.Test; -import org.opentripplanner.openstreetmap.model.OSMNode; +import org.opentripplanner.osm.model.OsmNode; class RingTest { @Test void testIsNodeConvex() { - OSMNode a = new OSMNode(); + OsmNode a = new OsmNode(); a.lat = 0.0; a.lon = 0.0; - OSMNode b = new OSMNode(); + OsmNode b = new OsmNode(); b.lat = 1.0; b.lon = 0.0; - OSMNode c = new OSMNode(); + OsmNode c = new OsmNode(); c.lat = 1.0; c.lon = 1.0; - OSMNode d = new OSMNode(); + OsmNode d = new OsmNode(); d.lat = 0.0; d.lon = 1.0; - OSMNode e = new OSMNode(); + OsmNode e = new OsmNode(); e.lat = 0.5; e.lon = 0.5; diff --git a/src/test/java/org/opentripplanner/graph_builder/module/osm/TriangleInequalityTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/TriangleInequalityTest.java similarity index 96% rename from src/test/java/org/opentripplanner/graph_builder/module/osm/TriangleInequalityTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/TriangleInequalityTest.java index b6c498de44c..ffc1f661dcc 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/osm/TriangleInequalityTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/TriangleInequalityTest.java @@ -15,12 +15,13 @@ import org.opentripplanner.astar.model.GraphPath; import org.opentripplanner.astar.model.ShortestPathTree; import org.opentripplanner.model.modes.ExcludeAllTransitFilter; -import org.opentripplanner.openstreetmap.OsmProvider; +import org.opentripplanner.osm.OsmProvider; import org.opentripplanner.routing.api.request.RequestModes; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.request.filter.AllowAllTransitFilter; import org.opentripplanner.routing.api.request.request.filter.TransitFilter; import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.model.vertex.VertexLabel; @@ -50,7 +51,10 @@ public static void onlyOnce() { File file = ResourceLoader.of(TriangleInequalityTest.class).file("NYC_small.osm.pbf"); OsmProvider provider = new OsmProvider(file, true); - OsmModule osmModule = OsmModule.of(provider, graph).withAreaVisibility(true).build(); + OsmModule osmModule = OsmModule + .of(provider, graph, new DefaultVehicleParkingRepository()) + .withAreaVisibility(true) + .build(); osmModule.buildGraph(); } diff --git a/src/test/java/org/opentripplanner/graph_builder/module/osm/UnconnectedAreasTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/UnconnectedAreasTest.java similarity index 90% rename from src/test/java/org/opentripplanner/graph_builder/module/osm/UnconnectedAreasTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/UnconnectedAreasTest.java index 01221f16c31..103dafa61b9 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/osm/UnconnectedAreasTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/UnconnectedAreasTest.java @@ -11,16 +11,17 @@ import org.opentripplanner.graph_builder.issue.service.DefaultDataImportIssueStore; import org.opentripplanner.graph_builder.issues.ParkAndRideUnlinked; import org.opentripplanner.graph_builder.module.TestStreetLinkerModule; -import org.opentripplanner.openstreetmap.OsmProvider; +import org.opentripplanner.osm.OsmProvider; import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; import org.opentripplanner.street.model.edge.StreetVehicleParkingLink; import org.opentripplanner.street.model.edge.VehicleParkingEdge; import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex; import org.opentripplanner.street.model.vertex.VertexLabel; 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; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; public class UnconnectedAreasTest { @@ -39,7 +40,7 @@ public class UnconnectedAreasTest { @Test public void unconnectedCarParkAndRide() { DefaultDataImportIssueStore issueStore = new DefaultDataImportIssueStore(); - Graph gg = buildOSMGraph("P+R.osm.pbf", issueStore); + Graph gg = buildOsmGraph("P+R.osm.pbf", issueStore); assertEquals(1, getParkAndRideUnlinkedIssueCount(issueStore)); @@ -56,7 +57,7 @@ public void unconnectedCarParkAndRide() { @Test public void unconnectedBikeParkAndRide() { DefaultDataImportIssueStore issueStore = new DefaultDataImportIssueStore(); - Graph gg = buildOSMGraph("B+R.osm.pbf", issueStore); + Graph gg = buildOsmGraph("B+R.osm.pbf", issueStore); assertEquals(2, getParkAndRideUnlinkedIssueCount(issueStore)); @@ -151,18 +152,18 @@ public void testRoadPassingOverParkRide() { assertTrue(connections.contains(VertexLabel.osm(-102284))); } - private Graph buildOSMGraph(String osmFileName) { - return buildOSMGraph(osmFileName, DataImportIssueStore.NOOP); + private Graph buildOsmGraph(String osmFileName) { + return buildOsmGraph(osmFileName, DataImportIssueStore.NOOP); } - private Graph buildOSMGraph(String osmFileName, DataImportIssueStore issueStore) { + private Graph buildOsmGraph(String osmFileName, DataImportIssueStore issueStore) { var deduplicator = new Deduplicator(); - var stopModel = new StopModel(); + var siteRepository = new SiteRepository(); var graph = new Graph(deduplicator); - var transitModel = new TransitModel(stopModel, deduplicator); + var timetableRepository = new TimetableRepository(siteRepository, deduplicator); OsmProvider provider = new OsmProvider(RESOURCE_LOADER.file(osmFileName), false); OsmModule loader = OsmModule - .of(provider, graph) + .of(provider, graph, new DefaultVehicleParkingRepository()) .withIssueStore(issueStore) .withAreaVisibility(true) .withStaticParkAndRide(true) @@ -171,7 +172,7 @@ private Graph buildOSMGraph(String osmFileName, DataImportIssueStore issueStore) loader.buildGraph(); - TestStreetLinkerModule.link(graph, transitModel); + TestStreetLinkerModule.link(graph, timetableRepository); return graph; } @@ -185,7 +186,7 @@ private List testGeometricGraphWithClasspathFile( int prCount, int prlCount ) { - Graph graph = buildOSMGraph(fileName); + Graph graph = buildOsmGraph(fileName); var vehicleParkingVertices = graph.getVerticesOfType(VehicleParkingEntranceVertex.class); int nParkAndRide = vehicleParkingVertices.size(); diff --git a/src/test/java/org/opentripplanner/graph_builder/module/osm/UnroutableTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/UnroutableTest.java similarity index 90% rename from src/test/java/org/opentripplanner/graph_builder/module/osm/UnroutableTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/UnroutableTest.java index f921062e790..138c3e67181 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/osm/UnroutableTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/UnroutableTest.java @@ -6,10 +6,11 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.astar.model.GraphPath; import org.opentripplanner.astar.model.ShortestPathTree; -import org.opentripplanner.openstreetmap.OsmProvider; +import org.opentripplanner.osm.OsmProvider; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.model.vertex.VertexLabel; @@ -37,7 +38,10 @@ public void setUp() throws Exception { var osmDataFile = ResourceLoader.of(UnroutableTest.class).file("bridge_construction.osm.pbf"); OsmProvider provider = new OsmProvider(osmDataFile, true); - OsmModule osmBuilder = OsmModule.of(provider, graph).withAreaVisibility(true).build(); + OsmModule osmBuilder = OsmModule + .of(provider, graph, new DefaultVehicleParkingRepository()) + .withAreaVisibility(true) + .build(); osmBuilder.buildGraph(); } diff --git a/src/test/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilderTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilderTest.java similarity index 97% rename from src/test/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilderTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilderTest.java index 4906bce930d..b712ee48c5a 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilderTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilderTest.java @@ -19,8 +19,8 @@ import org.junit.jupiter.api.TestInfo; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.module.osm.naming.DefaultNamer; -import org.opentripplanner.openstreetmap.OsmProvider; -import org.opentripplanner.openstreetmap.model.OSMLevel; +import org.opentripplanner.osm.OsmProvider; +import org.opentripplanner.osm.model.OsmLevel; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.street.model.edge.AreaEdge; import org.opentripplanner.street.model.vertex.VertexLabel; @@ -42,7 +42,7 @@ public Graph buildGraph(final TestInfo testInfo) { final File file = ResourceLoader.of(WalkableAreaBuilderTest.class).file(osmFile); assertTrue(file.exists()); - new OsmProvider(file, false).readOSM(osmdb); + new OsmProvider(file, false).readOsm(osmdb); osmdb.postLoad(); final WalkableAreaBuilder walkableAreaBuilder = new WalkableAreaBuilder( @@ -57,7 +57,7 @@ public Graph buildGraph(final TestInfo testInfo) { boardingAreaRefTags ); - final Map areasLevels = osmdb + final Map areasLevels = osmdb .getWalkableAreas() .stream() .collect(toMap(a -> a, a -> osmdb.getLevelForWay(a.parent))); diff --git a/src/test/java/org/opentripplanner/graph_builder/module/osm/naming/SidewalkNamerTest.java b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/naming/SidewalkNamerTest.java similarity index 95% rename from src/test/java/org/opentripplanner/graph_builder/module/osm/naming/SidewalkNamerTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/module/osm/naming/SidewalkNamerTest.java index c1c3d7e5e73..465eeb32ba2 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/osm/naming/SidewalkNamerTest.java +++ b/application/src/test/java/org/opentripplanner/graph_builder/module/osm/naming/SidewalkNamerTest.java @@ -14,8 +14,8 @@ import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.graph_builder.module.osm.StreetEdgePair; import org.opentripplanner.graph_builder.services.osm.EdgeNamer; -import org.opentripplanner.openstreetmap.model.OSMWay; -import org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData; +import org.opentripplanner.osm.model.OsmWay; +import org.opentripplanner.osm.wayproperty.specifier.WayTestData; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model._data.StreetModelForTest; import org.opentripplanner.street.model.edge.StreetEdge; @@ -111,5 +111,5 @@ private static StreetEdgeBuilder edgeBuilder(WgsCoordinate... c) { } } - private record EdgePair(OSMWay way, StreetEdge edge) {} + private record EdgePair(OsmWay way, StreetEdge edge) {} } diff --git a/src/test/java/org/opentripplanner/graph_builder/services/osm/EdgeNamerTest.java b/application/src/test/java/org/opentripplanner/graph_builder/services/osm/EdgeNamerTest.java similarity index 100% rename from src/test/java/org/opentripplanner/graph_builder/services/osm/EdgeNamerTest.java rename to application/src/test/java/org/opentripplanner/graph_builder/services/osm/EdgeNamerTest.java diff --git a/application/src/test/java/org/opentripplanner/gtfs/GenerateTripPatternsOperationTest.java b/application/src/test/java/org/opentripplanner/gtfs/GenerateTripPatternsOperationTest.java new file mode 100644 index 00000000000..d0968adf7e9 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/gtfs/GenerateTripPatternsOperationTest.java @@ -0,0 +1,305 @@ +package org.opentripplanner.gtfs; + +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.trip; + +import java.util.Collection; +import java.util.List; +import java.util.Set; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +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.graph_builder.issue.api.DataImportIssueStore; +import org.opentripplanner.graph_builder.issue.service.DefaultDataImportIssueStore; +import org.opentripplanner.graph_builder.issues.TripDegenerate; +import org.opentripplanner.graph_builder.issues.TripUndefinedService; +import org.opentripplanner.graph_builder.module.geometry.GeometryProcessor; +import org.opentripplanner.model.StopTime; +import org.opentripplanner.model.impl.OtpTransitServiceBuilder; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.transit.model.framework.Deduplicator; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.transit.model.timetable.Direction; +import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.transit.service.SiteRepository; + +class GenerateTripPatternsOperationTest { + + private static SiteRepository siteRepository; + private static RegularStop stopA; + private static RegularStop stopB; + private static RegularStop stopC; + private static Trip trip1; + private static Trip trip2; + private static Trip trip3; + private static Trip trip4; + private static Trip trip5; + private static StopTime stopTimeA; + private static StopTime stopTimeB; + private static StopTime stopTimeC; + + private Deduplicator deduplicator; + private DataImportIssueStore issueStore; + private OtpTransitServiceBuilder transitServiceBuilder; + private GeometryProcessor geometryProcessor; + + @BeforeAll + static void setupClass() { + TimetableRepositoryForTest timetableRepositoryForTest = TimetableRepositoryForTest.of(); + stopA = timetableRepositoryForTest.stop("stopA").build(); + stopB = timetableRepositoryForTest.stop("stopB").build(); + stopC = timetableRepositoryForTest.stop("stopC").build(); + siteRepository = + timetableRepositoryForTest + .siteRepositoryBuilder() + .withRegularStop(stopA) + .withRegularStop(stopB) + .withRegularStop(stopC) + .build(); + + stopTimeA = new StopTime(); + stopTimeA.setStop(stopA); + stopTimeB = new StopTime(); + stopTimeB.setStop(stopB); + stopTimeC = new StopTime(); + stopTimeC.setStop(stopC); + + FeedScopedId serviceId1 = TimetableRepositoryForTest.id("SERVICE_ID_1"); + trip1 = + trip("TRIP_ID_1") + .withServiceId(serviceId1) + .withMode(TransitMode.RAIL) + .withNetexSubmode("SUBMODE_1") + .withDirection(Direction.INBOUND) + .build(); + + // same route, mode, submode and direction as trip1 + FeedScopedId serviceId2 = TimetableRepositoryForTest.id("SERVICE_ID_2"); + trip2 = + trip("TRIP_ID_2") + .withServiceId(serviceId2) + .withRoute(trip1.getRoute()) + .withMode(trip1.getMode()) + .withNetexSubmode(trip1.getNetexSubMode().name()) + .withDirection(trip1.getDirection()) + .build(); + + // same route, direction as trip1, different mode + FeedScopedId serviceId3 = TimetableRepositoryForTest.id("SERVICE_ID_3"); + trip3 = + trip("TRIP_ID_3") + .withServiceId(serviceId3) + .withRoute(trip1.getRoute()) + .withMode(TransitMode.BUS) + .withDirection(trip1.getDirection()) + .build(); + + // same route, mode, direction as trip1, different submode + FeedScopedId serviceId4 = TimetableRepositoryForTest.id("SERVICE_ID_4"); + trip4 = + trip("TRIP_ID_4") + .withServiceId(serviceId4) + .withRoute(trip1.getRoute()) + .withMode(trip1.getMode()) + .withNetexSubmode("SUMODE_2") + .withDirection(trip1.getDirection()) + .build(); + + // same route, mode as trip1, different direction + FeedScopedId serviceId5 = TimetableRepositoryForTest.id("SERVICE_ID_5"); + trip5 = + trip("TRIP_ID_5") + .withServiceId(serviceId5) + .withRoute(trip1.getRoute()) + .withMode(trip1.getMode()) + .withNetexSubmode(trip1.getNetexSubMode().name()) + .withDirection(Direction.OUTBOUND) + .build(); + } + + @BeforeEach + void setup() { + deduplicator = new Deduplicator(); + issueStore = new DefaultDataImportIssueStore(); + transitServiceBuilder = new OtpTransitServiceBuilder(siteRepository, issueStore); + double maxStopToShapeSnapDistance = 100; + geometryProcessor = + new GeometryProcessor(transitServiceBuilder, maxStopToShapeSnapDistance, issueStore); + } + + @Test + void testGenerateTripPatternsNoTrip() { + Set calendarServiceIds = Set.of(); + GenerateTripPatternsOperation generateTripPatternsOperation = new GenerateTripPatternsOperation( + transitServiceBuilder, + issueStore, + deduplicator, + calendarServiceIds, + geometryProcessor + ); + generateTripPatternsOperation.run(); + + Assertions.assertTrue(transitServiceBuilder.getTripPatterns().isEmpty()); + Assertions.assertTrue(issueStore.listIssues().isEmpty()); + } + + @Test + void testGenerateTripPatternsTripWithUndefinedService() { + transitServiceBuilder.getTripsById().computeIfAbsent(trip1.getId(), feedScopedId -> trip1); + Set calendarServiceIds = Set.of(); + + GenerateTripPatternsOperation generateTripPatternsOperation = new GenerateTripPatternsOperation( + transitServiceBuilder, + issueStore, + deduplicator, + calendarServiceIds, + geometryProcessor + ); + generateTripPatternsOperation.run(); + + Assertions.assertTrue(transitServiceBuilder.getTripPatterns().isEmpty()); + Assertions.assertFalse(issueStore.listIssues().isEmpty()); + Assertions.assertInstanceOf(TripUndefinedService.class, issueStore.listIssues().getFirst()); + } + + @Test + void testGenerateTripPatternsDegeneratedTrip() { + transitServiceBuilder.getTripsById().computeIfAbsent(trip1.getId(), feedScopedId -> trip1); + Set calendarServiceIds = Set.of(trip1.getServiceId()); + + GenerateTripPatternsOperation generateTripPatternsOperation = new GenerateTripPatternsOperation( + transitServiceBuilder, + issueStore, + deduplicator, + calendarServiceIds, + geometryProcessor + ); + generateTripPatternsOperation.run(); + + Assertions.assertTrue(transitServiceBuilder.getTripPatterns().isEmpty()); + Assertions.assertFalse(issueStore.listIssues().isEmpty()); + Assertions.assertInstanceOf(TripDegenerate.class, issueStore.listIssues().getFirst()); + } + + @Test + void testGenerateTripPatterns() { + transitServiceBuilder.getTripsById().computeIfAbsent(trip1.getId(), feedScopedId -> trip1); + Collection stopTimes = List.of(stopTimeA, stopTimeB); + transitServiceBuilder.getStopTimesSortedByTrip().put(trip1, stopTimes); + Set calendarServiceIds = Set.of(trip1.getServiceId()); + + GenerateTripPatternsOperation generateTripPatternsOperation = new GenerateTripPatternsOperation( + transitServiceBuilder, + issueStore, + deduplicator, + calendarServiceIds, + geometryProcessor + ); + generateTripPatternsOperation.run(); + + Assertions.assertEquals(1, transitServiceBuilder.getTripPatterns().size()); + Assertions.assertTrue(issueStore.listIssues().isEmpty()); + } + + @Test + void testGenerateTripPatterns2TripsSameStops() { + transitServiceBuilder.getTripsById().computeIfAbsent(trip1.getId(), feedScopedId -> trip1); + transitServiceBuilder.getTripsById().computeIfAbsent(trip2.getId(), feedScopedId -> trip2); + Collection stopTimes = List.of(stopTimeA, stopTimeB); + + transitServiceBuilder.getStopTimesSortedByTrip().put(trip1, stopTimes); + transitServiceBuilder.getStopTimesSortedByTrip().put(trip2, stopTimes); + + Set calendarServiceIds = Set.of(trip1.getServiceId(), trip2.getServiceId()); + + GenerateTripPatternsOperation generateTripPatternsOperation = new GenerateTripPatternsOperation( + transitServiceBuilder, + issueStore, + deduplicator, + calendarServiceIds, + geometryProcessor + ); + generateTripPatternsOperation.run(); + + Assertions.assertEquals(1, transitServiceBuilder.getTripPatterns().size()); + Assertions.assertEquals( + 2, + transitServiceBuilder + .getTripPatterns() + .values() + .stream() + .findFirst() + .orElseThrow() + .getScheduledTimetable() + .getTripTimes() + .size() + ); + Assertions.assertTrue(issueStore.listIssues().isEmpty()); + } + + @Test + void testGenerateTripPatterns2TripsDifferentStops() { + transitServiceBuilder.getTripsById().computeIfAbsent(trip1.getId(), feedScopedId -> trip1); + transitServiceBuilder.getTripsById().computeIfAbsent(trip2.getId(), feedScopedId -> trip2); + Collection stopTimesTrip1 = List.of(stopTimeA, stopTimeB); + Collection stopTimesTrip2 = List.of(stopTimeA, stopTimeC); + + transitServiceBuilder.getStopTimesSortedByTrip().put(trip1, stopTimesTrip1); + transitServiceBuilder.getStopTimesSortedByTrip().put(trip2, stopTimesTrip2); + + Set calendarServiceIds = Set.of(trip1.getServiceId(), trip2.getServiceId()); + + GenerateTripPatternsOperation generateTripPatternsOperation = new GenerateTripPatternsOperation( + transitServiceBuilder, + issueStore, + deduplicator, + calendarServiceIds, + geometryProcessor + ); + generateTripPatternsOperation.run(); + + Assertions.assertEquals(2, transitServiceBuilder.getTripPatterns().size()); + Assertions.assertTrue(issueStore.listIssues().isEmpty()); + } + + static List testCases() { + return List.of( + // trips with different modes + Arguments.of(trip1, trip3), + // trips with different sub-modes + Arguments.of(trip1, trip4), + // trips with different directions + Arguments.of(trip1, trip5) + ); + } + + @ParameterizedTest + @MethodSource("testCases") + void testGenerateDifferentTripPatterns(Trip t1, Trip t2) { + transitServiceBuilder.getTripsById().computeIfAbsent(t1.getId(), feedScopedId -> t1); + transitServiceBuilder.getTripsById().computeIfAbsent(t2.getId(), feedScopedId -> t2); + Collection stopTimes = List.of(stopTimeA, stopTimeB); + + transitServiceBuilder.getStopTimesSortedByTrip().put(t1, stopTimes); + transitServiceBuilder.getStopTimesSortedByTrip().put(t2, stopTimes); + + Set calendarServiceIds = Set.of(t1.getServiceId(), t2.getServiceId()); + + GenerateTripPatternsOperation generateTripPatternsOperation = new GenerateTripPatternsOperation( + transitServiceBuilder, + issueStore, + deduplicator, + calendarServiceIds, + geometryProcessor + ); + generateTripPatternsOperation.run(); + + Assertions.assertEquals(2, transitServiceBuilder.getTripPatterns().size()); + Assertions.assertTrue(issueStore.listIssues().isEmpty()); + } +} diff --git a/src/test/java/org/opentripplanner/gtfs/GtfsContext.java b/application/src/test/java/org/opentripplanner/gtfs/GtfsContext.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/GtfsContext.java rename to application/src/test/java/org/opentripplanner/gtfs/GtfsContext.java diff --git a/src/test/java/org/opentripplanner/gtfs/GtfsContextBuilder.java b/application/src/test/java/org/opentripplanner/gtfs/GtfsContextBuilder.java similarity index 97% rename from src/test/java/org/opentripplanner/gtfs/GtfsContextBuilder.java rename to application/src/test/java/org/opentripplanner/gtfs/GtfsContextBuilder.java index d74903495b3..80f66caf98e 100644 --- a/src/test/java/org/opentripplanner/gtfs/GtfsContextBuilder.java +++ b/application/src/test/java/org/opentripplanner/gtfs/GtfsContextBuilder.java @@ -17,7 +17,7 @@ import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.site.StopTransferPriority; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; /** * This class helps building GtfsContext and post process the GtfsDao by repairing @@ -44,7 +44,10 @@ public static GtfsContextBuilder contextBuilder(File file) throws IOException { public static GtfsContextBuilder contextBuilder(@Nullable String defaultFeedId, File path) throws IOException { - var transitBuilder = new OtpTransitServiceBuilder(new StopModel(), DataImportIssueStore.NOOP); + var transitBuilder = new OtpTransitServiceBuilder( + new SiteRepository(), + DataImportIssueStore.NOOP + ); GtfsImport gtfsImport = gtfsImport(defaultFeedId, path); GtfsFeedId feedId = gtfsImport.getFeedId(); var mapper = new GTFSToOtpTransitServiceMapper( diff --git a/src/test/java/org/opentripplanner/gtfs/GtfsImport.java b/application/src/test/java/org/opentripplanner/gtfs/GtfsImport.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/GtfsImport.java rename to application/src/test/java/org/opentripplanner/gtfs/GtfsImport.java diff --git a/src/test/java/org/opentripplanner/gtfs/integration/InterliningTest.java b/application/src/test/java/org/opentripplanner/gtfs/integration/InterliningTest.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/integration/InterliningTest.java rename to application/src/test/java/org/opentripplanner/gtfs/integration/InterliningTest.java diff --git a/src/test/java/org/opentripplanner/gtfs/interlining/InterlineProcessorTest.java b/application/src/test/java/org/opentripplanner/gtfs/interlining/InterlineProcessorTest.java similarity index 94% rename from src/test/java/org/opentripplanner/gtfs/interlining/InterlineProcessorTest.java rename to application/src/test/java/org/opentripplanner/gtfs/interlining/InterlineProcessorTest.java index a1aa4f9d753..1fd24f17f3b 100644 --- a/src/test/java/org/opentripplanner/gtfs/interlining/InterlineProcessorTest.java +++ b/application/src/test/java/org/opentripplanner/gtfs/interlining/InterlineProcessorTest.java @@ -16,7 +16,7 @@ import org.opentripplanner.model.calendar.CalendarServiceData; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.model.transfer.DefaultTransferService; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.StopPattern; @@ -25,7 +25,7 @@ class InterlineProcessorTest implements PlanTestConstants { - private static TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); List patterns = List.of( tripPattern("trip-1", "block-1", "service-1"), @@ -150,7 +150,7 @@ void staySeatedNotAllowed() { } private static TripPattern tripPattern(String tripId, String blockId, String serviceId) { - var trip = TransitModelForTest + var trip = TimetableRepositoryForTest .trip(tripId) .withGtfsBlockId(blockId) .withServiceId(new FeedScopedId("1", serviceId)) @@ -163,13 +163,12 @@ private static TripPattern tripPattern(String tripId, String blockId, String ser ); var stopPattern = new StopPattern(stopTimes); - var tp = TripPattern - .of(TransitModelForTest.id(tripId)) + var tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, new Deduplicator()); + return TripPattern + .of(TimetableRepositoryForTest.id(tripId)) .withRoute(trip.getRoute()) .withStopPattern(stopPattern) + .withScheduledTimeTableBuilder(builder -> builder.addTripTimes(tripTimes)) .build(); - var tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, new Deduplicator()); - tp.add(tripTimes); - return tp; } } diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/AgencyMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/AgencyMapperTest.java similarity index 86% rename from src/test/java/org/opentripplanner/gtfs/mapping/AgencyMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/AgencyMapperTest.java index c37df887927..789b94991b0 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/AgencyMapperTest.java +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/AgencyMapperTest.java @@ -11,7 +11,7 @@ import java.util.Collections; import org.junit.jupiter.api.Test; import org.onebusaway.gtfs.model.Agency; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; public class AgencyMapperTest { @@ -31,8 +31,7 @@ public class AgencyMapperTest { private static final String FARE_URL = "www.url.com/fare"; - private static final String BRANDING_URL = "www.url.com/brand"; - private final AgencyMapper subject = new AgencyMapper(TransitModelForTest.FEED_ID); + private final AgencyMapper subject = new AgencyMapper(TimetableRepositoryForTest.FEED_ID); static { AGENCY.setId(ID); @@ -42,7 +41,6 @@ public class AgencyMapperTest { AGENCY.setTimezone(TIMEZONE); AGENCY.setUrl(URL); AGENCY.setFareUrl(FARE_URL); - AGENCY.setBrandingUrl(BRANDING_URL); } @Test @@ -58,7 +56,7 @@ public void testMap() throws Exception { result = subject.map(AGENCY); - assertEquals(TransitModelForTest.FEED_ID, result.getId().getFeedId()); + assertEquals(TimetableRepositoryForTest.FEED_ID, result.getId().getFeedId()); assertEquals(ID, result.getId().getId()); assertEquals(NAME, result.getName()); assertEquals(LANG, result.getLang()); @@ -66,7 +64,6 @@ public void testMap() throws Exception { assertEquals(TIMEZONE, result.getTimezone().getId()); assertEquals(URL, result.getUrl()); assertEquals(FARE_URL, result.getFareUrl()); - assertEquals(BRANDING_URL, result.getBrandingUrl()); } @Test @@ -88,7 +85,6 @@ public void testMapWithNulls() throws Exception { assertNull(result.getLang()); assertNull(result.getPhone()); assertNull(result.getFareUrl()); - assertNull(result.getBrandingUrl()); } /** Mapping the same object twice, should return the the same instance. */ diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/BikeAccessMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/BikeAccessMapperTest.java similarity index 50% rename from src/test/java/org/opentripplanner/gtfs/mapping/BikeAccessMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/BikeAccessMapperTest.java index a17886311dc..d5ed02dfd9c 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/BikeAccessMapperTest.java +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/BikeAccessMapperTest.java @@ -11,10 +11,6 @@ public class BikeAccessMapperTest { private static final int BIKES_ALLOWED = 1; private static final int BIKES_NOT_ALLOWED = 2; - private static final int TRIP_BIKES_ALLOWED = 2; - private static final int TRIP_BIKES_NOT_ALLOWED = 1; - private static final int ROUTE_BIKES_ALLOWED = 2; - private static final int ROUTE_BIKES_NOT_ALLOWED = 1; @Test public void testTripProvidedValues() { @@ -28,25 +24,12 @@ public void testTripProvidedValues() { assertEquals(BikeAccess.NOT_ALLOWED, BikeAccessMapper.mapForTrip(trip)); } - @Test - public void testLegacyTripProvidedValues() { - Trip trip = new Trip(); - assertEquals(BikeAccess.UNKNOWN, BikeAccessMapper.mapForTrip(trip)); - - trip.setTripBikesAllowed(TRIP_BIKES_ALLOWED); - assertEquals(BikeAccess.ALLOWED, BikeAccessMapper.mapForTrip(trip)); - - trip.setTripBikesAllowed(TRIP_BIKES_NOT_ALLOWED); - assertEquals(BikeAccess.NOT_ALLOWED, BikeAccessMapper.mapForTrip(trip)); - } - @Test public void testTripProvidedValuesPrecedence() { Trip trip = new Trip(); assertEquals(BikeAccess.UNKNOWN, BikeAccessMapper.mapForTrip(trip)); trip.setBikesAllowed(BIKES_ALLOWED); - trip.setTripBikesAllowed(TRIP_BIKES_NOT_ALLOWED); assertEquals(BikeAccess.ALLOWED, BikeAccessMapper.mapForTrip(trip)); } @@ -61,26 +44,4 @@ public void testRouteProvidedValues() { route.setBikesAllowed(BIKES_NOT_ALLOWED); assertEquals(BikeAccess.NOT_ALLOWED, BikeAccessMapper.mapForRoute(route)); } - - @Test - public void testLegacyRouteProvidedValues() { - Route route = new Route(); - assertEquals(BikeAccess.UNKNOWN, BikeAccessMapper.mapForRoute(route)); - - route.setRouteBikesAllowed(ROUTE_BIKES_ALLOWED); - assertEquals(BikeAccess.ALLOWED, BikeAccessMapper.mapForRoute(route)); - - route.setRouteBikesAllowed(ROUTE_BIKES_NOT_ALLOWED); - assertEquals(BikeAccess.NOT_ALLOWED, BikeAccessMapper.mapForRoute(route)); - } - - @Test - public void testRouteProvidedValuesPrecedence() { - Route route = new Route(); - assertEquals(BikeAccess.UNKNOWN, BikeAccessMapper.mapForRoute(route)); - - route.setBikesAllowed(BIKES_ALLOWED); - route.setRouteBikesAllowed(ROUTE_BIKES_NOT_ALLOWED); - assertEquals(BikeAccess.ALLOWED, BikeAccessMapper.mapForRoute(route)); - } } diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/BoardingAreaMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/BoardingAreaMapperTest.java similarity index 95% rename from src/test/java/org/opentripplanner/gtfs/mapping/BoardingAreaMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/BoardingAreaMapperTest.java index 083db3bcb84..cb4ff3caaa3 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/BoardingAreaMapperTest.java +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/BoardingAreaMapperTest.java @@ -12,7 +12,7 @@ import org.junit.jupiter.api.Test; import org.onebusaway.gtfs.model.AgencyAndId; import org.onebusaway.gtfs.model.Stop; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.site.BoardingArea; import org.opentripplanner.transit.model.site.RegularStop; @@ -40,7 +40,7 @@ public class BoardingAreaMapperTest { private static final int VEHICLE_TYPE = 5; private static final int WHEELCHAIR_BOARDING = 1; - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final RegularStop PARENT_STOP = TEST_MODEL.stop(PARENT).build(); diff --git a/application/src/test/java/org/opentripplanner/gtfs/mapping/CarAccessMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/CarAccessMapperTest.java new file mode 100644 index 00000000000..a312d9967d6 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/CarAccessMapperTest.java @@ -0,0 +1,26 @@ +package org.opentripplanner.gtfs.mapping; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; +import org.onebusaway.gtfs.model.Route; +import org.onebusaway.gtfs.model.Trip; +import org.opentripplanner.transit.model.network.CarAccess; + +public class CarAccessMapperTest { + + private static final int CARS_ALLOWED = 1; + private static final int CARS_NOT_ALLOWED = 2; + + @Test + public void testTripProvidedValues() { + Trip trip = new Trip(); + assertEquals(CarAccess.UNKNOWN, CarAccessMapper.mapForTrip(trip)); + + trip.setCarsAllowed(CARS_ALLOWED); + assertEquals(CarAccess.ALLOWED, CarAccessMapper.mapForTrip(trip)); + + trip.setCarsAllowed(CARS_NOT_ALLOWED); + assertEquals(CarAccess.NOT_ALLOWED, CarAccessMapper.mapForTrip(trip)); + } +} diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/EntranceMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/EntranceMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/mapping/EntranceMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/EntranceMapperTest.java diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/FareAttributeMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/FareAttributeMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/mapping/FareAttributeMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/FareAttributeMapperTest.java diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/FareLegRuleMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/FareLegRuleMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/mapping/FareLegRuleMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/FareLegRuleMapperTest.java diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/FareProductMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/FareProductMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/mapping/FareProductMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/FareProductMapperTest.java diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/FareRuleMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/FareRuleMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/mapping/FareRuleMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/FareRuleMapperTest.java diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/FareTransferRuleMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/FareTransferRuleMapperTest.java similarity index 98% rename from src/test/java/org/opentripplanner/gtfs/mapping/FareTransferRuleMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/FareTransferRuleMapperTest.java index dc924f6f0aa..eda714257cd 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/FareTransferRuleMapperTest.java +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/FareTransferRuleMapperTest.java @@ -6,7 +6,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.List; -import javax.annotation.Nonnull; import org.junit.jupiter.api.Test; import org.onebusaway.gtfs.model.AgencyAndId; import org.onebusaway.gtfs.model.FareProduct; @@ -65,7 +64,6 @@ void transferRuleWithLegGroup() { assertEquals(groupId2.getId(), transferRule.toLegGroup().getId()); } - @Nonnull private FareProduct fareProduct() { var fareProduct = new FareProduct(); fareProduct.setId(id); diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/FeedInfoMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/FeedInfoMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/mapping/FeedInfoMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/FeedInfoMapperTest.java diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/FeedScopedIdMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/FeedScopedIdMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/mapping/FeedScopedIdMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/FeedScopedIdMapperTest.java diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/FrequencyMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/FrequencyMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/mapping/FrequencyMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/FrequencyMapperTest.java diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/GtfsTestData.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/GtfsTestData.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/mapping/GtfsTestData.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/GtfsTestData.java diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/LocationGroupMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/LocationGroupMapperTest.java similarity index 91% rename from src/test/java/org/opentripplanner/gtfs/mapping/LocationGroupMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/LocationGroupMapperTest.java index 3a3c3f28649..99d7c4f3fce 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/LocationGroupMapperTest.java +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/LocationGroupMapperTest.java @@ -4,7 +4,6 @@ import java.util.Set; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.junit.jupiter.api.Test; import org.onebusaway.gtfs.model.AgencyAndId; import org.onebusaway.gtfs.model.LocationGroup; @@ -12,7 +11,7 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.StopLocation; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; class LocationGroupMapperTest { @@ -20,7 +19,7 @@ class LocationGroupMapperTest { @Test void map() { - var builder = StopModel.of(); + var builder = SiteRepository.of(); var mapper = new LocationGroupMapper( new StopMapper(new TranslationHelper(), id -> null, builder), new LocationMapper(builder, DataImportIssueStore.NOOP), @@ -45,7 +44,6 @@ void map() { ); } - @Nonnull private static AgencyAndId id(String id) { return new AgencyAndId("1", id); } diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/LocationMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/LocationMapperTest.java similarity index 91% rename from src/test/java/org/opentripplanner/gtfs/mapping/LocationMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/LocationMapperTest.java index ab8bd66a810..fb910765f1b 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/LocationMapperTest.java +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/LocationMapperTest.java @@ -16,7 +16,7 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issue.api.Issue; import org.opentripplanner.graph_builder.issue.service.DefaultDataImportIssueStore; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; class LocationMapperTest { @@ -29,7 +29,7 @@ static Stream testCases() { void testMapping(String name, boolean isBogusName) { var gtfsLocation = getLocation(name, Polygons.OSLO); - var mapper = new LocationMapper(StopModel.of(), DataImportIssueStore.NOOP); + var mapper = new LocationMapper(SiteRepository.of(), DataImportIssueStore.NOOP); var flexLocation = mapper.map(gtfsLocation); assertEquals(isBogusName, flexLocation.hasFallbackName()); @@ -43,7 +43,7 @@ void invalidPolygon() { var gtfsLocation = getLocation("invalid", selfIntersecting); var issueStore = new DefaultDataImportIssueStore(); - var mapper = new LocationMapper(StopModel.of(), issueStore); + var mapper = new LocationMapper(SiteRepository.of(), issueStore); mapper.map(gtfsLocation); diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/PathwayMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/PathwayMapperTest.java similarity index 95% rename from src/test/java/org/opentripplanner/gtfs/mapping/PathwayMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/PathwayMapperTest.java index 1e321216305..ba913965c2d 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/PathwayMapperTest.java +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/PathwayMapperTest.java @@ -13,7 +13,7 @@ import org.onebusaway.gtfs.model.Pathway; import org.onebusaway.gtfs.model.Stop; import org.opentripplanner.transit.model.site.PathwayMode; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; public class PathwayMapperTest { @@ -30,7 +30,7 @@ public class PathwayMapperTest { private static final Stop TO_STOP = new Stop(); private final PathwayMapper subject = new PathwayMapper( - new StopMapper(TRANSLATION_HELPER, stationId -> null, new StopModel().withContext()), + new StopMapper(TRANSLATION_HELPER, stationId -> null, new SiteRepository().withContext()), new EntranceMapper(TRANSLATION_HELPER, stationId -> null), new PathwayNodeMapper(TRANSLATION_HELPER, stationId -> null), new BoardingAreaMapper(TRANSLATION_HELPER, stationId -> null) diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/PathwayNodeMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/PathwayNodeMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/mapping/PathwayNodeMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/PathwayNodeMapperTest.java diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/RouteMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/RouteMapperTest.java similarity index 94% rename from src/test/java/org/opentripplanner/gtfs/mapping/RouteMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/RouteMapperTest.java index 01eeaa662fa..56b760a1fd8 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/RouteMapperTest.java +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/RouteMapperTest.java @@ -14,7 +14,7 @@ import org.onebusaway.gtfs.model.AgencyAndId; import org.onebusaway.gtfs.model.Route; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.network.BikeAccess; import org.opentripplanner.transit.model.organization.Branding; @@ -47,11 +47,9 @@ public class RouteMapperTest { private static final Integer SORT_ORDER = 1; - private static final String BRANDING_URL = "www.url.me/brand"; - private static final Route ROUTE = new Route(); private final RouteMapper subject = new RouteMapper( - new AgencyMapper(TransitModelForTest.FEED_ID), + new AgencyMapper(TimetableRepositoryForTest.FEED_ID), DataImportIssueStore.NOOP, new TranslationHelper() ); @@ -68,7 +66,6 @@ public class RouteMapperTest { ROUTE.setTextColor(TEXT_COLOR); ROUTE.setBikesAllowed(BIKES_ALLOWED); ROUTE.setSortOrder(SORT_ORDER); - ROUTE.setBrandingUrl(BRANDING_URL); } @Test @@ -95,9 +92,9 @@ public void testMap() throws Exception { assertEquals(BikeAccess.ALLOWED, result.getBikesAllowed()); assertEquals(SORT_ORDER, result.getGtfsSortOrder()); + // We no longer read the non-standard brandingUrl from gtfs, but if it is supplied, it will not cause an error. Branding branding = result.getBranding(); - assertNotNull(branding); - assertEquals(BRANDING_URL, branding.getUrl()); + assertNull(branding); } @Test diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/ServiceCalendarDateMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/ServiceCalendarDateMapperTest.java similarity index 97% rename from src/test/java/org/opentripplanner/gtfs/mapping/ServiceCalendarDateMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/ServiceCalendarDateMapperTest.java index 320ef4ba555..f363b1c1cb1 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/ServiceCalendarDateMapperTest.java +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/ServiceCalendarDateMapperTest.java @@ -11,7 +11,7 @@ import org.onebusaway.gtfs.model.AgencyAndId; import org.onebusaway.gtfs.model.ServiceCalendarDate; import org.onebusaway.gtfs.model.calendar.ServiceDate; -import org.opentripplanner.framework.time.ServiceDateUtils; +import org.opentripplanner.utils.time.ServiceDateUtils; public class ServiceCalendarDateMapperTest { diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/ServiceCalendarMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/ServiceCalendarMapperTest.java similarity index 98% rename from src/test/java/org/opentripplanner/gtfs/mapping/ServiceCalendarMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/ServiceCalendarMapperTest.java index 41d3c4c64cc..8a9265376f3 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/ServiceCalendarMapperTest.java +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/ServiceCalendarMapperTest.java @@ -12,7 +12,7 @@ import org.onebusaway.gtfs.model.AgencyAndId; import org.onebusaway.gtfs.model.ServiceCalendar; import org.onebusaway.gtfs.model.calendar.ServiceDate; -import org.opentripplanner.framework.time.ServiceDateUtils; +import org.opentripplanner.utils.time.ServiceDateUtils; public class ServiceCalendarMapperTest { diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/ServiceDateMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/ServiceDateMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/mapping/ServiceDateMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/ServiceDateMapperTest.java diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/ShapePointMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/ShapePointMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/mapping/ShapePointMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/ShapePointMapperTest.java diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/StationMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/StationMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/mapping/StationMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/StationMapperTest.java diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/StopAndStationMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/StopAndStationMapperTest.java similarity index 97% rename from src/test/java/org/opentripplanner/gtfs/mapping/StopAndStationMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/StopAndStationMapperTest.java index d15ad9d75cf..51d4ec2605f 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/StopAndStationMapperTest.java +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/StopAndStationMapperTest.java @@ -14,7 +14,7 @@ import org.onebusaway.gtfs.model.Stop; import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; public class StopAndStationMapperTest { @@ -51,7 +51,7 @@ public class StopAndStationMapperTest { private final StopMapper subject = new StopMapper( new TranslationHelper(), stationId -> null, - new StopModel().withContext() + new SiteRepository().withContext() ); static { diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/StopTimeMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/StopTimeMapperTest.java similarity index 95% rename from src/test/java/org/opentripplanner/gtfs/mapping/StopTimeMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/StopTimeMapperTest.java index e45f7a8ff0d..2bbed14334e 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/StopTimeMapperTest.java +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/StopTimeMapperTest.java @@ -27,8 +27,8 @@ import org.opentripplanner.model.PickDrop; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.model.site.GroupStop; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.StopModelBuilder; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; public class StopTimeMapperTest { @@ -68,34 +68,28 @@ public class StopTimeMapperTest { .map(c -> new LngLatAlt(c.x, c.y)) .toList(); - private final StopModelBuilder stopModelBuilder = StopModel.of(); + private final SiteRepositoryBuilder siteRepositoryBuilder = SiteRepository.of(); private final StopMapper stopMapper = new StopMapper( new TranslationHelper(), stationId -> null, - stopModelBuilder + siteRepositoryBuilder ); private final BookingRuleMapper bookingRuleMapper = new BookingRuleMapper(); private final LocationMapper locationMapper = new LocationMapper( - stopModelBuilder, + siteRepositoryBuilder, DataImportIssueStore.NOOP ); private final LocationGroupMapper locationGroupMapper = new LocationGroupMapper( stopMapper, locationMapper, - stopModelBuilder - ); - private final StopAreaMapper stopAreaMapper = new StopAreaMapper( - stopMapper, - locationMapper, - stopModelBuilder + siteRepositoryBuilder ); private final TranslationHelper translationHelper = new TranslationHelper(); private final StopTimeMapper subject = new StopTimeMapper( stopMapper, locationMapper, locationGroupMapper, - stopAreaMapper, new TripMapper( new RouteMapper(new AgencyMapper(FEED_ID), ISSUE_STORE, translationHelper), new DirectionMapper(ISSUE_STORE), diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/TransferMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/TransferMapperTest.java similarity index 95% rename from src/test/java/org/opentripplanner/gtfs/mapping/TransferMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/TransferMapperTest.java index 3581cca9ac8..0273c3055b9 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/TransferMapperTest.java +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/TransferMapperTest.java @@ -19,8 +19,8 @@ import org.opentripplanner.model.transfer.ConstrainedTransfer; import org.opentripplanner.model.transfer.TransferPriority; import org.opentripplanner.transit.model.site.StopTransferPriority; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.StopModelBuilder; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; public class TransferMapperTest { @@ -37,29 +37,24 @@ public class TransferMapperTest { private static StationMapper STATION_MAPPER; - private static final StopModelBuilder STOP_MODEL_BUILDER = StopModel.of(); + private static final SiteRepositoryBuilder SITE_REPOSITORY_BUILDER = SiteRepository.of(); private static final StopMapper STOP_MAPPER = new StopMapper( TRANSLATION_HELPER, stationId -> null, - STOP_MODEL_BUILDER + SITE_REPOSITORY_BUILDER ); private static final BookingRuleMapper BOOKING_RULE_MAPPER = new BookingRuleMapper(); private static final LocationMapper LOCATION_MAPPER = new LocationMapper( - STOP_MODEL_BUILDER, + SITE_REPOSITORY_BUILDER, ISSUE_STORE ); private static final LocationGroupMapper LOCATION_GROUP_MAPPER = new LocationGroupMapper( STOP_MAPPER, LOCATION_MAPPER, - STOP_MODEL_BUILDER - ); - private static final StopAreaMapper STOP_AREA_MAPPER = new StopAreaMapper( - STOP_MAPPER, - LOCATION_MAPPER, - STOP_MODEL_BUILDER + SITE_REPOSITORY_BUILDER ); private static StopTimeMapper STOP_TIME_MAPPER; @@ -99,7 +94,6 @@ void prepare() { STOP_MAPPER, LOCATION_MAPPER, LOCATION_GROUP_MAPPER, - STOP_AREA_MAPPER, new TripMapper( new RouteMapper(new AgencyMapper(FEED_ID), ISSUE_STORE, TRANSLATION_HELPER), new DirectionMapper(ISSUE_STORE), diff --git a/application/src/test/java/org/opentripplanner/gtfs/mapping/TransitModeMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/TransitModeMapperTest.java new file mode 100644 index 00000000000..55e6f3a0d86 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/TransitModeMapperTest.java @@ -0,0 +1,89 @@ +package org.opentripplanner.gtfs.mapping; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.transit.model.basic.TransitMode.AIRPLANE; +import static org.opentripplanner.transit.model.basic.TransitMode.BUS; +import static org.opentripplanner.transit.model.basic.TransitMode.CABLE_CAR; +import static org.opentripplanner.transit.model.basic.TransitMode.CARPOOL; +import static org.opentripplanner.transit.model.basic.TransitMode.COACH; +import static org.opentripplanner.transit.model.basic.TransitMode.FERRY; +import static org.opentripplanner.transit.model.basic.TransitMode.FUNICULAR; +import static org.opentripplanner.transit.model.basic.TransitMode.GONDOLA; +import static org.opentripplanner.transit.model.basic.TransitMode.MONORAIL; +import static org.opentripplanner.transit.model.basic.TransitMode.RAIL; +import static org.opentripplanner.transit.model.basic.TransitMode.SUBWAY; +import static org.opentripplanner.transit.model.basic.TransitMode.TAXI; +import static org.opentripplanner.transit.model.basic.TransitMode.TRAM; +import static org.opentripplanner.transit.model.basic.TransitMode.TROLLEYBUS; + +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.opentripplanner.transit.model.basic.TransitMode; + +class TransitModeMapperTest { + + static Stream testCases() { + return Stream.of( + // base GTFS route types + // https://gtfs.org/documentation/schedule/reference/#routestxt + Arguments.of(0, TRAM), + Arguments.of(1, SUBWAY), + Arguments.of(2, RAIL), + Arguments.of(3, BUS), + Arguments.of(4, FERRY), + Arguments.of(5, CABLE_CAR), + Arguments.of(6, GONDOLA), + Arguments.of(7, FUNICULAR), + Arguments.of(11, TROLLEYBUS), + Arguments.of(12, MONORAIL), + // extended route types + // https://developers.google.com/transit/gtfs/reference/extended-route-types + // https://groups.google.com/g/gtfs-changes/c/keT5rTPS7Y0/m/71uMz2l6ke0J?pli=1 + Arguments.of(100, RAIL), + Arguments.of(199, RAIL), + Arguments.of(200, COACH), + Arguments.of(299, COACH), + Arguments.of(400, RAIL), + Arguments.of(401, SUBWAY), + Arguments.of(402, SUBWAY), + Arguments.of(403, RAIL), + Arguments.of(404, RAIL), + Arguments.of(405, MONORAIL), + Arguments.of(500, SUBWAY), + Arguments.of(599, SUBWAY), + Arguments.of(600, SUBWAY), + Arguments.of(699, SUBWAY), + Arguments.of(700, BUS), + Arguments.of(799, BUS), + Arguments.of(800, TROLLEYBUS), + Arguments.of(899, TROLLEYBUS), + Arguments.of(900, TRAM), + Arguments.of(999, TRAM), + Arguments.of(1000, FERRY), + Arguments.of(1099, FERRY), + Arguments.of(1100, AIRPLANE), + Arguments.of(1199, AIRPLANE), + Arguments.of(1200, FERRY), + Arguments.of(1299, FERRY), + Arguments.of(1300, GONDOLA), + Arguments.of(1399, GONDOLA), + Arguments.of(1400, FUNICULAR), + Arguments.of(1499, FUNICULAR), + Arguments.of(1500, TAXI), + Arguments.of(1510, TAXI), + Arguments.of(1551, CARPOOL), + Arguments.of(1555, CARPOOL), + Arguments.of(1560, CARPOOL), + Arguments.of(1561, TAXI), + Arguments.of(1580, TAXI) + ); + } + + @ParameterizedTest(name = "{0} should map to {1}") + @MethodSource("testCases") + void map(int mode, TransitMode expectedMode) { + assertEquals(expectedMode, TransitModeMapper.mapMode(mode)); + } +} diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/TranslationHelperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/TranslationHelperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/gtfs/mapping/TranslationHelperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/TranslationHelperTest.java diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/TripMapperTest.java b/application/src/test/java/org/opentripplanner/gtfs/mapping/TripMapperTest.java similarity index 79% rename from src/test/java/org/opentripplanner/gtfs/mapping/TripMapperTest.java rename to application/src/test/java/org/opentripplanner/gtfs/mapping/TripMapperTest.java index 964c3d8155e..12df141eaf4 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/TripMapperTest.java +++ b/application/src/test/java/org/opentripplanner/gtfs/mapping/TripMapperTest.java @@ -6,14 +6,20 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.time.Duration; import java.util.Collection; import java.util.Collections; +import java.util.stream.Stream; 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.onebusaway.gtfs.model.AgencyAndId; import org.onebusaway.gtfs.model.Trip; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.network.BikeAccess; +import org.opentripplanner.transit.model.network.CarAccess; import org.opentripplanner.transit.model.timetable.Direction; public class TripMapperTest { @@ -21,6 +27,7 @@ public class TripMapperTest { private static final String FEED_ID = "FEED"; private static final AgencyAndId AGENCY_AND_ID = new AgencyAndId("A", "1"); private static final int BIKES_ALLOWED = 1; + private static final int CARS_ALLOWED = 1; private static final String BLOCK_ID = "Block Id"; private static final int DIRECTION_ID = 1; private static final String TRIP_HEADSIGN = "Trip Headsign"; @@ -47,6 +54,7 @@ private static TripMapper defaultTripMapper() { TRIP.setId(AGENCY_AND_ID); TRIP.setBikesAllowed(BIKES_ALLOWED); + TRIP.setCarsAllowed(CARS_ALLOWED); TRIP.setBlockId(BLOCK_ID); TRIP.setDirectionId(Integer.toString(DIRECTION_ID)); TRIP.setRoute(data.route); @@ -78,6 +86,7 @@ void testMap() throws Exception { assertEquals(TRIP_SHORT_NAME, result.getShortName()); assertEquals(Accessibility.POSSIBLE, result.getWheelchairBoarding()); assertEquals(BikeAccess.ALLOWED, result.getBikesAllowed()); + assertEquals(CarAccess.ALLOWED, result.getCarsAllowed()); } @Test @@ -99,6 +108,7 @@ void testMapWithNulls() throws Exception { assertEquals(Direction.UNKNOWN, result.getDirection()); assertEquals(Accessibility.NO_INFORMATION, result.getWheelchairBoarding()); assertEquals(BikeAccess.UNKNOWN, result.getBikesAllowed()); + assertEquals(CarAccess.UNKNOWN, result.getCarsAllowed()); } /** Mapping the same object twice, should return the same instance. */ @@ -117,17 +127,32 @@ void noFlexTimePenalty() { assertTrue(mapper.flexSafeTimePenalties().isEmpty()); } - @Test - void flexTimePenalty() { + @ParameterizedTest + @MethodSource("provideOffsetAndFactor") + void testFlexFactorAndOffset( + Double inputFactor, + Double inputOffset, + double expectedCoefficient, + Duration expectedConstant + ) { var flexTrip = new Trip(); flexTrip.setId(new AgencyAndId("1", "1")); - flexTrip.setSafeDurationFactor(1.5); - flexTrip.setSafeDurationOffset(600d); + flexTrip.setSafeDurationFactor(inputFactor); + flexTrip.setSafeDurationOffset(inputOffset); flexTrip.setRoute(new GtfsTestData().route); var mapper = defaultTripMapper(); var mapped = mapper.map(flexTrip); var penalty = mapper.flexSafeTimePenalties().get(mapped); - assertEquals(1.5f, penalty.coefficient()); - assertEquals(600, penalty.constant().toSeconds()); + + assertEquals(expectedCoefficient, penalty.coefficient()); + assertEquals(expectedConstant, penalty.constant()); + } + + private static Stream provideOffsetAndFactor() { + return Stream.of( + Arguments.of(1.5d, 60d, 1.5d, Duration.ofMinutes(1)), + Arguments.of(null, 120d, 1d, Duration.ofMinutes(2)), + Arguments.of(1.5d, null, 1.5d, Duration.ZERO) + ); } } diff --git a/src/test/java/org/opentripplanner/inspector/vector/VectorTileResponseFactoryTest.java b/application/src/test/java/org/opentripplanner/inspector/vector/VectorTileResponseFactoryTest.java similarity index 96% rename from src/test/java/org/opentripplanner/inspector/vector/VectorTileResponseFactoryTest.java rename to application/src/test/java/org/opentripplanner/inspector/vector/VectorTileResponseFactoryTest.java index 1489cd87c13..6c874c7108f 100644 --- a/src/test/java/org/opentripplanner/inspector/vector/VectorTileResponseFactoryTest.java +++ b/application/src/test/java/org/opentripplanner/inspector/vector/VectorTileResponseFactoryTest.java @@ -11,13 +11,13 @@ import org.opentripplanner.inspector.vector.geofencing.GeofencingZonesLayerBuilder; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.standalone.api.OtpServerRequestContext; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; class VectorTileResponseFactoryTest { public static final OtpServerRequestContext SERVER_CONTEXT = TestServerContext.createServerContext( new Graph(), - new TransitModel() + new TimetableRepository() ); enum LayerType { diff --git a/src/test/java/org/opentripplanner/inspector/vector/stop/AreaStopLayerBuilderTest.java b/application/src/test/java/org/opentripplanner/inspector/vector/stop/AreaStopLayerBuilderTest.java similarity index 79% rename from src/test/java/org/opentripplanner/inspector/vector/stop/AreaStopLayerBuilderTest.java rename to application/src/test/java/org/opentripplanner/inspector/vector/stop/AreaStopLayerBuilderTest.java index a1c01ca2e99..23a9ce972d0 100644 --- a/src/test/java/org/opentripplanner/inspector/vector/stop/AreaStopLayerBuilderTest.java +++ b/application/src/test/java/org/opentripplanner/inspector/vector/stop/AreaStopLayerBuilderTest.java @@ -9,17 +9,17 @@ import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.AreaStop; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.StopModelBuilder; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; class AreaStopLayerBuilderTest { private static final FeedScopedId ID = new FeedScopedId("FEED", "ID"); private static final I18NString NAME = I18NString.of("Test stop"); - private final StopModelBuilder stopModelBuilder = StopModel.of(); + private final SiteRepositoryBuilder siteRepositoryBuilder = SiteRepository.of(); - private final AreaStop areaStop = stopModelBuilder + private final AreaStop areaStop = siteRepositoryBuilder .areaStop(ID) .withName(NAME) .withGeometry(Polygons.BERLIN) diff --git a/src/test/java/org/opentripplanner/mmri/BeneficialChangesTest.java b/application/src/test/java/org/opentripplanner/mmri/BeneficialChangesTest.java similarity index 100% rename from src/test/java/org/opentripplanner/mmri/BeneficialChangesTest.java rename to application/src/test/java/org/opentripplanner/mmri/BeneficialChangesTest.java diff --git a/src/test/java/org/opentripplanner/mmri/ExcludedRoutesTest.java b/application/src/test/java/org/opentripplanner/mmri/ExcludedRoutesTest.java similarity index 100% rename from src/test/java/org/opentripplanner/mmri/ExcludedRoutesTest.java rename to application/src/test/java/org/opentripplanner/mmri/ExcludedRoutesTest.java diff --git a/src/test/java/org/opentripplanner/mmri/ExcludedTripsTest.java b/application/src/test/java/org/opentripplanner/mmri/ExcludedTripsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/mmri/ExcludedTripsTest.java rename to application/src/test/java/org/opentripplanner/mmri/ExcludedTripsTest.java diff --git a/src/test/java/org/opentripplanner/mmri/FirstForbiddenTripToTripTransferTest.java b/application/src/test/java/org/opentripplanner/mmri/FirstForbiddenTripToTripTransferTest.java similarity index 100% rename from src/test/java/org/opentripplanner/mmri/FirstForbiddenTripToTripTransferTest.java rename to application/src/test/java/org/opentripplanner/mmri/FirstForbiddenTripToTripTransferTest.java diff --git a/src/test/java/org/opentripplanner/mmri/FirstPreferredTripToTripTransferTest.java b/application/src/test/java/org/opentripplanner/mmri/FirstPreferredTripToTripTransferTest.java similarity index 100% rename from src/test/java/org/opentripplanner/mmri/FirstPreferredTripToTripTransferTest.java rename to application/src/test/java/org/opentripplanner/mmri/FirstPreferredTripToTripTransferTest.java diff --git a/src/test/java/org/opentripplanner/mmri/FirstUnpreferredTransferTest.java b/application/src/test/java/org/opentripplanner/mmri/FirstUnpreferredTransferTest.java similarity index 100% rename from src/test/java/org/opentripplanner/mmri/FirstUnpreferredTransferTest.java rename to application/src/test/java/org/opentripplanner/mmri/FirstUnpreferredTransferTest.java diff --git a/src/test/java/org/opentripplanner/mmri/MMRI Testdocument.pdf b/application/src/test/java/org/opentripplanner/mmri/MMRI_Testdocument.pdf similarity index 100% rename from src/test/java/org/opentripplanner/mmri/MMRI Testdocument.pdf rename to application/src/test/java/org/opentripplanner/mmri/MMRI_Testdocument.pdf diff --git a/src/test/java/org/opentripplanner/mmri/OptimizationTest.java b/application/src/test/java/org/opentripplanner/mmri/OptimizationTest.java similarity index 100% rename from src/test/java/org/opentripplanner/mmri/OptimizationTest.java rename to application/src/test/java/org/opentripplanner/mmri/OptimizationTest.java diff --git a/src/test/java/org/opentripplanner/mmri/PreferencesTest.java b/application/src/test/java/org/opentripplanner/mmri/PreferencesTest.java similarity index 100% rename from src/test/java/org/opentripplanner/mmri/PreferencesTest.java rename to application/src/test/java/org/opentripplanner/mmri/PreferencesTest.java diff --git a/src/test/java/org/opentripplanner/mmri/SecondForbiddenTripToTripTransferTest.java b/application/src/test/java/org/opentripplanner/mmri/SecondForbiddenTripToTripTransferTest.java similarity index 100% rename from src/test/java/org/opentripplanner/mmri/SecondForbiddenTripToTripTransferTest.java rename to application/src/test/java/org/opentripplanner/mmri/SecondForbiddenTripToTripTransferTest.java diff --git a/src/test/java/org/opentripplanner/mmri/SecondPreferredTripToTripTransferTest.java b/application/src/test/java/org/opentripplanner/mmri/SecondPreferredTripToTripTransferTest.java similarity index 100% rename from src/test/java/org/opentripplanner/mmri/SecondPreferredTripToTripTransferTest.java rename to application/src/test/java/org/opentripplanner/mmri/SecondPreferredTripToTripTransferTest.java diff --git a/src/test/java/org/opentripplanner/mmri/SecondUnpreferredTransferTest.java b/application/src/test/java/org/opentripplanner/mmri/SecondUnpreferredTransferTest.java similarity index 100% rename from src/test/java/org/opentripplanner/mmri/SecondUnpreferredTransferTest.java rename to application/src/test/java/org/opentripplanner/mmri/SecondUnpreferredTransferTest.java diff --git a/src/test/java/org/opentripplanner/mmri/StopToStopTransfersTest.java b/application/src/test/java/org/opentripplanner/mmri/StopToStopTransfersTest.java similarity index 100% rename from src/test/java/org/opentripplanner/mmri/StopToStopTransfersTest.java rename to application/src/test/java/org/opentripplanner/mmri/StopToStopTransfersTest.java diff --git a/src/test/java/org/opentripplanner/mmri/TimeTest.java b/application/src/test/java/org/opentripplanner/mmri/TimeTest.java similarity index 100% rename from src/test/java/org/opentripplanner/mmri/TimeTest.java rename to application/src/test/java/org/opentripplanner/mmri/TimeTest.java diff --git a/src/test/java/org/opentripplanner/mmri/UnplannedChangesTest.java b/application/src/test/java/org/opentripplanner/mmri/UnplannedChangesTest.java similarity index 100% rename from src/test/java/org/opentripplanner/mmri/UnplannedChangesTest.java rename to application/src/test/java/org/opentripplanner/mmri/UnplannedChangesTest.java diff --git a/src/test/java/org/opentripplanner/mmri/WheelchairTest.java b/application/src/test/java/org/opentripplanner/mmri/WheelchairTest.java similarity index 100% rename from src/test/java/org/opentripplanner/mmri/WheelchairTest.java rename to application/src/test/java/org/opentripplanner/mmri/WheelchairTest.java diff --git a/application/src/test/java/org/opentripplanner/mmri/package-info.md b/application/src/test/java/org/opentripplanner/mmri/package-info.md new file mode 100644 index 00000000000..5d4f541f1cb --- /dev/null +++ b/application/src/test/java/org/opentripplanner/mmri/package-info.md @@ -0,0 +1,19 @@ +# MMRI ("MultiModale ReisInformatie" => "multimodal travel information") + +What is this package doing here? + +In 2013, significant improvements were made to OTP as part of a precommercial procurement project +in The Netherlands called MMRI ("MultiModale ReisInformatie" => "multimodal travel information"). +This project is itself part of a larger project called "Better Benutten" => "better utilization". +Most effort concentrated on the implementation of GTFS-RT updates and related improvements to the +architecture of OTP. Additionally, a testing module was developed to verify that all the planners +that were involved in the project (not just OTP) met a minimum set of requirements. OTP was first +to pass all tests, ahead of two different solutions. Unfortunately, having two sets of tests does +not make it simpler to continuously verify that OTP still functions correctly, which is why these +MMRI tests have now been added to OTP's own test suite. These versions are intended to be a close +approximation of reality, but several minor shortcuts have been taken, like applying trip updates +directly to the graph instead of going through the thread-safe graph writer framework. Given that +thread-safety is a technical issue and not a functional one, this is considered to be +acceptable. + +The test cases are described [here](https://github.com/plannerstack/testset) and [here](./MMRI_Testdocument.pdf) diff --git a/src/test/java/org/opentripplanner/model/ShapeGeometryTest.java b/application/src/test/java/org/opentripplanner/model/ShapeGeometryTest.java similarity index 79% rename from src/test/java/org/opentripplanner/model/ShapeGeometryTest.java rename to application/src/test/java/org/opentripplanner/model/ShapeGeometryTest.java index 167bd2a2972..bcfd93513ce 100644 --- a/src/test/java/org/opentripplanner/model/ShapeGeometryTest.java +++ b/application/src/test/java/org/opentripplanner/model/ShapeGeometryTest.java @@ -6,17 +6,17 @@ import org.opentripplanner.ConstantsForTests; import org.opentripplanner.TestOtpModel; import org.opentripplanner.transit.model.network.TripPattern; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; public class ShapeGeometryTest { @Test public void useShapeGeometries() { TestOtpModel model = ConstantsForTests.buildGtfsGraph(ConstantsForTests.SHAPE_DIST_GTFS); - TransitModel transitModel = model.transitModel(); + TimetableRepository timetableRepository = model.timetableRepository(); // data includes 2 trips, of which one has incorrect shape_dist_traveled parametrization in stop_times - for (TripPattern pattern : transitModel.getAllTripPatterns()) { + for (TripPattern pattern : timetableRepository.getAllTripPatterns()) { // examine if shape extraction worked at first stop intervals, where dist parameter is wrong assertTrue(pattern.getHopGeometry(0).getCoordinates().length > 2); assertTrue(pattern.getHopGeometry(1).getCoordinates().length > 2); diff --git a/src/test/java/org/opentripplanner/model/TimetableSnapshotTest.java b/application/src/test/java/org/opentripplanner/model/TimetableSnapshotTest.java similarity index 62% rename from src/test/java/org/opentripplanner/model/TimetableSnapshotTest.java rename to application/src/test/java/org/opentripplanner/model/TimetableSnapshotTest.java index 0a737630a5b..4f3e12c1368 100644 --- a/src/test/java/org/opentripplanner/model/TimetableSnapshotTest.java +++ b/application/src/test/java/org/opentripplanner/model/TimetableSnapshotTest.java @@ -1,7 +1,9 @@ package org.opentripplanner.model; +import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; @@ -13,37 +15,48 @@ import com.google.transit.realtime.GtfsRealtime.TripUpdate; import java.time.LocalDate; import java.time.ZoneId; +import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.SortedSet; +import java.util.concurrent.atomic.AtomicBoolean; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.opentripplanner.ConstantsForTests; import org.opentripplanner.TestOtpModel; import org.opentripplanner._support.time.ZoneIds; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers.TransitLayerUpdater; +import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.framework.Result; import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.transit.model.timetable.TripIdAndServiceDate; +import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.model.timetable.TripTimes; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.model.timetable.TripTimesFactory; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.updater.spi.UpdateError; import org.opentripplanner.updater.trip.BackwardsDelayPropagationType; public class TimetableSnapshotTest { private static final ZoneId timeZone = ZoneIds.GMT; + public static final LocalDate SERVICE_DATE = LocalDate.of(2024, 1, 1); private static Map patternIndex; static String feedId; @BeforeAll public static void setUp() throws Exception { TestOtpModel model = ConstantsForTests.buildGtfsGraph(ConstantsForTests.SIMPLE_GTFS); - TransitModel transitModel = model.transitModel(); + TimetableRepository timetableRepository = model.timetableRepository(); - feedId = transitModel.getFeedIds().iterator().next(); + feedId = timetableRepository.getFeedIds().iterator().next(); patternIndex = new HashMap<>(); - for (TripPattern tripPattern : transitModel.getAllTripPatterns()) { + for (TripPattern tripPattern : timetableRepository.getAllTripPatterns()) { tripPattern .scheduledTripsAsStream() .forEach(trip -> patternIndex.put(trip.getId(), tripPattern)); @@ -52,9 +65,9 @@ public static void setUp() throws Exception { @Test public void testCompare() { - Timetable orig = new Timetable(null); - Timetable a = new Timetable(orig, LocalDate.now(timeZone).minusDays(1)); - Timetable b = new Timetable(orig, LocalDate.now(timeZone)); + Timetable orig = Timetable.of().build(); + Timetable a = orig.copyOf().withServiceDate(LocalDate.now(timeZone).minusDays(1)).build(); + Timetable b = orig.copyOf().withServiceDate(LocalDate.now(timeZone)).build(); assertTrue(new TimetableSnapshot.SortedTimetableComparator().compare(a, b) < 0); } @@ -106,52 +119,50 @@ public void testResolve() { @Test public void testUpdate() { - assertThrows( - ConcurrentModificationException.class, - () -> { - LocalDate today = LocalDate.now(timeZone); - LocalDate yesterday = today.minusDays(1); - TripPattern pattern = patternIndex.get(new FeedScopedId(feedId, "1.1")); + LocalDate today = LocalDate.now(timeZone); + LocalDate yesterday = today.minusDays(1); + TripPattern pattern = patternIndex.get(new FeedScopedId(feedId, "1.1")); - TimetableSnapshot resolver = new TimetableSnapshot(); - Timetable origNow = resolver.resolve(pattern, today); + TimetableSnapshot resolver = new TimetableSnapshot(); + Timetable origNow = resolver.resolve(pattern, today); - TripDescriptor.Builder tripDescriptorBuilder = TripDescriptor.newBuilder(); + TripDescriptor.Builder tripDescriptorBuilder = TripDescriptor.newBuilder(); - tripDescriptorBuilder.setTripId("1.1"); - tripDescriptorBuilder.setScheduleRelationship(ScheduleRelationship.SCHEDULED); + tripDescriptorBuilder.setTripId("1.1"); + tripDescriptorBuilder.setScheduleRelationship(ScheduleRelationship.SCHEDULED); - TripUpdate.Builder tripUpdateBuilder = TripUpdate.newBuilder(); + TripUpdate.Builder tripUpdateBuilder = TripUpdate.newBuilder(); - tripUpdateBuilder.setTrip(tripDescriptorBuilder); + tripUpdateBuilder.setTrip(tripDescriptorBuilder); - var stopTimeUpdateBuilder = tripUpdateBuilder.addStopTimeUpdateBuilder(0); - stopTimeUpdateBuilder.setStopSequence(2); - stopTimeUpdateBuilder.setScheduleRelationship( - TripUpdate.StopTimeUpdate.ScheduleRelationship.SCHEDULED - ); - stopTimeUpdateBuilder.setDeparture( - TripUpdate.StopTimeEvent.newBuilder().setDelay(5).build() - ); + var stopTimeUpdateBuilder = tripUpdateBuilder.addStopTimeUpdateBuilder(0); + stopTimeUpdateBuilder.setStopSequence(2); + stopTimeUpdateBuilder.setScheduleRelationship( + TripUpdate.StopTimeUpdate.ScheduleRelationship.SCHEDULED + ); + stopTimeUpdateBuilder.setDeparture(TripUpdate.StopTimeEvent.newBuilder().setDelay(5).build()); - TripUpdate tripUpdate = tripUpdateBuilder.build(); + TripUpdate tripUpdate = tripUpdateBuilder.build(); - // new timetable for today - updateResolver(resolver, pattern, tripUpdate, today); - Timetable updatedNow = resolver.resolve(pattern, today); - assertNotSame(origNow, updatedNow); + // new timetable for today + updateResolver(resolver, pattern, tripUpdate, today); + Timetable updatedNow = resolver.resolve(pattern, today); + assertNotSame(origNow, updatedNow); - // reuse timetable for today - updateResolver(resolver, pattern, tripUpdate, today); - assertEquals(updatedNow, resolver.resolve(pattern, today)); + // a new timetable instance is created for today + updateResolver(resolver, pattern, tripUpdate, today); + assertNotEquals(updatedNow, resolver.resolve(pattern, today)); - // create new timetable for tomorrow - updateResolver(resolver, pattern, tripUpdate, yesterday); - assertNotSame(origNow, resolver.resolve(pattern, yesterday)); - assertNotSame(updatedNow, resolver.resolve(pattern, yesterday)); + // create new timetable for tomorrow + updateResolver(resolver, pattern, tripUpdate, yesterday); + assertNotSame(origNow, resolver.resolve(pattern, yesterday)); + assertNotSame(updatedNow, resolver.resolve(pattern, yesterday)); - // exception if we try to modify a snapshot - TimetableSnapshot snapshot = resolver.commit(); + // exception if we try to modify a snapshot + TimetableSnapshot snapshot = resolver.commit(); + assertThrows( + ConcurrentModificationException.class, + () -> { updateResolver(snapshot, pattern, tripUpdate, yesterday); } ); @@ -262,6 +273,49 @@ public void testPurge() { assertFalse(resolver.isDirty()); } + @Test + void testUniqueDirtyTimetablesAfterMultipleUpdates() { + TimetableSnapshot snapshot = new TimetableSnapshot(); + TripPattern pattern = patternIndex.get(new FeedScopedId(feedId, "1.1")); + Trip trip = pattern.scheduledTripsAsStream().findFirst().orElseThrow(); + + TripTimes updatedTriptimes = TripTimesFactory.tripTimes( + trip, + List.of(new StopTime()), + new Deduplicator() + ); + RealTimeTripUpdate realTimeTripUpdate = new RealTimeTripUpdate( + pattern, + updatedTriptimes, + SERVICE_DATE, + TripOnServiceDate.of(trip.getId()).withTrip(trip).withServiceDate(SERVICE_DATE).build(), + true, + true + ); + + snapshot.update(realTimeTripUpdate); + snapshot.update(realTimeTripUpdate); + assertTrue(snapshot.isDirty()); + + AtomicBoolean updateIsCalled = new AtomicBoolean(); + + TransitLayerUpdater transitLayer = new TransitLayerUpdater(null) { + @Override + public void update( + Collection updatedTimetables, + Map> timetables + ) { + updateIsCalled.set(true); + assertThat(updatedTimetables).hasSize(1); + assertThat(timetables).hasSize(1); + } + }; + + snapshot.commit(transitLayer, true); + + assertTrue(updateIsCalled.get()); + } + @Test void testCannotUpdateReadOnlyTimetableSnapshot() { TimetableSnapshot committedSnapshot = createCommittedSnapshot(); @@ -305,6 +359,59 @@ void testCannotRevertReadOnlyTimetableSnapshot() { ); } + @Test + void testClear() { + TimetableSnapshot snapshot = new TimetableSnapshot(); + TripPattern pattern = patternIndex.get(new FeedScopedId(feedId, "1.1")); + Trip trip = pattern.scheduledTripsAsStream().findFirst().orElseThrow(); + + TripIdAndServiceDate tripIdAndServiceDate = new TripIdAndServiceDate( + trip.getId(), + SERVICE_DATE + ); + TripTimes updatedTriptimes = TripTimesFactory.tripTimes( + trip, + List.of(new StopTime()), + new Deduplicator() + ); + RealTimeTripUpdate realTimeTripUpdate = new RealTimeTripUpdate( + pattern, + updatedTriptimes, + SERVICE_DATE, + TripOnServiceDate.of(trip.getId()).withTrip(trip).withServiceDate(SERVICE_DATE).build(), + true, + true + ); + + snapshot.update(realTimeTripUpdate); + + assertNotNull(snapshot.getRealTimeAddedTrip(trip.getId())); + assertNotNull(snapshot.getRealTimeAddedPatternForTrip(trip)); + assertFalse(snapshot.getRealTimeAddedPatternForRoute(pattern.getRoute()).isEmpty()); + assertNotNull(snapshot.getRealTimeAddedTripOnServiceDateById(trip.getId())); + assertNotNull(snapshot.getRealTimeAddedTripOnServiceDateForTripAndDay(tripIdAndServiceDate)); + assertNotNull(snapshot.getRealtimeAddedRoute(pattern.getRoute().getId())); + + snapshot.clear(trip.getId().getFeedId()); + + assertNull(snapshot.getRealTimeAddedTrip(trip.getId())); + assertNull(snapshot.getRealTimeAddedPatternForTrip(trip)); + assertNull(snapshot.getRealTimeAddedTripOnServiceDateById(trip.getId())); + assertNull(snapshot.getRealTimeAddedTripOnServiceDateForTripAndDay(tripIdAndServiceDate)); + assertNull(snapshot.getRealtimeAddedRoute(pattern.getRoute().getId())); + assertTrue(snapshot.getRealTimeAddedPatternForRoute(pattern.getRoute()).isEmpty()); + + snapshot.update(realTimeTripUpdate); + snapshot.clear("another feed id"); + + assertNotNull(snapshot.getRealTimeAddedTrip(trip.getId())); + assertNotNull(snapshot.getRealTimeAddedPatternForTrip(trip)); + assertFalse(snapshot.getRealTimeAddedPatternForRoute(pattern.getRoute()).isEmpty()); + assertNotNull(snapshot.getRealTimeAddedTripOnServiceDateById(trip.getId())); + assertNotNull(snapshot.getRealTimeAddedTripOnServiceDateForTripAndDay(tripIdAndServiceDate)); + assertNotNull(snapshot.getRealtimeAddedRoute(pattern.getRoute().getId())); + } + private static TimetableSnapshot createCommittedSnapshot() { TimetableSnapshot timetableSnapshot = new TimetableSnapshot(); return timetableSnapshot.commit(null, true); diff --git a/src/test/java/org/opentripplanner/model/TimetableTest.java b/application/src/test/java/org/opentripplanner/model/TimetableTest.java similarity index 98% rename from src/test/java/org/opentripplanner/model/TimetableTest.java rename to application/src/test/java/org/opentripplanner/model/TimetableTest.java index 9e6a7467dc5..a615041d7a1 100644 --- a/src/test/java/org/opentripplanner/model/TimetableTest.java +++ b/application/src/test/java/org/opentripplanner/model/TimetableTest.java @@ -22,7 +22,6 @@ import java.util.HashMap; import java.util.Map; import java.util.function.BiConsumer; -import javax.annotation.Nonnull; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -33,7 +32,7 @@ import org.opentripplanner.transit.model.framework.Result; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.RealTimeState; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.updater.spi.UpdateError; import org.opentripplanner.updater.trip.BackwardsDelayPropagationType; import org.opentripplanner.updater.trip.TripUpdateBuilder; @@ -52,12 +51,12 @@ public class TimetableTest { @BeforeAll public static void setUp() throws Exception { TestOtpModel model = ConstantsForTests.buildGtfsGraph(ConstantsForTests.SIMPLE_GTFS); - TransitModel transitModel = model.transitModel(); + TimetableRepository timetableRepository = model.timetableRepository(); - feedId = transitModel.getFeedIds().stream().findFirst().get(); + feedId = timetableRepository.getFeedIds().stream().findFirst().get(); patternIndex = new HashMap<>(); - for (TripPattern pattern : transitModel.getAllTripPatterns()) { + for (TripPattern pattern : timetableRepository.getAllTripPatterns()) { pattern.scheduledTripsAsStream().forEach(trip -> patternIndex.put(trip.getId(), pattern)); } @@ -190,7 +189,7 @@ public void update() { result.ifSuccess(p -> { var updatedTripTimes = p.getTripTimes(); assertNotNull(updatedTripTimes); - timetable.setTripTimes(trip_1_1_index, updatedTripTimes); + timetable = timetable.copyOf().addOrUpdateTripTimes(updatedTripTimes).build(); assertEquals(20 * 60 + 120, timetable.getTripTimes(trip_1_1_index).getArrivalTime(2)); }); @@ -217,7 +216,7 @@ public void update() { result.ifSuccess(p -> { var updatedTripTimes = p.getTripTimes(); assertNotNull(updatedTripTimes); - timetable.setTripTimes(trip_1_1_index, updatedTripTimes); + timetable = timetable.copyOf().addOrUpdateTripTimes(updatedTripTimes).build(); }); // update trip arrival time only @@ -246,7 +245,7 @@ public void update() { result.ifSuccess(p -> { var updatedTripTimes = p.getTripTimes(); assertNotNull(updatedTripTimes); - timetable.setTripTimes(trip_1_1_index, updatedTripTimes); + timetable = timetable.copyOf().addOrUpdateTripTimes(updatedTripTimes).build(); }); // update trip departure time only @@ -273,7 +272,7 @@ public void update() { result.ifSuccess(p -> { var updatedTripTimes = p.getTripTimes(); assertNotNull(updatedTripTimes); - timetable.setTripTimes(trip_1_1_index, updatedTripTimes); + timetable = timetable.copyOf().addOrUpdateTripTimes(updatedTripTimes).build(); }); // update trip using stop id @@ -299,7 +298,7 @@ public void update() { result.ifSuccess(p -> { var updatedTripTimes = p.getTripTimes(); assertNotNull(updatedTripTimes); - timetable.setTripTimes(trip_1_1_index, updatedTripTimes); + timetable = timetable.copyOf().addOrUpdateTripTimes(updatedTripTimes).build(); }); } @@ -975,7 +974,6 @@ private static void testInvalidStopTime( }); } - @Nonnull private static StopTimeUpdate emptyStopTime( int sequence, BiConsumer setEmptyEvent diff --git a/src/test/java/org/opentripplanner/model/TripPatternTest.java b/application/src/test/java/org/opentripplanner/model/TripPatternTest.java similarity index 96% rename from src/test/java/org/opentripplanner/model/TripPatternTest.java rename to application/src/test/java/org/opentripplanner/model/TripPatternTest.java index bad159eb3cd..f629902f3e1 100644 --- a/src/test/java/org/opentripplanner/model/TripPatternTest.java +++ b/application/src/test/java/org/opentripplanner/model/TripPatternTest.java @@ -8,7 +8,7 @@ import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.LineString; import org.opentripplanner.framework.geometry.GeometryUtils; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.StopPattern; import org.opentripplanner.transit.model.network.TripPattern; @@ -28,7 +28,7 @@ public class TripPatternTest { */ @Test public void testSetHopGeometriesFromPattern() { - var testModel = TransitModelForTest.of(); + var testModel = TimetableRepositoryForTest.of(); var stationOrigin = testModel.station("S1").withCoordinate(0.0, 0.0).build(); var stationDestination = testModel.station("S2").withCoordinate(1.0, 1.0).build(); var stopOrigin = testModel @@ -103,7 +103,7 @@ public TripPattern setupTripPattern( } var stopPattern = builder.build(); - var route = TransitModelForTest.route("R1").build(); + var route = TimetableRepositoryForTest.route("R1").build(); return TripPattern .of(new FeedScopedId("Test", "T1")) diff --git a/src/test/java/org/opentripplanner/model/TripTimeOnDateTest.java b/application/src/test/java/org/opentripplanner/model/TripTimeOnDateTest.java similarity index 77% rename from src/test/java/org/opentripplanner/model/TripTimeOnDateTest.java rename to application/src/test/java/org/opentripplanner/model/TripTimeOnDateTest.java index 78002e46eae..7fc2b577fd2 100644 --- a/src/test/java/org/opentripplanner/model/TripTimeOnDateTest.java +++ b/application/src/test/java/org/opentripplanner/model/TripTimeOnDateTest.java @@ -5,7 +5,7 @@ import java.time.LocalTime; import org.junit.jupiter.api.Test; import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.timetable.TripTimesFactory; @@ -14,10 +14,10 @@ class TripTimeOnDateTest implements PlanTestConstants { @Test void gtfsSequence() { - var testModel = TransitModelForTest.of(); + var testModel = TimetableRepositoryForTest.of(); var pattern = testModel.pattern(TransitMode.BUS).build(); - var trip = TransitModelForTest.trip("123").build(); - var stopTimes = testModel.stopTimesEvery5Minutes(3, trip, T11_00); + var trip = TimetableRepositoryForTest.trip("123").build(); + var stopTimes = testModel.stopTimesEvery5Minutes(3, trip, "11:00"); var tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, new Deduplicator()); diff --git a/src/test/java/org/opentripplanner/model/calendar/ServiceDateIntervalTest.java b/application/src/test/java/org/opentripplanner/model/calendar/ServiceDateIntervalTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/calendar/ServiceDateIntervalTest.java rename to application/src/test/java/org/opentripplanner/model/calendar/ServiceDateIntervalTest.java diff --git a/src/test/java/org/opentripplanner/model/calendar/impl/CalendarServiceDataFactoryImplTest.java b/application/src/test/java/org/opentripplanner/model/calendar/impl/CalendarServiceDataFactoryImplTest.java similarity index 94% rename from src/test/java/org/opentripplanner/model/calendar/impl/CalendarServiceDataFactoryImplTest.java rename to application/src/test/java/org/opentripplanner/model/calendar/impl/CalendarServiceDataFactoryImplTest.java index 135a3045c3c..1a322fde916 100644 --- a/src/test/java/org/opentripplanner/model/calendar/impl/CalendarServiceDataFactoryImplTest.java +++ b/application/src/test/java/org/opentripplanner/model/calendar/impl/CalendarServiceDataFactoryImplTest.java @@ -8,7 +8,7 @@ import static org.opentripplanner.gtfs.GtfsContextBuilder.contextBuilder; import static org.opentripplanner.model.calendar.ServiceCalendarDate.EXCEPTION_TYPE_REMOVE; import static org.opentripplanner.model.calendar.impl.CalendarServiceDataFactoryImpl.merge; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.io.IOException; import java.time.LocalDate; @@ -19,7 +19,6 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.opentripplanner.ConstantsForTests; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.gtfs.GtfsContext; import org.opentripplanner.gtfs.GtfsContextBuilder; @@ -28,8 +27,9 @@ import org.opentripplanner.model.calendar.CalendarServiceData; import org.opentripplanner.model.calendar.ServiceCalendarDate; import org.opentripplanner.model.impl.OtpTransitServiceBuilder; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.time.ServiceDateUtils; /** * @author Thomas Gran (Capra) - tgr@capraconsulting.no (08.11.2017) @@ -123,7 +123,7 @@ public void testServiceGetServiceDatesForServiceId() { private static GtfsContext createCtxBuilder() throws IOException { GtfsContextBuilder ctxBuilder = contextBuilder( - TransitModelForTest.FEED_ID, + TimetableRepositoryForTest.FEED_ID, ConstantsForTests.SIMPLE_GTFS ); OtpTransitServiceBuilder builder = ctxBuilder @@ -132,7 +132,7 @@ private static GtfsContext createCtxBuilder() throws IOException { // Supplement test data with at least one entity in all collections builder.getCalendarDates().add(removeMondayFromAlldays()); - builder.getFeedInfos().add(FeedInfo.dummyForTest(TransitModelForTest.FEED_ID)); + builder.getFeedInfos().add(FeedInfo.dummyForTest(TimetableRepositoryForTest.FEED_ID)); return ctxBuilder.build(); } diff --git a/src/test/java/org/opentripplanner/model/calendar/openinghours/OHCalendarTest.java b/application/src/test/java/org/opentripplanner/model/calendar/openinghours/OHCalendarTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/calendar/openinghours/OHCalendarTest.java rename to application/src/test/java/org/opentripplanner/model/calendar/openinghours/OHCalendarTest.java diff --git a/src/test/java/org/opentripplanner/model/impl/OtpTransitServiceBuilderLimitPeriodTest.java b/application/src/test/java/org/opentripplanner/model/impl/OtpTransitServiceBuilderLimitPeriodTest.java similarity index 76% rename from src/test/java/org/opentripplanner/model/impl/OtpTransitServiceBuilderLimitPeriodTest.java rename to application/src/test/java/org/opentripplanner/model/impl/OtpTransitServiceBuilderLimitPeriodTest.java index 5d1fef21271..ae44e7239f5 100644 --- a/src/test/java/org/opentripplanner/model/impl/OtpTransitServiceBuilderLimitPeriodTest.java +++ b/application/src/test/java/org/opentripplanner/model/impl/OtpTransitServiceBuilderLimitPeriodTest.java @@ -1,6 +1,7 @@ package org.opentripplanner.model.impl; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertTrue; import java.time.LocalDate; @@ -15,18 +16,19 @@ import org.opentripplanner.model.calendar.ServiceCalendar; import org.opentripplanner.model.calendar.ServiceCalendarDate; import org.opentripplanner.model.calendar.ServiceDateInterval; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.EntityById; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.StopPattern; import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.network.TripPatternBuilder; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.timetable.Direction; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimesFactory; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; /** * This test will create a Transit service builder and then limit the service period. The services @@ -43,12 +45,12 @@ public class OtpTransitServiceBuilderLimitPeriodTest { private static final LocalDate D1 = LocalDate.of(2020, 1, 8); private static final LocalDate D2 = LocalDate.of(2020, 1, 15); private static final LocalDate D3 = LocalDate.of(2020, 1, 31); - private static final FeedScopedId SERVICE_C_IN = TransitModelForTest.id("CalSrvIn"); - private static final FeedScopedId SERVICE_D_IN = TransitModelForTest.id("CalSrvDIn"); - private static final FeedScopedId SERVICE_C_OUT = TransitModelForTest.id("CalSrvOut"); - private static final FeedScopedId SERVICE_D_OUT = TransitModelForTest.id("CalSrvDOut"); + private static final FeedScopedId SERVICE_C_IN = TimetableRepositoryForTest.id("CalSrvIn"); + private static final FeedScopedId SERVICE_D_IN = TimetableRepositoryForTest.id("CalSrvDIn"); + private static final FeedScopedId SERVICE_C_OUT = TimetableRepositoryForTest.id("CalSrvOut"); + private static final FeedScopedId SERVICE_D_OUT = TimetableRepositoryForTest.id("CalSrvDOut"); private static final Deduplicator DEDUPLICATOR = new Deduplicator(); - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final RegularStop STOP_1 = TEST_MODEL.stop("Stop-1").build(); private static final RegularStop STOP_2 = TEST_MODEL.stop("Stop-2").build(); private static final List STOP_TIMES = List.of( @@ -57,7 +59,7 @@ public class OtpTransitServiceBuilderLimitPeriodTest { ); private static final StopPattern STOP_PATTERN = new StopPattern(STOP_TIMES); private static int SEQ_NR = 0; - private final Route route = TransitModelForTest.route(newId().getId()).build(); + private final Route route = TimetableRepositoryForTest.route(newId().getId()).build(); private final Trip tripCSIn = createTrip("TCalIn", SERVICE_C_IN); private final Trip tripCSOut = createTrip("TCalOut", SERVICE_C_OUT); private final Trip tripCSDIn = createTrip("TDateIn", SERVICE_D_IN); @@ -68,7 +70,7 @@ public class OtpTransitServiceBuilderLimitPeriodTest { @BeforeEach public void setUp() { - subject = new OtpTransitServiceBuilder(new StopModel(), DataImportIssueStore.NOOP); + subject = new OtpTransitServiceBuilder(new SiteRepository(), DataImportIssueStore.NOOP); // Add a service calendar that overlap with the period limit subject.getCalendars().add(createServiceCalendar(SERVICE_C_IN, D1, D3)); @@ -83,8 +85,8 @@ public void setUp() { subject.getCalendarDates().add(new ServiceCalendarDate(SERVICE_D_OUT, D1, 1)); // Add 2 stops - subject.stopModel().withRegularStop(STOP_1); - subject.stopModel().withRegularStop(STOP_2); + subject.siteRepository().withRegularStop(STOP_1); + subject.siteRepository().withRegularStop(STOP_2); // Add Route subject.getRoutes().add(route); @@ -141,16 +143,27 @@ public void testLimitPeriod() { assertTrue(patterns.contains(patternInT1), patterns.toString()); assertTrue(patterns.contains(patternInT2), patterns.toString()); - // Verify trips in pattern (one trip is removed from patternInT1) - assertEquals(1, patternInT1.scheduledTripsAsStream().count()); - assertEquals(tripCSIn, patternInT1.scheduledTripsAsStream().findFirst().orElseThrow()); - - // Verify trips in pattern is unchanged (one trip) + // Verify patternInT1 is replaced by a copy that contains one less trip + TripPattern copyOfTripPattern1 = subject + .getTripPatterns() + .values() + .stream() + .filter(p -> p.getId().equals(patternInT1.getId())) + .findFirst() + .orElseThrow(); + assertNotSame(patternInT1, copyOfTripPattern1); + assertEquals(1, copyOfTripPattern1.scheduledTripsAsStream().count()); + assertEquals(tripCSIn, copyOfTripPattern1.scheduledTripsAsStream().findFirst().orElseThrow()); + + // Verify trips in patternInT2 is unchanged (one trip) assertEquals(1, patternInT2.scheduledTripsAsStream().count()); - // Verify scheduledTimetable trips (one trip is removed from patternInT1) - assertEquals(1, patternInT1.getScheduledTimetable().getTripTimes().size()); - assertEquals(tripCSIn, patternInT1.getScheduledTimetable().getTripTimes().get(0).getTrip()); + // Verify scheduledTimetable trips (one trip is removed from the copy of patternInT1) + assertEquals(1, copyOfTripPattern1.getScheduledTimetable().getTripTimes().size()); + assertEquals( + tripCSIn, + copyOfTripPattern1.getScheduledTimetable().getTripTimes().get(0).getTrip() + ); // Verify scheduledTimetable trips in pattern is unchanged (one trip) assertEquals(1, patternInT2.getScheduledTimetable().getTripTimes().size()); @@ -179,27 +192,28 @@ private static StopTime createStopTime(RegularStop stop, int time) { } private static FeedScopedId newId() { - return TransitModelForTest.id(Integer.toString(++SEQ_NR)); + return TimetableRepositoryForTest.id(Integer.toString(++SEQ_NR)); } private TripPattern createTripPattern(Collection trips) { - FeedScopedId patternId = TransitModelForTest.id( + FeedScopedId patternId = TimetableRepositoryForTest.id( trips.stream().map(t -> t.getId().getId()).collect(Collectors.joining(":")) ); - TripPattern p = TripPattern + TripPatternBuilder tpb = TripPattern .of(patternId) .withRoute(route) - .withStopPattern(STOP_PATTERN) - .build(); + .withStopPattern(STOP_PATTERN); for (Trip trip : trips) { - p.add(TripTimesFactory.tripTimes(trip, STOP_TIMES, DEDUPLICATOR)); + tpb.withScheduledTimeTableBuilder(builder -> + builder.addTripTimes(TripTimesFactory.tripTimes(trip, STOP_TIMES, DEDUPLICATOR)) + ); } - return p; + return tpb.build(); } private Trip createTrip(String id, FeedScopedId serviceId) { - return TransitModelForTest + return TimetableRepositoryForTest .trip(id) .withServiceId(serviceId) .withDirection(Direction.INBOUND) diff --git a/src/test/java/org/opentripplanner/model/impl/OtpTransitServiceBuilderTest.java b/application/src/test/java/org/opentripplanner/model/impl/OtpTransitServiceBuilderTest.java similarity index 93% rename from src/test/java/org/opentripplanner/model/impl/OtpTransitServiceBuilderTest.java rename to application/src/test/java/org/opentripplanner/model/impl/OtpTransitServiceBuilderTest.java index 9fd0bd4d8cb..d1c406d4ae1 100644 --- a/src/test/java/org/opentripplanner/model/impl/OtpTransitServiceBuilderTest.java +++ b/application/src/test/java/org/opentripplanner/model/impl/OtpTransitServiceBuilderTest.java @@ -17,15 +17,15 @@ import org.opentripplanner.model.ShapePoint; import org.opentripplanner.model.calendar.ServiceCalendar; import org.opentripplanner.model.calendar.ServiceCalendarDate; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Agency; public class OtpTransitServiceBuilderTest { - private static final String FEED_ID = TransitModelForTest.FEED_ID; - private static final FeedScopedId SERVICE_WEEKDAYS_ID = TransitModelForTest.id("weekdays"); + private static final String FEED_ID = TimetableRepositoryForTest.FEED_ID; + private static final FeedScopedId SERVICE_WEEKDAYS_ID = TimetableRepositoryForTest.id("weekdays"); private static OtpTransitServiceBuilder subject; diff --git a/src/test/java/org/opentripplanner/model/impl/OtpTransitServiceImplTest.java b/application/src/test/java/org/opentripplanner/model/impl/OtpTransitServiceImplTest.java similarity index 90% rename from src/test/java/org/opentripplanner/model/impl/OtpTransitServiceImplTest.java rename to application/src/test/java/org/opentripplanner/model/impl/OtpTransitServiceImplTest.java index 9ecdbbeb451..4b7636ca07f 100644 --- a/src/test/java/org/opentripplanner/model/impl/OtpTransitServiceImplTest.java +++ b/application/src/test/java/org/opentripplanner/model/impl/OtpTransitServiceImplTest.java @@ -6,7 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.gtfs.GtfsContextBuilder.contextBuilder; -import static org.opentripplanner.transit.model._data.TransitModelForTest.FEED_ID; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.FEED_ID; import java.io.IOException; import java.util.ArrayList; @@ -20,7 +20,7 @@ import org.opentripplanner.model.OtpTransitService; import org.opentripplanner.model.ShapePoint; import org.opentripplanner.model.StopTime; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.Pathway; @@ -31,7 +31,7 @@ public class OtpTransitServiceImplTest { - private static final FeedScopedId STATION_ID = TransitModelForTest.id("station"); + private static final FeedScopedId STATION_ID = TimetableRepositoryForTest.id("station"); // The subject is used as read only; hence static is ok private static OtpTransitService subject; @@ -94,7 +94,7 @@ public void testGetAllTransfers() { @Test public void testGetAllStations() { - Collection stations = subject.stopModel().listStations(); + Collection stations = subject.siteRepository().listStations(); assertEquals(1, stations.size()); assertEquals("Station{F:station station}", first(stations).toString()); @@ -102,7 +102,7 @@ public void testGetAllStations() { @Test public void testGetAllStops() { - Collection stops = subject.stopModel().listRegularStops(); + Collection stops = subject.siteRepository().listRegularStops(); assertEquals(25, stops.size()); assertEquals("RegularStop{F:A A}", first(stops).toString()); @@ -123,7 +123,7 @@ public void testGetAllStopTimes() { } @Test - public void testGetAllTrips() { + public void testListTrips() { Collection trips = subject.getAllTrips(); assertEquals(34, trips.size()); @@ -132,21 +132,23 @@ public void testGetAllTrips() { @Test public void testGetStopForId() { - RegularStop stop = subject.stopModel().getRegularStop(TransitModelForTest.id("P")); + RegularStop stop = subject.siteRepository().getRegularStop(TimetableRepositoryForTest.id("P")); assertEquals("RegularStop{F:P P}", stop.toString()); } @Test public void testGetStopsForStation() { List stops = new ArrayList<>( - subject.stopModel().getStationById(STATION_ID).getChildStops() + subject.siteRepository().getStationById(STATION_ID).getChildStops() ); assertEquals("[RegularStop{F:A A}]", stops.toString()); } @Test public void testGetShapePointsForShapeId() { - List shapePoints = subject.getShapePointsForShapeId(TransitModelForTest.id("5")); + List shapePoints = subject.getShapePointsForShapeId( + TimetableRepositoryForTest.id("5") + ); assertEquals( "[#1 (41,-72), #2 (41,-72), #3 (40,-72), #4 (41,-73), #5 (41,-74)]", shapePoints.stream().map(OtpTransitServiceImplTest::toString).toList().toString() diff --git a/src/test/java/org/opentripplanner/model/modes/AllowAllModesFilterTest.java b/application/src/test/java/org/opentripplanner/model/modes/AllowAllModesFilterTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/modes/AllowAllModesFilterTest.java rename to application/src/test/java/org/opentripplanner/model/modes/AllowAllModesFilterTest.java diff --git a/src/test/java/org/opentripplanner/model/modes/AllowMainAndSubModeFilterTest.java b/application/src/test/java/org/opentripplanner/model/modes/AllowMainAndSubModeFilterTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/modes/AllowMainAndSubModeFilterTest.java rename to application/src/test/java/org/opentripplanner/model/modes/AllowMainAndSubModeFilterTest.java diff --git a/src/test/java/org/opentripplanner/model/modes/AllowMainAndSubModesFilterTest.java b/application/src/test/java/org/opentripplanner/model/modes/AllowMainAndSubModesFilterTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/modes/AllowMainAndSubModesFilterTest.java rename to application/src/test/java/org/opentripplanner/model/modes/AllowMainAndSubModesFilterTest.java diff --git a/src/test/java/org/opentripplanner/model/modes/AllowMainModeFilterTest.java b/application/src/test/java/org/opentripplanner/model/modes/AllowMainModeFilterTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/modes/AllowMainModeFilterTest.java rename to application/src/test/java/org/opentripplanner/model/modes/AllowMainModeFilterTest.java diff --git a/src/test/java/org/opentripplanner/model/modes/AllowMainModesFilterTest.java b/application/src/test/java/org/opentripplanner/model/modes/AllowMainModesFilterTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/modes/AllowMainModesFilterTest.java rename to application/src/test/java/org/opentripplanner/model/modes/AllowMainModesFilterTest.java diff --git a/src/test/java/org/opentripplanner/model/modes/PathTailFilterFactoryTest.java b/application/src/test/java/org/opentripplanner/model/modes/PathTailFilterFactoryTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/modes/PathTailFilterFactoryTest.java rename to application/src/test/java/org/opentripplanner/model/modes/PathTailFilterFactoryTest.java diff --git a/src/test/java/org/opentripplanner/model/plan/ElevationProfileTest.java b/application/src/test/java/org/opentripplanner/model/plan/ElevationProfileTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/plan/ElevationProfileTest.java rename to application/src/test/java/org/opentripplanner/model/plan/ElevationProfileTest.java diff --git a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java b/application/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java similarity index 94% rename from src/test/java/org/opentripplanner/model/plan/ItineraryTest.java rename to application/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java index 142ced31504..58bb8d84ba0 100644 --- a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java +++ b/application/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java @@ -16,7 +16,7 @@ import org.opentripplanner.framework.model.TimeAndCost; import org.opentripplanner.model.SystemNotice; import org.opentripplanner.street.search.TraverseMode; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; public class ItineraryTest implements PlanTestConstants { @@ -65,7 +65,7 @@ void testDerivedFieldsWithBusAllTheWay() { assertEquals(newTime(T11_00), result.firstLeg().getStartTime()); assertEquals(newTime(T11_10), result.firstLeg().getEndTime()); assertEquals(TransitMode.BUS, result.getTransitLeg(0).getMode()); - assertEquals(TransitModelForTest.id("55"), result.firstLeg().getTrip().getId()); + assertEquals(TimetableRepositoryForTest.id("55"), result.firstLeg().getTrip().getId()); assertEquals(7500, result.firstLeg().getDistanceMeters(), 1E-3); assertEquals("A ~ BUS 55 11:00 11:10 ~ B [C₁720]", result.toStr()); @@ -89,7 +89,7 @@ void testDerivedFieldsWithTrainAllTheWay() { assertEquals(newTime(T11_05), result.firstLeg().getStartTime()); assertEquals(newTime(T11_15), result.firstLeg().getEndTime()); assertEquals(TransitMode.RAIL, result.getTransitLeg(0).getMode()); - assertEquals(TransitModelForTest.id("20"), result.firstLeg().getTrip().getId()); + assertEquals(TimetableRepositoryForTest.id("20"), result.firstLeg().getTrip().getId()); assertEquals(15_000, result.firstLeg().getDistanceMeters(), 1E-3); assertEquals("A ~ RAIL R2 11:05 11:15 ~ B [C₁720]", result.toStr()); @@ -258,6 +258,17 @@ void bothPenalties() { ); } + @Test + void directFlex() { + assertFalse(itinerary().isDirectFlex()); + assertTrue(newItinerary(A).flex(T11_10, T11_20, B).build().isDirectFlex()); + } + + @Test + void walkOnlyIsNotDirectFlex() { + assertFalse(TestItineraryBuilder.newItinerary(A, T11_00).walk(10, B).build().isDirectFlex()); + } + private static Itinerary itinerary() { return newItinerary(A).bus(1, T11_04, T11_14, B).build(); } diff --git a/src/test/java/org/opentripplanner/model/plan/LegTest.java b/application/src/test/java/org/opentripplanner/model/plan/LegTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/plan/LegTest.java rename to application/src/test/java/org/opentripplanner/model/plan/LegTest.java diff --git a/src/test/java/org/opentripplanner/model/plan/PlaceTest.java b/application/src/test/java/org/opentripplanner/model/plan/PlaceTest.java similarity index 94% rename from src/test/java/org/opentripplanner/model/plan/PlaceTest.java rename to application/src/test/java/org/opentripplanner/model/plan/PlaceTest.java index 95d7cf629a2..4d7375b7c89 100644 --- a/src/test/java/org/opentripplanner/model/plan/PlaceTest.java +++ b/application/src/test/java/org/opentripplanner/model/plan/PlaceTest.java @@ -16,10 +16,10 @@ import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.street.model.vertex.SimpleVertex; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; public class PlaceTest { @@ -51,7 +51,7 @@ public void sameLocationBasedOnCoordinates() { @Test public void sameLocationBasedOnStopId() { - var testModel = TransitModelForTest.of(); + var testModel = TimetableRepositoryForTest.of(); var s1 = testModel.stop("1").withCoordinate(1.0, 1.0).build(); var s2 = testModel.stop("2").withCoordinate(1.0, 2.0).build(); @@ -79,7 +79,7 @@ static Stream flexStopCases() { @ParameterizedTest(name = "Flex stop name of {0} should lead to a place name of {1}") @MethodSource("flexStopCases") public void flexStop(I18NString stopName, String expectedPlaceName) { - var stop = StopModel + var stop = SiteRepository .of() .areaStop(new FeedScopedId("1", "stop_id")) .withGeometry(GEOMETRY) diff --git a/src/test/java/org/opentripplanner/model/plan/PlanTestConstants.java b/application/src/test/java/org/opentripplanner/model/plan/PlanTestConstants.java similarity index 67% rename from src/test/java/org/opentripplanner/model/plan/PlanTestConstants.java rename to application/src/test/java/org/opentripplanner/model/plan/PlanTestConstants.java index edb967b5b16..adebe4f111c 100644 --- a/src/test/java/org/opentripplanner/model/plan/PlanTestConstants.java +++ b/application/src/test/java/org/opentripplanner/model/plan/PlanTestConstants.java @@ -1,9 +1,9 @@ package org.opentripplanner.model.plan; -import static org.opentripplanner.framework.time.TimeUtils.time; +import static org.opentripplanner.utils.time.TimeUtils.time; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.utils.time.DurationUtils; public interface PlanTestConstants { int NOT_SET = -999_999; @@ -55,55 +55,55 @@ public interface PlanTestConstants { int T11_55 = time("11:55"); /** - * @deprecated Create the TransitModelForTest per test, do not share between tests - it has state + * @deprecated Create the TimetableRepositoryForTest per test, do not share between tests - it has state */ @Deprecated - TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); /** - * @deprecated Depend on TransitModelForTest. Create per test, do not share between tests - it has state + * @deprecated Depend on TimetableRepositoryForTest. Create per test, do not share between tests - it has state */ @Deprecated Place A = Place.forStop(TEST_MODEL.stop("A").withCoordinate(5.0, 8.0).build()); /** - * @deprecated Depend on TransitModelForTest. Create per test, do not share between tests - it has state + * @deprecated Depend on TimetableRepositoryForTest. Create per test, do not share between tests - it has state */ @Deprecated Place B = Place.forStop(TEST_MODEL.stop("B").withCoordinate(6.0, 8.5).build()); /** - * @deprecated Depend on TransitModelForTest. Create per test, do not share between tests - it has state + * @deprecated Depend on TimetableRepositoryForTest. Create per test, do not share between tests - it has state */ @Deprecated Place C = Place.forStop(TEST_MODEL.stop("C").withCoordinate(7.0, 9.0).build()); /** - * @deprecated Depend on TransitModelForTest. Create per test, do not share between tests - it has state + * @deprecated Depend on TimetableRepositoryForTest. Create per test, do not share between tests - it has state */ @Deprecated Place D = Place.forStop(TEST_MODEL.stop("D").withCoordinate(8.0, 9.5).build()); /** - * @deprecated Depend on TransitModelForTest. Create per test, do not share between tests - it has state + * @deprecated Depend on TimetableRepositoryForTest. Create per test, do not share between tests - it has state */ @Deprecated Place E = Place.forStop(TEST_MODEL.stop("E").withCoordinate(9.0, 10.0).build()); /** - * @deprecated Depend on TransitModelForTest. Create per test, do not share between tests - it has state + * @deprecated Depend on TimetableRepositoryForTest. Create per test, do not share between tests - it has state */ @Deprecated Place F = Place.forStop(TEST_MODEL.stop("F").withCoordinate(9.0, 10.5).build()); /** - * @deprecated Depend on TransitModelForTest. Create per test, do not share between tests - it has state + * @deprecated Depend on TimetableRepositoryForTest. Create per test, do not share between tests - it has state */ @Deprecated Place G = Place.forStop(TEST_MODEL.stop("G").withCoordinate(9.5, 11.0).build()); /** - * @deprecated Depend on TransitModelForTest. Create per test, do not share between tests - it has state + * @deprecated Depend on TimetableRepositoryForTest. Create per test, do not share between tests - it has state */ @Deprecated Place H = Place.forStop(TEST_MODEL.stop("H").withCoordinate(10.0, 11.5).build()); diff --git a/src/test/java/org/opentripplanner/model/plan/RelativeDirectionTest.java b/application/src/test/java/org/opentripplanner/model/plan/RelativeDirectionTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/plan/RelativeDirectionTest.java rename to application/src/test/java/org/opentripplanner/model/plan/RelativeDirectionTest.java diff --git a/src/test/java/org/opentripplanner/model/plan/ScheduledTransitLegBuilderTest.java b/application/src/test/java/org/opentripplanner/model/plan/ScheduledTransitLegBuilderTest.java similarity index 84% rename from src/test/java/org/opentripplanner/model/plan/ScheduledTransitLegBuilderTest.java rename to application/src/test/java/org/opentripplanner/model/plan/ScheduledTransitLegBuilderTest.java index 4b26ccb1c55..8d3d6ed7c1e 100644 --- a/src/test/java/org/opentripplanner/model/plan/ScheduledTransitLegBuilderTest.java +++ b/application/src/test/java/org/opentripplanner/model/plan/ScheduledTransitLegBuilderTest.java @@ -5,14 +5,14 @@ import java.time.LocalDate; import org.junit.jupiter.api.Test; import org.opentripplanner._support.time.ZoneIds; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; class ScheduledTransitLegBuilderTest { @Test void transferZoneId() { - var pattern = TransitModelForTest.of().pattern(TransitMode.BUS).build(); + var pattern = TimetableRepositoryForTest.of().pattern(TransitMode.BUS).build(); var leg = new ScheduledTransitLegBuilder<>() .withZoneId(ZoneIds.BERLIN) .withServiceDate(LocalDate.of(2023, 11, 15)) diff --git a/src/test/java/org/opentripplanner/model/plan/ScheduledTransitLegTest.java b/application/src/test/java/org/opentripplanner/model/plan/ScheduledTransitLegTest.java similarity index 82% rename from src/test/java/org/opentripplanner/model/plan/ScheduledTransitLegTest.java rename to application/src/test/java/org/opentripplanner/model/plan/ScheduledTransitLegTest.java index b41ace81e8d..89eb13c56af 100644 --- a/src/test/java/org/opentripplanner/model/plan/ScheduledTransitLegTest.java +++ b/application/src/test/java/org/opentripplanner/model/plan/ScheduledTransitLegTest.java @@ -3,14 +3,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.time.OffsetDateTime; import java.time.ZonedDateTime; import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner._support.time.ZoneIds; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.RealTimeTripTimes; @@ -22,13 +22,13 @@ class ScheduledTransitLegTest { static final ZonedDateTime TIME = OffsetDateTime .parse("2023-04-17T17:49:06+02:00") .toZonedDateTime(); - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); - private static final Route ROUTE = TransitModelForTest.route(id("2")).build(); - private static final TripPattern PATTERN = TransitModelForTest + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); + private static final Route ROUTE = TimetableRepositoryForTest.route(id("2")).build(); + private static final TripPattern PATTERN = TimetableRepositoryForTest .tripPattern("1", ROUTE) .withStopPattern(TEST_MODEL.stopPattern(3)) .build(); - private static final Trip TRIP = TransitModelForTest.trip("trip1").build(); + private static final Trip TRIP = TimetableRepositoryForTest.trip("trip1").build(); private static final ScheduledTripTimes TRIP_TIMES = ScheduledTripTimes .of() .withArrivalTimes("10:00 11:00 12:00") diff --git a/src/test/java/org/opentripplanner/model/plan/TestItineraryBuilder.java b/application/src/test/java/org/opentripplanner/model/plan/TestItineraryBuilder.java similarity index 93% rename from src/test/java/org/opentripplanner/model/plan/TestItineraryBuilder.java rename to application/src/test/java/org/opentripplanner/model/plan/TestItineraryBuilder.java index edaafabd753..33eeae0a553 100644 --- a/src/test/java/org/opentripplanner/model/plan/TestItineraryBuilder.java +++ b/application/src/test/java/org/opentripplanner/model/plan/TestItineraryBuilder.java @@ -4,9 +4,9 @@ import static org.opentripplanner.street.search.TraverseMode.BICYCLE; import static org.opentripplanner.street.search.TraverseMode.CAR; import static org.opentripplanner.street.search.TraverseMode.WALK; -import static org.opentripplanner.transit.model._data.TransitModelForTest.FEED_ID; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; -import static org.opentripplanner.transit.model._data.TransitModelForTest.route; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.FEED_ID; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.route; import java.time.Duration; import java.time.LocalDate; @@ -22,14 +22,12 @@ import org.opentripplanner.ext.ridehailing.model.RideHailingLeg; import org.opentripplanner.ext.ridehailing.model.RideHailingProvider; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.lang.IntUtils; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.model.StopTime; import org.opentripplanner.model.transfer.ConstrainedTransfer; import org.opentripplanner.model.transfer.TransferConstraint; import org.opentripplanner.street.model._data.StreetModelForTest; import org.opentripplanner.street.search.TraverseMode; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; @@ -41,6 +39,8 @@ import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.model.timetable.TripTimesFactory; +import org.opentripplanner.utils.lang.IntUtils; +import org.opentripplanner.utils.time.TimeUtils; /** * This is a helper class to allow unit-testing on Itineraries. The builder does not necessarily @@ -73,6 +73,7 @@ public class TestItineraryBuilder implements PlanTestConstants { private int lastEndTime; private int c1 = 0; private int c2 = NOT_SET; + private boolean isSearchWindowAware = true; private TestItineraryBuilder(Place origin, int startTime) { this.lastPlace = origin; @@ -199,9 +200,13 @@ public TestItineraryBuilder flex(int start, int end, Place to) { int legCost = 0; StopTime fromStopTime = new StopTime(); fromStopTime.setStop(lastPlace.stop); + fromStopTime.setFlexWindowStart(start); + fromStopTime.setFlexWindowEnd(end); StopTime toStopTime = new StopTime(); toStopTime.setStop(to.stop); + toStopTime.setFlexWindowStart(start); + toStopTime.setFlexWindowEnd(end); Trip trip = trip("1", route("flex").build()); @@ -398,6 +403,11 @@ public TestItineraryBuilder withGeneralizedCost2(int c2) { return this; } + public TestItineraryBuilder withIsSearchWindowAware(boolean searchWindowAware) { + this.isSearchWindowAware = searchWindowAware; + return this; + } + public Itinerary egress(int walkDuration) { walk(walkDuration, null); return build(); @@ -413,7 +423,12 @@ public Itinerary build(int c1) { } public Itinerary build() { - Itinerary itinerary = new Itinerary(legs); + Itinerary itinerary; + if (isSearchWindowAware) { + itinerary = Itinerary.createScheduledTransitItinerary(legs); + } else { + itinerary = Itinerary.createDirectItinerary(legs); + } itinerary.setGeneralizedCost(c1); if (c2 != NOT_SET) { itinerary.setGeneralizedCost2(c2); @@ -425,7 +440,7 @@ public Itinerary build() { /** Create a dummy trip */ private static Trip trip(String id, Route route) { - return TransitModelForTest + return TimetableRepositoryForTest .trip(id) .withRoute(route) .withHeadsign(I18NString.of("Trip headsign %s".formatted(id))) @@ -482,13 +497,13 @@ public TestItineraryBuilder transit( stopTimes.add(toStopTime); StopPattern stopPattern = new StopPattern(stopTimes); + final TripTimes tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, new Deduplicator()); TripPattern tripPattern = TripPattern .of(route.getId()) .withRoute(route) .withStopPattern(stopPattern) + .withScheduledTimeTableBuilder(builder -> builder.addTripTimes(tripTimes)) .build(); - final TripTimes tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, new Deduplicator()); - tripPattern.add(tripTimes); ScheduledTransitLeg leg; diff --git a/src/test/java/org/opentripplanner/model/plan/WalkStepTest.java b/application/src/test/java/org/opentripplanner/model/plan/WalkStepTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/plan/WalkStepTest.java rename to application/src/test/java/org/opentripplanner/model/plan/WalkStepTest.java diff --git a/src/test/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializerTest.java b/application/src/test/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializerTest.java similarity index 90% rename from src/test/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializerTest.java rename to application/src/test/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializerTest.java index 2d7df788ad3..d0d17cc95ab 100644 --- a/src/test/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializerTest.java +++ b/application/src/test/java/org/opentripplanner/model/plan/legreference/LegReferenceSerializerTest.java @@ -6,18 +6,18 @@ import java.time.LocalDate; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; class LegReferenceSerializerTest { - private static final FeedScopedId TRIP_ID = TransitModelForTest.id("Trip"); + private static final FeedScopedId TRIP_ID = TimetableRepositoryForTest.id("Trip"); private static final LocalDate SERVICE_DATE = LocalDate.of(2022, 1, 31); private static final int FROM_STOP_POS = 1; - private static final FeedScopedId FROM_STOP_ID = TransitModelForTest.id("Boarding Stop"); + private static final FeedScopedId FROM_STOP_ID = TimetableRepositoryForTest.id("Boarding Stop"); private static final int TO_STOP_POS = 3; - private static final FeedScopedId TO_STOP_ID = TransitModelForTest.id("Alighting Stop"); + private static final FeedScopedId TO_STOP_ID = TimetableRepositoryForTest.id("Alighting Stop"); /** * Token based on the initial format, without stop ids. diff --git a/src/test/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReferenceTest.java b/application/src/test/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReferenceTest.java similarity index 82% rename from src/test/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReferenceTest.java rename to application/src/test/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReferenceTest.java index 480639e5bda..210d58e054e 100644 --- a/src/test/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReferenceTest.java +++ b/application/src/test/java/org/opentripplanner/model/plan/legreference/ScheduledTransitLegReferenceTest.java @@ -4,18 +4,16 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.time.LocalDate; import java.util.List; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.model.Timetable; import org.opentripplanner.model.calendar.CalendarServiceData; -import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.model.plan.ScheduledTransitLeg; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.TripPattern; @@ -25,13 +23,13 @@ import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.model.timetable.TripTimesFactory; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.transit.service.TransitService; class ScheduledTransitLegReferenceTest { - private static TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final int SERVICE_CODE = 555; private static final LocalDate SERVICE_DATE = LocalDate.of(2023, 1, 1); private static final int NUMBER_OF_STOPS = 3; @@ -54,41 +52,47 @@ static void buildTransitService() { stop4 = TEST_MODEL.stop("STOP4", 0, 0).withParentStation(parentStation).build(); // build transit data - TripPattern tripPattern = TransitModelForTest - .tripPattern("1", TransitModelForTest.route(id("1")).build()) - .withStopPattern(TransitModelForTest.stopPattern(stop1, stop2, stop3)) - .build(); - Timetable timetable = tripPattern.getScheduledTimetable(); - Trip trip = TransitModelForTest.trip("1").build(); - tripId = trip.getId(); - stopIdAtPosition0 = tripPattern.getStop(0).getId(); - stopIdAtPosition1 = tripPattern.getStop(1).getId(); - stopIdAtPosition2 = tripPattern.getStop(2).getId(); + Trip trip = TimetableRepositoryForTest.trip("1").build(); var tripTimes = TripTimesFactory.tripTimes( trip, - TEST_MODEL.stopTimesEvery5Minutes(5, trip, PlanTestConstants.T11_00), + TEST_MODEL.stopTimesEvery5Minutes(5, trip, "11:00"), new Deduplicator() ); tripTimes.setServiceCode(SERVICE_CODE); - timetable.addTripTimes(tripTimes); + TripPattern tripPattern = TimetableRepositoryForTest + .tripPattern("1", TimetableRepositoryForTest.route(id("1")).build()) + .withStopPattern(TimetableRepositoryForTest.stopPattern(stop1, stop2, stop3)) + .withScheduledTimeTableBuilder(builder -> builder.addTripTimes(tripTimes)) + .build(); + + tripId = trip.getId(); + stopIdAtPosition0 = tripPattern.getStop(0).getId(); + stopIdAtPosition1 = tripPattern.getStop(1).getId(); + stopIdAtPosition2 = tripPattern.getStop(2).getId(); // build transit model - StopModel stopModel = TEST_MODEL - .stopModelBuilder() + SiteRepository siteRepository = TEST_MODEL + .siteRepositoryBuilder() .withRegularStop(stop1) .withRegularStop(stop2) .withRegularStop(stop3) .withRegularStop(stop4) .build(); - TransitModel transitModel = new TransitModel(stopModel, new Deduplicator()); - transitModel.addTripPattern(tripPattern.getId(), tripPattern); - transitModel.getServiceCodes().put(tripPattern.getId(), SERVICE_CODE); + TimetableRepository timetableRepository = new TimetableRepository( + siteRepository, + new Deduplicator() + ); + timetableRepository.addTripPattern(tripPattern.getId(), tripPattern); + timetableRepository.getServiceCodes().put(tripPattern.getId(), SERVICE_CODE); CalendarServiceData calendarServiceData = new CalendarServiceData(); calendarServiceData.putServiceDatesForServiceId(tripPattern.getId(), List.of(SERVICE_DATE)); - transitModel.updateCalendarServiceData(true, calendarServiceData, DataImportIssueStore.NOOP); + timetableRepository.updateCalendarServiceData( + true, + calendarServiceData, + DataImportIssueStore.NOOP + ); - transitModel.addTripOnServiceDate( - TRIP_ON_SERVICE_DATE_ID, + timetableRepository.addTripOnServiceDate( TripOnServiceDate .of(TRIP_ON_SERVICE_DATE_ID) .withTrip(trip) @@ -96,10 +100,10 @@ static void buildTransitService() { .build() ); - transitModel.index(); + timetableRepository.index(); // build transit service - transitService = new DefaultTransitService(transitModel); + transitService = new DefaultTransitService(timetableRepository); } @Test @@ -172,7 +176,7 @@ void getLegFromReferenceMismatchOnBoardingStop() { SERVICE_DATE, 0, 1, - TransitModelForTest.id("invalid stop id"), + TimetableRepositoryForTest.id("invalid stop id"), stopIdAtPosition1, null ); @@ -221,7 +225,7 @@ void legReferenceCannotReferToBothTripAndTripOnServiceDate() { NUMBER_OF_STOPS, stopIdAtPosition0, stopIdAtPosition1, - TransitModelForTest.id("trip on date id") + TimetableRepositoryForTest.id("trip on date id") ) ); } @@ -249,7 +253,7 @@ void getLegFromReferenceWithUnknownTripOnDate() { NUMBER_OF_STOPS, stopIdAtPosition0, stopIdAtPosition1, - TransitModelForTest.id("unknown trip on date id") + TimetableRepositoryForTest.id("unknown trip on date id") ); assertNull(scheduledTransitLegReference.getLeg(transitService)); } diff --git a/src/test/java/org/opentripplanner/model/plan/paging/PagingSearchWindowAdjusterTest.java b/application/src/test/java/org/opentripplanner/model/plan/paging/PagingSearchWindowAdjusterTest.java similarity index 98% rename from src/test/java/org/opentripplanner/model/plan/paging/PagingSearchWindowAdjusterTest.java rename to application/src/test/java/org/opentripplanner/model/plan/paging/PagingSearchWindowAdjusterTest.java index 22dcd49e63f..784fa4b5f99 100644 --- a/src/test/java/org/opentripplanner/model/plan/paging/PagingSearchWindowAdjusterTest.java +++ b/application/src/test/java/org/opentripplanner/model/plan/paging/PagingSearchWindowAdjusterTest.java @@ -1,7 +1,7 @@ package org.opentripplanner.model.plan.paging; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.time.DurationUtils.duration; +import static org.opentripplanner.utils.time.DurationUtils.duration; import java.time.Duration; import java.time.Instant; diff --git a/src/test/java/org/opentripplanner/model/plan/paging/cursor/DeduplicationPageCutTest.java b/application/src/test/java/org/opentripplanner/model/plan/paging/cursor/DeduplicationPageCutTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/plan/paging/cursor/DeduplicationPageCutTest.java rename to application/src/test/java/org/opentripplanner/model/plan/paging/cursor/DeduplicationPageCutTest.java diff --git a/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactoryTest.java b/application/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactoryTest.java similarity index 99% rename from src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactoryTest.java rename to application/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactoryTest.java index 7bf54d05bc2..910620872f3 100644 --- a/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactoryTest.java +++ b/application/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactoryTest.java @@ -10,10 +10,10 @@ import java.time.Duration; import java.time.Instant; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.PlanTestConstants; +import org.opentripplanner.utils.time.TimeUtils; @SuppressWarnings("ConstantConditions") class PageCursorFactoryTest implements PlanTestConstants { diff --git a/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializerTest.java b/application/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializerTest.java similarity index 97% rename from src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializerTest.java rename to application/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializerTest.java index 20c0230f309..e60c2aa1a5b 100644 --- a/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializerTest.java +++ b/application/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializerTest.java @@ -8,8 +8,8 @@ import java.time.Duration; import java.time.Instant; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.model.plan.ItinerarySortKey; +import org.opentripplanner.utils.time.DurationUtils; class PageCursorSerializerTest { diff --git a/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorTest.java b/application/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorTest.java similarity index 92% rename from src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorTest.java rename to application/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorTest.java index 10b59007c17..bd6037ef4a1 100644 --- a/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorTest.java +++ b/application/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorTest.java @@ -2,12 +2,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.opentripplanner.framework.collection.ListSection.HEAD; -import static org.opentripplanner.framework.collection.ListSection.TAIL; import static org.opentripplanner.model.plan.SortOrder.STREET_AND_ARRIVAL_TIME; import static org.opentripplanner.model.plan.SortOrder.STREET_AND_DEPARTURE_TIME; import static org.opentripplanner.model.plan.paging.cursor.PageType.NEXT_PAGE; import static org.opentripplanner.model.plan.paging.cursor.PageType.PREVIOUS_PAGE; +import static org.opentripplanner.utils.collection.ListSection.HEAD; +import static org.opentripplanner.utils.collection.ListSection.TAIL; import java.time.Duration; import java.time.Instant; @@ -21,17 +21,17 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner._support.time.ZoneIds; -import org.opentripplanner.framework.collection.ListSection; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.model.plan.SortOrder; import org.opentripplanner.model.plan.TestItineraryBuilder; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.utils.collection.ListSection; class PageCursorTest implements PlanTestConstants { - public static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + public static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); public static final Place A = Place.forStop( TEST_MODEL.stop("A").withCoordinate(5.0, 8.0).build() ); diff --git a/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageTypeTest.java b/application/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageTypeTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/plan/paging/cursor/PageTypeTest.java rename to application/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageTypeTest.java diff --git a/src/test/java/org/opentripplanner/model/projectinfo/GraphFileHeaderTest.java b/application/src/test/java/org/opentripplanner/model/projectinfo/GraphFileHeaderTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/projectinfo/GraphFileHeaderTest.java rename to application/src/test/java/org/opentripplanner/model/projectinfo/GraphFileHeaderTest.java diff --git a/src/test/java/org/opentripplanner/model/projectinfo/MavenProjectVersionTest.java b/application/src/test/java/org/opentripplanner/model/projectinfo/MavenProjectVersionTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/projectinfo/MavenProjectVersionTest.java rename to application/src/test/java/org/opentripplanner/model/projectinfo/MavenProjectVersionTest.java diff --git a/src/test/java/org/opentripplanner/model/projectinfo/OtpProjectInfoTest.java b/application/src/test/java/org/opentripplanner/model/projectinfo/OtpProjectInfoTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/projectinfo/OtpProjectInfoTest.java rename to application/src/test/java/org/opentripplanner/model/projectinfo/OtpProjectInfoTest.java diff --git a/src/test/java/org/opentripplanner/model/routing/TripSearchMetadataTest.java b/application/src/test/java/org/opentripplanner/model/routing/TripSearchMetadataTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/routing/TripSearchMetadataTest.java rename to application/src/test/java/org/opentripplanner/model/routing/TripSearchMetadataTest.java diff --git a/src/test/java/org/opentripplanner/model/transfer/ConstrainedTransferTest.java b/application/src/test/java/org/opentripplanner/model/transfer/ConstrainedTransferTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/transfer/ConstrainedTransferTest.java rename to application/src/test/java/org/opentripplanner/model/transfer/ConstrainedTransferTest.java diff --git a/src/test/java/org/opentripplanner/model/transfer/TransferConstraintTest.java b/application/src/test/java/org/opentripplanner/model/transfer/TransferConstraintTest.java similarity index 99% rename from src/test/java/org/opentripplanner/model/transfer/TransferConstraintTest.java rename to application/src/test/java/org/opentripplanner/model/transfer/TransferConstraintTest.java index 100e3137f49..47ff414790e 100644 --- a/src/test/java/org/opentripplanner/model/transfer/TransferConstraintTest.java +++ b/application/src/test/java/org/opentripplanner/model/transfer/TransferConstraintTest.java @@ -10,7 +10,7 @@ import java.util.function.IntSupplier; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.utils.time.DurationUtils; public class TransferConstraintTest { diff --git a/src/test/java/org/opentripplanner/model/transfer/TransferPointMapTest.java b/application/src/test/java/org/opentripplanner/model/transfer/TransferPointMapTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/transfer/TransferPointMapTest.java rename to application/src/test/java/org/opentripplanner/model/transfer/TransferPointMapTest.java diff --git a/src/test/java/org/opentripplanner/model/transfer/TransferPointTest.java b/application/src/test/java/org/opentripplanner/model/transfer/TransferPointTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/transfer/TransferPointTest.java rename to application/src/test/java/org/opentripplanner/model/transfer/TransferPointTest.java diff --git a/src/test/java/org/opentripplanner/model/transfer/TransferPriorityTest.java b/application/src/test/java/org/opentripplanner/model/transfer/TransferPriorityTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/transfer/TransferPriorityTest.java rename to application/src/test/java/org/opentripplanner/model/transfer/TransferPriorityTest.java diff --git a/src/test/java/org/opentripplanner/model/transfer/TransferServiceTest.java b/application/src/test/java/org/opentripplanner/model/transfer/TransferServiceTest.java similarity index 100% rename from src/test/java/org/opentripplanner/model/transfer/TransferServiceTest.java rename to application/src/test/java/org/opentripplanner/model/transfer/TransferServiceTest.java diff --git a/src/test/java/org/opentripplanner/model/transfer/TransferTestData.java b/application/src/test/java/org/opentripplanner/model/transfer/TransferTestData.java similarity index 68% rename from src/test/java/org/opentripplanner/model/transfer/TransferTestData.java rename to application/src/test/java/org/opentripplanner/model/transfer/TransferTestData.java index 19e0f82e8d5..6d70936657d 100644 --- a/src/test/java/org/opentripplanner/model/transfer/TransferTestData.java +++ b/application/src/test/java/org/opentripplanner/model/transfer/TransferTestData.java @@ -1,6 +1,6 @@ package org.opentripplanner.model.transfer; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; @@ -8,7 +8,7 @@ public class TransferTestData { - private static TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); static final Station STATION = TEST_MODEL.station("Central Station").build(); @@ -32,14 +32,14 @@ public class TransferTestData { .build(); static final RegularStop ANY_STOP = TEST_MODEL.stop("any", 60.0, 11.0).build(); - static final Route ROUTE_1 = TransitModelForTest.route("1").build(); - static final Route ROUTE_2 = TransitModelForTest.route("2").build(); - static final Route ANY_ROUTE = TransitModelForTest.route("ANY").build(); + static final Route ROUTE_1 = TimetableRepositoryForTest.route("1").build(); + static final Route ROUTE_2 = TimetableRepositoryForTest.route("2").build(); + static final Route ANY_ROUTE = TimetableRepositoryForTest.route("ANY").build(); - static final Trip TRIP_11 = TransitModelForTest.trip("11").withRoute(ROUTE_1).build(); - static final Trip TRIP_12 = TransitModelForTest.trip("12").withRoute(ROUTE_1).build(); - static final Trip TRIP_21 = TransitModelForTest.trip("21").withRoute(ROUTE_2).build(); - static final Trip ANY_TRIP = TransitModelForTest.trip("999").withRoute(ANY_ROUTE).build(); + static final Trip TRIP_11 = TimetableRepositoryForTest.trip("11").withRoute(ROUTE_1).build(); + static final Trip TRIP_12 = TimetableRepositoryForTest.trip("12").withRoute(ROUTE_1).build(); + static final Trip TRIP_21 = TimetableRepositoryForTest.trip("21").withRoute(ROUTE_2).build(); + static final Trip ANY_TRIP = TimetableRepositoryForTest.trip("999").withRoute(ANY_ROUTE).build(); static final TransferPoint STATION_POINT = new StationTransferPoint(STATION); diff --git a/src/test/java/org/opentripplanner/netex/NetexEpipBundleSmokeTest.java b/application/src/test/java/org/opentripplanner/netex/NetexEpipBundleSmokeTest.java similarity index 94% rename from src/test/java/org/opentripplanner/netex/NetexEpipBundleSmokeTest.java rename to application/src/test/java/org/opentripplanner/netex/NetexEpipBundleSmokeTest.java index b89e6883951..ac893842ccc 100644 --- a/src/test/java/org/opentripplanner/netex/NetexEpipBundleSmokeTest.java +++ b/application/src/test/java/org/opentripplanner/netex/NetexEpipBundleSmokeTest.java @@ -62,8 +62,8 @@ void smokeTestOfNetexEpipLoadData() { assertAgencies(otpModel.getAllAgencies()); assertOperators(otpModel.getAllOperators()); - assertStops(otpModel.stopModel().listRegularStops()); - assertStations(otpModel.stopModel().listStations()); + assertStops(otpModel.siteRepository().listRegularStops()); + assertStations(otpModel.siteRepository().listStations()); assertTripPatterns(otpModel.getTripPatterns()); assertTrips(otpModel.getAllTrips()); assertServiceIds(otpModel.getAllTrips(), otpModel.getAllServiceIds()); @@ -84,7 +84,7 @@ private static FeedScopedId fId(String id) { private void assertAgencies(Collection agencies) { assertEquals(3, agencies.size()); - Agency a = list(agencies).get(0); + Agency a = list(agencies).getFirst(); assertEquals("DE::Authority:41::", a.getId().getId()); assertEquals("HOCHBAHN, Bus", a.getName()); assertNull(a.getUrl()); @@ -92,7 +92,6 @@ private void assertAgencies(Collection agencies) { assertNull(a.getLang()); assertNull(a.getPhone()); assertNull(a.getFareUrl()); - assertNull(a.getBrandingUrl()); } private void assertOperators(Collection operators) { @@ -146,7 +145,7 @@ private void assertTripPatterns(Collection patterns) { p.getStops().toString() ); List trips = p.scheduledTripsAsStream().toList(); - assertEquals("Trip{HH:DE::ServiceJourney:36439031_0:: X86}", trips.get(0).toString()); + assertEquals("Trip{HH:DE::ServiceJourney:36439062_0:: X86}", trips.getFirst().toString()); assertEquals(55, trips.size()); assertEquals(4, patterns.size()); } @@ -176,12 +175,12 @@ private void assertServiceIds(Collection trips, Collection s private void assetServiceCalendar(CalendarServiceData cal) { ArrayList sIds = new ArrayList<>(cal.getServiceIds()); assertEquals(2, sIds.size()); - FeedScopedId serviceId1 = sIds.get(0); + FeedScopedId serviceId1 = sIds.getFirst(); List dates = cal.getServiceDatesForServiceId(serviceId1); - assertEquals("2023-02-02", dates.get(0).toString()); - assertEquals("2023-12-08", dates.get(dates.size() - 1).toString()); + assertEquals("2023-02-02", dates.getFirst().toString()); + assertEquals("2023-12-08", dates.getLast().toString()); assertEquals(214, dates.size()); } } diff --git a/src/test/java/org/opentripplanner/netex/NetexNordicBundleSmokeTest.java b/application/src/test/java/org/opentripplanner/netex/NetexNordicBundleSmokeTest.java similarity index 97% rename from src/test/java/org/opentripplanner/netex/NetexNordicBundleSmokeTest.java rename to application/src/test/java/org/opentripplanner/netex/NetexNordicBundleSmokeTest.java index 6b5e9b60098..f0b59e697ee 100644 --- a/src/test/java/org/opentripplanner/netex/NetexNordicBundleSmokeTest.java +++ b/application/src/test/java/org/opentripplanner/netex/NetexNordicBundleSmokeTest.java @@ -67,10 +67,10 @@ public void smokeTestOfNetexNordicLoadData() { OtpTransitService otpModel = transitBuilder.build(); assertAgencies(otpModel.getAllAgencies()); - assertMultiModalStations(otpModel.stopModel().listMultiModalStations()); + assertMultiModalStations(otpModel.siteRepository().listMultiModalStations()); assertOperators(otpModel.getAllOperators()); - assertStops(otpModel.stopModel().listRegularStops()); - assertStations(otpModel.stopModel().listStations()); + assertStops(otpModel.siteRepository().listRegularStops()); + assertStations(otpModel.siteRepository().listStations()); assertTripPatterns(otpModel.getTripPatterns()); assertTrips(otpModel.getAllTrips()); assertServiceIds(otpModel.getAllTrips(), otpModel.getAllServiceIds()); @@ -104,7 +104,6 @@ private void assertAgencies(Collection agencies) { assertNull(a.getLang()); assertNull(a.getPhone()); assertNull(a.getFareUrl()); - assertNull(a.getBrandingUrl()); } private void assertMultiModalStations(Collection multiModalStations) { diff --git a/src/test/java/org/opentripplanner/netex/NetexTestDataSupport.java b/application/src/test/java/org/opentripplanner/netex/NetexTestDataSupport.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/NetexTestDataSupport.java rename to application/src/test/java/org/opentripplanner/netex/NetexTestDataSupport.java diff --git a/src/test/java/org/opentripplanner/netex/config/NetexFeedParametersTest.java b/application/src/test/java/org/opentripplanner/netex/config/NetexFeedParametersTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/config/NetexFeedParametersTest.java rename to application/src/test/java/org/opentripplanner/netex/config/NetexFeedParametersTest.java diff --git a/src/test/java/org/opentripplanner/netex/index/hierarchy/E.java b/application/src/test/java/org/opentripplanner/netex/index/hierarchy/E.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/index/hierarchy/E.java rename to application/src/test/java/org/opentripplanner/netex/index/hierarchy/E.java diff --git a/src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalElementTest.java b/application/src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalElementTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalElementTest.java rename to application/src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalElementTest.java diff --git a/src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapByIdTest.java b/application/src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapByIdTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapByIdTest.java rename to application/src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapByIdTest.java diff --git a/src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapTest.java b/application/src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapTest.java rename to application/src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMapTest.java diff --git a/src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMultimapTest.java b/application/src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMultimapTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMultimapTest.java rename to application/src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalMultimapTest.java diff --git a/src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalVersionMapByIdTest.java b/application/src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalVersionMapByIdTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalVersionMapByIdTest.java rename to application/src/test/java/org/opentripplanner/netex/index/hierarchy/HierarchicalVersionMapByIdTest.java diff --git a/src/test/java/org/opentripplanner/netex/index/hierarchy/SetSupport.java b/application/src/test/java/org/opentripplanner/netex/index/hierarchy/SetSupport.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/index/hierarchy/SetSupport.java rename to application/src/test/java/org/opentripplanner/netex/index/hierarchy/SetSupport.java diff --git a/src/test/java/org/opentripplanner/netex/index/hierarchy/ValidOnDateTest.java b/application/src/test/java/org/opentripplanner/netex/index/hierarchy/ValidOnDateTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/index/hierarchy/ValidOnDateTest.java rename to application/src/test/java/org/opentripplanner/netex/index/hierarchy/ValidOnDateTest.java diff --git a/src/test/java/org/opentripplanner/netex/loader/NetexEntityIndexTest.java b/application/src/test/java/org/opentripplanner/netex/loader/NetexEntityIndexTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/loader/NetexEntityIndexTest.java rename to application/src/test/java/org/opentripplanner/netex/loader/NetexEntityIndexTest.java diff --git a/src/test/java/org/opentripplanner/netex/loader/parser/ResourceFrameParserTest.java b/application/src/test/java/org/opentripplanner/netex/loader/parser/ResourceFrameParserTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/loader/parser/ResourceFrameParserTest.java rename to application/src/test/java/org/opentripplanner/netex/loader/parser/ResourceFrameParserTest.java diff --git a/src/test/java/org/opentripplanner/netex/loader/parser/ServiceCalendarFrameParserTest.java b/application/src/test/java/org/opentripplanner/netex/loader/parser/ServiceCalendarFrameParserTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/loader/parser/ServiceCalendarFrameParserTest.java rename to application/src/test/java/org/opentripplanner/netex/loader/parser/ServiceCalendarFrameParserTest.java diff --git a/src/test/java/org/opentripplanner/netex/loader/parser/SiteFrameParserTest.java b/application/src/test/java/org/opentripplanner/netex/loader/parser/SiteFrameParserTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/loader/parser/SiteFrameParserTest.java rename to application/src/test/java/org/opentripplanner/netex/loader/parser/SiteFrameParserTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/AuthorityToAgencyMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/AuthorityToAgencyMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/AuthorityToAgencyMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/AuthorityToAgencyMapperTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/BookingInfoMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/BookingInfoMapperTest.java similarity index 99% rename from src/test/java/org/opentripplanner/netex/mapping/BookingInfoMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/BookingInfoMapperTest.java index e561a6155d3..7b917dcf912 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/BookingInfoMapperTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/BookingInfoMapperTest.java @@ -193,6 +193,6 @@ void testMapMinimumBookingNotice() { BookingInfo bookingInfo = subject.map(stopPoint, null, null); - assertEquals(THIRTY_MINUTES, bookingInfo.getMinimumBookingNotice()); + assertEquals(THIRTY_MINUTES, bookingInfo.getMinimumBookingNotice().get()); } } diff --git a/src/test/java/org/opentripplanner/netex/mapping/BrandingMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/BrandingMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/BrandingMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/BrandingMapperTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/DurationMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/DurationMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/DurationMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/DurationMapperTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/FeedScopedIdFactoryTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/FeedScopedIdFactoryTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/FeedScopedIdFactoryTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/FeedScopedIdFactoryTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java similarity index 95% rename from src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java index 7529ae52a34..272db6b62f0 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java @@ -17,13 +17,13 @@ import org.locationtech.jts.geom.Coordinate; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.model.site.GroupStop; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; -import org.opentripplanner.transit.service.StopModelBuilder; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; import org.rutebanken.netex.model.AllVehicleModesOfTransportEnumeration; import org.rutebanken.netex.model.FlexibleArea; import org.rutebanken.netex.model.FlexibleStopPlace; @@ -126,15 +126,15 @@ class FlexStopsMapperTest { .withValue("UnrestrictedPublicTransportAreas") ); - private final TransitModelForTest testModel = TransitModelForTest.of(); - private final StopModelBuilder stopModelBuilder = testModel.stopModelBuilder(); + private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of(); + private final SiteRepositoryBuilder siteRepositoryBuilder = testModel.siteRepositoryBuilder(); @Test void testMapAreaStop() { FlexStopsMapper flexStopsMapper = new FlexStopsMapper( ID_FACTORY, List.of(), - stopModelBuilder, + siteRepositoryBuilder, DataImportIssueStore.NOOP ); @@ -195,7 +195,7 @@ void testMapFlexibleStopPlaceMissingStops() { FlexStopsMapper subject = new FlexStopsMapper( ID_FACTORY, List.of(), - stopModelBuilder, + siteRepositoryBuilder, DataImportIssueStore.NOOP ); @@ -216,7 +216,7 @@ void testMapFlexibleStopPlaceWithInvalidGeometryOnUnrestrictedPublicTransportAre FlexStopsMapper subject = new FlexStopsMapper( ID_FACTORY, List.of(stop1, stop2), - stopModelBuilder, + siteRepositoryBuilder, DataImportIssueStore.NOOP ); @@ -248,7 +248,7 @@ private void assertGroupStopMapping(FlexibleStopPlace flexibleStopPlace) { FlexStopsMapper subject = new FlexStopsMapper( ID_FACTORY, List.of(stop1, stop2, stop3), - stopModelBuilder, + siteRepositoryBuilder, DataImportIssueStore.NOOP ); @@ -292,7 +292,7 @@ private AreaStop createAreaStop(Collection polygonCoordinates) { FlexStopsMapper flexStopsMapper = new FlexStopsMapper( ID_FACTORY, List.of(), - stopModelBuilder, + siteRepositoryBuilder, DataImportIssueStore.NOOP ); FlexibleStopPlace flexibleStopPlace = getFlexibleStopPlace(polygonCoordinates); diff --git a/src/test/java/org/opentripplanner/netex/mapping/GroupOfRoutesMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/GroupOfRoutesMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/GroupOfRoutesMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/GroupOfRoutesMapperTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/MappingSupport.java b/application/src/test/java/org/opentripplanner/netex/mapping/MappingSupport.java similarity index 94% rename from src/test/java/org/opentripplanner/netex/mapping/MappingSupport.java rename to application/src/test/java/org/opentripplanner/netex/mapping/MappingSupport.java index 49f6d88c26b..cbabe19ad2d 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/MappingSupport.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/MappingSupport.java @@ -1,7 +1,6 @@ package org.opentripplanner.netex.mapping; import jakarta.xml.bind.JAXBElement; -import javax.annotation.Nonnull; import javax.xml.namespace.QName; import org.opentripplanner.netex.mapping.support.FeedScopedIdFactory; import org.rutebanken.netex.model.VersionOfObjectRefStructure; @@ -54,7 +53,7 @@ public static T createRef(String id, Cla * @return the value wrapped in a JAXBElement */ @SuppressWarnings("unchecked") - public static JAXBElement createJaxbElement(@Nonnull T value) { + public static JAXBElement createJaxbElement(T value) { return new JAXBElement<>(new QName("x"), (Class) value.getClass(), value); } } diff --git a/src/test/java/org/opentripplanner/netex/mapping/MultiModalStationMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/MultiModalStationMapperTest.java similarity index 82% rename from src/test/java/org/opentripplanner/netex/mapping/MultiModalStationMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/MultiModalStationMapperTest.java index 218942d29ef..47442ce5fe2 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/MultiModalStationMapperTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/MultiModalStationMapperTest.java @@ -1,6 +1,7 @@ package org.opentripplanner.netex.mapping; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import java.util.List; import org.junit.jupiter.api.Test; @@ -8,7 +9,7 @@ import org.opentripplanner.graph_builder.issue.service.DefaultDataImportIssueStore; import org.opentripplanner.netex.NetexTestDataSupport; import org.opentripplanner.netex.mapping.support.FeedScopedIdFactory; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.rutebanken.netex.model.StopPlace; class MultiModalStationMapperTest { @@ -16,7 +17,9 @@ class MultiModalStationMapperTest { @Test void testMissingCoordinates() { DataImportIssueStore dataIssueStore = new DefaultDataImportIssueStore(); - FeedScopedIdFactory feedScopeIdFactory = new FeedScopedIdFactory(TransitModelForTest.FEED_ID); + FeedScopedIdFactory feedScopeIdFactory = new FeedScopedIdFactory( + TimetableRepositoryForTest.FEED_ID + ); MultiModalStationMapper multiModalStationMapper = new MultiModalStationMapper( dataIssueStore, feedScopeIdFactory diff --git a/src/test/java/org/opentripplanner/netex/mapping/NetexTestDataSample.java b/application/src/test/java/org/opentripplanner/netex/mapping/NetexTestDataSample.java similarity index 98% rename from src/test/java/org/opentripplanner/netex/mapping/NetexTestDataSample.java rename to application/src/test/java/org/opentripplanner/netex/mapping/NetexTestDataSample.java index b72c9b05277..56c672c7ef8 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/NetexTestDataSample.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/NetexTestDataSample.java @@ -14,7 +14,7 @@ import java.util.List; import org.opentripplanner.netex.index.hierarchy.HierarchicalMap; import org.opentripplanner.netex.index.hierarchy.HierarchicalMapById; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.DefaultEntityById; import org.opentripplanner.transit.model.framework.EntityById; import org.opentripplanner.transit.model.site.RegularStop; @@ -63,7 +63,7 @@ public class NetexTestDataSample { .withName(new MultilingualString().withValue("everyday")); private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - private final TransitModelForTest testModel = TransitModelForTest.of(); + private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of(); private final JourneyPattern journeyPattern; private final HierarchicalMapById journeyPatternById = new HierarchicalMapById<>(); @@ -89,7 +89,7 @@ public NetexTestDataSample() { JAXBElement lineRef = createWrappedRef(line.getId(), LineRefStructure.class); // Add OTP Route (correspond to Netex Line) - otpRouteByid.add(TransitModelForTest.route(line.getId()).build()); + otpRouteByid.add(TimetableRepositoryForTest.route(line.getId()).build()); // Add Netex Route (not the same as an OTP Route) String routeId = "RUT:Route:1"; diff --git a/src/test/java/org/opentripplanner/netex/mapping/NoticeAssignmentMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/NoticeAssignmentMapperTest.java similarity index 96% rename from src/test/java/org/opentripplanner/netex/mapping/NoticeAssignmentMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/NoticeAssignmentMapperTest.java index 99fcc2cb0e8..09a806169ab 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/NoticeAssignmentMapperTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/NoticeAssignmentMapperTest.java @@ -11,7 +11,7 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.model.StopTime; import org.opentripplanner.netex.index.hierarchy.HierarchicalMapById; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.framework.DefaultEntityById; import org.opentripplanner.transit.model.framework.EntityById; @@ -47,7 +47,7 @@ public void mapNoticeAssignment() { noticeAssignment.setNoticedObjectRef(new VersionOfObjectRefStructure().withRef(ROUTE_ID)); noticeAssignment.setNotice(NOTICE); - Route route = TransitModelForTest.route(ROUTE_ID).build(); + Route route = TimetableRepositoryForTest.route(ROUTE_ID).build(); EntityById routesById = new DefaultEntityById<>(); routesById.add(route); @@ -89,7 +89,7 @@ public void mapNoticeAssignmentOnStopPoint() { ) ); - var trip = TransitModelForTest.trip("1").build(); + var trip = TimetableRepositoryForTest.trip("1").build(); StopTime stopTime1 = createStopTime(1, trip); StopTime stopTime2 = createStopTime(2, trip); diff --git a/src/test/java/org/opentripplanner/netex/mapping/NoticeMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/NoticeMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/NoticeMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/NoticeMapperTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/OperatorToAgencyMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/OperatorToAgencyMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/OperatorToAgencyMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/OperatorToAgencyMapperTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/RouteMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/RouteMapperTest.java similarity index 96% rename from src/test/java/org/opentripplanner/netex/mapping/RouteMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/RouteMapperTest.java index 665650d0389..b2187af4216 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/RouteMapperTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/RouteMapperTest.java @@ -15,14 +15,14 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.model.impl.OtpTransitServiceBuilder; import org.opentripplanner.netex.index.NetexEntityIndex; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.DefaultEntityById; import org.opentripplanner.transit.model.network.BikeAccess; import org.opentripplanner.transit.model.network.GroupOfRoutes; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.organization.Branding; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; import org.rutebanken.netex.model.AllVehicleModesOfTransportEnumeration; import org.rutebanken.netex.model.Authority; import org.rutebanken.netex.model.BrandingRefStructure; @@ -76,7 +76,7 @@ void mapRouteWithDefaultAgency() { void mapRouteWithAgencySpecified() { NetexEntityIndex netexIndex = new NetexEntityIndex(); OtpTransitServiceBuilder transitBuilder = new OtpTransitServiceBuilder( - new StopModel(), + new SiteRepository(), DataImportIssueStore.NOOP ); @@ -102,7 +102,7 @@ void mapRouteWithAgencySpecified() { transitBuilder.getGroupsOfRoutesByRouteId(), transitBuilder.getGroupOfRouteById(), netexIndex.readOnlyView(), - TransitModelForTest.TIME_ZONE_ID, + TimetableRepositoryForTest.TIME_ZONE_ID, EMPTY_FERRY_WITHOUT_BICYCLE_IDS ); @@ -191,7 +191,7 @@ void mapRouteWithoutBranding() { void mapRouteWithBranding() { NetexEntityIndex netexIndex = new NetexEntityIndex(); OtpTransitServiceBuilder transitBuilder = new OtpTransitServiceBuilder( - new StopModel(), + new SiteRepository(), DataImportIssueStore.NOOP ); @@ -210,7 +210,7 @@ void mapRouteWithBranding() { ArrayListMultimap.create(), new DefaultEntityById<>(), netexIndex.readOnlyView(), - TransitModelForTest.TIME_ZONE_ID, + TimetableRepositoryForTest.TIME_ZONE_ID, EMPTY_FERRY_WITHOUT_BICYCLE_IDS ); @@ -225,7 +225,7 @@ void mapRouteWithBranding() { void mapRouteWithGroupOfRoutes() { NetexEntityIndex netexIndex = new NetexEntityIndex(); OtpTransitServiceBuilder transitBuilder = new OtpTransitServiceBuilder( - new StopModel(), + new SiteRepository(), DataImportIssueStore.NOOP ); @@ -246,7 +246,7 @@ void mapRouteWithGroupOfRoutes() { transitBuilder.getGroupsOfRoutesByRouteId(), transitBuilder.getGroupOfRouteById(), netexIndex.readOnlyView(), - TransitModelForTest.TIME_ZONE_ID, + TimetableRepositoryForTest.TIME_ZONE_ID, EMPTY_FERRY_WITHOUT_BICYCLE_IDS ); @@ -278,7 +278,7 @@ private Line createExampleFerry(String id) { } private Agency createAgency() { - return TransitModelForTest + return TimetableRepositoryForTest .agency("Ruter AS") .copy() .withId(MappingSupport.ID_FACTORY.createId(AUTHORITY_ID)) diff --git a/src/test/java/org/opentripplanner/netex/mapping/ServiceLinkMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/ServiceLinkMapperTest.java similarity index 98% rename from src/test/java/org/opentripplanner/netex/mapping/ServiceLinkMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/ServiceLinkMapperTest.java index aa19a436112..52c1564f025 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/ServiceLinkMapperTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/ServiceLinkMapperTest.java @@ -25,7 +25,7 @@ import org.opentripplanner.transit.model.network.StopPattern; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; import org.rutebanken.netex.model.JourneyPattern; import org.rutebanken.netex.model.LinkSequenceProjection; import org.rutebanken.netex.model.LinkSequenceProjection_VersionStructure; @@ -107,7 +107,11 @@ void setUpTestData() { EntityById stopsById = new DefaultEntityById<>(); issueStore = new DefaultDataImportIssueStore(); - QuayMapper quayMapper = new QuayMapper(ID_FACTORY, issueStore, new StopModel().withContext()); + QuayMapper quayMapper = new QuayMapper( + ID_FACTORY, + issueStore, + new SiteRepository().withContext() + ); stopPatternBuilder = StopPattern.create(3); Station parentStation = Station diff --git a/src/test/java/org/opentripplanner/netex/mapping/StationMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/StationMapperTest.java similarity index 92% rename from src/test/java/org/opentripplanner/netex/mapping/StationMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/StationMapperTest.java index b100a38782a..6f0524d92d7 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/StationMapperTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/StationMapperTest.java @@ -5,13 +5,14 @@ import static org.opentripplanner.netex.NetexTestDataSupport.createStopPlace; import java.time.ZoneId; +import java.util.Set; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.netex.NetexTestDataSupport; import org.opentripplanner.netex.mapping.support.FeedScopedIdFactory; import org.opentripplanner.transit.model.site.Station; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; import org.rutebanken.netex.model.Quay; import org.rutebanken.netex.model.StopPlace; @@ -27,7 +28,8 @@ void setUp() { new FeedScopedIdFactory("FEED_ID"), ZoneId.of("UTC"), false, - StopModel.of() + Set.of(), + SiteRepository.of() ); } diff --git a/src/test/java/org/opentripplanner/netex/mapping/StopAndStationMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/StopAndStationMapperTest.java similarity index 85% rename from src/test/java/org/opentripplanner/netex/mapping/StopAndStationMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/StopAndStationMapperTest.java index 30ca5cebfa8..2d710224661 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/StopAndStationMapperTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/StopAndStationMapperTest.java @@ -1,16 +1,19 @@ package org.opentripplanner.netex.mapping; +import static com.google.common.truth.Truth.assertThat; import static graphql.Assert.assertFalse; import static graphql.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.opentripplanner.netex.NetexTestDataSupport.createQuay; import static org.opentripplanner.netex.NetexTestDataSupport.createStopPlace; +import static org.rutebanken.netex.model.AllVehicleModesOfTransportEnumeration.TRAM; import java.time.ZoneId; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Set; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -20,8 +23,8 @@ import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.StopModelBuilder; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; import org.rutebanken.netex.model.AccessibilityAssessment; import org.rutebanken.netex.model.AccessibilityLimitation; import org.rutebanken.netex.model.AccessibilityLimitations_RelStructure; @@ -75,7 +78,7 @@ void testWheelChairBoarding() { var stopPlaceById = new HierarchicalVersionMapById(); stopPlaceById.add(stopPlace); - StopAndStationMapper stopAndStationMapper = createStopAndStationMapper(StopModel.of()); + StopAndStationMapper stopAndStationMapper = createStopAndStationMapper(SiteRepository.of()); stopAndStationMapper.mapParentAndChildStops(List.of(stopPlace)); @@ -156,10 +159,11 @@ void mapStopPlaceAndQuays() { MappingSupport.ID_FACTORY, quaysById, null, - StopModel.of(), + SiteRepository.of(), DEFAULT_TIME_ZONE, DataImportIssueStore.NOOP, - false + false, + Set.of() ); stopMapper.mapParentAndChildStops(stopPlaces); @@ -226,10 +230,11 @@ void testMapIsolatedStopPlace(boolean isolated) { MappingSupport.ID_FACTORY, new HierarchicalVersionMapById<>(), null, - StopModel.of(), + SiteRepository.of(), DEFAULT_TIME_ZONE, DataImportIssueStore.NOOP, - isolated + isolated, + Set.of() ); stopMapper.mapParentAndChildStops(stopPlaces); @@ -259,37 +264,65 @@ void testDuplicateStopIndices() { stopPlace.setQuays(new Quays_RelStructure().withQuayRefOrQuay(objectFactory.createQuay(quay1))); - StopModelBuilder stopModelBuilder = StopModel.of(); + SiteRepositoryBuilder siteRepositoryBuilder = SiteRepository.of(); - StopAndStationMapper stopAndStationMapper = createStopAndStationMapper(stopModelBuilder); + StopAndStationMapper stopAndStationMapper = createStopAndStationMapper(siteRepositoryBuilder); stopAndStationMapper.mapParentAndChildStops(List.of(stopPlace)); - stopModelBuilder.withRegularStops(stopAndStationMapper.resultStops); + siteRepositoryBuilder.withRegularStops(stopAndStationMapper.resultStops); - StopAndStationMapper stopAndStationMapper2 = createStopAndStationMapper(stopModelBuilder); + StopAndStationMapper stopAndStationMapper2 = createStopAndStationMapper(siteRepositoryBuilder); stopAndStationMapper2.mapParentAndChildStops(List.of(stopPlace)); - stopModelBuilder.withRegularStops(stopAndStationMapper2.resultStops); + siteRepositoryBuilder.withRegularStops(stopAndStationMapper2.resultStops); - assertEquals(1, stopModelBuilder.regularStopsById().size()); + assertEquals(1, siteRepositoryBuilder.regularStopsById().size()); assertEquals( 0, - stopModelBuilder + siteRepositoryBuilder .regularStopsById() .get(MappingSupport.ID_FACTORY.createId("ST:Quay:1")) .getIndex() ); } + @Test + void testRouteToCentroid() { + var routeToCentroidStopPlaceIds = Set.of(MappingSupport.ID_FACTORY.createId("NSR:StopPlace:1")); + StopAndStationMapper stopMapper = new StopAndStationMapper( + MappingSupport.ID_FACTORY, + new HierarchicalVersionMapById<>(), + null, + SiteRepository.of(), + DEFAULT_TIME_ZONE, + DataImportIssueStore.NOOP, + false, + routeToCentroidStopPlaceIds + ); + + stopMapper.mapParentAndChildStops( + List.of(createStopPlace("NSR:StopPlace:1", "A", "1", 59.1, 10.0, TRAM)) + ); + stopMapper.mapParentAndChildStops( + List.of(createStopPlace("NSR:StopPlace:2", "B", "1", 59.2, 10.0, TRAM)) + ); + + var stations = stopMapper.resultStations; + assertThat(stations).hasSize(2); + assertTrue(stations.get(0).shouldRouteToCentroid()); + assertFalse(stations.get(1).shouldRouteToCentroid()); + } + private static StopAndStationMapper createStopAndStationMapper( - StopModelBuilder stopModelBuilder + SiteRepositoryBuilder siteRepositoryBuilder ) { return new StopAndStationMapper( MappingSupport.ID_FACTORY, new HierarchicalVersionMapById<>(), null, - stopModelBuilder, + siteRepositoryBuilder, DEFAULT_TIME_ZONE, DataImportIssueStore.NOOP, - false + false, + Set.of() ); } diff --git a/src/test/java/org/opentripplanner/netex/mapping/StopPlaceTypeMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/StopPlaceTypeMapperTest.java similarity index 88% rename from src/test/java/org/opentripplanner/netex/mapping/StopPlaceTypeMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/StopPlaceTypeMapperTest.java index cb9dabc911d..50e0f45929a 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/StopPlaceTypeMapperTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/StopPlaceTypeMapperTest.java @@ -30,6 +30,15 @@ void mapWithTransportModeOnly() { assertNull(transitMode.subMode()); } + @Test + void mapCableway() { + var transitMode = stopPlaceTypeMapper.map( + new StopPlace().withTransportMode(AllVehicleModesOfTransportEnumeration.CABLEWAY) + ); + assertEquals(TransitMode.GONDOLA, transitMode.mainMode()); + assertNull(transitMode.subMode()); + } + @Test void mapWithSubMode() { var transitMode = stopPlaceTypeMapper.map( diff --git a/src/test/java/org/opentripplanner/netex/mapping/StopTimesMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/StopTimesMapperTest.java similarity index 97% rename from src/test/java/org/opentripplanner/netex/mapping/StopTimesMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/StopTimesMapperTest.java index 54f38421b8d..1f1ade2aa66 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/StopTimesMapperTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/StopTimesMapperTest.java @@ -17,7 +17,7 @@ import org.opentripplanner.model.StopTime; import org.opentripplanner.netex.index.hierarchy.HierarchicalMap; import org.opentripplanner.netex.index.hierarchy.HierarchicalMapById; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.DefaultEntityById; import org.opentripplanner.transit.model.timetable.Trip; import org.rutebanken.netex.model.StopPointInJourneyPattern; @@ -30,7 +30,7 @@ public class StopTimesMapperTest { private static final BigInteger TWO = BigInteger.valueOf(2); private static final LocalTime QUARTER_PAST_FIVE = LocalTime.of(5, 15); - public static final Trip TRIP = TransitModelForTest.trip("T1").build(); + public static final Trip TRIP = TimetableRepositoryForTest.trip("T1").build(); @Test public void testCalculateOtpTime() { diff --git a/src/test/java/org/opentripplanner/netex/mapping/StopTransferPriorityMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/StopTransferPriorityMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/StopTransferPriorityMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/StopTransferPriorityMapperTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/TransportModeMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/TransportModeMapperTest.java similarity index 95% rename from src/test/java/org/opentripplanner/netex/mapping/TransportModeMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/TransportModeMapperTest.java index 5df2cc3dc05..11c41548a60 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/TransportModeMapperTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/TransportModeMapperTest.java @@ -67,6 +67,13 @@ void mapWithTransportModeOnly() throws UnsupportedModeException { assertNull(transitMode.subMode()); } + @Test + void mapCableway() throws UnsupportedModeException { + var transitMode = transportModeMapper.map(AllVehicleModesOfTransportEnumeration.CABLEWAY, null); + assertEquals(TransitMode.GONDOLA, transitMode.mainMode()); + assertNull(transitMode.subMode()); + } + @Test void mapWithSubMode() throws UnsupportedModeException { var transitMode = transportModeMapper.map( diff --git a/src/test/java/org/opentripplanner/netex/mapping/TripCalendarBuilderTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/TripCalendarBuilderTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/TripCalendarBuilderTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/TripCalendarBuilderTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/TripMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/TripMapperTest.java similarity index 89% rename from src/test/java/org/opentripplanner/netex/mapping/TripMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/TripMapperTest.java index ebb83d44709..6c4973329d3 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/TripMapperTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/TripMapperTest.java @@ -12,11 +12,11 @@ import org.opentripplanner.model.impl.OtpTransitServiceBuilder; import org.opentripplanner.netex.index.hierarchy.HierarchicalMap; import org.opentripplanner.netex.index.hierarchy.HierarchicalMapById; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.timetable.Trip; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; import org.rutebanken.netex.model.AccessibilityAssessment; import org.rutebanken.netex.model.AccessibilityLimitation; import org.rutebanken.netex.model.AccessibilityLimitations_RelStructure; @@ -33,7 +33,7 @@ public class TripMapperTest { private static final String ROUTE_ID = "RUT:Route:1"; private static final String SERVICE_JOURNEY_ID = NetexTestDataSample.SERVICE_JOURNEY_ID; private static final String JOURNEY_PATTERN_ID = "RUT:JourneyPattern:1"; - private static final FeedScopedId SERVICE_ID = TransitModelForTest.id("S001"); + private static final FeedScopedId SERVICE_ID = TimetableRepositoryForTest.id("S001"); private static final DataImportIssueStore issueStore = DataImportIssueStore.NOOP; private static final JAXBElement LINE_REF = MappingSupport.createWrappedRef( @@ -49,8 +49,8 @@ public void mapTripWithWheelchairAccess() { var limitations = new AccessibilityLimitations_RelStructure(); var access = new AccessibilityAssessment(); - var transitBuilder = new OtpTransitServiceBuilder(new StopModel(), issueStore); - transitBuilder.getRoutes().add(TransitModelForTest.route(ROUTE_ID).build()); + var transitBuilder = new OtpTransitServiceBuilder(new SiteRepository(), issueStore); + transitBuilder.getRoutes().add(TimetableRepositoryForTest.route(ROUTE_ID).build()); TripMapper tripMapper = new TripMapper( ID_FACTORY, @@ -79,10 +79,10 @@ public void mapTripWithWheelchairAccess() { @Test public void mapTrip() { OtpTransitServiceBuilder transitBuilder = new OtpTransitServiceBuilder( - new StopModel(), + new SiteRepository(), issueStore ); - transitBuilder.getRoutes().add(TransitModelForTest.route(ROUTE_ID).build()); + transitBuilder.getRoutes().add(TimetableRepositoryForTest.route(ROUTE_ID).build()); TripMapper tripMapper = new TripMapper( ID_FACTORY, @@ -106,10 +106,10 @@ public void mapTrip() { @Test public void mapTripWithRouteRefViaJourneyPattern() { OtpTransitServiceBuilder transitBuilder = new OtpTransitServiceBuilder( - new StopModel(), + new SiteRepository(), issueStore ); - transitBuilder.getRoutes().add(TransitModelForTest.route(ROUTE_ID).build()); + transitBuilder.getRoutes().add(TimetableRepositoryForTest.route(ROUTE_ID).build()); JourneyPattern journeyPattern = new JourneyPattern().withId(JOURNEY_PATTERN_ID); journeyPattern.setRouteRef(new RouteRefStructure().withRef(ROUTE_ID)); diff --git a/src/test/java/org/opentripplanner/netex/mapping/TripPatternMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/TripPatternMapperTest.java similarity index 97% rename from src/test/java/org/opentripplanner/netex/mapping/TripPatternMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/TripPatternMapperTest.java index 95af8f623e5..3af2f41391d 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/TripPatternMapperTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/TripPatternMapperTest.java @@ -13,7 +13,7 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.netex.index.hierarchy.HierarchicalMap; import org.opentripplanner.netex.index.hierarchy.HierarchicalMapById; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.DefaultEntityById; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -31,7 +31,7 @@ */ class TripPatternMapperTest { - private static final FeedScopedId SERVICE_ID = TransitModelForTest.id("S01"); + private static final FeedScopedId SERVICE_ID = TimetableRepositoryForTest.id("S01"); @Test void testMapTripPattern() { diff --git a/src/test/java/org/opentripplanner/netex/mapping/VehicleParkingMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/VehicleParkingMapperTest.java similarity index 96% rename from src/test/java/org/opentripplanner/netex/mapping/VehicleParkingMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/VehicleParkingMapperTest.java index bf56be1be1b..d803e1867cb 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/VehicleParkingMapperTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/VehicleParkingMapperTest.java @@ -22,8 +22,8 @@ import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.graph_builder.issue.service.DefaultDataImportIssueStore; import org.opentripplanner.netex.mapping.support.FeedScopedIdFactory; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; import org.rutebanken.netex.model.LocationStructure; import org.rutebanken.netex.model.MultilingualString; import org.rutebanken.netex.model.Parking; diff --git a/src/test/java/org/opentripplanner/netex/mapping/WgsCoordinateMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/WgsCoordinateMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/WgsCoordinateMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/WgsCoordinateMapperTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/calendar/CalendarServiceBuilderTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/calendar/CalendarServiceBuilderTest.java similarity index 81% rename from src/test/java/org/opentripplanner/netex/mapping/calendar/CalendarServiceBuilderTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/calendar/CalendarServiceBuilderTest.java index aff56902c07..042887aee7a 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/calendar/CalendarServiceBuilderTest.java +++ b/application/src/test/java/org/opentripplanner/netex/mapping/calendar/CalendarServiceBuilderTest.java @@ -2,7 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; -import static org.opentripplanner.transit.model._data.TransitModelForTest.FEED_ID; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.FEED_ID; import java.time.LocalDate; import java.util.Collection; @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.model.calendar.ServiceCalendarDate; import org.opentripplanner.netex.mapping.support.FeedScopedIdFactory; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; public class CalendarServiceBuilderTest { @@ -18,9 +18,9 @@ public class CalendarServiceBuilderTest { private static final LocalDate D1 = LocalDate.of(2020, 11, 1); private static final LocalDate D2 = LocalDate.of(2020, 11, 2); - private static final FeedScopedId EXP_SID_1 = TransitModelForTest.id("S000001"); - private static final FeedScopedId EXP_SID_2 = TransitModelForTest.id("S000002"); - private static final FeedScopedId EXP_SID_3 = TransitModelForTest.id("S000003"); + private static final FeedScopedId EXP_SID_1 = TimetableRepositoryForTest.id("S000001"); + private static final FeedScopedId EXP_SID_2 = TimetableRepositoryForTest.id("S000002"); + private static final FeedScopedId EXP_SID_3 = TimetableRepositoryForTest.id("S000003"); @Test public void addDatesForAGivenService() { @@ -64,8 +64,8 @@ public void createServiceCalendar() { @Test public void createServiceId() { CalendarServiceBuilder subject = new CalendarServiceBuilder(new FeedScopedIdFactory(FEED_ID)); - assertEquals(TransitModelForTest.id("S000001"), subject.createServiceId()); - assertEquals(TransitModelForTest.id("S000002"), subject.createServiceId()); + assertEquals(TimetableRepositoryForTest.id("S000001"), subject.createServiceId()); + assertEquals(TimetableRepositoryForTest.id("S000002"), subject.createServiceId()); } private void assertServiceDateExistInList( diff --git a/src/test/java/org/opentripplanner/netex/mapping/calendar/DatedServiceJourneyMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/calendar/DatedServiceJourneyMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/calendar/DatedServiceJourneyMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/calendar/DatedServiceJourneyMapperTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/calendar/DayOfWeekMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/calendar/DayOfWeekMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/calendar/DayOfWeekMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/calendar/DayOfWeekMapperTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/calendar/DayTypeAssignmentMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/calendar/DayTypeAssignmentMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/calendar/DayTypeAssignmentMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/calendar/DayTypeAssignmentMapperTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/calendar/OperatingDayMapperTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/calendar/OperatingDayMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/calendar/OperatingDayMapperTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/calendar/OperatingDayMapperTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/support/NetexMapperIndexesTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/support/NetexMapperIndexesTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/support/NetexMapperIndexesTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/support/NetexMapperIndexesTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/support/NetexObjectDecoratorTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/support/NetexObjectDecoratorTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/support/NetexObjectDecoratorTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/support/NetexObjectDecoratorTest.java diff --git a/src/test/java/org/opentripplanner/netex/mapping/support/ValidityComparatorTest.java b/application/src/test/java/org/opentripplanner/netex/mapping/support/ValidityComparatorTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/mapping/support/ValidityComparatorTest.java rename to application/src/test/java/org/opentripplanner/netex/mapping/support/ValidityComparatorTest.java diff --git a/src/test/java/org/opentripplanner/netex/support/NetexVersionHelperTest.java b/application/src/test/java/org/opentripplanner/netex/support/NetexVersionHelperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/support/NetexVersionHelperTest.java rename to application/src/test/java/org/opentripplanner/netex/support/NetexVersionHelperTest.java diff --git a/src/test/java/org/opentripplanner/netex/validation/JourneyPatternSJMismatchTest.java b/application/src/test/java/org/opentripplanner/netex/validation/JourneyPatternSJMismatchTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/validation/JourneyPatternSJMismatchTest.java rename to application/src/test/java/org/opentripplanner/netex/validation/JourneyPatternSJMismatchTest.java diff --git a/src/test/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTimeTest.java b/application/src/test/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTimeTest.java similarity index 100% rename from src/test/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTimeTest.java rename to application/src/test/java/org/opentripplanner/netex/validation/ServiceJourneyNonIncreasingPassingTimeTest.java diff --git a/src/test/java/org/opentripplanner/openstreetmap/OSMOpeningHoursParserTest.java b/application/src/test/java/org/opentripplanner/osm/OsmOpeningHoursParserTest.java similarity index 97% rename from src/test/java/org/opentripplanner/openstreetmap/OSMOpeningHoursParserTest.java rename to application/src/test/java/org/opentripplanner/osm/OsmOpeningHoursParserTest.java index 34f141e8504..bcd5f0bb4c6 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/OSMOpeningHoursParserTest.java +++ b/application/src/test/java/org/opentripplanner/osm/OsmOpeningHoursParserTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap; +package org.opentripplanner.osm; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -17,7 +17,7 @@ import org.opentripplanner.model.calendar.openinghours.OpeningHoursCalendarService; import org.opentripplanner.transit.model.framework.Deduplicator; -public class OSMOpeningHoursParserTest { +public class OsmOpeningHoursParserTest { static OpeningHoursCalendarService openingHoursCalendarService = new OpeningHoursCalendarService( new Deduplicator(), @@ -25,7 +25,7 @@ public class OSMOpeningHoursParserTest { LocalDate.of(2023, Month.DECEMBER, 31) ); - static OSMOpeningHoursParser osmOpeningHoursParser = new OSMOpeningHoursParser( + static OsmOpeningHoursParser osmOpeningHoursParser = new OsmOpeningHoursParser( openingHoursCalendarService, ZoneIds.PARIS ); @@ -176,7 +176,7 @@ static Stream osmOpeningHoursTestCases() { @ParameterizedTest(name = "{0} should be open on {1} but not on {2}") @MethodSource("osmOpeningHoursTestCases") - void testOSMOpeningHoursParsing( + void testOsmOpeningHoursParsing( String openingHours, List openTimes, List closedTimes diff --git a/src/test/java/org/opentripplanner/openstreetmap/model/OSMNodeTest.java b/application/src/test/java/org/opentripplanner/osm/model/OsmNodeTest.java similarity index 78% rename from src/test/java/org/opentripplanner/openstreetmap/model/OSMNodeTest.java rename to application/src/test/java/org/opentripplanner/osm/model/OsmNodeTest.java index a4579dec71e..82820f4e422 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/model/OSMNodeTest.java +++ b/application/src/test/java/org/opentripplanner/osm/model/OsmNodeTest.java @@ -1,15 +1,15 @@ -package org.opentripplanner.openstreetmap.model; +package org.opentripplanner.osm.model; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -public class OSMNodeTest { +public class OsmNodeTest { @Test public void testIsMultiLevel() { - OSMNode node = new OSMNode(); + OsmNode node = new OsmNode(); assertFalse(node.isMultiLevel()); node.addTag("highway", "var"); diff --git a/src/test/java/org/opentripplanner/openstreetmap/model/OSMWayTest.java b/application/src/test/java/org/opentripplanner/osm/model/OsmWayTest.java similarity index 58% rename from src/test/java/org/opentripplanner/openstreetmap/model/OSMWayTest.java rename to application/src/test/java/org/opentripplanner/osm/model/OsmWayTest.java index c0af4cf2701..9ac9457a9ec 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/model/OSMWayTest.java +++ b/application/src/test/java/org/opentripplanner/osm/model/OsmWayTest.java @@ -1,25 +1,75 @@ -package org.opentripplanner.openstreetmap.model; +package org.opentripplanner.osm.model; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -import org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData; +import org.opentripplanner.osm.wayproperty.specifier.WayTestData; -public class OSMWayTest { +public class OsmWayTest { @Test void testIsBicycleDismountForced() { - OSMWay way = new OSMWay(); + OsmWay way = new OsmWay(); assertFalse(way.isBicycleDismountForced()); way.addTag("bicycle", "dismount"); assertTrue(way.isBicycleDismountForced()); } + @Test + void testAreaMustContain3Nodes() { + OsmWay way = new OsmWay(); + way.addTag("area", "yes"); + assertFalse(way.isRoutableArea()); + way.addNodeRef(1); + assertFalse(way.isRoutableArea()); + way.addNodeRef(2); + assertFalse(way.isRoutableArea()); + way.addNodeRef(3); + assertTrue(way.isRoutableArea()); + way.addNodeRef(4); + assertTrue(way.isRoutableArea()); + } + + @Test + void testAreaTags() { + OsmWay platform = getClosedPolygon(); + platform.addTag("public_transport", "platform"); + assertTrue(platform.isRoutableArea()); + platform.addTag("area", "no"); + assertFalse(platform.isRoutableArea()); + + OsmWay roundabout = getClosedPolygon(); + roundabout.addTag("highway", "roundabout"); + assertFalse(roundabout.isRoutableArea()); + + OsmWay pedestrian = getClosedPolygon(); + pedestrian.addTag("highway", "pedestrian"); + assertFalse(pedestrian.isRoutableArea()); + pedestrian.addTag("area", "yes"); + assertTrue(pedestrian.isRoutableArea()); + + OsmWay indoorArea = getClosedPolygon(); + indoorArea.addTag("indoor", "area"); + assertTrue(indoorArea.isRoutableArea()); + + OsmWay bikeParking = getClosedPolygon(); + bikeParking.addTag("amenity", "bicycle_parking"); + assertTrue(bikeParking.isRoutableArea()); + + OsmWay corridor = getClosedPolygon(); + corridor.addTag("indoor", "corridor"); + assertTrue(corridor.isRoutableArea()); + + OsmWay door = getClosedPolygon(); + door.addTag("indoor", "door"); + assertFalse(door.isRoutableArea()); + } + @Test void testIsSteps() { - OSMWay way = new OSMWay(); + OsmWay way = new OsmWay(); assertFalse(way.isSteps()); way.addTag("highway", "primary"); @@ -31,12 +81,12 @@ void testIsSteps() { @Test void wheelchairAccessibleStairs() { - var osm1 = new OSMWay(); + var osm1 = new OsmWay(); osm1.addTag("highway", "steps"); assertFalse(osm1.isWheelchairAccessible()); // explicitly suitable for wheelchair users, perhaps because of a ramp - var osm2 = new OSMWay(); + var osm2 = new OsmWay(); osm2.addTag("highway", "steps"); osm2.addTag("wheelchair", "yes"); assertTrue(osm2.isWheelchairAccessible()); @@ -44,7 +94,7 @@ void wheelchairAccessibleStairs() { @Test void testIsRoundabout() { - OSMWay way = new OSMWay(); + OsmWay way = new OsmWay(); assertFalse(way.isRoundabout()); way.addTag("junction", "dovetail"); @@ -56,7 +106,7 @@ void testIsRoundabout() { @Test void testIsOneWayDriving() { - OSMWay way = new OSMWay(); + OsmWay way = new OsmWay(); assertFalse(way.isOneWayForwardDriving()); assertFalse(way.isOneWayReverseDriving()); @@ -75,7 +125,7 @@ void testIsOneWayDriving() { @Test void testIsOneWayBicycle() { - OSMWay way = new OSMWay(); + OsmWay way = new OsmWay(); assertFalse(way.isOneWayForwardBicycle()); assertFalse(way.isOneWayReverseBicycle()); @@ -94,7 +144,7 @@ void testIsOneWayBicycle() { @Test void testIsOpposableCycleway() { - OSMWay way = new OSMWay(); + OsmWay way = new OsmWay(); assertFalse(way.isOpposableCycleway()); way.addTag("cycleway", "notatagvalue"); @@ -115,7 +165,7 @@ void testIsOpposableCycleway() { void escalator() { assertFalse(WayTestData.cycleway().isEscalator()); - var escalator = new OSMWay(); + var escalator = new OsmWay(); escalator.addTag("highway", "steps"); assertFalse(escalator.isEscalator()); @@ -125,4 +175,13 @@ void escalator() { escalator.addTag("conveying", "whoknows?"); assertFalse(escalator.isEscalator()); } + + private OsmWay getClosedPolygon() { + var way = new OsmWay(); + way.addNodeRef(1); + way.addNodeRef(2); + way.addNodeRef(3); + way.addNodeRef(1); + return way; + } } diff --git a/src/test/java/org/opentripplanner/openstreetmap/model/OSMWithTagsTest.java b/application/src/test/java/org/opentripplanner/osm/model/OsmWithTagsTest.java similarity index 70% rename from src/test/java/org/opentripplanner/openstreetmap/model/OSMWithTagsTest.java rename to application/src/test/java/org/opentripplanner/osm/model/OsmWithTagsTest.java index 3b50d0bff0d..a89f8612040 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/model/OSMWithTagsTest.java +++ b/application/src/test/java/org/opentripplanner/osm/model/OsmWithTagsTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap.model; +package org.opentripplanner.osm.model; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -8,15 +8,19 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.OptionalInt; import java.util.Set; import org.junit.jupiter.api.Test; -import org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.opentripplanner.osm.wayproperty.specifier.WayTestData; -public class OSMWithTagsTest { +public class OsmWithTagsTest { @Test void testHasTag() { - OSMWithTags o = new OSMWithTags(); + OsmWithTags o = new OsmWithTags(); assertFalse(o.hasTag("foo")); assertFalse(o.hasTag("FOO")); o.addTag("foo", "bar"); @@ -27,7 +31,7 @@ void testHasTag() { @Test void testGetTag() { - OSMWithTags o = new OSMWithTags(); + OsmWithTags o = new OsmWithTags(); assertNull(o.getTag("foo")); assertNull(o.getTag("FOO")); @@ -38,35 +42,35 @@ void testGetTag() { @Test void testIsFalse() { - assertTrue(OSMWithTags.isFalse("no")); - assertTrue(OSMWithTags.isFalse("0")); - assertTrue(OSMWithTags.isFalse("false")); - - assertFalse(OSMWithTags.isFalse("yes")); - assertFalse(OSMWithTags.isFalse("1")); - assertFalse(OSMWithTags.isFalse("true")); - assertFalse(OSMWithTags.isFalse("foo")); - assertFalse(OSMWithTags.isFalse("bar")); - assertFalse(OSMWithTags.isFalse("baz")); + assertTrue(OsmWithTags.isFalse("no")); + assertTrue(OsmWithTags.isFalse("0")); + assertTrue(OsmWithTags.isFalse("false")); + + assertFalse(OsmWithTags.isFalse("yes")); + assertFalse(OsmWithTags.isFalse("1")); + assertFalse(OsmWithTags.isFalse("true")); + assertFalse(OsmWithTags.isFalse("foo")); + assertFalse(OsmWithTags.isFalse("bar")); + assertFalse(OsmWithTags.isFalse("baz")); } @Test void testIsTrue() { - assertTrue(OSMWithTags.isTrue("yes")); - assertTrue(OSMWithTags.isTrue("1")); - assertTrue(OSMWithTags.isTrue("true")); - - assertFalse(OSMWithTags.isTrue("no")); - assertFalse(OSMWithTags.isTrue("0")); - assertFalse(OSMWithTags.isTrue("false")); - assertFalse(OSMWithTags.isTrue("foo")); - assertFalse(OSMWithTags.isTrue("bar")); - assertFalse(OSMWithTags.isTrue("baz")); + assertTrue(OsmWithTags.isTrue("yes")); + assertTrue(OsmWithTags.isTrue("1")); + assertTrue(OsmWithTags.isTrue("true")); + + assertFalse(OsmWithTags.isTrue("no")); + assertFalse(OsmWithTags.isTrue("0")); + assertFalse(OsmWithTags.isTrue("false")); + assertFalse(OsmWithTags.isTrue("foo")); + assertFalse(OsmWithTags.isTrue("bar")); + assertFalse(OsmWithTags.isTrue("baz")); } @Test void testIsTagFalseOrTrue() { - OSMWithTags o = new OSMWithTags(); + OsmWithTags o = new OsmWithTags(); assertFalse(o.isTagFalse("foo")); assertFalse(o.isTagFalse("FOO")); assertFalse(o.isTagTrue("foo")); @@ -88,7 +92,7 @@ void testIsTagFalseOrTrue() { @Test void isTag() { var name = "Brendan"; - var osm = new OSMWithTags(); + var osm = new OsmWithTags(); osm.addTag("NAME", name); assertTrue(osm.isTag("name", name)); @@ -98,7 +102,7 @@ void isTag() { @Test void testDoesAllowTagAccess() { - OSMWithTags o = new OSMWithTags(); + OsmWithTags o = new OsmWithTags(); assertFalse(o.doesTagAllowAccess("foo")); o.addTag("foo", "bar"); @@ -113,7 +117,7 @@ void testDoesAllowTagAccess() { @Test void testIsGeneralAccessDenied() { - OSMWithTags o = new OSMWithTags(); + OsmWithTags o = new OsmWithTags(); assertFalse(o.isGeneralAccessDenied()); o.addTag("access", "something"); @@ -128,7 +132,7 @@ void testIsGeneralAccessDenied() { @Test void testBicycleDenied() { - OSMWithTags tags = new OSMWithTags(); + OsmWithTags tags = new OsmWithTags(); assertFalse(tags.isBicycleExplicitlyDenied()); for (var allowedValue : List.of("yes", "unknown", "somevalue")) { @@ -144,7 +148,7 @@ void testBicycleDenied() { @Test void getReferenceTags() { - var osm = new OSMWithTags(); + var osm = new OsmWithTags(); osm.addTag("ref", "A"); assertEquals(Set.of("A"), osm.getMultiTagValues(Set.of("ref", "test"))); @@ -153,7 +157,7 @@ void getReferenceTags() { @Test void getEmptyRefList() { - var osm = new OSMWithTags(); + var osm = new OsmWithTags(); osm.addTag("ref", "A"); assertEquals(Set.of(), osm.getMultiTagValues(Set.of())); @@ -161,7 +165,7 @@ void getEmptyRefList() { @Test void ignoreRefCase() { - var osm = new OSMWithTags(); + var osm = new OsmWithTags(); osm.addTag("ref:IFOPT", "A"); assertEquals(Set.of("A"), osm.getMultiTagValues(Set.of("ref:ifopt"))); @@ -169,7 +173,7 @@ void ignoreRefCase() { @Test void readSemicolonSeparated() { - var osm = new OSMWithTags(); + var osm = new OsmWithTags(); osm.addTag("ref:A", "A;A;B"); assertEquals(Set.of("A", "B"), osm.getMultiTagValues(Set.of("ref:A"))); @@ -177,7 +181,7 @@ void readSemicolonSeparated() { @Test void removeBlankRef() { - var osm = new OSMWithTags(); + var osm = new OsmWithTags(); osm.addTag("ref1", " "); osm.addTag("ref2", ""); @@ -187,7 +191,7 @@ void removeBlankRef() { @Test void shouldNotReturnNull() { - var osm = new OSMWithTags(); + var osm = new OsmWithTags(); osm.addTag("ref1", " "); osm.addTag("ref2", ""); @@ -197,14 +201,14 @@ void shouldNotReturnNull() { @Test void isWheelchairAccessible() { - var osm1 = new OSMWithTags(); + var osm1 = new OsmWithTags(); assertTrue(osm1.isWheelchairAccessible()); - var osm2 = new OSMWithTags(); + var osm2 = new OsmWithTags(); osm2.addTag("wheelchair", "no"); assertFalse(osm2.isWheelchairAccessible()); - var osm3 = new OSMWithTags(); + var osm3 = new OsmWithTags(); osm3.addTag("wheelchair", "yes"); assertTrue(osm3.isWheelchairAccessible()); } @@ -212,6 +216,8 @@ void isWheelchairAccessible() { @Test void isRoutable() { assertFalse(WayTestData.zooPlatform().isRoutable()); + assertTrue(WayTestData.indoor("area").isRoutable()); + assertFalse(WayTestData.indoor("room").isRoutable()); } @Test @@ -221,13 +227,12 @@ void isPlatform() { @Test void testGenerateI18NForPattern() { - OSMWithTags osmTags = new OSMWithTags(); + OsmWithTags osmTags = new OsmWithTags(); osmTags.addTag("note", "Note EN"); osmTags.addTag("description:fr", "Description FR"); osmTags.addTag("wheelchair:description", "Wheelchair description EN"); osmTags.addTag("wheelchair:description:fr", "Wheelchair description FR"); - assertNull(osmTags.generateI18NForPattern(null)); Map expected = new HashMap<>(); expected.put(null, ""); @@ -271,4 +276,26 @@ void fallbackName() { var namedTunnel = WayTestData.carTunnel(); assertFalse(namedTunnel.hasNoName()); } + + private static List parseIntOrBooleanCases() { + return List.of( + Arguments.of("true", OptionalInt.of(1)), + Arguments.of("yes", OptionalInt.of(1)), + Arguments.of("no", OptionalInt.of(0)), + Arguments.of("false", OptionalInt.of(0)), + Arguments.of("0", OptionalInt.of(0)), + Arguments.of("12", OptionalInt.of(12)), + Arguments.of("", OptionalInt.empty()) + ); + } + + @ParameterizedTest + @MethodSource("parseIntOrBooleanCases") + void parseIntOrBoolean(String value, OptionalInt expected) { + var way = new OsmWithTags(); + var key = "capacity:disabled"; + way.addTag(key, value); + var maybeInt = way.parseIntOrBoolean(key, i -> {}); + assertEquals(expected, maybeInt); + } } diff --git a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/AtlantaMapperTest.java b/application/src/test/java/org/opentripplanner/osm/tagmapping/AtlantaMapperTest.java similarity index 89% rename from src/test/java/org/opentripplanner/openstreetmap/tagmapping/AtlantaMapperTest.java rename to application/src/test/java/org/opentripplanner/osm/tagmapping/AtlantaMapperTest.java index 3480135cff7..45ef6a66b55 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/AtlantaMapperTest.java +++ b/application/src/test/java/org/opentripplanner/osm/tagmapping/AtlantaMapperTest.java @@ -1,10 +1,10 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.WayPropertySet; import org.opentripplanner.street.model.StreetTraversalPermission; class AtlantaMapperTest { @@ -27,7 +27,7 @@ class AtlantaMapperTest { public void peachtreeRoad() { // Peachtree Rd in Atlanta has sidewalks, and bikes are allowed. // https://www.openstreetmap.org/way/144429544 - OSMWithTags peachtreeRd = new OSMWithTags(); + OsmWithTags peachtreeRd = new OsmWithTags(); peachtreeRd.addTag("highway", "trunk"); peachtreeRd.addTag("lanes", "6"); peachtreeRd.addTag("name", "Peachtree Road"); @@ -42,7 +42,7 @@ public void peachtreeRoad() { public void deKalbAvenue() { // "Outer" ramps from DeKalb Ave onto Moreland Ave in Atlanta have sidewalks, and bikes are allowed. // https://www.openstreetmap.org/way/9164434 - OSMWithTags morelandRamp = new OSMWithTags(); + OsmWithTags morelandRamp = new OsmWithTags(); morelandRamp.addTag("highway", "trunk_link"); morelandRamp.addTag("lanes", "1"); morelandRamp.addTag("oneway", "yes"); @@ -57,7 +57,7 @@ public void deKalbAvenue() { public void tenthStreetNE() { // For sanity check, secondary roads (e.g. 10th Street) should remain allowed for all modes. // https://www.openstreetmap.org/way/505912700 - OSMWithTags tenthSt = new OSMWithTags(); + OsmWithTags tenthSt = new OsmWithTags(); tenthSt.addTag("highway", "secondary"); tenthSt.addTag("lanes", "4"); tenthSt.addTag("maxspeed", "30 mph"); diff --git a/application/src/test/java/org/opentripplanner/osm/tagmapping/ConstantSpeedMapperTest.java b/application/src/test/java/org/opentripplanner/osm/tagmapping/ConstantSpeedMapperTest.java new file mode 100644 index 00000000000..6256044320d --- /dev/null +++ b/application/src/test/java/org/opentripplanner/osm/tagmapping/ConstantSpeedMapperTest.java @@ -0,0 +1,23 @@ +package org.opentripplanner.osm.tagmapping; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; +import org.opentripplanner.osm.model.OsmWithTags; + +public class ConstantSpeedMapperTest { + + @Test + public void constantSpeedCarRouting() { + OsmTagMapper osmTagMapper = new ConstantSpeedFinlandMapper(20f); + + var slowWay = new OsmWithTags(); + slowWay.addTag("highway", "residential"); + assertEquals(20f, osmTagMapper.getCarSpeedForWay(slowWay, true)); + + var fastWay = new OsmWithTags(); + fastWay.addTag("highway", "motorway"); + fastWay.addTag("maxspeed", "120 kmph"); + assertEquals(20f, osmTagMapper.getCarSpeedForWay(fastWay, true)); + } +} diff --git a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/FinlandMapperTest.java b/application/src/test/java/org/opentripplanner/osm/tagmapping/FinlandMapperTest.java similarity index 65% rename from src/test/java/org/opentripplanner/openstreetmap/tagmapping/FinlandMapperTest.java rename to application/src/test/java/org/opentripplanner/osm/tagmapping/FinlandMapperTest.java index 4dd52195acb..ecbd2eec3be 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/FinlandMapperTest.java +++ b/application/src/test/java/org/opentripplanner/osm/tagmapping/FinlandMapperTest.java @@ -1,83 +1,93 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.street.model.StreetTraversalPermission.ALL; +import static org.opentripplanner.street.model.StreetTraversalPermission.CAR; import static org.opentripplanner.street.model.StreetTraversalPermission.NONE; +import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN; +import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN_AND_BICYCLE; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.opentripplanner.openstreetmap.model.OSMWay; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.WayProperties; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; +import org.opentripplanner.osm.model.OsmWay; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.WayProperties; +import org.opentripplanner.osm.wayproperty.WayPropertySet; +import org.opentripplanner.osm.wayproperty.specifier.WayTestData; -public class FinlandMapperTest { +class FinlandMapperTest { - static WayPropertySet wps = new WayPropertySet(); + private WayPropertySet wps; + private OsmTagMapper mapper; static float epsilon = 0.01f; - static { - var source = new FinlandMapper(); - source.populateProperties(wps); + @BeforeEach + void setup() { + this.wps = new WayPropertySet(); + this.mapper = new FinlandMapper(); + this.mapper.populateProperties(this.wps); } /** * Test that bike and walk safety factors are calculated accurately */ @Test - public void testSafety() { - OSMWithTags primaryWay = new OSMWithTags(); + void testSafety() { + OsmWithTags primaryWay = new OsmWithTags(); primaryWay.addTag("highway", "primary"); primaryWay.addTag("oneway", "no"); - OSMWithTags livingStreetWay = new OSMWithTags(); + OsmWithTags livingStreetWay = new OsmWithTags(); livingStreetWay.addTag("highway", "living_street"); - OSMWithTags footway = new OSMWithTags(); + OsmWithTags footway = new OsmWithTags(); footway.addTag("highway", "footway"); - OSMWithTags sidewalk = new OSMWithTags(); + OsmWithTags sidewalk = new OsmWithTags(); sidewalk.addTag("footway", "sidewalk"); sidewalk.addTag("highway", "footway"); - OSMWithTags segregatedCycleway = new OSMWithTags(); + OsmWithTags segregatedCycleway = new OsmWithTags(); segregatedCycleway.addTag("segregated", "yes"); segregatedCycleway.addTag("highway", "cycleway"); - OSMWithTags tunnel = new OSMWithTags(); + OsmWithTags tunnel = new OsmWithTags(); tunnel.addTag("tunnel", "yes"); tunnel.addTag("highway", "footway"); - OSMWithTags bridge = new OSMWithTags(); + OsmWithTags bridge = new OsmWithTags(); bridge.addTag("bridge", "yes"); bridge.addTag("highway", "footway"); - OSMWithTags footwayCrossing = new OSMWithTags(); + OsmWithTags footwayCrossing = new OsmWithTags(); footwayCrossing.addTag("footway", "crossing"); footwayCrossing.addTag("highway", "footway"); - OSMWithTags footwayCrossingWithTrafficLights = new OSMWithTags(); + OsmWithTags footwayCrossingWithTrafficLights = new OsmWithTags(); footwayCrossingWithTrafficLights.addTag("footway", "crossing"); footwayCrossingWithTrafficLights.addTag("highway", "footway"); footwayCrossingWithTrafficLights.addTag("crossing", "traffic_signals"); - OSMWithTags cyclewayCrossing = new OSMWithTags(); + OsmWithTags cyclewayCrossing = new OsmWithTags(); cyclewayCrossing.addTag("cycleway", "crossing"); cyclewayCrossing.addTag("highway", "cycleway"); - OSMWithTags cyclewayFootwayCrossing = new OSMWithTags(); + OsmWithTags cyclewayFootwayCrossing = new OsmWithTags(); cyclewayFootwayCrossing.addTag("footway", "crossing"); cyclewayFootwayCrossing.addTag("highway", "cycleway"); - OSMWithTags cyclewayCrossingWithTrafficLights = new OSMWithTags(); + OsmWithTags cyclewayCrossingWithTrafficLights = new OsmWithTags(); cyclewayCrossingWithTrafficLights.addTag("cycleway", "crossing"); cyclewayCrossingWithTrafficLights.addTag("highway", "cycleway"); cyclewayCrossingWithTrafficLights.addTag("crossing", "traffic_signals"); - OSMWithTags cyclewayFootwayCrossingWithTrafficLights = new OSMWithTags(); + OsmWithTags cyclewayFootwayCrossingWithTrafficLights = new OsmWithTags(); cyclewayFootwayCrossingWithTrafficLights.addTag("footway", "crossing"); cyclewayFootwayCrossingWithTrafficLights.addTag("highway", "cycleway"); cyclewayFootwayCrossingWithTrafficLights.addTag("crossing", "traffic_signals"); - OSMWithTags cyclewaySegregatedCrossing = new OSMWithTags(); + OsmWithTags cyclewaySegregatedCrossing = new OsmWithTags(); cyclewaySegregatedCrossing.addTag("cycleway", "crossing"); cyclewaySegregatedCrossing.addTag("segregated", "yes"); cyclewaySegregatedCrossing.addTag("highway", "cycleway"); - OSMWithTags cyclewaySegregatedFootwayCrossing = new OSMWithTags(); + OsmWithTags cyclewaySegregatedFootwayCrossing = new OsmWithTags(); cyclewaySegregatedFootwayCrossing.addTag("footway", "crossing"); cyclewaySegregatedFootwayCrossing.addTag("segregated", "yes"); cyclewaySegregatedFootwayCrossing.addTag("highway", "cycleway"); - OSMWithTags cyclewaySegregatedCrossingWithTrafficLights = new OSMWithTags(); + OsmWithTags cyclewaySegregatedCrossingWithTrafficLights = new OsmWithTags(); cyclewaySegregatedCrossingWithTrafficLights.addTag("cycleway", "crossing"); cyclewaySegregatedCrossingWithTrafficLights.addTag("segregated", "yes"); cyclewaySegregatedCrossingWithTrafficLights.addTag("highway", "cycleway"); cyclewaySegregatedCrossingWithTrafficLights.addTag("crossing", "traffic_signals"); - OSMWithTags cyclewaySegregatedFootwayCrossingWithTrafficLights = new OSMWithTags(); + OsmWithTags cyclewaySegregatedFootwayCrossingWithTrafficLights = new OsmWithTags(); cyclewaySegregatedFootwayCrossingWithTrafficLights.addTag("footway", "crossing"); cyclewaySegregatedFootwayCrossingWithTrafficLights.addTag("segregated", "yes"); cyclewaySegregatedFootwayCrossingWithTrafficLights.addTag("highway", "cycleway"); @@ -134,8 +144,8 @@ public void testSafety() { } @Test - public void testSafetyWithMixins() { - OSMWithTags wayWithMixins = new OSMWithTags(); + void testSafetyWithMixins() { + OsmWithTags wayWithMixins = new OsmWithTags(); // highway=service has no custom bicycle or walk safety wayWithMixins.addTag("highway", "unclassified"); // surface has mixin bicycle safety of 1.3 but no walk safety @@ -145,7 +155,7 @@ public void testSafetyWithMixins() { // 1.6 is the default walk safety for a way with ALL permissions and speed limit > 35 and <= 60 kph assertEquals(1.6, wps.getDataForWay(wayWithMixins).walkSafety().forward(), epsilon); - OSMWithTags wayWithMixinsAndCustomSafety = new OSMWithTags(); + OsmWithTags wayWithMixinsAndCustomSafety = new OsmWithTags(); // highway=service has custom bicycle safety of 1.1 but no custom walk safety wayWithMixinsAndCustomSafety.addTag("highway", "service"); // surface has mixin bicycle safety of 1.3 but no walk safety @@ -163,35 +173,78 @@ public void testSafetyWithMixins() { epsilon ); - OSMWithTags wayWithBicycleSidePath = new OSMWithTags(); + OsmWithTags wayWithBicycleSidePath = new OsmWithTags(); wayWithBicycleSidePath.addTag("bicycle", "use_sidepath"); assertEquals(8, wps.getDataForWay(wayWithBicycleSidePath).walkSafety().forward(), epsilon); - OSMWithTags wayWithFootSidePath = new OSMWithTags(); + OsmWithTags wayWithFootSidePath = new OsmWithTags(); wayWithFootSidePath.addTag("foot", "use_sidepath"); assertEquals(8, wps.getDataForWay(wayWithFootSidePath).walkSafety().forward(), epsilon); } @Test - public void testTagMapping() { - OSMWithTags way; + void testTagMapping() { + OsmWithTags way; WayProperties wayData; - way = new OSMWay(); + way = new OsmWay(); way.addTag("highway", "unclassified"); way.addTag("seasonal", "winter"); wayData = wps.getDataForWay(way); assertEquals(wayData.getPermission(), NONE); - way = new OSMWay(); + way = new OsmWay(); way.addTag("highway", "trunk"); way.addTag("ice_road", "yes"); wayData = wps.getDataForWay(way); assertEquals(wayData.getPermission(), NONE); - way = new OSMWay(); + way = new OsmWay(); way.addTag("highway", "track"); way.addTag("winter_road", "yes"); wayData = wps.getDataForWay(way); assertEquals(wayData.getPermission(), NONE); } + + /** + * Test that biking is not allowed in footway areas and transit platforms + */ + @Test + void testArea() { + OsmWithTags way; + WayProperties wayData; + + way = new OsmWay(); + way.addTag("highway", "footway"); + way.addTag("area", "yes"); + wayData = wps.getDataForWay(way); + assertEquals(wayData.getPermission(), PEDESTRIAN); + + way = new OsmWay(); + way.addTag("public_transport", "platform"); + way.addTag("area", "yes"); + wayData = wps.getDataForWay(way); + assertEquals(wayData.getPermission(), PEDESTRIAN); + way.addTag("bicycle", "yes"); + wayData = wps.getDataForWay(way); + assertEquals(wayData.getPermission(), PEDESTRIAN_AND_BICYCLE); + } + + @Test + void serviceNoThroughTraffic() { + var way = new OsmWay(); + way.addTag("highway", "residential"); + way.addTag("service", "driveway"); + assertTrue(mapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(way)); + } + + @Test + void motorroad() { + OsmTagMapper osmTagMapper = new FinlandMapper(); + WayPropertySet wps = new WayPropertySet(); + osmTagMapper.populateProperties(wps); + var way = WayTestData.carTunnel(); + assertEquals(ALL, wps.getDataForWay(way).getPermission()); + way.addTag("motorroad", "yes"); + assertEquals(CAR, wps.getDataForWay(way).getPermission()); + } } diff --git a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/GermanyMapperTest.java b/application/src/test/java/org/opentripplanner/osm/tagmapping/GermanyMapperTest.java similarity index 84% rename from src/test/java/org/opentripplanner/openstreetmap/tagmapping/GermanyMapperTest.java rename to application/src/test/java/org/opentripplanner/osm/tagmapping/GermanyMapperTest.java index 00b1049bdda..c0901f4fcf5 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/GermanyMapperTest.java +++ b/application/src/test/java/org/opentripplanner/osm/tagmapping/GermanyMapperTest.java @@ -1,11 +1,13 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN; +import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN_AND_BICYCLE; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.WayPropertySet; import org.opentripplanner.street.model.StreetTraversalPermission; public class GermanyMapperTest { @@ -26,10 +28,10 @@ class BikeSafety { @Test void testBikeSafety() { - OSMWithTags way; + OsmWithTags way; // way 361961158 - way = new OSMWithTags(); + way = new OsmWithTags(); way.addTag("bicycle", "yes"); way.addTag("foot", "designated"); way.addTag("footway", "sidewalk"); @@ -42,7 +44,7 @@ void testBikeSafety() { @Test void cyclewayOpposite() { - var way = new OSMWithTags(); + var way = new OsmWithTags(); way.addTag("cycleway", "opposite"); way.addTag("highway", "residential"); way.addTag("lit", "yes"); @@ -65,7 +67,7 @@ void cyclewayOpposite() { @Test void bikePath() { // way332589799 (Radschnellweg BW1) - var way = new OSMWithTags(); + var way = new OsmWithTags(); way.addTag("bicycle", "designated"); way.addTag("class:bicycle", "2"); way.addTag("class:bicycle:roadcycling", "1"); @@ -85,7 +87,7 @@ void bikePath() { @Test void track() { - var way = new OSMWithTags(); + var way = new OsmWithTags(); way.addTag("highway", "track"); way.addTag("motor_vehicle", "agricultural"); way.addTag("surface", "asphalt"); @@ -99,7 +101,7 @@ void track() { @Test void testPermissions() { // https://www.openstreetmap.org/way/124263424 - var way = new OSMWithTags(); + var way = new OsmWithTags(); way.addTag("highway", "track"); way.addTag("tracktype", "grade1"); assertEquals( @@ -108,7 +110,7 @@ void testPermissions() { ); // https://www.openstreetmap.org/way/5155805 - way = new OSMWithTags(); + way = new OsmWithTags(); way.addTag("access:lanes:forward", "yes|no"); way.addTag("bicycle:lanes:forward", "|designated"); way.addTag("change:lanes:forward", "not_right|no"); @@ -142,16 +144,16 @@ void lcnAndRcnShouldNotBeAddedUp() { // https://www.openstreetmap.org/way/26443041 is part of both an lcn and rcn but that shouldn't mean that // it is to be more heavily favoured than other ways that are part of just one. - var both = new OSMWithTags(); + var both = new OsmWithTags(); both.addTag("highway", "residential"); both.addTag("rcn", "yes"); both.addTag("lcn", "yes"); - var justLcn = new OSMWithTags(); + var justLcn = new OsmWithTags(); justLcn.addTag("lcn", "yes"); justLcn.addTag("highway", "residential"); - var residential = new OSMWithTags(); + var residential = new OsmWithTags(); residential.addTag("highway", "residential"); assertEquals( @@ -170,25 +172,25 @@ void bicycleRoadAndLcnShouldNotBeAddedUp() { // https://www.openstreetmap.org/way/22201321 was tagged as bicycle_road without lcn // make it so all ways tagged as some kind of cyclestreets are considered as equally safe - var both = new OSMWithTags(); + var both = new OsmWithTags(); both.addTag("highway", "residential"); both.addTag("bicycle_road", "yes"); both.addTag("cyclestreet", "yes"); both.addTag("lcn", "yes"); - var justBicycleRoad = new OSMWithTags(); + var justBicycleRoad = new OsmWithTags(); justBicycleRoad.addTag("bicycle_road", "yes"); justBicycleRoad.addTag("highway", "residential"); - var justCyclestreet = new OSMWithTags(); + var justCyclestreet = new OsmWithTags(); justCyclestreet.addTag("cyclestreet", "yes"); justCyclestreet.addTag("highway", "residential"); - var justLcn = new OSMWithTags(); + var justLcn = new OsmWithTags(); justLcn.addTag("lcn", "yes"); justLcn.addTag("highway", "residential"); - var residential = new OSMWithTags(); + var residential = new OsmWithTags(); residential.addTag("highway", "residential"); assertEquals( @@ -224,13 +226,13 @@ void bicycleRoadAndLcnShouldNotBeAddedUp() { @Test void setCorrectPermissionsForRoundabouts() { // https://www.openstreetmap.org/way/184185551 - var residential = new OSMWithTags(); + var residential = new OsmWithTags(); residential.addTag("highway", "residential"); residential.addTag("junction", "roundabout"); assertEquals(wps.getDataForWay(residential).getPermission(), StreetTraversalPermission.ALL); //https://www.openstreetmap.org/way/31109939 - var primary = new OSMWithTags(); + var primary = new OsmWithTags(); primary.addTag("highway", "primary"); primary.addTag("junction", "roundabout"); assertEquals( @@ -242,7 +244,7 @@ void setCorrectPermissionsForRoundabouts() { @Test void setCorrectBikeSafetyValuesForBothDirections() { // https://www.openstreetmap.org/way/13420871 - var residential = new OSMWithTags(); + var residential = new OsmWithTags(); residential.addTag("highway", "residential"); residential.addTag("lit", "yes"); residential.addTag("maxspeed", "30"); @@ -258,7 +260,7 @@ void setCorrectBikeSafetyValuesForBothDirections() { @Test void setCorrectPermissionsForSteps() { // https://www.openstreetmap.org/way/64359102 - var steps = new OSMWithTags(); + var steps = new OsmWithTags(); steps.addTag("highway", "steps"); assertEquals(wps.getDataForWay(steps).getPermission(), StreetTraversalPermission.PEDESTRIAN); } @@ -266,7 +268,7 @@ void setCorrectPermissionsForSteps() { @Test void testGermanAutobahnSpeed() { // https://www.openstreetmap.org/way/10879847 - var alzentalstr = new OSMWithTags(); + var alzentalstr = new OsmWithTags(); alzentalstr.addTag("highway", "residential"); alzentalstr.addTag("lit", "yes"); alzentalstr.addTag("maxspeed", "30"); @@ -274,9 +276,24 @@ void testGermanAutobahnSpeed() { alzentalstr.addTag("surface", "asphalt"); assertEquals(8.33333969116211, wps.getCarSpeedForWay(alzentalstr, false), epsilon); - var autobahn = new OSMWithTags(); + var autobahn = new OsmWithTags(); autobahn.addTag("highway", "motorway"); autobahn.addTag("maxspeed", "none"); assertEquals(33.33000183105469, wps.getCarSpeedForWay(autobahn, false), epsilon); } + + /** + * Test that biking is not allowed in transit platforms + */ + @Test + public void testArea() { + OsmWithTags way; + + way = new OsmWithTags(); + way.addTag("public_transport", "platform"); + way.addTag("area", "yes"); + assertEquals(wps.getDataForWay(way).getPermission(), PEDESTRIAN); + way.addTag("bicycle", "yes"); + assertEquals(wps.getDataForWay(way).getPermission(), PEDESTRIAN_AND_BICYCLE); + } } diff --git a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/HamburgMapperTest.java b/application/src/test/java/org/opentripplanner/osm/tagmapping/HamburgMapperTest.java similarity index 87% rename from src/test/java/org/opentripplanner/openstreetmap/tagmapping/HamburgMapperTest.java rename to application/src/test/java/org/opentripplanner/osm/tagmapping/HamburgMapperTest.java index 1af3eefee18..5c8270a38b8 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/HamburgMapperTest.java +++ b/application/src/test/java/org/opentripplanner/osm/tagmapping/HamburgMapperTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -7,7 +7,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; /** * @author Maintained by HBT (geofox-team@hbt.de) @@ -23,7 +23,7 @@ void createMapper() { @Test public void shouldAllowThroughTraffic_WhenAccessCustomers_AndCustomersHVV() { - OSMWithTags way = new OSMWithTags(); + OsmWithTags way = new OsmWithTags(); way.addTag("access", "customers"); way.addTag("customers", "HVV"); @@ -38,7 +38,7 @@ public void shouldAllowThroughTraffic_WhenAccessCustomers_AndCustomersHVV() { @ParameterizedTest @ValueSource(strings = { "no", "destination", "private", "customers", "delivery" }) public void shouldDisallowThroughTraffic_WhenNoCustomersHVV(String access) { - OSMWithTags way = new OSMWithTags(); + OsmWithTags way = new OsmWithTags(); way.addTag("access", access); boolean generalNoThroughTraffic = mapper.isGeneralNoThroughTraffic(way); diff --git a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/HoustonMapperTest.java b/application/src/test/java/org/opentripplanner/osm/tagmapping/HoustonMapperTest.java similarity index 87% rename from src/test/java/org/opentripplanner/openstreetmap/tagmapping/HoustonMapperTest.java rename to application/src/test/java/org/opentripplanner/osm/tagmapping/HoustonMapperTest.java index 163a206e667..8db47bbf1dc 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/HoustonMapperTest.java +++ b/application/src/test/java/org/opentripplanner/osm/tagmapping/HoustonMapperTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.street.model.StreetTraversalPermission.ALL; @@ -7,8 +7,8 @@ import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN_AND_BICYCLE; import org.junit.jupiter.api.Test; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.WayPropertySet; class HoustonMapperTest { @@ -22,7 +22,7 @@ class HoustonMapperTest { @Test public void lamarTunnel() { // https://www.openstreetmap.org/way/127288293 - OSMWithTags tunnel = new OSMWithTags(); + OsmWithTags tunnel = new OsmWithTags(); tunnel.addTag("highway", "footway"); tunnel.addTag("indoor", "yes"); tunnel.addTag("layer", "-1"); @@ -36,7 +36,7 @@ public void lamarTunnel() { @Test public void harrisCountyTunnel() { // https://www.openstreetmap.org/way/127288288 - OSMWithTags tunnel = new OSMWithTags(); + OsmWithTags tunnel = new OsmWithTags(); tunnel.addTag("highway", "footway"); tunnel.addTag("indoor", "yes"); tunnel.addTag("name", "Harris County Tunnel"); @@ -48,7 +48,7 @@ public void harrisCountyTunnel() { @Test public void pedestrianUnderpass() { // https://www.openstreetmap.org/way/783648925 - OSMWithTags tunnel = new OSMWithTags(); + OsmWithTags tunnel = new OsmWithTags(); tunnel.addTag("highway", "footway"); tunnel.addTag("layer", "-1"); tunnel.addTag("tunnel", "yes"); @@ -59,7 +59,7 @@ public void pedestrianUnderpass() { @Test public void cyclingTunnel() { // https://www.openstreetmap.org/way/220484967 - OSMWithTags tunnel = new OSMWithTags(); + OsmWithTags tunnel = new OsmWithTags(); tunnel.addTag("bicycle", "designated"); tunnel.addTag("foot", "designated"); tunnel.addTag("highway", "cycleway"); @@ -70,7 +70,7 @@ public void cyclingTunnel() { assertEquals(ALL, wps.getDataForWay(tunnel).getPermission()); // https://www.openstreetmap.org/way/101884176 - tunnel = new OSMWithTags(); + tunnel = new OsmWithTags(); tunnel.addTag("highway", "cycleway"); tunnel.addTag("layer", "-1"); tunnel.addTag("name", "Hogg Woods Trail"); @@ -81,7 +81,7 @@ public void cyclingTunnel() { @Test public void carTunnel() { // https://www.openstreetmap.org/way/598694756 - OSMWithTags tunnel = new OSMWithTags(); + OsmWithTags tunnel = new OsmWithTags(); tunnel.addTag("highway", "primary"); tunnel.addTag("hov", "lane"); tunnel.addTag("lanes", "4"); @@ -100,7 +100,7 @@ public void carTunnel() { @Test public void carUnderpass() { // https://www.openstreetmap.org/way/102925214 - OSMWithTags tunnel = new OSMWithTags(); + OsmWithTags tunnel = new OsmWithTags(); tunnel.addTag("highway", "motorway_link"); tunnel.addTag("lanes", "2"); tunnel.addTag("layer", "-1"); @@ -113,7 +113,7 @@ public void carUnderpass() { @Test public void serviceTunnel() { // https://www.openstreetmap.org/way/15334550 - OSMWithTags tunnel = new OSMWithTags(); + OsmWithTags tunnel = new OsmWithTags(); tunnel.addTag("highway", "service"); tunnel.addTag("layer", "-1"); tunnel.addTag("tunnel", "yes"); @@ -124,7 +124,7 @@ public void serviceTunnel() { @Test public void unclassified() { // https://www.openstreetmap.org/way/44896136 - OSMWithTags tunnel = new OSMWithTags(); + OsmWithTags tunnel = new OsmWithTags(); tunnel.addTag("highway", "unclassified"); tunnel.addTag("name", "Ross Sterling Street"); tunnel.addTag("layer", "-1"); diff --git a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/NorwayMapperTest.java b/application/src/test/java/org/opentripplanner/osm/tagmapping/NorwayMapperTest.java similarity index 85% rename from src/test/java/org/opentripplanner/openstreetmap/tagmapping/NorwayMapperTest.java rename to application/src/test/java/org/opentripplanner/osm/tagmapping/NorwayMapperTest.java index cce2bf85cb4..a87103648dc 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/NorwayMapperTest.java +++ b/application/src/test/java/org/opentripplanner/osm/tagmapping/NorwayMapperTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.tagmapping; import static java.lang.Double.NaN; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -9,9 +9,9 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.SafetyFeatures; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.SafetyFeatures; +import org.opentripplanner.osm.wayproperty.WayPropertySet; import org.opentripplanner.street.model.StreetTraversalPermission; public class NorwayMapperTest { @@ -50,7 +50,7 @@ static List createExpectedBicycleSafetyForMaxspeedCases() { var expectedSafety = expectedBicycleSafetyMatrix[i][j]; if (!Double.isNaN(expectedSafety)) { var maxspeed = expectedMaxspeeds[j]; - var way = new OSMWithTags(); + var way = new OsmWithTags(); way.addTag("highway", highway); way.addTag("maxspeed", String.valueOf(maxspeed)); argumentsList.add(Arguments.of(way, expectedSafety)); @@ -66,7 +66,7 @@ static List createBicycleSafetyWithoutExplicitMaxspeed() { for (int i = 0; i < expectedHighways.length; i++) { var highway = expectedHighways[i]; var expectedSafety = expectedBicycleSafety[i]; - var way = new OSMWithTags(); + var way = new OsmWithTags(); way.addTag("highway", highway); argumentsList.add(Arguments.of(way, expectedSafety)); } @@ -78,10 +78,10 @@ static List createLinkRoadLikeMainCases() { for (var i = 0; i < 4; i++) { var highway = expectedHighways[i]; for (var maxspeed : expectedMaxspeeds) { - var mainRoad = new OSMWithTags(); + var mainRoad = new OsmWithTags(); mainRoad.addTag("highway", highway); mainRoad.addTag("maxspeed", String.valueOf(maxspeed)); - var linkRoad = new OSMWithTags(); + var linkRoad = new OsmWithTags(); linkRoad.addTag("highway", highway.concat("_link")); linkRoad.addTag("maxspeed", String.valueOf(maxspeed)); argumentsList.add(Arguments.of(mainRoad, linkRoad)); @@ -92,7 +92,7 @@ static List createLinkRoadLikeMainCases() { @ParameterizedTest(name = "{0} should have a score of {1}") @MethodSource("createExpectedBicycleSafetyForMaxspeedCases") - public void testBicycleSafetyForMaxspeed(OSMWithTags way, Double expected) { + public void testBicycleSafetyForMaxspeed(OsmWithTags way, Double expected) { var result = wps.getDataForWay(way).bicycleSafety(); var expectedSafetyFeatures = new SafetyFeatures(expected, expected); assertEquals(expectedSafetyFeatures, result); @@ -100,7 +100,7 @@ public void testBicycleSafetyForMaxspeed(OSMWithTags way, Double expected) { @ParameterizedTest @MethodSource("createBicycleSafetyWithoutExplicitMaxspeed") - public void testBicycleSafetyWithoutMaxspeed(OSMWithTags way, Double expected) { + public void testBicycleSafetyWithoutMaxspeed(OsmWithTags way, Double expected) { var result = wps.getDataForWay(way).bicycleSafety(); var expectedSafetyFeatures = new SafetyFeatures(expected, expected); assertEquals(expectedSafetyFeatures, result); @@ -108,7 +108,7 @@ public void testBicycleSafetyWithoutMaxspeed(OSMWithTags way, Double expected) { @ParameterizedTest @MethodSource("createLinkRoadLikeMainCases") - public void testBicycleSafetyLikeLinkRoad(OSMWithTags mainRoad, OSMWithTags linkRoad) { + public void testBicycleSafetyLikeLinkRoad(OsmWithTags mainRoad, OsmWithTags linkRoad) { var resultMain = wps.getDataForWay(mainRoad).bicycleSafety(); var resultLink = wps.getDataForWay(linkRoad).bicycleSafety(); @@ -117,7 +117,7 @@ public void testBicycleSafetyLikeLinkRoad(OSMWithTags mainRoad, OSMWithTags link @Test public void testTrunkIsWalkable() { - var way = new OSMWithTags(); + var way = new OsmWithTags(); way.addTag("highway", "trunk"); assertEquals(StreetTraversalPermission.ALL, wps.getDataForWay(way).getPermission()); @@ -126,13 +126,13 @@ public void testTrunkIsWalkable() { @Test public void testMtbScaleNone() { // https://www.openstreetmap.org/way/302610220 - var way1 = new OSMWithTags(); + var way1 = new OsmWithTags(); way1.addTag("highway", "path"); way1.addTag("mtb:scale", "3"); assertEquals(StreetTraversalPermission.NONE, wps.getDataForWay(way1).getPermission()); - var way2 = new OSMWithTags(); + var way2 = new OsmWithTags(); way2.addTag("highway", "track"); way2.addTag("mtb:scale", "3"); @@ -141,13 +141,13 @@ public void testMtbScaleNone() { @Test public void testMtbScalePedestrian() { - var way1 = new OSMWithTags(); + var way1 = new OsmWithTags(); way1.addTag("highway", "path"); way1.addTag("mtb:scale", "1"); assertEquals(StreetTraversalPermission.PEDESTRIAN, wps.getDataForWay(way1).getPermission()); - var way2 = new OSMWithTags(); + var way2 = new OsmWithTags(); way2.addTag("highway", "track"); way2.addTag("mtb:scale", "1"); @@ -156,13 +156,13 @@ public void testMtbScalePedestrian() { @Test public void testMotorroad() { - var way1 = new OSMWithTags(); + var way1 = new OsmWithTags(); way1.addTag("highway", "trunk"); way1.addTag("motorroad", "yes"); assertEquals(StreetTraversalPermission.CAR, wps.getDataForWay(way1).getPermission()); - var way2 = new OSMWithTags(); + var way2 = new OsmWithTags(); way2.addTag("highway", "primary"); way2.addTag("motorroad", "yes"); diff --git a/application/src/test/java/org/opentripplanner/osm/tagmapping/OsmTagMapperTest.java b/application/src/test/java/org/opentripplanner/osm/tagmapping/OsmTagMapperTest.java new file mode 100644 index 00000000000..5448f84294d --- /dev/null +++ b/application/src/test/java/org/opentripplanner/osm/tagmapping/OsmTagMapperTest.java @@ -0,0 +1,202 @@ +package org.opentripplanner.osm.tagmapping; + +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.street.model.StreetTraversalPermission.ALL; +import static org.opentripplanner.street.model.StreetTraversalPermission.CAR; + +import java.util.List; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.WayPropertySet; +import org.opentripplanner.osm.wayproperty.specifier.WayTestData; + +class OsmTagMapperTest { + + @Test + void isMotorThroughTrafficExplicitlyDisallowed() { + OsmWithTags o = new OsmWithTags(); + OsmTagMapper osmTagMapper = new OsmTagMapper(); + + assertFalse(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(o)); + + o.addTag("access", "something"); + assertFalse(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(o)); + + o.addTag("access", "destination"); + assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(o)); + + o.addTag("access", "private"); + assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(o)); + + assertTrue( + osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed( + way("motor_vehicle", "destination") + ) + ); + } + + @Test + void isBicycleThroughTrafficExplicitlyDisallowed() { + OsmTagMapper osmTagMapper = new OsmTagMapper(); + assertTrue( + osmTagMapper.isBicycleThroughTrafficExplicitlyDisallowed(way("bicycle", "destination")) + ); + assertTrue( + osmTagMapper.isBicycleThroughTrafficExplicitlyDisallowed(way("access", "destination")) + ); + } + + @Test + void isWalkThroughTrafficExplicitlyDisallowed() { + OsmTagMapper osmTagMapper = new OsmTagMapper(); + assertTrue(osmTagMapper.isWalkThroughTrafficExplicitlyDisallowed(way("foot", "destination"))); + assertTrue(osmTagMapper.isWalkThroughTrafficExplicitlyDisallowed(way("access", "destination"))); + } + + @Test + void testAccessNo() { + OsmWithTags tags = new OsmWithTags(); + OsmTagMapper osmTagMapper = new OsmTagMapper(); + + tags.addTag("access", "no"); + + assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); + assertTrue(osmTagMapper.isBicycleThroughTrafficExplicitlyDisallowed(tags)); + assertTrue(osmTagMapper.isWalkThroughTrafficExplicitlyDisallowed(tags)); + } + + @Test + void testAccessPrivate() { + OsmWithTags tags = new OsmWithTags(); + OsmTagMapper osmTagMapper = new OsmTagMapper(); + + tags.addTag("access", "private"); + + assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); + assertTrue(osmTagMapper.isBicycleThroughTrafficExplicitlyDisallowed(tags)); + assertTrue(osmTagMapper.isWalkThroughTrafficExplicitlyDisallowed(tags)); + } + + @Test + void testFootModifier() { + OsmWithTags tags = new OsmWithTags(); + OsmTagMapper osmTagMapper = new OsmTagMapper(); + + tags.addTag("access", "private"); + tags.addTag("foot", "yes"); + + assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); + assertTrue(osmTagMapper.isBicycleThroughTrafficExplicitlyDisallowed(tags)); + assertFalse(osmTagMapper.isWalkThroughTrafficExplicitlyDisallowed(tags)); + } + + @Test + void testVehicleDenied() { + OsmWithTags tags = new OsmWithTags(); + OsmTagMapper osmTagMapper = new OsmTagMapper(); + + tags.addTag("vehicle", "destination"); + + assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); + assertTrue(osmTagMapper.isBicycleThroughTrafficExplicitlyDisallowed(tags)); + assertFalse(osmTagMapper.isWalkThroughTrafficExplicitlyDisallowed(tags)); + } + + @Test + void testVehicleDeniedMotorVehiclePermissive() { + OsmWithTags tags = new OsmWithTags(); + OsmTagMapper osmTagMapper = new OsmTagMapper(); + + tags.addTag("vehicle", "destination"); + tags.addTag("motor_vehicle", "designated"); + + assertFalse(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); + assertTrue(osmTagMapper.isBicycleThroughTrafficExplicitlyDisallowed(tags)); + assertFalse(osmTagMapper.isWalkThroughTrafficExplicitlyDisallowed(tags)); + } + + @Test + void testVehicleDeniedBicyclePermissive() { + OsmWithTags tags = new OsmWithTags(); + OsmTagMapper osmTagMapper = new OsmTagMapper(); + + tags.addTag("vehicle", "destination"); + tags.addTag("bicycle", "designated"); + + assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); + assertFalse(osmTagMapper.isBicycleThroughTrafficExplicitlyDisallowed(tags)); + assertFalse(osmTagMapper.isWalkThroughTrafficExplicitlyDisallowed(tags)); + } + + @Test + void testMotorcycleModifier() { + OsmWithTags tags = new OsmWithTags(); + OsmTagMapper osmTagMapper = new OsmTagMapper(); + + tags.addTag("access", "private"); + tags.addTag("motor_vehicle", "yes"); + + assertFalse(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); + assertTrue(osmTagMapper.isBicycleThroughTrafficExplicitlyDisallowed(tags)); + assertTrue(osmTagMapper.isWalkThroughTrafficExplicitlyDisallowed(tags)); + } + + @Test + void testBicycleModifier() { + OsmWithTags tags = new OsmWithTags(); + OsmTagMapper osmTagMapper = new OsmTagMapper(); + + tags.addTag("access", "private"); + tags.addTag("bicycle", "yes"); + + assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); + assertFalse(osmTagMapper.isBicycleThroughTrafficExplicitlyDisallowed(tags)); + assertTrue(osmTagMapper.isWalkThroughTrafficExplicitlyDisallowed(tags)); + } + + @Test + void testBicyclePermissive() { + OsmWithTags tags = new OsmWithTags(); + OsmTagMapper osmTagMapper = new OsmTagMapper(); + + tags.addTag("access", "private"); + tags.addTag("bicycle", "permissive"); + + assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); + assertFalse(osmTagMapper.isBicycleThroughTrafficExplicitlyDisallowed(tags)); + assertTrue(osmTagMapper.isWalkThroughTrafficExplicitlyDisallowed(tags)); + } + + public static List roadCases() { + return List.of( + WayTestData.carTunnel(), + WayTestData.southwestMayoStreet(), + WayTestData.southeastLaBonitaWay(), + WayTestData.fiveLanes(), + WayTestData.highwayTertiary() + ); + } + + @ParameterizedTest + @MethodSource("roadCases") + void motorroad(OsmWithTags way) { + OsmTagMapper osmTagMapper = new OsmTagMapper(); + WayPropertySet wps = new WayPropertySet(); + osmTagMapper.populateProperties(wps); + + assertEquals(ALL, wps.getDataForWay(way).getPermission()); + + way.addTag("motorroad", "yes"); + assertEquals(CAR, wps.getDataForWay(way).getPermission()); + } + + public OsmWithTags way(String key, String value) { + var way = new OsmWithTags(); + way.addTag(key, value); + return way; + } +} diff --git a/application/src/test/java/org/opentripplanner/osm/tagmapping/PortlandMapperTest.java b/application/src/test/java/org/opentripplanner/osm/tagmapping/PortlandMapperTest.java new file mode 100644 index 00000000000..c24e311d5d3 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/osm/tagmapping/PortlandMapperTest.java @@ -0,0 +1,63 @@ +package org.opentripplanner.osm.tagmapping; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.carTunnel; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.cobblestones; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.fiveLanes; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.footwaySidewalk; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.highwayTertiary; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.highwayTertiaryWithSidewalk; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.highwayTrunk; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.noSidewalk; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.noSidewalkHighSpeed; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.pedestrianTunnel; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.sidewalkBoth; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.southeastLaBonitaWay; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.southwestMayoStreet; + +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.WayPropertySet; + +public class PortlandMapperTest { + + static double delta = 0.1; + + static WayPropertySet wps = new WayPropertySet(); + + static Stream cases() { + return Stream.of( + Arguments.of(southeastLaBonitaWay(), 0.8), + Arguments.of(southwestMayoStreet(), 0.9), + Arguments.of(sidewalkBoth(), 0.96), + Arguments.of(pedestrianTunnel(), 1.0), + Arguments.of(highwayTertiaryWithSidewalk(), 1.056), + Arguments.of(cobblestones(), 1.2), + Arguments.of(noSidewalk(), 1.2), + Arguments.of(carTunnel(), 1.2), + Arguments.of(footwaySidewalk(), 1.32), + Arguments.of(highwayTertiary(), 1.32), + Arguments.of(highwayTrunk(), 1.44), + Arguments.of(fiveLanes(), 1.584), + Arguments.of(noSidewalkHighSpeed(), 7.19) + ); + } + + static { + var source = new PortlandMapper(); + source.populateProperties(wps); + } + + @ParameterizedTest(name = "way {0} should have walk safety factor {1}") + @MethodSource("cases") + void walkSafety(OsmWithTags way, double expected) { + var score = wps.getDataForWay(way); + + var ws = score.walkSafety(); + assertEquals(expected, ws.forward(), delta); + assertEquals(expected, ws.back(), delta); + } +} diff --git a/application/src/test/java/org/opentripplanner/osm/tagmapping/UKMapperTest.java b/application/src/test/java/org/opentripplanner/osm/tagmapping/UKMapperTest.java new file mode 100644 index 00000000000..3e9e46618fd --- /dev/null +++ b/application/src/test/java/org/opentripplanner/osm/tagmapping/UKMapperTest.java @@ -0,0 +1,26 @@ +package org.opentripplanner.osm.tagmapping; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN; + +import org.junit.jupiter.api.Test; +import org.opentripplanner.osm.wayproperty.WayPropertySet; +import org.opentripplanner.osm.wayproperty.specifier.WayTestData; + +public class UKMapperTest { + + static WayPropertySet wps = new WayPropertySet(); + + static { + var source = new UKMapper(); + source.populateProperties(wps); + } + + @Test + void indoor() { + var corridor = wps.getDataForWay(WayTestData.indoor("corridor")); + assertEquals(PEDESTRIAN, corridor.getPermission()); + var area = wps.getDataForWay(WayTestData.indoor("area")); + assertEquals(PEDESTRIAN, area.getPermission()); + } +} diff --git a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/DefaultMapperTest.java b/application/src/test/java/org/opentripplanner/osm/wayproperty/MapperTest.java similarity index 81% rename from src/test/java/org/opentripplanner/openstreetmap/tagmapping/DefaultMapperTest.java rename to application/src/test/java/org/opentripplanner/osm/wayproperty/MapperTest.java index 2a8988dda61..2cd9a74f06b 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/DefaultMapperTest.java +++ b/application/src/test/java/org/opentripplanner/osm/wayproperty/MapperTest.java @@ -1,20 +1,23 @@ -package org.opentripplanner.openstreetmap.tagmapping; +package org.opentripplanner.osm.wayproperty; 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.osm.wayproperty.MixinPropertiesBuilder.ofBicycleSafety; +import static org.opentripplanner.osm.wayproperty.WayPropertiesBuilder.withModes; import static org.opentripplanner.street.model.StreetTraversalPermission.ALL; +import static org.opentripplanner.street.model.StreetTraversalPermission.CAR; import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN; import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN_AND_BICYCLE; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.SpeedPicker; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; -import org.opentripplanner.openstreetmap.wayproperty.specifier.BestMatchSpecifier; -import org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.tagmapping.OsmTagMapper; +import org.opentripplanner.osm.wayproperty.specifier.BestMatchSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.WayTestData; -public class DefaultMapperTest { +public class MapperTest { private WayPropertySet wps; private OsmTagMapper mapper; @@ -23,7 +26,7 @@ public class DefaultMapperTest { @BeforeEach public void setup() { var wps = new WayPropertySet(); - DefaultMapper source = new DefaultMapper(); + var source = new OsmTagMapper(); source.populateProperties(wps); this.wps = wps; this.mapper = source; @@ -34,34 +37,34 @@ public void setup() { */ @Test public void testCarSpeeds() { - OSMWithTags way; + OsmWithTags way; - way = new OSMWithTags(); + way = new OsmWithTags(); way.addTag("maxspeed", "60"); assertTrue(within(kmhAsMs(60), wps.getCarSpeedForWay(way, false), epsilon)); assertTrue(within(kmhAsMs(60), wps.getCarSpeedForWay(way, true), epsilon)); - way = new OSMWithTags(); + way = new OsmWithTags(); way.addTag("maxspeed:forward", "80"); way.addTag("maxspeed:backward", "20"); way.addTag("maxspeed", "40"); assertTrue(within(kmhAsMs(80), wps.getCarSpeedForWay(way, false), epsilon)); assertTrue(within(kmhAsMs(20), wps.getCarSpeedForWay(way, true), epsilon)); - way = new OSMWithTags(); + way = new OsmWithTags(); way.addTag("maxspeed", "40"); way.addTag("maxspeed:lanes", "60|80|40"); assertTrue(within(kmhAsMs(80), wps.getCarSpeedForWay(way, false), epsilon)); assertTrue(within(kmhAsMs(80), wps.getCarSpeedForWay(way, true), epsilon)); - way = new OSMWithTags(); + way = new OsmWithTags(); way.addTag("maxspeed", "20"); way.addTag("maxspeed:motorcar", "80"); assertTrue(within(kmhAsMs(80), wps.getCarSpeedForWay(way, false), epsilon)); assertTrue(within(kmhAsMs(80), wps.getCarSpeedForWay(way, true), epsilon)); // test with english units - way = new OSMWithTags(); + way = new OsmWithTags(); way.addTag("maxspeed", "35 mph"); assertTrue(within(kmhAsMs(35 * 1.609f), wps.getCarSpeedForWay(way, false), epsilon)); assertTrue(within(kmhAsMs(35 * 1.609f), wps.getCarSpeedForWay(way, true), epsilon)); @@ -73,7 +76,7 @@ public void testCarSpeeds() { wps.addSpeedPicker(getSpeedPicker("surface=gravel", kmhAsMs(10))); wps.defaultCarSpeed = kmhAsMs(25); - way = new OSMWithTags(); + way = new OsmWithTags(); // test default speeds assertTrue(within(kmhAsMs(25), wps.getCarSpeedForWay(way, false), epsilon)); @@ -83,18 +86,18 @@ public void testCarSpeeds() { assertTrue(within(kmhAsMs(35), wps.getCarSpeedForWay(way, false), epsilon)); assertTrue(within(kmhAsMs(35), wps.getCarSpeedForWay(way, true), epsilon)); - way = new OSMWithTags(); + way = new OsmWithTags(); way.addTag("surface", "gravel"); assertTrue(within(kmhAsMs(10), wps.getCarSpeedForWay(way, false), epsilon)); assertTrue(within(kmhAsMs(10), wps.getCarSpeedForWay(way, true), epsilon)); - way = new OSMWithTags(); + way = new OsmWithTags(); way.addTag("highway", "motorway"); assertTrue(within(kmhAsMs(100), wps.getCarSpeedForWay(way, false), epsilon)); assertTrue(within(kmhAsMs(100), wps.getCarSpeedForWay(way, true), epsilon)); // make sure that 0-speed ways can't exist - way = new OSMWithTags(); + way = new OsmWithTags(); way.addTag("maxspeed", "0"); assertTrue(within(kmhAsMs(25), wps.getCarSpeedForWay(way, false), epsilon)); assertTrue(within(kmhAsMs(25), wps.getCarSpeedForWay(way, true), epsilon)); @@ -189,6 +192,31 @@ void bicycleUseSidepath() { assertEquals(4.9, useSidepathBackwardProps.bicycleSafety().back(), epsilon); } + @Test + void slopeOverrides() { + var regular = WayTestData.southeastLaBonitaWay(); + assertFalse(wps.getSlopeOverride(regular)); + + var indoor = WayTestData.southeastLaBonitaWay().addTag("indoor", "yes"); + assertTrue(wps.getSlopeOverride(indoor)); + } + + @Test + public void mixin() { + wps.setProperties("tag=imaginary", withModes(CAR).bicycleSafety(2)); + wps.setMixinProperties("foo=bar", ofBicycleSafety(0.5)); + + var withoutFoo = new OsmWithTags(); + withoutFoo.addTag("tag", "imaginary"); + assertEquals(2, wps.getDataForWay(withoutFoo).bicycleSafety().back()); + + // the mixin for foo=bar reduces the bike safety factor + var withFoo = new OsmWithTags(); + withFoo.addTag("tag", "imaginary"); + withFoo.addTag("foo", "bar"); + assertEquals(1, wps.getDataForWay(withFoo).bicycleSafety().back()); + } + /** * Test that two values are within epsilon of each other. */ diff --git a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/MixinPropertiesBuilderTest.java b/application/src/test/java/org/opentripplanner/osm/wayproperty/MixinPropertiesBuilderTest.java similarity index 84% rename from src/test/java/org/opentripplanner/openstreetmap/wayproperty/MixinPropertiesBuilderTest.java rename to application/src/test/java/org/opentripplanner/osm/wayproperty/MixinPropertiesBuilderTest.java index 62d9b192a97..2c2dc5bd987 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/MixinPropertiesBuilderTest.java +++ b/application/src/test/java/org/opentripplanner/osm/wayproperty/MixinPropertiesBuilderTest.java @@ -1,9 +1,9 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import org.opentripplanner.openstreetmap.wayproperty.specifier.BestMatchSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.BestMatchSpecifier; class MixinPropertiesBuilderTest { diff --git a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/WayPropertySetTest.java b/application/src/test/java/org/opentripplanner/osm/wayproperty/WayPropertySetTest.java similarity index 89% rename from src/test/java/org/opentripplanner/openstreetmap/wayproperty/WayPropertySetTest.java rename to application/src/test/java/org/opentripplanner/osm/wayproperty/WayPropertySetTest.java index 24360539b6f..8d460b92cc5 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/WayPropertySetTest.java +++ b/application/src/test/java/org/opentripplanner/osm/wayproperty/WayPropertySetTest.java @@ -1,22 +1,21 @@ -package org.opentripplanner.openstreetmap.wayproperty; +package org.opentripplanner.osm.wayproperty; 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.openstreetmap.wayproperty.MixinPropertiesBuilder.ofBicycleSafety; -import static org.opentripplanner.openstreetmap.wayproperty.WayPropertiesBuilder.withModes; +import static org.opentripplanner.osm.wayproperty.MixinPropertiesBuilder.ofBicycleSafety; +import static org.opentripplanner.osm.wayproperty.WayPropertiesBuilder.withModes; import static org.opentripplanner.street.model.StreetTraversalPermission.CAR; import static org.opentripplanner.street.model.StreetTraversalPermission.NONE; -import javax.annotation.Nonnull; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.opentripplanner.graph_builder.module.osm.StreetTraversalPermissionPair; -import org.opentripplanner.openstreetmap.model.OSMWay; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.tagmapping.OsmTagMapper; -import org.opentripplanner.openstreetmap.wayproperty.specifier.ExactMatchSpecifier; -import org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData; +import org.opentripplanner.osm.model.OsmWay; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.tagmapping.OsmTagMapper; +import org.opentripplanner.osm.wayproperty.specifier.ExactMatchSpecifier; +import org.opentripplanner.osm.wayproperty.specifier.WayTestData; import org.opentripplanner.street.model.StreetTraversalPermission; class WayPropertySetTest { @@ -26,7 +25,7 @@ class ConditionSpecificity { @Test public void carTunnel() { - OSMWithTags tunnel = WayTestData.carTunnel(); + OsmWithTags tunnel = WayTestData.carTunnel(); WayPropertySet wps = wps(); assertEquals(CAR, wps.getDataForWay(tunnel).getPermission()); } @@ -43,7 +42,7 @@ public void carMaxSpeed() { assertEquals(0f, wps.maxUsedCarSpeed, delta); // Speed limit that is within limits should be used as the max used car speed - OSMWithTags streetWithSpeedLimit = new OSMWithTags(); + OsmWithTags streetWithSpeedLimit = new OsmWithTags(); streetWithSpeedLimit.addTag("highway", "motorway"); streetWithSpeedLimit.addTag("maxspeed", "120"); var waySpeed = wps.getCarSpeedForWay(streetWithSpeedLimit, false); @@ -52,7 +51,7 @@ public void carMaxSpeed() { // Speed limit that is higher than maxPossibleCarSpeed should be ignored and regular motorway // speed limit should be used instead - OSMWithTags streetWithTooHighSpeedLimit = new OSMWithTags(); + OsmWithTags streetWithTooHighSpeedLimit = new OsmWithTags(); streetWithTooHighSpeedLimit.addTag("highway", "motorway"); streetWithTooHighSpeedLimit.addTag("maxspeed", "200"); waySpeed = wps.getCarSpeedForWay(streetWithTooHighSpeedLimit, false); @@ -61,7 +60,7 @@ public void carMaxSpeed() { // Speed limit that is too low should be ignored and regular motorway speed limit should // be used instead - OSMWithTags streetWithTooLowSpeedLimit = new OSMWithTags(); + OsmWithTags streetWithTooLowSpeedLimit = new OsmWithTags(); streetWithTooLowSpeedLimit.addTag("highway", "motorway"); streetWithTooLowSpeedLimit.addTag("maxspeed", "0"); waySpeed = wps.getCarSpeedForWay(streetWithTooLowSpeedLimit, false); @@ -84,7 +83,6 @@ void mixinLeftSide() { assertEquals(expected, wps.getDataForWay(cycleway).bicycleSafety()); } - @Nonnull private static WayPropertySet wps() { var wps = new WayPropertySet(); var source = new OsmTagMapper() { @@ -113,7 +111,7 @@ class NoMapper { */ @Test void testCarPermission() { - OSMWay way = new OSMWay(); + OsmWay way = new OsmWay(); way.addTag("highway", "unclassified"); var permissionPair = getWayProperties(way); @@ -130,7 +128,7 @@ void testCarPermission() { */ @Test void testMotorCarTagAllowedPermissions() { - OSMWay way = new OSMWay(); + OsmWay way = new OsmWay(); way.addTag("highway", "residential"); var permissionPair = getWayProperties(way); assertTrue(permissionPair.main().allows(StreetTraversalPermission.ALL)); @@ -164,7 +162,7 @@ void testMotorCarTagAllowedPermissions() { */ @Test void testMotorCarTagDeniedPermissions() { - OSMWay way = new OSMWay(); + OsmWay way = new OsmWay(); way.addTag("highway", "residential"); var permissionPair = getWayProperties(way); assertTrue(permissionPair.main().allows(StreetTraversalPermission.ALL)); @@ -196,7 +194,7 @@ void testMotorCarTagDeniedPermissions() { */ @Test void testMotorVehicleTagAllowedPermissions() { - OSMWay way = new OSMWay(); + OsmWay way = new OsmWay(); way.addTag("highway", "residential"); var permissionPair = getWayProperties(way); assertTrue(permissionPair.main().allows(StreetTraversalPermission.ALL)); @@ -232,7 +230,7 @@ void testMotorVehicleTagAllowedPermissions() { */ @Test void testMotorVehicleTagDeniedPermissions() { - OSMWay way = new OSMWay(); + OsmWay way = new OsmWay(); way.addTag("highway", "residential"); var permissionPair = getWayProperties(way); assertTrue(permissionPair.main().allows(StreetTraversalPermission.ALL)); @@ -256,7 +254,7 @@ void testMotorVehicleTagDeniedPermissions() { assertTrue(permissionPair.main().allowsNothing());*/ } - private StreetTraversalPermissionPair getWayProperties(OSMWay way) { + private StreetTraversalPermissionPair getWayProperties(OsmWay way) { WayPropertySet wayPropertySet = new WayPropertySet(); WayProperties wayData = wayPropertySet.getDataForWay(way); diff --git a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/BestMatchSpecifierTest.java b/application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/BestMatchSpecifierTest.java similarity index 85% rename from src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/BestMatchSpecifierTest.java rename to application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/BestMatchSpecifierTest.java index 517e4b57bfd..3c2efa46710 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/BestMatchSpecifierTest.java +++ b/application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/BestMatchSpecifierTest.java @@ -1,15 +1,15 @@ -package org.opentripplanner.openstreetmap.wayproperty.specifier; +package org.opentripplanner.osm.wayproperty.specifier; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.cyclewayLaneTrack; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.cyclewayLeft; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.cyclewayLaneTrack; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.cyclewayLeft; import java.util.stream.Stream; 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.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; class BestMatchSpecifierTest extends SpecifierTest { @@ -61,7 +61,7 @@ static Stream leftRightTestCases() { name = "way {0} with specifier {1} should have a backward score {2} and forward score {3}" ) @MethodSource("leftRightTestCases") - void leftRight(OSMWithTags way, OsmSpecifier spec, int expectedBackward, int expectedForward) { + void leftRight(OsmWithTags way, OsmSpecifier spec, int expectedBackward, int expectedForward) { var result = spec.matchScores(way); assertEquals(expectedBackward, result.backward()); assertEquals(expectedForward, result.forward()); diff --git a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/ConditionTest.java b/application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/ConditionTest.java similarity index 58% rename from src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/ConditionTest.java rename to application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/ConditionTest.java index 6386aa902e2..60adf602594 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/ConditionTest.java +++ b/application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/ConditionTest.java @@ -1,24 +1,24 @@ -package org.opentripplanner.openstreetmap.wayproperty.specifier; +package org.opentripplanner.osm.wayproperty.specifier; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.MatchResult.EXACT; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.MatchResult.NONE; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.MatchResult.WILDCARD; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.carTunnel; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.cobblestones; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.cycleway; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.cyclewayBoth; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.cyclewayLaneTrack; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.cyclewayLeft; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.excellentSmoothness; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.fiveLanes; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.highwayTertiary; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.noSidewalk; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.pedestrianTunnel; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.sidewalkBoth; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.threeLanes; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.tramsForward; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.veryBadSmoothness; +import static org.opentripplanner.osm.wayproperty.specifier.Condition.MatchResult.EXACT; +import static org.opentripplanner.osm.wayproperty.specifier.Condition.MatchResult.NONE; +import static org.opentripplanner.osm.wayproperty.specifier.Condition.MatchResult.WILDCARD; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.carTunnel; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.cobblestones; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.cycleway; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.cyclewayBoth; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.cyclewayLaneTrack; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.cyclewayLeft; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.excellentSmoothness; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.fiveLanes; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.highwayTertiary; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.noSidewalk; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.pedestrianTunnel; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.sidewalkBoth; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.threeLanes; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.tramsForward; +import static org.opentripplanner.osm.wayproperty.specifier.WayTestData.veryBadSmoothness; import java.util.stream.Stream; import org.junit.jupiter.api.Assertions; @@ -26,15 +26,15 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.Absent; -import org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.Equals; -import org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.GreaterThan; -import org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.InclusiveRange; -import org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.LessThan; -import org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.MatchResult; -import org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.OneOf; -import org.opentripplanner.openstreetmap.wayproperty.specifier.Condition.Present; +import org.opentripplanner.osm.model.OsmWithTags; +import org.opentripplanner.osm.wayproperty.specifier.Condition.Absent; +import org.opentripplanner.osm.wayproperty.specifier.Condition.Equals; +import org.opentripplanner.osm.wayproperty.specifier.Condition.GreaterThan; +import org.opentripplanner.osm.wayproperty.specifier.Condition.InclusiveRange; +import org.opentripplanner.osm.wayproperty.specifier.Condition.LessThan; +import org.opentripplanner.osm.wayproperty.specifier.Condition.MatchResult; +import org.opentripplanner.osm.wayproperty.specifier.Condition.OneOf; +import org.opentripplanner.osm.wayproperty.specifier.Condition.Present; class ConditionTest { @@ -71,7 +71,7 @@ static Stream equalsCases() { ) @MethodSource("equalsCases") void leftRight( - OSMWithTags way, + OsmWithTags way, Condition op, MatchResult backwardExpectation, MatchResult forwardExpectation @@ -108,7 +108,7 @@ static Stream otherCases() { @ParameterizedTest(name = "way {0} with op {1} should have a result {2}") @MethodSource("otherCases") - void otherTests(OSMWithTags way, Condition op, MatchResult expectation) { + void otherTests(OsmWithTags way, Condition op, MatchResult expectation) { assertEquals(expectation, op.match(way)); } diff --git a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/ExactMatchSpecifierTest.java b/application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/ExactMatchSpecifierTest.java similarity index 82% rename from src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/ExactMatchSpecifierTest.java rename to application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/ExactMatchSpecifierTest.java index 85898abd8f2..90fee463677 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/ExactMatchSpecifierTest.java +++ b/application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/ExactMatchSpecifierTest.java @@ -1,7 +1,7 @@ -package org.opentripplanner.openstreetmap.wayproperty.specifier; +package org.opentripplanner.osm.wayproperty.specifier; import org.junit.jupiter.api.Test; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; class ExactMatchSpecifierTest extends SpecifierTest { @@ -23,7 +23,7 @@ public void carTunnel() { @Test public void pedestrianTunnelSpecificity() { - OSMWithTags tunnel = WayTestData.pedestrianTunnel(); + OsmWithTags tunnel = WayTestData.pedestrianTunnel(); assertScore(0, highwayPrimarySpec, tunnel); assertScore(600, pedestrianUndergroundTunnelSpec, tunnel); assertScore(800, pedestrianUndergroundIndoorTunnelSpec, tunnel); diff --git a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/LogicalOrSpecifierTest.java b/application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/LogicalOrSpecifierTest.java similarity index 89% rename from src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/LogicalOrSpecifierTest.java rename to application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/LogicalOrSpecifierTest.java index 5375c0d920c..cc99129cec6 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/LogicalOrSpecifierTest.java +++ b/application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/LogicalOrSpecifierTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap.wayproperty.specifier; +package org.opentripplanner.osm.wayproperty.specifier; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/OsmSpecifierTest.java b/application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/OsmSpecifierTest.java similarity index 85% rename from src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/OsmSpecifierTest.java rename to application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/OsmSpecifierTest.java index e9f9730ddfe..5467f9f709a 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/OsmSpecifierTest.java +++ b/application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/OsmSpecifierTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.openstreetmap.wayproperty.specifier; +package org.opentripplanner.osm.wayproperty.specifier; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/SpecifierTest.java b/application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/SpecifierTest.java similarity index 72% rename from src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/SpecifierTest.java rename to application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/SpecifierTest.java index 2a754a1a883..5da2353bf57 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/SpecifierTest.java +++ b/application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/SpecifierTest.java @@ -1,12 +1,12 @@ -package org.opentripplanner.openstreetmap.wayproperty.specifier; +package org.opentripplanner.osm.wayproperty.specifier; import static org.junit.jupiter.api.Assertions.assertEquals; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWithTags; public class SpecifierTest { - protected void assertScore(int expectedScore, OsmSpecifier spec, OSMWithTags tunnel) { + protected void assertScore(int expectedScore, OsmSpecifier spec, OsmWithTags tunnel) { var result = spec.matchScores(tunnel); assertEquals(expectedScore, result.backward()); assertEquals(expectedScore, result.forward()); diff --git a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/WayTestData.java b/application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/WayTestData.java similarity index 62% rename from src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/WayTestData.java rename to application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/WayTestData.java index b09f690f794..6d468b42db0 100644 --- a/src/test/java/org/opentripplanner/openstreetmap/wayproperty/specifier/WayTestData.java +++ b/application/src/test/java/org/opentripplanner/osm/wayproperty/specifier/WayTestData.java @@ -1,13 +1,13 @@ -package org.opentripplanner.openstreetmap.wayproperty.specifier; +package org.opentripplanner.osm.wayproperty.specifier; -import org.opentripplanner.openstreetmap.model.OSMWay; -import org.opentripplanner.openstreetmap.model.OSMWithTags; +import org.opentripplanner.osm.model.OsmWay; +import org.opentripplanner.osm.model.OsmWithTags; public class WayTestData { - public static OSMWithTags carTunnel() { + public static OsmWithTags carTunnel() { // https://www.openstreetmap.org/way/598694756 - OSMWithTags tunnel = new OSMWithTags(); + OsmWithTags tunnel = new OsmWithTags(); tunnel.addTag("highway", "primary"); tunnel.addTag("hov", "lane"); tunnel.addTag("lanes", "4"); @@ -22,9 +22,9 @@ public static OSMWithTags carTunnel() { return tunnel; } - public static OSMWithTags pedestrianTunnel() { + public static OsmWithTags pedestrianTunnel() { // https://www.openstreetmap.org/way/127288293 - OSMWithTags tunnel = new OSMWithTags(); + OsmWithTags tunnel = new OsmWithTags(); tunnel.addTag("highway", "footway"); tunnel.addTag("indoor", "yes"); tunnel.addTag("layer", "-1"); @@ -34,10 +34,10 @@ public static OSMWithTags pedestrianTunnel() { return tunnel; } - public static OSMWithTags streetOnBikeRoute() { + public static OsmWithTags streetOnBikeRoute() { // https://www.openstreetmap.org/way/26443041 is part of both an lcn relation - var way = new OSMWithTags(); + var way = new OsmWithTags(); way.addTag("highway", "residential"); way.addTag("lit", "yes"); way.addTag("maxspeed", "30"); @@ -50,9 +50,9 @@ public static OSMWithTags streetOnBikeRoute() { return way; } - public static OSMWithTags stairs() { + public static OsmWithTags stairs() { // https://www.openstreetmap.org/way/1058669389 - var way = new OSMWithTags(); + var way = new OsmWithTags(); way.addTag("handrail", "yes"); way.addTag("highway", "steps"); way.addTag("incline", "down"); @@ -65,9 +65,9 @@ public static OSMWithTags stairs() { return way; } - public static OSMWithTags southeastLaBonitaWay() { + public static OsmWithTags southeastLaBonitaWay() { // https://www.openstreetmap.org/way/5302874 - var way = new OSMWithTags(); + var way = new OsmWithTags(); way.addTag("highway", "residential"); way.addTag("name", "Southeast la Bonita Way"); way.addTag("sidewalk", "both"); @@ -75,9 +75,9 @@ public static OSMWithTags southeastLaBonitaWay() { return way; } - public static OSMWithTags southwestMayoStreet() { + public static OsmWithTags southwestMayoStreet() { //https://www.openstreetmap.org/way/425004690 - var way = new OSMWithTags(); + var way = new OsmWithTags(); way.addTag("highway", "residential"); way.addTag("name", "Southwest Mayo Street"); way.addTag("maxspeed", "25 mph"); @@ -86,124 +86,124 @@ public static OSMWithTags southwestMayoStreet() { return way; } - public static OSMWithTags fiveLanes() { - OSMWithTags way = new OSMWithTags(); + public static OsmWithTags fiveLanes() { + OsmWithTags way = new OsmWithTags(); way.addTag("highway", "primary"); way.addTag("lanes", "5"); return way; } - public static OSMWithTags threeLanes() { - OSMWithTags way = new OSMWithTags(); + public static OsmWithTags threeLanes() { + OsmWithTags way = new OsmWithTags(); way.addTag("highway", "primary"); way.addTag("lanes", "3"); return way; } - public static OSMWay cycleway() { - var way = new OSMWay(); + public static OsmWay cycleway() { + var way = new OsmWay(); way.addTag("highway", "residential"); way.addTag("cycleway", "lane"); return way; } - public static OSMWithTags cyclewayLeft() { - var way = new OSMWithTags(); + public static OsmWithTags cyclewayLeft() { + var way = new OsmWithTags(); way.addTag("highway", "residential"); way.addTag("cycleway:left", "lane"); return way; } - public static OSMWithTags cyclewayBoth() { - var way = new OSMWithTags(); + public static OsmWithTags cyclewayBoth() { + var way = new OsmWithTags(); way.addTag("highway", "residential"); way.addTag("cycleway:both", "lane"); return way; } - public static OSMWay footwaySidewalk() { - var way = new OSMWay(); + public static OsmWay footwaySidewalk() { + var way = new OsmWay(); way.addTag("footway", "sidewalk"); way.addTag("highway", "footway"); return way; } - public static OSMWithTags sidewalkBoth() { - var way = new OSMWithTags(); + public static OsmWithTags sidewalkBoth() { + var way = new OsmWithTags(); way.addTag("highway", "both"); way.addTag("sidewalk", "both"); return way; } - public static OSMWithTags noSidewalk() { - var way = new OSMWithTags(); + public static OsmWithTags noSidewalk() { + var way = new OsmWithTags(); way.addTag("highway", "residential"); way.addTag("sidewalk", "no"); return way; } - public static OSMWithTags noSidewalkHighSpeed() { - var way = new OSMWithTags(); + public static OsmWithTags noSidewalkHighSpeed() { + var way = new OsmWithTags(); way.addTag("highway", "residential"); way.addTag("sidewalk", "no"); way.addTag("maxspeed", "55 mph"); return way; } - public static OSMWithTags highwayTrunk() { - var way = new OSMWithTags(); + public static OsmWithTags highwayTrunk() { + var way = new OsmWithTags(); way.addTag("highway", "trunk"); return way; } - public static OSMWay highwayTertiary() { - var way = new OSMWay(); + public static OsmWay highwayTertiary() { + var way = new OsmWay(); way.addTag("highway", "tertiary"); return way; } - public static OSMWithTags highwayTertiaryWithSidewalk() { - var way = new OSMWithTags(); + public static OsmWithTags highwayTertiaryWithSidewalk() { + var way = new OsmWithTags(); way.addTag("highway", "tertiary"); way.addTag("sidewalk", "both"); return way; } - public static OSMWithTags cobblestones() { - var way = new OSMWithTags(); + public static OsmWithTags cobblestones() { + var way = new OsmWithTags(); way.addTag("highway", "residential"); way.addTag("surface", "cobblestones"); return way; } - public static OSMWithTags cyclewayLaneTrack() { - var way = new OSMWithTags(); + public static OsmWithTags cyclewayLaneTrack() { + var way = new OsmWithTags(); way.addTag("highway", "footway"); way.addTag("cycleway", "lane"); way.addTag("cycleway:right", "track"); return way; } - public static OSMWithTags tramsForward() { + public static OsmWithTags tramsForward() { // https://www.openstreetmap.org/way/108037345 - var way = new OSMWithTags(); + var way = new OsmWithTags(); way.addTag("highway", "tertiary"); way.addTag("embedded_rails:forward", "tram"); return way; } - public static OSMWithTags veryBadSmoothness() { + public static OsmWithTags veryBadSmoothness() { // https://www.openstreetmap.org/way/11402648 - var way = new OSMWithTags(); + var way = new OsmWithTags(); way.addTag("highway", "footway"); way.addTag("surface", "sett"); way.addTag("smoothness", "very_bad"); return way; } - public static OSMWithTags excellentSmoothness() { + public static OsmWithTags excellentSmoothness() { // https://www.openstreetmap.org/way/437167371 - var way = new OSMWithTags(); + var way = new OsmWithTags(); way.addTag("highway", "cycleway"); way.addTag("segregated", "no"); way.addTag("surface", "asphalt"); @@ -211,11 +211,25 @@ public static OSMWithTags excellentSmoothness() { return way; } - public static OSMWithTags zooPlatform() { + public static OsmWithTags zooPlatform() { // https://www.openstreetmap.org/way/119108622 - var way = new OSMWithTags(); + var way = new OsmWithTags(); way.addTag("public_transport", "platform"); way.addTag("usage", "tourism"); return way; } + + public static OsmWithTags indoor(String value) { + var way = new OsmWithTags(); + way.addTag("indoor", value); + return way; + } + + public static OsmWithTags parkAndRide() { + var way = new OsmWithTags(); + way.addTag("amenity", "parking"); + way.addTag("park_ride", "yes"); + way.addTag("capacity", "10"); + return way; + } } diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/RaptorTestConstants.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/RaptorTestConstants.java new file mode 100644 index 00000000000..88a6b97bb75 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/RaptorTestConstants.java @@ -0,0 +1,92 @@ +package org.opentripplanner.raptorlegacy._data; + +import static org.opentripplanner.utils.time.DurationUtils.durationInSeconds; +import static org.opentripplanner.utils.time.TimeUtils.hm2time; + +import org.opentripplanner.raptor.spi.DefaultSlackProvider; +import org.opentripplanner.raptor.spi.RaptorSlackProvider; + +/** + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated +public interface RaptorTestConstants { + // Time duration(D) constants, all values are in seconds + int D0s = 0; + int D1s = 1; + int D10s = 10; + int D11s = 11; + int D20s = 20; + int D30s = 30; + int D40s = 40; + int D1m = durationInSeconds("1m"); + int D2m = durationInSeconds("2m"); + int D3m = durationInSeconds("3m"); + int D4m = durationInSeconds("4m"); + int D5m = durationInSeconds("5m"); + int D7m = durationInSeconds("7m"); + int D8m = durationInSeconds("8m"); + int D10m = durationInSeconds("10m"); + int D11m = durationInSeconds("11m"); + int D20m = durationInSeconds("20m"); + int D24h = durationInSeconds("24h"); + + /** + * There are 86400 seconds in a "normal" day(24 * 60 * 60). + */ + int SECONDS_IN_A_DAY = (int) D24h; + + // Time constants, all values are in seconds + int T00_00 = hm2time(0, 0); + int T00_02 = hm2time(0, 2); + int T00_10 = hm2time(0, 10); + int T00_30 = hm2time(0, 30); + int T00_40 = hm2time(0, 40); + int T01_00 = hm2time(1, 0); + + int TX_0 = 0; + int TX_1 = 1; + int TX_2 = 2; + + // Stop indexes - Note! There is no stop defined for index 0(zero)! You must + // account for that in the test if you use the stop index. + int STOP_A = 1; + int STOP_B = 2; + int STOP_C = 3; + int STOP_D = 4; + int STOP_E = 5; + int STOP_F = 6; + int STOP_G = 7; + int STOP_H = 8; + int STOP_I = 9; + int STOP_J = 10; + int STOP_K = 11; + int STOP_L = 12; + int STOP_M = 13; + + int NUM_STOPS = 14; + + // Stop position in pattern + int STOP_POS_0 = 0; + int STOP_POS_1 = 1; + + // Slack + int BOARD_SLACK = 45; + int ALIGHT_SLACK = 15; + int TRANSFER_SLACK = 60; + + RaptorSlackProvider SLACK_PROVIDER = new DefaultSlackProvider( + TRANSFER_SLACK, + BOARD_SLACK, + ALIGHT_SLACK + ); + + // FLEX + int ONE_RIDE = 1; + int TWO_RIDES = 2; + + default String stopIndexToName(int index) { + return Character.toString('A' + index - 1); + } +} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/PathUtils.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/PathUtils.java new file mode 100644 index 00000000000..15e16217fa2 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/PathUtils.java @@ -0,0 +1,61 @@ +package org.opentripplanner.raptorlegacy._data.api; + +import java.util.Collection; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.opentripplanner.raptor.api.path.RaptorPath; +import org.opentripplanner.raptor.api.response.RaptorResponse; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; + +/** + * This utility help converting a Raptor path to a string which is used in several unit tests for + * easy comparison. The Stop index(1..n) is translated to stop names(A..N) using {@link + * RaptorTestConstants#stopIndexToName(int)}. + * + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated +public class PathUtils { + + private static final RaptorTestConstants TRANSLATOR = new RaptorTestConstants() {}; + + /** Util class, private constructor */ + private PathUtils() {} + + public static String pathsToString(RaptorResponse response) { + return pathsToString(response.paths()); + } + + public static String pathsToString(Collection> paths) { + return pathsToString(paths, p -> p.toString(TRANSLATOR::stopIndexToName)); + } + + public static String pathsToStringDetailed(RaptorResponse response) { + return pathsToStringDetailed(response.paths()); + } + + public static String pathsToStringDetailed(Collection> paths) { + return pathsToString(paths, p -> p.toStringDetailed(TRANSLATOR::stopIndexToName)); + } + + public static String join(String... paths) { + return String.join("\n", paths); + } + + public static String withoutCost(String path) { + return path.replaceAll(" C₁[\\d_]+", ""); + } + + public static String[] withoutCost(String... paths) { + return Stream.of(paths).map(path -> withoutCost(path)).toList().toArray(new String[0]); + } + + public static String pathsToString( + Collection> paths, + Function, String> mapToStr + ) { + return paths.stream().sorted().map(mapToStr).collect(Collectors.joining("\n")); + } +} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/TestPathBuilder.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/TestPathBuilder.java new file mode 100644 index 00000000000..a7fe2f9f3c8 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/TestPathBuilder.java @@ -0,0 +1,157 @@ +package org.opentripplanner.raptorlegacy._data.api; + +import static org.opentripplanner.raptor.rangeraptor.transit.TripTimesSearch.findTripTimes; + +import javax.annotation.Nullable; +import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; +import org.opentripplanner.raptor.api.path.RaptorPath; +import org.opentripplanner.raptor.path.PathBuilder; +import org.opentripplanner.raptor.spi.DefaultSlackProvider; +import org.opentripplanner.raptor.spi.RaptorCostCalculator; +import org.opentripplanner.raptor.spi.RaptorSlackProvider; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; +import org.opentripplanner.raptorlegacy._data.transit.TestAccessEgress; +import org.opentripplanner.raptorlegacy._data.transit.TestTransfer; +import org.opentripplanner.raptorlegacy._data.transit.TestTripPattern; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; + +/** + * Utility to help build paths for testing. The path builder is "reusable", every time the {@code + * access(...)} methods are called the builder reset it self. + *

    + * If the {@code costCalculator} is null, paths will not include cost. + * + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated +public class TestPathBuilder implements RaptorTestConstants { + + private static final int BOARD_ALIGHT_OFFSET = 30; + + @Nullable + private final RaptorCostCalculator costCalculator; + + private final RaptorSlackProvider slackProvider; + private PathBuilder builder; + private int startTime; + private int c2 = RaptorConstants.NOT_SET; + + public TestPathBuilder( + RaptorSlackProvider slackProvider, + @Nullable RaptorCostCalculator costCalculator + ) { + this.slackProvider = slackProvider; + this.costCalculator = costCalculator; + } + + /** + * Uses the slacks in {@link RaptorTestConstants}. + */ + public TestPathBuilder(@Nullable RaptorCostCalculator costCalculator) { + this(new DefaultSlackProvider(TRANSFER_SLACK, BOARD_SLACK, ALIGHT_SLACK), costCalculator); + } + + /** Assign c2 value for path. TODO: Add c2 value for each leg. */ + public TestPathBuilder c2(int c2) { + this.c2 = c2; + return this; + } + + /** + * Create access starting at the fixed given {@code starting}. Opening hours is used to enforce + * the access start time and prevent time-shifting it. + */ + public TestPathBuilder access(int startTime, int toStop, int duration) { + return access(startTime, TestAccessEgress.walk(toStop, duration)); + } + + /** Same as {@link #access(int, int, int)} , but with a free access - duration is 0s. */ + public TestPathBuilder access(int startTime, int toStop) { + return access(startTime, TestAccessEgress.free(toStop)); + } + + /** + * Create access with the given {@code startTime}, but allow the access to be time-shifted + * according to the opening hours of the given {@code transfer}. + */ + private TestPathBuilder access(int startTime, TestAccessEgress transfer) { + reset(startTime); + builder.access(transfer); + return this; + } + + public TestPathBuilder walk(int duration, int toStop) { + return walk(TestTransfer.transfer(toStop, duration)); + } + + public TestPathBuilder walk(int duration, int toStop, int cost) { + return walk(TestTransfer.transfer(toStop, duration, cost)); + } + + public TestPathBuilder walk(TestTransfer transfer) { + builder.transfer(transfer, transfer.stop()); + return this; + } + + public TestPathBuilder bus(TestTripSchedule trip, int alightStop) { + int boardStop = currentStop(); + // We use the startTime as earliest-board-time, this may cause problems for + // testing routes visiting the same stop more than once. Create a new factory + // method if this happens. + var baTime = findTripTimes(trip, boardStop, alightStop, startTime); + builder.transit(trip, baTime); + return this; + } + + public TestPathBuilder bus(String patternName, int fromTime, int duration, int toStop) { + int toTime = fromTime + duration; + int fromStop = currentStop(); + + TestTripSchedule trip = TestTripSchedule + .schedule(TestTripPattern.pattern(patternName, fromStop, toStop)) + .arrDepOffset(BOARD_ALIGHT_OFFSET) + .departures(fromTime, toTime + BOARD_ALIGHT_OFFSET) + .build(); + + return bus(trip, toStop); + } + + public RaptorPath egress(int duration) { + return egress( + duration == 0 + ? TestAccessEgress.free(currentStop()) + : TestAccessEgress.walk(currentStop(), duration) + ); + } + + public PathBuilder access(TestAccessEgress access) { + builder.access(access); + return builder; + } + + public RaptorPath egress(TestAccessEgress egress) { + builder.egress(egress); + builder.c2(c2); + return builder.build(); + } + + /* private methods */ + + int currentStop() { + return builder.tail().toStop(); + } + + private void reset(int startTime) { + this.startTime = startTime; + this.builder = + PathBuilder.tailPathBuilder( + slackProvider, + startTime, + costCalculator, + RaptorStopNameResolver.nullSafe(null), + null + ); + } +} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/TestPathBuilderTestRaptor.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/TestPathBuilderTestRaptor.java new file mode 100644 index 00000000000..e68bf7ad7cf --- /dev/null +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/TestPathBuilderTestRaptor.java @@ -0,0 +1,99 @@ +package org.opentripplanner.raptorlegacy._data.api; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.model.transfer.TransferConstraint.REGULAR_TRANSFER; +import static org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase.C1_CALCULATOR; +import static org.opentripplanner.utils.time.DurationUtils.durationInSeconds; +import static org.opentripplanner.utils.time.TimeUtils.time; + +import org.junit.jupiter.api.Test; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; +import org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase; +import org.opentripplanner.raptorlegacy._data.transit.TestAccessEgress; + +/** + * Test the PathBuilder to be sure that it works properly before using it in other tests. + * + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated +public class TestPathBuilderTestRaptor implements RaptorTestConstants { + + private final TestPathBuilder subject = new TestPathBuilder(C1_CALCULATOR); + + @Test + public void testSimplePathWithOneTransit() { + int transitDuration = durationInSeconds("5m"); + + var path = subject + .access(time("10:00:15"), STOP_A, D1m) + .bus("L1", time("10:02"), transitDuration, STOP_B) + .egress(D2m); + + var transitLeg = path.accessLeg().nextLeg().asTransitLeg(); + int boardCost = C1_CALCULATOR.boardingCost( + true, + path.accessLeg().toTime(), + STOP_A, + transitLeg.fromTime(), + transitLeg.trip(), + REGULAR_TRANSFER + ); + + int transitCost = C1_CALCULATOR.transitArrivalCost( + boardCost, + ALIGHT_SLACK, + transitDuration, + BasicPathTestCase.TRIP_1, + STOP_B + ); + + int accessEgressCost = C1_CALCULATOR.costEgress(TestAccessEgress.walk(STOP_B, D2m + D1m)); + + assertEquals(accessEgressCost + transitCost, path.c1()); + assertEquals( + "Walk 1m 10:00:15 10:01:15 C₁120 ~ A 45s " + + "~ BUS L1 10:02 10:07 5m C₁438 ~ B 15s " + + "~ Walk 2m 10:07:15 10:09:15 C₁210 " + + "[10:00:15 10:09:15 9m Tₓ0 C₁768]", + path.toStringDetailed(this::stopIndexToName) + ); + } + + @Test + public void testBasicPath() { + var path = subject + .c2(7) + .access(BasicPathTestCase.ACCESS_START, STOP_A, BasicPathTestCase.ACCESS_DURATION) + .bus( + BasicPathTestCase.LINE_11, + BasicPathTestCase.L11_START, + BasicPathTestCase.L11_DURATION, + STOP_B + ) + .walk(BasicPathTestCase.TX_DURATION, STOP_C, BasicPathTestCase.TX_C1) + .bus( + BasicPathTestCase.LINE_21, + BasicPathTestCase.L21_START, + BasicPathTestCase.L21_DURATION, + STOP_D + ) + .bus( + BasicPathTestCase.LINE_31, + BasicPathTestCase.L31_START, + BasicPathTestCase.L31_DURATION, + STOP_E + ) + .egress(BasicPathTestCase.EGRESS_DURATION); + + assertEquals(BasicPathTestCase.BASIC_PATH_AS_STRING, path.toString(this::stopIndexToName)); + assertEquals( + BasicPathTestCase.BASIC_PATH_AS_DETAILED_STRING, + path.toStringDetailed(this::stopIndexToName) + ); + assertEquals(BasicPathTestCase.TOTAL_C1, path.c1()); + assertTrue(path.isC2Set()); + } +} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/AbstractStopArrival.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/AbstractStopArrival.java new file mode 100644 index 00000000000..bb4edf3a6a7 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/AbstractStopArrival.java @@ -0,0 +1,85 @@ +package org.opentripplanner.raptorlegacy._data.stoparrival; + +import org.opentripplanner.raptor.api.view.ArrivalView; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; + +/** + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated +abstract class AbstractStopArrival implements ArrivalView { + + private final int round; + private final int stop; + private final int arrivalTime; + private final int c1; + private final int c2; + private final ArrivalView previous; + + AbstractStopArrival( + int round, + int stop, + int arrivalTime, + int extraCost, + int c2, + ArrivalView previous + ) { + this.round = round; + this.stop = stop; + this.arrivalTime = arrivalTime; + this.previous = previous; + this.c2 = c2; + + if (previous == null) { + this.c1 = extraCost; + } else { + this.c1 = previous.c1() + extraCost; + } + } + + AbstractStopArrival( + int round, + int stop, + int arrivalTime, + int extraCost, + ArrivalView previous + ) { + this(round, stop, arrivalTime, extraCost, previous.c2(), previous); + } + + @Override + public int stop() { + return stop; + } + + @Override + public int round() { + return round; + } + + @Override + public int arrivalTime() { + return arrivalTime; + } + + @Override + public int c1() { + return c1; + } + + @Override + public int c2() { + return c2; + } + + @Override + public ArrivalView previous() { + return previous; + } + + @Override + public String toString() { + return asString(); + } +} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Access.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Access.java new file mode 100644 index 00000000000..bb2fa1f481b --- /dev/null +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Access.java @@ -0,0 +1,37 @@ +package org.opentripplanner.raptorlegacy._data.stoparrival; + +import static org.opentripplanner.raptor.api.model.PathLegType.ACCESS; + +import org.opentripplanner.raptor.api.model.PathLegType; +import org.opentripplanner.raptor.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.view.AccessPathView; + +/** + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated +class Access extends AbstractStopArrival { + + private final RaptorAccessEgress access; + + Access(int stop, int arrivalTime, RaptorAccessEgress path, int c2) { + super(0, stop, arrivalTime, path.c1(), c2, null); + this.access = path; + } + + @Override + public PathLegType arrivedBy() { + return ACCESS; + } + + @Override + public AccessPathView accessPath() { + return () -> access; + } + + @Override + public boolean arrivedOnBoard() { + return access.stopReachedOnBoard(); + } +} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/BasicPathTestCase.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/BasicPathTestCase.java new file mode 100644 index 00000000000..0130625784b --- /dev/null +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/BasicPathTestCase.java @@ -0,0 +1,462 @@ +package org.opentripplanner.raptorlegacy._data.stoparrival; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.model.transfer.TransferConstraint.REGULAR_TRANSFER; +import static org.opentripplanner.raptor.api.model.RaptorCostConverter.toRaptorCost; +import static org.opentripplanner.utils.time.DurationUtils.durationToStr; +import static org.opentripplanner.utils.time.TimeUtils.time; + +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.opentripplanner.raptor.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.model.RaptorConstrainedTransfer; +import org.opentripplanner.raptor.api.model.RaptorTransfer; +import org.opentripplanner.raptor.api.path.AccessPathLeg; +import org.opentripplanner.raptor.api.path.EgressPathLeg; +import org.opentripplanner.raptor.api.path.PathLeg; +import org.opentripplanner.raptor.api.path.RaptorPath; +import org.opentripplanner.raptor.api.path.TransferPathLeg; +import org.opentripplanner.raptor.api.path.TransitPathLeg; +import org.opentripplanner.raptor.api.view.ArrivalView; +import org.opentripplanner.raptor.path.Path; +import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; +import org.opentripplanner.raptor.rangeraptor.lifecycle.LifeCycleSubscriptions; +import org.opentripplanner.raptor.rangeraptor.path.DestinationArrival; +import org.opentripplanner.raptor.spi.RaptorCostCalculator; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; +import org.opentripplanner.raptorlegacy._data.transit.TestAccessEgress; +import org.opentripplanner.raptorlegacy._data.transit.TestTransfer; +import org.opentripplanner.raptorlegacy._data.transit.TestTripPattern; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.DefaultCostCalculator; + +/** + * This class is used to create a journeys with stop arrivals. + *

    + * It creates different data structures representing the same 'basic' trip to be used in + * unit-tests: + *

    + *   ~
    + *   Origin 10:00:15
    + *   ~ Walk 3m ~ A
    + *   ~ BUS L11 10:04 10:35 ~ B
    + *   ~ Walk 3m45s ~ C
    + *   ~ BUS L21 11:00 11:23 ~ D
    + *   ~ BUS L31 11:40 11:52 ~ E
    + *   ~ Walk 7m45s
    + *   ~ Destination 12:00
    + *
    + *   Duration: 1h59m45s
    + *   Transfers: 2
    + *   Generalized-cost: $8154
    + * 
    + * The Trip has 2 transfers, 1 connected by walking and without. The trip start at 10:00 and ends at + * 12:00, total 2 hours. + * + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated +public class BasicPathTestCase implements RaptorTestConstants { + + private static final RaptorConstrainedTransfer EMPTY_CONSTRAINTS = null; + + public static final String BASIC_PATH_AS_DETAILED_STRING = + "Walk 3m 10:00:15 10:03:15 C₁360 " + + "~ A 45s ~ " + + "BUS L11 10:04 10:35 31m C₁1_998 " + + "~ B 15s ~ " + + "Walk 3m45s 10:35:15 10:39 C₁450 " + + "~ C 21m ~ " + + "BUS L21 11:00 11:23 23m C₁2_640 " + + "~ D 17m ~ " + + "BUS L31 11:40 11:52 12m C₁1_776 " + + "~ E 15s ~ " + + "Walk 7m45s 11:52:15 12:00 C₁930 " + + "[10:00:15 12:00 1h59m45s Tₓ2 C₁8_154 C₂7]"; + + public static final String BASIC_PATH_AS_STRING = + "Walk 3m ~ A" + + " ~ BUS L11 10:04 10:35 ~ B" + + " ~ Walk 3m45s ~ C" + + " ~ BUS L21 11:00 11:23 ~ D" + + " ~ BUS L31 11:40 11:52 ~ E" + + " ~ Walk 7m45s " + + "[10:00:15 12:00 1h59m45s Tₓ2 C₁8_154 C₂7]"; + + private static final int BOARD_C1_SEC = 60; + private static final int TRANSFER_C1_SEC = 120; + private static final double[] TRANSIT_RELUCTANCE = new double[] { 1.0 }; + public static final int TRANSIT_RELUCTANCE_INDEX = 0; + public static final double WAIT_RELUCTANCE = 0.8; + private static final int C2 = 7; + + /** Stop cost for stop NA, A, C, E .. H is zero(0), B: 30s, and D: 60s. ?=0, A=1 .. H=8 */ + private static final int[] STOP_C1S = { 0, 0, 3_000, 0, 6_000, 0, 0, 0, 0, 0 }; + + // Some times which should not have eny effect on tests + private static final int VERY_EARLY = time("00:00"); + private static final int VERY_LATE = time("23:59"); + + public static final int RAPTOR_ITERATION_START_TIME = time("09:00"); + + // Access (Walk 3m15s ~ A) + public static final int ACCESS_START = time("10:00:15"); + public static final int ACCESS_END = time("10:03:15"); + public static final int ACCESS_DURATION = ACCESS_END - ACCESS_START; + public static final RaptorAccessEgress ACCESS_TRANSFER = TestAccessEgress.walk( + STOP_A, + ACCESS_DURATION + ); + public static final int ACCESS_C1 = ACCESS_TRANSFER.c1(); + public static final int ACCESS_C2 = 0; + + // Trip 1 (A ~ BUS L11 10:04 10:35 ~ B) + public static final int L11_START = time("10:04"); + private static final int L11_END = time("10:35"); + public static final int L11_DURATION = L11_END - L11_START; + private static final int L11_WAIT_DURATION = L11_START - ACCESS_END + ALIGHT_SLACK; + public static final int LINE_11_C1 = + STOP_C1S[STOP_A] + + STOP_C1S[STOP_B] + + toRaptorCost(BOARD_C1_SEC + WAIT_RELUCTANCE * L11_WAIT_DURATION + L11_DURATION); + public static final int LINE_11_C2 = 2; + + // Transfers (B ~ Walk 3m45s ~ C) + private static final int TX_START = time("10:35:15"); + private static final int TX_END = time("10:39:00"); + public static final int TX_DURATION = TX_END - TX_START; + public static final RaptorTransfer TX_TRANSFER = TestTransfer.transfer(STOP_C, TX_DURATION); + public static final int TX_C1 = TX_TRANSFER.c1(); + public static final int TX_C3 = 3; + + // Trip 2 (C ~ BUS L21 11:00 11:23 ~ D) + public static final int L21_START = time("11:00"); + private static final int L21_END = time("11:23"); + public static final int L21_DURATION = L21_END - L21_START; + private static final int L21_WAIT_DURATION = L21_START - TX_END + ALIGHT_SLACK; + public static final int LINE_21_C1 = + STOP_C1S[STOP_C] + + STOP_C1S[STOP_D] + + toRaptorCost( + BOARD_C1_SEC + TRANSFER_C1_SEC + WAIT_RELUCTANCE * L21_WAIT_DURATION + L21_DURATION + ); + public static final int LINE_21_C2 = 5; + + // Trip 3 (D ~ BUS L31 11:40 11:52 ~ E) + public static final int L31_START = time("11:40"); + private static final int L31_END = time("11:52"); + public static final int L31_DURATION = L31_END - L31_START; + private static final int L31_WAIT_DURATION = L31_START - (L21_END + ALIGHT_SLACK) + ALIGHT_SLACK; + public static final int LINE_31_C1 = + STOP_C1S[STOP_D] + + STOP_C1S[STOP_E] + + toRaptorCost( + BOARD_C1_SEC + TRANSFER_C1_SEC + WAIT_RELUCTANCE * L31_WAIT_DURATION + L31_DURATION + ); + public static final int LINE_31_C2 = 6; + + // Egress (E ~ Walk 7m45s ~ ) + public static final int EGRESS_START = time("11:52:15"); + public static final int EGRESS_END = time("12:00"); + public static final int EGRESS_DURATION = EGRESS_END - EGRESS_START; + public static final RaptorAccessEgress EGRESS_TRANSFER = TestAccessEgress.walk( + STOP_E, + EGRESS_DURATION + ); + public static final int EGRESS_C1 = EGRESS_TRANSFER.c1(); + public static final int EGRESS_C2 = 7; + + public static final int TRIP_DURATION = EGRESS_END - ACCESS_START; + + private static final RaptorAccessEgress ACCESS = TestAccessEgress.walk( + STOP_A, + ACCESS_DURATION, + ACCESS_C1 + ); + private static final RaptorAccessEgress EGRESS = TestAccessEgress.walk( + STOP_E, + EGRESS_DURATION, + EGRESS_C1 + ); + // this is of course not a real flex egress + private static final RaptorAccessEgress FLEX = TestAccessEgress.flexWithOnBoard( + STOP_E, + EGRESS_DURATION, + EGRESS_C1 + ); + + public static final String LINE_11 = "L11"; + public static final String LINE_21 = "L21"; + public static final String LINE_31 = "L31"; + + public static final TestTripSchedule TRIP_1 = TestTripSchedule + .schedule(TestTripPattern.pattern(LINE_11, STOP_A, STOP_B)) + .times(L11_START, L11_END) + .transitReluctanceIndex(TRANSIT_RELUCTANCE_INDEX) + .build(); + + public static final TestTripSchedule TRIP_2 = TestTripSchedule + .schedule(TestTripPattern.pattern(LINE_21, STOP_C, STOP_D)) + .times(L21_START, L21_END) + .transitReluctanceIndex(TRANSIT_RELUCTANCE_INDEX) + .build(); + + public static final TestTripSchedule TRIP_3 = TestTripSchedule + .schedule(TestTripPattern.pattern(LINE_31, STOP_D, STOP_E)) + // The early arrival and late departure should not have any effect on tests + .arrivals(VERY_EARLY, L31_END) + .departures(L31_START, VERY_LATE) + .transitReluctanceIndex(TRANSIT_RELUCTANCE_INDEX) + .build(); + + public static final RaptorCostCalculator C1_CALCULATOR = new DefaultCostCalculator<>( + BOARD_C1_SEC, + TRANSFER_C1_SEC, + WAIT_RELUCTANCE, + TRANSIT_RELUCTANCE, + STOP_C1S + ); + + public static final int TOTAL_C1 = + ACCESS_C1 + LINE_11_C1 + TX_C1 + LINE_21_C1 + LINE_31_C1 + EGRESS_C1; + + /** Wait time between trip L11 and L21 including slack */ + public static final int WAIT_TIME_L11_L21 = L21_START - L11_END - TX_DURATION; + + /** Wait time between trip L21 and L31 including slack */ + public static final int WAIT_TIME_L21_L31 = L31_START - L21_END; + + public static WorkerLifeCycle lifeCycle() { + return new LifeCycleSubscriptions(); + } + + public static DestinationArrival basicTripByForwardSearch() { + ArrivalView prevArrival, egress; + prevArrival = TestArrivals.access(STOP_A, ACCESS_START, ACCESS_END, ACCESS_C1, ACCESS_C2); + prevArrival = TestArrivals.bus(1, STOP_B, L11_END, LINE_11_C1, LINE_11_C2, TRIP_1, prevArrival); + prevArrival = TestArrivals.transfer(1, STOP_C, TX_START, TX_END, TX_C1, prevArrival); + prevArrival = TestArrivals.bus(2, STOP_D, L21_END, LINE_21_C1, LINE_21_C2, TRIP_2, prevArrival); + prevArrival = TestArrivals.bus(3, STOP_E, L31_END, LINE_31_C1, LINE_31_C2, TRIP_3, prevArrival); + egress = TestArrivals.egress(EGRESS_START, EGRESS_END, EGRESS_C1, EGRESS_C2, prevArrival); + return new DestinationArrival<>( + egress.egressPath().egress(), + egress.previous(), + egress.arrivalTime(), + egress.egressPath().egress().c1(), + egress.c2() + ); + } + + /** + * This is the same itinerary as {@link #basicTripByForwardSearch()}, as found by a reverse + * search: + */ + public static DestinationArrival basicTripByReverseSearch() { + ArrivalView nextArrival, egress; + nextArrival = TestArrivals.access(STOP_E, EGRESS_END, EGRESS_START, EGRESS_C1, EGRESS_C2); + // Board slack is subtracted from the arrival time to get the latest possible + nextArrival = + TestArrivals.bus(1, STOP_D, L31_START, LINE_31_C1, LINE_31_C2, TRIP_3, nextArrival); + nextArrival = + TestArrivals.bus(2, STOP_C, L21_START, LINE_21_C1, LINE_21_C2, TRIP_2, nextArrival); + nextArrival = TestArrivals.transfer(2, STOP_B, TX_END, TX_START, TX_C1, nextArrival); + nextArrival = + TestArrivals.bus(3, STOP_A, L11_START, LINE_11_C1, LINE_11_C2, TRIP_1, nextArrival); + egress = TestArrivals.egress(ACCESS_END, ACCESS_START, ACCESS_C1, ACCESS_C2, nextArrival); + return new DestinationArrival<>( + egress.egressPath().egress(), + egress.previous(), + egress.arrivalTime(), + egress.egressPath().egress().c1(), + egress.c2() + ); + } + + /** + * Both {@link #basicTripByForwardSearch()} and {@link #basicTripByReverseSearch()} should return + * the same trip, here returned as a path. + */ + public static RaptorPath basicTripAsPath() { + PathLeg leg6 = new EgressPathLeg<>( + EGRESS, + EGRESS_START, + EGRESS_END, + EGRESS_C1 + ); + TransitPathLeg leg5 = new TransitPathLeg<>( + TRIP_3, + L31_START, + L31_END, + TRIP_3.findDepartureStopPosition(L31_START, STOP_D), + TRIP_3.findArrivalStopPosition(L31_END, STOP_E), + EMPTY_CONSTRAINTS, + LINE_31_C1, + leg6 + ); + TransitPathLeg leg4 = new TransitPathLeg<>( + TRIP_2, + L21_START, + L21_END, + TRIP_2.findDepartureStopPosition(L21_START, STOP_C), + TRIP_2.findArrivalStopPosition(L21_END, STOP_D), + EMPTY_CONSTRAINTS, + LINE_21_C1, + leg5 + ); + var transfer = TestTransfer.transfer(STOP_C, TX_END - TX_START); + PathLeg leg3 = new TransferPathLeg<>( + STOP_B, + TX_START, + TX_END, + transfer.c1(), + transfer, + leg4.asTransitLeg() + ); + var leg2 = new TransitPathLeg<>( + TRIP_1, + L11_START, + L11_END, + TRIP_1.findDepartureStopPosition(L11_START, STOP_A), + TRIP_1.findArrivalStopPosition(L11_END, STOP_B), + EMPTY_CONSTRAINTS, + LINE_11_C1, + leg3 + ); + AccessPathLeg leg1 = new AccessPathLeg<>( + ACCESS, + ACCESS_START, + ACCESS_END, + ACCESS_C1, + leg2.asTransitLeg() + ); + return new Path<>(RAPTOR_ITERATION_START_TIME, leg1, TOTAL_C1, 7); + } + + public static RaptorPath flexTripAsPath() { + PathLeg leg6 = new EgressPathLeg<>(FLEX, EGRESS_START, EGRESS_END, EGRESS_C1); + var transfer = TestTransfer.transfer(STOP_E, TX_END - TX_START); + PathLeg leg3 = new TransferPathLeg<>( + STOP_B, + TX_START, + TX_END, + transfer.c1(), + transfer, + leg6 + ); + var leg2 = new TransitPathLeg<>( + TRIP_1, + L11_START, + L11_END, + TRIP_1.findDepartureStopPosition(L11_START, STOP_A), + TRIP_1.findArrivalStopPosition(L11_END, STOP_B), + EMPTY_CONSTRAINTS, + LINE_11_C1, + leg3 + ); + AccessPathLeg leg1 = new AccessPathLeg<>( + ACCESS, + ACCESS_START, + ACCESS_END, + ACCESS_C1, + leg2.asTransitLeg() + ); + return new Path<>(RAPTOR_ITERATION_START_TIME, leg1, TOTAL_C1, C2); + } + + public static List basicTripStops() { + return Arrays.asList(STOP_A, STOP_B, STOP_C, STOP_D, STOP_E); + } + + @Test + public void testSetup() { + // Assert test data is configured correct + assertEquals(ACCESS_END + BOARD_SLACK, L11_START); + assertEquals(BOARD_SLACK + ALIGHT_SLACK, L11_WAIT_DURATION); + assertEquals(L31_END + ALIGHT_SLACK, EGRESS_START); + assertEquals( + durationToStr(TRIP_DURATION), + durationToStr( + ACCESS_DURATION + + L11_DURATION + + L11_WAIT_DURATION + + TX_DURATION + + L21_DURATION + + L21_WAIT_DURATION + + L31_DURATION + + L31_WAIT_DURATION + + EGRESS_DURATION + ), + "Access: " + + durationToStr(ACCESS_DURATION) + + ", Line 11: " + + durationToStr(L11_DURATION) + + " (wait " + + durationToStr(L11_WAIT_DURATION) + + ")" + + ", Tx: " + + durationToStr(TX_DURATION) + + ", Line 21: " + + durationToStr(L21_DURATION) + + " (wait " + + durationToStr(L21_WAIT_DURATION) + + ")" + + ", Line 31: " + + durationToStr(L31_DURATION) + + " (wait " + + durationToStr(L31_WAIT_DURATION) + + ")" + + ", Egress: " + + durationToStr(EGRESS_DURATION) + ); + + // The calculator is not under test here, so we assert everything is as expected + assertEquals( + LINE_11_C1, + transitArrivalCost(ACCESS_END, TRIP_1, STOP_A, L11_START, STOP_B, L11_END) + ); + assertEquals( + LINE_21_C1, + transitArrivalCost(TX_END, TRIP_2, STOP_C, L21_START, STOP_D, L21_END) + ); + assertEquals( + LINE_31_C1, + transitArrivalCost(L21_END + ALIGHT_SLACK, TRIP_3, STOP_D, L31_START, STOP_E, L31_END) + ); + + assertEquals(BASIC_PATH_AS_STRING, basicTripAsPath().toString(this::stopIndexToName)); + + assertEquals( + BASIC_PATH_AS_DETAILED_STRING, + basicTripAsPath().toStringDetailed(this::stopIndexToName) + ); + } + + private static int transitArrivalCost( + int prevArrivalTime, + TestTripSchedule trip, + int boardStop, + int boardTime, + int alightStop, + int alightTime + ) { + boolean firstTransit = TRIP_1 == trip; + int boardCost = C1_CALCULATOR.boardingCost( + firstTransit, + prevArrivalTime, + boardStop, + boardTime, + trip, + REGULAR_TRANSFER + ); + + return C1_CALCULATOR.transitArrivalCost( + boardCost, + ALIGHT_SLACK, + alightTime - boardTime, + trip, + alightStop + ); + } +} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Egress.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Egress.java new file mode 100644 index 00000000000..9b781b0beb0 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Egress.java @@ -0,0 +1,54 @@ +package org.opentripplanner.raptorlegacy._data.stoparrival; + +import org.opentripplanner.raptor.api.model.PathLegType; +import org.opentripplanner.raptor.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.view.ArrivalView; +import org.opentripplanner.raptor.api.view.EgressPathView; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; +import org.opentripplanner.utils.time.TimeUtils; + +/** + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated +public class Egress extends AbstractStopArrival { + + private final RaptorAccessEgress egressPath; + + public Egress( + int arrivalTime, + RaptorAccessEgress egressPath, + int c2, + ArrivalView previous + ) { + super(previous.round(), previous.stop(), arrivalTime, egressPath.c1(), c2, previous); + this.egressPath = egressPath; + } + + @Override + public EgressPathView egressPath() { + return () -> egressPath; + } + + @Override + public String toString() { + return String.format( + "Egress { round: %d, stop: %d, arrival-time: %s $%d }", + round(), + stop(), + TimeUtils.timeToStrCompact(arrivalTime()), + c1() + ); + } + + @Override + public PathLegType arrivedBy() { + return PathLegType.EGRESS; + } + + @Override + public boolean arrivedOnBoard() { + return egressPath.stopReachedOnBoard(); + } +} diff --git a/src/test/java/org/opentripplanner/raptor/_data/stoparrival/FlexAccessAndEgressPathTestCase.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/FlexAccessAndEgressPathTestCase.java similarity index 89% rename from src/test/java/org/opentripplanner/raptor/_data/stoparrival/FlexAccessAndEgressPathTestCase.java rename to application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/FlexAccessAndEgressPathTestCase.java index 1e694e3d771..99dd81ebbb7 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/stoparrival/FlexAccessAndEgressPathTestCase.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/FlexAccessAndEgressPathTestCase.java @@ -1,29 +1,27 @@ -package org.opentripplanner.raptor._data.stoparrival; +package org.opentripplanner.raptorlegacy._data.stoparrival; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.time.DurationUtils.durationInSeconds; -import static org.opentripplanner.framework.time.TimeUtils.time; -import static org.opentripplanner.raptor._data.stoparrival.TestArrivals.access; -import static org.opentripplanner.raptor._data.stoparrival.TestArrivals.bus; +import static org.opentripplanner.raptor.api.model.RaptorCostConverter.toRaptorCost; import static org.opentripplanner.raptor.api.model.RaptorValueFormatter.formatC1; -import static org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter.toRaptorCost; +import static org.opentripplanner.utils.time.DurationUtils.durationInSeconds; +import static org.opentripplanner.utils.time.TimeUtils.time; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.TimeUtils; -import org.opentripplanner.raptor._data.RaptorTestConstants; -import org.opentripplanner.raptor._data.transit.TestAccessEgress; -import org.opentripplanner.raptor._data.transit.TestTransfer; -import org.opentripplanner.raptor._data.transit.TestTripPattern; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.view.ArrivalView; import org.opentripplanner.raptor.rangeraptor.path.DestinationArrival; import org.opentripplanner.raptor.spi.DefaultSlackProvider; import org.opentripplanner.raptor.spi.RaptorSlackProvider; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; +import org.opentripplanner.raptorlegacy._data.transit.TestAccessEgress; +import org.opentripplanner.raptorlegacy._data.transit.TestTransfer; +import org.opentripplanner.raptorlegacy._data.transit.TestTripPattern; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.DefaultCostCalculator; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; +import org.opentripplanner.utils.time.TimeUtils; /** * This test case construct two Raptor paths for forward and reverse search, with and without @@ -44,7 +42,11 @@ *
  • Walk transfer
  • *
  • Flex
  • * + * + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. */ +@Deprecated public class FlexAccessAndEgressPathTestCase implements RaptorTestConstants { private static final int ZERO = 0; @@ -292,19 +294,19 @@ private static DestinationArrival flexForwardSearch( if (LINE_A.equals(line)) { // The latest time the access can arrive is the same as the TX1 arrival time in case B arrivalTime = accessPath.latestArrivalTime(TX1_END); - prevArrival = access(accessPath.stop(), arrivalTime, accessPath); + prevArrival = TestArrivals.access(accessPath.stop(), arrivalTime, accessPath); int waitCost = costL1ForwardIncWait(prevArrival.arrivalTime()); - prevArrival = bus(2, STOP_D, L1_STOP_ARR_TIME, waitCost, 0, TRIP_A, prevArrival); + prevArrival = TestArrivals.bus(2, STOP_D, L1_STOP_ARR_TIME, waitCost, 0, TRIP_A, prevArrival); } else { arrivalTime = accessPath.latestArrivalTime(TX1_START); - prevArrival = access(accessPath.stop(), arrivalTime, accessPath); + prevArrival = TestArrivals.access(accessPath.stop(), arrivalTime, accessPath); int timeShift = TX1_START - prevArrival.arrivalTime(); prevArrival = new Transfer(1, TX1_END - timeShift, TX1_TRANSFER, prevArrival); int waitCost = costL1ForwardIncWait(prevArrival.arrivalTime()); - prevArrival = bus(2, STOP_C, L1_STOP_ARR_TIME, waitCost, 0, TRIP_B, prevArrival); + prevArrival = TestArrivals.bus(2, STOP_C, L1_STOP_ARR_TIME, waitCost, 0, TRIP_B, prevArrival); prevArrival = new Transfer(2, TX2_END, TX2_TRANSFER, prevArrival); } @@ -338,18 +340,18 @@ private static DestinationArrival flexReverseSearch( if (LINE_A.equals(line)) { arrivalTime = L1_END + ALIGHT_SLACK + TRANSFER_SLACK; arrivalTime = egressPath.earliestDepartureTime(arrivalTime); - prevArrival = access(egressPath.stop(), arrivalTime, egressPath); + prevArrival = TestArrivals.access(egressPath.stop(), arrivalTime, egressPath); cost = costL1ReverseIncWait(prevArrival.arrivalTime()); - prevArrival = bus(2, STOP_A, L1_STOP_ARR_TIME_REV, cost, 0, TRIP_A, prevArrival); + prevArrival = TestArrivals.bus(2, STOP_A, L1_STOP_ARR_TIME_REV, cost, 0, TRIP_A, prevArrival); } else { arrivalTime = L1_END + ALIGHT_SLACK + TX2_DURATION + TRANSFER_SLACK; arrivalTime = egressPath.earliestDepartureTime(arrivalTime); - prevArrival = access(egressPath.stop(), arrivalTime, egressPath); + prevArrival = TestArrivals.access(egressPath.stop(), arrivalTime, egressPath); arrivalTime = prevArrival.arrivalTime() - TX2_DURATION; prevArrival = new Transfer(1, arrivalTime, TX2_TRANSFER_REV, prevArrival); cost = costL1ReverseIncWait(prevArrival.arrivalTime()); - prevArrival = bus(2, STOP_B, L1_STOP_ARR_TIME_REV, cost, 0, TRIP_B, prevArrival); + prevArrival = TestArrivals.bus(2, STOP_B, L1_STOP_ARR_TIME_REV, cost, 0, TRIP_B, prevArrival); arrivalTime = prevArrival.arrivalTime() - TX1_DURATION; prevArrival = new Transfer(2, arrivalTime, TX1_TRANSFER_REV, prevArrival); } diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/TestArrivals.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/TestArrivals.java new file mode 100644 index 00000000000..4ea0398efa4 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/TestArrivals.java @@ -0,0 +1,110 @@ +package org.opentripplanner.raptorlegacy._data.stoparrival; + +import org.opentripplanner.raptor.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorTransfer; +import org.opentripplanner.raptor.api.view.ArrivalView; +import org.opentripplanner.raptorlegacy._data.transit.TestAccessEgress; +import org.opentripplanner.raptorlegacy._data.transit.TestTransfer; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; + +/** + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated +public class TestArrivals { + + public static ArrivalView access( + int stop, + int arrivalTime, + RaptorAccessEgress path, + int c2 + ) { + return new Access(stop, arrivalTime, path, c2); + } + + public static ArrivalView access( + int stop, + int arrivalTime, + RaptorAccessEgress path + ) { + return access(stop, arrivalTime, path, RaptorConstants.NOT_SET); + } + + public static ArrivalView access( + int stop, + int departureTime, + int arrivalTime, + int c1, + int c2 + ) { + return access( + stop, + arrivalTime, + TestAccessEgress.walk(stop, Math.abs(arrivalTime - departureTime), c1), + c2 + ); + } + + public static ArrivalView access( + int stop, + int departureTime, + int arrivalTime, + int c1 + ) { + return access(stop, departureTime, arrivalTime, c1, RaptorConstants.NOT_SET); + } + + public static ArrivalView transfer( + int round, + int arrivalTime, + RaptorTransfer transfer, + ArrivalView previous + ) { + return new Transfer(round, arrivalTime, transfer, previous); + } + + public static ArrivalView transfer( + int round, + int stop, + int departureTime, + int arrivalTime, + int extraCost, + ArrivalView previous + ) { + return transfer( + round, + arrivalTime, + TestTransfer.transfer(stop, Math.abs(arrivalTime - departureTime), extraCost), + previous + ); + } + + public static ArrivalView bus( + int round, + int stop, + int arrivalTime, + int c1, + int c2, + TestTripSchedule trip, + ArrivalView previous + ) { + return new Transit(round, stop, arrivalTime, c1, c2, trip, previous); + } + + public static ArrivalView egress( + int departureTime, + int arrivalTime, + int c1, + int c2, + ArrivalView previous + ) { + return new Egress( + departureTime, + TestAccessEgress.walk(previous.stop(), Math.abs(arrivalTime - departureTime), c1), + c2, + previous + ); + } +} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Transfer.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Transfer.java new file mode 100644 index 00000000000..56363c4fdde --- /dev/null +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Transfer.java @@ -0,0 +1,43 @@ +package org.opentripplanner.raptorlegacy._data.stoparrival; + +import static org.opentripplanner.raptor.api.model.PathLegType.TRANSFER; + +import org.opentripplanner.raptor.api.model.PathLegType; +import org.opentripplanner.raptor.api.model.RaptorTransfer; +import org.opentripplanner.raptor.api.view.ArrivalView; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; + +/* + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated +class Transfer extends AbstractStopArrival { + + private final RaptorTransfer transfer; + + Transfer( + int round, + int arrivalTime, + RaptorTransfer transfer, + ArrivalView previous + ) { + super(round, transfer.stop(), arrivalTime, transfer.c1(), previous.c2(), previous); + this.transfer = transfer; + } + + @Override + public PathLegType arrivedBy() { + return TRANSFER; + } + + @Override + public RaptorTransfer transfer() { + return transfer; + } + + @Override + public boolean arrivedOnBoard() { + return false; + } +} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Transit.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Transit.java new file mode 100644 index 00000000000..5de1cdbd4dc --- /dev/null +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Transit.java @@ -0,0 +1,57 @@ +package org.opentripplanner.raptorlegacy._data.stoparrival; + +import static org.opentripplanner.raptor.api.model.PathLegType.TRANSIT; + +import org.opentripplanner.raptor.api.model.PathLegType; +import org.opentripplanner.raptor.api.view.ArrivalView; +import org.opentripplanner.raptor.api.view.TransitPathView; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; + +/** + * + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated +class Transit extends AbstractStopArrival implements TransitPathView { + + private final TestTripSchedule trip; + + Transit( + int round, + int stop, + int arrivalTime, + int c1, + int c2, + TestTripSchedule trip, + ArrivalView previous + ) { + super(round, stop, arrivalTime, c1, c2, previous); + this.trip = trip; + } + + @Override + public PathLegType arrivedBy() { + return TRANSIT; + } + + @Override + public TransitPathView transitPath() { + return this; + } + + @Override + public int boardStop() { + return previous().stop(); + } + + @Override + public TestTripSchedule trip() { + return trip; + } + + @Override + public boolean arrivedOnBoard() { + return true; + } +} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestAccessEgress.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestAccessEgress.java new file mode 100644 index 00000000000..6fb26c22dfb --- /dev/null +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestAccessEgress.java @@ -0,0 +1,365 @@ +package org.opentripplanner.raptorlegacy._data.transit; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.raptor.api.model.RaptorCostConverter.toRaptorCost; +import static org.opentripplanner.raptorlegacy._data.RaptorTestConstants.SECONDS_IN_A_DAY; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import org.opentripplanner.raptor.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.utils.time.TimeUtils; + +/** + * Simple implementation for {@link RaptorAccessEgress} for use in unit-tests. + * + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated +public class TestAccessEgress implements RaptorAccessEgress { + + public static final int DEFAULT_NUMBER_OF_RIDES = 0; + public static final boolean STOP_REACHED_ON_BOARD = true; + public static final boolean STOP_REACHED_ON_FOOT = false; + public static final double DEFAULT_WALK_RELUCTANCE = 2.0; + + private final int stop; + private final int durationInSeconds; + private final int c1; + private final int numberOfRides; + private final boolean stopReachedOnBoard; + private final boolean free; + private final Integer opening; + private final Integer closing; + private final boolean closed; + private final int timePenalty; + + private TestAccessEgress(Builder builder) { + this.stop = builder.stop; + this.durationInSeconds = builder.durationInSeconds; + this.numberOfRides = builder.numberOfRides; + this.stopReachedOnBoard = builder.stopReachedOnBoard; + this.free = builder.free; + this.opening = builder.opening; + this.closing = builder.closing; + this.closed = builder.closed; + this.timePenalty = builder.timePenalty; + this.c1 = builder.c1; + + if (free) { + assertEquals(0, durationInSeconds); + } else { + assertTrue(durationInSeconds > 0); + } + if (closed) { + assertNull(opening); + assertNull(closing); + } + assertTrue(numberOfRides >= 0); + } + + public static TestAccessEgress free(int stop) { + return new Builder(stop, 0).withFree().build(); + } + + /** + * @deprecated A stop cannot be both free and have a cost - This is not a valid + * access/egress. + */ + @Deprecated + public static TestAccessEgress free(int stop, int cost) { + return new Builder(stop, 0).withFree().withCost(cost).build(); + } + + public static TestAccessEgress walk(int stop, int durationInSeconds) { + return new Builder(stop, durationInSeconds).build(); + } + + public static TestAccessEgress walk(int stop, int durationInSeconds, double walkReluctance) { + return walk(stop, durationInSeconds, walkCost(durationInSeconds, walkReluctance)); + } + + public static TestAccessEgress walk(int stop, int durationInSeconds, int cost) { + return new Builder(stop, durationInSeconds).withCost(cost).build(); + } + + public static TestAccessEgress flexWithOnBoard(int stop, int durationInSeconds, int cost) { + return new Builder(stop, durationInSeconds) + .withCost(cost) + .withNRides(1) + .stopReachedOnBoard() + .build(); + } + + /** Create a new flex access and arrive stop onBoard with 1 ride/extra transfer. */ + public static TestAccessEgress flex(int stop, int durationInSeconds) { + return flex(stop, durationInSeconds, 1, walkCost(durationInSeconds)); + } + + /** Create a new flex access and arrive stop onBoard with 1 ride/extra transfer. */ + public static TestAccessEgress flex(int stop, int durationInSeconds, int nRides) { + return flex(stop, durationInSeconds, nRides, walkCost(durationInSeconds)); + } + + /** Create a new flex access and arrive stop onBoard. */ + public static TestAccessEgress flex(int stop, int durationInSeconds, int nRides, int cost) { + assert nRides > DEFAULT_NUMBER_OF_RIDES; + return new Builder(stop, durationInSeconds) + .stopReachedOnBoard() + .withNRides(nRides) + .withCost(cost) + .build(); + } + + /** Create a flex access arriving at given stop by walking with 1 ride/extra transfer. */ + public static TestAccessEgress flexAndWalk(int stop, int durationInSeconds) { + return flexAndWalk(stop, durationInSeconds, 1, walkCost(durationInSeconds)); + } + + /** Create a flex access arriving at given stop by walking with 1 ride/extra transfer. */ + public static TestAccessEgress flexAndWalk(int stop, int durationInSeconds, int nRides) { + return flexAndWalk(stop, durationInSeconds, nRides, walkCost(durationInSeconds)); + } + + /** Create a flex access arriving at given stop by walking. */ + public static TestAccessEgress flexAndWalk( + int stop, + int durationInSeconds, + int nRides, + int cost + ) { + assert nRides > DEFAULT_NUMBER_OF_RIDES; + return new Builder(stop, durationInSeconds).withNRides(nRides).withCost(cost).build(); + } + + public static Collection transfers(int... stopTimes) { + List legs = new ArrayList<>(); + for (int i = 0; i < stopTimes.length; i += 2) { + legs.add(walk(stopTimes[i], stopTimes[i + 1])); + } + return legs; + } + + public static int walkCost(int durationInSeconds) { + return walkCost(durationInSeconds, DEFAULT_WALK_RELUCTANCE); + } + + public static int walkCost(int durationInSeconds, double reluctance) { + return toRaptorCost(durationInSeconds * reluctance); + } + + /** + * Add opening and closing hours and return a new object. + *

    + * Opening and closing is specified as seconds since the start of "RAPTOR time" to limit the + * time periods that the access is traversable, which is repeatead every 24 hours. This allows + * access to only be traversable between given times like 08:00 and 16:00 every day. + */ + public TestAccessEgress openingHours(int opening, int closing) { + return copyOf().withOpeningHours(opening, closing).build(); + } + + /** Alias for {@code openingHours(TimeUtils.time(opening), TimeUtils.time(closing))} */ + public TestAccessEgress openingHours(String opening, String closing) { + return openingHours(TimeUtils.time(opening), TimeUtils.time(closing)); + } + + public TestAccessEgress openingHoursClosed() { + return copyOf().withClosed().build(); + } + + public TestAccessEgress withTimePenalty(int timePenalty) { + return this.copyOf().withTimePenalty(timePenalty).build(); + } + + public Builder copyOf() { + return new Builder(this); + } + + @Override + public int stop() { + return stop; + } + + @Override + public int c1() { + return c1; + } + + @Override + public int durationInSeconds() { + return durationInSeconds; + } + + @Override + public int timePenalty() { + return timePenalty; + } + + @Override + public int earliestDepartureTime(int requestedDepartureTime) { + if (!hasOpeningHours()) { + return requestedDepartureTime; + } + if (closed) { + return RaptorConstants.TIME_NOT_SET; + } + + int days = Math.floorDiv(requestedDepartureTime, SECONDS_IN_A_DAY); + int specificOpening = days * SECONDS_IN_A_DAY + opening; + int specificClosing = days * SECONDS_IN_A_DAY + closing; + + if (requestedDepartureTime < specificOpening) { + return specificOpening; + } else if (requestedDepartureTime > specificClosing) { + // return the opening time for the next day + return specificOpening + SECONDS_IN_A_DAY; + } + return requestedDepartureTime; + } + + @Override + public int latestArrivalTime(int requestedArrivalTime) { + if (!hasOpeningHours()) { + return requestedArrivalTime; + } + if (closed) { + return RaptorConstants.TIME_NOT_SET; + } + + // opening & closing is relative to the departure + int requestedDepartureTime = requestedArrivalTime - durationInSeconds(); + int days = Math.floorDiv(requestedDepartureTime, SECONDS_IN_A_DAY); + int specificOpening = days * SECONDS_IN_A_DAY + opening; + int specificClosing = days * SECONDS_IN_A_DAY + closing; + int closeAtArrival = specificClosing + durationInSeconds(); + + if (requestedDepartureTime < specificOpening) { + // return the closing for the previous day, offset with durationInSeconds() + return closeAtArrival - SECONDS_IN_A_DAY; + } else if (requestedArrivalTime > closeAtArrival) { + return closeAtArrival; + } + return requestedArrivalTime; + } + + @Override + public boolean hasOpeningHours() { + return closed || opening != null || closing != null; + } + + @Override + public int numberOfRides() { + return numberOfRides; + } + + @Override + public boolean stopReachedOnBoard() { + return stopReachedOnBoard; + } + + @Override + public boolean isFree() { + return this.free; + } + + @Override + public String toString() { + return asString(true, true, null); + } + + /** + * Do not use the builder, use the static factory methods. Only use the builder if you need to + * override the {@link TestAccessEgress class}. + */ + protected static class Builder { + + int stop; + int durationInSeconds; + int c1; + int numberOfRides = DEFAULT_NUMBER_OF_RIDES; + boolean stopReachedOnBoard = STOP_REACHED_ON_FOOT; + Integer opening = null; + Integer closing = null; + private boolean free = false; + private boolean closed = false; + private int timePenalty; + + Builder(int stop, int durationInSeconds) { + this.stop = stop; + this.durationInSeconds = durationInSeconds; + this.c1 = walkCost(durationInSeconds); + this.timePenalty = RaptorConstants.TIME_NOT_SET; + } + + Builder(TestAccessEgress original) { + this.free = original.free; + this.stop = original.stop; + this.durationInSeconds = original.durationInSeconds; + this.stopReachedOnBoard = original.stopReachedOnBoard; + this.c1 = original.c1; + this.numberOfRides = original.numberOfRides; + this.opening = original.opening; + this.closing = original.closing; + this.closed = original.closed; + this.timePenalty = original.timePenalty; + } + + Builder withFree() { + this.free = true; + this.durationInSeconds = 0; + return this; + } + + Builder withCost(int cost) { + this.c1 = cost; + return this; + } + + Builder withNRides(int numberOfRides) { + this.numberOfRides = numberOfRides; + return this; + } + + Builder stopReachedOnBoard() { + this.stopReachedOnBoard = STOP_REACHED_ON_BOARD; + return this; + } + + Builder withTimePenalty(int timePenalty) { + this.timePenalty = timePenalty; + return this; + } + + Builder withOpeningHours(int opening, int closing) { + if (opening > closing) { + throw new IllegalStateException( + "Must open before is close. Opens at " + + TimeUtils.timeToStrCompact(opening) + + " and close at " + + TimeUtils.timeToStrCompact(closing) + + "." + ); + } + this.closed = false; + this.opening = opening; + this.closing = closing; + return this; + } + + Builder withClosed() { + this.opening = null; + this.closing = null; + this.closed = true; + return this; + } + + TestAccessEgress build() { + return new TestAccessEgress(this); + } + } +} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestConstrainedBoardingSearch.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestConstrainedBoardingSearch.java new file mode 100644 index 00000000000..2766f760067 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestConstrainedBoardingSearch.java @@ -0,0 +1,128 @@ +package org.opentripplanner.raptorlegacy._data.transit; + +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.Collection; +import java.util.List; +import java.util.function.BiPredicate; +import java.util.stream.Collectors; +import javax.annotation.Nullable; +import org.opentripplanner.model.transfer.TransferConstraint; +import org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent; +import org.opentripplanner.raptor.spi.RaptorConstrainedBoardingSearch; +import org.opentripplanner.raptor.spi.RaptorTimeTable; +import org.opentripplanner.utils.tostring.ToStringBuilder; + +/** + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated +public class TestConstrainedBoardingSearch + implements RaptorConstrainedBoardingSearch { + + /** Index of guaranteed transfers by fromStopPos */ + private final TIntObjectMap> transfersByFromStopPos = new TIntObjectHashMap<>(); + private final BitSet transfersByToStopPosExist = new BitSet(); + private final BiPredicate timeAfterOrEqual; + private int currentTargetStopPos; + + TestConstrainedBoardingSearch(boolean forward) { + this.timeAfterOrEqual = forward ? (a, b) -> a >= b : (a, b) -> a <= b; + } + + @Override + public boolean transferExistTargetStop(int targetStopPos) { + this.currentTargetStopPos = targetStopPos; + return transfersByFromStopPos.containsKey(targetStopPos); + } + + @Override + public boolean transferExistSourceStop(int targetStopPos) { + // This is only used to check for + return transfersByToStopPosExist.get(targetStopPos); + } + + @Nullable + @Override + public RaptorBoardOrAlightEvent find( + RaptorTimeTable targetTimetable, + int transferSlack, + TestTripSchedule sourceTrip, + int sourceStopIndex, + int prevTransitArrivalTime, + int earliestBoardTime + ) { + var list = transfersByFromStopPos.get(currentTargetStopPos); + for (TestConstrainedTransfer tx : list) { + var trip = tx.getSourceTrip(); + if (trip == sourceTrip) { + int stopPos = trip.findDepartureStopPosition(prevTransitArrivalTime, sourceStopIndex); + boolean boardAlightPossible = timeAfterOrEqual.test(tx.getTime(), prevTransitArrivalTime); + if (tx.getSourceStopPos() == stopPos && boardAlightPossible) { + return tx.boardingEvent(tx.isFacilitated() ? prevTransitArrivalTime : earliestBoardTime); + } + } + } + return RaptorBoardOrAlightEvent.empty(earliestBoardTime); + } + + /** + * Return boardings as a result for constrained transfers like a guaranteed transfer. + */ + public List constrainedBoardings() { + return transfersByFromStopPos + .valueCollection() + .stream() + .flatMap(Collection::stream) + .collect(Collectors.toList()); + } + + @Override + public String toString() { + return ToStringBuilder + .of(TestConstrainedBoardingSearch.class) + .addNum("currentTargetStopPos", currentTargetStopPos) + .addObj("index", transfersByFromStopPos) + .toString(); + } + + /** + * The the {@code source/target} is the trips in order of the search direction (forward or + * reverse). For reverse search it is the opposite from {@code from/to} in the result path. + */ + void addConstraintTransfers( + TestTripSchedule sourceTrip, + int sourceStopPos, + TestTripSchedule targetTrip, + int targetTripIndex, + int targetStopPos, + int targetTime, + TransferConstraint constraint + ) { + List list = transfersByFromStopPos.get(targetStopPos); + if (list == null) { + list = new ArrayList<>(); + transfersByFromStopPos.put(targetStopPos, list); + } + list.add( + new TestConstrainedTransfer( + constraint, + sourceTrip, + sourceStopPos, + targetTrip, + targetTripIndex, + targetStopPos, + targetTime + ) + ); + transfersByToStopPosExist.set(sourceStopPos); + } + + void clear() { + transfersByFromStopPos.clear(); + transfersByToStopPosExist.clear(); + } +} diff --git a/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedTransfer.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestConstrainedTransfer.java similarity index 89% rename from src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedTransfer.java rename to application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestConstrainedTransfer.java index 66233e4eb74..034a029787d 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedTransfer.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestConstrainedTransfer.java @@ -1,13 +1,18 @@ -package org.opentripplanner.raptor._data.transit; +package org.opentripplanner.raptorlegacy._data.transit; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.transfer.TransferConstraint; import org.opentripplanner.raptor.api.model.RaptorConstrainedTransfer; import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; import org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent; import org.opentripplanner.routing.algorithm.raptoradapter.transit.constrainedtransfer.ConstrainedTransferBoarding; +import org.opentripplanner.utils.tostring.ToStringBuilder; +/** + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated class TestConstrainedTransfer implements RaptorConstrainedTransfer { private final TransferConstraint transferConstraints; diff --git a/src/test/java/org/opentripplanner/raptor/_data/transit/TestRoute.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestRoute.java similarity index 94% rename from src/test/java/org/opentripplanner/raptor/_data/transit/TestRoute.java rename to application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestRoute.java index c3029b9ebfd..715021521ef 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/transit/TestRoute.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestRoute.java @@ -1,9 +1,8 @@ -package org.opentripplanner.raptor._data.transit; +package org.opentripplanner.raptorlegacy._data.transit; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.transfer.TransferConstraint; import org.opentripplanner.raptor.api.model.SearchDirection; import org.opentripplanner.raptor.spi.RaptorConstrainedBoardingSearch; @@ -12,7 +11,13 @@ import org.opentripplanner.raptor.spi.RaptorTripScheduleSearch; import org.opentripplanner.routing.algorithm.raptoradapter.api.DefaultTripPattern; import org.opentripplanner.routing.algorithm.raptoradapter.transit.request.TripScheduleSearchFactory; +import org.opentripplanner.utils.tostring.ToStringBuilder; +/** + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated public class TestRoute implements RaptorRoute, RaptorTimeTable { private final TestTripPattern pattern; diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransfer.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransfer.java new file mode 100644 index 00000000000..dead63d0135 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransfer.java @@ -0,0 +1,52 @@ +package org.opentripplanner.raptorlegacy._data.transit; + +import static org.opentripplanner.raptor.api.model.RaptorCostConverter.toRaptorCost; + +import org.opentripplanner.raptor.api.model.RaptorTransfer; + +/** + * Simple implementation for {@link RaptorTransfer} for use in unit-tests. + * + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated +public record TestTransfer(int stop, int durationInSeconds, int cost) implements RaptorTransfer { + public static final double DEFAULT_WALK_RELUCTANCE = 2.0; + + public static TestTransfer transfer(int stop, int durationInSeconds) { + return new TestTransfer(stop, durationInSeconds, walkCost(durationInSeconds)); + } + + public static TestTransfer transfer(int stop, int durationInSeconds, int cost) { + return new TestTransfer(stop, durationInSeconds, cost); + } + + public static int walkCost(int durationInSeconds) { + return walkCost(durationInSeconds, DEFAULT_WALK_RELUCTANCE); + } + + public static int walkCost(int durationInSeconds, double reluctance) { + return toRaptorCost(durationInSeconds * reluctance); + } + + @Override + public int stop() { + return stop; + } + + @Override + public int c1() { + return cost; + } + + @Override + public int durationInSeconds() { + return durationInSeconds; + } + + @Override + public String toString() { + return asString(); + } +} diff --git a/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransferPoint.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransferPoint.java similarity index 80% rename from src/test/java/org/opentripplanner/raptor/_data/transit/TestTransferPoint.java rename to application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransferPoint.java index d3a0e4c3d4e..8c274f779d8 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransferPoint.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransferPoint.java @@ -1,8 +1,13 @@ -package org.opentripplanner.raptor._data.transit; +package org.opentripplanner.raptorlegacy._data.transit; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.transfer.TransferPoint; +import org.opentripplanner.utils.tostring.ToStringBuilder; +/** + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated public class TestTransferPoint implements TransferPoint { private final int stop; diff --git a/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransitData.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransitData.java similarity index 95% rename from src/test/java/org/opentripplanner/raptor/_data/transit/TestTransitData.java rename to application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransitData.java index 97ad09e3bfd..1cbf591c01d 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransitData.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransitData.java @@ -1,8 +1,8 @@ -package org.opentripplanner.raptor._data.transit; +package org.opentripplanner.raptorlegacy._data.transit; -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 static org.opentripplanner.raptorlegacy._data.transit.TestRoute.route; +import static org.opentripplanner.raptorlegacy._data.transit.TestTripPattern.pattern; +import static org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule.schedule; import java.util.ArrayList; import java.util.BitSet; @@ -10,15 +10,13 @@ import java.util.Iterator; import java.util.List; import java.util.Set; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.model.transfer.ConstrainedTransfer; import org.opentripplanner.model.transfer.TransferConstraint; -import org.opentripplanner.raptor._data.RaptorTestConstants; import org.opentripplanner.raptor.api.model.RaptorConstrainedTransfer; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTripPattern; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; import org.opentripplanner.raptor.rangeraptor.SystemErrDebugLogger; import org.opentripplanner.raptor.spi.DefaultSlackProvider; @@ -31,6 +29,7 @@ import org.opentripplanner.raptor.spi.RaptorTimeTable; import org.opentripplanner.raptor.spi.RaptorTransitDataProvider; import org.opentripplanner.raptor.util.BitSetIterator; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; import org.opentripplanner.routing.algorithm.raptoradapter.api.DefaultTripPattern; import org.opentripplanner.routing.algorithm.raptoradapter.transit.DefaultRaptorTransfer; import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.CostCalculatorFactory; @@ -39,6 +38,11 @@ import org.opentripplanner.routing.algorithm.transferoptimization.model.TripStopTime; import org.opentripplanner.routing.algorithm.transferoptimization.services.TransferServiceAdaptor; +/** + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated @SuppressWarnings("UnusedReturnValue") public class TestTransitData implements RaptorTransitDataProvider, RaptorTestConstants { @@ -151,7 +155,6 @@ public RaptorConstrainedTransfer findConstrainedTransfer( }; } - @Nonnull @Override public RaptorStopNameResolver stopNameResolver() { // Index is translated: 1->'A', 2->'B', 3->'C' ... diff --git a/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripPattern.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripPattern.java similarity index 93% rename from src/test/java/org/opentripplanner/raptor/_data/transit/TestTripPattern.java rename to application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripPattern.java index 63dcbeb5863..f6d9aace021 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripPattern.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripPattern.java @@ -1,9 +1,15 @@ -package org.opentripplanner.raptor._data.transit; +package org.opentripplanner.raptorlegacy._data.transit; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.algorithm.raptoradapter.api.DefaultTripPattern; import org.opentripplanner.transit.model.network.Route; - +import org.opentripplanner.utils.tostring.ToStringBuilder; + +/** + * + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated public class TestTripPattern implements DefaultTripPattern { public static final byte BOARDING_MASK = 0b0001; diff --git a/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripSchedule.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripSchedule.java similarity index 96% rename from src/test/java/org/opentripplanner/raptor/_data/transit/TestTripSchedule.java rename to application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripSchedule.java index ab8d26406ee..0ef437cb3d0 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripSchedule.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripSchedule.java @@ -1,26 +1,29 @@ -package org.opentripplanner.raptor._data.transit; +package org.opentripplanner.raptorlegacy._data.transit; import static org.opentripplanner.transit.model.basic.Accessibility.NO_INFORMATION; import java.time.LocalDate; import java.util.Arrays; import java.util.stream.IntStream; -import org.opentripplanner.framework.lang.IntUtils; -import org.opentripplanner.framework.time.TimeUtils; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.routing.algorithm.raptoradapter.api.DefaultTripPattern; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripSchedule; import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.utils.lang.IntUtils; +import org.opentripplanner.utils.time.TimeUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * An implementation of the {@link RaptorTripSchedule} for unit-testing. *

    * The {@link DefaultTripPattern} for this schedule return {@code stopIndex == stopPosInPattern + 1 } + * + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. */ -// TODO : This class should implement RaptorTripSchedule not raptoradapter TripSchedule +@Deprecated public class TestTripSchedule implements TripSchedule { private static final int DEFAULT_DEPARTURE_DELAY = 10; diff --git a/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripSearchTimetable.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripSearchTimetable.java similarity index 86% rename from src/test/java/org/opentripplanner/raptor/_data/transit/TestTripSearchTimetable.java rename to application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripSearchTimetable.java index 0785e20c241..a486492a2c6 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripSearchTimetable.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripSearchTimetable.java @@ -1,4 +1,4 @@ -package org.opentripplanner.raptor._data.transit; +package org.opentripplanner.raptorlegacy._data.transit; import java.util.function.IntUnaryOperator; import org.opentripplanner.raptor.api.model.SearchDirection; @@ -6,6 +6,12 @@ import org.opentripplanner.routing.algorithm.raptoradapter.transit.request.TripScheduleSearchFactory; import org.opentripplanner.routing.algorithm.raptoradapter.transit.request.TripSearchTimetable; +/** + * + * @deprecated This was earlier part of Raptor and should not be used outside the Raptor + * module. Use the OTP model entities instead. + */ +@Deprecated public class TestTripSearchTimetable implements TripSearchTimetable { private final TestTripSchedule[] trips; diff --git a/src/test/java/org/opentripplanner/routing/TestHalfEdges.java b/application/src/test/java/org/opentripplanner/routing/TestHalfEdges.java similarity index 95% rename from src/test/java/org/opentripplanner/routing/TestHalfEdges.java rename to application/src/test/java/org/opentripplanner/routing/TestHalfEdges.java index ba7e024e57a..dc473276c7b 100644 --- a/src/test/java/org/opentripplanner/routing/TestHalfEdges.java +++ b/application/src/test/java/org/opentripplanner/routing/TestHalfEdges.java @@ -48,27 +48,27 @@ import org.opentripplanner.street.search.request.StreetSearchRequestBuilder; import org.opentripplanner.street.search.state.State; import org.opentripplanner.street.search.strategy.EuclideanRemainingWeightHeuristic; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; public class TestHalfEdges { - private final TransitModelForTest testModel = TransitModelForTest.of(); + private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of(); private Graph graph; private StreetEdge top, bottom, left, right, leftBack, rightBack; private IntersectionVertex br, tr, bl, tl; private TransitStopVertex station1; private TransitStopVertex station2; - private TransitModel transitModel; + private TimetableRepository timetableRepository; @BeforeEach public void setUp() { var deduplicator = new Deduplicator(); graph = new Graph(deduplicator); - var stopModelBuilder = testModel.stopModelBuilder(); + var siteRepositoryBuilder = testModel.siteRepositoryBuilder(); var factory = new VertexFactory(graph); // a 0.1 degree x 0.1 degree square tl = factory.intersection("tl", -74.01, 40.01); @@ -161,8 +161,8 @@ public void setUp() { var s1 = testModel.stop("fleem station", 40.0099999, -74.005).build(); var s2 = testModel.stop("morx station", 40.0099999, -74.002).build(); - stopModelBuilder.withRegularStop(s1).withRegularStop(s2); - transitModel = new TransitModel(stopModelBuilder.build(), deduplicator); + siteRepositoryBuilder.withRegularStop(s1).withRegularStop(s2); + timetableRepository = new TimetableRepository(siteRepositoryBuilder.build(), deduplicator); station1 = factory.transitStop(TransitStopVertex.of().withStop(s1)); station2 = factory.transitStop(TransitStopVertex.of().withStop(s2)); @@ -172,8 +172,8 @@ public void setUp() { //Linkers aren't run otherwise in testNetworkLinker graph.hasStreets = true; - transitModel.index(); - graph.index(transitModel.getStopModel()); + timetableRepository.index(); + graph.index(timetableRepository.getSiteRepository()); } @Test @@ -595,14 +595,16 @@ public void testStreetSplittingAlerts() { @Test public void testStreetLocationFinder() { StreetIndex finder = graph.getStreetIndex(); - GraphFinder graphFinder = new DirectGraphFinder(transitModel.getStopModel()::findRegularStops); + GraphFinder graphFinder = new DirectGraphFinder( + timetableRepository.getSiteRepository()::findRegularStops + ); Set tempEdges = new HashSet<>(); // test that the local stop finder finds stops assertTrue(graphFinder.findClosestStops(new Coordinate(-74.005000001, 40.01), 100).size() > 0); // test that the closest vertex finder returns the closest vertex - TemporaryStreetLocation some = (TemporaryStreetLocation) finder.getVertexForLocationForTest( - new GenericLocation(40.00, -74.00), + TemporaryStreetLocation some = (TemporaryStreetLocation) finder.createVertexForCoordinateForTest( + new Coordinate(-74.00, 40.00), StreetMode.WALK, true, tempEdges @@ -610,8 +612,8 @@ public void testStreetLocationFinder() { assertNotNull(some); // test that the closest vertex finder correctly splits streets - TemporaryStreetLocation start = (TemporaryStreetLocation) finder.getVertexForLocationForTest( - new GenericLocation(40.004, -74.01), + TemporaryStreetLocation start = (TemporaryStreetLocation) finder.createVertexForCoordinateForTest( + new Coordinate(-74.01, 40.004), StreetMode.WALK, false, tempEdges @@ -625,8 +627,8 @@ public void testStreetLocationFinder() { Collection edges = start.getOutgoing(); assertEquals(2, edges.size()); - TemporaryStreetLocation end = (TemporaryStreetLocation) finder.getVertexForLocationForTest( - new GenericLocation(40.008, -74.0), + TemporaryStreetLocation end = (TemporaryStreetLocation) finder.createVertexForCoordinateForTest( + new Coordinate(-74.0, 40.008), StreetMode.BIKE, true, tempEdges @@ -648,7 +650,8 @@ public void testTemporaryVerticesContainer() { try ( var container = new TemporaryVerticesContainer( graph, - walking, + walking.from(), + walking.to(), StreetMode.WALK, StreetMode.WALK ) @@ -673,7 +676,7 @@ public void testTemporaryVerticesContainer() { @Test public void testNetworkLinker() { int numVerticesBefore = graph.getVertices().size(); - TestStreetLinkerModule.link(graph, transitModel); + TestStreetLinkerModule.link(graph, timetableRepository); int numVerticesAfter = graph.getVertices().size(); assertEquals(4, numVerticesAfter - numVerticesBefore); Collection outgoing = station1.getOutgoing(); diff --git a/src/test/java/org/opentripplanner/routing/alertpatch/EntitySelectorTest.java b/application/src/test/java/org/opentripplanner/routing/alertpatch/EntitySelectorTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/alertpatch/EntitySelectorTest.java rename to application/src/test/java/org/opentripplanner/routing/alertpatch/EntitySelectorTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/FilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/FilterTest.java similarity index 80% rename from src/test/java/org/opentripplanner/routing/algorithm/FilterTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/FilterTest.java index de40617d3d3..958bf97d41a 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/FilterTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/FilterTest.java @@ -2,7 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.util.Collection; import java.util.List; @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.routing.api.request.request.filter.SelectRequest; import org.opentripplanner.routing.api.request.request.filter.TransitFilterRequest; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.MainAndSubMode; import org.opentripplanner.transit.model.basic.SubMode; import org.opentripplanner.transit.model.basic.TransitMode; @@ -27,17 +27,17 @@ public class FilterTest { static final String AGENCY_ID_2 = "RUT:Agency:2"; static final String AGENCY_ID_3 = "RUT:Agency:3"; - static final Agency AGENCY_1 = TransitModelForTest + static final Agency AGENCY_1 = TimetableRepositoryForTest .agency("A") .copy() .withId(id(AGENCY_ID_1)) .build(); - static final Agency AGENCY_2 = TransitModelForTest + static final Agency AGENCY_2 = TimetableRepositoryForTest .agency("B") .copy() .withId(id(AGENCY_ID_2)) .build(); - static final Agency AGENCY_3 = TransitModelForTest + static final Agency AGENCY_3 = TimetableRepositoryForTest .agency("C") .copy() .withId(id(AGENCY_ID_3)) @@ -53,7 +53,7 @@ public class FilterTest { static final String JOURNEY_PATTERN_ID_3 = "RUT:JourneyPattern:3"; static final String JOURNEY_PATTERN_ID_4 = "RUT:JourneyPattern:4"; - static final StopPattern STOP_PATTERN = TransitModelForTest.of().stopPattern(2); + static final StopPattern STOP_PATTERN = TimetableRepositoryForTest.of().stopPattern(2); private static final SubMode LOCAL_BUS = SubMode.getOrBuildAndCacheForever("localBus"); private static final SubMode NIGHT_BUS = SubMode.getOrBuildAndCacheForever("nightBus"); @@ -61,10 +61,10 @@ public class FilterTest { final String GROUP_OF_Routes_ID_1 = "RUT:GroupOfLines:1"; final String GROUP_OF_Routes_ID_2 = "RUT:GroupOfLines:2"; - final GroupOfRoutes GROUP_OF_ROUTES_1 = TransitModelForTest + final GroupOfRoutes GROUP_OF_ROUTES_1 = TimetableRepositoryForTest .groupOfRoutes(GROUP_OF_Routes_ID_1) .build(); - final GroupOfRoutes GROUP_OF_ROUTES_2 = TransitModelForTest + final GroupOfRoutes GROUP_OF_ROUTES_2 = TimetableRepositoryForTest .groupOfRoutes(GROUP_OF_Routes_ID_2) .build(); @@ -83,20 +83,20 @@ public class FilterTest { """ ) public void testOne() { - Route route1 = TransitModelForTest.route(ROUTE_ID_1).withAgency(AGENCY_1).build(); - Route route2 = TransitModelForTest.route(ROUTE_ID_2).withAgency(AGENCY_2).build(); - Route route3 = TransitModelForTest.route(ROUTE_ID_3).withAgency(AGENCY_3).build(); + Route route1 = TimetableRepositoryForTest.route(ROUTE_ID_1).withAgency(AGENCY_1).build(); + Route route2 = TimetableRepositoryForTest.route(ROUTE_ID_2).withAgency(AGENCY_2).build(); + Route route3 = TimetableRepositoryForTest.route(ROUTE_ID_3).withAgency(AGENCY_3).build(); var patterns = List.of( - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_1, route1) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_2, route2) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_3, route3) .withStopPattern(STOP_PATTERN) .build() @@ -129,20 +129,20 @@ public void testOne() { """ ) public void testTwo() { - Route route1 = TransitModelForTest.route(ROUTE_ID_1).withAgency(AGENCY_1).build(); - Route route2 = TransitModelForTest.route(ROUTE_ID_2).withAgency(AGENCY_2).build(); - Route route3 = TransitModelForTest.route(ROUTE_ID_3).withAgency(AGENCY_3).build(); + Route route1 = TimetableRepositoryForTest.route(ROUTE_ID_1).withAgency(AGENCY_1).build(); + Route route2 = TimetableRepositoryForTest.route(ROUTE_ID_2).withAgency(AGENCY_2).build(); + Route route3 = TimetableRepositoryForTest.route(ROUTE_ID_3).withAgency(AGENCY_3).build(); var patterns = List.of( - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_1, route1) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_2, route2) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_3, route3) .withStopPattern(STOP_PATTERN) .build() @@ -174,34 +174,34 @@ public void testTwo() { """ ) public void testThree() { - Route route1 = TransitModelForTest + Route route1 = TimetableRepositoryForTest .route(ROUTE_ID_1) .withAgency(AGENCY_1) .withMode(TransitMode.BUS) .withNetexSubmode("schoolBus") .build(); - Route route2 = TransitModelForTest + Route route2 = TimetableRepositoryForTest .route(ROUTE_ID_2) .withAgency(AGENCY_2) .withMode(TransitMode.RAIL) .withNetexSubmode("railShuttle") .build(); - Route route3 = TransitModelForTest + Route route3 = TimetableRepositoryForTest .route(ROUTE_ID_3) .withAgency(AGENCY_3) .withMode(TransitMode.TRAM) .build(); var patterns = List.of( - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_1, route1) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_2, route2) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_3, route3) .withStopPattern(STOP_PATTERN) .build() @@ -249,20 +249,20 @@ public void testThree() { """ ) public void testFour() { - Route route1 = TransitModelForTest.route(ROUTE_ID_1).build(); - Route route2 = TransitModelForTest.route(ROUTE_ID_2).build(); - Route route3 = TransitModelForTest.route(ROUTE_ID_3).build(); + Route route1 = TimetableRepositoryForTest.route(ROUTE_ID_1).build(); + Route route2 = TimetableRepositoryForTest.route(ROUTE_ID_2).build(); + Route route3 = TimetableRepositoryForTest.route(ROUTE_ID_3).build(); var patterns = List.of( - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_1, route1) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_2, route2) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_3, route3) .withStopPattern(STOP_PATTERN) .build() @@ -302,15 +302,15 @@ public void testFour() { """ ) public void testFive() { - Route route1 = TransitModelForTest.route(ROUTE_ID_1).build(); - Route route2 = TransitModelForTest.route(ROUTE_ID_2).build(); + Route route1 = TimetableRepositoryForTest.route(ROUTE_ID_1).build(); + Route route2 = TimetableRepositoryForTest.route(ROUTE_ID_2).build(); var patterns = List.of( - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_1, route1) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_2, route2) .withStopPattern(STOP_PATTERN) .build() @@ -347,20 +347,20 @@ public void testFive() { """ ) public void testSix() { - Route route1 = TransitModelForTest.route(ROUTE_ID_1).withAgency(AGENCY_1).build(); - Route route2 = TransitModelForTest.route(ROUTE_ID_2).withAgency(AGENCY_1).build(); - Route route3 = TransitModelForTest.route(ROUTE_ID_3).withAgency(AGENCY_1).build(); + Route route1 = TimetableRepositoryForTest.route(ROUTE_ID_1).withAgency(AGENCY_1).build(); + Route route2 = TimetableRepositoryForTest.route(ROUTE_ID_2).withAgency(AGENCY_1).build(); + Route route3 = TimetableRepositoryForTest.route(ROUTE_ID_3).withAgency(AGENCY_1).build(); var patterns = List.of( - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_1, route1) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_2, route2) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_3, route3) .withStopPattern(STOP_PATTERN) .build() @@ -397,20 +397,20 @@ public void testSix() { """ ) public void testSeven() { - Route route1 = TransitModelForTest.route(ROUTE_ID_1).withAgency(AGENCY_1).build(); - Route route2 = TransitModelForTest.route(ROUTE_ID_2).withAgency(AGENCY_2).build(); - Route route3 = TransitModelForTest.route(ROUTE_ID_3).withAgency(AGENCY_2).build(); + Route route1 = TimetableRepositoryForTest.route(ROUTE_ID_1).withAgency(AGENCY_1).build(); + Route route2 = TimetableRepositoryForTest.route(ROUTE_ID_2).withAgency(AGENCY_2).build(); + Route route3 = TimetableRepositoryForTest.route(ROUTE_ID_3).withAgency(AGENCY_2).build(); var patterns = List.of( - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_1, route1) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_2, route2) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_3, route3) .withStopPattern(STOP_PATTERN) .build() @@ -448,32 +448,32 @@ public void testSeven() { """ ) public void testEight() { - final Route route1 = TransitModelForTest + final Route route1 = TimetableRepositoryForTest .route(ROUTE_ID_1) .withMode(TransitMode.BUS) .withAgency(AGENCY_1) .build(); - final Route route2 = TransitModelForTest + final Route route2 = TimetableRepositoryForTest .route(ROUTE_ID_2) .withMode(TransitMode.RAIL) .withAgency(AGENCY_1) .build(); - final Route route3 = TransitModelForTest + final Route route3 = TimetableRepositoryForTest .route(ROUTE_ID_3) .withMode(TransitMode.BUS) .withAgency(AGENCY_2) .build(); var patterns = List.of( - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_1, route1) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_2, route2) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_3, route3) .withStopPattern(STOP_PATTERN) .build() @@ -513,41 +513,41 @@ public void testEight() { """ ) public void testNine() { - Route route1 = TransitModelForTest + Route route1 = TimetableRepositoryForTest .route(ROUTE_ID_1) .withAgency(AGENCY_1) .withMode(TransitMode.BUS) .build(); - Route route2 = TransitModelForTest + Route route2 = TimetableRepositoryForTest .route(ROUTE_ID_2) .withAgency(AGENCY_1) .withMode(TransitMode.RAIL) .build(); - Route route3 = TransitModelForTest + Route route3 = TimetableRepositoryForTest .route(ROUTE_ID_3) .withAgency(AGENCY_1) .withMode(TransitMode.BUS) .build(); - Route route4 = TransitModelForTest + Route route4 = TimetableRepositoryForTest .route(ROUTE_ID_4) .withAgency(AGENCY_2) .withMode(TransitMode.BUS) .build(); var patterns = List.of( - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_1, route1) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_2, route2) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_3, route3) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_4, route4) .withStopPattern(STOP_PATTERN) .build() @@ -589,37 +589,37 @@ public void testNine() { """ ) public void testTen() { - final Route route1 = TransitModelForTest + final Route route1 = TimetableRepositoryForTest .route(ROUTE_ID_1) .withMode(TransitMode.BUS) .withAgency(AGENCY_1) .build(); - final Route route2 = TransitModelForTest + final Route route2 = TimetableRepositoryForTest .route(ROUTE_ID_2) .withMode(TransitMode.RAIL) .withAgency(AGENCY_1) .build(); - final Route route3 = TransitModelForTest + final Route route3 = TimetableRepositoryForTest .route(ROUTE_ID_3) .withMode(TransitMode.BUS) .withAgency(AGENCY_1) .build(); - final Route route4 = TransitModelForTest.route(ROUTE_ID_4).withAgency(AGENCY_2).build(); + final Route route4 = TimetableRepositoryForTest.route(ROUTE_ID_4).withAgency(AGENCY_2).build(); var patterns = List.of( - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_1, route1) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_2, route2) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_3, route3) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_4, route4) .withStopPattern(STOP_PATTERN) .build() @@ -646,19 +646,19 @@ public void testTen() { @Test void testDifferentSubModesInRoute() { - final Route route1 = TransitModelForTest + final Route route1 = TimetableRepositoryForTest .route(ROUTE_ID_1) .withMode(TransitMode.BUS) .withAgency(AGENCY_1) .build(); var patterns = List.of( - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_1, route1) .withStopPattern(STOP_PATTERN) .withNetexSubmode(LOCAL_BUS) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_2, route1) .withStopPattern(STOP_PATTERN) .withNetexSubmode(NIGHT_BUS) @@ -696,21 +696,21 @@ private static Collection bannedPatterns( @Test public void testGroupOfLinesSelectFunctionality() { - var route1 = TransitModelForTest + var route1 = TimetableRepositoryForTest .route(ROUTE_ID_1) .withGroupOfRoutes(List.of(GROUP_OF_ROUTES_1)) .build(); - var route2 = TransitModelForTest + var route2 = TimetableRepositoryForTest .route(ROUTE_ID_2) .withGroupOfRoutes(List.of(GROUP_OF_ROUTES_2)) .build(); var patterns = List.of( - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_1, route1) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_2, route2) .withStopPattern(STOP_PATTERN) .build() @@ -734,21 +734,21 @@ public void testGroupOfLinesSelectFunctionality() { @Test public void testGroupOfLinesExcludeFunctionality() { - var route1 = TransitModelForTest + var route1 = TimetableRepositoryForTest .route(ROUTE_ID_1) .withGroupOfRoutes(List.of(GROUP_OF_ROUTES_1)) .build(); - var route2 = TransitModelForTest + var route2 = TimetableRepositoryForTest .route(ROUTE_ID_2) .withGroupOfRoutes(List.of(GROUP_OF_ROUTES_2)) .build(); var patterns = List.of( - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_1, route1) .withStopPattern(STOP_PATTERN) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern(JOURNEY_PATTERN_ID_2, route2) .withStopPattern(STOP_PATTERN) .build() diff --git a/src/test/java/org/opentripplanner/routing/algorithm/GraphRoutingTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/GraphRoutingTest.java similarity index 79% rename from src/test/java/org/opentripplanner/routing/algorithm/GraphRoutingTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/GraphRoutingTest.java index 69e2ddaa944..e283e4e9fa8 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/GraphRoutingTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/GraphRoutingTest.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.function.Consumer; +import javax.annotation.Nullable; import org.locationtech.jts.geom.Coordinate; import org.opentripplanner.TestOtpModel; import org.opentripplanner.framework.geometry.GeometryUtils; @@ -11,9 +13,9 @@ import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.StopTime; import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParking.VehicleParkingEntranceCreator; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingHelper; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParking.VehicleParkingEntranceCreator; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingHelper; import org.opentripplanner.service.vehiclerental.model.RentalVehicleType; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; @@ -29,12 +31,14 @@ import org.opentripplanner.street.model.edge.PathwayEdge; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.edge.StreetEdgeBuilder; +import org.opentripplanner.street.model.edge.StreetStationCentroidLink; import org.opentripplanner.street.model.edge.StreetTransitEntranceLink; import org.opentripplanner.street.model.edge.StreetTransitStopLink; import org.opentripplanner.street.model.edge.StreetVehicleParkingLink; import org.opentripplanner.street.model.edge.TemporaryFreeEdge; import org.opentripplanner.street.model.vertex.ElevatorOnboardVertex; import org.opentripplanner.street.model.vertex.IntersectionVertex; +import org.opentripplanner.street.model.vertex.StationCentroidVertex; import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.street.model.vertex.TemporaryStreetLocation; import org.opentripplanner.street.model.vertex.TemporaryVertex; @@ -44,7 +48,7 @@ import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.model.vertex.VertexFactory; import org.opentripplanner.street.model.vertex.VertexLabel; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; @@ -56,8 +60,9 @@ import org.opentripplanner.transit.model.site.PathwayMode; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.model.site.StationBuilder; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; public abstract class GraphRoutingTest { @@ -66,21 +71,21 @@ public abstract class GraphRoutingTest { protected TestOtpModel modelOf(Builder builder) { builder.build(); Graph graph = builder.graph(); - TransitModel transitModel = builder.transitModel(); - return new TestOtpModel(graph, transitModel).index(); + TimetableRepository timetableRepository = builder.timetableRepository(); + return new TestOtpModel(graph, timetableRepository).index(); } public abstract static class Builder { private final Graph graph; - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; private final VertexFactory vertexFactory; private final VehicleParkingHelper vehicleParkingHelper; protected Builder() { var deduplicator = new Deduplicator(); graph = new Graph(deduplicator); - transitModel = new TransitModel(new StopModel(), deduplicator); + timetableRepository = new TimetableRepository(new SiteRepository(), deduplicator); vertexFactory = new VertexFactory(graph); vehicleParkingHelper = new VehicleParkingHelper(graph); } @@ -91,8 +96,8 @@ public Graph graph() { return graph; } - public TransitModel transitModel() { - return transitModel; + public TimetableRepository timetableRepository() { + return timetableRepository; } public T v(VertexLabel label) { @@ -108,6 +113,10 @@ public IntersectionVertex intersection(String label, double latitude, double lon return vertexFactory.intersection(label, longitude, latitude); } + public IntersectionVertex intersection(String label, WgsCoordinate coordinate) { + return intersection(label, coordinate.latitude(), coordinate.longitude()); + } + public StreetEdgeBuilder streetBuilder( StreetVertex from, StreetVertex to, @@ -126,6 +135,13 @@ public StreetEdgeBuilder streetBuilder( .withBack(false); } + /** + * Create a street with all permissions in both directions + */ + public List biStreet(StreetVertex from, StreetVertex to, int length) { + return street(from, to, length, StreetTraversalPermission.ALL, StreetTraversalPermission.ALL); + } + public StreetEdge street( StreetVertex from, StreetVertex to, @@ -213,46 +229,66 @@ public List elevator(StreetTraversalPermission permission, Vertex. // -- Transit network (pathways, linking) public Entrance entranceEntity(String id, double latitude, double longitude) { return Entrance - .of(TransitModelForTest.id(id)) + .of(TimetableRepositoryForTest.id(id)) .withName(new NonLocalizedString(id)) .withCode(id) .withCoordinate(latitude, longitude) .build(); } - RegularStop stopEntity(String id, double latitude, double longitude, boolean noTransfers) { - var stopModelBuilder = transitModel.getStopModel().withContext(); - var testModel = new TransitModelForTest(stopModelBuilder); + RegularStop stopEntity( + String id, + double latitude, + double longitude, + @Nullable Station parentStation + ) { + var siteRepositoryBuilder = timetableRepository.getSiteRepository().withContext(); + var testModel = new TimetableRepositoryForTest(siteRepositoryBuilder); var stopBuilder = testModel.stop(id).withCoordinate(latitude, longitude); - if (noTransfers) { - stopBuilder.withParentStation( - Station - .of(TransitModelForTest.id("1")) - .withName(new NonLocalizedString("Malmö C")) - .withCoordinate(latitude, longitude) - .withTransfersNotAllowed(true) - .build() - ); + if (parentStation != null) { + stopBuilder.withParentStation(parentStation); } var stop = stopBuilder.build(); - transitModel.mergeStopModels(stopModelBuilder.withRegularStop(stop).build()); + timetableRepository.mergeSiteRepositories( + siteRepositoryBuilder.withRegularStop(stop).build() + ); return stop; } + public Station stationEntity(String id, Consumer stationBuilder) { + var siteRepositoryBuilder = timetableRepository.getSiteRepository().withContext(); + var testModel = new TimetableRepositoryForTest(siteRepositoryBuilder); + + var builder = testModel.station(id); + stationBuilder.accept(builder); + var station = builder.build(); + + timetableRepository.mergeSiteRepositories(siteRepositoryBuilder.withStation(station).build()); + return station; + } + + public TransitStopVertex stop(String id, WgsCoordinate coordinate, Station parentStation) { + return stop(id, coordinate.latitude(), coordinate.longitude(), parentStation); + } + + public TransitStopVertex stop(String id, WgsCoordinate coordinate) { + return stop(id, coordinate, null); + } + public TransitStopVertex stop(String id, double latitude, double longitude) { - return stop(id, latitude, longitude, false); + return stop(id, latitude, longitude, null); } public TransitStopVertex stop( String id, double latitude, double longitude, - boolean noTransfers + @Nullable Station parentStation ) { return vertexFactory.transitStop( - TransitStopVertex.of().withStop(stopEntity(id, latitude, longitude, noTransfers)) + TransitStopVertex.of().withStop(stopEntity(id, latitude, longitude, parentStation)) ); } @@ -260,6 +296,10 @@ public TransitEntranceVertex entrance(String id, double latitude, double longitu return new TransitEntranceVertex(entranceEntity(id, latitude, longitude)); } + public StationCentroidVertex stationCentroid(Station station) { + return vertexFactory.stationCentroid(station); + } + public StreetTransitEntranceLink link(StreetVertex from, TransitEntranceVertex to) { return StreetTransitEntranceLink.createStreetTransitEntranceLink(from, to); } @@ -284,6 +324,18 @@ public List biLink(StreetVertex from, TransitStopVertex t return List.of(link(from, to), link(to, from)); } + public StreetStationCentroidLink link(StreetVertex from, StationCentroidVertex to) { + return StreetStationCentroidLink.createStreetStationLink(from, to); + } + + public StreetStationCentroidLink link(StationCentroidVertex from, StreetVertex to) { + return StreetStationCentroidLink.createStreetStationLink(from, to); + } + + public List biLink(StreetVertex from, StationCentroidVertex to) { + return List.of(link(from, to), link(to, from)); + } + public PathwayEdge pathway(Vertex from, Vertex to, int time, int length) { return PathwayEdge.createPathwayEdge( from, @@ -404,7 +456,7 @@ public VehicleParking vehicleParking( ) { var vehicleParking = VehicleParking .builder() - .id(TransitModelForTest.id(id)) + .id(TimetableRepositoryForTest.id(id)) .coordinate(new WgsCoordinate(y, x)) .bicyclePlaces(bicyclePlaces) .carPlaces(carPlaces) @@ -427,7 +479,7 @@ public VehicleParking.VehicleParkingEntranceCreator vehicleParkingEntrance( ) { return builder -> builder - .entranceId(TransitModelForTest.id(id)) + .entranceId(TimetableRepositoryForTest.id(id)) .name(new NonLocalizedString(id)) .coordinate(new WgsCoordinate(streetVertex.getCoordinate())) .vertex(streetVertex) @@ -451,12 +503,12 @@ public List biLink( } public Route route(String id, TransitMode mode, Agency agency) { - return TransitModelForTest.route(id).withAgency(agency).withMode(mode).build(); + return TimetableRepositoryForTest.route(id).withAgency(agency).withMode(mode).build(); } // Transit public void tripPattern(TripPattern tripPattern) { - transitModel.addTripPattern(tripPattern.getId(), tripPattern); + timetableRepository.addTripPattern(tripPattern.getId(), tripPattern); } public StopTime st(TransitStopVertex s1) { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/MultiTargetTerminationStrategy.java b/application/src/test/java/org/opentripplanner/routing/algorithm/MultiTargetTerminationStrategy.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/MultiTargetTerminationStrategy.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/MultiTargetTerminationStrategy.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/StreetModeLinkingTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/StreetModeLinkingTest.java similarity index 92% rename from src/test/java/org/opentripplanner/routing/algorithm/StreetModeLinkingTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/StreetModeLinkingTest.java index 4d1b14832a9..1ee0ec9c481 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/StreetModeLinkingTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/StreetModeLinkingTest.java @@ -15,7 +15,7 @@ import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.search.TemporaryVerticesContainer; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; /** * This tests linking of GenericLocations to streets for each StreetMode. The test has 5 parallel @@ -77,7 +77,7 @@ public void build() { graph = otpModel.graph(); graph.hasStreets = true; - TestStreetLinkerModule.link(graph, otpModel.transitModel()); + TestStreetLinkerModule.link(graph, otpModel.timetableRepository()); } @Test @@ -110,8 +110,8 @@ public void testCarParkLinking() { assertLinking(setup.apply(47.501, 19.04), "E1E2 street", "D1D2 street", StreetMode.CAR_TO_PARK); assertLinking( rr -> { - rr.setFrom(new GenericLocation(null, TransitModelForTest.id("STOP"), null, null)); - rr.setTo(new GenericLocation(null, TransitModelForTest.id("STOP"), null, null)); + rr.setFrom(new GenericLocation(null, TimetableRepositoryForTest.id("STOP"), null, null)); + rr.setTo(new GenericLocation(null, TimetableRepositoryForTest.id("STOP"), null, null)); }, "E1E2 street", "D1D2 street", @@ -180,8 +180,8 @@ private void assertLinkedFromTo( private void assertLinkedFromTo(String stopId, String streetName, StreetMode... streetModes) { assertLinking( rr -> { - rr.setFrom(new GenericLocation(null, TransitModelForTest.id(stopId), null, null)); - rr.setTo(new GenericLocation(null, TransitModelForTest.id(stopId), null, null)); + rr.setFrom(new GenericLocation(null, TimetableRepositoryForTest.id(stopId), null, null)); + rr.setTo(new GenericLocation(null, TimetableRepositoryForTest.id(stopId), null, null)); }, streetName, streetName, @@ -206,7 +206,8 @@ private void assertLinking( try ( var temporaryVertices = new TemporaryVerticesContainer( graph, - routingRequest, + routingRequest.from(), + routingRequest.to(), streetMode, streetMode ) @@ -230,7 +231,8 @@ private void assertLinking( try ( var temporaryVertices = new TemporaryVerticesContainer( graph, - routingRequest, + routingRequest.from(), + routingRequest.to(), streetMode, streetMode ) diff --git a/src/test/java/org/opentripplanner/routing/algorithm/TestBanning.java b/application/src/test/java/org/opentripplanner/routing/algorithm/TestBanning.java similarity index 76% rename from src/test/java/org/opentripplanner/routing/algorithm/TestBanning.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/TestBanning.java index 075fceed4eb..07d9074c350 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/TestBanning.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/TestBanning.java @@ -2,14 +2,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.util.Collection; import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner.routing.api.request.request.filter.SelectRequest; import org.opentripplanner.routing.api.request.request.filter.TransitFilterRequest; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.StopPattern; @@ -56,24 +56,32 @@ public void testSetWhiteListedOnRequest() { } private List getTestPatterns() { - Agency agency1 = TransitModelForTest.agency("A").copy().withId(id("RUT:Agency:1")).build(); - Agency agency2 = TransitModelForTest.agency("B").copy().withId(id("RUT:Agency:2")).build(); + Agency agency1 = TimetableRepositoryForTest + .agency("A") + .copy() + .withId(id("RUT:Agency:1")) + .build(); + Agency agency2 = TimetableRepositoryForTest + .agency("B") + .copy() + .withId(id("RUT:Agency:2")) + .build(); - Route route1 = TransitModelForTest.route("RUT:Route:1").withAgency(agency1).build(); - Route route2 = TransitModelForTest.route("RUT:Route:2").withAgency(agency1).build(); - Route route3 = TransitModelForTest.route("RUT:Route:3").withAgency(agency2).build(); + Route route1 = TimetableRepositoryForTest.route("RUT:Route:1").withAgency(agency1).build(); + Route route2 = TimetableRepositoryForTest.route("RUT:Route:2").withAgency(agency1).build(); + Route route3 = TimetableRepositoryForTest.route("RUT:Route:3").withAgency(agency2).build(); - final StopPattern stopPattern = TransitModelForTest.of().stopPattern(2); + final StopPattern stopPattern = TimetableRepositoryForTest.of().stopPattern(2); return List.of( - TransitModelForTest + TimetableRepositoryForTest .tripPattern("RUT:JourneyPattern:1", route1) .withStopPattern(stopPattern) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern("RUT:JourneyPattern:2", route2) .withStopPattern(stopPattern) .build(), - TransitModelForTest + TimetableRepositoryForTest .tripPattern("RUT:JourneyPattern:3", route3) .withStopPattern(stopPattern) .build() diff --git a/src/test/java/org/opentripplanner/routing/algorithm/TurnCostTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/TurnCostTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/TurnCostTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/TurnCostTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java similarity index 85% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java index d897c948e6d..4ccb7ac9793 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java @@ -35,16 +35,16 @@ import org.opentripplanner.routing.api.response.RoutingError; import org.opentripplanner.routing.api.response.RoutingErrorCode; import org.opentripplanner.routing.services.TransitAlertService; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; /** * This class test the whole filter chain with a few test cases. Each filter should be tested with a * unit test. This is just a some test on top of the other filter unit-tests. */ -public class ItineraryListFilterChainTest implements PlanTestConstants { +class ItineraryListFilterChainTest implements PlanTestConstants { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final Place A = Place.forStop(TEST_MODEL.stop("A").build()); private static final Place B = Place.forStop(TEST_MODEL.stop("B").build()); private static final Place C = Place.forStop(TEST_MODEL.stop("C").build()); @@ -59,7 +59,7 @@ public class ItineraryListFilterChainTest implements PlanTestConstants { private Itinerary i3; @BeforeEach - public void setUpItineraries() { + void setUpItineraries() { // Add some itineraries, with some none optimal options // Short walk - 2 minutes - to destination: i1 = newItinerary(A, T11_06).walk(D2m, E).build(); @@ -72,7 +72,7 @@ public void setUpItineraries() { } @Test - public void testDefaultFilterChain() { + void testDefaultFilterChain() { // Given a default chain ItineraryListFilterChain chain = createBuilder(false, false, 10).build(); @@ -80,7 +80,7 @@ public void testDefaultFilterChain() { } @Test - public void testFilterChainWithSearchWindowFilterSet() { + void testFilterChainWithSearchWindowFilterSet() { ItineraryListFilterChain chain = createBuilder(false, false, 10) .withSearchWindow(TestItineraryBuilder.newTime(T11_00).toInstant(), SW_D10m) .build(); @@ -89,7 +89,7 @@ public void testFilterChainWithSearchWindowFilterSet() { } @Test - public void withMinBikeParkingDistance() { + void withMinBikeParkingDistance() { // Given a "default" chain ItineraryListFilterChain chain = createBuilder(false, false, 10) .withMinBikeParkingDistance(500) @@ -105,7 +105,7 @@ public void withMinBikeParkingDistance() { } @Test - public void testDebugFilterChain() { + void testDebugFilterChain() { // Given a filter-chain with debugging enabled ItineraryListFilterChain chain = createBuilder(false, true, 3) .withSearchWindow(newTime(T11_00).toInstant(), SW_D10m) @@ -122,7 +122,7 @@ public void testDebugFilterChain() { } @Test - public void removeAllWalkingOnly() { + void removeAllWalkingOnly() { ItineraryListFilterChain chain = createBuilder(false, false, 20) .withRemoveWalkAllTheWayResults(true) .build(); @@ -134,7 +134,7 @@ public void removeAllWalkingOnly() { } @Test - public void groupByTheLongestItineraryAndTwoGroups() { + void groupByTheLongestItineraryAndTwoGroups() { ItineraryListFilterChain chain = createBuilder(false, false, 20) .addGroupBySimilarity(GroupBySimilarity.createWithOneItineraryPerGroup(.5)) .build(); @@ -157,7 +157,7 @@ public void groupByTheLongestItineraryAndTwoGroups() { } @Test - public void testSameFirstOrLastTripFilter() { + void testSameFirstOrLastTripFilter() { ItineraryListFilterChain chain = createBuilder(false, false, 20) .withSameFirstOrLastTripFilter(true) .build(); @@ -238,7 +238,7 @@ void transitAlertsTest() { } @Test - public void removeItinerariesWithSameRoutesAndStops() { + void removeItinerariesWithSameRoutesAndStops() { var i1 = newItinerary(A).bus(21, T11_06, T11_28, E).bus(41, T11_30, T11_32, D).build(); var i2 = newItinerary(A).bus(22, T11_09, T11_30, E).bus(42, T11_32, T11_33, D).build(); var i3 = newItinerary(A).bus(23, T11_10, T11_32, E).bus(43, T11_33, T11_50, D).build(); @@ -274,34 +274,67 @@ private ItineraryListFilterChainBuilder createBuilder( class MaxItinerariesBuilderTest { @BeforeEach - public void setUpItineraries() { + void setUpItineraries() { i1 = newItinerary(A).bus(21, T11_05, T11_10, E).build(); i2 = newItinerary(A).bus(31, T11_07, T11_12, E).build(); i3 = newItinerary(A).bus(41, T11_09, T11_14, E).build(); } @Test - public void testPostProcessorWithMaxItinerariesFilterSetToTwo() { + void testPostProcessorWithMaxItinerariesFilterSetToTwo() { // Given a default postProcessor with 'numOfItineraries=2' ItineraryListFilterChain chain = createBuilder(false, false, 2).build(); assertEquals(List.of(i1, i2), chain.filter(List.of(i1, i2, i3))); } @Test - public void testPostProcessorWithMaxItinerariesFilterSetToOneDepartAt() { + void testPostProcessorWithMaxItinerariesFilterSetToOneDepartAt() { // Given a default postProcessor with 'numOfItineraries=1' ItineraryListFilterChain chain = createBuilder(false, false, 1).build(); assertEquals(List.of(i1), chain.filter(List.of(i1, i2, i3))); } @Test - public void testPostProcessorWithMaxItinerariesFilterSetToOneArriveBy() { + void testPostProcessorWithMaxItinerariesFilterSetToOneArriveBy() { // Given a postProcessor with 'numOfItineraries=1' and 'arriveBy=true' ItineraryListFilterChain chain = createBuilder(true, false, 1).build(); assertEquals(List.of(i3), chain.filter(List.of(i1, i2, i3))); } } + @Nested + class FlexSearchWindow { + + private final Itinerary flex = newItinerary(A, T11_00) + .flex(T11_00, T11_30, B) + .withIsSearchWindowAware(false) + .build(); + private final Instant earliestDeparture = flex.startTime().plusMinutes(10).toInstant(); + private final Duration searchWindow = Duration.ofHours(7); + + /** + * When the filtering of direct flex by the transit search window is deactivated, the direct + * flex result should _not_ be filtered even though it starts before the earliest departure time. + */ + @Test + void keepDirectFlexWhenFilteringByEarliestDepartureIsDisabled() { + ItineraryListFilterChain chain = createBuilder(true, false, 10) + .withFilterDirectFlexBySearchWindow(false) + .withSearchWindow(earliestDeparture, searchWindow) + .build(); + assertEquals(toStr(List.of(flex)), toStr(chain.filter(List.of(flex)))); + } + + @Test + void removeDirectFlexWhenFilteringByEarliestDepartureIsEnabled() { + ItineraryListFilterChain chain = createBuilder(true, false, 10) + .withFilterDirectFlexBySearchWindow(true) + .withSearchWindow(earliestDeparture, searchWindow) + .build(); + assertEquals(toStr(List.of()), toStr(chain.filter(List.of(flex)))); + } + } + @Nested class RemoveTransitWithHigherCostThanBestOnStreetOnlyTest { @@ -310,7 +343,7 @@ class RemoveTransitWithHigherCostThanBestOnStreetOnlyTest { ItineraryListFilterChainBuilder builder = createBuilder(true, false, 20); @BeforeEach - public void setUpItineraries() { + void setUpItineraries() { // given // Walk for 12 minute walk = newItinerary(A, T11_06).walk(D12m, E).build(); @@ -319,7 +352,7 @@ public void setUpItineraries() { } @Test - public void removeTransitWithHigherCostThanBestOnStreetOnlyDisabled() { + void removeTransitWithHigherCostThanBestOnStreetOnlyDisabled() { // Allow non-optimal bus itinerary pass through ItineraryListFilterChain chain = builder .withRemoveTransitWithHigherCostThanBestOnStreetOnly(null) @@ -329,7 +362,7 @@ public void removeTransitWithHigherCostThanBestOnStreetOnlyDisabled() { } @Test - public void removeTransitWithHigherCostThanBestOnStreetOnlyEnabled() { + void removeTransitWithHigherCostThanBestOnStreetOnlyEnabled() { // Enable filter and remove bus itinerary ItineraryListFilterChain chain = builder .withRemoveTransitWithHigherCostThanBestOnStreetOnly( @@ -355,7 +388,7 @@ class AddEmissionsToItineraryTest { EmissionsService eService; @BeforeEach - public void setUpItineraries() { + void setUpItineraries() { bus = newItinerary(A).bus(21, T11_06, T11_09, B).build(); car = newItinerary(A).drive(T11_30, T11_50, B).build(); Map emissions = new HashMap<>(); @@ -364,7 +397,7 @@ public void setUpItineraries() { } @Test - public void emissionsTest() { + void emissionsTest() { ItineraryListFilterChain chain = builder .withEmissions(new DecorateWithEmission(eService)) .build(); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalkingTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalkingTest.java similarity index 93% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalkingTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalkingTest.java index 4e47306601c..c1dc34413cd 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalkingTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalkingTest.java @@ -8,9 +8,9 @@ import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; public class RemoveBikeRentalWithMostlyWalkingTest { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingTest.java similarity index 93% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingTest.java index a4c90d1346f..88baabb1e2a 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingTest.java @@ -8,9 +8,9 @@ import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; public class RemoveParkAndRideWithMostlyWalkingTest { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilterTest.java similarity index 93% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilterTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilterTest.java index 359423a842b..6281c4f744c 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilterTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilterTest.java @@ -8,9 +8,9 @@ import java.util.List; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; public class RemoveWalkOnlyFilterTest { diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/FlexSearchWindowFilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/FlexSearchWindowFilterTest.java new file mode 100644 index 00000000000..dd51ccbcd19 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/FlexSearchWindowFilterTest.java @@ -0,0 +1,74 @@ +package org.opentripplanner.routing.algorithm.filterchain.filters.system; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; +import static org.opentripplanner.utils.time.TimeUtils.time; + +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.opentripplanner.model.plan.PlanTestConstants; +import org.opentripplanner.model.plan.SortOrder; +import org.opentripplanner.model.plan.TestItineraryBuilder; + +class FlexSearchWindowFilterTest implements PlanTestConstants { + + private static final Instant LATEST_DEPARTURE_TIME = TestItineraryBuilder + .newTime(time("09:20")) + .toInstant(); + + @ParameterizedTest + @ValueSource(strings = { "09:20", "09:21", "13:20" }) + void keepArriveByFlexItinerariesAfterEDT(String startTime) { + var edt = "9:20"; + var subject = new FlexSearchWindowFilter( + TestItineraryBuilder.newTime(time(edt)).toInstant(), + Duration.ofMinutes(30), + SortOrder.STREET_AND_DEPARTURE_TIME + ); + + var itin = newItinerary(A, time(startTime)) + .flex(T11_00, T11_30, B) + .withIsSearchWindowAware(false) + .build(); + + assertThat(subject.flagForRemoval(List.of(itin))).isEmpty(); + } + + @ParameterizedTest + @ValueSource(strings = { "00:00", "00:01", "09:19" }) + void removeArriveByFlexItinerariesBeforeEDT(String startTime) { + var subject = new FlexSearchWindowFilter( + LATEST_DEPARTURE_TIME, + Duration.ofMinutes(30), + SortOrder.STREET_AND_DEPARTURE_TIME + ); + + var itin = newItinerary(A, time(startTime)) + .flex(T11_00, T11_30, B) + .withIsSearchWindowAware(false) + .build(); + + assertThat(subject.flagForRemoval(List.of(itin))).isEmpty(); + } + + @ParameterizedTest + @ValueSource(strings = { "12:00" }) + void removeDepartAtFlexItinerariesAfterLAT(String startTime) { + var subject = new FlexSearchWindowFilter( + LATEST_DEPARTURE_TIME, + Duration.ofMinutes(30), + SortOrder.STREET_AND_ARRIVAL_TIME + ); + + var itin = newItinerary(A, time(startTime)) + .flex(T11_00, T11_30, B) + .withIsSearchWindowAware(false) + .build(); + + assertEquals(subject.flagForRemoval(List.of(itin)), List.of(itin)); + } +} diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterTest.java similarity index 97% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterTest.java index 622482fe4b3..1943104e1d0 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterTest.java @@ -8,9 +8,9 @@ import java.util.List; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.collection.ListSection; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; +import org.opentripplanner.utils.collection.ListSection; public class NumItinerariesFilterTest { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilterTest.java similarity index 64% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilterTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilterTest.java index 9752004560e..0e61d146d17 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilterTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilterTest.java @@ -1,17 +1,19 @@ package org.opentripplanner.routing.algorithm.filterchain.filters.system; +import static com.google.common.truth.Truth.assertThat; 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.model.plan.TestItineraryBuilder.newItinerary; +import static org.opentripplanner.utils.time.TimeUtils.time; import java.time.Duration; import java.util.List; +import java.util.stream.Stream; 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.framework.time.TimeUtils; import org.opentripplanner.model.SystemNotice; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; @@ -20,8 +22,8 @@ public class OutsideSearchWindowFilterTest implements PlanTestConstants { private static final Duration SEARCH_WINDOW_10m = Duration.ofMinutes(10); - private final int startTime = TimeUtils.time("09:30"); - private final int endTime = TimeUtils.time("09:40"); + private final int startTime = time("09:30"); + private final int endTime = time("09:40"); private final Itinerary itinerary = newItinerary(A).bus(32, startTime, endTime, E).build(); private final List input = List.of(itinerary); @@ -40,7 +42,7 @@ static List filterOnSearchWindowTestCases() { public void filterOnSearchWindow(String description, String edt, boolean flaggedForRemoval) { List expected = flaggedForRemoval ? input : List.of(); var subject = new OutsideSearchWindowFilter( - TestItineraryBuilder.newTime(TimeUtils.time(edt)).toInstant(), + TestItineraryBuilder.newTime(time(edt)).toInstant(), SEARCH_WINDOW_10m ); var result = subject.flagForRemoval(input); @@ -55,4 +57,31 @@ public void testTaggedBy() { it.flagForDeletion(new SystemNotice(OutsideSearchWindowFilter.TAG, "Text")); assertTrue(OutsideSearchWindowFilter.taggedBy(it)); } + + private static Stream onStreetTestCases() { + int t9_28 = time("9:28"); + int t9_38 = time("9:38"); + return Stream + .of( + newItinerary(A, t9_28).walk(D2m, B), + newItinerary(A, t9_38).walk(D12m, B), + newItinerary(A, t9_28).bicycle(t9_28, t9_38, B), + newItinerary(A, t9_28).flex(t9_28, t9_38, B), + newItinerary(A, t9_28).flex(t9_38, time("9:48"), B), + newItinerary(A, time("9:20")).flex(time("9:20"), t9_28, B).walk(D12m, C) + ) + // results from the street & flex routers are not aware of the search window + .map(b -> b.withIsSearchWindowAware(false).build()); + } + + @ParameterizedTest + @MethodSource("onStreetTestCases") + void onStreetArriveByShouldNotBeRemoved(Itinerary itin) { + var edt = "9:20"; + var subject = new OutsideSearchWindowFilter( + TestItineraryBuilder.newTime(time(edt)).toInstant(), + SEARCH_WINDOW_10m + ); + assertThat(subject.flagForRemoval(List.of(itin))).isEmpty(); + } } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilterTest.java similarity index 95% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilterTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilterTest.java index 751dcc7ad3c..165cddd31f3 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilterTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilterTest.java @@ -1,10 +1,10 @@ package org.opentripplanner.routing.algorithm.filterchain.filters.system; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.collection.ListUtils.first; -import static org.opentripplanner.framework.collection.ListUtils.last; import static org.opentripplanner.model.plan.Itinerary.toStr; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; +import static org.opentripplanner.utils.collection.ListUtils.first; +import static org.opentripplanner.utils.collection.ListUtils.last; import java.util.ArrayList; import java.util.List; @@ -13,18 +13,18 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.opentripplanner._support.debug.TestDebug; -import org.opentripplanner.framework.collection.ListSection; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.model.plan.SortOrder; import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.utils.collection.ListSection; +import org.opentripplanner.utils.time.TimeUtils; public class PagingFilterTest implements PlanTestConstants { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final Place A = TEST_MODEL.place("A", 10, 11); private static final Place B = TEST_MODEL.place("B", 10, 13); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/SingleCriteriaComparatorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/SingleCriteriaComparatorTest.java similarity index 96% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/SingleCriteriaComparatorTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/SingleCriteriaComparatorTest.java index 3626ada63b3..da55d884d5c 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/SingleCriteriaComparatorTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/SingleCriteriaComparatorTest.java @@ -9,12 +9,12 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Place; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.network.grouppriority.DefaultTransitGroupPriorityCalculator; class SingleCriteriaComparatorTest { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final DefaultTransitGroupPriorityCalculator GROUP_PRIORITY_CALCULATOR = new DefaultTransitGroupPriorityCalculator(); private static final Place A = TEST_MODEL.place("A", 10, 11); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/ItemTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/ItemTest.java similarity index 91% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/ItemTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/ItemTest.java index c8cd04212e5..ea8ed58ae3a 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/ItemTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/ItemTest.java @@ -9,11 +9,11 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Place; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; class ItemTest { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final Place A = TEST_MODEL.place("A", 10, 11); private static final Place B = TEST_MODEL.place("B", 10, 11); private static final Itinerary ITINERARY = newItinerary(A).bus(1, 1, 2, B).build(); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/McMaxLimitFilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/McMaxLimitFilterTest.java similarity index 97% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/McMaxLimitFilterTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/McMaxLimitFilterTest.java index d5f2323ad90..3a192853684 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/McMaxLimitFilterTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/mcmax/McMaxLimitFilterTest.java @@ -11,12 +11,12 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Place; import org.opentripplanner.routing.algorithm.filterchain.filters.system.SingleCriteriaComparator; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.network.grouppriority.DefaultTransitGroupPriorityCalculator; class McMaxLimitFilterTest { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final DefaultTransitGroupPriorityCalculator GROUP_PRIORITY_CALCULATOR = new DefaultTransitGroupPriorityCalculator(); private static final Place A = TEST_MODEL.place("A", 10, 11); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLegTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLegTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLegTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLegTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetterTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetterTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetterTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitAlertFilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitAlertFilterTest.java similarity index 91% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitAlertFilterTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitAlertFilterTest.java index 379eb207155..8c64d7231d8 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitAlertFilterTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitAlertFilterTest.java @@ -12,7 +12,7 @@ import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.impl.TransitAlertServiceImpl; import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; class TransitAlertFilterTest implements PlanTestConstants { @@ -20,7 +20,7 @@ class TransitAlertFilterTest implements PlanTestConstants { @Test void testFilter() { - var transitAlertService = new TransitAlertServiceImpl(new TransitModel()); + var transitAlertService = new TransitAlertServiceImpl(new TimetableRepository()); transitAlertService.setAlerts( List.of( TransitAlert diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilterTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilterTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilterTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSameTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSameTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSameTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSameTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCostTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCostTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCostTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCostTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilterTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilterTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilterTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilterTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilterTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilterTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/SortingFilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/SortingFilterTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/SortingFilterTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/SortingFilterTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandlerTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandlerTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandlerTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandlerTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacherTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacherTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacherTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacherTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStationsTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStationsTest.java similarity index 94% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStationsTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStationsTest.java index 692f3a61ca7..7ee32b845f2 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStationsTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStationsTest.java @@ -7,13 +7,13 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.site.RegularStopBuilder; import org.opentripplanner.transit.model.site.Station; class GroupByAllSameStationsTest implements PlanTestConstants { - private final TransitModelForTest testModel = TransitModelForTest.of(); + private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of(); Station STATION_1 = testModel.station("1").build(); Station STATION_2 = testModel.station("2").build(); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistanceTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistanceTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistanceTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistanceTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameFirstOrLastTripTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameFirstOrLastTripTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameFirstOrLastTripTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameFirstOrLastTripTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStopsTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStopsTest.java similarity index 93% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStopsTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStopsTest.java index 26d3ca1d04b..48772cb69e2 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStopsTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStopsTest.java @@ -8,13 +8,13 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.network.Route; class GroupBySameRoutesAndStopsTest implements PlanTestConstants { - Route routeA = TransitModelForTest.route("A").build(); - Route routeB = TransitModelForTest.route("B").build(); + Route routeA = TimetableRepositoryForTest.route("A").build(); + Route routeB = TimetableRepositoryForTest.route("B").build(); Itinerary i1 = newItinerary(A) .bus(routeA, 21, T11_06, T11_28, E) diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnGeneralizedCostTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnGeneralizedCostTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnGeneralizedCostTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnGeneralizedCostTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnNumberOfTransfersTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnNumberOfTransfersTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnNumberOfTransfersTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnNumberOfTransfersTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparatorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparatorTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparatorTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparatorTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/BikeRentalSnapshotTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/BikeRentalSnapshotTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/mapping/BikeRentalSnapshotTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/mapping/BikeRentalSnapshotTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/CarSnapshotTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/CarSnapshotTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/mapping/CarSnapshotTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/mapping/CarSnapshotTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/ElevationSnapshotTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/ElevationSnapshotTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/mapping/ElevationSnapshotTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/mapping/ElevationSnapshotTest.java diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapperTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapperTest.java new file mode 100644 index 00000000000..2d5c1b1770b --- /dev/null +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapperTest.java @@ -0,0 +1,40 @@ +package org.opentripplanner.routing.algorithm.mapping; + +import static org.junit.jupiter.api.Assertions.assertFalse; + +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.opentripplanner._support.time.ZoneIds; +import org.opentripplanner.astar.model.GraphPath; +import org.opentripplanner.routing.services.notes.StreetNotesService; +import org.opentripplanner.street.search.state.State; +import org.opentripplanner.street.search.state.TestStateBuilder; + +class GraphPathToItineraryMapperTest { + + private static Stream cases() { + return Stream + .of( + TestStateBuilder.ofWalking(), + TestStateBuilder.ofCycling(), + TestStateBuilder.ofDriving(), + TestStateBuilder.ofScooterRental().pickUpFreeFloatingScooter(), + TestStateBuilder.ofBikeAndRide(), + TestStateBuilder.parkAndRide() + ) + .map(b -> { + var state = b.streetEdge().streetEdge().build(); + return Arguments.argumentSet(state.currentMode().toString(), state); + }); + } + + @ParameterizedTest + @MethodSource("cases") + void isSearchWindowAware(State state) { + var mapper = new GraphPathToItineraryMapper(ZoneIds.UTC, new StreetNotesService(), 1); + var itin = mapper.generateItinerary(new GraphPath<>(state)); + assertFalse(itin.isSearchWindowAware()); + } +} diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactoryTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactoryTest.java similarity index 95% rename from src/test/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactoryTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactoryTest.java index 369f58d6ef1..0eb7bfae1d3 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactoryTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactoryTest.java @@ -7,14 +7,14 @@ import java.time.Instant; import java.util.List; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; -import org.opentripplanner.raptor._data.transit.TestAccessEgress; import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; import org.opentripplanner.raptor.api.request.RaptorTuningParameters; import org.opentripplanner.raptor.api.request.SearchParams; +import org.opentripplanner.raptorlegacy._data.transit.TestAccessEgress; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitTuningParameters; import org.opentripplanner.routing.api.request.RouteRequest; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; class PagingServiceFactoryTest { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java similarity index 63% rename from src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java index 8f5d1a0208e..8f2fc45b875 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java @@ -1,9 +1,11 @@ package org.opentripplanner.routing.algorithm.mapping; +import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.opentripplanner.raptor._data.RaptorTestConstants.BOARD_SLACK; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.raptorlegacy._data.RaptorTestConstants.BOARD_SLACK; import java.time.Duration; import java.time.Instant; @@ -11,6 +13,7 @@ import java.time.Month; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -18,18 +21,16 @@ import org.opentripplanner._support.time.ZoneIds; import org.opentripplanner.ext.flex.FlexAccessEgress; import org.opentripplanner.ext.flex.FlexPathDurations; +import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.framework.model.TimeAndCost; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.StopTime; -import org.opentripplanner.raptor._data.api.TestPathBuilder; -import org.opentripplanner.raptor._data.transit.TestAccessEgress; -import org.opentripplanner.raptor._data.transit.TestRoute; -import org.opentripplanner.raptor._data.transit.TestTransitData; -import org.opentripplanner.raptor._data.transit.TestTripPattern; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.model.plan.Leg; +import org.opentripplanner.model.plan.ScheduledTransitLeg; +import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.AccessPathLeg; @@ -39,32 +40,37 @@ import org.opentripplanner.raptor.api.path.TransferPathLeg; import org.opentripplanner.raptor.path.Path; import org.opentripplanner.raptor.spi.RaptorCostCalculator; +import org.opentripplanner.raptorlegacy._data.api.TestPathBuilder; +import org.opentripplanner.raptorlegacy._data.transit.TestAccessEgress; +import org.opentripplanner.raptorlegacy._data.transit.TestRoute; +import org.opentripplanner.raptorlegacy._data.transit.TestTransitData; +import org.opentripplanner.raptorlegacy._data.transit.TestTripPattern; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; +import org.opentripplanner.routing.algorithm.raptoradapter.router.street.AccessEgressType; import org.opentripplanner.routing.algorithm.raptoradapter.transit.DefaultAccessEgress; import org.opentripplanner.routing.algorithm.raptoradapter.transit.DefaultRaptorTransfer; import org.opentripplanner.routing.algorithm.raptoradapter.transit.FlexAccessEgressAdapter; import org.opentripplanner.routing.algorithm.raptoradapter.transit.Transfer; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitLayer; import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.DefaultCostCalculator; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.street.search.state.State; import org.opentripplanner.street.search.state.TestStateBuilder; -import org.opentripplanner.transit.model._data.TransitModelForTest; -import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.StopPattern; import org.opentripplanner.transit.model.network.TripPattern; -import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.timetable.booking.RoutingBookingInfo; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; +import org.opentripplanner.utils.time.TimeUtils; public class RaptorPathToItineraryMapperTest { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final int BOARD_COST_SEC = 60; private static final int TRANSFER_COST_SEC = 120; private static final double[] TRANSIT_RELUCTANCE = new double[] { 1.0 }; @@ -73,8 +79,7 @@ public class RaptorPathToItineraryMapperTest { private static final int TRANSIT_START = TimeUtils.time("10:00"); private static final int TRANSIT_END = TimeUtils.time("11:00"); - - private final TestTransitData data = new TestTransitData(); + private static final Route ROUTE = TimetableRepositoryForTest.route("route").build(); public static final RaptorCostCalculator COST_CALCULATOR = new DefaultCostCalculator<>( BOARD_COST_SEC, @@ -84,9 +89,9 @@ public class RaptorPathToItineraryMapperTest { STOP_COSTS ); - private static final RegularStop S1 = TEST_MODEL.stop("STOP1", 0.0, 0.0).build(); - - private static final RegularStop S2 = TEST_MODEL.stop("STOP2", 1.0, 1.0).build(); + private static final RegularStop S1 = TEST_MODEL.stop("STOP1").build(); + private static final RegularStop S2 = TEST_MODEL.stop("STOP2").build(); + private static final RegularStop S3 = TEST_MODEL.stop("STOP3").build(); @ParameterizedTest @ValueSource(ints = { 0, 3000, -3000 }) @@ -113,6 +118,35 @@ void createItineraryTestZeroDurationEgress(int lastLegCost) { ); } + @Test + void noExtraLegWhenTransferringAtSameStop() { + var mapper = getRaptorPathToItineraryMapper(); + + var path = transferAtSameStopPath(); + var itinerary = mapper.createItinerary(path); + assertThat(itinerary.getLegs().stream().map(Object::getClass)).doesNotContain(StreetLeg.class); + } + + @Test + void extraLegWhenTransferringAtSameStop() { + RaptorPathToItineraryMapper mapper = getRaptorPathToItineraryMapper(); + + var schedule = getTestTripSchedule2(); + var path = new TestPathBuilder(COST_CALCULATOR) + .access(TRANSIT_START - BOARD_SLACK, 1) + .bus(schedule, 2) + .bus(schedule, 1) + .egress(TestAccessEgress.free(1, RaptorCostConverter.toRaptorCost(100))); + + OTPFeature.ExtraTransferLegOnSameStop.testOn(() -> { + var itinerary = mapper.createItinerary(path); + assertEquals( + List.of(ScheduledTransitLeg.class, StreetLeg.class, ScheduledTransitLeg.class), + itinerary.getLegs().stream().map(Leg::getClass).toList() + ); + }); + } + @Test @Disabled("Need to write a general test framework to enable this.") void penalty() { @@ -161,7 +195,10 @@ void createItineraryWithOnBoardFlexAccess() { true, RoutingBookingInfo.NOT_SET ); - RaptorAccessEgress access = new FlexAccessEgressAdapter(flexAccessEgress, false); + RaptorAccessEgress access = new FlexAccessEgressAdapter( + flexAccessEgress, + AccessEgressType.ACCESS + ); Transfer transfer = new Transfer(S2.getIndex(), 0); RaptorTransfer raptorTransfer = new DefaultRaptorTransfer(S1.getIndex(), 0, 0, transfer); RaptorAccessEgress egress = new DefaultAccessEgress(S2.getIndex(), state); @@ -184,12 +221,52 @@ void createItineraryWithOnBoardFlexAccess() { assertEquals(3, itinerary.getLegs().size(), "The wrong number of legs was returned"); } + private RaptorPath transferAtSameStopPath() { + var schedule = transferAtSameStopSchedule(); + return new TestPathBuilder(COST_CALCULATOR) + .access(TRANSIT_START, 1) + .bus(schedule, 2) + .bus(schedule, 1) + .egress(TestAccessEgress.free(1, RaptorCostConverter.toRaptorCost(100))); + } + + private TestTripSchedule transferAtSameStopSchedule() { + TestTransitData data = new TestTransitData(); + var pattern = TestTripPattern.pattern("TestPattern", 1, 2, 3, 2, 1).withRoute(ROUTE); + + var timetable = new TestTripSchedule.Builder() + .times( + TimeUtils.time("10:00"), + TimeUtils.time("10:05"), + TimeUtils.time("10:10"), + TimeUtils.time("10:15"), + TimeUtils.time("10:20") + ) + .pattern(pattern) + .originalPattern(getOriginalPattern(pattern)) + .build(); + + data.withRoutes(TestRoute.route("TransferAtSameStop", 1, 2, 3, 2, 1).withTimetable(timetable)); + + return data.getRoute(0).getTripSchedule(0); + } + + @Test + void isSearchWindowAware() { + var mapper = getRaptorPathToItineraryMapper(); + + var path = createTestTripSchedulePath(getTestTripSchedule()) + .egress(TestAccessEgress.free(2, RaptorCostConverter.toRaptorCost(100))); + var itinerary = mapper.createItinerary(path); + assertTrue(itinerary.isSearchWindowAware()); + } + private TripPattern getOriginalPattern(TestTripPattern pattern) { - var stopModelBuilder = TEST_MODEL.stopModelBuilder(); + var siteRepositoryBuilder = TEST_MODEL.siteRepositoryBuilder(); ArrayList stopTimes = new ArrayList<>(); for (int i = 0; i < pattern.numberOfStopsInPattern(); i++) { - var stop = stopModelBuilder + var stop = siteRepositoryBuilder .regularStop(new FeedScopedId("TestFeed", i + "")) .withCoordinate(0.0, 0.0) .build(); @@ -217,11 +294,11 @@ private RaptorPathToItineraryMapper getRaptorPathToItineraryMa .of(2022, Month.OCTOBER, 10, 12, 0, 0) .atZone(ZoneIds.STOCKHOLM) .toInstant(); - TransitModel transitModel = new TransitModel(); - transitModel.initTimeZone(ZoneIds.CET); + TimetableRepository timetableRepository = new TimetableRepository(); + timetableRepository.initTimeZone(ZoneIds.CET); return new RaptorPathToItineraryMapper<>( new Graph(), - new DefaultTransitService(transitModel), + new DefaultTransitService(timetableRepository), getTransitLayer(), dateTime.atZone(ZoneIds.CET), new RouteRequest() @@ -233,7 +310,12 @@ private static TransitLayer getTransitLayer() { new HashMap<>(), null, null, - TEST_MODEL.stopModelBuilder().withRegularStop(S1).withRegularStop(S2).build(), + TEST_MODEL + .siteRepositoryBuilder() + .withRegularStop(S1) + .withRegularStop(S2) + .withRegularStop(S3) + .build(), null, null, null, @@ -241,21 +323,30 @@ private static TransitLayer getTransitLayer() { ); } - private TestTripSchedule getTestTripSchedule() { - var agency = Agency - .of(new FeedScopedId("TestFeed", "Auth_1")) - .withName("Test_Agency") - .withTimezone("Europe/Stockholm") - .build(); + private TestTripSchedule getTestTripSchedule2() { + TestTransitData data = new TestTransitData(); + var pattern = TestTripPattern.pattern("TestPattern", 1, 2, 3, 2, 1).withRoute(ROUTE); - var route = Route - .of(new FeedScopedId("TestFeed", "Line_1")) - .withAgency(agency) - .withMode(TransitMode.BUS) - .withShortName("Test_Bus") + var timetable = new TestTripSchedule.Builder() + .times( + TimeUtils.time("10:00"), + TimeUtils.time("10:05"), + TimeUtils.time("10:10"), + TimeUtils.time("10:15"), + TimeUtils.time("10:20") + ) + .pattern(pattern) + .originalPattern(getOriginalPattern(pattern)) .build(); - var pattern = TestTripPattern.pattern("TestPattern", 1, 2).withRoute(route); + data.withRoutes(TestRoute.route("TestRoute_1", 1, 2, 3, 2, 1).withTimetable(timetable)); + + return data.getRoute(0).getTripSchedule(0); + } + + private TestTripSchedule getTestTripSchedule() { + TestTransitData data = new TestTransitData(); + var pattern = TestTripPattern.pattern("TestPattern", 1, 2).withRoute(ROUTE); var timetable = new TestTripSchedule.Builder() .times(TRANSIT_START, TRANSIT_END) diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java similarity index 98% rename from src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java index 8dbf5536ea2..cab308c092b 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java @@ -41,7 +41,6 @@ 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; import org.opentripplanner.model.plan.Leg; @@ -54,6 +53,7 @@ import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.transit.model.basic.MainAndSubMode; import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.utils.time.TimeUtils; /** * A base class for creating snapshots test of itinerary generation using the Portland graph. @@ -85,7 +85,8 @@ public static void loadGraphBeforeClass(boolean withElevation) { protected OtpServerRequestContext serverContext() { if (serverContext == null) { TestOtpModel model = getGraph(); - serverContext = TestServerContext.createServerContext(model.graph(), model.transitModel()); + serverContext = + TestServerContext.createServerContext(model.graph(), model.timetableRepository()); } return serverContext; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapperTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapperTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapperTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/TransitSnapshotTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/TransitSnapshotTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/mapping/TransitSnapshotTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/mapping/TransitSnapshotTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap rename to application/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap similarity index 99% rename from src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap rename to application/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap index 5d83d85cd7a..80614689ff4 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap @@ -98,13 +98,13 @@ org.opentripplanner.routing.algorithm.mapping.CarSnapshotTest.directCarPark=[ "lon" : -122.7016859, "name" : "P+R (#2)", "vehicleParking" : { - "entranceId" : "OSM:OSMWay/-102488/osm:node:-102438", + "entranceId" : "OSM:OsmWay/-102488/osm:node:-102438", "entranceName" : "P+R (#2)", "hasAnyCarPlaces" : true, "hasBicyclePlaces" : false, "hasCarPlaces" : true, "hasWheelchairAccessibleCarPlaces" : false, - "id" : "OSM:OSMWay/-102488", + "id" : "OSM:OsmWay/-102488", "name" : "P+R", "realtime" : false, "tags" : [ @@ -129,13 +129,13 @@ org.opentripplanner.routing.algorithm.mapping.CarSnapshotTest.directCarPark=[ "lon" : -122.7016931, "name" : "P+R (#1)", "vehicleParking" : { - "entranceId" : "OSM:OSMWay/-102488/osm:node:-102437", + "entranceId" : "OSM:OsmWay/-102488/osm:node:-102437", "entranceName" : "P+R (#1)", "hasAnyCarPlaces" : true, "hasBicyclePlaces" : false, "hasCarPlaces" : true, "hasWheelchairAccessibleCarPlaces" : false, - "id" : "OSM:OSMWay/-102488", + "id" : "OSM:OsmWay/-102488", "name" : "P+R", "realtime" : false, "tags" : [ diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap rename to application/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap similarity index 83% rename from src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap rename to application/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap index adc5ee69635..0f00b88e65b 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap @@ -230,10 +230,10 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan }, { "arrivedAtDestinationWithRentedBicycle" : false, - "duration" : 2261, + "duration" : 2020, "elevationGained" : 0.0, "elevationLost" : 0.0, - "endTime" : "2009-11-17T18:38:41.000+00:00", + "endTime" : "2009-11-17T18:35:19.000+00:00", "fare" : { "details" : { }, "fare" : { }, @@ -257,42 +257,62 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "name" : "regular" } ] + }, + { + "legIndices" : [ + 3 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "regular" + } + ] } ] }, - "generalizedCost" : 4281, + "generalizedCost" : 4023, "legs" : [ { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 920.33, - "endTime" : "2009-11-17T18:12:58.000+00:00", + "distance" : 1022.47, + "endTime" : "2009-11-17T18:14:50.000+00:00", "from" : { - "departure" : "2009-11-17T18:01:00.000+00:00", + "departure" : "2009-11-17T18:01:39.000+00:00", "lat" : 45.51726, "lon" : -122.64847, "name" : "SE Morrison St. & SE 17th Ave. (P1)", "vertexType" : "NORMAL" }, - "generalizedCost" : 1398, + "generalizedCost" : 1543, "interlineWithPreviousLeg" : false, "legGeometry" : { - "length" : 45, - "points" : "kaytG~wqkV?T?fCAl@?RmC?oCAmCAoC?_CAM?aC??A?A?A?A??AA?AAA??AAA???A?A?A???A@A??@A@?@??A@?@?BcC?mCAmCAmC?QBIYIWOH" + "length" : 37, + "points" : "kaytG~wqkV?T?fCAl@?R?jE?rC?t@?hEAvD?R?R?|@?dBAP?PAxD?nD?X?jE?bA?t@?N?Z?ZAX?^@bBAt@?zC?N?J?NQ?O?sA@?W" }, "mode" : "WALK", "pathway" : false, "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T18:01:00.000+00:00", + "startTime" : "2009-11-17T18:01:39.000+00:00", "steps" : [ { "absoluteDirection" : "WEST", "area" : false, "bogusName" : false, - "distance" : 87.68, + "distance" : 956.36, "elevation" : "", "lat" : 45.517186, "lon" : -122.6484704, @@ -305,50 +325,24 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "absoluteDirection" : "NORTH", "area" : false, "bogusName" : false, - "distance" : 641.04, - "elevation" : "", - "lat" : 45.5171903, - "lon" : -122.6495956, - "relativeDirection" : "RIGHT", - "stayOn" : false, - "streetName" : "Southeast 16th Avenue", - "walkingBike" : false - }, - { - "absoluteDirection" : "NORTH", - "area" : false, - "bogusName" : false, - "distance" : 168.89, - "elevation" : "", - "lat" : 45.5228912, - "lon" : -122.6495528, - "relativeDirection" : "CONTINUE", - "stayOn" : false, - "streetName" : "Northeast 16th Avenue", - "walkingBike" : false - }, - { - "absoluteDirection" : "NORTHEAST", - "area" : false, - "bogusName" : false, - "distance" : 22.74, + "distance" : 66.13, "elevation" : "", - "lat" : 45.524409, - "lon" : -122.6495675, + "lat" : 45.5172325, + "lon" : -122.6607432, "relativeDirection" : "RIGHT", "stayOn" : false, - "streetName" : "Northeast Sandy Boulevard", + "streetName" : "Southeast Grand Avenue", "walkingBike" : false } ], "to" : { - "arrival" : "2009-11-17T18:12:58.000+00:00", - "departure" : "2009-11-17T18:12:58.000+00:00", - "lat" : 45.524581, - "lon" : -122.649367, - "name" : "NE Sandy & 16th", - "stopCode" : "5060", - "stopId" : "prt:5060", + "arrival" : "2009-11-17T18:14:50.000+00:00", + "departure" : "2009-11-17T18:14:50.000+00:00", + "lat" : 45.517828, + "lon" : -122.660632, + "name" : "SE Grand & Alder", + "stopCode" : "11485", + "stopId" : "prt:11485", "vertexType" : "TRANSIT", "zoneId" : "1" }, @@ -362,312 +356,403 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "agencyUrl" : "http://trimet.org", "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 3602.73, - "endTime" : "2009-11-17T18:25:49.000+00:00", + "distance" : 1580.92, + "endTime" : "2009-11-17T18:18:49.000+00:00", "from" : { - "arrival" : "2009-11-17T18:12:58.000+00:00", - "departure" : "2009-11-17T18:12:58.000+00:00", - "lat" : 45.524581, - "lon" : -122.649367, - "name" : "NE Sandy & 16th", - "stopCode" : "5060", - "stopId" : "prt:5060", - "stopIndex" : 92, - "stopSequence" : 93, + "arrival" : "2009-11-17T18:14:50.000+00:00", + "departure" : "2009-11-17T18:14:50.000+00:00", + "lat" : 45.517828, + "lon" : -122.660632, + "name" : "SE Grand & Alder", + "stopCode" : "11485", + "stopId" : "prt:11485", + "stopIndex" : 11, + "stopSequence" : 12, "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 1371, - "headsign" : "Beaverton TC", + "generalizedCost" : 839, + "headsign" : "Jantzen Beach", "interlineWithPreviousLeg" : false, "intermediateStops" : [ { - "arrival" : "2009-11-17T18:13:32.000+00:00", - "departure" : "2009-11-17T18:13:32.000+00:00", - "lat" : 45.523767, - "lon" : -122.651428, - "name" : "NE Sandy & 14th", - "stopCode" : "5058", - "stopId" : "prt:5058", - "stopIndex" : 93, - "stopSequence" : 94, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:14:00.000+00:00", - "departure" : "2009-11-17T18:14:00.000+00:00", - "lat" : 45.523103, - "lon" : -122.653064, - "name" : "NE Sandy & 12th", - "stopCode" : "5055", - "stopId" : "prt:5055", - "stopIndex" : 94, - "stopSequence" : 95, + "arrival" : "2009-11-17T18:15:25.000+00:00", + "departure" : "2009-11-17T18:15:25.000+00:00", + "lat" : 45.519986, + "lon" : -122.660636, + "name" : "SE Grand & Oak", + "stopCode" : "2174", + "stopId" : "prt:2174", + "stopIndex" : 12, + "stopSequence" : 13, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:14:47.000+00:00", - "departure" : "2009-11-17T18:14:47.000+00:00", - "lat" : 45.523024, - "lon" : -122.656526, - "name" : "E Burnside & NE 9th", - "stopCode" : "819", - "stopId" : "prt:819", - "stopIndex" : 95, - "stopSequence" : 96, + "arrival" : "2009-11-17T18:16:10.000+00:00", + "departure" : "2009-11-17T18:16:10.000+00:00", + "lat" : 45.522782, + "lon" : -122.660589, + "name" : "SE Grand & E Burnside", + "stopCode" : "2167", + "stopId" : "prt:2167", + "stopIndex" : 13, + "stopSequence" : 14, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:15:24.000+00:00", - "departure" : "2009-11-17T18:15:24.000+00:00", - "lat" : 45.523012, - "lon" : -122.659365, - "name" : "E Burnside & NE 6th", - "stopCode" : "805", - "stopId" : "prt:805", - "stopIndex" : 96, - "stopSequence" : 97, + "arrival" : "2009-11-17T18:16:39.000+00:00", + "departure" : "2009-11-17T18:16:39.000+00:00", + "lat" : 45.524582, + "lon" : -122.660578, + "name" : "NE Grand & Davis", + "stopCode" : "8829", + "stopId" : "prt:8829", + "stopIndex" : 14, + "stopSequence" : 15, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:15:52.000+00:00", - "departure" : "2009-11-17T18:15:52.000+00:00", - "lat" : 45.523015, - "lon" : -122.661534, - "name" : "E Burnside & NE M L King", - "stopCode" : "705", - "stopId" : "prt:705", - "stopIndex" : 97, - "stopSequence" : 98, + "arrival" : "2009-11-17T18:17:26.000+00:00", + "departure" : "2009-11-17T18:17:26.000+00:00", + "lat" : 45.527519, + "lon" : -122.66056, + "name" : "NE Grand & Hoyt", + "stopCode" : "2169", + "stopId" : "prt:2169", + "stopIndex" : 15, + "stopSequence" : 16, "vertexType" : "TRANSIT", "zoneId" : "1" }, { "arrival" : "2009-11-17T18:18:00.000+00:00", "departure" : "2009-11-17T18:18:00.000+00:00", - "lat" : 45.523249, - "lon" : -122.671269, - "name" : "W Burnside & Burnside Bridge", - "stopCode" : "689", - "stopId" : "prt:689", - "stopIndex" : 98, - "stopSequence" : 99, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - { - "arrival" : "2009-11-17T18:19:00.000+00:00", - "departure" : "2009-11-17T18:19:00.000+00:00", - "lat" : 45.523169, - "lon" : -122.675893, - "name" : "W Burnside & NW 5th", - "stopCode" : "782", - "stopId" : "prt:782", - "stopIndex" : 99, - "stopSequence" : 100, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - { - "arrival" : "2009-11-17T18:20:17.000+00:00", - "departure" : "2009-11-17T18:20:17.000+00:00", - "lat" : 45.523115, - "lon" : -122.678939, - "name" : "W Burnside & NW Park", - "stopCode" : "716", - "stopId" : "prt:716", - "stopIndex" : 100, - "stopSequence" : 101, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - { - "arrival" : "2009-11-17T18:21:25.000+00:00", - "departure" : "2009-11-17T18:21:25.000+00:00", - "lat" : 45.523048, - "lon" : -122.681606, - "name" : "W Burnside & NW 10th", - "stopCode" : "10791", - "stopId" : "prt:10791", - "stopIndex" : 101, - "stopSequence" : 102, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - { - "arrival" : "2009-11-17T18:22:14.000+00:00", - "departure" : "2009-11-17T18:22:14.000+00:00", - "lat" : 45.523, - "lon" : -122.683535, - "name" : "W Burnside & NW 12th", - "stopCode" : "11032", - "stopId" : "prt:11032", - "stopIndex" : 102, - "stopSequence" : 103, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - { - "arrival" : "2009-11-17T18:24:09.000+00:00", - "departure" : "2009-11-17T18:24:09.000+00:00", - "lat" : 45.522985, - "lon" : -122.688091, - "name" : "W Burnside & NW 17th", - "stopCode" : "10809", - "stopId" : "prt:10809", - "stopIndex" : 103, - "stopSequence" : 104, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:25:00.000+00:00", - "departure" : "2009-11-17T18:25:00.000+00:00", - "lat" : 45.523097, - "lon" : -122.690083, - "name" : "W Burnside & NW 19th", - "stopCode" : "735", - "stopId" : "prt:735", - "stopIndex" : 104, - "stopSequence" : 105, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:25:21.000+00:00", - "departure" : "2009-11-17T18:25:21.000+00:00", - "lat" : 45.523176, - "lon" : -122.692139, - "name" : "W Burnside & NW 20th", - "stopCode" : "741", - "stopId" : "prt:741", - "stopIndex" : 105, - "stopSequence" : 106, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:25:31.000+00:00", - "departure" : "2009-11-17T18:25:31.000+00:00", - "lat" : 45.52322, - "lon" : -122.69313, - "name" : "W Burnside & NW 20th Pl", - "stopCode" : "742", - "stopId" : "prt:742", - "stopIndex" : 106, - "stopSequence" : 107, + "lat" : 45.529602, + "lon" : -122.660529, + "name" : "NE Grand & Pacific", + "stopCode" : "2175", + "stopId" : "prt:2175", + "stopIndex" : 16, + "stopSequence" : 17, "vertexType" : "TRANSIT", "zoneId" : "1" } ], "legGeometry" : { - "length" : 94, - "points" : "coztGd}qkVNl@r@`CZhA`A`D??Ph@l@tBb@rARh@Pd@???BPj@@jA?jEAhE?pD???VAjE?hE?dB?b@???`AAhE?dD???l@C`EAhEEhE?bAA|@?XAZ@\\AzACnGKbKAjC?bE???JEnE@fEDlE@hE@~A??@rBBzDBpE@~A???Z@tD@RBnEB|A???@BdB?lEBjA??BnBApF@dB?X?^@r@?f@@bCAx@EtB???VChAE|BGnD??AXKnEGnD???XGjD??AZEfCC`AEzB" + "length" : 35, + "points" : "meytGtdtkVC?OAQ?}B?mC?{BA??Q?oCAmC?mC?qBA??]?mC?mCAm@???aB?{AC[?kDAsCBq@A??uA?iCAgC?w@???yA?sCCoCAiB@" }, "mode" : "BUS", "pathway" : false, "realTime" : false, - "route" : "Burnside/Stark", - "routeId" : "prt:20", - "routeLongName" : "Burnside/Stark", - "routeShortName" : "20", + "route" : "Martin Luther King Jr Blvd", + "routeId" : "prt:6", + "routeLongName" : "Martin Luther King Jr Blvd", + "routeShortName" : "6", "routeType" : 3, "serviceDate" : "2009-11-17", - "startTime" : "2009-11-17T18:12:58.000+00:00", + "startTime" : "2009-11-17T18:14:50.000+00:00", "steps" : [ ], "to" : { - "arrival" : "2009-11-17T18:25:49.000+00:00", - "departure" : "2009-11-17T18:25:49.000+00:00", - "lat" : 45.523312, - "lon" : -122.694901, - "name" : "W Burnside & NW King", - "stopCode" : "747", - "stopId" : "prt:747", - "stopIndex" : 107, - "stopSequence" : 108, + "arrival" : "2009-11-17T18:18:49.000+00:00", + "departure" : "2009-11-17T18:18:49.000+00:00", + "lat" : 45.532047, + "lon" : -122.660537, + "name" : "NE Grand & Wasco", + "stopCode" : "10953", + "stopId" : "prt:10953", + "stopIndex" : 17, + "stopSequence" : 18, "vertexType" : "TRANSIT", "zoneId" : "1" }, "transitLeg" : true, - "tripBlockId" : "2002", - "tripId" : "prt:200W1200" + "tripBlockId" : "604", + "tripId" : "prt:60W1210" }, { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 999.1, - "endTime" : "2009-11-17T18:38:41.000+00:00", + "distance" : 51.83, + "endTime" : "2009-11-17T18:19:32.000+00:00", "from" : { - "arrival" : "2009-11-17T18:25:49.000+00:00", - "departure" : "2009-11-17T18:25:49.000+00:00", - "lat" : 45.523312, - "lon" : -122.694901, - "name" : "W Burnside & NW King", - "stopCode" : "747", - "stopId" : "prt:747", + "arrival" : "2009-11-17T18:18:49.000+00:00", + "departure" : "2009-11-17T18:18:49.000+00:00", + "lat" : 45.532047, + "lon" : -122.660537, + "name" : "NE Grand & Wasco", + "stopCode" : "10953", + "stopId" : "prt:10953", "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 1511, + "generalizedCost" : 80, "interlineWithPreviousLeg" : false, "legGeometry" : { - "length" : 29, - "points" : "ugztGdzzkVL?ATClAI|DK?G?mCBkCDoCDmCBoCDkCBoCB[?sBD]?Y@eA@K?C?K?W@{A@M@C@I?_CB?G" + "length" : 10, + "points" : "g~{tGjctkV?B`@?\\?R?@?@?BC???I" }, "mode" : "WALK", "pathway" : false, "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T18:25:49.000+00:00", + "startTime" : "2009-11-17T18:18:49.000+00:00", "steps" : [ { - "absoluteDirection" : "WEST", + "absoluteDirection" : "SOUTH", "area" : false, "bogusName" : false, - "distance" : 113.27, + "distance" : 51.83, "elevation" : "", - "lat" : 45.5232491, - "lon" : -122.6949067, + "lat" : 45.532047, + "lon" : -122.6605564, "relativeDirection" : "DEPART", "stayOn" : false, - "streetName" : "West Burnside Street", + "streetName" : "Northeast Grand Avenue", "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:19:32.000+00:00", + "departure" : "2009-11-17T18:22:05.000+00:00", + "lat" : 45.531586, + "lon" : -122.660482, + "name" : "NE Multnomah & Grand", + "stopCode" : "4043", + "stopId" : "prt:4043", + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyId" : "prt:prt", + "agencyName" : "TriMet", + "agencyTimeZoneOffset" : -28800000, + "agencyUrl" : "http://trimet.org", + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 3448.6, + "endTime" : "2009-11-17T18:34:55.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:19:32.000+00:00", + "departure" : "2009-11-17T18:22:05.000+00:00", + "lat" : 45.531586, + "lon" : -122.660482, + "name" : "NE Multnomah & Grand", + "stopCode" : "4043", + "stopId" : "prt:4043", + "stopIndex" : 82, + "stopSequence" : 83, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + "generalizedCost" : 1523, + "headsign" : "Montgomery Park", + "interlineWithPreviousLeg" : false, + "intermediateStops" : [ + { + "arrival" : "2009-11-17T18:23:09.000+00:00", + "departure" : "2009-11-17T18:23:09.000+00:00", + "lat" : 45.531159, + "lon" : -122.66293, + "name" : "NE Multnomah & 3rd", + "stopCode" : "11492", + "stopId" : "prt:11492", + "stopIndex" : 83, + "stopSequence" : 84, + "vertexType" : "TRANSIT", + "zoneId" : "0" }, { - "absoluteDirection" : "NORTH", - "area" : false, - "bogusName" : false, - "distance" : 882.16, - "elevation" : "", - "lat" : 45.5233204, - "lon" : -122.696357, - "relativeDirection" : "RIGHT", - "stayOn" : false, - "streetName" : "Northwest 22nd Avenue", - "walkingBike" : false + "arrival" : "2009-11-17T18:25:00.000+00:00", + "departure" : "2009-11-17T18:25:00.000+00:00", + "lat" : 45.530005, + "lon" : -122.666476, + "name" : "Rose Quarter Transit Center", + "stopCode" : "2592", + "stopId" : "prt:2592", + "stopIndex" : 84, + "stopSequence" : 85, + "vertexType" : "TRANSIT", + "zoneId" : "0" }, { - "absoluteDirection" : "EAST", + "arrival" : "2009-11-17T18:28:20.000+00:00", + "departure" : "2009-11-17T18:28:20.000+00:00", + "lat" : 45.526655, + "lon" : -122.676462, + "name" : "NW Glisan & 6th", + "stopCode" : "10803", + "stopId" : "prt:10803", + "stopIndex" : 85, + "stopSequence" : 86, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:29:15.000+00:00", + "departure" : "2009-11-17T18:29:15.000+00:00", + "lat" : 45.528799, + "lon" : -122.677238, + "name" : "NW Station Way & Union Station", + "stopCode" : "12801", + "stopId" : "prt:12801", + "stopIndex" : 86, + "stopSequence" : 87, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:31:00.000+00:00", + "departure" : "2009-11-17T18:31:00.000+00:00", + "lat" : 45.531582, + "lon" : -122.681193, + "name" : "NW Northrup & 10th", + "stopCode" : "12802", + "stopId" : "prt:12802", + "stopIndex" : 87, + "stopSequence" : 88, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:31:33.000+00:00", + "departure" : "2009-11-17T18:31:33.000+00:00", + "lat" : 45.531534, + "lon" : -122.683319, + "name" : "NW 12th & Northrup", + "stopCode" : "12796", + "stopId" : "prt:12796", + "stopIndex" : 88, + "stopSequence" : 89, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:32:04.000+00:00", + "departure" : "2009-11-17T18:32:04.000+00:00", + "lat" : 45.531503, + "lon" : -122.685357, + "name" : "NW Northrup & 14th", + "stopCode" : "10775", + "stopId" : "prt:10775", + "stopIndex" : 89, + "stopSequence" : 90, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:33:07.000+00:00", + "departure" : "2009-11-17T18:33:07.000+00:00", + "lat" : 45.531434, + "lon" : -122.689417, + "name" : "NW Northrup & 18th", + "stopCode" : "10776", + "stopId" : "prt:10776", + "stopIndex" : 90, + "stopSequence" : 91, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:34:24.000+00:00", + "departure" : "2009-11-17T18:34:24.000+00:00", + "lat" : 45.531346, + "lon" : -122.694455, + "name" : "NW Northrup & 21st", + "stopCode" : "10777", + "stopId" : "prt:10777", + "stopIndex" : 91, + "stopSequence" : 92, + "vertexType" : "TRANSIT", + "zoneId" : "1" + } + ], + "legGeometry" : { + "length" : 101, + "points" : "}z{tG~btkV?^?nE?V@Z?PH\\Nb@`@~@Rf@??`@bANb@FV@R?P?pE?jA@h@AnAbBl@LFJN\\f@LT??NXJPPVJFf@Vf@Pp@Nd@NRLB@RNXZR\\vAhC@BhAhD`AhClAbDBrDCnG@n@@^@d@HdAP`CBjEDvD???LqCFmCDYBGDEBGJkAzAQR??KNa@b@MJuBBY?OHW@u@~@aD`EcBhBBrD@xC??@l@BlE@lD???XBjEBpD???VBlE?dA@t@?b@?h@BfEBrD???VBhEFtKDvJ??@\\DnJ" + }, + "mode" : "BUS", + "pathway" : false, + "realTime" : false, + "route" : "Broadway/Halsey", + "routeId" : "prt:77", + "routeLongName" : "Broadway/Halsey", + "routeShortName" : "77", + "routeType" : 3, + "serviceDate" : "2009-11-17", + "startTime" : "2009-11-17T18:22:05.000+00:00", + "steps" : [ ], + "to" : { + "arrival" : "2009-11-17T18:34:55.000+00:00", + "departure" : "2009-11-17T18:34:55.000+00:00", + "lat" : 45.531308, + "lon" : -122.696445, + "name" : "NW Northrup & 22nd", + "stopCode" : "10778", + "stopId" : "prt:10778", + "stopIndex" : 92, + "stopSequence" : 93, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "transitLeg" : true, + "tripBlockId" : "7736", + "tripId" : "prt:771W1160" + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 18.81, + "endTime" : "2009-11-17T18:35:19.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:34:55.000+00:00", + "departure" : "2009-11-17T18:34:55.000+00:00", + "lat" : 45.531308, + "lon" : -122.696445, + "name" : "NW Northrup & 22nd", + "stopCode" : "10778", + "stopId" : "prt:10778", + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "generalizedCost" : 37, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 7, + "points" : "sy{tGxc{kV???LABF?B??J" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:34:55.000+00:00", + "steps" : [ + { + "absoluteDirection" : "WEST", "area" : false, "bogusName" : false, - "distance" : 3.68, + "distance" : 18.81, "elevation" : "", - "lat" : 45.5312508, - "lon" : -122.6966386, - "relativeDirection" : "RIGHT", + "lat" : 45.5313019, + "lon" : -122.6964448, + "relativeDirection" : "DEPART", "stayOn" : false, "streetName" : "Northwest Northrup Street", "walkingBike" : false } ], "to" : { - "arrival" : "2009-11-17T18:38:41.000+00:00", + "arrival" : "2009-11-17T18:35:19.000+00:00", "lat" : 45.53122, "lon" : -122.69659, "name" : "NW Northrup St. & NW 22nd Ave. (P2)", @@ -677,21 +762,21 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "walkingBike" : false } ], - "startTime" : "2009-11-17T18:01:00.000+00:00", + "startTime" : "2009-11-17T18:01:39.000+00:00", "tooSloped" : false, - "transfers" : 0, - "transitTime" : 771, - "waitingTime" : 0, - "walkDistance" : 1919.43, + "transfers" : 1, + "transitTime" : 1009, + "waitingTime" : 153, + "walkDistance" : 1093.11, "walkLimitExceeded" : false, - "walkTime" : 1490 + "walkTime" : 858 }, { "arrivedAtDestinationWithRentedBicycle" : false, - "duration" : 1470, + "duration" : 2261, "elevationGained" : 0.0, "elevationLost" : 0.0, - "endTime" : "2009-11-17T18:39:22.000+00:00", + "endTime" : "2009-11-17T18:38:41.000+00:00", "fare" : { "details" : { }, "fare" : { }, @@ -718,39 +803,39 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } ] }, - "generalizedCost" : 2315, + "generalizedCost" : 4281, "legs" : [ { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 62.01, - "endTime" : "2009-11-17T18:15:40.000+00:00", + "distance" : 920.33, + "endTime" : "2009-11-17T18:12:58.000+00:00", "from" : { - "departure" : "2009-11-17T18:14:52.000+00:00", + "departure" : "2009-11-17T18:01:00.000+00:00", "lat" : 45.51726, "lon" : -122.64847, "name" : "SE Morrison St. & SE 17th Ave. (P1)", "vertexType" : "NORMAL" }, - "generalizedCost" : 95, + "generalizedCost" : 1398, "interlineWithPreviousLeg" : false, "legGeometry" : { - "length" : 4, - "points" : "kaytG~wqkV?T?fCG?" + "length" : 45, + "points" : "kaytG~wqkV?T?fCAl@?RmC?oCAmCAoC?_CAM?aC??A?A?A?A??AA?AAA??AAA???A?A?A???A@A??@A@?@??A@?@?BcC?mCAmCAmC?QBIYIWOH" }, "mode" : "WALK", "pathway" : false, "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T18:14:52.000+00:00", + "startTime" : "2009-11-17T18:01:00.000+00:00", "steps" : [ { "absoluteDirection" : "WEST", "area" : false, "bogusName" : false, - "distance" : 62.02, + "distance" : 87.68, "elevation" : "", "lat" : 45.517186, "lon" : -122.6484704, @@ -758,16 +843,55 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "stayOn" : false, "streetName" : "Southeast Morrison Street", "walkingBike" : false - } - ], - "to" : { - "arrival" : "2009-11-17T18:15:40.000+00:00", - "departure" : "2009-11-17T18:15:40.000+00:00", - "lat" : 45.517226, - "lon" : -122.649266, - "name" : "SE Morrison & 16th", - "stopCode" : "4019", - "stopId" : "prt:4019", + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 641.04, + "elevation" : "", + "lat" : 45.5171903, + "lon" : -122.6495956, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Southeast 16th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 168.89, + "elevation" : "", + "lat" : 45.5228912, + "lon" : -122.6495528, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "Northeast 16th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTHEAST", + "area" : false, + "bogusName" : false, + "distance" : 22.74, + "elevation" : "", + "lat" : 45.524409, + "lon" : -122.6495675, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northeast Sandy Boulevard", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:12:58.000+00:00", + "departure" : "2009-11-17T18:12:58.000+00:00", + "lat" : 45.524581, + "lon" : -122.649367, + "name" : "NE Sandy & 16th", + "stopCode" : "5060", + "stopId" : "prt:5060", "vertexType" : "TRANSIT", "zoneId" : "1" }, @@ -781,416 +905,312 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "agencyUrl" : "http://trimet.org", "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 5218.86, - "endTime" : "2009-11-17T18:35:54.000+00:00", + "distance" : 3602.73, + "endTime" : "2009-11-17T18:25:49.000+00:00", "from" : { - "arrival" : "2009-11-17T18:15:40.000+00:00", - "departure" : "2009-11-17T18:15:40.000+00:00", - "lat" : 45.517226, - "lon" : -122.649266, - "name" : "SE Morrison & 16th", - "stopCode" : "4019", - "stopId" : "prt:4019", - "stopIndex" : 50, - "stopSequence" : 51, + "arrival" : "2009-11-17T18:12:58.000+00:00", + "departure" : "2009-11-17T18:12:58.000+00:00", + "lat" : 45.524581, + "lon" : -122.649367, + "name" : "NE Sandy & 16th", + "stopCode" : "5060", + "stopId" : "prt:5060", + "stopIndex" : 92, + "stopSequence" : 93, "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 1814, - "headsign" : "Montgomery Park", + "generalizedCost" : 1371, + "headsign" : "Beaverton TC", "interlineWithPreviousLeg" : false, "intermediateStops" : [ { - "arrival" : "2009-11-17T18:16:15.000+00:00", - "departure" : "2009-11-17T18:16:15.000+00:00", - "lat" : 45.517253, - "lon" : -122.651354, - "name" : "SE Morrison & 14th", - "stopCode" : "4016", - "stopId" : "prt:4016", - "stopIndex" : 51, - "stopSequence" : 52, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:17:00.000+00:00", - "departure" : "2009-11-17T18:17:00.000+00:00", - "lat" : 45.517299, - "lon" : -122.654067, - "name" : "SE Morrison & 12th", - "stopCode" : "4014", - "stopId" : "prt:4014", - "stopIndex" : 52, - "stopSequence" : 53, + "arrival" : "2009-11-17T18:13:32.000+00:00", + "departure" : "2009-11-17T18:13:32.000+00:00", + "lat" : 45.523767, + "lon" : -122.651428, + "name" : "NE Sandy & 14th", + "stopCode" : "5058", + "stopId" : "prt:5058", + "stopIndex" : 93, + "stopSequence" : 94, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:17:38.000+00:00", - "departure" : "2009-11-17T18:17:38.000+00:00", - "lat" : 45.517292, - "lon" : -122.656563, - "name" : "SE Morrison & 9th", - "stopCode" : "4026", - "stopId" : "prt:4026", - "stopIndex" : 53, - "stopSequence" : 54, + "arrival" : "2009-11-17T18:14:00.000+00:00", + "departure" : "2009-11-17T18:14:00.000+00:00", + "lat" : 45.523103, + "lon" : -122.653064, + "name" : "NE Sandy & 12th", + "stopCode" : "5055", + "stopId" : "prt:5055", + "stopIndex" : 94, + "stopSequence" : 95, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:18:08.000+00:00", - "departure" : "2009-11-17T18:18:08.000+00:00", - "lat" : 45.517322, - "lon" : -122.65847, - "name" : "SE Morrison & 7th", - "stopCode" : "4025", - "stopId" : "prt:4025", - "stopIndex" : 54, - "stopSequence" : 55, + "arrival" : "2009-11-17T18:14:47.000+00:00", + "departure" : "2009-11-17T18:14:47.000+00:00", + "lat" : 45.523024, + "lon" : -122.656526, + "name" : "E Burnside & NE 9th", + "stopCode" : "819", + "stopId" : "prt:819", + "stopIndex" : 95, + "stopSequence" : 96, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:18:39.000+00:00", - "departure" : "2009-11-17T18:18:39.000+00:00", - "lat" : 45.517298, - "lon" : -122.660523, - "name" : "SE Morrison & Grand", - "stopCode" : "4013", - "stopId" : "prt:4013", - "stopIndex" : 55, - "stopSequence" : 56, + "arrival" : "2009-11-17T18:15:24.000+00:00", + "departure" : "2009-11-17T18:15:24.000+00:00", + "lat" : 45.523012, + "lon" : -122.659365, + "name" : "E Burnside & NE 6th", + "stopCode" : "805", + "stopId" : "prt:805", + "stopIndex" : 96, + "stopSequence" : 97, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:20:03.000+00:00", - "departure" : "2009-11-17T18:20:03.000+00:00", - "lat" : 45.517351, - "lon" : -122.66601, - "name" : "Morrison Bridge", - "stopCode" : "4029", - "stopId" : "prt:4029", - "stopIndex" : 56, - "stopSequence" : 57, + "arrival" : "2009-11-17T18:15:52.000+00:00", + "departure" : "2009-11-17T18:15:52.000+00:00", + "lat" : 45.523015, + "lon" : -122.661534, + "name" : "E Burnside & NE M L King", + "stopCode" : "705", + "stopId" : "prt:705", + "stopIndex" : 97, + "stopSequence" : 98, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:22:27.000+00:00", - "departure" : "2009-11-17T18:22:27.000+00:00", - "lat" : 45.51959, - "lon" : -122.674599, - "name" : "SW Washington & 3rd", - "stopCode" : "6158", - "stopId" : "prt:6158", - "stopIndex" : 57, - "stopSequence" : 58, + "arrival" : "2009-11-17T18:18:00.000+00:00", + "departure" : "2009-11-17T18:18:00.000+00:00", + "lat" : 45.523249, + "lon" : -122.671269, + "name" : "W Burnside & Burnside Bridge", + "stopCode" : "689", + "stopId" : "prt:689", + "stopIndex" : 98, + "stopSequence" : 99, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:23:00.000+00:00", - "departure" : "2009-11-17T18:23:00.000+00:00", - "lat" : 45.520129, - "lon" : -122.676635, - "name" : "SW Washington & 5th", - "stopCode" : "6160", - "stopId" : "prt:6160", - "stopIndex" : 58, - "stopSequence" : 59, + "arrival" : "2009-11-17T18:19:00.000+00:00", + "departure" : "2009-11-17T18:19:00.000+00:00", + "lat" : 45.523169, + "lon" : -122.675893, + "name" : "W Burnside & NW 5th", + "stopCode" : "782", + "stopId" : "prt:782", + "stopIndex" : 99, + "stopSequence" : 100, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:23:52.000+00:00", - "departure" : "2009-11-17T18:23:52.000+00:00", - "lat" : 45.520695, - "lon" : -122.678657, - "name" : "SW Washington & Broadway", - "stopCode" : "6137", - "stopId" : "prt:6137", - "stopIndex" : 59, - "stopSequence" : 60, + "arrival" : "2009-11-17T18:20:17.000+00:00", + "departure" : "2009-11-17T18:20:17.000+00:00", + "lat" : 45.523115, + "lon" : -122.678939, + "name" : "W Burnside & NW Park", + "stopCode" : "716", + "stopId" : "prt:716", + "stopIndex" : 100, + "stopSequence" : 101, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:24:34.000+00:00", - "departure" : "2009-11-17T18:24:34.000+00:00", - "lat" : 45.521124, - "lon" : -122.6803, - "name" : "SW Washington & 9th", - "stopCode" : "6169", - "stopId" : "prt:6169", - "stopIndex" : 60, - "stopSequence" : 61, + "arrival" : "2009-11-17T18:21:25.000+00:00", + "departure" : "2009-11-17T18:21:25.000+00:00", + "lat" : 45.523048, + "lon" : -122.681606, + "name" : "W Burnside & NW 10th", + "stopCode" : "10791", + "stopId" : "prt:10791", + "stopIndex" : 101, + "stopSequence" : 102, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:25:47.000+00:00", - "departure" : "2009-11-17T18:25:47.000+00:00", - "lat" : 45.521094, - "lon" : -122.682819, - "name" : "SW 11th & Alder", - "stopCode" : "9600", - "stopId" : "prt:9600", - "stopIndex" : 61, - "stopSequence" : 62, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - { - "arrival" : "2009-11-17T18:26:36.000+00:00", - "departure" : "2009-11-17T18:26:36.000+00:00", - "lat" : 45.52055, - "lon" : -122.683933, - "name" : "SW Morrison & 12th", - "stopCode" : "9598", - "stopId" : "prt:9598", - "stopIndex" : 62, - "stopSequence" : 63, + "arrival" : "2009-11-17T18:22:14.000+00:00", + "departure" : "2009-11-17T18:22:14.000+00:00", + "lat" : 45.523, + "lon" : -122.683535, + "name" : "W Burnside & NW 12th", + "stopCode" : "11032", + "stopId" : "prt:11032", + "stopIndex" : 102, + "stopSequence" : 103, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:27:25.000+00:00", - "departure" : "2009-11-17T18:27:25.000+00:00", - "lat" : 45.521063, - "lon" : -122.685848, - "name" : "SW Morrison & 14th", - "stopCode" : "9708", - "stopId" : "prt:9708", - "stopIndex" : 63, - "stopSequence" : 64, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:28:18.000+00:00", - "departure" : "2009-11-17T18:28:18.000+00:00", - "lat" : 45.521641, - "lon" : -122.687932, - "name" : "SW Morrison & 16th", - "stopCode" : "9613", - "stopId" : "prt:9613", - "stopIndex" : 64, - "stopSequence" : 65, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:29:00.000+00:00", - "departure" : "2009-11-17T18:29:00.000+00:00", - "lat" : 45.52206, - "lon" : -122.689577, - "name" : "SW Morrison & 17th", - "stopCode" : "9599", - "stopId" : "prt:9599", - "stopIndex" : 65, - "stopSequence" : 66, + "arrival" : "2009-11-17T18:24:09.000+00:00", + "departure" : "2009-11-17T18:24:09.000+00:00", + "lat" : 45.522985, + "lon" : -122.688091, + "name" : "W Burnside & NW 17th", + "stopCode" : "10809", + "stopId" : "prt:10809", + "stopIndex" : 103, + "stopSequence" : 104, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:29:54.000+00:00", - "departure" : "2009-11-17T18:29:54.000+00:00", + "arrival" : "2009-11-17T18:25:00.000+00:00", + "departure" : "2009-11-17T18:25:00.000+00:00", "lat" : 45.523097, "lon" : -122.690083, "name" : "W Burnside & NW 19th", "stopCode" : "735", "stopId" : "prt:735", - "stopIndex" : 66, - "stopSequence" : 67, + "stopIndex" : 104, + "stopSequence" : 105, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:30:31.000+00:00", - "departure" : "2009-11-17T18:30:31.000+00:00", + "arrival" : "2009-11-17T18:25:21.000+00:00", + "departure" : "2009-11-17T18:25:21.000+00:00", "lat" : 45.523176, "lon" : -122.692139, "name" : "W Burnside & NW 20th", "stopCode" : "741", "stopId" : "prt:741", - "stopIndex" : 67, - "stopSequence" : 68, + "stopIndex" : 105, + "stopSequence" : 106, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:30:48.000+00:00", - "departure" : "2009-11-17T18:30:48.000+00:00", + "arrival" : "2009-11-17T18:25:31.000+00:00", + "departure" : "2009-11-17T18:25:31.000+00:00", "lat" : 45.52322, "lon" : -122.69313, "name" : "W Burnside & NW 20th Pl", "stopCode" : "742", "stopId" : "prt:742", - "stopIndex" : 68, - "stopSequence" : 69, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:31:20.000+00:00", - "departure" : "2009-11-17T18:31:20.000+00:00", - "lat" : 45.523312, - "lon" : -122.694901, - "name" : "W Burnside & NW King", - "stopCode" : "747", - "stopId" : "prt:747", - "stopIndex" : 69, - "stopSequence" : 70, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:32:18.000+00:00", - "departure" : "2009-11-17T18:32:18.000+00:00", - "lat" : 45.523512, - "lon" : -122.698081, - "name" : "W Burnside & NW 23rd", - "stopCode" : "755", - "stopId" : "prt:755", - "stopIndex" : 70, - "stopSequence" : 71, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:33:11.000+00:00", - "departure" : "2009-11-17T18:33:11.000+00:00", - "lat" : 45.525416, - "lon" : -122.698381, - "name" : "NW 23rd & Flanders", - "stopCode" : "7157", - "stopId" : "prt:7157", - "stopIndex" : 71, - "stopSequence" : 72, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:34:05.000+00:00", - "departure" : "2009-11-17T18:34:05.000+00:00", - "lat" : 45.527543, - "lon" : -122.698473, - "name" : "NW 23rd & Irving", - "stopCode" : "7161", - "stopId" : "prt:7161", - "stopIndex" : 72, - "stopSequence" : 73, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:35:00.000+00:00", - "departure" : "2009-11-17T18:35:00.000+00:00", - "lat" : 45.529681, - "lon" : -122.698529, - "name" : "NW 23rd & Lovejoy", - "stopCode" : "7163", - "stopId" : "prt:7163", - "stopIndex" : 73, - "stopSequence" : 74, + "stopIndex" : 106, + "stopSequence" : 107, "vertexType" : "TRANSIT", "zoneId" : "1" } ], "legGeometry" : { - "length" : 135, - "points" : "kaytG||qkVA~@?jE?tC???r@AhE?jE?rA???tBAjE?nD???X?hE?xC??Ah@?pE?~C???J?`@?vAAvBEbE?jEAlE?`BAbB@d@??@tAAj@Cx@Cb@Cp@_@dEcAtFoA`IS~@i@`BmAzDi@zAc@pAi@~C??Id@u@jEm@bD??If@u@jEk@bD??If@u@|DW`B??CPs@|Du@lElBz@??VJbCfAk@dD??Id@w@rEWvAId@AF??Q~@s@`Ei@~C??Ib@u@dEWzA??]jB]MQSe@WOKOKIIQe@GWE]GnD??AXKnEGnD???XGjD??AZEfCC`AEzB??AXCfAGxDE|AEtBIlC??APkAh@o@?sCB{BD??S?mCDmCDyBB??U?mCDmCDyBB??S?oCDmCDmCBo@@" + "length" : 94, + "points" : "coztGd}qkVNl@r@`CZhA`A`D??Ph@l@tBb@rARh@Pd@???BPj@@jA?jEAhE?pD???VAjE?hE?dB?b@???`AAhE?dD???l@C`EAhEEhE?bAA|@?XAZ@\\AzACnGKbKAjC?bE???JEnE@fEDlE@hE@~A??@rBBzDBpE@~A???Z@tD@RBnEB|A???@BdB?lEBjA??BnBApF@dB?X?^@r@?f@@bCAx@EtB???VChAE|BGnD??AXKnEGnD???XGjD??AZEfCC`AEzB" }, "mode" : "BUS", "pathway" : false, "realTime" : false, - "route" : "Belmont/NW 23rd", - "routeId" : "prt:15", - "routeLongName" : "Belmont/NW 23rd", - "routeShortName" : "15", + "route" : "Burnside/Stark", + "routeId" : "prt:20", + "routeLongName" : "Burnside/Stark", + "routeShortName" : "20", "routeType" : 3, "serviceDate" : "2009-11-17", - "startTime" : "2009-11-17T18:15:40.000+00:00", + "startTime" : "2009-11-17T18:12:58.000+00:00", "steps" : [ ], "to" : { - "arrival" : "2009-11-17T18:35:54.000+00:00", - "departure" : "2009-11-17T18:35:54.000+00:00", - "lat" : 45.532159, - "lon" : -122.698634, - "name" : "NW 23rd & Overton", - "stopCode" : "8981", - "stopId" : "prt:8981", - "stopIndex" : 74, - "stopSequence" : 75, + "arrival" : "2009-11-17T18:25:49.000+00:00", + "departure" : "2009-11-17T18:25:49.000+00:00", + "lat" : 45.523312, + "lon" : -122.694901, + "name" : "W Burnside & NW King", + "stopCode" : "747", + "stopId" : "prt:747", + "stopIndex" : 107, + "stopSequence" : 108, "vertexType" : "TRANSIT", "zoneId" : "1" }, "transitLeg" : true, - "tripBlockId" : "1549", - "tripId" : "prt:150W1400" + "tripBlockId" : "2002", + "tripId" : "prt:200W1200" }, { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 266.21, - "endTime" : "2009-11-17T18:39:22.000+00:00", + "distance" : 999.1, + "endTime" : "2009-11-17T18:38:41.000+00:00", "from" : { - "arrival" : "2009-11-17T18:35:54.000+00:00", - "departure" : "2009-11-17T18:35:54.000+00:00", - "lat" : 45.532159, - "lon" : -122.698634, - "name" : "NW 23rd & Overton", - "stopCode" : "8981", - "stopId" : "prt:8981", + "arrival" : "2009-11-17T18:25:49.000+00:00", + "departure" : "2009-11-17T18:25:49.000+00:00", + "lat" : 45.523312, + "lon" : -122.694901, + "name" : "W Burnside & NW King", + "stopCode" : "747", + "stopId" : "prt:747", "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 405, + "generalizedCost" : 1511, "interlineWithPreviousLeg" : false, "legGeometry" : { - "length" : 13, - "points" : "}~{tGnq{kV?LVAF?J?L?rBCLA?Q?EAyAEcH?G" + "length" : 29, + "points" : "ugztGdzzkVL?ATClAI|DK?G?mCBkCDoCDmCBoCDkCBoCB[?sBD]?Y@eA@K?C?K?W@{A@M@C@I?_CB?G" }, "mode" : "WALK", "pathway" : false, "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T18:35:54.000+00:00", + "startTime" : "2009-11-17T18:25:49.000+00:00", "steps" : [ { - "absoluteDirection" : "SOUTH", + "absoluteDirection" : "WEST", "area" : false, "bogusName" : false, - "distance" : 104.46, + "distance" : 113.27, "elevation" : "", - "lat" : 45.5321578, - "lon" : -122.6987026, + "lat" : 45.5232491, + "lon" : -122.6949067, "relativeDirection" : "DEPART", "stayOn" : false, - "streetName" : "Northwest 23rd Avenue", + "streetName" : "West Burnside Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 882.16, + "elevation" : "", + "lat" : 45.5233204, + "lon" : -122.696357, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northwest 22nd Avenue", "walkingBike" : false }, { "absoluteDirection" : "EAST", "area" : false, "bogusName" : false, - "distance" : 161.77, + "distance" : 3.68, "elevation" : "", - "lat" : 45.5312188, - "lon" : -122.6986675, - "relativeDirection" : "LEFT", + "lat" : 45.5312508, + "lon" : -122.6966386, + "relativeDirection" : "RIGHT", "stayOn" : false, "streetName" : "Northwest Northrup Street", "walkingBike" : false } ], "to" : { - "arrival" : "2009-11-17T18:39:22.000+00:00", + "arrival" : "2009-11-17T18:38:41.000+00:00", "lat" : 45.53122, "lon" : -122.69659, "name" : "NW Northrup St. & NW 22nd Ave. (P2)", @@ -1200,21 +1220,21 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "walkingBike" : false } ], - "startTime" : "2009-11-17T18:14:52.000+00:00", + "startTime" : "2009-11-17T18:01:00.000+00:00", "tooSloped" : false, "transfers" : 0, - "transitTime" : 1214, + "transitTime" : 771, "waitingTime" : 0, - "walkDistance" : 328.22, + "walkDistance" : 1919.43, "walkLimitExceeded" : false, - "walkTime" : 256 + "walkTime" : 1490 }, { "arrivedAtDestinationWithRentedBicycle" : false, - "duration" : 2275, + "duration" : 1470, "elevationGained" : 0.0, "elevationLost" : 0.0, - "endTime" : "2009-11-17T18:53:55.000+00:00", + "endTime" : "2009-11-17T18:39:22.000+00:00", "fare" : { "details" : { }, "fare" : { }, @@ -1241,39 +1261,39 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } ] }, - "generalizedCost" : 4295, + "generalizedCost" : 2315, "legs" : [ { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 920.33, - "endTime" : "2009-11-17T18:27:58.000+00:00", + "distance" : 62.01, + "endTime" : "2009-11-17T18:15:40.000+00:00", "from" : { - "departure" : "2009-11-17T18:16:00.000+00:00", + "departure" : "2009-11-17T18:14:52.000+00:00", "lat" : 45.51726, "lon" : -122.64847, "name" : "SE Morrison St. & SE 17th Ave. (P1)", "vertexType" : "NORMAL" }, - "generalizedCost" : 1398, + "generalizedCost" : 95, "interlineWithPreviousLeg" : false, "legGeometry" : { - "length" : 45, - "points" : "kaytG~wqkV?T?fCAl@?RmC?oCAmCAoC?_CAM?aC??A?A?A?A??AA?AAA??AAA???A?A?A???A@A??@A@?@??A@?@?BcC?mCAmCAmC?QBIYIWOH" + "length" : 4, + "points" : "kaytG~wqkV?T?fCG?" }, "mode" : "WALK", "pathway" : false, "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T18:16:00.000+00:00", + "startTime" : "2009-11-17T18:14:52.000+00:00", "steps" : [ { "absoluteDirection" : "WEST", "area" : false, "bogusName" : false, - "distance" : 87.68, + "distance" : 62.02, "elevation" : "", "lat" : 45.517186, "lon" : -122.6484704, @@ -1281,55 +1301,16 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "stayOn" : false, "streetName" : "Southeast Morrison Street", "walkingBike" : false - }, - { - "absoluteDirection" : "NORTH", - "area" : false, - "bogusName" : false, - "distance" : 641.04, - "elevation" : "", - "lat" : 45.5171903, - "lon" : -122.6495956, - "relativeDirection" : "RIGHT", - "stayOn" : false, - "streetName" : "Southeast 16th Avenue", - "walkingBike" : false - }, - { - "absoluteDirection" : "NORTH", - "area" : false, - "bogusName" : false, - "distance" : 168.89, - "elevation" : "", - "lat" : 45.5228912, - "lon" : -122.6495528, - "relativeDirection" : "CONTINUE", - "stayOn" : false, - "streetName" : "Northeast 16th Avenue", - "walkingBike" : false - }, - { - "absoluteDirection" : "NORTHEAST", - "area" : false, - "bogusName" : false, - "distance" : 22.74, - "elevation" : "", - "lat" : 45.524409, - "lon" : -122.6495675, - "relativeDirection" : "RIGHT", - "stayOn" : false, - "streetName" : "Northeast Sandy Boulevard", - "walkingBike" : false } ], "to" : { - "arrival" : "2009-11-17T18:27:58.000+00:00", - "departure" : "2009-11-17T18:27:58.000+00:00", - "lat" : 45.524581, - "lon" : -122.649367, - "name" : "NE Sandy & 16th", - "stopCode" : "5060", - "stopId" : "prt:5060", + "arrival" : "2009-11-17T18:15:40.000+00:00", + "departure" : "2009-11-17T18:15:40.000+00:00", + "lat" : 45.517226, + "lon" : -122.649266, + "name" : "SE Morrison & 16th", + "stopCode" : "4019", + "stopId" : "prt:4019", "vertexType" : "TRANSIT", "zoneId" : "1" }, @@ -1343,312 +1324,416 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "agencyUrl" : "http://trimet.org", "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 3602.73, - "endTime" : "2009-11-17T18:41:03.000+00:00", + "distance" : 5218.86, + "endTime" : "2009-11-17T18:35:54.000+00:00", "from" : { - "arrival" : "2009-11-17T18:27:58.000+00:00", - "departure" : "2009-11-17T18:27:58.000+00:00", - "lat" : 45.524581, - "lon" : -122.649367, - "name" : "NE Sandy & 16th", - "stopCode" : "5060", - "stopId" : "prt:5060", - "stopIndex" : 92, - "stopSequence" : 93, + "arrival" : "2009-11-17T18:15:40.000+00:00", + "departure" : "2009-11-17T18:15:40.000+00:00", + "lat" : 45.517226, + "lon" : -122.649266, + "name" : "SE Morrison & 16th", + "stopCode" : "4019", + "stopId" : "prt:4019", + "stopIndex" : 50, + "stopSequence" : 51, "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 1385, - "headsign" : "23rd Ave to Tichner", + "generalizedCost" : 1814, + "headsign" : "Montgomery Park", "interlineWithPreviousLeg" : false, "intermediateStops" : [ { - "arrival" : "2009-11-17T18:28:32.000+00:00", - "departure" : "2009-11-17T18:28:32.000+00:00", - "lat" : 45.523767, - "lon" : -122.651428, - "name" : "NE Sandy & 14th", - "stopCode" : "5058", - "stopId" : "prt:5058", - "stopIndex" : 93, - "stopSequence" : 94, + "arrival" : "2009-11-17T18:16:15.000+00:00", + "departure" : "2009-11-17T18:16:15.000+00:00", + "lat" : 45.517253, + "lon" : -122.651354, + "name" : "SE Morrison & 14th", + "stopCode" : "4016", + "stopId" : "prt:4016", + "stopIndex" : 51, + "stopSequence" : 52, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:29:00.000+00:00", - "departure" : "2009-11-17T18:29:00.000+00:00", - "lat" : 45.523103, - "lon" : -122.653064, - "name" : "NE Sandy & 12th", - "stopCode" : "5055", - "stopId" : "prt:5055", - "stopIndex" : 94, - "stopSequence" : 95, + "arrival" : "2009-11-17T18:17:00.000+00:00", + "departure" : "2009-11-17T18:17:00.000+00:00", + "lat" : 45.517299, + "lon" : -122.654067, + "name" : "SE Morrison & 12th", + "stopCode" : "4014", + "stopId" : "prt:4014", + "stopIndex" : 52, + "stopSequence" : 53, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:29:47.000+00:00", - "departure" : "2009-11-17T18:29:47.000+00:00", - "lat" : 45.523024, - "lon" : -122.656526, - "name" : "E Burnside & NE 9th", - "stopCode" : "819", - "stopId" : "prt:819", - "stopIndex" : 95, - "stopSequence" : 96, + "arrival" : "2009-11-17T18:17:38.000+00:00", + "departure" : "2009-11-17T18:17:38.000+00:00", + "lat" : 45.517292, + "lon" : -122.656563, + "name" : "SE Morrison & 9th", + "stopCode" : "4026", + "stopId" : "prt:4026", + "stopIndex" : 53, + "stopSequence" : 54, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:30:24.000+00:00", - "departure" : "2009-11-17T18:30:24.000+00:00", - "lat" : 45.523012, - "lon" : -122.659365, - "name" : "E Burnside & NE 6th", - "stopCode" : "805", - "stopId" : "prt:805", - "stopIndex" : 96, - "stopSequence" : 97, + "arrival" : "2009-11-17T18:18:08.000+00:00", + "departure" : "2009-11-17T18:18:08.000+00:00", + "lat" : 45.517322, + "lon" : -122.65847, + "name" : "SE Morrison & 7th", + "stopCode" : "4025", + "stopId" : "prt:4025", + "stopIndex" : 54, + "stopSequence" : 55, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:30:52.000+00:00", - "departure" : "2009-11-17T18:30:52.000+00:00", - "lat" : 45.523015, - "lon" : -122.661534, - "name" : "E Burnside & NE M L King", - "stopCode" : "705", - "stopId" : "prt:705", - "stopIndex" : 97, - "stopSequence" : 98, + "arrival" : "2009-11-17T18:18:39.000+00:00", + "departure" : "2009-11-17T18:18:39.000+00:00", + "lat" : 45.517298, + "lon" : -122.660523, + "name" : "SE Morrison & Grand", + "stopCode" : "4013", + "stopId" : "prt:4013", + "stopIndex" : 55, + "stopSequence" : 56, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:33:00.000+00:00", - "departure" : "2009-11-17T18:33:00.000+00:00", - "lat" : 45.523249, - "lon" : -122.671269, - "name" : "W Burnside & Burnside Bridge", - "stopCode" : "689", - "stopId" : "prt:689", - "stopIndex" : 98, - "stopSequence" : 99, + "arrival" : "2009-11-17T18:20:03.000+00:00", + "departure" : "2009-11-17T18:20:03.000+00:00", + "lat" : 45.517351, + "lon" : -122.66601, + "name" : "Morrison Bridge", + "stopCode" : "4029", + "stopId" : "prt:4029", + "stopIndex" : 56, + "stopSequence" : 57, "vertexType" : "TRANSIT", - "zoneId" : "0" + "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:34:00.000+00:00", - "departure" : "2009-11-17T18:34:00.000+00:00", - "lat" : 45.523169, - "lon" : -122.675893, - "name" : "W Burnside & NW 5th", - "stopCode" : "782", - "stopId" : "prt:782", - "stopIndex" : 99, - "stopSequence" : 100, + "arrival" : "2009-11-17T18:22:27.000+00:00", + "departure" : "2009-11-17T18:22:27.000+00:00", + "lat" : 45.51959, + "lon" : -122.674599, + "name" : "SW Washington & 3rd", + "stopCode" : "6158", + "stopId" : "prt:6158", + "stopIndex" : 57, + "stopSequence" : 58, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:35:17.000+00:00", - "departure" : "2009-11-17T18:35:17.000+00:00", - "lat" : 45.523115, - "lon" : -122.678939, - "name" : "W Burnside & NW Park", - "stopCode" : "716", - "stopId" : "prt:716", - "stopIndex" : 100, - "stopSequence" : 101, + "arrival" : "2009-11-17T18:23:00.000+00:00", + "departure" : "2009-11-17T18:23:00.000+00:00", + "lat" : 45.520129, + "lon" : -122.676635, + "name" : "SW Washington & 5th", + "stopCode" : "6160", + "stopId" : "prt:6160", + "stopIndex" : 58, + "stopSequence" : 59, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:36:25.000+00:00", - "departure" : "2009-11-17T18:36:25.000+00:00", - "lat" : 45.523048, - "lon" : -122.681606, - "name" : "W Burnside & NW 10th", - "stopCode" : "10791", - "stopId" : "prt:10791", - "stopIndex" : 101, - "stopSequence" : 102, + "arrival" : "2009-11-17T18:23:52.000+00:00", + "departure" : "2009-11-17T18:23:52.000+00:00", + "lat" : 45.520695, + "lon" : -122.678657, + "name" : "SW Washington & Broadway", + "stopCode" : "6137", + "stopId" : "prt:6137", + "stopIndex" : 59, + "stopSequence" : 60, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:37:14.000+00:00", - "departure" : "2009-11-17T18:37:14.000+00:00", - "lat" : 45.523, - "lon" : -122.683535, - "name" : "W Burnside & NW 12th", - "stopCode" : "11032", - "stopId" : "prt:11032", - "stopIndex" : 102, - "stopSequence" : 103, + "arrival" : "2009-11-17T18:24:34.000+00:00", + "departure" : "2009-11-17T18:24:34.000+00:00", + "lat" : 45.521124, + "lon" : -122.6803, + "name" : "SW Washington & 9th", + "stopCode" : "6169", + "stopId" : "prt:6169", + "stopIndex" : 60, + "stopSequence" : 61, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:39:09.000+00:00", - "departure" : "2009-11-17T18:39:09.000+00:00", - "lat" : 45.522985, - "lon" : -122.688091, - "name" : "W Burnside & NW 17th", - "stopCode" : "10809", - "stopId" : "prt:10809", - "stopIndex" : 103, - "stopSequence" : 104, + "arrival" : "2009-11-17T18:25:47.000+00:00", + "departure" : "2009-11-17T18:25:47.000+00:00", + "lat" : 45.521094, + "lon" : -122.682819, + "name" : "SW 11th & Alder", + "stopCode" : "9600", + "stopId" : "prt:9600", + "stopIndex" : 61, + "stopSequence" : 62, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:26:36.000+00:00", + "departure" : "2009-11-17T18:26:36.000+00:00", + "lat" : 45.52055, + "lon" : -122.683933, + "name" : "SW Morrison & 12th", + "stopCode" : "9598", + "stopId" : "prt:9598", + "stopIndex" : 62, + "stopSequence" : 63, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:27:25.000+00:00", + "departure" : "2009-11-17T18:27:25.000+00:00", + "lat" : 45.521063, + "lon" : -122.685848, + "name" : "SW Morrison & 14th", + "stopCode" : "9708", + "stopId" : "prt:9708", + "stopIndex" : 63, + "stopSequence" : 64, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:40:00.000+00:00", - "departure" : "2009-11-17T18:40:00.000+00:00", + "arrival" : "2009-11-17T18:28:18.000+00:00", + "departure" : "2009-11-17T18:28:18.000+00:00", + "lat" : 45.521641, + "lon" : -122.687932, + "name" : "SW Morrison & 16th", + "stopCode" : "9613", + "stopId" : "prt:9613", + "stopIndex" : 64, + "stopSequence" : 65, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:29:00.000+00:00", + "departure" : "2009-11-17T18:29:00.000+00:00", + "lat" : 45.52206, + "lon" : -122.689577, + "name" : "SW Morrison & 17th", + "stopCode" : "9599", + "stopId" : "prt:9599", + "stopIndex" : 65, + "stopSequence" : 66, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:29:54.000+00:00", + "departure" : "2009-11-17T18:29:54.000+00:00", "lat" : 45.523097, "lon" : -122.690083, "name" : "W Burnside & NW 19th", "stopCode" : "735", "stopId" : "prt:735", - "stopIndex" : 104, - "stopSequence" : 105, + "stopIndex" : 66, + "stopSequence" : 67, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:40:27.000+00:00", - "departure" : "2009-11-17T18:40:27.000+00:00", + "arrival" : "2009-11-17T18:30:31.000+00:00", + "departure" : "2009-11-17T18:30:31.000+00:00", "lat" : 45.523176, "lon" : -122.692139, "name" : "W Burnside & NW 20th", "stopCode" : "741", "stopId" : "prt:741", - "stopIndex" : 105, - "stopSequence" : 106, + "stopIndex" : 67, + "stopSequence" : 68, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:40:40.000+00:00", - "departure" : "2009-11-17T18:40:40.000+00:00", + "arrival" : "2009-11-17T18:30:48.000+00:00", + "departure" : "2009-11-17T18:30:48.000+00:00", "lat" : 45.52322, "lon" : -122.69313, "name" : "W Burnside & NW 20th Pl", "stopCode" : "742", "stopId" : "prt:742", - "stopIndex" : 106, - "stopSequence" : 107, + "stopIndex" : 68, + "stopSequence" : 69, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:31:20.000+00:00", + "departure" : "2009-11-17T18:31:20.000+00:00", + "lat" : 45.523312, + "lon" : -122.694901, + "name" : "W Burnside & NW King", + "stopCode" : "747", + "stopId" : "prt:747", + "stopIndex" : 69, + "stopSequence" : 70, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:32:18.000+00:00", + "departure" : "2009-11-17T18:32:18.000+00:00", + "lat" : 45.523512, + "lon" : -122.698081, + "name" : "W Burnside & NW 23rd", + "stopCode" : "755", + "stopId" : "prt:755", + "stopIndex" : 70, + "stopSequence" : 71, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:33:11.000+00:00", + "departure" : "2009-11-17T18:33:11.000+00:00", + "lat" : 45.525416, + "lon" : -122.698381, + "name" : "NW 23rd & Flanders", + "stopCode" : "7157", + "stopId" : "prt:7157", + "stopIndex" : 71, + "stopSequence" : 72, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:34:05.000+00:00", + "departure" : "2009-11-17T18:34:05.000+00:00", + "lat" : 45.527543, + "lon" : -122.698473, + "name" : "NW 23rd & Irving", + "stopCode" : "7161", + "stopId" : "prt:7161", + "stopIndex" : 72, + "stopSequence" : 73, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:35:00.000+00:00", + "departure" : "2009-11-17T18:35:00.000+00:00", + "lat" : 45.529681, + "lon" : -122.698529, + "name" : "NW 23rd & Lovejoy", + "stopCode" : "7163", + "stopId" : "prt:7163", + "stopIndex" : 73, + "stopSequence" : 74, "vertexType" : "TRANSIT", "zoneId" : "1" } ], "legGeometry" : { - "length" : 94, - "points" : "coztGd}qkVNl@r@`CZhA`A`D??Ph@l@tBb@rARh@Pd@???BPj@@jA?jEAhE?pD???VAjE?hE?dB?b@???`AAhE?dD???l@C`EAhEEhE?bAA|@?XAZ@\\AzACnGKbKAjC?bE???JEnE@fEDlE@hE@~A??@rBBzDBpE@~A???Z@tD@RBnEB|A???@BdB?lEBjA??BnBApF@dB?X?^@r@?f@@bCAx@EtB???VChAE|BGnD??AXKnEGnD???XGjD??AZEfCC`AEzB" + "length" : 135, + "points" : "kaytG||qkVA~@?jE?tC???r@AhE?jE?rA???tBAjE?nD???X?hE?xC??Ah@?pE?~C???J?`@?vAAvBEbE?jEAlE?`BAbB@d@??@tAAj@Cx@Cb@Cp@_@dEcAtFoA`IS~@i@`BmAzDi@zAc@pAi@~C??Id@u@jEm@bD??If@u@jEk@bD??If@u@|DW`B??CPs@|Du@lElBz@??VJbCfAk@dD??Id@w@rEWvAId@AF??Q~@s@`Ei@~C??Ib@u@dEWzA??]jB]MQSe@WOKOKIIQe@GWE]GnD??AXKnEGnD???XGjD??AZEfCC`AEzB??AXCfAGxDE|AEtBIlC??APkAh@o@?sCB{BD??S?mCDmCDyBB??U?mCDmCDyBB??S?oCDmCDmCBo@@" }, "mode" : "BUS", "pathway" : false, "realTime" : false, - "route" : "Burnside/Stark", - "routeId" : "prt:20", - "routeLongName" : "Burnside/Stark", - "routeShortName" : "20", + "route" : "Belmont/NW 23rd", + "routeId" : "prt:15", + "routeLongName" : "Belmont/NW 23rd", + "routeShortName" : "15", "routeType" : 3, "serviceDate" : "2009-11-17", - "startTime" : "2009-11-17T18:27:58.000+00:00", + "startTime" : "2009-11-17T18:15:40.000+00:00", "steps" : [ ], "to" : { - "arrival" : "2009-11-17T18:41:03.000+00:00", - "departure" : "2009-11-17T18:41:03.000+00:00", - "lat" : 45.523312, - "lon" : -122.694901, - "name" : "W Burnside & NW King", - "stopCode" : "747", - "stopId" : "prt:747", - "stopIndex" : 107, - "stopSequence" : 108, + "arrival" : "2009-11-17T18:35:54.000+00:00", + "departure" : "2009-11-17T18:35:54.000+00:00", + "lat" : 45.532159, + "lon" : -122.698634, + "name" : "NW 23rd & Overton", + "stopCode" : "8981", + "stopId" : "prt:8981", + "stopIndex" : 74, + "stopSequence" : 75, "vertexType" : "TRANSIT", "zoneId" : "1" }, "transitLeg" : true, - "tripBlockId" : "2071", - "tripId" : "prt:200W1210" + "tripBlockId" : "1549", + "tripId" : "prt:150W1400" }, { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 999.1, - "endTime" : "2009-11-17T18:53:55.000+00:00", + "distance" : 266.21, + "endTime" : "2009-11-17T18:39:22.000+00:00", "from" : { - "arrival" : "2009-11-17T18:41:03.000+00:00", - "departure" : "2009-11-17T18:41:03.000+00:00", - "lat" : 45.523312, - "lon" : -122.694901, - "name" : "W Burnside & NW King", - "stopCode" : "747", - "stopId" : "prt:747", + "arrival" : "2009-11-17T18:35:54.000+00:00", + "departure" : "2009-11-17T18:35:54.000+00:00", + "lat" : 45.532159, + "lon" : -122.698634, + "name" : "NW 23rd & Overton", + "stopCode" : "8981", + "stopId" : "prt:8981", "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 1511, + "generalizedCost" : 405, "interlineWithPreviousLeg" : false, "legGeometry" : { - "length" : 29, - "points" : "ugztGdzzkVL?ATClAI|DK?G?mCBkCDoCDmCBoCDkCBoCB[?sBD]?Y@eA@K?C?K?W@{A@M@C@I?_CB?G" + "length" : 13, + "points" : "}~{tGnq{kV?LVAF?J?L?rBCLA?Q?EAyAEcH?G" }, "mode" : "WALK", "pathway" : false, "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T18:41:03.000+00:00", + "startTime" : "2009-11-17T18:35:54.000+00:00", "steps" : [ { - "absoluteDirection" : "WEST", + "absoluteDirection" : "SOUTH", "area" : false, "bogusName" : false, - "distance" : 113.27, + "distance" : 104.46, "elevation" : "", - "lat" : 45.5232491, - "lon" : -122.6949067, + "lat" : 45.5321578, + "lon" : -122.6987026, "relativeDirection" : "DEPART", "stayOn" : false, - "streetName" : "West Burnside Street", - "walkingBike" : false - }, - { - "absoluteDirection" : "NORTH", - "area" : false, - "bogusName" : false, - "distance" : 882.16, - "elevation" : "", - "lat" : 45.5233204, - "lon" : -122.696357, - "relativeDirection" : "RIGHT", - "stayOn" : false, - "streetName" : "Northwest 22nd Avenue", + "streetName" : "Northwest 23rd Avenue", "walkingBike" : false }, { "absoluteDirection" : "EAST", "area" : false, "bogusName" : false, - "distance" : 3.68, + "distance" : 161.77, "elevation" : "", - "lat" : 45.5312508, - "lon" : -122.6966386, - "relativeDirection" : "RIGHT", + "lat" : 45.5312188, + "lon" : -122.6986675, + "relativeDirection" : "LEFT", "stayOn" : false, "streetName" : "Northwest Northrup Street", "walkingBike" : false } ], "to" : { - "arrival" : "2009-11-17T18:53:55.000+00:00", + "arrival" : "2009-11-17T18:39:22.000+00:00", "lat" : 45.53122, "lon" : -122.69659, "name" : "NW Northrup St. & NW 22nd Ave. (P2)", @@ -1658,21 +1743,21 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "walkingBike" : false } ], - "startTime" : "2009-11-17T18:16:00.000+00:00", + "startTime" : "2009-11-17T18:14:52.000+00:00", "tooSloped" : false, "transfers" : 0, - "transitTime" : 785, + "transitTime" : 1214, "waitingTime" : 0, - "walkDistance" : 1919.43, + "walkDistance" : 328.22, "walkLimitExceeded" : false, - "walkTime" : 1490 + "walkTime" : 256 }, { "arrivedAtDestinationWithRentedBicycle" : false, - "duration" : 1540, + "duration" : 2020, "elevationGained" : 0.0, "elevationLost" : 0.0, - "endTime" : "2009-11-17T18:55:32.000+00:00", + "endTime" : "2009-11-17T18:51:19.000+00:00", "fare" : { "details" : { }, "fare" : { }, @@ -1696,42 +1781,62 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "name" : "regular" } ] + }, + { + "legIndices" : [ + 3 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "regular" + } + ] } ] }, - "generalizedCost" : 2385, + "generalizedCost" : 4023, "legs" : [ { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 62.01, - "endTime" : "2009-11-17T18:30:40.000+00:00", + "distance" : 1022.47, + "endTime" : "2009-11-17T18:30:50.000+00:00", "from" : { - "departure" : "2009-11-17T18:29:52.000+00:00", + "departure" : "2009-11-17T18:17:39.000+00:00", "lat" : 45.51726, "lon" : -122.64847, "name" : "SE Morrison St. & SE 17th Ave. (P1)", "vertexType" : "NORMAL" }, - "generalizedCost" : 95, + "generalizedCost" : 1543, "interlineWithPreviousLeg" : false, "legGeometry" : { - "length" : 4, - "points" : "kaytG~wqkV?T?fCG?" + "length" : 37, + "points" : "kaytG~wqkV?T?fCAl@?R?jE?rC?t@?hEAvD?R?R?|@?dBAP?PAxD?nD?X?jE?bA?t@?N?Z?ZAX?^@bBAt@?zC?N?J?NQ?O?sA@?W" }, "mode" : "WALK", "pathway" : false, "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T18:29:52.000+00:00", + "startTime" : "2009-11-17T18:17:39.000+00:00", "steps" : [ { "absoluteDirection" : "WEST", "area" : false, "bogusName" : false, - "distance" : 62.02, + "distance" : 956.36, "elevation" : "", "lat" : 45.517186, "lon" : -122.6484704, @@ -1739,16 +1844,29 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "stayOn" : false, "streetName" : "Southeast Morrison Street", "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 66.13, + "elevation" : "", + "lat" : 45.5172325, + "lon" : -122.6607432, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Southeast Grand Avenue", + "walkingBike" : false } ], "to" : { - "arrival" : "2009-11-17T18:30:40.000+00:00", - "departure" : "2009-11-17T18:30:40.000+00:00", - "lat" : 45.517226, - "lon" : -122.649266, - "name" : "SE Morrison & 16th", - "stopCode" : "4019", - "stopId" : "prt:4019", + "arrival" : "2009-11-17T18:30:50.000+00:00", + "departure" : "2009-11-17T18:30:50.000+00:00", + "lat" : 45.517828, + "lon" : -122.660632, + "name" : "SE Grand & Alder", + "stopCode" : "11485", + "stopId" : "prt:11485", "vertexType" : "TRANSIT", "zoneId" : "1" }, @@ -1762,416 +1880,403 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "agencyUrl" : "http://trimet.org", "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 5218.86, - "endTime" : "2009-11-17T18:52:04.000+00:00", + "distance" : 1580.92, + "endTime" : "2009-11-17T18:34:53.000+00:00", "from" : { - "arrival" : "2009-11-17T18:30:40.000+00:00", - "departure" : "2009-11-17T18:30:40.000+00:00", - "lat" : 45.517226, - "lon" : -122.649266, - "name" : "SE Morrison & 16th", - "stopCode" : "4019", - "stopId" : "prt:4019", - "stopIndex" : 50, - "stopSequence" : 51, + "arrival" : "2009-11-17T18:30:50.000+00:00", + "departure" : "2009-11-17T18:30:50.000+00:00", + "lat" : 45.517828, + "lon" : -122.660632, + "name" : "SE Grand & Alder", + "stopCode" : "11485", + "stopId" : "prt:11485", + "stopIndex" : 11, + "stopSequence" : 12, "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 1884, - "headsign" : "NW 27th & Thurman", + "generalizedCost" : 843, + "headsign" : "Jantzen Beach", "interlineWithPreviousLeg" : false, "intermediateStops" : [ { - "arrival" : "2009-11-17T18:31:15.000+00:00", - "departure" : "2009-11-17T18:31:15.000+00:00", - "lat" : 45.517253, - "lon" : -122.651354, - "name" : "SE Morrison & 14th", - "stopCode" : "4016", - "stopId" : "prt:4016", - "stopIndex" : 51, - "stopSequence" : 52, + "arrival" : "2009-11-17T18:31:25.000+00:00", + "departure" : "2009-11-17T18:31:25.000+00:00", + "lat" : 45.519986, + "lon" : -122.660636, + "name" : "SE Grand & Oak", + "stopCode" : "2174", + "stopId" : "prt:2174", + "stopIndex" : 12, + "stopSequence" : 13, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:32:00.000+00:00", - "departure" : "2009-11-17T18:32:00.000+00:00", - "lat" : 45.517299, - "lon" : -122.654067, - "name" : "SE Morrison & 12th", - "stopCode" : "4014", - "stopId" : "prt:4014", - "stopIndex" : 52, - "stopSequence" : 53, + "arrival" : "2009-11-17T18:32:10.000+00:00", + "departure" : "2009-11-17T18:32:10.000+00:00", + "lat" : 45.522782, + "lon" : -122.660589, + "name" : "SE Grand & E Burnside", + "stopCode" : "2167", + "stopId" : "prt:2167", + "stopIndex" : 13, + "stopSequence" : 14, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:32:38.000+00:00", - "departure" : "2009-11-17T18:32:38.000+00:00", - "lat" : 45.517292, - "lon" : -122.656563, - "name" : "SE Morrison & 9th", - "stopCode" : "4026", - "stopId" : "prt:4026", - "stopIndex" : 53, - "stopSequence" : 54, + "arrival" : "2009-11-17T18:32:39.000+00:00", + "departure" : "2009-11-17T18:32:39.000+00:00", + "lat" : 45.524582, + "lon" : -122.660578, + "name" : "NE Grand & Davis", + "stopCode" : "8829", + "stopId" : "prt:8829", + "stopIndex" : 14, + "stopSequence" : 15, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:33:08.000+00:00", - "departure" : "2009-11-17T18:33:08.000+00:00", - "lat" : 45.517322, - "lon" : -122.65847, - "name" : "SE Morrison & 7th", - "stopCode" : "4025", - "stopId" : "prt:4025", - "stopIndex" : 54, - "stopSequence" : 55, + "arrival" : "2009-11-17T18:33:26.000+00:00", + "departure" : "2009-11-17T18:33:26.000+00:00", + "lat" : 45.527519, + "lon" : -122.66056, + "name" : "NE Grand & Hoyt", + "stopCode" : "2169", + "stopId" : "prt:2169", + "stopIndex" : 15, + "stopSequence" : 16, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:33:39.000+00:00", - "departure" : "2009-11-17T18:33:39.000+00:00", - "lat" : 45.517298, - "lon" : -122.660523, - "name" : "SE Morrison & Grand", - "stopCode" : "4013", - "stopId" : "prt:4013", - "stopIndex" : 55, - "stopSequence" : 56, + "arrival" : "2009-11-17T18:34:00.000+00:00", + "departure" : "2009-11-17T18:34:00.000+00:00", + "lat" : 45.529602, + "lon" : -122.660529, + "name" : "NE Grand & Pacific", + "stopCode" : "2175", + "stopId" : "prt:2175", + "stopIndex" : 16, + "stopSequence" : 17, "vertexType" : "TRANSIT", "zoneId" : "1" - }, + } + ], + "legGeometry" : { + "length" : 35, + "points" : "meytGtdtkVC?OAQ?}B?mC?{BA??Q?oCAmC?mC?qBA??]?mC?mCAm@???aB?{AC[?kDAsCBq@A??uA?iCAgC?w@???yA?sCCoCAiB@" + }, + "mode" : "BUS", + "pathway" : false, + "realTime" : false, + "route" : "Martin Luther King Jr Blvd", + "routeId" : "prt:6", + "routeLongName" : "Martin Luther King Jr Blvd", + "routeShortName" : "6", + "routeType" : 3, + "serviceDate" : "2009-11-17", + "startTime" : "2009-11-17T18:30:50.000+00:00", + "steps" : [ ], + "to" : { + "arrival" : "2009-11-17T18:34:53.000+00:00", + "departure" : "2009-11-17T18:34:53.000+00:00", + "lat" : 45.532047, + "lon" : -122.660537, + "name" : "NE Grand & Wasco", + "stopCode" : "10953", + "stopId" : "prt:10953", + "stopIndex" : 17, + "stopSequence" : 18, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "transitLeg" : true, + "tripBlockId" : "605", + "tripId" : "prt:60W1220" + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 51.83, + "endTime" : "2009-11-17T18:35:36.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:34:53.000+00:00", + "departure" : "2009-11-17T18:34:53.000+00:00", + "lat" : 45.532047, + "lon" : -122.660537, + "name" : "NE Grand & Wasco", + "stopCode" : "10953", + "stopId" : "prt:10953", + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "generalizedCost" : 80, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 10, + "points" : "g~{tGjctkV?B`@?\\?R?@?@?BC???I" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:34:53.000+00:00", + "steps" : [ { - "arrival" : "2009-11-17T18:35:03.000+00:00", - "departure" : "2009-11-17T18:35:03.000+00:00", - "lat" : 45.517351, - "lon" : -122.66601, - "name" : "Morrison Bridge", - "stopCode" : "4029", - "stopId" : "prt:4029", - "stopIndex" : 56, - "stopSequence" : 57, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, + "absoluteDirection" : "SOUTH", + "area" : false, + "bogusName" : false, + "distance" : 51.83, + "elevation" : "", + "lat" : 45.532047, + "lon" : -122.6605564, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "Northeast Grand Avenue", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:35:36.000+00:00", + "departure" : "2009-11-17T18:38:05.000+00:00", + "lat" : 45.531586, + "lon" : -122.660482, + "name" : "NE Multnomah & Grand", + "stopCode" : "4043", + "stopId" : "prt:4043", + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyId" : "prt:prt", + "agencyName" : "TriMet", + "agencyTimeZoneOffset" : -28800000, + "agencyUrl" : "http://trimet.org", + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 3448.6, + "endTime" : "2009-11-17T18:50:55.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:35:36.000+00:00", + "departure" : "2009-11-17T18:38:05.000+00:00", + "lat" : 45.531586, + "lon" : -122.660482, + "name" : "NE Multnomah & Grand", + "stopCode" : "4043", + "stopId" : "prt:4043", + "stopIndex" : 82, + "stopSequence" : 83, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + "generalizedCost" : 1519, + "headsign" : "Montgomery Park", + "interlineWithPreviousLeg" : false, + "intermediateStops" : [ { - "arrival" : "2009-11-17T18:37:27.000+00:00", - "departure" : "2009-11-17T18:37:27.000+00:00", - "lat" : 45.51959, - "lon" : -122.674599, - "name" : "SW Washington & 3rd", - "stopCode" : "6158", - "stopId" : "prt:6158", - "stopIndex" : 57, - "stopSequence" : 58, + "arrival" : "2009-11-17T18:39:09.000+00:00", + "departure" : "2009-11-17T18:39:09.000+00:00", + "lat" : 45.531159, + "lon" : -122.66293, + "name" : "NE Multnomah & 3rd", + "stopCode" : "11492", + "stopId" : "prt:11492", + "stopIndex" : 83, + "stopSequence" : 84, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:38:00.000+00:00", - "departure" : "2009-11-17T18:38:00.000+00:00", - "lat" : 45.520129, - "lon" : -122.676635, - "name" : "SW Washington & 5th", - "stopCode" : "6160", - "stopId" : "prt:6160", - "stopIndex" : 58, - "stopSequence" : 59, + "arrival" : "2009-11-17T18:41:00.000+00:00", + "departure" : "2009-11-17T18:41:00.000+00:00", + "lat" : 45.530005, + "lon" : -122.666476, + "name" : "Rose Quarter Transit Center", + "stopCode" : "2592", + "stopId" : "prt:2592", + "stopIndex" : 84, + "stopSequence" : 85, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:38:52.000+00:00", - "departure" : "2009-11-17T18:38:52.000+00:00", - "lat" : 45.520695, - "lon" : -122.678657, - "name" : "SW Washington & Broadway", - "stopCode" : "6137", - "stopId" : "prt:6137", - "stopIndex" : 59, - "stopSequence" : 60, + "arrival" : "2009-11-17T18:44:20.000+00:00", + "departure" : "2009-11-17T18:44:20.000+00:00", + "lat" : 45.526655, + "lon" : -122.676462, + "name" : "NW Glisan & 6th", + "stopCode" : "10803", + "stopId" : "prt:10803", + "stopIndex" : 85, + "stopSequence" : 86, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:39:34.000+00:00", - "departure" : "2009-11-17T18:39:34.000+00:00", - "lat" : 45.521124, - "lon" : -122.6803, - "name" : "SW Washington & 9th", - "stopCode" : "6169", - "stopId" : "prt:6169", - "stopIndex" : 60, - "stopSequence" : 61, + "arrival" : "2009-11-17T18:45:15.000+00:00", + "departure" : "2009-11-17T18:45:15.000+00:00", + "lat" : 45.528799, + "lon" : -122.677238, + "name" : "NW Station Way & Union Station", + "stopCode" : "12801", + "stopId" : "prt:12801", + "stopIndex" : 86, + "stopSequence" : 87, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:40:47.000+00:00", - "departure" : "2009-11-17T18:40:47.000+00:00", - "lat" : 45.521094, - "lon" : -122.682819, - "name" : "SW 11th & Alder", - "stopCode" : "9600", - "stopId" : "prt:9600", - "stopIndex" : 61, - "stopSequence" : 62, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - { - "arrival" : "2009-11-17T18:41:36.000+00:00", - "departure" : "2009-11-17T18:41:36.000+00:00", - "lat" : 45.52055, - "lon" : -122.683933, - "name" : "SW Morrison & 12th", - "stopCode" : "9598", - "stopId" : "prt:9598", - "stopIndex" : 62, - "stopSequence" : 63, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - { - "arrival" : "2009-11-17T18:42:25.000+00:00", - "departure" : "2009-11-17T18:42:25.000+00:00", - "lat" : 45.521063, - "lon" : -122.685848, - "name" : "SW Morrison & 14th", - "stopCode" : "9708", - "stopId" : "prt:9708", - "stopIndex" : 63, - "stopSequence" : 64, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:43:18.000+00:00", - "departure" : "2009-11-17T18:43:18.000+00:00", - "lat" : 45.521641, - "lon" : -122.687932, - "name" : "SW Morrison & 16th", - "stopCode" : "9613", - "stopId" : "prt:9613", - "stopIndex" : 64, - "stopSequence" : 65, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:44:00.000+00:00", - "departure" : "2009-11-17T18:44:00.000+00:00", - "lat" : 45.52206, - "lon" : -122.689577, - "name" : "SW Morrison & 17th", - "stopCode" : "9599", - "stopId" : "prt:9599", - "stopIndex" : 65, - "stopSequence" : 66, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:45:03.000+00:00", - "departure" : "2009-11-17T18:45:03.000+00:00", - "lat" : 45.523097, - "lon" : -122.690083, - "name" : "W Burnside & NW 19th", - "stopCode" : "735", - "stopId" : "prt:735", - "stopIndex" : 66, - "stopSequence" : 67, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:45:46.000+00:00", - "departure" : "2009-11-17T18:45:46.000+00:00", - "lat" : 45.523176, - "lon" : -122.692139, - "name" : "W Burnside & NW 20th", - "stopCode" : "741", - "stopId" : "prt:741", - "stopIndex" : 67, - "stopSequence" : 68, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:46:07.000+00:00", - "departure" : "2009-11-17T18:46:07.000+00:00", - "lat" : 45.52322, - "lon" : -122.69313, - "name" : "W Burnside & NW 20th Pl", - "stopCode" : "742", - "stopId" : "prt:742", - "stopIndex" : 68, - "stopSequence" : 69, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T18:46:44.000+00:00", - "departure" : "2009-11-17T18:46:44.000+00:00", - "lat" : 45.523312, - "lon" : -122.694901, - "name" : "W Burnside & NW King", - "stopCode" : "747", - "stopId" : "prt:747", - "stopIndex" : 69, - "stopSequence" : 70, + "arrival" : "2009-11-17T18:47:00.000+00:00", + "departure" : "2009-11-17T18:47:00.000+00:00", + "lat" : 45.531582, + "lon" : -122.681193, + "name" : "NW Northrup & 10th", + "stopCode" : "12802", + "stopId" : "prt:12802", + "stopIndex" : 87, + "stopSequence" : 88, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:47:51.000+00:00", - "departure" : "2009-11-17T18:47:51.000+00:00", - "lat" : 45.523512, - "lon" : -122.698081, - "name" : "W Burnside & NW 23rd", - "stopCode" : "755", - "stopId" : "prt:755", - "stopIndex" : 70, - "stopSequence" : 71, + "arrival" : "2009-11-17T18:47:33.000+00:00", + "departure" : "2009-11-17T18:47:33.000+00:00", + "lat" : 45.531534, + "lon" : -122.683319, + "name" : "NW 12th & Northrup", + "stopCode" : "12796", + "stopId" : "prt:12796", + "stopIndex" : 88, + "stopSequence" : 89, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:48:53.000+00:00", - "departure" : "2009-11-17T18:48:53.000+00:00", - "lat" : 45.525416, - "lon" : -122.698381, - "name" : "NW 23rd & Flanders", - "stopCode" : "7157", - "stopId" : "prt:7157", - "stopIndex" : 71, - "stopSequence" : 72, + "arrival" : "2009-11-17T18:48:04.000+00:00", + "departure" : "2009-11-17T18:48:04.000+00:00", + "lat" : 45.531503, + "lon" : -122.685357, + "name" : "NW Northrup & 14th", + "stopCode" : "10775", + "stopId" : "prt:10775", + "stopIndex" : 89, + "stopSequence" : 90, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:49:56.000+00:00", - "departure" : "2009-11-17T18:49:56.000+00:00", - "lat" : 45.527543, - "lon" : -122.698473, - "name" : "NW 23rd & Irving", - "stopCode" : "7161", - "stopId" : "prt:7161", - "stopIndex" : 72, - "stopSequence" : 73, + "arrival" : "2009-11-17T18:49:07.000+00:00", + "departure" : "2009-11-17T18:49:07.000+00:00", + "lat" : 45.531434, + "lon" : -122.689417, + "name" : "NW Northrup & 18th", + "stopCode" : "10776", + "stopId" : "prt:10776", + "stopIndex" : 90, + "stopSequence" : 91, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:51:00.000+00:00", - "departure" : "2009-11-17T18:51:00.000+00:00", - "lat" : 45.529681, - "lon" : -122.698529, - "name" : "NW 23rd & Lovejoy", - "stopCode" : "7163", - "stopId" : "prt:7163", - "stopIndex" : 73, - "stopSequence" : 74, + "arrival" : "2009-11-17T18:50:24.000+00:00", + "departure" : "2009-11-17T18:50:24.000+00:00", + "lat" : 45.531346, + "lon" : -122.694455, + "name" : "NW Northrup & 21st", + "stopCode" : "10777", + "stopId" : "prt:10777", + "stopIndex" : 91, + "stopSequence" : 92, "vertexType" : "TRANSIT", "zoneId" : "1" } ], "legGeometry" : { - "length" : 135, - "points" : "kaytG||qkVA~@?jE?tC???r@AhE?jE?rA???tBAjE?nD???X?hE?xC??Ah@?pE?~C???J?`@?vAAvBEbE?jEAlE?`BAbB@d@??@tAAj@Cx@Cb@Cp@_@dEcAtFoA`IS~@i@`BmAzDi@zAc@pAi@~C??Id@u@jEm@bD??If@u@jEk@bD??If@u@|DW`B??CPs@|Du@lElBz@??VJbCfAk@dD??Id@w@rEWvAId@AF??Q~@s@`Ei@~C??Ib@u@dEWzA??]jB]MQSe@WOKOKIIQe@GWE]GnD??AXKnEGnD???XGjD??AZEfCC`AEzB??AXCfAGxDE|AEtBIlC??APkAh@o@?sCB{BD??S?mCDmCDyBB??U?mCDmCDyBB??S?oCDmCDmCBo@@" + "length" : 101, + "points" : "}z{tG~btkV?^?nE?V@Z?PH\\Nb@`@~@Rf@??`@bANb@FV@R?P?pE?jA@h@AnAbBl@LFJN\\f@LT??NXJPPVJFf@Vf@Pp@Nd@NRLB@RNXZR\\vAhC@BhAhD`AhClAbDBrDCnG@n@@^@d@HdAP`CBjEDvD???LqCFmCDYBGDEBGJkAzAQR??KNa@b@MJuBBY?OHW@u@~@aD`EcBhBBrD@xC??@l@BlE@lD???XBjEBpD???VBlE?dA@t@?b@?h@BfEBrD???VBhEFtKDvJ??@\\DnJ" }, "mode" : "BUS", "pathway" : false, "realTime" : false, - "route" : "Belmont/NW 23rd", - "routeId" : "prt:15", - "routeLongName" : "Belmont/NW 23rd", - "routeShortName" : "15", + "route" : "Broadway/Halsey", + "routeId" : "prt:77", + "routeLongName" : "Broadway/Halsey", + "routeShortName" : "77", "routeType" : 3, "serviceDate" : "2009-11-17", - "startTime" : "2009-11-17T18:30:40.000+00:00", + "startTime" : "2009-11-17T18:38:05.000+00:00", "steps" : [ ], "to" : { - "arrival" : "2009-11-17T18:52:04.000+00:00", - "departure" : "2009-11-17T18:52:04.000+00:00", - "lat" : 45.532159, - "lon" : -122.698634, - "name" : "NW 23rd & Overton", - "stopCode" : "8981", - "stopId" : "prt:8981", - "stopIndex" : 74, - "stopSequence" : 75, + "arrival" : "2009-11-17T18:50:55.000+00:00", + "departure" : "2009-11-17T18:50:55.000+00:00", + "lat" : 45.531308, + "lon" : -122.696445, + "name" : "NW Northrup & 22nd", + "stopCode" : "10778", + "stopId" : "prt:10778", + "stopIndex" : 92, + "stopSequence" : 93, "vertexType" : "TRANSIT", "zoneId" : "1" }, "transitLeg" : true, - "tripBlockId" : "1541", - "tripId" : "prt:150W1410" + "tripBlockId" : "7705", + "tripId" : "prt:771W1170" }, { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 266.21, - "endTime" : "2009-11-17T18:55:32.000+00:00", + "distance" : 18.81, + "endTime" : "2009-11-17T18:51:19.000+00:00", "from" : { - "arrival" : "2009-11-17T18:52:04.000+00:00", - "departure" : "2009-11-17T18:52:04.000+00:00", - "lat" : 45.532159, - "lon" : -122.698634, - "name" : "NW 23rd & Overton", - "stopCode" : "8981", - "stopId" : "prt:8981", + "arrival" : "2009-11-17T18:50:55.000+00:00", + "departure" : "2009-11-17T18:50:55.000+00:00", + "lat" : 45.531308, + "lon" : -122.696445, + "name" : "NW Northrup & 22nd", + "stopCode" : "10778", + "stopId" : "prt:10778", "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 405, + "generalizedCost" : 37, "interlineWithPreviousLeg" : false, "legGeometry" : { - "length" : 13, - "points" : "}~{tGnq{kV?LVAF?J?L?rBCLA?Q?EAyAEcH?G" + "length" : 7, + "points" : "sy{tGxc{kV???LABF?B??J" }, "mode" : "WALK", "pathway" : false, "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T18:52:04.000+00:00", + "startTime" : "2009-11-17T18:50:55.000+00:00", "steps" : [ { - "absoluteDirection" : "SOUTH", + "absoluteDirection" : "WEST", "area" : false, "bogusName" : false, - "distance" : 104.46, + "distance" : 18.81, "elevation" : "", - "lat" : 45.5321578, - "lon" : -122.6987026, + "lat" : 45.5313019, + "lon" : -122.6964448, "relativeDirection" : "DEPART", "stayOn" : false, - "streetName" : "Northwest 23rd Avenue", - "walkingBike" : false - }, - { - "absoluteDirection" : "EAST", - "area" : false, - "bogusName" : false, - "distance" : 161.77, - "elevation" : "", - "lat" : 45.5312188, - "lon" : -122.6986675, - "relativeDirection" : "LEFT", - "stayOn" : false, "streetName" : "Northwest Northrup Street", "walkingBike" : false } ], "to" : { - "arrival" : "2009-11-17T18:55:32.000+00:00", + "arrival" : "2009-11-17T18:51:19.000+00:00", "lat" : 45.53122, "lon" : -122.69659, "name" : "NW Northrup St. & NW 22nd Ave. (P2)", @@ -2181,21 +2286,21 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "walkingBike" : false } ], - "startTime" : "2009-11-17T18:29:52.000+00:00", + "startTime" : "2009-11-17T18:17:39.000+00:00", "tooSloped" : false, - "transfers" : 0, - "transitTime" : 1284, - "waitingTime" : 0, - "walkDistance" : 328.22, + "transfers" : 1, + "transitTime" : 1013, + "waitingTime" : 149, + "walkDistance" : 1093.11, "walkLimitExceeded" : false, - "walkTime" : 256 + "walkTime" : 858 }, { "arrivedAtDestinationWithRentedBicycle" : false, - "duration" : 1849, + "duration" : 2275, "elevationGained" : 0.0, "elevationLost" : 0.0, - "endTime" : "2009-11-17T19:08:19.000+00:00", + "endTime" : "2009-11-17T18:53:55.000+00:00", "fare" : { "details" : { }, "fare" : { }, @@ -2219,62 +2324,42 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "name" : "regular" } ] - }, - { - "legIndices" : [ - 2 - ], - "products" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:8", - "name" : "regular" - } - ] } ] }, - "generalizedCost" : 3375, + "generalizedCost" : 4295, "legs" : [ { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 419.62, - "endTime" : "2009-11-17T18:42:54.000+00:00", + "distance" : 920.33, + "endTime" : "2009-11-17T18:27:58.000+00:00", "from" : { - "departure" : "2009-11-17T18:37:30.000+00:00", + "departure" : "2009-11-17T18:16:00.000+00:00", "lat" : 45.51726, "lon" : -122.64847, "name" : "SE Morrison St. & SE 17th Ave. (P1)", "vertexType" : "NORMAL" }, - "generalizedCost" : 636, + "generalizedCost" : 1398, "interlineWithPreviousLeg" : false, "legGeometry" : { - "length" : 14, - "points" : "kaytG~wqkV?T?fCAl@?R?jE?rC?t@?hEAvD?RN?L??O" + "length" : 45, + "points" : "kaytG~wqkV?T?fCAl@?RmC?oCAmCAoC?_CAM?aC??A?A?A?A??AA?AAA??AAA???A?A?A???A@A??@A@?@??A@?@?BcC?mCAmCAmC?QBIYIWOH" }, "mode" : "WALK", "pathway" : false, "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T18:37:30.000+00:00", + "startTime" : "2009-11-17T18:16:00.000+00:00", "steps" : [ { "absoluteDirection" : "WEST", "area" : false, "bogusName" : false, - "distance" : 403.66, + "distance" : 87.68, "elevation" : "", "lat" : 45.517186, "lon" : -122.6484704, @@ -2284,27 +2369,53 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "walkingBike" : false }, { - "absoluteDirection" : "SOUTH", + "absoluteDirection" : "NORTH", "area" : false, "bogusName" : false, - "distance" : 15.96, + "distance" : 641.04, "elevation" : "", - "lat" : 45.5172031, - "lon" : -122.6536511, - "relativeDirection" : "LEFT", + "lat" : 45.5171903, + "lon" : -122.6495956, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Southeast 16th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 168.89, + "elevation" : "", + "lat" : 45.5228912, + "lon" : -122.6495528, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "Northeast 16th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTHEAST", + "area" : false, + "bogusName" : false, + "distance" : 22.74, + "elevation" : "", + "lat" : 45.524409, + "lon" : -122.6495675, + "relativeDirection" : "RIGHT", "stayOn" : false, - "streetName" : "Southeast 12th Avenue", + "streetName" : "Northeast Sandy Boulevard", "walkingBike" : false } ], "to" : { - "arrival" : "2009-11-17T18:42:54.000+00:00", - "departure" : "2009-11-17T18:42:54.000+00:00", - "lat" : 45.517059, - "lon" : -122.65358, - "name" : "SE 12th & Morrison", - "stopCode" : "6588", - "stopId" : "prt:6588", + "arrival" : "2009-11-17T18:27:58.000+00:00", + "departure" : "2009-11-17T18:27:58.000+00:00", + "lat" : 45.524581, + "lon" : -122.649367, + "name" : "NE Sandy & 16th", + "stopCode" : "5060", + "stopId" : "prt:5060", "vertexType" : "TRANSIT", "zoneId" : "1" }, @@ -2318,384 +2429,312 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "agencyUrl" : "http://trimet.org", "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 2035.62, - "endTime" : "2009-11-17T18:51:01.000+00:00", + "distance" : 3602.73, + "endTime" : "2009-11-17T18:41:03.000+00:00", "from" : { - "arrival" : "2009-11-17T18:42:54.000+00:00", - "departure" : "2009-11-17T18:42:54.000+00:00", - "lat" : 45.517059, - "lon" : -122.65358, - "name" : "SE 12th & Morrison", - "stopCode" : "6588", - "stopId" : "prt:6588", - "stopIndex" : 31, - "stopSequence" : 32, + "arrival" : "2009-11-17T18:27:58.000+00:00", + "departure" : "2009-11-17T18:27:58.000+00:00", + "lat" : 45.524581, + "lon" : -122.649367, + "name" : "NE Sandy & 16th", + "stopCode" : "5060", + "stopId" : "prt:5060", + "stopIndex" : 92, + "stopSequence" : 93, "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 1087, - "headsign" : "Rose Qtr TC", + "generalizedCost" : 1385, + "headsign" : "23rd Ave to Tichner", "interlineWithPreviousLeg" : false, "intermediateStops" : [ { - "arrival" : "2009-11-17T18:44:00.000+00:00", - "departure" : "2009-11-17T18:44:00.000+00:00", - "lat" : 45.519229, - "lon" : -122.653546, - "name" : "SE 12th & Stark", - "stopCode" : "6594", - "stopId" : "prt:6594", - "stopIndex" : 32, - "stopSequence" : 33, + "arrival" : "2009-11-17T18:28:32.000+00:00", + "departure" : "2009-11-17T18:28:32.000+00:00", + "lat" : 45.523767, + "lon" : -122.651428, + "name" : "NE Sandy & 14th", + "stopCode" : "5058", + "stopId" : "prt:5058", + "stopIndex" : 93, + "stopSequence" : 94, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:44:44.000+00:00", - "departure" : "2009-11-17T18:44:44.000+00:00", - "lat" : 45.520674, - "lon" : -122.653544, - "name" : "SE 12th & Pine", - "stopCode" : "6589", - "stopId" : "prt:6589", - "stopIndex" : 33, - "stopSequence" : 34, + "arrival" : "2009-11-17T18:29:00.000+00:00", + "departure" : "2009-11-17T18:29:00.000+00:00", + "lat" : 45.523103, + "lon" : -122.653064, + "name" : "NE Sandy & 12th", + "stopCode" : "5055", + "stopId" : "prt:5055", + "stopIndex" : 94, + "stopSequence" : 95, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:46:00.000+00:00", - "departure" : "2009-11-17T18:46:00.000+00:00", - "lat" : 45.52318, - "lon" : -122.653507, - "name" : "NE 12th & Sandy", - "stopCode" : "6592", - "stopId" : "prt:6592", - "stopIndex" : 34, - "stopSequence" : 35, + "arrival" : "2009-11-17T18:29:47.000+00:00", + "departure" : "2009-11-17T18:29:47.000+00:00", + "lat" : 45.523024, + "lon" : -122.656526, + "name" : "E Burnside & NE 9th", + "stopCode" : "819", + "stopId" : "prt:819", + "stopIndex" : 95, + "stopSequence" : 96, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:47:45.000+00:00", - "departure" : "2009-11-17T18:47:45.000+00:00", - "lat" : 45.527449, - "lon" : -122.653462, - "name" : "NE 12th & Irving", - "stopCode" : "6582", - "stopId" : "prt:6582", - "stopIndex" : 35, - "stopSequence" : 36, + "arrival" : "2009-11-17T18:30:24.000+00:00", + "departure" : "2009-11-17T18:30:24.000+00:00", + "lat" : 45.523012, + "lon" : -122.659365, + "name" : "E Burnside & NE 6th", + "stopCode" : "805", + "stopId" : "prt:805", + "stopIndex" : 96, + "stopSequence" : 97, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:49:00.000+00:00", - "departure" : "2009-11-17T18:49:00.000+00:00", - "lat" : 45.529793, - "lon" : -122.654429, - "name" : "NE 11th & Holladay", - "stopCode" : "8513", - "stopId" : "prt:8513", - "stopIndex" : 36, - "stopSequence" : 37, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - { - "arrival" : "2009-11-17T18:49:39.000+00:00", - "departure" : "2009-11-17T18:49:39.000+00:00", - "lat" : 45.53135, - "lon" : -122.654497, - "name" : "NE 11th & Multnomah", - "stopCode" : "8938", - "stopId" : "prt:8938", - "stopIndex" : 37, - "stopSequence" : 38, + "arrival" : "2009-11-17T18:30:52.000+00:00", + "departure" : "2009-11-17T18:30:52.000+00:00", + "lat" : 45.523015, + "lon" : -122.661534, + "name" : "E Burnside & NE M L King", + "stopCode" : "705", + "stopId" : "prt:705", + "stopIndex" : 97, + "stopSequence" : 98, "vertexType" : "TRANSIT", - "zoneId" : "0" + "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:50:15.000+00:00", - "departure" : "2009-11-17T18:50:15.000+00:00", - "lat" : 45.531573, - "lon" : -122.656408, - "name" : "NE Multnomah & 9th", - "stopCode" : "4056", - "stopId" : "prt:4056", - "stopIndex" : 38, - "stopSequence" : 39, - "vertexType" : "TRANSIT", - "zoneId" : "0" - } - ], - "legGeometry" : { - "length" : 49, - "points" : "s`ytGhxrkV[?mCAmC?wBA??W?mC?{BA??Q?oC?mC?kBAa@?w@???wA?mCAmC?oCA}C?sDC??aBAm@@k@AY?uABU@I@IBQFb@fC}@d@OFO@q@???Q?]?gGA??[??nJ???b@?vK?rA" - }, - "mode" : "BUS", - "pathway" : false, - "realTime" : false, - "route" : "12th Ave", - "routeId" : "prt:70", - "routeLongName" : "12th Ave", - "routeShortName" : "70", - "routeType" : 3, - "serviceDate" : "2009-11-17", - "startTime" : "2009-11-17T18:42:54.000+00:00", - "steps" : [ ], - "to" : { - "arrival" : "2009-11-17T18:51:01.000+00:00", - "departure" : "2009-11-17T18:54:29.000+00:00", - "lat" : 45.531569, - "lon" : -122.659045, - "name" : "NE Multnomah & 7th", - "stopCode" : "4054", - "stopId" : "prt:4054", - "stopIndex" : 39, - "stopSequence" : 40, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - "transitLeg" : true, - "tripBlockId" : "7002", - "tripId" : "prt:700W1170" - }, - { - "agencyId" : "prt:prt", - "agencyName" : "TriMet", - "agencyTimeZoneOffset" : -28800000, - "agencyUrl" : "http://trimet.org", - "arrivalDelay" : 0, - "departureDelay" : 0, - "distance" : 3560.24, - "endTime" : "2009-11-17T19:07:55.000+00:00", - "from" : { - "arrival" : "2009-11-17T18:51:01.000+00:00", - "departure" : "2009-11-17T18:54:29.000+00:00", - "lat" : 45.531569, - "lon" : -122.659045, - "name" : "NE Multnomah & 7th", - "stopCode" : "4054", - "stopId" : "prt:4054", - "stopIndex" : 81, - "stopSequence" : 82, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - "generalizedCost" : 1614, - "headsign" : "Montgomery Park", - "interlineWithPreviousLeg" : false, - "intermediateStops" : [ - { - "arrival" : "2009-11-17T18:55:05.000+00:00", - "departure" : "2009-11-17T18:55:05.000+00:00", - "lat" : 45.531586, - "lon" : -122.660482, - "name" : "NE Multnomah & Grand", - "stopCode" : "4043", - "stopId" : "prt:4043", - "stopIndex" : 82, - "stopSequence" : 83, + "arrival" : "2009-11-17T18:33:00.000+00:00", + "departure" : "2009-11-17T18:33:00.000+00:00", + "lat" : 45.523249, + "lon" : -122.671269, + "name" : "W Burnside & Burnside Bridge", + "stopCode" : "689", + "stopId" : "prt:689", + "stopIndex" : 98, + "stopSequence" : 99, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:56:09.000+00:00", - "departure" : "2009-11-17T18:56:09.000+00:00", - "lat" : 45.531159, - "lon" : -122.66293, - "name" : "NE Multnomah & 3rd", - "stopCode" : "11492", - "stopId" : "prt:11492", - "stopIndex" : 83, - "stopSequence" : 84, + "arrival" : "2009-11-17T18:34:00.000+00:00", + "departure" : "2009-11-17T18:34:00.000+00:00", + "lat" : 45.523169, + "lon" : -122.675893, + "name" : "W Burnside & NW 5th", + "stopCode" : "782", + "stopId" : "prt:782", + "stopIndex" : 99, + "stopSequence" : 100, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:58:00.000+00:00", - "departure" : "2009-11-17T18:58:00.000+00:00", - "lat" : 45.530005, - "lon" : -122.666476, - "name" : "Rose Quarter Transit Center", - "stopCode" : "2592", - "stopId" : "prt:2592", - "stopIndex" : 84, - "stopSequence" : 85, + "arrival" : "2009-11-17T18:35:17.000+00:00", + "departure" : "2009-11-17T18:35:17.000+00:00", + "lat" : 45.523115, + "lon" : -122.678939, + "name" : "W Burnside & NW Park", + "stopCode" : "716", + "stopId" : "prt:716", + "stopIndex" : 100, + "stopSequence" : 101, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T19:01:20.000+00:00", - "departure" : "2009-11-17T19:01:20.000+00:00", - "lat" : 45.526655, - "lon" : -122.676462, - "name" : "NW Glisan & 6th", - "stopCode" : "10803", - "stopId" : "prt:10803", - "stopIndex" : 85, - "stopSequence" : 86, + "arrival" : "2009-11-17T18:36:25.000+00:00", + "departure" : "2009-11-17T18:36:25.000+00:00", + "lat" : 45.523048, + "lon" : -122.681606, + "name" : "W Burnside & NW 10th", + "stopCode" : "10791", + "stopId" : "prt:10791", + "stopIndex" : 101, + "stopSequence" : 102, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T19:02:15.000+00:00", - "departure" : "2009-11-17T19:02:15.000+00:00", - "lat" : 45.528799, - "lon" : -122.677238, - "name" : "NW Station Way & Union Station", - "stopCode" : "12801", - "stopId" : "prt:12801", - "stopIndex" : 86, - "stopSequence" : 87, + "arrival" : "2009-11-17T18:37:14.000+00:00", + "departure" : "2009-11-17T18:37:14.000+00:00", + "lat" : 45.523, + "lon" : -122.683535, + "name" : "W Burnside & NW 12th", + "stopCode" : "11032", + "stopId" : "prt:11032", + "stopIndex" : 102, + "stopSequence" : 103, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T19:04:00.000+00:00", - "departure" : "2009-11-17T19:04:00.000+00:00", - "lat" : 45.531582, - "lon" : -122.681193, - "name" : "NW Northrup & 10th", - "stopCode" : "12802", - "stopId" : "prt:12802", - "stopIndex" : 87, - "stopSequence" : 88, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T19:04:33.000+00:00", - "departure" : "2009-11-17T19:04:33.000+00:00", - "lat" : 45.531534, - "lon" : -122.683319, - "name" : "NW 12th & Northrup", - "stopCode" : "12796", - "stopId" : "prt:12796", - "stopIndex" : 88, - "stopSequence" : 89, + "arrival" : "2009-11-17T18:39:09.000+00:00", + "departure" : "2009-11-17T18:39:09.000+00:00", + "lat" : 45.522985, + "lon" : -122.688091, + "name" : "W Burnside & NW 17th", + "stopCode" : "10809", + "stopId" : "prt:10809", + "stopIndex" : 103, + "stopSequence" : 104, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T19:05:04.000+00:00", - "departure" : "2009-11-17T19:05:04.000+00:00", - "lat" : 45.531503, - "lon" : -122.685357, - "name" : "NW Northrup & 14th", - "stopCode" : "10775", - "stopId" : "prt:10775", - "stopIndex" : 89, - "stopSequence" : 90, + "arrival" : "2009-11-17T18:40:00.000+00:00", + "departure" : "2009-11-17T18:40:00.000+00:00", + "lat" : 45.523097, + "lon" : -122.690083, + "name" : "W Burnside & NW 19th", + "stopCode" : "735", + "stopId" : "prt:735", + "stopIndex" : 104, + "stopSequence" : 105, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T19:06:07.000+00:00", - "departure" : "2009-11-17T19:06:07.000+00:00", - "lat" : 45.531434, - "lon" : -122.689417, - "name" : "NW Northrup & 18th", - "stopCode" : "10776", - "stopId" : "prt:10776", - "stopIndex" : 90, - "stopSequence" : 91, + "arrival" : "2009-11-17T18:40:27.000+00:00", + "departure" : "2009-11-17T18:40:27.000+00:00", + "lat" : 45.523176, + "lon" : -122.692139, + "name" : "W Burnside & NW 20th", + "stopCode" : "741", + "stopId" : "prt:741", + "stopIndex" : 105, + "stopSequence" : 106, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T19:07:24.000+00:00", - "departure" : "2009-11-17T19:07:24.000+00:00", - "lat" : 45.531346, - "lon" : -122.694455, - "name" : "NW Northrup & 21st", - "stopCode" : "10777", - "stopId" : "prt:10777", - "stopIndex" : 91, - "stopSequence" : 92, + "arrival" : "2009-11-17T18:40:40.000+00:00", + "departure" : "2009-11-17T18:40:40.000+00:00", + "lat" : 45.52322, + "lon" : -122.69313, + "name" : "W Burnside & NW 20th Pl", + "stopCode" : "742", + "stopId" : "prt:742", + "stopIndex" : 106, + "stopSequence" : 107, "vertexType" : "TRANSIT", "zoneId" : "1" } ], "legGeometry" : { - "length" : 104, - "points" : "yz{tG`zskV?tBCfD???^?nE?V@Z?PH\\Nb@`@~@Rf@??`@bANb@FV@R?P?pE?jA@h@AnAbBl@LFJN\\f@LT??NXJPPVJFf@Vf@Pp@Nd@NRLB@RNXZR\\vAhC@BhAhD`AhClAbDBrDCnG@n@@^@d@HdAP`CBjEDvD???LqCFmCDYBGDEBGJkAzAQR??KNa@b@MJuBBY?OHW@u@~@aD`EcBhBBrD@xC??@l@BlE@lD???XBjEBpD???VBlE?dA@t@?b@?h@BfEBrD???VBhEFtKDvJ??@\\DnJ" + "length" : 94, + "points" : "coztGd}qkVNl@r@`CZhA`A`D??Ph@l@tBb@rARh@Pd@???BPj@@jA?jEAhE?pD???VAjE?hE?dB?b@???`AAhE?dD???l@C`EAhEEhE?bAA|@?XAZ@\\AzACnGKbKAjC?bE???JEnE@fEDlE@hE@~A??@rBBzDBpE@~A???Z@tD@RBnEB|A???@BdB?lEBjA??BnBApF@dB?X?^@r@?f@@bCAx@EtB???VChAE|BGnD??AXKnEGnD???XGjD??AZEfCC`AEzB" }, "mode" : "BUS", "pathway" : false, "realTime" : false, - "route" : "Broadway/Halsey", - "routeId" : "prt:77", - "routeLongName" : "Broadway/Halsey", - "routeShortName" : "77", + "route" : "Burnside/Stark", + "routeId" : "prt:20", + "routeLongName" : "Burnside/Stark", + "routeShortName" : "20", "routeType" : 3, "serviceDate" : "2009-11-17", - "startTime" : "2009-11-17T18:54:29.000+00:00", + "startTime" : "2009-11-17T18:27:58.000+00:00", "steps" : [ ], "to" : { - "arrival" : "2009-11-17T19:07:55.000+00:00", - "departure" : "2009-11-17T19:07:55.000+00:00", - "lat" : 45.531308, - "lon" : -122.696445, - "name" : "NW Northrup & 22nd", - "stopCode" : "10778", - "stopId" : "prt:10778", - "stopIndex" : 92, - "stopSequence" : 93, + "arrival" : "2009-11-17T18:41:03.000+00:00", + "departure" : "2009-11-17T18:41:03.000+00:00", + "lat" : 45.523312, + "lon" : -122.694901, + "name" : "W Burnside & NW King", + "stopCode" : "747", + "stopId" : "prt:747", + "stopIndex" : 107, + "stopSequence" : 108, "vertexType" : "TRANSIT", "zoneId" : "1" }, "transitLeg" : true, - "tripBlockId" : "7702", - "tripId" : "prt:771W1180" + "tripBlockId" : "2071", + "tripId" : "prt:200W1210" }, { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 18.81, - "endTime" : "2009-11-17T19:08:19.000+00:00", + "distance" : 999.1, + "endTime" : "2009-11-17T18:53:55.000+00:00", "from" : { - "arrival" : "2009-11-17T19:07:55.000+00:00", - "departure" : "2009-11-17T19:07:55.000+00:00", - "lat" : 45.531308, - "lon" : -122.696445, - "name" : "NW Northrup & 22nd", - "stopCode" : "10778", - "stopId" : "prt:10778", + "arrival" : "2009-11-17T18:41:03.000+00:00", + "departure" : "2009-11-17T18:41:03.000+00:00", + "lat" : 45.523312, + "lon" : -122.694901, + "name" : "W Burnside & NW King", + "stopCode" : "747", + "stopId" : "prt:747", "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 37, + "generalizedCost" : 1511, "interlineWithPreviousLeg" : false, "legGeometry" : { - "length" : 7, - "points" : "sy{tGxc{kV???LABF?B??J" + "length" : 29, + "points" : "ugztGdzzkVL?ATClAI|DK?G?mCBkCDoCDmCBoCDkCBoCB[?sBD]?Y@eA@K?C?K?W@{A@M@C@I?_CB?G" }, "mode" : "WALK", "pathway" : false, "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T19:07:55.000+00:00", + "startTime" : "2009-11-17T18:41:03.000+00:00", "steps" : [ { "absoluteDirection" : "WEST", "area" : false, "bogusName" : false, - "distance" : 18.81, + "distance" : 113.27, "elevation" : "", - "lat" : 45.5313019, - "lon" : -122.6964448, + "lat" : 45.5232491, + "lon" : -122.6949067, "relativeDirection" : "DEPART", "stayOn" : false, + "streetName" : "West Burnside Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 882.16, + "elevation" : "", + "lat" : 45.5233204, + "lon" : -122.696357, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northwest 22nd Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "EAST", + "area" : false, + "bogusName" : false, + "distance" : 3.68, + "elevation" : "", + "lat" : 45.5312508, + "lon" : -122.6966386, + "relativeDirection" : "RIGHT", + "stayOn" : false, "streetName" : "Northwest Northrup Street", "walkingBike" : false } ], "to" : { - "arrival" : "2009-11-17T19:08:19.000+00:00", + "arrival" : "2009-11-17T18:53:55.000+00:00", "lat" : 45.53122, "lon" : -122.69659, "name" : "NW Northrup St. & NW 22nd Ave. (P2)", @@ -2705,14 +2744,14 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "walkingBike" : false } ], - "startTime" : "2009-11-17T18:37:30.000+00:00", + "startTime" : "2009-11-17T18:16:00.000+00:00", "tooSloped" : false, - "transfers" : 1, - "transitTime" : 1293, - "waitingTime" : 208, - "walkDistance" : 438.43, + "transfers" : 0, + "transitTime" : 785, + "waitingTime" : 0, + "walkDistance" : 1919.43, "walkLimitExceeded" : false, - "walkTime" : 348 + "walkTime" : 1490 } ] ] @@ -3836,10 +3875,10 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan }, { "arrivedAtDestinationWithRentedBicycle" : false, - "duration" : 1553, + "duration" : 2260, "elevationGained" : 0.0, "elevationLost" : 0.0, - "endTime" : "2009-11-17T19:09:40.000+00:00", + "endTime" : "2009-11-17T19:07:27.000+00:00", "fare" : { "details" : { }, "fare" : { }, @@ -3863,19 +3902,39 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "name" : "regular" } ] + }, + { + "legIndices" : [ + 3 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "regular" + } + ] } ] }, - "generalizedCost" : 2895, + "generalizedCost" : 4058, "legs" : [ { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, "distance" : 87.02, - "endTime" : "2009-11-17T18:45:00.000+00:00", + "endTime" : "2009-11-17T18:31:00.000+00:00", "from" : { - "departure" : "2009-11-17T18:43:47.000+00:00", + "departure" : "2009-11-17T18:29:47.000+00:00", "lat" : 45.52337, "lon" : -122.653725, "name" : "NE 12th & Couch", @@ -3895,7 +3954,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T18:43:47.000+00:00", + "startTime" : "2009-11-17T18:29:47.000+00:00", "steps" : [ { "absoluteDirection" : "SOUTH", @@ -3925,8 +3984,8 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } ], "to" : { - "arrival" : "2009-11-17T18:45:00.000+00:00", - "departure" : "2009-11-17T18:45:00.000+00:00", + "arrival" : "2009-11-17T18:31:00.000+00:00", + "departure" : "2009-11-17T18:31:00.000+00:00", "lat" : 45.523103, "lon" : -122.653064, "name" : "NE Sandy & 12th", @@ -3945,338 +4004,493 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "agencyUrl" : "http://trimet.org", "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 3729.97, - "endTime" : "2009-11-17T18:57:49.000+00:00", + "distance" : 1883.59, + "endTime" : "2009-11-17T18:38:19.000+00:00", "from" : { - "arrival" : "2009-11-17T18:45:00.000+00:00", - "departure" : "2009-11-17T18:45:00.000+00:00", + "arrival" : "2009-11-17T18:31:00.000+00:00", + "departure" : "2009-11-17T18:31:00.000+00:00", "lat" : 45.523103, "lon" : -122.653064, "name" : "NE Sandy & 12th", "stopCode" : "5055", "stopId" : "prt:5055", - "stopIndex" : 94, - "stopSequence" : 95, + "stopIndex" : 84, + "stopSequence" : 85, "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 1369, - "headsign" : "Beaverton TC", + "generalizedCost" : 1039, + "headsign" : "Sherwood via Portland city center", "interlineWithPreviousLeg" : false, "intermediateStops" : [ { - "arrival" : "2009-11-17T18:45:47.000+00:00", - "departure" : "2009-11-17T18:45:47.000+00:00", + "arrival" : "2009-11-17T18:31:47.000+00:00", + "departure" : "2009-11-17T18:31:47.000+00:00", "lat" : 45.523024, "lon" : -122.656526, "name" : "E Burnside & NE 9th", "stopCode" : "819", "stopId" : "prt:819", - "stopIndex" : 95, - "stopSequence" : 96, + "stopIndex" : 85, + "stopSequence" : 86, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:46:24.000+00:00", - "departure" : "2009-11-17T18:46:24.000+00:00", + "arrival" : "2009-11-17T18:32:24.000+00:00", + "departure" : "2009-11-17T18:32:24.000+00:00", "lat" : 45.523012, "lon" : -122.659365, "name" : "E Burnside & NE 6th", "stopCode" : "805", "stopId" : "prt:805", - "stopIndex" : 96, - "stopSequence" : 97, + "stopIndex" : 86, + "stopSequence" : 87, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:32:52.000+00:00", + "departure" : "2009-11-17T18:32:52.000+00:00", + "lat" : 45.523015, + "lon" : -122.661534, + "name" : "E Burnside & NE M L King", + "stopCode" : "705", + "stopId" : "prt:705", + "stopIndex" : 87, + "stopSequence" : 88, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:46:52.000+00:00", - "departure" : "2009-11-17T18:46:52.000+00:00", - "lat" : 45.523015, - "lon" : -122.661534, - "name" : "E Burnside & NE M L King", - "stopCode" : "705", - "stopId" : "prt:705", - "stopIndex" : 97, - "stopSequence" : 98, - "vertexType" : "TRANSIT", - "zoneId" : "1" + "arrival" : "2009-11-17T18:35:00.000+00:00", + "departure" : "2009-11-17T18:35:00.000+00:00", + "lat" : 45.523249, + "lon" : -122.671269, + "name" : "W Burnside & Burnside Bridge", + "stopCode" : "689", + "stopId" : "prt:689", + "stopIndex" : 88, + "stopSequence" : 89, + "vertexType" : "TRANSIT", + "zoneId" : "0" + } + ], + "legGeometry" : { + "length" : 43, + "points" : "weztGdtrkV?BPj@@jA?jEAhE?pD???VAjE?hE?dB?b@???`AAhE?dD???l@C`EAhEEhE?bAA|@?XAZ@\\AzACnGKbKAjC?bE???JEnE@fEDlE@hE\\CPBt@ZvAl@d@R" + }, + "mode" : "BUS", + "pathway" : false, + "realTime" : false, + "route" : "Barbur/Sandy Blvd", + "routeId" : "prt:12", + "routeLongName" : "Barbur/Sandy Blvd", + "routeShortName" : "12", + "routeType" : 3, + "serviceDate" : "2009-11-17", + "startTime" : "2009-11-17T18:31:00.000+00:00", + "steps" : [ ], + "to" : { + "arrival" : "2009-11-17T18:38:19.000+00:00", + "departure" : "2009-11-17T18:38:19.000+00:00", + "lat" : 45.521958, + "lon" : -122.675956, + "name" : "SW 5th & Pine", + "stopCode" : "7631", + "stopId" : "prt:7631", + "stopIndex" : 89, + "stopSequence" : 90, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + "transitLeg" : true, + "tripBlockId" : "1235", + "tripId" : "prt:120W1270" + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 534.33, + "endTime" : "2009-11-17T18:45:25.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:38:19.000+00:00", + "departure" : "2009-11-17T18:38:19.000+00:00", + "lat" : 45.521958, + "lon" : -122.675956, + "name" : "SW 5th & Pine", + "stopCode" : "7631", + "stopId" : "prt:7631", + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + "generalizedCost" : 820, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 24, + "points" : "e_ztGvcwkVADlAl@NFi@|CAFCJCJCNi@|CCRGXm@lDdCfA]hBo@rDCPADL@H@F@JB@@@K" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:38:19.000+00:00", + "steps" : [ + { + "absoluteDirection" : "SOUTH", + "area" : false, + "bogusName" : false, + "distance" : 47.2, + "elevation" : "", + "lat" : 45.5219669, + "lon" : -122.6759883, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "Southwest 5th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "SOUTH", + "area" : false, + "bogusName" : true, + "distance" : 9.01, + "elevation" : "", + "lat" : 45.5215719, + "lon" : -122.67621, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "path", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 243.52, + "elevation" : "", + "lat" : 45.5214961, + "lon" : -122.676251, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Southwest Oak Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "SOUTH", + "area" : false, + "bogusName" : false, + "distance" : 79.59, + "elevation" : "", + "lat" : 45.5222784, + "lon" : -122.6791704, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Southwest Park Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 129.53, + "elevation" : "", + "lat" : 45.5216085, + "lon" : -122.6795303, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Southwest Stark Street", + "walkingBike" : false }, { - "arrival" : "2009-11-17T18:49:00.000+00:00", - "departure" : "2009-11-17T18:49:00.000+00:00", - "lat" : 45.523249, - "lon" : -122.671269, - "name" : "W Burnside & Burnside Bridge", - "stopCode" : "689", - "stopId" : "prt:689", - "stopIndex" : 98, - "stopSequence" : 99, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, + "absoluteDirection" : "SOUTH", + "area" : false, + "bogusName" : false, + "distance" : 25.48, + "elevation" : "", + "lat" : 45.5220244, + "lon" : -122.6810834, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Southwest 10th Avenue", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:45:25.000+00:00", + "departure" : "2009-11-17T18:48:09.000+00:00", + "lat" : 45.521786, + "lon" : -122.68109, + "name" : "SW 10th & Stark", + "stopCode" : "10769", + "stopId" : "prt:10769", + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyId" : "prt:prt", + "agencyName" : "TriMet", + "agencyTimeZoneOffset" : -28800000, + "agencyUrl" : "http://trimet.org", + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 2493.24, + "endTime" : "2009-11-17T19:05:00.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:45:25.000+00:00", + "departure" : "2009-11-17T18:48:09.000+00:00", + "lat" : 45.521786, + "lon" : -122.68109, + "name" : "SW 10th & Stark", + "stopCode" : "10769", + "stopId" : "prt:10769", + "stopIndex" : 12, + "stopSequence" : 13, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + "generalizedCost" : 1775, + "headsign" : "NW 23rd Ave", + "interlineWithPreviousLeg" : false, + "intermediateStops" : [ { - "arrival" : "2009-11-17T18:50:00.000+00:00", - "departure" : "2009-11-17T18:50:00.000+00:00", - "lat" : 45.523169, - "lon" : -122.675893, - "name" : "W Burnside & NW 5th", - "stopCode" : "782", - "stopId" : "prt:782", - "stopIndex" : 99, - "stopSequence" : 100, + "arrival" : "2009-11-17T18:49:35.000+00:00", + "departure" : "2009-11-17T18:49:35.000+00:00", + "lat" : 45.523593, + "lon" : -122.681083, + "name" : "NW 10th & Couch", + "stopCode" : "10770", + "stopId" : "prt:10770", + "stopIndex" : 13, + "stopSequence" : 14, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:51:17.000+00:00", - "departure" : "2009-11-17T18:51:17.000+00:00", - "lat" : 45.523115, - "lon" : -122.678939, - "name" : "W Burnside & NW Park", - "stopCode" : "716", - "stopId" : "prt:716", - "stopIndex" : 100, - "stopSequence" : 101, + "arrival" : "2009-11-17T18:50:41.000+00:00", + "departure" : "2009-11-17T18:50:41.000+00:00", + "lat" : 45.525011, + "lon" : -122.681113, + "name" : "NW 10th & Everett", + "stopCode" : "10771", + "stopId" : "prt:10771", + "stopIndex" : 14, + "stopSequence" : 15, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:52:25.000+00:00", - "departure" : "2009-11-17T18:52:25.000+00:00", - "lat" : 45.523048, - "lon" : -122.681606, - "name" : "W Burnside & NW 10th", - "stopCode" : "10791", - "stopId" : "prt:10791", - "stopIndex" : 101, - "stopSequence" : 102, + "arrival" : "2009-11-17T18:51:49.000+00:00", + "departure" : "2009-11-17T18:51:49.000+00:00", + "lat" : 45.526446, + "lon" : -122.68118, + "name" : "NW 10th & Glisan", + "stopCode" : "10772", + "stopId" : "prt:10772", + "stopIndex" : 15, + "stopSequence" : 16, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:53:14.000+00:00", - "departure" : "2009-11-17T18:53:14.000+00:00", - "lat" : 45.523, - "lon" : -122.683535, - "name" : "W Burnside & NW 12th", - "stopCode" : "11032", - "stopId" : "prt:11032", - "stopIndex" : 102, - "stopSequence" : 103, + "arrival" : "2009-11-17T18:53:30.000+00:00", + "departure" : "2009-11-17T18:53:30.000+00:00", + "lat" : 45.528572, + "lon" : -122.68125, + "name" : "NW 10th & Johnson", + "stopCode" : "10773", + "stopId" : "prt:10773", + "stopIndex" : 16, + "stopSequence" : 17, "vertexType" : "TRANSIT", - "zoneId" : "0" + "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:55:09.000+00:00", - "departure" : "2009-11-17T18:55:09.000+00:00", - "lat" : 45.522985, - "lon" : -122.688091, - "name" : "W Burnside & NW 17th", - "stopCode" : "10809", - "stopId" : "prt:10809", - "stopIndex" : 103, - "stopSequence" : 104, + "arrival" : "2009-11-17T18:55:11.000+00:00", + "departure" : "2009-11-17T18:55:11.000+00:00", + "lat" : 45.530707, + "lon" : -122.68132, + "name" : "NW 10th & Marshall", + "stopCode" : "10774", + "stopId" : "prt:10774", + "stopIndex" : 17, + "stopSequence" : 18, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:56:00.000+00:00", - "departure" : "2009-11-17T18:56:00.000+00:00", - "lat" : 45.523097, - "lon" : -122.690083, - "name" : "W Burnside & NW 19th", - "stopCode" : "735", - "stopId" : "prt:735", - "stopIndex" : 104, - "stopSequence" : 105, + "arrival" : "2009-11-17T18:56:52.000+00:00", + "departure" : "2009-11-17T18:56:52.000+00:00", + "lat" : 45.531534, + "lon" : -122.683319, + "name" : "NW 12th & Northrup", + "stopCode" : "12796", + "stopId" : "prt:12796", + "stopIndex" : 18, + "stopSequence" : 19, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:56:21.000+00:00", - "departure" : "2009-11-17T18:56:21.000+00:00", - "lat" : 45.523176, - "lon" : -122.692139, - "name" : "W Burnside & NW 20th", - "stopCode" : "741", - "stopId" : "prt:741", - "stopIndex" : 105, - "stopSequence" : 106, + "arrival" : "2009-11-17T18:58:00.000+00:00", + "departure" : "2009-11-17T19:00:00.000+00:00", + "lat" : 45.531503, + "lon" : -122.685357, + "name" : "NW Northrup & 14th", + "stopCode" : "10775", + "stopId" : "prt:10775", + "stopIndex" : 19, + "stopSequence" : 20, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:56:31.000+00:00", - "departure" : "2009-11-17T18:56:31.000+00:00", - "lat" : 45.52322, - "lon" : -122.69313, - "name" : "W Burnside & NW 20th Pl", - "stopCode" : "742", - "stopId" : "prt:742", - "stopIndex" : 106, - "stopSequence" : 107, + "arrival" : "2009-11-17T19:01:26.000+00:00", + "departure" : "2009-11-17T19:01:26.000+00:00", + "lat" : 45.531434, + "lon" : -122.689417, + "name" : "NW Northrup & 18th", + "stopCode" : "10776", + "stopId" : "prt:10776", + "stopIndex" : 20, + "stopSequence" : 21, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:56:49.000+00:00", - "departure" : "2009-11-17T18:56:49.000+00:00", - "lat" : 45.523312, - "lon" : -122.694901, - "name" : "W Burnside & NW King", - "stopCode" : "747", - "stopId" : "prt:747", - "stopIndex" : 107, - "stopSequence" : 108, + "arrival" : "2009-11-17T19:03:13.000+00:00", + "departure" : "2009-11-17T19:03:13.000+00:00", + "lat" : 45.531346, + "lon" : -122.694455, + "name" : "NW Northrup & 21st", + "stopCode" : "10777", + "stopId" : "prt:10777", + "stopIndex" : 21, + "stopSequence" : 22, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:57:22.000+00:00", - "departure" : "2009-11-17T18:57:22.000+00:00", - "lat" : 45.523512, - "lon" : -122.698081, - "name" : "W Burnside & NW 23rd", - "stopCode" : "755", - "stopId" : "prt:755", - "stopIndex" : 108, - "stopSequence" : 109, + "arrival" : "2009-11-17T19:03:55.000+00:00", + "departure" : "2009-11-17T19:03:55.000+00:00", + "lat" : 45.531308, + "lon" : -122.696445, + "name" : "NW Northrup & 22nd", + "stopCode" : "10778", + "stopId" : "prt:10778", + "stopIndex" : 22, + "stopSequence" : 23, "vertexType" : "TRANSIT", "zoneId" : "1" } ], "legGeometry" : { - "length" : 95, - "points" : "weztGdtrkV?BPj@@jA?jEAhE?pD???VAjE?hE?dB?b@???`AAhE?dD???l@C`EAhEEhE?bAA|@?XAZ@\\AzACnGKbKAjC?bE???JEnE@fEDlE@hE@~A??@rBBzDBpE@~A???Z@tD@RBnEB|A???@BdB?lEBjA??BnBApF@dB?X?^@r@?f@@bCAx@EtB???VChAE|BGnD??AXKnEGnD???XGjD??AZEfCC`AEzB??AXCfAGxDE|AEtBIlC??APu@lJMhBI`@" + "length" : 55, + "points" : "e~ytGbdxkV[OQ@{CFa@B{B@??S@mC@Q@eB@??U@mCB{BD??S?mCBmCFyBB??U?kCBsCDsBD??W?kCBBlE@lD???XBjEBpD???VBlE?dA@t@?b@?h@BfEBrD???VBhEFtKDvJ??@\\DnJ???d@FtKvBE" }, - "mode" : "BUS", + "mode" : "TRAM", "pathway" : false, "realTime" : false, - "route" : "Burnside/Stark", - "routeId" : "prt:20", - "routeLongName" : "Burnside/Stark", - "routeShortName" : "20", - "routeType" : 3, + "route" : "Portland Streetcar", + "routeId" : "prt:193", + "routeLongName" : "Portland Streetcar", + "routeType" : 0, "serviceDate" : "2009-11-17", - "startTime" : "2009-11-17T18:45:00.000+00:00", + "startTime" : "2009-11-17T18:48:09.000+00:00", "steps" : [ ], "to" : { - "arrival" : "2009-11-17T18:57:49.000+00:00", - "departure" : "2009-11-17T18:57:49.000+00:00", - "lat" : 45.523897, - "lon" : -122.700681, - "name" : "W Burnside & NW 23rd Pl", - "stopCode" : "9555", - "stopId" : "prt:9555", - "stopIndex" : 109, - "stopSequence" : 110, + "arrival" : "2009-11-17T19:05:00.000+00:00", + "departure" : "2009-11-17T19:05:00.000+00:00", + "lat" : 45.530612, + "lon" : -122.698688, + "name" : "NW 23rd & Marshall", + "stopCode" : "8989", + "stopId" : "prt:8989", + "stopIndex" : 23, + "stopSequence" : 24, "vertexType" : "TRANSIT", "zoneId" : "1" }, "transitLeg" : true, - "tripBlockId" : "2037", - "tripId" : "prt:200W1220" + "tripBlockId" : "9380", + "tripId" : "prt:1930W1240" }, { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 913.81, - "endTime" : "2009-11-17T19:09:40.000+00:00", + "distance" : 187.24, + "endTime" : "2009-11-17T19:07:27.000+00:00", "from" : { - "arrival" : "2009-11-17T18:57:49.000+00:00", - "departure" : "2009-11-17T18:57:49.000+00:00", - "lat" : 45.523897, - "lon" : -122.700681, - "name" : "W Burnside & NW 23rd Pl", - "stopCode" : "9555", - "stopId" : "prt:9555", + "arrival" : "2009-11-17T19:05:00.000+00:00", + "departure" : "2009-11-17T19:05:00.000+00:00", + "lat" : 45.530612, + "lon" : -122.698688, + "name" : "NW 23rd & Marshall", + "stopCode" : "8989", + "stopId" : "prt:8989", "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 1388, + "generalizedCost" : 286, "interlineWithPreviousLeg" : false, "legGeometry" : { - "length" : 39, - "points" : "ikztGh~{kVNDEVUzACPOUQO_@Yc@[QMMEOKOIECGCIAMCGCGAECECECOOMOGKIFMLk@BsABGDGBoCBkCDoC@mCBmCDoCDmCD?qA" + "length" : 7, + "points" : "iu{tGxq{kV?DK?GBwADK?DpH" }, "mode" : "WALK", "pathway" : false, "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T18:57:49.000+00:00", + "startTime" : "2009-11-17T19:05:00.000+00:00", "steps" : [ { - "absoluteDirection" : "WEST", + "absoluteDirection" : "NORTH", "area" : false, "bogusName" : false, - "distance" : 54.63, + "distance" : 60.76, "elevation" : "", - "lat" : 45.5238156, - "lon" : -122.7007199, + "lat" : 45.5306118, + "lon" : -122.6987102, "relativeDirection" : "DEPART", "stayOn" : false, - "streetName" : "West Burnside Street", - "walkingBike" : false - }, - { - "absoluteDirection" : "NORTHEAST", - "area" : false, - "bogusName" : false, - "distance" : 176.41, - "elevation" : "", - "lat" : 45.5239733, - "lon" : -122.701384, - "relativeDirection" : "RIGHT", - "stayOn" : false, - "streetName" : "Northwest 24th Place", - "walkingBike" : false - }, - { - "absoluteDirection" : "NORTHWEST", - "area" : false, - "bogusName" : false, - "distance" : 15.26, - "elevation" : "", - "lat" : 45.5253583, - "lon" : -122.7003357, - "relativeDirection" : "LEFT", - "stayOn" : false, - "streetName" : "Northwest Westover Road", + "streetName" : "Northwest 23rd Avenue", "walkingBike" : false }, { "absoluteDirection" : "NORTH", "area" : false, - "bogusName" : false, - "distance" : 635.66, + "bogusName" : true, + "distance" : 7.29, "elevation" : "", - "lat" : 45.5254724, - "lon" : -122.7004445, - "relativeDirection" : "SLIGHTLY_RIGHT", + "lat" : 45.531153, + "lon" : -122.6987606, + "relativeDirection" : "CONTINUE", "stayOn" : false, - "streetName" : "Northwest 24th Avenue", + "streetName" : "path", "walkingBike" : false }, { - "absoluteDirection" : "EAST", + "absoluteDirection" : "WEST", "area" : false, "bogusName" : false, - "distance" : 31.86, + "distance" : 119.18, "elevation" : "", - "lat" : 45.531181, - "lon" : -122.7007063, - "relativeDirection" : "RIGHT", + "lat" : 45.5312184, + "lon" : -122.698768, + "relativeDirection" : "LEFT", "stayOn" : false, "streetName" : "Northwest Northrup Street", "walkingBike" : false } ], "to" : { - "arrival" : "2009-11-17T19:09:40.000+00:00", + "arrival" : "2009-11-17T19:07:27.000+00:00", "lat" : 45.531, "lon" : -122.70029, "name" : "NW Northrup St. & NW 24th Ave. (P3)", @@ -4286,21 +4500,21 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "walkingBike" : false } ], - "startTime" : "2009-11-17T18:43:47.000+00:00", + "startTime" : "2009-11-17T18:29:47.000+00:00", "tooSloped" : false, - "transfers" : 0, - "transitTime" : 769, - "waitingTime" : 0, - "walkDistance" : 1000.83, + "transfers" : 1, + "transitTime" : 1450, + "waitingTime" : 164, + "walkDistance" : 808.59, "walkLimitExceeded" : false, - "walkTime" : 784 + "walkTime" : 646 }, { "arrivedAtDestinationWithRentedBicycle" : false, - "duration" : 1567, + "duration" : 1553, "elevationGained" : 0.0, "elevationLost" : 0.0, - "endTime" : "2009-11-17T19:11:51.000+00:00", + "endTime" : "2009-11-17T19:09:40.000+00:00", "fare" : { "details" : { }, "fare" : { }, @@ -4324,39 +4538,19 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "name" : "regular" } ] - }, - { - "legIndices" : [ - 2 - ], - "products" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:8", - "name" : "regular" - } - ] } ] }, - "generalizedCost" : 2957, + "generalizedCost" : 2895, "legs" : [ { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 20.74, - "endTime" : "2009-11-17T18:46:00.000+00:00", + "distance" : 87.02, + "endTime" : "2009-11-17T18:45:00.000+00:00", "from" : { - "departure" : "2009-11-17T18:45:44.000+00:00", + "departure" : "2009-11-17T18:43:47.000+00:00", "lat" : 45.52337, "lon" : -122.653725, "name" : "NE 12th & Couch", @@ -4365,24 +4559,24 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 33, + "generalizedCost" : 137, "interlineWithPreviousLeg" : false, "legGeometry" : { - "length" : 4, - "points" : "ahztGxxrkV@Sb@??W" + "length" : 9, + "points" : "ahztGxxrkV@Sb@?`@@?a@?k@GGKY@A" }, "mode" : "WALK", "pathway" : false, "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T18:45:44.000+00:00", + "startTime" : "2009-11-17T18:43:47.000+00:00", "steps" : [ { "absoluteDirection" : "SOUTH", "area" : false, "bogusName" : false, - "distance" : 20.74, + "distance" : 39.06, "elevation" : "", "lat" : 45.5233684, "lon" : -122.6536225, @@ -4390,16 +4584,29 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "stayOn" : false, "streetName" : "Northeast 12th Avenue", "walkingBike" : false + }, + { + "absoluteDirection" : "EAST", + "area" : false, + "bogusName" : true, + "distance" : 47.96, + "elevation" : "", + "lat" : 45.5230172, + "lon" : -122.6536338, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "path", + "walkingBike" : false } ], "to" : { - "arrival" : "2009-11-17T18:46:00.000+00:00", - "departure" : "2009-11-17T18:46:00.000+00:00", - "lat" : 45.52318, - "lon" : -122.653507, - "name" : "NE 12th & Sandy", - "stopCode" : "6592", - "stopId" : "prt:6592", + "arrival" : "2009-11-17T18:45:00.000+00:00", + "departure" : "2009-11-17T18:45:00.000+00:00", + "lat" : 45.523103, + "lon" : -122.653064, + "name" : "NE Sandy & 12th", + "stopCode" : "5055", + "stopId" : "prt:5055", "vertexType" : "TRANSIT", "zoneId" : "1" }, @@ -4413,363 +4620,330 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "agencyUrl" : "http://trimet.org", "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 1355.21, - "endTime" : "2009-11-17T18:51:01.000+00:00", + "distance" : 3729.97, + "endTime" : "2009-11-17T18:57:49.000+00:00", "from" : { - "arrival" : "2009-11-17T18:46:00.000+00:00", - "departure" : "2009-11-17T18:46:00.000+00:00", - "lat" : 45.52318, - "lon" : -122.653507, - "name" : "NE 12th & Sandy", - "stopCode" : "6592", - "stopId" : "prt:6592", - "stopIndex" : 34, - "stopSequence" : 35, + "arrival" : "2009-11-17T18:45:00.000+00:00", + "departure" : "2009-11-17T18:45:00.000+00:00", + "lat" : 45.523103, + "lon" : -122.653064, + "name" : "NE Sandy & 12th", + "stopCode" : "5055", + "stopId" : "prt:5055", + "stopIndex" : 94, + "stopSequence" : 95, "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 901, - "headsign" : "Rose Qtr TC", + "generalizedCost" : 1369, + "headsign" : "Beaverton TC", "interlineWithPreviousLeg" : false, "intermediateStops" : [ { - "arrival" : "2009-11-17T18:47:45.000+00:00", - "departure" : "2009-11-17T18:47:45.000+00:00", - "lat" : 45.527449, - "lon" : -122.653462, - "name" : "NE 12th & Irving", - "stopCode" : "6582", - "stopId" : "prt:6582", - "stopIndex" : 35, - "stopSequence" : 36, + "arrival" : "2009-11-17T18:45:47.000+00:00", + "departure" : "2009-11-17T18:45:47.000+00:00", + "lat" : 45.523024, + "lon" : -122.656526, + "name" : "E Burnside & NE 9th", + "stopCode" : "819", + "stopId" : "prt:819", + "stopIndex" : 95, + "stopSequence" : 96, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:49:00.000+00:00", - "departure" : "2009-11-17T18:49:00.000+00:00", - "lat" : 45.529793, - "lon" : -122.654429, - "name" : "NE 11th & Holladay", - "stopCode" : "8513", - "stopId" : "prt:8513", - "stopIndex" : 36, - "stopSequence" : 37, + "arrival" : "2009-11-17T18:46:24.000+00:00", + "departure" : "2009-11-17T18:46:24.000+00:00", + "lat" : 45.523012, + "lon" : -122.659365, + "name" : "E Burnside & NE 6th", + "stopCode" : "805", + "stopId" : "prt:805", + "stopIndex" : 96, + "stopSequence" : 97, "vertexType" : "TRANSIT", - "zoneId" : "0" + "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:49:39.000+00:00", - "departure" : "2009-11-17T18:49:39.000+00:00", - "lat" : 45.53135, - "lon" : -122.654497, - "name" : "NE 11th & Multnomah", - "stopCode" : "8938", - "stopId" : "prt:8938", - "stopIndex" : 37, - "stopSequence" : 38, + "arrival" : "2009-11-17T18:46:52.000+00:00", + "departure" : "2009-11-17T18:46:52.000+00:00", + "lat" : 45.523015, + "lon" : -122.661534, + "name" : "E Burnside & NE M L King", + "stopCode" : "705", + "stopId" : "prt:705", + "stopIndex" : 97, + "stopSequence" : 98, "vertexType" : "TRANSIT", - "zoneId" : "0" + "zoneId" : "1" }, { - "arrival" : "2009-11-17T18:50:15.000+00:00", - "departure" : "2009-11-17T18:50:15.000+00:00", - "lat" : 45.531573, - "lon" : -122.656408, - "name" : "NE Multnomah & 9th", - "stopCode" : "4056", - "stopId" : "prt:4056", - "stopIndex" : 38, - "stopSequence" : 39, - "vertexType" : "TRANSIT", - "zoneId" : "0" - } - ], - "legGeometry" : { - "length" : 33, - "points" : "{fztG`xrkVwA?mCAmC?oCA}C?sDC??aBAm@@k@AY?uABU@I@IBQFb@fC}@d@OFO@q@???Q?]?gGA??[??nJ???b@?vK?rA" - }, - "mode" : "BUS", - "pathway" : false, - "realTime" : false, - "route" : "12th Ave", - "routeId" : "prt:70", - "routeLongName" : "12th Ave", - "routeShortName" : "70", - "routeType" : 3, - "serviceDate" : "2009-11-17", - "startTime" : "2009-11-17T18:46:00.000+00:00", - "steps" : [ ], - "to" : { - "arrival" : "2009-11-17T18:51:01.000+00:00", - "departure" : "2009-11-17T18:54:29.000+00:00", - "lat" : 45.531569, - "lon" : -122.659045, - "name" : "NE Multnomah & 7th", - "stopCode" : "4054", - "stopId" : "prt:4054", - "stopIndex" : 39, - "stopSequence" : 40, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - "transitLeg" : true, - "tripBlockId" : "7002", - "tripId" : "prt:700W1170" - }, - { - "agencyId" : "prt:prt", - "agencyName" : "TriMet", - "agencyTimeZoneOffset" : -28800000, - "agencyUrl" : "http://trimet.org", - "arrivalDelay" : 0, - "departureDelay" : 0, - "distance" : 3838.71, - "endTime" : "2009-11-17T19:08:50.000+00:00", - "from" : { - "arrival" : "2009-11-17T18:51:01.000+00:00", - "departure" : "2009-11-17T18:54:29.000+00:00", - "lat" : 45.531569, - "lon" : -122.659045, - "name" : "NE Multnomah & 7th", - "stopCode" : "4054", - "stopId" : "prt:4054", - "stopIndex" : 81, - "stopSequence" : 82, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - "generalizedCost" : 1669, - "headsign" : "Montgomery Park", - "interlineWithPreviousLeg" : false, - "intermediateStops" : [ - { - "arrival" : "2009-11-17T18:55:05.000+00:00", - "departure" : "2009-11-17T18:55:05.000+00:00", - "lat" : 45.531586, - "lon" : -122.660482, - "name" : "NE Multnomah & Grand", - "stopCode" : "4043", - "stopId" : "prt:4043", - "stopIndex" : 82, - "stopSequence" : 83, + "arrival" : "2009-11-17T18:49:00.000+00:00", + "departure" : "2009-11-17T18:49:00.000+00:00", + "lat" : 45.523249, + "lon" : -122.671269, + "name" : "W Burnside & Burnside Bridge", + "stopCode" : "689", + "stopId" : "prt:689", + "stopIndex" : 98, + "stopSequence" : 99, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:56:09.000+00:00", - "departure" : "2009-11-17T18:56:09.000+00:00", - "lat" : 45.531159, - "lon" : -122.66293, - "name" : "NE Multnomah & 3rd", - "stopCode" : "11492", - "stopId" : "prt:11492", - "stopIndex" : 83, - "stopSequence" : 84, + "arrival" : "2009-11-17T18:50:00.000+00:00", + "departure" : "2009-11-17T18:50:00.000+00:00", + "lat" : 45.523169, + "lon" : -122.675893, + "name" : "W Burnside & NW 5th", + "stopCode" : "782", + "stopId" : "prt:782", + "stopIndex" : 99, + "stopSequence" : 100, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T18:58:00.000+00:00", - "departure" : "2009-11-17T18:58:00.000+00:00", - "lat" : 45.530005, - "lon" : -122.666476, - "name" : "Rose Quarter Transit Center", - "stopCode" : "2592", - "stopId" : "prt:2592", - "stopIndex" : 84, - "stopSequence" : 85, + "arrival" : "2009-11-17T18:51:17.000+00:00", + "departure" : "2009-11-17T18:51:17.000+00:00", + "lat" : 45.523115, + "lon" : -122.678939, + "name" : "W Burnside & NW Park", + "stopCode" : "716", + "stopId" : "prt:716", + "stopIndex" : 100, + "stopSequence" : 101, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T19:01:20.000+00:00", - "departure" : "2009-11-17T19:01:20.000+00:00", - "lat" : 45.526655, - "lon" : -122.676462, - "name" : "NW Glisan & 6th", - "stopCode" : "10803", - "stopId" : "prt:10803", - "stopIndex" : 85, - "stopSequence" : 86, + "arrival" : "2009-11-17T18:52:25.000+00:00", + "departure" : "2009-11-17T18:52:25.000+00:00", + "lat" : 45.523048, + "lon" : -122.681606, + "name" : "W Burnside & NW 10th", + "stopCode" : "10791", + "stopId" : "prt:10791", + "stopIndex" : 101, + "stopSequence" : 102, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T19:02:15.000+00:00", - "departure" : "2009-11-17T19:02:15.000+00:00", - "lat" : 45.528799, - "lon" : -122.677238, - "name" : "NW Station Way & Union Station", - "stopCode" : "12801", - "stopId" : "prt:12801", - "stopIndex" : 86, - "stopSequence" : 87, + "arrival" : "2009-11-17T18:53:14.000+00:00", + "departure" : "2009-11-17T18:53:14.000+00:00", + "lat" : 45.523, + "lon" : -122.683535, + "name" : "W Burnside & NW 12th", + "stopCode" : "11032", + "stopId" : "prt:11032", + "stopIndex" : 102, + "stopSequence" : 103, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T19:04:00.000+00:00", - "departure" : "2009-11-17T19:04:00.000+00:00", - "lat" : 45.531582, - "lon" : -122.681193, - "name" : "NW Northrup & 10th", - "stopCode" : "12802", - "stopId" : "prt:12802", - "stopIndex" : 87, - "stopSequence" : 88, + "arrival" : "2009-11-17T18:55:09.000+00:00", + "departure" : "2009-11-17T18:55:09.000+00:00", + "lat" : 45.522985, + "lon" : -122.688091, + "name" : "W Burnside & NW 17th", + "stopCode" : "10809", + "stopId" : "prt:10809", + "stopIndex" : 103, + "stopSequence" : 104, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T19:04:33.000+00:00", - "departure" : "2009-11-17T19:04:33.000+00:00", - "lat" : 45.531534, - "lon" : -122.683319, - "name" : "NW 12th & Northrup", - "stopCode" : "12796", - "stopId" : "prt:12796", - "stopIndex" : 88, - "stopSequence" : 89, + "arrival" : "2009-11-17T18:56:00.000+00:00", + "departure" : "2009-11-17T18:56:00.000+00:00", + "lat" : 45.523097, + "lon" : -122.690083, + "name" : "W Burnside & NW 19th", + "stopCode" : "735", + "stopId" : "prt:735", + "stopIndex" : 104, + "stopSequence" : 105, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T19:05:04.000+00:00", - "departure" : "2009-11-17T19:05:04.000+00:00", - "lat" : 45.531503, - "lon" : -122.685357, - "name" : "NW Northrup & 14th", - "stopCode" : "10775", - "stopId" : "prt:10775", - "stopIndex" : 89, - "stopSequence" : 90, + "arrival" : "2009-11-17T18:56:21.000+00:00", + "departure" : "2009-11-17T18:56:21.000+00:00", + "lat" : 45.523176, + "lon" : -122.692139, + "name" : "W Burnside & NW 20th", + "stopCode" : "741", + "stopId" : "prt:741", + "stopIndex" : 105, + "stopSequence" : 106, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T19:06:07.000+00:00", - "departure" : "2009-11-17T19:06:07.000+00:00", - "lat" : 45.531434, - "lon" : -122.689417, - "name" : "NW Northrup & 18th", - "stopCode" : "10776", - "stopId" : "prt:10776", - "stopIndex" : 90, - "stopSequence" : 91, + "arrival" : "2009-11-17T18:56:31.000+00:00", + "departure" : "2009-11-17T18:56:31.000+00:00", + "lat" : 45.52322, + "lon" : -122.69313, + "name" : "W Burnside & NW 20th Pl", + "stopCode" : "742", + "stopId" : "prt:742", + "stopIndex" : 106, + "stopSequence" : 107, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T19:07:24.000+00:00", - "departure" : "2009-11-17T19:07:24.000+00:00", - "lat" : 45.531346, - "lon" : -122.694455, - "name" : "NW Northrup & 21st", - "stopCode" : "10777", - "stopId" : "prt:10777", - "stopIndex" : 91, - "stopSequence" : 92, + "arrival" : "2009-11-17T18:56:49.000+00:00", + "departure" : "2009-11-17T18:56:49.000+00:00", + "lat" : 45.523312, + "lon" : -122.694901, + "name" : "W Burnside & NW King", + "stopCode" : "747", + "stopId" : "prt:747", + "stopIndex" : 107, + "stopSequence" : 108, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T19:07:55.000+00:00", - "departure" : "2009-11-17T19:07:55.000+00:00", - "lat" : 45.531308, - "lon" : -122.696445, - "name" : "NW Northrup & 22nd", - "stopCode" : "10778", - "stopId" : "prt:10778", - "stopIndex" : 92, - "stopSequence" : 93, + "arrival" : "2009-11-17T18:57:22.000+00:00", + "departure" : "2009-11-17T18:57:22.000+00:00", + "lat" : 45.523512, + "lon" : -122.698081, + "name" : "W Burnside & NW 23rd", + "stopCode" : "755", + "stopId" : "prt:755", + "stopIndex" : 108, + "stopSequence" : 109, "vertexType" : "TRANSIT", "zoneId" : "1" } ], "legGeometry" : { - "length" : 109, - "points" : "yz{tG`zskV?tBCfD???^?nE?V@Z?PH\\Nb@`@~@Rf@??`@bANb@FV@R?P?pE?jA@h@AnAbBl@LFJN\\f@LT??NXJPPVJFf@Vf@Pp@Nd@NRLB@RNXZR\\vAhC@BhAhD`AhClAbDBrDCnG@n@@^@d@HdAP`CBjEDvD???LqCFmCDYBGDEBGJkAzAQR??KNa@b@MJuBBY?OHW@u@~@aD`EcBhBBrD@xC??@l@BlE@lD???XBjEBpD???VBlE?dA@t@?b@?h@BfEBrD???VBhEFtKDvJ??@\\DnJ???d@FtKmCBo@@" + "length" : 95, + "points" : "weztGdtrkV?BPj@@jA?jEAhE?pD???VAjE?hE?dB?b@???`AAhE?dD???l@C`EAhEEhE?bAA|@?XAZ@\\AzACnGKbKAjC?bE???JEnE@fEDlE@hE@~A??@rBBzDBpE@~A???Z@tD@RBnEB|A???@BdB?lEBjA??BnBApF@dB?X?^@r@?f@@bCAx@EtB???VChAE|BGnD??AXKnEGnD???XGjD??AZEfCC`AEzB??AXCfAGxDE|AEtBIlC??APu@lJMhBI`@" }, "mode" : "BUS", "pathway" : false, "realTime" : false, - "route" : "Broadway/Halsey", - "routeId" : "prt:77", - "routeLongName" : "Broadway/Halsey", - "routeShortName" : "77", + "route" : "Burnside/Stark", + "routeId" : "prt:20", + "routeLongName" : "Burnside/Stark", + "routeShortName" : "20", "routeType" : 3, "serviceDate" : "2009-11-17", - "startTime" : "2009-11-17T18:54:29.000+00:00", + "startTime" : "2009-11-17T18:45:00.000+00:00", "steps" : [ ], "to" : { - "arrival" : "2009-11-17T19:08:50.000+00:00", - "departure" : "2009-11-17T19:08:50.000+00:00", - "lat" : 45.532159, - "lon" : -122.698634, - "name" : "NW 23rd & Overton", - "stopCode" : "8981", - "stopId" : "prt:8981", - "stopIndex" : 93, - "stopSequence" : 94, + "arrival" : "2009-11-17T18:57:49.000+00:00", + "departure" : "2009-11-17T18:57:49.000+00:00", + "lat" : 45.523897, + "lon" : -122.700681, + "name" : "W Burnside & NW 23rd Pl", + "stopCode" : "9555", + "stopId" : "prt:9555", + "stopIndex" : 109, + "stopSequence" : 110, "vertexType" : "TRANSIT", "zoneId" : "1" }, "transitLeg" : true, - "tripBlockId" : "7702", - "tripId" : "prt:771W1180" + "tripBlockId" : "2037", + "tripId" : "prt:200W1220" }, { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 231.46, - "endTime" : "2009-11-17T19:11:51.000+00:00", + "distance" : 913.81, + "endTime" : "2009-11-17T19:09:40.000+00:00", "from" : { - "arrival" : "2009-11-17T19:08:50.000+00:00", - "departure" : "2009-11-17T19:08:50.000+00:00", - "lat" : 45.532159, - "lon" : -122.698634, - "name" : "NW 23rd & Overton", - "stopCode" : "8981", - "stopId" : "prt:8981", + "arrival" : "2009-11-17T18:57:49.000+00:00", + "departure" : "2009-11-17T18:57:49.000+00:00", + "lat" : 45.523897, + "lon" : -122.700681, + "name" : "W Burnside & NW 23rd Pl", + "stopCode" : "9555", + "stopId" : "prt:9555", "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 353, + "generalizedCost" : 1388, "interlineWithPreviousLeg" : false, "legGeometry" : { - "length" : 10, - "points" : "}~{tGnq{kV?LVAF?J?L?rBCLA?RDpH" + "length" : 39, + "points" : "ikztGh~{kVNDEVUzACPOUQO_@Yc@[QMMEOKOIECGCIAMCGCGAECECECOOMOGKIFMLk@BsABGDGBoCBkCDoC@mCBmCDoCDmCD?qA" }, "mode" : "WALK", "pathway" : false, "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T19:08:50.000+00:00", + "startTime" : "2009-11-17T18:57:49.000+00:00", "steps" : [ { - "absoluteDirection" : "SOUTH", + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 54.63, + "elevation" : "", + "lat" : 45.5238156, + "lon" : -122.7007199, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "West Burnside Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTHEAST", "area" : false, "bogusName" : false, - "distance" : 104.46, + "distance" : 176.41, "elevation" : "", - "lat" : 45.5321578, - "lon" : -122.6987026, - "relativeDirection" : "DEPART", + "lat" : 45.5239733, + "lon" : -122.701384, + "relativeDirection" : "RIGHT", "stayOn" : false, - "streetName" : "Northwest 23rd Avenue", + "streetName" : "Northwest 24th Place", "walkingBike" : false }, { - "absoluteDirection" : "WEST", + "absoluteDirection" : "NORTHWEST", "area" : false, "bogusName" : false, - "distance" : 127.01, + "distance" : 15.26, "elevation" : "", - "lat" : 45.5312188, - "lon" : -122.6986675, + "lat" : 45.5253583, + "lon" : -122.7003357, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Northwest Westover Road", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 635.66, + "elevation" : "", + "lat" : 45.5254724, + "lon" : -122.7004445, + "relativeDirection" : "SLIGHTLY_RIGHT", + "stayOn" : false, + "streetName" : "Northwest 24th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "EAST", + "area" : false, + "bogusName" : false, + "distance" : 31.86, + "elevation" : "", + "lat" : 45.531181, + "lon" : -122.7007063, "relativeDirection" : "RIGHT", "stayOn" : false, "streetName" : "Northwest Northrup Street", @@ -4777,7 +4951,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } ], "to" : { - "arrival" : "2009-11-17T19:11:51.000+00:00", + "arrival" : "2009-11-17T19:09:40.000+00:00", "lat" : 45.531, "lon" : -122.70029, "name" : "NW Northrup St. & NW 24th Ave. (P3)", @@ -4787,21 +4961,21 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "walkingBike" : false } ], - "startTime" : "2009-11-17T18:45:44.000+00:00", + "startTime" : "2009-11-17T18:43:47.000+00:00", "tooSloped" : false, - "transfers" : 1, - "transitTime" : 1162, - "waitingTime" : 208, - "walkDistance" : 252.2, + "transfers" : 0, + "transitTime" : 769, + "waitingTime" : 0, + "walkDistance" : 1000.83, "walkLimitExceeded" : false, - "walkTime" : 197 + "walkTime" : 784 }, { "arrivedAtDestinationWithRentedBicycle" : false, - "duration" : 1578, + "duration" : 1567, "elevationGained" : 0.0, "elevationLost" : 0.0, - "endTime" : "2009-11-17T19:25:05.000+00:00", + "endTime" : "2009-11-17T19:11:51.000+00:00", "fare" : { "details" : { }, "fare" : { }, @@ -4848,16 +5022,16 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } ] }, - "generalizedCost" : 3015, + "generalizedCost" : 2957, "legs" : [ { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 87.02, - "endTime" : "2009-11-17T19:00:00.000+00:00", + "distance" : 20.74, + "endTime" : "2009-11-17T18:46:00.000+00:00", "from" : { - "departure" : "2009-11-17T18:58:47.000+00:00", + "departure" : "2009-11-17T18:45:44.000+00:00", "lat" : 45.52337, "lon" : -122.653725, "name" : "NE 12th & Couch", @@ -4866,24 +5040,24 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 137, + "generalizedCost" : 33, "interlineWithPreviousLeg" : false, "legGeometry" : { - "length" : 9, - "points" : "ahztGxxrkV@Sb@?`@@?a@?k@GGKY@A" + "length" : 4, + "points" : "ahztGxxrkV@Sb@??W" }, "mode" : "WALK", "pathway" : false, "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T18:58:47.000+00:00", + "startTime" : "2009-11-17T18:45:44.000+00:00", "steps" : [ { "absoluteDirection" : "SOUTH", "area" : false, "bogusName" : false, - "distance" : 39.06, + "distance" : 20.74, "elevation" : "", "lat" : 45.5233684, "lon" : -122.6536225, @@ -4891,29 +5065,16 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "stayOn" : false, "streetName" : "Northeast 12th Avenue", "walkingBike" : false - }, - { - "absoluteDirection" : "EAST", - "area" : false, - "bogusName" : true, - "distance" : 47.96, - "elevation" : "", - "lat" : 45.5230172, - "lon" : -122.6536338, - "relativeDirection" : "LEFT", - "stayOn" : false, - "streetName" : "path", - "walkingBike" : false } ], "to" : { - "arrival" : "2009-11-17T19:00:00.000+00:00", - "departure" : "2009-11-17T19:00:00.000+00:00", - "lat" : 45.523103, - "lon" : -122.653064, - "name" : "NE Sandy & 12th", - "stopCode" : "5055", - "stopId" : "prt:5055", + "arrival" : "2009-11-17T18:46:00.000+00:00", + "departure" : "2009-11-17T18:46:00.000+00:00", + "lat" : 45.52318, + "lon" : -122.653507, + "name" : "NE 12th & Sandy", + "stopCode" : "6592", + "stopId" : "prt:6592", "vertexType" : "TRANSIT", "zoneId" : "1" }, @@ -4927,226 +5088,109 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "agencyUrl" : "http://trimet.org", "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 3520.32, - "endTime" : "2009-11-17T19:12:44.000+00:00", + "distance" : 1355.21, + "endTime" : "2009-11-17T18:51:01.000+00:00", "from" : { - "arrival" : "2009-11-17T19:00:00.000+00:00", - "departure" : "2009-11-17T19:00:00.000+00:00", - "lat" : 45.523103, - "lon" : -122.653064, - "name" : "NE Sandy & 12th", - "stopCode" : "5055", - "stopId" : "prt:5055", - "stopIndex" : 94, - "stopSequence" : 95, + "arrival" : "2009-11-17T18:46:00.000+00:00", + "departure" : "2009-11-17T18:46:00.000+00:00", + "lat" : 45.52318, + "lon" : -122.653507, + "name" : "NE 12th & Sandy", + "stopCode" : "6592", + "stopId" : "prt:6592", + "stopIndex" : 34, + "stopSequence" : 35, "vertexType" : "TRANSIT", "zoneId" : "1" }, - "generalizedCost" : 1364, - "headsign" : "23rd Ave to Tichner", + "generalizedCost" : 901, + "headsign" : "Rose Qtr TC", "interlineWithPreviousLeg" : false, "intermediateStops" : [ { - "arrival" : "2009-11-17T19:00:47.000+00:00", - "departure" : "2009-11-17T19:00:47.000+00:00", - "lat" : 45.523024, - "lon" : -122.656526, - "name" : "E Burnside & NE 9th", - "stopCode" : "819", - "stopId" : "prt:819", - "stopIndex" : 95, - "stopSequence" : 96, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T19:01:24.000+00:00", - "departure" : "2009-11-17T19:01:24.000+00:00", - "lat" : 45.523012, - "lon" : -122.659365, - "name" : "E Burnside & NE 6th", - "stopCode" : "805", - "stopId" : "prt:805", - "stopIndex" : 96, - "stopSequence" : 97, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T19:01:52.000+00:00", - "departure" : "2009-11-17T19:01:52.000+00:00", - "lat" : 45.523015, - "lon" : -122.661534, - "name" : "E Burnside & NE M L King", - "stopCode" : "705", - "stopId" : "prt:705", - "stopIndex" : 97, - "stopSequence" : 98, + "arrival" : "2009-11-17T18:47:45.000+00:00", + "departure" : "2009-11-17T18:47:45.000+00:00", + "lat" : 45.527449, + "lon" : -122.653462, + "name" : "NE 12th & Irving", + "stopCode" : "6582", + "stopId" : "prt:6582", + "stopIndex" : 35, + "stopSequence" : 36, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T19:04:00.000+00:00", - "departure" : "2009-11-17T19:04:00.000+00:00", - "lat" : 45.523249, - "lon" : -122.671269, - "name" : "W Burnside & Burnside Bridge", - "stopCode" : "689", - "stopId" : "prt:689", - "stopIndex" : 98, - "stopSequence" : 99, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - { - "arrival" : "2009-11-17T19:05:00.000+00:00", - "departure" : "2009-11-17T19:05:00.000+00:00", - "lat" : 45.523169, - "lon" : -122.675893, - "name" : "W Burnside & NW 5th", - "stopCode" : "782", - "stopId" : "prt:782", - "stopIndex" : 99, - "stopSequence" : 100, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - { - "arrival" : "2009-11-17T19:06:17.000+00:00", - "departure" : "2009-11-17T19:06:17.000+00:00", - "lat" : 45.523115, - "lon" : -122.678939, - "name" : "W Burnside & NW Park", - "stopCode" : "716", - "stopId" : "prt:716", - "stopIndex" : 100, - "stopSequence" : 101, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - { - "arrival" : "2009-11-17T19:07:25.000+00:00", - "departure" : "2009-11-17T19:07:25.000+00:00", - "lat" : 45.523048, - "lon" : -122.681606, - "name" : "W Burnside & NW 10th", - "stopCode" : "10791", - "stopId" : "prt:10791", - "stopIndex" : 101, - "stopSequence" : 102, - "vertexType" : "TRANSIT", - "zoneId" : "0" - }, - { - "arrival" : "2009-11-17T19:08:14.000+00:00", - "departure" : "2009-11-17T19:08:14.000+00:00", - "lat" : 45.523, - "lon" : -122.683535, - "name" : "W Burnside & NW 12th", - "stopCode" : "11032", - "stopId" : "prt:11032", - "stopIndex" : 102, - "stopSequence" : 103, + "arrival" : "2009-11-17T18:49:00.000+00:00", + "departure" : "2009-11-17T18:49:00.000+00:00", + "lat" : 45.529793, + "lon" : -122.654429, + "name" : "NE 11th & Holladay", + "stopCode" : "8513", + "stopId" : "prt:8513", + "stopIndex" : 36, + "stopSequence" : 37, "vertexType" : "TRANSIT", "zoneId" : "0" }, { - "arrival" : "2009-11-17T19:10:09.000+00:00", - "departure" : "2009-11-17T19:10:09.000+00:00", - "lat" : 45.522985, - "lon" : -122.688091, - "name" : "W Burnside & NW 17th", - "stopCode" : "10809", - "stopId" : "prt:10809", - "stopIndex" : 103, - "stopSequence" : 104, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T19:11:00.000+00:00", - "departure" : "2009-11-17T19:11:00.000+00:00", - "lat" : 45.523097, - "lon" : -122.690083, - "name" : "W Burnside & NW 19th", - "stopCode" : "735", - "stopId" : "prt:735", - "stopIndex" : 104, - "stopSequence" : 105, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T19:11:27.000+00:00", - "departure" : "2009-11-17T19:11:27.000+00:00", - "lat" : 45.523176, - "lon" : -122.692139, - "name" : "W Burnside & NW 20th", - "stopCode" : "741", - "stopId" : "prt:741", - "stopIndex" : 105, - "stopSequence" : 106, - "vertexType" : "TRANSIT", - "zoneId" : "1" - }, - { - "arrival" : "2009-11-17T19:11:40.000+00:00", - "departure" : "2009-11-17T19:11:40.000+00:00", - "lat" : 45.52322, - "lon" : -122.69313, - "name" : "W Burnside & NW 20th Pl", - "stopCode" : "742", - "stopId" : "prt:742", - "stopIndex" : 106, - "stopSequence" : 107, + "arrival" : "2009-11-17T18:49:39.000+00:00", + "departure" : "2009-11-17T18:49:39.000+00:00", + "lat" : 45.53135, + "lon" : -122.654497, + "name" : "NE 11th & Multnomah", + "stopCode" : "8938", + "stopId" : "prt:8938", + "stopIndex" : 37, + "stopSequence" : 38, "vertexType" : "TRANSIT", - "zoneId" : "1" + "zoneId" : "0" }, { - "arrival" : "2009-11-17T19:12:03.000+00:00", - "departure" : "2009-11-17T19:12:03.000+00:00", - "lat" : 45.523312, - "lon" : -122.694901, - "name" : "W Burnside & NW King", - "stopCode" : "747", - "stopId" : "prt:747", - "stopIndex" : 107, - "stopSequence" : 108, + "arrival" : "2009-11-17T18:50:15.000+00:00", + "departure" : "2009-11-17T18:50:15.000+00:00", + "lat" : 45.531573, + "lon" : -122.656408, + "name" : "NE Multnomah & 9th", + "stopCode" : "4056", + "stopId" : "prt:4056", + "stopIndex" : 38, + "stopSequence" : 39, "vertexType" : "TRANSIT", - "zoneId" : "1" + "zoneId" : "0" } ], "legGeometry" : { - "length" : 90, - "points" : "weztGdtrkV?BPj@@jA?jEAhE?pD???VAjE?hE?dB?b@???`AAhE?dD???l@C`EAhEEhE?bAA|@?XAZ@\\AzACnGKbKAjC?bE???JEnE@fEDlE@hE@~A??@rBBzDBpE@~A???Z@tD@RBnEB|A???@BdB?lEBjA??BnBApF@dB?X?^@r@?f@@bCAx@EtB???VChAE|BGnD??AXKnEGnD???XGjD??AZEfCC`AEzB??AXCfAGxDE|AEtBIlC" + "length" : 33, + "points" : "{fztG`xrkVwA?mCAmC?oCA}C?sDC??aBAm@@k@AY?uABU@I@IBQFb@fC}@d@OFO@q@???Q?]?gGA??[??nJ???b@?vK?rA" }, "mode" : "BUS", "pathway" : false, "realTime" : false, - "route" : "Burnside/Stark", - "routeId" : "prt:20", - "routeLongName" : "Burnside/Stark", - "routeShortName" : "20", + "route" : "12th Ave", + "routeId" : "prt:70", + "routeLongName" : "12th Ave", + "routeShortName" : "70", "routeType" : 3, "serviceDate" : "2009-11-17", - "startTime" : "2009-11-17T19:00:00.000+00:00", + "startTime" : "2009-11-17T18:46:00.000+00:00", "steps" : [ ], "to" : { - "arrival" : "2009-11-17T19:12:44.000+00:00", - "departure" : "2009-11-17T19:17:51.000+00:00", - "lat" : 45.523512, - "lon" : -122.698081, - "name" : "W Burnside & NW 23rd", - "stopCode" : "755", - "stopId" : "prt:755", - "stopIndex" : 108, - "stopSequence" : 109, + "arrival" : "2009-11-17T18:51:01.000+00:00", + "departure" : "2009-11-17T18:54:29.000+00:00", + "lat" : 45.531569, + "lon" : -122.659045, + "name" : "NE Multnomah & 7th", + "stopCode" : "4054", + "stopId" : "prt:4054", + "stopIndex" : 39, + "stopSequence" : 40, "vertexType" : "TRANSIT", - "zoneId" : "1" + "zoneId" : "0" }, "transitLeg" : true, - "tripBlockId" : "2038", - "tripId" : "prt:200W1230" + "tripBlockId" : "7002", + "tripId" : "prt:700W1170" }, { "agencyId" : "prt:prt", @@ -5155,106 +5199,210 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "agencyUrl" : "http://trimet.org", "arrivalDelay" : 0, "departureDelay" : 0, - "distance" : 981.85, - "endTime" : "2009-11-17T19:22:04.000+00:00", + "distance" : 3838.71, + "endTime" : "2009-11-17T19:08:50.000+00:00", "from" : { - "arrival" : "2009-11-17T19:12:44.000+00:00", - "departure" : "2009-11-17T19:17:51.000+00:00", - "lat" : 45.523512, - "lon" : -122.698081, - "name" : "W Burnside & NW 23rd", - "stopCode" : "755", - "stopId" : "prt:755", - "stopIndex" : 70, - "stopSequence" : 71, + "arrival" : "2009-11-17T18:51:01.000+00:00", + "departure" : "2009-11-17T18:54:29.000+00:00", + "lat" : 45.531569, + "lon" : -122.659045, + "name" : "NE Multnomah & 7th", + "stopCode" : "4054", + "stopId" : "prt:4054", + "stopIndex" : 81, + "stopSequence" : 82, "vertexType" : "TRANSIT", - "zoneId" : "1" + "zoneId" : "0" }, - "generalizedCost" : 1160, - "headsign" : "27th & Thurman", + "generalizedCost" : 1669, + "headsign" : "Montgomery Park", "interlineWithPreviousLeg" : false, "intermediateStops" : [ { - "arrival" : "2009-11-17T19:18:53.000+00:00", - "departure" : "2009-11-17T19:18:53.000+00:00", - "lat" : 45.525416, - "lon" : -122.698381, - "name" : "NW 23rd & Flanders", - "stopCode" : "7157", - "stopId" : "prt:7157", - "stopIndex" : 71, - "stopSequence" : 72, + "arrival" : "2009-11-17T18:55:05.000+00:00", + "departure" : "2009-11-17T18:55:05.000+00:00", + "lat" : 45.531586, + "lon" : -122.660482, + "name" : "NE Multnomah & Grand", + "stopCode" : "4043", + "stopId" : "prt:4043", + "stopIndex" : 82, + "stopSequence" : 83, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:56:09.000+00:00", + "departure" : "2009-11-17T18:56:09.000+00:00", + "lat" : 45.531159, + "lon" : -122.66293, + "name" : "NE Multnomah & 3rd", + "stopCode" : "11492", + "stopId" : "prt:11492", + "stopIndex" : 83, + "stopSequence" : 84, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:58:00.000+00:00", + "departure" : "2009-11-17T18:58:00.000+00:00", + "lat" : 45.530005, + "lon" : -122.666476, + "name" : "Rose Quarter Transit Center", + "stopCode" : "2592", + "stopId" : "prt:2592", + "stopIndex" : 84, + "stopSequence" : 85, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T19:01:20.000+00:00", + "departure" : "2009-11-17T19:01:20.000+00:00", + "lat" : 45.526655, + "lon" : -122.676462, + "name" : "NW Glisan & 6th", + "stopCode" : "10803", + "stopId" : "prt:10803", + "stopIndex" : 85, + "stopSequence" : 86, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T19:02:15.000+00:00", + "departure" : "2009-11-17T19:02:15.000+00:00", + "lat" : 45.528799, + "lon" : -122.677238, + "name" : "NW Station Way & Union Station", + "stopCode" : "12801", + "stopId" : "prt:12801", + "stopIndex" : 86, + "stopSequence" : 87, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T19:04:00.000+00:00", + "departure" : "2009-11-17T19:04:00.000+00:00", + "lat" : 45.531582, + "lon" : -122.681193, + "name" : "NW Northrup & 10th", + "stopCode" : "12802", + "stopId" : "prt:12802", + "stopIndex" : 87, + "stopSequence" : 88, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T19:19:56.000+00:00", - "departure" : "2009-11-17T19:19:56.000+00:00", - "lat" : 45.527543, - "lon" : -122.698473, - "name" : "NW 23rd & Irving", - "stopCode" : "7161", - "stopId" : "prt:7161", - "stopIndex" : 72, - "stopSequence" : 73, + "arrival" : "2009-11-17T19:04:33.000+00:00", + "departure" : "2009-11-17T19:04:33.000+00:00", + "lat" : 45.531534, + "lon" : -122.683319, + "name" : "NW 12th & Northrup", + "stopCode" : "12796", + "stopId" : "prt:12796", + "stopIndex" : 88, + "stopSequence" : 89, "vertexType" : "TRANSIT", "zoneId" : "1" }, { - "arrival" : "2009-11-17T19:21:00.000+00:00", - "departure" : "2009-11-17T19:21:00.000+00:00", - "lat" : 45.529681, - "lon" : -122.698529, - "name" : "NW 23rd & Lovejoy", - "stopCode" : "7163", - "stopId" : "prt:7163", - "stopIndex" : 73, - "stopSequence" : 74, + "arrival" : "2009-11-17T19:05:04.000+00:00", + "departure" : "2009-11-17T19:05:04.000+00:00", + "lat" : 45.531503, + "lon" : -122.685357, + "name" : "NW Northrup & 14th", + "stopCode" : "10775", + "stopId" : "prt:10775", + "stopIndex" : 89, + "stopSequence" : 90, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T19:06:07.000+00:00", + "departure" : "2009-11-17T19:06:07.000+00:00", + "lat" : 45.531434, + "lon" : -122.689417, + "name" : "NW Northrup & 18th", + "stopCode" : "10776", + "stopId" : "prt:10776", + "stopIndex" : 90, + "stopSequence" : 91, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T19:07:24.000+00:00", + "departure" : "2009-11-17T19:07:24.000+00:00", + "lat" : 45.531346, + "lon" : -122.694455, + "name" : "NW Northrup & 21st", + "stopCode" : "10777", + "stopId" : "prt:10777", + "stopIndex" : 91, + "stopSequence" : 92, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T19:07:55.000+00:00", + "departure" : "2009-11-17T19:07:55.000+00:00", + "lat" : 45.531308, + "lon" : -122.696445, + "name" : "NW Northrup & 22nd", + "stopCode" : "10778", + "stopId" : "prt:10778", + "stopIndex" : 92, + "stopSequence" : 93, "vertexType" : "TRANSIT", "zoneId" : "1" } ], "legGeometry" : { - "length" : 22, - "points" : "khztGbn{kVAPkAh@o@?sCB{BD??S?mCDmCDyBB??U?mCDmCDyBB??S?oCDmCDmCBo@@" + "length" : 109, + "points" : "yz{tG`zskV?tBCfD???^?nE?V@Z?PH\\Nb@`@~@Rf@??`@bANb@FV@R?P?pE?jA@h@AnAbBl@LFJN\\f@LT??NXJPPVJFf@Vf@Pp@Nd@NRLB@RNXZR\\vAhC@BhAhD`AhClAbDBrDCnG@n@@^@d@HdAP`CBjEDvD???LqCFmCDYBGDEBGJkAzAQR??KNa@b@MJuBBY?OHW@u@~@aD`EcBhBBrD@xC??@l@BlE@lD???XBjEBpD???VBlE?dA@t@?b@?h@BfEBrD???VBhEFtKDvJ??@\\DnJ???d@FtKmCBo@@" }, "mode" : "BUS", "pathway" : false, "realTime" : false, - "route" : "Belmont/NW 23rd", - "routeId" : "prt:15", - "routeLongName" : "Belmont/NW 23rd", - "routeShortName" : "15", + "route" : "Broadway/Halsey", + "routeId" : "prt:77", + "routeLongName" : "Broadway/Halsey", + "routeShortName" : "77", "routeType" : 3, "serviceDate" : "2009-11-17", - "startTime" : "2009-11-17T19:17:51.000+00:00", + "startTime" : "2009-11-17T18:54:29.000+00:00", "steps" : [ ], "to" : { - "arrival" : "2009-11-17T19:22:04.000+00:00", - "departure" : "2009-11-17T19:22:04.000+00:00", + "arrival" : "2009-11-17T19:08:50.000+00:00", + "departure" : "2009-11-17T19:08:50.000+00:00", "lat" : 45.532159, "lon" : -122.698634, "name" : "NW 23rd & Overton", "stopCode" : "8981", "stopId" : "prt:8981", - "stopIndex" : 74, - "stopSequence" : 75, + "stopIndex" : 93, + "stopSequence" : 94, "vertexType" : "TRANSIT", "zoneId" : "1" }, "transitLeg" : true, - "tripBlockId" : "1550", - "tripId" : "prt:150W1430" + "tripBlockId" : "7702", + "tripId" : "prt:771W1180" }, { "agencyTimeZoneOffset" : -28800000, "arrivalDelay" : 0, "departureDelay" : 0, "distance" : 231.46, - "endTime" : "2009-11-17T19:25:05.000+00:00", + "endTime" : "2009-11-17T19:11:51.000+00:00", "from" : { - "arrival" : "2009-11-17T19:22:04.000+00:00", - "departure" : "2009-11-17T19:22:04.000+00:00", + "arrival" : "2009-11-17T19:08:50.000+00:00", + "departure" : "2009-11-17T19:08:50.000+00:00", "lat" : 45.532159, "lon" : -122.698634, "name" : "NW 23rd & Overton", @@ -5274,7 +5422,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "realTime" : false, "rentedBike" : false, "route" : "", - "startTime" : "2009-11-17T19:22:04.000+00:00", + "startTime" : "2009-11-17T19:08:50.000+00:00", "steps" : [ { "absoluteDirection" : "SOUTH", @@ -5304,7 +5452,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } ], "to" : { - "arrival" : "2009-11-17T19:25:05.000+00:00", + "arrival" : "2009-11-17T19:11:51.000+00:00", "lat" : 45.531, "lon" : -122.70029, "name" : "NW Northrup St. & NW 24th Ave. (P3)", @@ -5314,14 +5462,14 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "walkingBike" : false } ], - "startTime" : "2009-11-17T18:58:47.000+00:00", + "startTime" : "2009-11-17T18:45:44.000+00:00", "tooSloped" : false, "transfers" : 1, - "transitTime" : 1017, - "waitingTime" : 307, - "walkDistance" : 318.48, + "transitTime" : 1162, + "waitingTime" : 208, + "walkDistance" : 252.2, "walkLimitExceeded" : false, - "walkTime" : 254 + "walkTime" : 197 } ] ] diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/AdditionalSearchDaysTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/AdditionalSearchDaysTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/AdditionalSearchDaysTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/AdditionalSearchDaysTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/FilterTransitWhenDirectModeIsEmptyTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/FilterTransitWhenDirectModeIsEmptyTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/FilterTransitWhenDirectModeIsEmptyTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/FilterTransitWhenDirectModeIsEmptyTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressPenaltyDecoratorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressPenaltyDecoratorTest.java similarity index 98% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressPenaltyDecoratorTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressPenaltyDecoratorTest.java index 78b12a97b82..a1b58ce76fa 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressPenaltyDecoratorTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressPenaltyDecoratorTest.java @@ -10,7 +10,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.routing.algorithm.raptoradapter.transit.DefaultAccessEgress; import org.opentripplanner.routing.algorithm.raptoradapter.transit.RoutingAccessEgress; import org.opentripplanner.routing.api.request.StreetMode; @@ -19,6 +18,7 @@ import org.opentripplanner.routing.api.request.framework.TimePenalty; import org.opentripplanner.street.search.state.State; import org.opentripplanner.street.search.state.TestStateBuilder; +import org.opentripplanner.utils.time.DurationUtils; class AccessEgressPenaltyDecoratorTest { diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressRouterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressRouterTest.java new file mode 100644 index 00000000000..9cd2b6b913e --- /dev/null +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressRouterTest.java @@ -0,0 +1,273 @@ +package org.opentripplanner.routing.algorithm.raptoradapter.router.street; + +import static com.google.common.truth.Truth.assertThat; + +import java.time.Duration; +import java.util.Collection; +import java.util.Set; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.opentripplanner.framework.geometry.WgsCoordinate; +import org.opentripplanner.model.GenericLocation; +import org.opentripplanner.routing.algorithm.GraphRoutingTest; +import org.opentripplanner.routing.api.request.RouteRequest; +import org.opentripplanner.routing.api.request.StreetMode; +import org.opentripplanner.routing.api.request.request.StreetRequest; +import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.routing.graphfinder.NearbyStop; +import org.opentripplanner.street.model.vertex.TransitStopVertex; +import org.opentripplanner.street.search.TemporaryVerticesContainer; +import org.opentripplanner.street.search.state.State; +import org.opentripplanner.transit.model.framework.FeedScopedId; + +class AccessEgressRouterTest extends GraphRoutingTest { + + private Graph graph; + + private TransitStopVertex stopForCentroidRoutingStation; + private TransitStopVertex stopForNoCentroidRoutingStation; + + private static final WgsCoordinate origin = new WgsCoordinate(0.0, 0.0); + private static final WgsCoordinate farAwayCoordinate = origin.moveEastMeters(100000); + + @BeforeEach + protected void setUp() throws Exception { + var otpModel = modelOf( + new GraphRoutingTest.Builder() { + @Override + public void build() { + var A = intersection("A", origin); + var B = intersection("B", origin.moveEastMeters(100)); + var C = intersection("C", origin.moveEastMeters(200)); + var D = intersection("D", origin.moveEastMeters(300)); + var farAway = intersection("FarAway", farAwayCoordinate); + + biStreet(A, B, 100); + biStreet(B, C, 100); + biStreet(C, D, 100); + biStreet(farAway, A, 1000000); + + var centroidRoutingStation = stationEntity( + "CentroidRoutingStation", + b -> b.withCoordinate(A.toWgsCoordinate()).withShouldRouteToCentroid(true) + ); + var centroidRoutingStationVertex = stationCentroid(centroidRoutingStation); + + var noCentroidRoutingStation = stationEntity( + "NoCentroidRoutingStation", + b -> b.withCoordinate(D.toWgsCoordinate()) + ); + var noCentroidRoutingStationVertex = stationCentroid(noCentroidRoutingStation); + + // StopForCentroidRoutingStation is a child of centroidRoutingStation + stopForCentroidRoutingStation = + stop("StopForCentroidRoutingStation", B.toWgsCoordinate(), centroidRoutingStation); + + // StopForNoCentroidRoutingStation is a child of noCentroidRoutingStation + stopForNoCentroidRoutingStation = + stop("StopForNoCentroidRoutingStation", C.toWgsCoordinate(), noCentroidRoutingStation); + + biLink(A, centroidRoutingStationVertex); + biLink(B, stopForCentroidRoutingStation); + biLink(C, stopForNoCentroidRoutingStation); + biLink(D, noCentroidRoutingStationVertex); + } + } + ); + graph = otpModel.graph(); + } + + @Test + void findAccessEgressFromStop() { + var accesses = findAccessEgressFromTo( + location("StopForCentroidRoutingStation"), + location(farAwayCoordinate), + AccessEgressType.ACCESS + ); + assertAcessEgresses( + Set.of( + "direct[StopForCentroidRoutingStation]", + "street[StopForCentroidRoutingStation -> StopForNoCentroidRoutingStation]" + ), + accesses + ); + + var egresses = findAccessEgressFromTo( + location(farAwayCoordinate), + location("StopForCentroidRoutingStation"), + AccessEgressType.EGRESS + ); + assertAcessEgresses( + Set.of( + "direct[StopForCentroidRoutingStation]", + "street[StopForCentroidRoutingStation -> StopForNoCentroidRoutingStation]" + ), + egresses + ); + } + + @Test + void findAccessEgressStation() { + // For stations with centroid routing we should use the station centroid as source for the street search + var accesses = findAccessEgressFromTo( + location("CentroidRoutingStation"), + location(farAwayCoordinate), + AccessEgressType.ACCESS + ); + assertAcessEgresses( + Set.of( + "direct[StopForCentroidRoutingStation]", + "street[CentroidRoutingStation -> StopForNoCentroidRoutingStation]" + ), + accesses + ); + + var egresses = findAccessEgressFromTo( + location(farAwayCoordinate), + location("CentroidRoutingStation"), + AccessEgressType.EGRESS + ); + assertAcessEgresses( + Set.of( + "direct[StopForCentroidRoutingStation]", + "street[CentroidRoutingStation -> StopForNoCentroidRoutingStation]" + ), + egresses + ); + } + + @Test + void findAccessEgressStationNoCentroidRouting() { + // For stations without centroid routing we should use the quay as source for the street search + var accesses = findAccessEgressFromTo( + location("NoCentroidRoutingStation"), + location(farAwayCoordinate), + AccessEgressType.ACCESS + ); + assertAcessEgresses( + Set.of( + "direct[StopForNoCentroidRoutingStation]", + "street[StopForNoCentroidRoutingStation -> StopForCentroidRoutingStation]" + ), + accesses + ); + + var egresses = findAccessEgressFromTo( + location(farAwayCoordinate), + location("NoCentroidRoutingStation"), + AccessEgressType.EGRESS + ); + assertAcessEgresses( + Set.of( + "direct[StopForNoCentroidRoutingStation]", + "street[StopForNoCentroidRoutingStation -> StopForCentroidRoutingStation]" + ), + egresses + ); + } + + @Test + void findAccessEgressFromCoordinate() { + var coordinate = origin.moveEastMeters(5); + + // We should get street access from coordinate to quay1 and quay2 + var accesses = findAccessEgressFromTo( + location(coordinate), + location(farAwayCoordinate), + AccessEgressType.ACCESS + ); + assertAcessEgresses( + Set.of( + "street[Origin -> StopForCentroidRoutingStation]", + "street[Origin -> StopForNoCentroidRoutingStation]" + ), + accesses + ); + + // We should get street access from coordinate to quay1 and quay2 + var egresses = findAccessEgressFromTo( + location(farAwayCoordinate), + location(coordinate), + AccessEgressType.EGRESS + ); + assertAcessEgresses( + Set.of( + "street[Destination -> StopForCentroidRoutingStation]", + "street[Destination -> StopForNoCentroidRoutingStation]" + ), + egresses + ); + } + + /* Helper methods */ + + private GenericLocation location(WgsCoordinate coordinate) { + return new GenericLocation(coordinate.latitude(), coordinate.longitude()); + } + + private GenericLocation location(FeedScopedId id) { + return new GenericLocation(null, id, null, null); + } + + private GenericLocation location(String id) { + return location(new FeedScopedId("F", id)); + } + + private RouteRequest requestFromTo(GenericLocation from, GenericLocation to) { + var routeRequest = new RouteRequest(); + routeRequest.setFrom(from); + routeRequest.setTo(to); + return routeRequest; + } + + private String nearbyStopDescription(NearbyStop nearbyStop) { + if (nearbyStop.edges.isEmpty()) { + return "direct[" + nearbyStop.stop.getName() + "]"; + } else { + return "street[" + stateDescription(nearbyStop.state) + "]"; + } + } + + private String stateDescription(State state) { + var last = state; + while (last.getBackState() != null) { + last = last.getBackState(); + } + return last.getVertex().getName() + " -> " + state.getVertex().getName(); + } + + private void assertAcessEgresses(Set expected, Collection actual) { + assertThat(actual.stream().map(this::nearbyStopDescription)) + .containsExactlyElementsIn(expected); + } + + private Collection findAccessEgressFromTo( + GenericLocation from, + GenericLocation to, + AccessEgressType accessEgress + ) { + var maxStopCount = 10; + var durationLimit = Duration.ofMinutes(10); + var request = requestFromTo(from, to); + + try ( + var verticesContainer = new TemporaryVerticesContainer( + graph, + from, + to, + StreetMode.WALK, + StreetMode.WALK + ) + ) { + return AccessEgressRouter.findAccessEgresses( + request, + verticesContainer, + new StreetRequest(), + null, + accessEgress, + durationLimit, + maxStopCount + ); + } + } +} diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressTypeTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressTypeTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressTypeTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressTypeTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressesTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressesTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressesTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressesTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgressTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgressTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgressTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgressTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransferTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransferTest.java similarity index 97% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransferTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransferTest.java index dacd0dcac9c..8dc4d548c18 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransferTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransferTest.java @@ -9,8 +9,8 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.opentripplanner._support.geometry.Coordinates; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.raptor.api.model.RaptorTransfer; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; import org.opentripplanner.street.model._data.StreetModelForTest; import org.opentripplanner.street.model.vertex.IntersectionVertex; import org.opentripplanner.street.search.request.StreetSearchRequest; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayerTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayerTest.java similarity index 94% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayerTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayerTest.java index 58a56ccb96f..db41d9b5768 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayerTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayerTest.java @@ -10,7 +10,7 @@ import java.util.Map; import org.junit.jupiter.api.Test; import org.opentripplanner.model.StopTime; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.network.RoutingTripPattern; import org.opentripplanner.transit.model.network.StopPattern; @@ -20,7 +20,7 @@ class TransitLayerTest { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final TripTimes TRIP_TIMES; private static final RoutingTripPattern TRIP_PATTERN; @@ -30,17 +30,17 @@ class TransitLayerTest { var stopTime = new StopTime(); stopTime.setStop(stop); var stopPattern = new StopPattern(List.of(stopTime)); - var route = TransitModelForTest.route("1").build(); + var route = TimetableRepositoryForTest.route("1").build(); TRIP_PATTERN = TripPattern - .of(TransitModelForTest.id("P1")) + .of(TimetableRepositoryForTest.id("P1")) .withRoute(route) .withStopPattern(stopPattern) .build() .getRoutingTripPattern(); TRIP_TIMES = TripTimesFactory.tripTimes( - TransitModelForTest.trip("1").withRoute(route).build(), + TimetableRepositoryForTest.trip("1").withRoute(route).build(), List.of(new StopTime()), new Deduplicator() ); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDateTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDateTest.java similarity index 86% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDateTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDateTest.java index dd9a2fffa66..c7f76fc3377 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDateTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TripPatternForDateTest.java @@ -11,7 +11,7 @@ import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.model.Frequency; import org.opentripplanner.model.StopTime; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.RoutingTripPattern; @@ -24,11 +24,11 @@ class TripPatternForDateTest { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final RegularStop STOP = TEST_MODEL.stop("TEST:STOP", 0, 0).build(); - private static final Route ROUTE = TransitModelForTest.route("1").build(); + private static final Route ROUTE = TimetableRepositoryForTest.route("1").build(); private static final TripTimes tripTimes = TripTimesFactory.tripTimes( - TransitModelForTest.trip("1").withRoute(ROUTE).build(), + TimetableRepositoryForTest.trip("1").withRoute(ROUTE).build(), List.of(new StopTime()), new Deduplicator() ); @@ -46,7 +46,7 @@ void shouldExcludeAndIncludeBasedOnFrequency(List freqs) { stopTime.setStop(STOP); StopPattern stopPattern = new StopPattern(List.of(stopTime)); RoutingTripPattern tripPattern = TripPattern - .of(TransitModelForTest.id("P1")) + .of(TimetableRepositoryForTest.id("P1")) .withRoute(ROUTE) .withStopPattern(stopPattern) .build() diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchTest.java similarity index 99% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchTest.java index 214ea55eb3c..80ec5de7ed4 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/ConstrainedBoardingSearchTest.java @@ -26,7 +26,7 @@ import org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripSchedule; import org.opentripplanner.routing.algorithm.raptoradapter.transit.request.TestRouteData; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.RoutingTripPattern; @@ -35,7 +35,7 @@ public class ConstrainedBoardingSearchTest { - private static final FeedScopedId ID = TransitModelForTest.id("ID"); + private static final FeedScopedId ID = TimetableRepositoryForTest.id("ID"); private static final TransferConstraint GUARANTEED_CONSTRAINT = TransferConstraint .of() .guaranteed() diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculatorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculatorTest.java similarity index 96% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculatorTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculatorTest.java index 3570d92bdbe..ad31b250046 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculatorTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculatorTest.java @@ -3,8 +3,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import org.opentripplanner.raptor._data.transit.TestAccessEgress; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; +import org.opentripplanner.raptorlegacy._data.transit.TestAccessEgress; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; public class DefaultCostCalculatorTest { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/PatternCostCalculatorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/PatternCostCalculatorTest.java similarity index 93% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/PatternCostCalculatorTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/PatternCostCalculatorTest.java index fb2a9bf04d0..1cf9a324de5 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/PatternCostCalculatorTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/PatternCostCalculatorTest.java @@ -3,9 +3,9 @@ import static graphql.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.opentripplanner.raptor._data.transit.TestRoute.route; -import static org.opentripplanner.transit.model._data.TransitModelForTest.agency; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.raptorlegacy._data.transit.TestRoute.route; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.agency; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.time.Duration; import java.util.List; @@ -16,16 +16,16 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.framework.model.Cost; -import org.opentripplanner.raptor._data.transit.TestTransitData; -import org.opentripplanner.raptor._data.transit.TestTripPattern; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; import org.opentripplanner.raptor.spi.RaptorCostCalculator; +import org.opentripplanner.raptorlegacy._data.transit.TestTransitData; +import org.opentripplanner.raptorlegacy._data.transit.TestTripPattern; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; import org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers.GeneralizedCostParametersMapper; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.test.support.TestTableParser; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.RouteBuilder; import org.opentripplanner.transit.model.organization.Agency; @@ -212,7 +212,7 @@ RouteRequest createRouteRequest() { } private static TestTripPattern pattern(boolean unpreferredRoute, boolean unpreferredAgency) { - RouteBuilder builder = TransitModelForTest.route( + RouteBuilder builder = TimetableRepositoryForTest.route( unpreferredRoute ? UNPREFERRED_ROUTE_ID : DEFAULT_ROUTE_ID ); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostLinearFunctionTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostLinearFunctionTest.java similarity index 97% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostLinearFunctionTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostLinearFunctionTest.java index 2769a95b634..b38cefe232c 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostLinearFunctionTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostLinearFunctionTest.java @@ -11,6 +11,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.framework.model.Cost; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.test.support.TestTableParser; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculatorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculatorTest.java similarity index 94% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculatorTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculatorTest.java index b7d3f255a9d..76de708c817 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculatorTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/WheelchairCostCalculatorTest.java @@ -6,9 +6,10 @@ 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.transit.TestTripSchedule; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; import org.opentripplanner.raptor.spi.RaptorCostCalculator; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; import org.opentripplanner.routing.api.request.preference.AccessibilityPreferences; import org.opentripplanner.transit.model.basic.Accessibility; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/GeneralizedCostParametersMapperTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/GeneralizedCostParametersMapperTest.java similarity index 83% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/GeneralizedCostParametersMapperTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/GeneralizedCostParametersMapperTest.java index 35aa9e1d7a2..2620dd506bc 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/GeneralizedCostParametersMapperTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/GeneralizedCostParametersMapperTest.java @@ -1,18 +1,18 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.transit.model._data.TransitModelForTest.agency; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; -import static org.opentripplanner.transit.model._data.TransitModelForTest.route; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.agency; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.route; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import java.util.BitSet; import java.util.List; import org.junit.jupiter.api.Test; -import org.opentripplanner.raptor._data.transit.TestRoute; -import org.opentripplanner.raptor._data.transit.TestTransitData; -import org.opentripplanner.raptor._data.transit.TestTripPattern; +import org.opentripplanner.raptorlegacy._data.transit.TestRoute; +import org.opentripplanner.raptorlegacy._data.transit.TestTransitData; +import org.opentripplanner.raptorlegacy._data.transit.TestTripPattern; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.transit.model.framework.FeedScopedId; diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/LookupStopIndexCallbackTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/LookupStopIndexCallbackTest.java new file mode 100644 index 00000000000..fb39db51cd5 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/LookupStopIndexCallbackTest.java @@ -0,0 +1,53 @@ +package org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.opentripplanner.transit.model.framework.EntityNotFoundException; +import org.opentripplanner.transit.model.framework.FeedScopedId; + +class LookupStopIndexCallbackTest { + + private static final FeedScopedId ID_1 = FeedScopedId.ofNullable("F", "1"); + private static final FeedScopedId ID_2 = FeedScopedId.ofNullable("F", "2"); + private static final FeedScopedId ID_3 = FeedScopedId.ofNullable("F", "3"); + + private final LookupStopIndexCallback subject = new TestLookupStopIndexCallback( + Map.of(ID_1, new int[] { 1, 7, 13 }, ID_2, new int[] { 2, 7, 15 }) + ); + + /** + * This mostly verifies that the test is set up correctly, the code tested is the dummy inside + * the test. + */ + void lookupStopLocationIndexesSingleIdInput() { + assertArrayEquals(new int[] { 1, 7, 13 }, subject.lookupStopLocationIndexes(ID_1).toArray()); + var ex = Assertions.assertThrows( + EntityNotFoundException.class, + () -> subject.lookupStopLocationIndexes(ID_3).toArray() + ); + assertEquals("StopLocation does not exist for id F:3", ex.getMessage()); + } + + @Test + void lookupStopLocationIndexesCollectionInput() { + assertArrayEquals(new int[] {}, subject.lookupStopLocationIndexes(List.of())); + assertArrayEquals(new int[] { 1, 7, 13 }, subject.lookupStopLocationIndexes(List.of(ID_1))); + assertArrayEquals( + new int[] { 1, 2, 7, 13, 15 }, + subject.lookupStopLocationIndexes(List.of(ID_1, ID_2)) + ); + + // Should throw exception? + var ex = assertThrows( + EntityNotFoundException.class, + () -> subject.lookupStopLocationIndexes(List.of(ID_1, ID_3)) + ); + assertEquals("StopLocation entity not found: F:3", ex.getMessage()); + } +} diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapperTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapperTest.java new file mode 100644 index 00000000000..9424a6b2d13 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapperTest.java @@ -0,0 +1,306 @@ +package org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers; + +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.routing.algorithm.raptoradapter.transit.mappers.RaptorRequestMapperTest.RequestFeature.RELAX_COST_DEST; +import static org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers.RaptorRequestMapperTest.RequestFeature.TRANSIT_GROUP_PRIORITY; +import static org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers.RaptorRequestMapperTest.RequestFeature.VIA_PASS_THROUGH; +import static org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers.RaptorRequestMapperTest.RequestFeature.VIA_VISIT; + +import java.time.Duration; +import java.time.ZonedDateTime; +import java.util.List; +import java.util.Map; +import java.util.stream.IntStream; +import javax.annotation.Nullable; +import org.junit.jupiter.api.Assertions; +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.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.request.RaptorRequest; +import org.opentripplanner.raptorlegacy._data.transit.TestAccessEgress; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; +import org.opentripplanner.routing.api.request.RouteRequest; +import org.opentripplanner.routing.api.request.framework.CostLinearFunction; +import org.opentripplanner.routing.api.request.via.PassThroughViaLocation; +import org.opentripplanner.routing.api.request.via.VisitViaLocation; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.utils.collection.ListUtils; + +class RaptorRequestMapperTest { + + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); + private static final StopLocation STOP_A = TEST_MODEL.stop("Stop:A").build(); + public static final PassThroughViaLocation PASS_THROUGH_VIA_LOCATION = new PassThroughViaLocation( + "Via A", + List.of(STOP_A.getId()) + ); + public static final VisitViaLocation VISIT_VIA_LOCATION = new VisitViaLocation( + "Via A", + null, + List.of(STOP_A.getId()), + List.of() + ); + private static final List ACCESS = List.of(TestAccessEgress.walk(12, 45)); + private static final List EGRESS = List.of(TestAccessEgress.walk(144, 54)); + + private static final CostLinearFunction R1 = CostLinearFunction.of("50 + 1.0x"); + private static final CostLinearFunction R2 = CostLinearFunction.of("0 + 1.5x"); + private static final CostLinearFunction R3 = CostLinearFunction.of("30 + 2.0x"); + + private static final Map STOPS_MAP = Map.of(STOP_A.getId(), STOP_A); + private static final CostLinearFunction RELAX_TRANSIT_GROUP_PRIORITY = CostLinearFunction.of( + "30m + 1.2t" + ); + public static final double RELAX_GENERALIZED_COST_AT_DESTINATION = 2.0; + + static List testCasesRelaxedCost() { + return List.of( + Arguments.of(CostLinearFunction.NORMAL, 0, 0), + Arguments.of(CostLinearFunction.NORMAL, 10, 10), + Arguments.of(R1, 0, 5000), + Arguments.of(R1, 7, 5007), + Arguments.of(R2, 0, 0), + Arguments.of(R2, 100, 150), + Arguments.of(R3, 0, 3000), + Arguments.of(R3, 100, 3200) + ); + } + + @ParameterizedTest + @MethodSource("testCasesRelaxedCost") + void mapRelaxCost(CostLinearFunction input, int cost, int expected) { + var calcCost = RaptorRequestMapper.mapRelaxCost(input); + assertEquals(expected, calcCost.relax(cost)); + } + + @Test + void testViaLocation() { + var req = new RouteRequest(); + var minWaitTime = Duration.ofMinutes(13); + + req.setViaLocations( + List.of(new VisitViaLocation("Via A", minWaitTime, List.of(STOP_A.getId()), List.of())) + ); + + var result = map(req); + + assertTrue(result.searchParams().hasViaLocations()); + assertEquals( + "[Via{label: Via A, minWaitTime: 13m, connections: [0 13m]}]", + result.searchParams().viaLocations().toString() + ); + } + + @Test + void testPassThroughPoints() { + var req = new RouteRequest(); + + req.setViaLocations(List.of(new PassThroughViaLocation("Via A", List.of(STOP_A.getId())))); + + var result = map(req); + + assertTrue(result.multiCriteria().hasPassThroughPoints()); + assertEquals( + "[(Via A, stops: " + STOP_A.getIndex() + ")]", + result.multiCriteria().passThroughPoints().toString() + ); + } + + @Test + void testTransitGroupPriority() { + var req = new RouteRequest(); + + // Set relax transit-group-priority + req.withPreferences(p -> + p.withTransit(t -> t.withRelaxTransitGroupPriority(CostLinearFunction.of("30m + 1.2t"))) + ); + + var result = map(req); + + assertTrue(result.multiCriteria().transitPriorityCalculator().isPresent()); + } + + static List testViaAndTransitGroupPriorityCombinationsTestCases() { + return List.of( + // If ONE feature is requested, the same feature is expected + Arguments.of( + "VIA_PASS_THROUGH only", + List.of(VIA_PASS_THROUGH), + List.of(VIA_PASS_THROUGH), + null + ), + Arguments.of("VIA_VISIT only", List.of(VIA_VISIT), List.of(VIA_VISIT), null), + Arguments.of( + "TRANSIT_GROUP_PRIORITY only", + List.of(TRANSIT_GROUP_PRIORITY), + List.of(TRANSIT_GROUP_PRIORITY), + null + ), + Arguments.of( + "RELAX_COST_DEST only", + List.of(RELAX_COST_DEST), + List.of(RELAX_COST_DEST), + null + ), + Arguments.of( + "VIA_VISIT is not allowed together VIA_PASS_THROUGH, an error is expected.", + List.of(VIA_VISIT, VIA_PASS_THROUGH), + List.of(), + "A mix of via-locations and pass-through is not allowed in this version." + ), + Arguments.of( + """ + VIA_VISIT is not allowed together VIA_PASS_THROUGH, an error is expected. + Other features are ignored. + """, + List.of(VIA_VISIT, VIA_PASS_THROUGH, TRANSIT_GROUP_PRIORITY, RELAX_COST_DEST), + List.of(), + "A mix of via-locations and pass-through is not allowed in this version." + ), + Arguments.of( + "VIA_PASS_THROUGH cannot be combined with other features, and other features are dropped", + List.of(VIA_PASS_THROUGH, TRANSIT_GROUP_PRIORITY, RELAX_COST_DEST), + List.of(VIA_PASS_THROUGH), + null + ), + Arguments.of( + "VIA_VISIT can be combined with TRANSIT_GROUP_PRIORITY", + List.of(VIA_VISIT, TRANSIT_GROUP_PRIORITY), + List.of(VIA_VISIT, TRANSIT_GROUP_PRIORITY), + null + ), + Arguments.of( + """ + VIA_VISIT can only be combined with TRANSIT_GROUP_PRIORITY, and other features are dropped + VIA_PASS_THROUGH override VIA_VISIT (see above) + """, + List.of(VIA_VISIT, TRANSIT_GROUP_PRIORITY, RELAX_COST_DEST), + List.of(VIA_VISIT, TRANSIT_GROUP_PRIORITY), + null + ), + Arguments.of( + """ + TRANSIT_GROUP_PRIORITY cannot be combined with other features, override RELAX_COST_DEST + VIA_PASS_THROUGH and VIA_VISIT override VIA_VISIT (see above) + """, + List.of(TRANSIT_GROUP_PRIORITY, RELAX_COST_DEST), + List.of(TRANSIT_GROUP_PRIORITY), + null + ) + ); + } + + @ParameterizedTest(name = "{0}. {1} => {2}") + @MethodSource("testViaAndTransitGroupPriorityCombinationsTestCases") + void testViaAndTransitGroupPriorityCombinations( + String testDescription, + List requestedFeatures, + List expectedFeatures, + @Nullable String errorMessage + ) { + var req = new RouteRequest(); + + for (RequestFeature it : requestedFeatures) { + req = setFeaturesOnRequest(req, it); + } + + if (errorMessage == null) { + var result = map(req); + + for (var feature : RequestFeature.values()) { + assertFeatureSet(feature, result, expectedFeatures.contains(feature)); + } + } else { + var r = req; + var ex = Assertions.assertThrows(IllegalArgumentException.class, () -> map(r)); + assertEquals(errorMessage, ex.getMessage()); + } + } + + private static RaptorRequest map(RouteRequest request) { + return RaptorRequestMapper.mapRequest( + request, + ZonedDateTime.now(), + false, + ACCESS, + EGRESS, + null, + id -> IntStream.of(STOPS_MAP.get(id).getIndex()) + ); + } + + private static void assertFeatureSet( + RequestFeature feature, + RaptorRequest result, + boolean expected + ) { + switch (feature) { + case VIA_VISIT: + if (expected) { + assertTrue(result.searchParams().hasViaLocations()); + // One via location exist(no NPE), but it does not allow pass-through + assertEquals( + "Via{label: Via A, connections: [0]}", + result.searchParams().viaLocations().get(0).toString() + ); + } + break; + case VIA_PASS_THROUGH: + if (expected) { + assertTrue(result.multiCriteria().hasPassThroughPoints()); + assertEquals( + "(Via A, stops: 0)", + result.multiCriteria().passThroughPoints().get(0).toString() + ); + } + break; + case TRANSIT_GROUP_PRIORITY: + assertEquals(expected, result.multiCriteria().transitPriorityCalculator().isPresent()); + if (expected) { + assertFalse(result.multiCriteria().hasPassThroughPoints()); + } + break; + case RELAX_COST_DEST: + assertEquals(expected, result.multiCriteria().relaxCostAtDestination() != null); + if (expected) { + assertFalse(result.multiCriteria().hasPassThroughPoints()); + assertFalse(result.searchParams().hasViaLocations()); + } + break; + } + } + + private static RouteRequest setFeaturesOnRequest(RouteRequest req, RequestFeature feature) { + return switch (feature) { + case VIA_VISIT -> req.setViaLocations( + ListUtils.combine(req.getViaLocations(), List.of(VISIT_VIA_LOCATION)) + ); + case VIA_PASS_THROUGH -> req.setViaLocations( + ListUtils.combine(req.getViaLocations(), List.of(PASS_THROUGH_VIA_LOCATION)) + ); + case TRANSIT_GROUP_PRIORITY -> req.withPreferences(p -> + p.withTransit(t -> t.withRelaxTransitGroupPriority(RELAX_TRANSIT_GROUP_PRIORITY)) + ); + case RELAX_COST_DEST -> req.withPreferences(p -> + p.withTransit(t -> + t.withRaptor(r -> + r.withRelaxGeneralizedCostAtDestination(RELAX_GENERALIZED_COST_AT_DESTINATION) + ) + ) + ); + }; + } + + enum RequestFeature { + VIA_VISIT, + VIA_PASS_THROUGH, + TRANSIT_GROUP_PRIORITY, + RELAX_COST_DEST, + } +} diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TestLookupStopIndexCallback.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TestLookupStopIndexCallback.java new file mode 100644 index 00000000000..f1898d69f52 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TestLookupStopIndexCallback.java @@ -0,0 +1,25 @@ +package org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers; + +import java.util.Map; +import java.util.stream.IntStream; +import org.opentripplanner.transit.model.framework.EntityNotFoundException; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.site.StopLocation; + +public class TestLookupStopIndexCallback implements LookupStopIndexCallback { + + private final Map index; + + public TestLookupStopIndexCallback(Map index) { + this.index = index; + } + + @Override + public IntStream lookupStopLocationIndexes(FeedScopedId stopLocationId) { + int[] values = index.get(stopLocationId); + if (values == null) { + throw new EntityNotFoundException(StopLocation.class, stopLocationId); + } + return IntStream.of(values); + } +} diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapperTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapperTest.java similarity index 88% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapperTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapperTest.java index 9296ee2730c..b7e441e4bf2 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapperTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapperTest.java @@ -6,16 +6,16 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitTuningParameters; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.site.StopTransferPriority; -import org.opentripplanner.transit.service.StopModelMock; +import org.opentripplanner.transit.service.SiteRepositoryMock; class TransitLayerMapperTest { - private final TransitModelForTest testModel = TransitModelForTest.of(); + private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of(); private final Station STATION_A = testModel .station("A") @@ -44,7 +44,7 @@ class TransitLayerMapperTest { @Test public void createStopBoardAlightTransferCosts() { int[] result = TransitLayerMapper.createStopBoardAlightTransferCosts( - new StopModelMock(STOPS), + new SiteRepositoryMock(STOPS), TransitTuningParameters.FOR_TEST ); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapperTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapperTest.java similarity index 89% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapperTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapperTest.java index 020dc6305a4..9985c3e559f 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapperTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapperTest.java @@ -10,20 +10,18 @@ import java.time.LocalDate; import java.util.HashMap; import java.util.Map; -import javax.annotation.Nonnull; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.opentripplanner.model.Timetable; -import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripPatternForDate; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.model.timetable.TripTimesFactory; public class TripPatternForDateMapperTest { - private static TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final LocalDate SERVICE_DATE = LocalDate.of(2009, 8, 7); private static final int SERVICE_CODE = 555; @@ -36,15 +34,14 @@ public class TripPatternForDateMapperTest { @BeforeAll public static void setUp() throws Exception { var pattern = TEST_MODEL.pattern(BUS).build(); - timetable = new Timetable(pattern); - var trip = TransitModelForTest.trip("1").build(); + var trip = TimetableRepositoryForTest.trip("1").build(); var tripTimes = TripTimesFactory.tripTimes( trip, - TEST_MODEL.stopTimesEvery5Minutes(5, trip, PlanTestConstants.T11_00), + TEST_MODEL.stopTimesEvery5Minutes(5, trip, "11:00"), new Deduplicator() ); tripTimes.setServiceCode(SERVICE_CODE); - timetable.addTripTimes(tripTimes); + timetable = Timetable.of().withTripPattern(pattern).addTripTimes(tripTimes).build(); } /** @@ -102,7 +99,6 @@ void testTimeTableWithServiceCodesRunningNotMatchingShouldReturnNull() { assertNull(mapper.map(timetable, SERVICE_DATE)); } - @Nonnull private static TIntHashSet tintHashSet(int... numbers) { var set = new TIntHashSet(); set.addAll(numbers); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreatorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreatorTest.java similarity index 92% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreatorTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreatorTest.java index ea815a2f47f..7df9677082d 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreatorTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreatorTest.java @@ -1,7 +1,7 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.request; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.time.LocalDate; import java.time.ZonedDateTime; @@ -10,10 +10,9 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner._support.time.ZoneIds; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.StopTime; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripPatternForDate; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.RoutingTripPattern; @@ -22,10 +21,11 @@ import org.opentripplanner.transit.model.network.grouppriority.TransitGroupPriorityService; import org.opentripplanner.transit.model.timetable.ScheduledTripTimes; import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.utils.time.ServiceDateUtils; public class RaptorRoutingRequestTransitDataCreatorTest { - private static TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); public static final FeedScopedId TP_ID_1 = id("1"); public static final FeedScopedId TP_ID_2 = id("2"); @@ -101,7 +101,7 @@ private static TripPatternForDates findTripPatternForDate( private TripTimes createTripTimesForTest() { return ScheduledTripTimes .of() - .withTrip(TransitModelForTest.trip("Test").build()) + .withTrip(TimetableRepositoryForTest.trip("Test").build()) .withDepartureTimes("00:00 02:00") .build(); } @@ -120,7 +120,7 @@ private static StopTime createStopTime() { private static RoutingTripPattern createTripPattern(FeedScopedId id) { return TripPattern .of(id) - .withRoute(TransitModelForTest.route("1").withMode(TransitMode.BUS).build()) + .withRoute(TimetableRepositoryForTest.route("1").withMode(TransitMode.BUS).build()) .withStopPattern(new StopPattern(List.of(createStopTime(), createStopTime()))) .build() .getRoutingTripPattern(); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RouteRequestTransitDataProviderFilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RouteRequestTransitDataProviderFilterTest.java similarity index 86% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RouteRequestTransitDataProviderFilterTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RouteRequestTransitDataProviderFilterTest.java index be6266ccdbe..ea4b7174e79 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RouteRequestTransitDataProviderFilterTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RouteRequestTransitDataProviderFilterTest.java @@ -1,5 +1,6 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.request; +import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -26,7 +27,7 @@ import org.opentripplanner.routing.api.request.request.filter.SelectRequest; import org.opentripplanner.routing.api.request.request.filter.TransitFilter; import org.opentripplanner.routing.api.request.request.filter.TransitFilterRequest; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.basic.MainAndSubMode; import org.opentripplanner.transit.model.basic.SubMode; @@ -34,6 +35,7 @@ import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.BikeAccess; +import org.opentripplanner.transit.model.network.CarAccess; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.RouteBuilder; import org.opentripplanner.transit.model.network.RoutingTripPattern; @@ -49,11 +51,11 @@ class RouteRequestTransitDataProviderFilterTest { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); - private static final Route ROUTE = TransitModelForTest.route("1").build(); + private static final Route ROUTE = TimetableRepositoryForTest.route("1").build(); - private static final FeedScopedId TRIP_ID = TransitModelForTest.id("T1"); + private static final FeedScopedId TRIP_ID = TimetableRepositoryForTest.id("T1"); private static final RegularStop STOP_FOR_TEST = TEST_MODEL.stop("TEST:STOP", 0, 0).build(); @@ -100,13 +102,14 @@ void testWheelchairAccess(Accessibility wheelchair, WheelchairPreferences access var stopPattern = new StopPattern(List.of(stopTimeStart, stopTimeEnd)); var tripPattern = TripPattern - .of(TransitModelForTest.id("P1")) - .withRoute(TransitModelForTest.route("1").build()) + .of(TimetableRepositoryForTest.id("P1")) + .withRoute(TimetableRepositoryForTest.route("1").build()) .withStopPattern(stopPattern) .build() .getRoutingTripPattern(); var filter = new RouteRequestTransitDataProviderFilter( + false, false, true, accessibility, @@ -150,13 +153,14 @@ void testRealtimeCancelledStops(boolean includeRealtimeCancellations) { var stopTime4 = getStopTime("TEST:4", PickDrop.SCHEDULED); var stopPattern = new StopPattern(List.of(stopTime1, stopTime2, stopTime3, stopTime4)); var tripPattern = TripPattern - .of(TransitModelForTest.id("P1")) - .withRoute(TransitModelForTest.route("1").build()) + .of(TimetableRepositoryForTest.id("P1")) + .withRoute(TimetableRepositoryForTest.route("1").build()) .withStopPattern(stopPattern) .build() .getRoutingTripPattern(); var filter = new RouteRequestTransitDataProviderFilter( + false, false, false, DEFAULT_ACCESSIBILITY, @@ -202,6 +206,7 @@ void notFilteringExpectedTripPatternForDateTest() { TripPatternForDate tripPatternForDate = createTestTripPatternForDate(); var filter = new RouteRequestTransitDataProviderFilter( + false, false, false, DEFAULT_ACCESSIBILITY, @@ -221,6 +226,7 @@ void bannedRouteFilteringTest() { TripPatternForDate tripPatternForDate = createTestTripPatternForDate(); var filter = new RouteRequestTransitDataProviderFilter( + false, false, false, DEFAULT_ACCESSIBILITY, @@ -246,6 +252,7 @@ void bannedTripFilteringTest() { TRIP_ID, ROUTE, BikeAccess.NOT_ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.BUS, null, Accessibility.NOT_POSSIBLE, @@ -253,6 +260,7 @@ void bannedTripFilteringTest() { ); var filter = new RouteRequestTransitDataProviderFilter( + false, false, false, DEFAULT_ACCESSIBILITY, @@ -281,6 +289,7 @@ void matchModeFilterAndBannedAgencyFilter() { ); var filter = new RouteRequestTransitDataProviderFilter( + false, false, false, DEFAULT_ACCESSIBILITY, @@ -294,7 +303,7 @@ void matchModeFilterAndBannedAgencyFilter() { SubMode.of(TransmodelTransportSubmode.UNKNOWN.getValue()) ) ), - List.of(TransitModelForTest.OTHER_AGENCY.getId()) + List.of(TimetableRepositoryForTest.OTHER_AGENCY.getId()) ) ); @@ -316,6 +325,7 @@ void matchCombinedModesAndBannedAgencyFilter() { ); var filter = new RouteRequestTransitDataProviderFilter( + false, false, false, DEFAULT_ACCESSIBILITY, @@ -329,7 +339,7 @@ void matchCombinedModesAndBannedAgencyFilter() { SubMode.of(TransmodelTransportSubmode.UNKNOWN.getValue()) ) ), - List.of(TransitModelForTest.OTHER_AGENCY.getId()) + List.of(TimetableRepositoryForTest.OTHER_AGENCY.getId()) ) ); @@ -347,6 +357,7 @@ void matchSelectedAgencyExcludedSubMode() { ); var filter = new RouteRequestTransitDataProviderFilter( + false, false, false, DEFAULT_ACCESSIBILITY, @@ -357,7 +368,10 @@ void matchSelectedAgencyExcludedSubMode() { TransitFilterRequest .of() .addSelect( - SelectRequest.of().withAgencies(List.of(TransitModelForTest.AGENCY.getId())).build() + SelectRequest + .of() + .withAgencies(List.of(TimetableRepositoryForTest.AGENCY.getId())) + .build() ) .addNot( SelectRequest @@ -386,6 +400,7 @@ void transitModeFilteringTest() { TRIP_ID, ROUTE, BikeAccess.NOT_ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.BUS, TransmodelTransportSubmode.LOCAL_BUS.getValue(), Accessibility.NOT_POSSIBLE, @@ -412,6 +427,7 @@ void notFilteringExpectedTripTimesTest() { TRIP_ID, ROUTE, BikeAccess.NOT_ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.BUS, null, Accessibility.NOT_POSSIBLE, @@ -419,6 +435,7 @@ void notFilteringExpectedTripTimesTest() { ); var filter = new RouteRequestTransitDataProviderFilter( + false, false, false, DEFAULT_ACCESSIBILITY, @@ -439,6 +456,36 @@ void bikesAllowedFilteringTest() { TRIP_ID, ROUTE, BikeAccess.NOT_ALLOWED, + CarAccess.NOT_ALLOWED, + TransitMode.BUS, + null, + Accessibility.NOT_POSSIBLE, + null + ); + + var filter = new RouteRequestTransitDataProviderFilter( + true, + false, + true, + WheelchairPreferences.DEFAULT, + false, + false, + Set.of(), + List.of(AllowAllTransitFilter.of()) + ); + + boolean valid = filter.tripTimesPredicate(tripTimes, true); + + assertFalse(valid); + } + + @Test + void carsAllowedFilteringTest() { + TripTimes tripTimes = createTestTripTimes( + TRIP_ID, + ROUTE, + BikeAccess.NOT_ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.BUS, null, Accessibility.NOT_POSSIBLE, @@ -446,6 +493,7 @@ void bikesAllowedFilteringTest() { ); var filter = new RouteRequestTransitDataProviderFilter( + false, true, true, WheelchairPreferences.DEFAULT, @@ -466,6 +514,7 @@ void removeInaccessibleTrip() { TRIP_ID, ROUTE, BikeAccess.NOT_ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.BUS, null, Accessibility.NOT_POSSIBLE, @@ -473,6 +522,7 @@ void removeInaccessibleTrip() { ); var filter = new RouteRequestTransitDataProviderFilter( + false, false, true, WheelchairPreferences.DEFAULT, @@ -493,6 +543,7 @@ void keepAccessibleTrip() { TRIP_ID, ROUTE, BikeAccess.NOT_ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.BUS, null, Accessibility.POSSIBLE, @@ -500,6 +551,7 @@ void keepAccessibleTrip() { ); var filter = new RouteRequestTransitDataProviderFilter( + false, false, true, WheelchairPreferences.DEFAULT, @@ -520,6 +572,7 @@ void keepRealTimeAccessibleTrip() { TRIP_ID, ROUTE, BikeAccess.NOT_ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.BUS, null, Accessibility.NOT_POSSIBLE, @@ -527,6 +580,7 @@ void keepRealTimeAccessibleTrip() { ); var filter = new RouteRequestTransitDataProviderFilter( + false, false, true, WheelchairPreferences.DEFAULT, @@ -549,6 +603,7 @@ void includePlannedCancellationsTest() { TRIP_ID, ROUTE, BikeAccess.NOT_ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.BUS, null, Accessibility.NOT_POSSIBLE, @@ -558,6 +613,7 @@ void includePlannedCancellationsTest() { TRIP_ID, ROUTE, BikeAccess.NOT_ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.BUS, null, Accessibility.NOT_POSSIBLE, @@ -566,6 +622,7 @@ void includePlannedCancellationsTest() { // Given var filter1 = new RouteRequestTransitDataProviderFilter( + false, false, false, WheelchairPreferences.DEFAULT, @@ -587,6 +644,7 @@ void includePlannedCancellationsTest() { // Given var filter2 = new RouteRequestTransitDataProviderFilter( + false, false, false, DEFAULT_ACCESSIBILITY, @@ -613,6 +671,7 @@ void includeRealtimeCancellationsTest() { TRIP_ID, ROUTE, BikeAccess.NOT_ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.BUS, null, Accessibility.NOT_POSSIBLE, @@ -623,6 +682,7 @@ void includeRealtimeCancellationsTest() { TRIP_ID, ROUTE, BikeAccess.NOT_ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.BUS, null, Accessibility.NOT_POSSIBLE, @@ -632,6 +692,7 @@ void includeRealtimeCancellationsTest() { // Given var filter1 = new RouteRequestTransitDataProviderFilter( + false, false, false, WheelchairPreferences.DEFAULT, @@ -653,6 +714,7 @@ void includeRealtimeCancellationsTest() { // Given var filter2 = new RouteRequestTransitDataProviderFilter( + false, false, false, DEFAULT_ACCESSIBILITY, @@ -675,8 +737,8 @@ void includeRealtimeCancellationsTest() { @Test void testBikesAllowed() { - RouteBuilder routeBuilder = TransitModelForTest.route("1"); - TripBuilder trip = Trip.of(TransitModelForTest.id("T1")).withRoute(routeBuilder.build()); + RouteBuilder routeBuilder = TimetableRepositoryForTest.route("1"); + TripBuilder trip = Trip.of(TimetableRepositoryForTest.id("T1")).withRoute(routeBuilder.build()); assertEquals( BikeAccess.UNKNOWN, @@ -709,12 +771,64 @@ void testBikesAllowed() { ); } + @Test + void testCarsAllowed() { + TripTimes tripTimesCarsAllowed = createTestTripTimes( + TRIP_ID, + ROUTE, + BikeAccess.UNKNOWN, + CarAccess.ALLOWED, + TransitMode.FERRY, + null, + Accessibility.NO_INFORMATION, + TripAlteration.PLANNED + ); + + TripTimes tripTimesCarsNotAllowed = createTestTripTimes( + TRIP_ID, + ROUTE, + BikeAccess.UNKNOWN, + CarAccess.NOT_ALLOWED, + TransitMode.FERRY, + null, + Accessibility.NO_INFORMATION, + TripAlteration.PLANNED + ); + + TripTimes tripTimesCarsUnknown = createTestTripTimes( + TRIP_ID, + ROUTE, + BikeAccess.UNKNOWN, + CarAccess.UNKNOWN, + TransitMode.FERRY, + null, + Accessibility.NO_INFORMATION, + TripAlteration.PLANNED + ); + + RouteRequestTransitDataProviderFilter filter = new RouteRequestTransitDataProviderFilter( + false, + true, + false, + DEFAULT_ACCESSIBILITY, + false, + false, + Set.of(), + List.of(AllowAllTransitFilter.of()) + ); + + assertThat(filter.tripTimesPredicate(tripTimesCarsAllowed, false)).isTrue(); + assertThat(filter.tripTimesPredicate(tripTimesCarsNotAllowed, false)).isFalse(); + assertThat(filter.tripTimesPredicate(tripTimesCarsUnknown, false)).isFalse(); + } + @Test void multipleFilteringTest() { TripTimes matchingTripTimes = createTestTripTimes( TRIP_ID, ROUTE, BikeAccess.ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.BUS, null, Accessibility.POSSIBLE, @@ -724,6 +838,7 @@ void multipleFilteringTest() { TRIP_ID, ROUTE, BikeAccess.ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.RAIL, null, Accessibility.POSSIBLE, @@ -733,6 +848,7 @@ void multipleFilteringTest() { TRIP_ID, ROUTE, BikeAccess.NOT_ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.RAIL, null, Accessibility.POSSIBLE, @@ -742,6 +858,7 @@ void multipleFilteringTest() { TRIP_ID, ROUTE, BikeAccess.NOT_ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.RAIL, null, Accessibility.NOT_POSSIBLE, @@ -751,6 +868,7 @@ void multipleFilteringTest() { TRIP_ID, ROUTE, BikeAccess.ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.BUS, null, Accessibility.NOT_POSSIBLE, @@ -760,6 +878,7 @@ void multipleFilteringTest() { TRIP_ID, ROUTE, BikeAccess.ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.BUS, null, Accessibility.POSSIBLE, @@ -768,6 +887,7 @@ void multipleFilteringTest() { var filter = new RouteRequestTransitDataProviderFilter( true, + false, true, DEFAULT_ACCESSIBILITY, false, @@ -790,6 +910,7 @@ private boolean validateModesOnTripTimes( TripTimes tripTimes ) { var filter = new RouteRequestTransitDataProviderFilter( + false, false, false, DEFAULT_ACCESSIBILITY, @@ -803,20 +924,20 @@ private boolean validateModesOnTripTimes( } private TripPatternForDate createTestTripPatternForDate() { - Route route = TransitModelForTest.route("1").build(); + Route route = TimetableRepositoryForTest.route("1").build(); var stopTime = new StopTime(); stopTime.setStop(STOP_FOR_TEST); StopPattern stopPattern = new StopPattern(List.of(stopTime)); RoutingTripPattern tripPattern = TripPattern - .of(TransitModelForTest.id("P1")) + .of(TimetableRepositoryForTest.id("P1")) .withRoute(route) .withStopPattern(stopPattern) .build() .getRoutingTripPattern(); TripTimes tripTimes = TripTimesFactory.tripTimes( - TransitModelForTest.trip("1").withRoute(route).build(), + TimetableRepositoryForTest.trip("1").withRoute(route).build(), List.of(new StopTime()), new Deduplicator() ); @@ -867,6 +988,7 @@ private RealTimeTripTimes createTestTripTimes( FeedScopedId tripId, Route route, BikeAccess bikeAccess, + CarAccess carAccess, TransitMode mode, String submode, Accessibility wheelchairBoarding, @@ -878,6 +1000,7 @@ private RealTimeTripTimes createTestTripTimes( .withMode(mode) .withNetexSubmode(submode) .withBikesAllowed(bikeAccess) + .withCarsAllowed(carAccess) .withWheelchairBoarding(wheelchairBoarding) .withNetexAlteration(tripAlteration) .build(); @@ -896,6 +1019,7 @@ private TripTimes createTestTripTimesWithSubmode(String submode) { TRIP_ID, ROUTE, BikeAccess.NOT_ALLOWED, + CarAccess.NOT_ALLOWED, TransitMode.BUS, submode, Accessibility.NOT_POSSIBLE, diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TestRouteData.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TestRouteData.java similarity index 93% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TestRouteData.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TestRouteData.java index f57f03705fd..5c345e55931 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TestRouteData.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TestRouteData.java @@ -12,12 +12,11 @@ import java.util.Map; import java.util.stream.Collectors; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.model.StopTime; import org.opentripplanner.raptor.spi.RaptorTimeTable; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripPatternForDate; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripSchedule; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.network.Route; @@ -29,6 +28,7 @@ import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.model.timetable.TripTimesFactory; +import org.opentripplanner.utils.time.TimeUtils; public class TestRouteData { @@ -59,11 +59,11 @@ public TestRouteData(Route route, List stops, List times) { tripPattern = TripPattern - .of(TransitModelForTest.id("TP:" + route)) + .of(TimetableRepositoryForTest.id("TP:" + route)) .withRoute(this.route) .withStopPattern(new StopPattern(stopTimesFistTrip)) + .withScheduledTimeTableBuilder(builder -> builder.addAllTripTimes(tripTimes)) .build(); - tripTimes.forEach(tripPattern::add); RoutingTripPattern routingTripPattern = tripPattern.getRoutingTripPattern(); @@ -167,7 +167,7 @@ private Trip parseTripInfo( Deduplicator deduplicator ) { var trip = Trip - .of(TransitModelForTest.id(route + "-" + stopTimesByTrip.size() + 1)) + .of(TimetableRepositoryForTest.id(route + "-" + stopTimesByTrip.size() + 1)) .withRoute(this.route) .build(); var stopTimes = stopTimes(trip, stops, tripTimes); @@ -260,9 +260,12 @@ public Builder withSubmode(String submode) { } public TestRouteData build() { - var routeBuilder = TransitModelForTest.route(route).withMode(mode).withShortName(route); + var routeBuilder = TimetableRepositoryForTest + .route(route) + .withMode(mode) + .withShortName(route); if (agency != null) { - routeBuilder.withAgency(TransitModelForTest.agency(agency)); + routeBuilder.withAgency(TimetableRepositoryForTest.agency(agency)); } if (submode != null) { routeBuilder.withNetexSubmode(submode); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TestTransitCaseData.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TestTransitCaseData.java similarity index 86% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TestTransitCaseData.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TestTransitCaseData.java index c8d99f1bfaf..729b643667a 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TestTransitCaseData.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TestTransitCaseData.java @@ -1,13 +1,13 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.request; import java.time.LocalDate; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; public final class TestTransitCaseData { - private static TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); public static final Station STATION_A = TEST_MODEL .station("A") diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripAssert.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripAssert.java similarity index 96% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripAssert.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripAssert.java index fa76a2790ed..37620d80bc3 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripAssert.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripAssert.java @@ -4,9 +4,9 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent; import org.opentripplanner.raptor.spi.RaptorTripScheduleSearch; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; class TripAssert { diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripPatternForDatesTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripPatternForDatesTest.java new file mode 100644 index 00000000000..9189a5b932a --- /dev/null +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripPatternForDatesTest.java @@ -0,0 +1,119 @@ +package org.opentripplanner.routing.algorithm.raptoradapter.transit.request; + +import static org.junit.jupiter.api.Assertions.*; + +import java.time.LocalDate; +import java.util.BitSet; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.opentripplanner.model.Frequency; +import org.opentripplanner.model.StopTime; +import org.opentripplanner.raptor.api.model.SearchDirection; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripPatternForDate; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.transit.model.framework.Deduplicator; +import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.transit.model.network.RoutingTripPattern; +import org.opentripplanner.transit.model.network.StopPattern; +import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.timetable.FrequencyEntry; +import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.transit.model.timetable.TripTimesFactory; + +class TripPatternForDatesTest { + + private static final int FREQUENCY_START = 7 * 60 * 60; + private static final int FREQUENCY_END = 23 * 60 * 60; + private static final int HEADWAY = 300; + private static final Route ROUTE = TimetableRepositoryForTest.route("1").build(); + private static final LocalDate SERVICE_DATE = LocalDate.of(2024, 11, 1); + + @Test + void forwardSearchInRange() { + var result = getTestSubjectWithExactFrequency() + .createCustomizedTripSearch(SearchDirection.FORWARD) + .search(FREQUENCY_END - HEADWAY, 0); + assertTrue(result.time() >= FREQUENCY_END - HEADWAY); + assertTrue(result.time() < FREQUENCY_END); + } + + @Test + void forwardSearchOutOfRange() { + var result = getTestSubjectWithExactFrequency() + .createCustomizedTripSearch(SearchDirection.FORWARD) + .search(FREQUENCY_END, 0); + assertTrue(result.empty()); + } + + @Test + void reverseSearchInRange() { + var result = getTestSubjectWithExactFrequency() + .createCustomizedTripSearch(SearchDirection.REVERSE) + .search(FREQUENCY_START, 0); + assertEquals(FREQUENCY_START, result.time()); + } + + @Test + void reverseSearchOutOfRange() { + var result = getTestSubjectWithExactFrequency() + .createCustomizedTripSearch(SearchDirection.REVERSE) + .search(FREQUENCY_START - 1, 0); + assertTrue(result.empty()); + } + + private static TripPatternForDates getTestSubjectWithExactFrequency() { + var testModel = TimetableRepositoryForTest.of(); + var stop1 = testModel.stop("FEED:STOP1", 0, 0).build(); + var stop2 = testModel.stop("FEED:STOP2", 0, 0).build(); + + var stopTime1 = new StopTime(); + stopTime1.setStop(stop1); + stopTime1.setArrivalTime(0); + stopTime1.setDepartureTime(0); + stopTime1.setStopSequence(0); + var stopTime2 = new StopTime(); + stopTime2.setStop(stop2); + stopTime2.setArrivalTime(300); + stopTime2.setDepartureTime(300); + stopTime2.setStopSequence(1); + StopPattern stopPattern = new StopPattern(List.of(stopTime1, stopTime2)); + RoutingTripPattern tripPattern = TripPattern + .of(TimetableRepositoryForTest.id("P1")) + .withRoute(ROUTE) + .withStopPattern(stopPattern) + .build() + .getRoutingTripPattern(); + + final TripTimes tripTimes = TripTimesFactory.tripTimes( + TimetableRepositoryForTest.trip("1").withRoute(ROUTE).build(), + List.of(stopTime1, stopTime2), + new Deduplicator() + ); + + var frequency = new Frequency(); + frequency.setStartTime(FREQUENCY_START); + frequency.setEndTime(FREQUENCY_END); + frequency.setHeadwaySecs(HEADWAY); + frequency.setExactTimes(1); + + var boardingAndAlightingPossible = new BitSet(2); + boardingAndAlightingPossible.set(0); + boardingAndAlightingPossible.set(1); + + return new TripPatternForDates( + tripPattern, + new TripPatternForDate[] { + new TripPatternForDate( + tripPattern, + List.of(tripTimes), + List.of(new FrequencyEntry(frequency, tripTimes)), + SERVICE_DATE + ), + }, + new int[] { 0 }, + boardingAndAlightingPossible, + boardingAndAlightingPossible, + 0 + ); + } +} diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearchTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearchTest.java similarity index 94% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearchTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearchTest.java index 8fddca9511f..55cb99b2f82 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearchTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleAlightSearchTest.java @@ -1,18 +1,18 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.request; -import static org.opentripplanner.raptor._data.transit.TestTripPattern.pattern; -import static org.opentripplanner.raptor._data.transit.TestTripSchedule.schedule; +import static org.opentripplanner.raptorlegacy._data.transit.TestTripPattern.pattern; +import static org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule.schedule; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.junit.jupiter.api.Test; -import org.opentripplanner.raptor._data.RaptorTestConstants; -import org.opentripplanner.raptor._data.transit.TestRoute; -import org.opentripplanner.raptor._data.transit.TestTripPattern; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.model.SearchDirection; import org.opentripplanner.raptor.spi.RaptorTripScheduleSearch; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; +import org.opentripplanner.raptorlegacy._data.transit.TestRoute; +import org.opentripplanner.raptorlegacy._data.transit.TestTripPattern; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; public class TripScheduleAlightSearchTest implements RaptorTestConstants { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearchTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearchTest.java similarity index 94% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearchTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearchTest.java index dd3a7d64cf6..28811fcc42c 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearchTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleBoardSearchTest.java @@ -1,17 +1,17 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.request; -import static org.opentripplanner.raptor._data.transit.TestTripSchedule.schedule; +import static org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule.schedule; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.junit.jupiter.api.Test; -import org.opentripplanner.raptor._data.RaptorTestConstants; -import org.opentripplanner.raptor._data.transit.TestRoute; -import org.opentripplanner.raptor._data.transit.TestTripPattern; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.model.SearchDirection; import org.opentripplanner.raptor.spi.RaptorTripScheduleSearch; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; +import org.opentripplanner.raptorlegacy._data.transit.TestRoute; +import org.opentripplanner.raptorlegacy._data.transit.TestTripPattern; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; public class TripScheduleBoardSearchTest implements RaptorTestConstants { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPathTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPathTest.java similarity index 94% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPathTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPathTest.java index 788192c45b5..bc01a082740 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPathTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPathTest.java @@ -4,9 +4,9 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import org.junit.jupiter.api.Test; -import org.opentripplanner.raptor._data.RaptorTestConstants; -import org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase; import org.opentripplanner.raptor.api.model.RaptorValueFormatter; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; +import org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase; class OptimizedPathTest implements RaptorTestConstants { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculatorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculatorTest.java similarity index 78% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculatorTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculatorTest.java index ae10dd0d03e..d5d8f7c7c62 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculatorTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculatorTest.java @@ -1,18 +1,18 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.time.TimeUtils.time; -import static org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase.C1_CALCULATOR; +import static org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase.C1_CALCULATOR; import static org.opentripplanner.routing.algorithm.transferoptimization.model.MinSafeTransferTimeCalculator.bound; +import static org.opentripplanner.utils.time.TimeUtils.time; import java.util.List; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.raptor._data.RaptorTestConstants; -import org.opentripplanner.raptor._data.api.TestPathBuilder; -import org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.path.RaptorPath; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; +import org.opentripplanner.raptorlegacy._data.api.TestPathBuilder; +import org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; +import org.opentripplanner.utils.time.DurationUtils; public class MinSafeTransferTimeCalculatorTest implements RaptorTestConstants { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTailTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTailTest.java similarity index 95% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTailTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTailTest.java index 8c82f68a8bc..505b6581000 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTailTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTailTest.java @@ -4,11 +4,11 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.opentripplanner.raptor._data.RaptorTestConstants; -import org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.path.RaptorPath; import org.opentripplanner.raptor.api.path.TransitPathLeg; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; +import org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; import org.opentripplanner.routing.algorithm.transferoptimization.services.TestTransferBuilder; class OptimizedPathTailTest implements RaptorTestConstants { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopPriorityCostCalculatorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopPriorityCostCalculatorTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopPriorityCostCalculatorTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopPriorityCostCalculatorTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopTimeTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopTimeTest.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopTimeTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/StopTimeTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TransferWaitTimeCostCalculatorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TransferWaitTimeCostCalculatorTest.java similarity index 98% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TransferWaitTimeCostCalculatorTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TransferWaitTimeCostCalculatorTest.java index 3d5ae037428..3a375f7968a 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TransferWaitTimeCostCalculatorTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TransferWaitTimeCostCalculatorTest.java @@ -2,7 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.opentripplanner.framework.time.DurationUtils.durationInSeconds; +import static org.opentripplanner.utils.time.DurationUtils.durationInSeconds; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripStopTimeTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripStopTimeTest.java similarity index 92% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripStopTimeTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripStopTimeTest.java index 0c0d50dfe74..640dd48d27d 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripStopTimeTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/TripStopTimeTest.java @@ -1,13 +1,13 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.time.TimeUtils.time; import static org.opentripplanner.routing.algorithm.transferoptimization.model.StopTime.stopTime; +import static org.opentripplanner.utils.time.TimeUtils.time; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.TimeUtils; -import org.opentripplanner.raptor._data.transit.TestTripPattern; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.raptorlegacy._data.transit.TestTripPattern; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; +import org.opentripplanner.utils.time.TimeUtils; public class TripStopTimeTest { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilterTest.java similarity index 92% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilterTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilterTest.java index 8ecf0006e48..e32559c2dad 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilterTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilterTest.java @@ -1,15 +1,15 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model.costfilter; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase.C1_CALCULATOR; +import static org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase.C1_CALCULATOR; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; import org.junit.jupiter.api.Test; -import org.opentripplanner.raptor._data.RaptorTestConstants; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; import org.opentripplanner.routing.algorithm.transferoptimization.model.OptimizedPathTail; import org.opentripplanner.routing.algorithm.transferoptimization.model.TransferWaitTimeCostCalculator; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughNoTransfersTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughNoTransfersTest.java similarity index 94% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughNoTransfersTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughNoTransfersTest.java index 926e6ebe15c..ff1f37ef5fa 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughNoTransfersTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughNoTransfersTest.java @@ -1,17 +1,17 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.time.TimeUtils.time; import static org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough.TestCase.testCase; import static org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough.TestUtils.domainService; import static org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough.TestUtils.first; import static org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough.TestUtils.pathBuilder; +import static org.opentripplanner.utils.time.TimeUtils.time; import java.util.List; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.raptor._data.RaptorTestConstants; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; /** * This test focus on the PASS-THROUGH functionality with a very simple scenario - one transit leg diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughOneTransferTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughOneTransferTest.java similarity index 97% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughOneTransferTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughOneTransferTest.java index ad41f43a586..d1bc95f3b68 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughOneTransferTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughOneTransferTest.java @@ -1,19 +1,19 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.time.TimeUtils.time; import static org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough.TestCase.testCase; import static org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough.TestUtils.domainService; import static org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough.TestUtils.pathBuilder; import static org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough.TestUtils.pathFocus; import static org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough.TestUtils.tx; +import static org.opentripplanner.utils.time.TimeUtils.time; import java.util.List; import java.util.stream.Collectors; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.raptor._data.RaptorTestConstants; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; /** * This test focus on the PASS-THROUGH functionality with two transit legs and one transfer in the diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughTwoTransfersTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughTwoTransfersTest.java similarity index 97% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughTwoTransfersTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughTwoTransfersTest.java index e92e0ba0b3b..bed2bff0202 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughTwoTransfersTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/PassThroughTwoTransfersTest.java @@ -1,19 +1,19 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.time.TimeUtils.time; import static org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough.TestCase.testCase; import static org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough.TestUtils.domainService; import static org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough.TestUtils.pathBuilder; import static org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough.TestUtils.tx; +import static org.opentripplanner.utils.time.TimeUtils.time; import java.util.List; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.raptor._data.RaptorTestConstants; -import org.opentripplanner.raptor._data.api.PathUtils; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.path.RaptorPath; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; +import org.opentripplanner.raptorlegacy._data.api.PathUtils; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; /** * This test focus on the PASS-THROUGH functionality with three transit legs and two transfer in diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/StopPair.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/StopPair.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/StopPair.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/StopPair.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestCase.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestCase.java similarity index 96% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestCase.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestCase.java index 3b2059cf4d9..8ca961dcab0 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestCase.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestCase.java @@ -1,8 +1,8 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model.passthrough; import java.util.List; -import org.opentripplanner.raptor._data.RaptorTestConstants; import org.opentripplanner.raptor.api.request.PassThroughPoint; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; record TestCase( String description, diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestCaseBuilder.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestCaseBuilder.java similarity index 100% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestCaseBuilder.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestCaseBuilder.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestUtils.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestUtils.java similarity index 91% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestUtils.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestUtils.java index 2faf0ee95c1..103e2c88f3f 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestUtils.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/TestUtils.java @@ -4,12 +4,12 @@ import java.util.Collection; import java.util.List; -import org.opentripplanner.raptor._data.RaptorTestConstants; -import org.opentripplanner.raptor._data.api.TestPathBuilder; -import org.opentripplanner.raptor._data.transit.TestTransitData; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.request.PassThroughPoint; import org.opentripplanner.raptor.spi.RaptorCostCalculator; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; +import org.opentripplanner.raptorlegacy._data.api.TestPathBuilder; +import org.opentripplanner.raptorlegacy._data.transit.TestTransitData; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.DefaultCostCalculator; import org.opentripplanner.routing.algorithm.transferoptimization.model.TripToTripTransfer; import org.opentripplanner.routing.algorithm.transferoptimization.model.costfilter.MinCostPathTailFilterFactory; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/WalkDurationForStopCombinations.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/WalkDurationForStopCombinations.java similarity index 97% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/WalkDurationForStopCombinations.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/WalkDurationForStopCombinations.java index cfd8f6c4e53..66bb1e02c17 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/WalkDurationForStopCombinations.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/passthrough/WalkDurationForStopCombinations.java @@ -4,8 +4,8 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; -import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.raptor.api.request.PassThroughPoint; +import org.opentripplanner.utils.lang.IntUtils; /** * This class is used to adjust the walk time - giving each path an unique generalized-cost. We want diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceConstrainedTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceConstrainedTest.java similarity index 96% rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceConstrainedTest.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceConstrainedTest.java index a040da1d23f..3cfba2330c1 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceConstrainedTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceConstrainedTest.java @@ -2,20 +2,20 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.opentripplanner.framework.time.TimeUtils.time; import static org.opentripplanner.model.transfer.TransferPriority.ALLOWED; import static org.opentripplanner.model.transfer.TransferPriority.NOT_ALLOWED; import static org.opentripplanner.model.transfer.TransferPriority.PREFERRED; import static org.opentripplanner.model.transfer.TransferPriority.RECOMMENDED; import static org.opentripplanner.routing.algorithm.transferoptimization.services.TransferGeneratorDummy.dummyTransferGenerator; +import static org.opentripplanner.utils.time.TimeUtils.time; import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner.model.transfer.ConstrainedTransfer; import org.opentripplanner.model.transfer.TransferPriority; -import org.opentripplanner.raptor._data.RaptorTestConstants; -import org.opentripplanner.raptor._data.api.PathUtils; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; +import org.opentripplanner.raptorlegacy._data.api.PathUtils; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; /** *

    diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceTest.java
    similarity index 97%
    rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceTest.java
    rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceTest.java
    index be927046c43..6a023138751 100644
    --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceTest.java
    @@ -1,20 +1,20 @@
     package org.opentripplanner.routing.algorithm.transferoptimization.services;
     
     import static org.junit.jupiter.api.Assertions.assertEquals;
    -import static org.opentripplanner.framework.time.TimeUtils.time;
     import static org.opentripplanner.routing.algorithm.transferoptimization.services.TestTransferBuilder.tx;
     import static org.opentripplanner.routing.algorithm.transferoptimization.services.TransferGeneratorDummy.dummyTransferGenerator;
    +import static org.opentripplanner.utils.time.TimeUtils.time;
     
     import java.util.List;
     import javax.annotation.Nullable;
     import org.junit.jupiter.api.Test;
    -import org.opentripplanner.raptor._data.RaptorTestConstants;
    -import org.opentripplanner.raptor._data.api.PathUtils;
    -import org.opentripplanner.raptor._data.api.TestPathBuilder;
    -import org.opentripplanner.raptor._data.transit.TestTripSchedule;
     import org.opentripplanner.raptor.spi.DefaultSlackProvider;
     import org.opentripplanner.raptor.spi.RaptorCostCalculator;
     import org.opentripplanner.raptor.spi.RaptorSlackProvider;
    +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants;
    +import org.opentripplanner.raptorlegacy._data.api.PathUtils;
    +import org.opentripplanner.raptorlegacy._data.api.TestPathBuilder;
    +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule;
     import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.DefaultCostCalculator;
     import org.opentripplanner.routing.algorithm.transferoptimization.model.TransferWaitTimeCostCalculator;
     import org.opentripplanner.routing.algorithm.transferoptimization.model.costfilter.MinCostPathTailFilterFactory;
    diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TestTransferBuilder.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TestTransferBuilder.java
    similarity index 96%
    rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TestTransferBuilder.java
    rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TestTransferBuilder.java
    index 4155d46fe63..f32b5366907 100644
    --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TestTransferBuilder.java
    +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TestTransferBuilder.java
    @@ -1,18 +1,18 @@
     package org.opentripplanner.routing.algorithm.transferoptimization.services;
     
     import java.util.Objects;
    -import org.opentripplanner.framework.time.TimeUtils;
     import org.opentripplanner.model.transfer.ConstrainedTransfer;
     import org.opentripplanner.model.transfer.TransferConstraint;
     import org.opentripplanner.model.transfer.TransferPriority;
     import org.opentripplanner.model.transfer.TripTransferPoint;
    -import org.opentripplanner.raptor._data.transit.TestTransfer;
     import org.opentripplanner.raptor.api.model.RaptorConstants;
     import org.opentripplanner.raptor.api.model.RaptorTripSchedule;
    +import org.opentripplanner.raptorlegacy._data.transit.TestTransfer;
     import org.opentripplanner.routing.algorithm.transferoptimization.model.TripStopTime;
     import org.opentripplanner.routing.algorithm.transferoptimization.model.TripToTripTransfer;
    -import org.opentripplanner.transit.model._data.TransitModelForTest;
    +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
     import org.opentripplanner.transit.model.timetable.Trip;
    +import org.opentripplanner.utils.time.TimeUtils;
     
     /**
      * This builder is used to create a {@link ConstrainedTransfer} for use in unit-tests. It build a
    @@ -154,7 +154,7 @@ public TripToTripTransfer build() {
     
       private static  Trip createDummyTrip(T trip) {
         // Set an uniq id: pattern + the first stop departure time
    -    return TransitModelForTest
    +    return TimetableRepositoryForTest
           .trip(trip.pattern().debugInfo() + ":" + TimeUtils.timeToStrCompact(trip.departure(0)))
           .build();
       }
    diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorDummy.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorDummy.java
    similarity index 85%
    rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorDummy.java
    rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorDummy.java
    index 4392e89a83d..e021a38a8de 100644
    --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorDummy.java
    +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorDummy.java
    @@ -2,9 +2,9 @@
     
     import java.util.Arrays;
     import java.util.List;
    -import org.opentripplanner.raptor._data.transit.TestTransitData;
    -import org.opentripplanner.raptor._data.transit.TestTripSchedule;
     import org.opentripplanner.raptor.api.path.TransitPathLeg;
    +import org.opentripplanner.raptorlegacy._data.transit.TestTransitData;
    +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule;
     import org.opentripplanner.routing.algorithm.transferoptimization.model.TripToTripTransfer;
     
     /**
    diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorTest.java
    similarity index 96%
    rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorTest.java
    rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorTest.java
    index 4283e5cca62..4e1d89c6b49 100644
    --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorTest.java
    @@ -2,9 +2,9 @@
     
     import static java.time.Duration.ofMinutes;
     import static org.junit.jupiter.api.Assertions.assertEquals;
    -import static org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase.C1_CALCULATOR;
    -import static org.opentripplanner.raptor._data.transit.TestRoute.route;
    -import static org.opentripplanner.raptor._data.transit.TestTripSchedule.schedule;
    +import static org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase.C1_CALCULATOR;
    +import static org.opentripplanner.raptorlegacy._data.transit.TestRoute.route;
    +import static org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule.schedule;
     
     import java.time.Duration;
     import java.util.List;
    @@ -16,19 +16,19 @@
     import org.junit.jupiter.params.ParameterizedTest;
     import org.junit.jupiter.params.provider.Arguments;
     import org.junit.jupiter.params.provider.MethodSource;
    -import org.opentripplanner.framework.time.TimeUtils;
     import org.opentripplanner.model.transfer.TransferConstraint;
    -import org.opentripplanner.raptor._data.RaptorTestConstants;
    -import org.opentripplanner.raptor._data.api.TestPathBuilder;
    -import org.opentripplanner.raptor._data.transit.TestRoute;
    -import org.opentripplanner.raptor._data.transit.TestTransfer;
    -import org.opentripplanner.raptor._data.transit.TestTransitData;
    -import org.opentripplanner.raptor._data.transit.TestTripPattern;
    -import org.opentripplanner.raptor._data.transit.TestTripSchedule;
     import org.opentripplanner.raptor.api.path.RaptorPath;
     import org.opentripplanner.raptor.api.path.TransitPathLeg;
     import org.opentripplanner.raptor.spi.DefaultSlackProvider;
     import org.opentripplanner.raptor.spi.RaptorSlackProvider;
    +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants;
    +import org.opentripplanner.raptorlegacy._data.api.TestPathBuilder;
    +import org.opentripplanner.raptorlegacy._data.transit.TestRoute;
    +import org.opentripplanner.raptorlegacy._data.transit.TestTransfer;
    +import org.opentripplanner.raptorlegacy._data.transit.TestTransitData;
    +import org.opentripplanner.raptorlegacy._data.transit.TestTripPattern;
    +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule;
    +import org.opentripplanner.utils.time.TimeUtils;
     
     public class TransferGeneratorTest implements RaptorTestConstants {
     
    diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelectorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelectorTest.java
    similarity index 94%
    rename from src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelectorTest.java
    rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelectorTest.java
    index d62f123e7d6..5ca18f63cb9 100644
    --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelectorTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelectorTest.java
    @@ -8,19 +8,19 @@
     import java.util.Set;
     import java.util.stream.Collectors;
     import org.junit.jupiter.api.Test;
    -import org.opentripplanner.framework.time.TimeUtils;
    -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.path.EgressPathLeg;
     import org.opentripplanner.raptor.api.path.TransitPathLeg;
     import org.opentripplanner.raptor.spi.DefaultSlackProvider;
     import org.opentripplanner.raptor.spi.RaptorCostCalculator;
     import org.opentripplanner.raptor.spi.RaptorSlackProvider;
    +import org.opentripplanner.raptorlegacy._data.RaptorTestConstants;
    +import org.opentripplanner.raptorlegacy._data.transit.TestAccessEgress;
    +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule;
     import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.DefaultCostCalculator;
     import org.opentripplanner.routing.algorithm.transferoptimization.model.OptimizedPathTail;
     import org.opentripplanner.routing.algorithm.transferoptimization.model.PathTailFilter;
     import org.opentripplanner.routing.algorithm.transferoptimization.model.costfilter.MinCostPathTailFilterFactory;
    +import org.opentripplanner.utils.time.TimeUtils;
     
     public class TransitPathLegSelectorTest implements RaptorTestConstants {
     
    diff --git a/src/test/java/org/opentripplanner/routing/algorithm/via/ViaRoutingWorkerTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/via/ViaRoutingWorkerTest.java
    similarity index 95%
    rename from src/test/java/org/opentripplanner/routing/algorithm/via/ViaRoutingWorkerTest.java
    rename to application/src/test/java/org/opentripplanner/routing/algorithm/via/ViaRoutingWorkerTest.java
    index 94c8c7b2f71..c11b25d4ac3 100644
    --- a/src/test/java/org/opentripplanner/routing/algorithm/via/ViaRoutingWorkerTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/via/ViaRoutingWorkerTest.java
    @@ -10,18 +10,18 @@
     import java.time.ZonedDateTime;
     import java.util.List;
     import org.junit.jupiter.api.Test;
    -import org.opentripplanner.framework.time.TimeUtils;
     import org.opentripplanner.model.GenericLocation;
     import org.opentripplanner.model.plan.Itinerary;
     import org.opentripplanner.model.plan.Place;
     import org.opentripplanner.model.plan.TripPlan;
     import org.opentripplanner.routing.api.request.RouteRequest;
     import org.opentripplanner.routing.api.request.RouteViaRequest;
    -import org.opentripplanner.routing.api.request.ViaLocation;
    +import org.opentripplanner.routing.api.request.ViaLocationDeprecated;
     import org.opentripplanner.routing.api.request.request.JourneyRequest;
     import org.opentripplanner.routing.api.response.RoutingResponse;
     import org.opentripplanner.routing.api.response.ViaRoutingResponseConnection;
    -import org.opentripplanner.transit.model._data.TransitModelForTest;
    +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
    +import org.opentripplanner.utils.time.TimeUtils;
     
     /**
      * Create search from point A to point B via point C. Search will start at 12:00 and will find two
    @@ -50,7 +50,7 @@ public class ViaRoutingWorkerTest {
       private static List firstSearch;
       private static List secondSearch;
     
    -  private final TransitModelForTest testModel = TransitModelForTest.of();
    +  private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of();
     
       private final Place fromA = testModel.place("A", 5.0, 8.0);
       private final Place viaC = testModel.place("C", 7.0, 9.0);
    @@ -136,7 +136,7 @@ public RouteViaRequest createRouteViaRequest() {
         int minSlack = 10;
         int maxSlack = 45;
         var viaLocations = List.of(
    -      new ViaLocation(
    +      new ViaLocationDeprecated(
             location(viaC),
             false,
             Duration.ofMinutes(minSlack),
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/DebugRaptorTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/DebugRaptorTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/DebugRaptorTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/DebugRaptorTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/WheelchairPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/WheelchairPreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/WheelchairPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/WheelchairPreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/framework/CostLinearFunctionTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/framework/CostLinearFunctionTest.java
    similarity index 98%
    rename from src/test/java/org/opentripplanner/routing/api/request/framework/CostLinearFunctionTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/framework/CostLinearFunctionTest.java
    index e4f42fcd409..8d972896878 100644
    --- a/src/test/java/org/opentripplanner/routing/api/request/framework/CostLinearFunctionTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/api/request/framework/CostLinearFunctionTest.java
    @@ -13,8 +13,8 @@
     import org.junit.jupiter.params.provider.Arguments;
     import org.junit.jupiter.params.provider.MethodSource;
     import org.opentripplanner.framework.model.Cost;
    -import org.opentripplanner.framework.time.DurationUtils;
     import org.opentripplanner.test.support.TestTableParser;
    +import org.opentripplanner.utils.time.DurationUtils;
     
     class CostLinearFunctionTest {
     
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/framework/DurationForEnumTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/framework/DurationForEnumTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/framework/DurationForEnumTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/framework/DurationForEnumTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/framework/LinearFunctionSerializationTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/framework/LinearFunctionSerializationTest.java
    similarity index 98%
    rename from src/test/java/org/opentripplanner/routing/api/request/framework/LinearFunctionSerializationTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/framework/LinearFunctionSerializationTest.java
    index 46ef4b50e77..dbb33e1f97b 100644
    --- a/src/test/java/org/opentripplanner/routing/api/request/framework/LinearFunctionSerializationTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/api/request/framework/LinearFunctionSerializationTest.java
    @@ -12,8 +12,8 @@
     import org.junit.jupiter.params.ParameterizedTest;
     import org.junit.jupiter.params.provider.Arguments;
     import org.junit.jupiter.params.provider.MethodSource;
    -import org.opentripplanner.framework.time.DurationUtils;
     import org.opentripplanner.test.support.TestTableParser;
    +import org.opentripplanner.utils.time.DurationUtils;
     
     class LinearFunctionSerializationTest {
     
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyForEnumTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyForEnumTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyForEnumTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyForEnumTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyTest.java
    similarity index 96%
    rename from src/test/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyTest.java
    index 58370722e7c..c13fb0e8c63 100644
    --- a/src/test/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyTest.java
    @@ -8,7 +8,7 @@
     import org.junit.jupiter.api.Test;
     import org.opentripplanner.framework.model.Cost;
     import org.opentripplanner.framework.model.TimeAndCost;
    -import org.opentripplanner.framework.time.DurationUtils;
    +import org.opentripplanner.utils.time.DurationUtils;
     
     class TimeAndCostPenaltyTest {
     
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/framework/TimePenaltyTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/framework/TimePenaltyTest.java
    similarity index 97%
    rename from src/test/java/org/opentripplanner/routing/api/request/framework/TimePenaltyTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/framework/TimePenaltyTest.java
    index 087ffa1d637..7321653192e 100644
    --- a/src/test/java/org/opentripplanner/routing/api/request/framework/TimePenaltyTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/api/request/framework/TimePenaltyTest.java
    @@ -7,7 +7,7 @@
     
     import java.time.Duration;
     import org.junit.jupiter.api.Test;
    -import org.opentripplanner.framework.time.DurationUtils;
    +import org.opentripplanner.utils.time.DurationUtils;
     
     class TimePenaltyTest {
     
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/AccessibilityPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/AccessibilityPreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/AccessibilityPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/AccessibilityPreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/ElevatorPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/ElevatorPreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/ElevatorPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/ElevatorPreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/ImmutablePreferencesAsserts.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/ImmutablePreferencesAsserts.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/ImmutablePreferencesAsserts.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/ImmutablePreferencesAsserts.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterDebugProfileTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterDebugProfileTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterDebugProfileTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterDebugProfileTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferencesTest.java
    similarity index 94%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferencesTest.java
    index f59586b0af9..4c1403b0b0f 100644
    --- a/src/test/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferencesTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/api/request/preference/ItineraryFilterPreferencesTest.java
    @@ -127,13 +127,20 @@ void testCopyOfEqualsAndHashCode() {
     
         // Create a copy, make a change and set it back again to force creating a new object
         var other = subject.copyOf().withGroupSimilarityKeepOne(0.95).build();
    -    var same = other.copyOf().withGroupSimilarityKeepOne(GROUP_SIMILARITY_KEEP_ONE).build();
    +    var same = other
    +      .copyOf()
    +      .withGroupSimilarityKeepOne(GROUP_SIMILARITY_KEEP_ONE)
    +      .withFilterDirectFlexBySearchWindow(true)
    +      .build();
         assertEqualsAndHashCode(subject, other, same);
       }
     
       @Test
       void testToString() {
    -    assertEquals("ItineraryFilterPreferences{}", ItineraryFilterPreferences.DEFAULT.toString());
    +    assertEquals(
    +      "ItineraryFilterPreferences{filterDirectFlexBySearchWindow}",
    +      ItineraryFilterPreferences.DEFAULT.toString()
    +    );
         assertEquals(
           "ItineraryFilterPreferences{" +
           "accessibilityScore, " +
    @@ -147,7 +154,8 @@ void testToString() {
           "nonTransitGeneralizedCostLimit: 4s + 5.0 t, " +
           "parkAndRideDurationRatio: 0.44, " +
           "transitGeneralizedCostLimit: TransitGeneralizedCostFilterParams[costLimitFunction=4s + 5.0 t, intervalRelaxFactor=3.0], " +
    -      "removeTransitWithHigherCostThanBestOnStreetOnly: 30s + 1.30 t" +
    +      "removeTransitWithHigherCostThanBestOnStreetOnly: 30s + 1.30 t, " +
    +      "filterDirectFlexBySearchWindow" +
           "}",
           subject.toString()
         );
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/RaptorPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/RaptorPreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/RaptorPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/RaptorPreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/RelaxTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/RelaxTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/RelaxTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/RelaxTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/SystemPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/SystemPreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/SystemPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/SystemPreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangleTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangleTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangleTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangleTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/TransferOptimizationPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/TransferOptimizationPreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/TransferOptimizationPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/TransferOptimizationPreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/TransferPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/TransferPreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/TransferPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/TransferPreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/TransitPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/TransitPreferencesTest.java
    similarity index 96%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/TransitPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/TransitPreferencesTest.java
    index b77a7d9085b..bcdfcfc545c 100644
    --- a/src/test/java/org/opentripplanner/routing/api/request/preference/TransitPreferencesTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/api/request/preference/TransitPreferencesTest.java
    @@ -81,6 +81,12 @@ void relaxTransitGroupPriority() {
         assertEquals(TRANSIT_GROUP_PRIORITY_RELAX, subject.relaxTransitGroupPriority());
       }
     
    +  @Test
    +  void isRelaxTransitGroupPrioritySet() {
    +    assertTrue(subject.isRelaxTransitGroupPrioritySet());
    +    assertFalse(TransitPreferences.DEFAULT.isRelaxTransitGroupPrioritySet());
    +  }
    +
       @Test
       void ignoreRealtimeUpdates() {
         assertFalse(TransitPreferences.DEFAULT.ignoreRealtimeUpdates());
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/WalkPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/preference/WalkPreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/preference/WalkPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/preference/WalkPreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/api/request/request/filter/SelectRequestTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/request/filter/SelectRequestTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/api/request/request/filter/SelectRequestTest.java
    rename to application/src/test/java/org/opentripplanner/routing/api/request/request/filter/SelectRequestTest.java
    diff --git a/application/src/test/java/org/opentripplanner/routing/api/request/via/PassThroughViaLocationTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/via/PassThroughViaLocationTest.java
    new file mode 100644
    index 00000000000..9ed431912ac
    --- /dev/null
    +++ b/application/src/test/java/org/opentripplanner/routing/api/request/via/PassThroughViaLocationTest.java
    @@ -0,0 +1,64 @@
    +package org.opentripplanner.routing.api.request.via;
    +
    +import static org.junit.jupiter.api.Assertions.assertEquals;
    +import static org.junit.jupiter.api.Assertions.assertTrue;
    +
    +import java.time.Duration;
    +import java.util.List;
    +import org.junit.jupiter.api.Test;
    +import org.opentripplanner._support.asserts.AssertEqualsAndHashCode;
    +import org.opentripplanner.transit.model.framework.FeedScopedId;
    +
    +class PassThroughViaLocationTest {
    +
    +  private static final FeedScopedId ID = FeedScopedId.ofNullable("F", "1");
    +
    +  private static final String LABEL = "AName";
    +
    +  @SuppressWarnings("DataFlowIssue")
    +  private static final ViaLocation subject = new PassThroughViaLocation(LABEL, List.of(ID));
    +
    +  @Test
    +  void allowAsPassThroughPoint() {
    +    assertTrue(subject.isPassThroughLocation());
    +  }
    +
    +  @Test
    +  void minimumWaitTime() {
    +    assertEquals(Duration.ZERO, subject.minimumWaitTime());
    +  }
    +
    +  @Test
    +  void label() {
    +    assertEquals(LABEL, subject.label());
    +  }
    +
    +  @Test
    +  void stopLocationIds() {
    +    assertEquals("[F:1]", subject.stopLocationIds().toString());
    +  }
    +
    +  @Test
    +  void coordinates() {
    +    assertEquals("[]", subject.coordinates().toString());
    +  }
    +
    +  @Test
    +  void testToString() {
    +    assertEquals(
    +      "PassThroughViaLocation{label: AName, stopLocationIds: [F:1]}",
    +      subject.toString()
    +    );
    +  }
    +
    +  @Test
    +  void testEqAndHashCode() {
    +    AssertEqualsAndHashCode
    +      .verify(subject)
    +      .sameAs(new PassThroughViaLocation(subject.label(), subject.stopLocationIds()))
    +      .differentFrom(
    +        new PassThroughViaLocation("Other", subject.stopLocationIds()),
    +        new PassThroughViaLocation(subject.label(), List.of(new FeedScopedId("F", "2")))
    +      );
    +  }
    +}
    diff --git a/application/src/test/java/org/opentripplanner/routing/api/request/via/VisitViaLocationTest.java b/application/src/test/java/org/opentripplanner/routing/api/request/via/VisitViaLocationTest.java
    new file mode 100644
    index 00000000000..e36ed42551e
    --- /dev/null
    +++ b/application/src/test/java/org/opentripplanner/routing/api/request/via/VisitViaLocationTest.java
    @@ -0,0 +1,77 @@
    +package org.opentripplanner.routing.api.request.via;
    +
    +import static org.junit.jupiter.api.Assertions.assertEquals;
    +import static org.junit.jupiter.api.Assertions.assertFalse;
    +
    +import java.time.Duration;
    +import java.util.List;
    +import org.junit.jupiter.api.Test;
    +import org.opentripplanner._support.asserts.AssertEqualsAndHashCode;
    +import org.opentripplanner.framework.geometry.WgsCoordinate;
    +import org.opentripplanner.transit.model.framework.FeedScopedId;
    +
    +class VisitViaLocationTest {
    +
    +  private static final FeedScopedId ID = FeedScopedId.ofNullable("F", "1");
    +  private static final String LABEL = "AName";
    +  private static final Duration MINIMUM_WAIT_TIME = Duration.ofMinutes(5);
    +
    +  @SuppressWarnings("DataFlowIssue")
    +  private static final ViaLocation subject = new VisitViaLocation(
    +    LABEL,
    +    MINIMUM_WAIT_TIME,
    +    List.of(ID),
    +    List.of(WgsCoordinate.GREENWICH)
    +  );
    +
    +  @Test
    +  void allowAsPassThroughPoint() {
    +    assertFalse(subject.isPassThroughLocation());
    +  }
    +
    +  @Test
    +  void minimumWaitTime() {
    +    assertEquals(MINIMUM_WAIT_TIME, subject.minimumWaitTime());
    +  }
    +
    +  @Test
    +  void label() {
    +    assertEquals(LABEL, subject.label());
    +  }
    +
    +  @Test
    +  void stopLocationIds() {
    +    assertEquals("[F:1]", subject.stopLocationIds().toString());
    +  }
    +
    +  @Test
    +  void coordinates() {
    +    assertEquals("[" + WgsCoordinate.GREENWICH + "]", subject.coordinates().toString());
    +  }
    +
    +  @Test
    +  void testToString() {
    +    assertEquals(
    +      "VisitViaLocation{label: AName, minimumWaitTime: 5m, stopLocationIds: [F:1], coordinates: [(51.48, 0.0)]}",
    +      subject.toString()
    +    );
    +  }
    +
    +  @Test
    +  void testEqAndHashCode() {
    +    var l = subject.label();
    +    var mwt = subject.minimumWaitTime();
    +    var ids = subject.stopLocationIds();
    +    var cs = subject.coordinates();
    +
    +    AssertEqualsAndHashCode
    +      .verify(subject)
    +      .sameAs(new VisitViaLocation(l, mwt, ids, cs))
    +      .differentFrom(
    +        new VisitViaLocation("other", mwt, ids, cs),
    +        new VisitViaLocation(l, Duration.ZERO, ids, cs),
    +        new VisitViaLocation(l, mwt, List.of(), cs),
    +        new VisitViaLocation(l, mwt, ids, List.of())
    +      );
    +  }
    +}
    diff --git a/src/test/java/org/opentripplanner/routing/core/GraphTest.java b/application/src/test/java/org/opentripplanner/routing/core/GraphTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/core/GraphTest.java
    rename to application/src/test/java/org/opentripplanner/routing/core/GraphTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/core/ItineraryFaresTest.java b/application/src/test/java/org/opentripplanner/routing/core/ItineraryFaresTest.java
    similarity index 95%
    rename from src/test/java/org/opentripplanner/routing/core/ItineraryFaresTest.java
    rename to application/src/test/java/org/opentripplanner/routing/core/ItineraryFaresTest.java
    index 3ad3b918ce1..7e40bb9670e 100644
    --- a/src/test/java/org/opentripplanner/routing/core/ItineraryFaresTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/core/ItineraryFaresTest.java
    @@ -12,10 +12,9 @@
     import static org.opentripplanner.model.plan.PlanTestConstants.T11_30;
     import static org.opentripplanner.model.plan.PlanTestConstants.T11_50;
     import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary;
    -import static org.opentripplanner.transit.model._data.TransitModelForTest.id;
    +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id;
     
     import java.util.List;
    -import javax.annotation.Nonnull;
     import org.junit.jupiter.api.Test;
     import org.opentripplanner.model.fare.FareProduct;
     import org.opentripplanner.model.fare.FareProductUse;
    @@ -65,7 +64,6 @@ void empty() {
         assertTrue(ItineraryFares.empty().isEmpty());
       }
     
    -  @Nonnull
       private static FareProduct fareProduct(String id) {
         return new FareProduct(id(id), id, Money.euros(10), null, null, null);
       }
    diff --git a/src/test/java/org/opentripplanner/routing/core/MoneyTest.java b/application/src/test/java/org/opentripplanner/routing/core/MoneyTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/core/MoneyTest.java
    rename to application/src/test/java/org/opentripplanner/routing/core/MoneyTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/core/RouteRequestTest.java b/application/src/test/java/org/opentripplanner/routing/core/RouteRequestTest.java
    similarity index 99%
    rename from src/test/java/org/opentripplanner/routing/core/RouteRequestTest.java
    rename to application/src/test/java/org/opentripplanner/routing/core/RouteRequestTest.java
    index b18c12e0485..15960c44122 100644
    --- a/src/test/java/org/opentripplanner/routing/core/RouteRequestTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/core/RouteRequestTest.java
    @@ -133,7 +133,7 @@ void testZeroSearchWindow() {
       @Test
       void testTooLongSearchWindow() {
         RouteRequest request = new RouteRequest();
    -    request.setMaxSearchWindow(DURATION_24_HOURS);
    +    request.initMaxSearchWindow(DURATION_24_HOURS);
         assertThrows(
           IllegalArgumentException.class,
           () -> request.setSearchWindow(DURATION_24_HOURS_AND_ONE_MINUTE)
    diff --git a/src/test/java/org/opentripplanner/routing/core/RoutingPreferencesTest.java b/application/src/test/java/org/opentripplanner/routing/core/RoutingPreferencesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/core/RoutingPreferencesTest.java
    rename to application/src/test/java/org/opentripplanner/routing/core/RoutingPreferencesTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/core/TemporaryVerticesContainerTest.java b/application/src/test/java/org/opentripplanner/routing/core/TemporaryVerticesContainerTest.java
    similarity index 94%
    rename from src/test/java/org/opentripplanner/routing/core/TemporaryVerticesContainerTest.java
    rename to application/src/test/java/org/opentripplanner/routing/core/TemporaryVerticesContainerTest.java
    index c01558338a4..03359143f54 100644
    --- a/src/test/java/org/opentripplanner/routing/core/TemporaryVerticesContainerTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/core/TemporaryVerticesContainerTest.java
    @@ -16,7 +16,6 @@
     import org.opentripplanner.framework.geometry.GeometryUtils;
     import org.opentripplanner.framework.geometry.SphericalDistanceLibrary;
     import org.opentripplanner.model.GenericLocation;
    -import org.opentripplanner.routing.api.request.RouteRequest;
     import org.opentripplanner.routing.api.request.StreetMode;
     import org.opentripplanner.routing.graph.Graph;
     import org.opentripplanner.street.model.StreetTraversalPermission;
    @@ -29,7 +28,7 @@
     import org.opentripplanner.street.model.vertex.Vertex;
     import org.opentripplanner.street.search.TemporaryVerticesContainer;
     import org.opentripplanner.transit.model.framework.Deduplicator;
    -import org.opentripplanner.transit.service.StopModel;
    +import org.opentripplanner.transit.service.SiteRepository;
     
     public class TemporaryVerticesContainerTest {
     
    @@ -55,18 +54,13 @@ public void setup() {
         createStreetEdge(a, b, "a -> b");
         createStreetEdge(b, a, "b -> a");
         createStreetEdge(a, c, "a -> c");
    -    g.index(new StopModel());
    +    g.index(new SiteRepository());
       }
     
       @Test
       public void temporaryChangesRemovedOnClose() {
    -    // Given - A request
    -    RouteRequest request = new RouteRequest();
    -    request.setFrom(from);
    -    request.setTo(to);
    -
         // When - the container is created
    -    subject = new TemporaryVerticesContainer(g, request, StreetMode.WALK, StreetMode.WALK);
    +    subject = new TemporaryVerticesContainer(g, from, to, StreetMode.WALK, StreetMode.WALK);
     
         // Then:
         originAndDestinationInsertedCorrect();
    diff --git a/src/test/java/org/opentripplanner/routing/core/TurnsTest.java b/application/src/test/java/org/opentripplanner/routing/core/TurnsTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/core/TurnsTest.java
    rename to application/src/test/java/org/opentripplanner/routing/core/TurnsTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/graph/DefaultRoutingServiceTest.java b/application/src/test/java/org/opentripplanner/routing/graph/DefaultRoutingServiceTest.java
    similarity index 86%
    rename from src/test/java/org/opentripplanner/routing/graph/DefaultRoutingServiceTest.java
    rename to application/src/test/java/org/opentripplanner/routing/graph/DefaultRoutingServiceTest.java
    index 8c56bb89a1f..ab897e3410b 100644
    --- a/src/test/java/org/opentripplanner/routing/graph/DefaultRoutingServiceTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/graph/DefaultRoutingServiceTest.java
    @@ -36,7 +36,7 @@ public class DefaultRoutingServiceTest extends GtfsTest {
       @Override
       public void setUp() throws Exception {
         super.setUp();
    -    transitService = new DefaultTransitService(transitModel);
    +    transitService = new DefaultTransitService(timetableRepository);
       }
     
       @Override
    @@ -56,11 +56,11 @@ public void testIdLookup() {
         }
     
         /* Agencies */
    -    String feedId = transitService.getFeedIds().iterator().next();
    +    String feedId = transitService.listFeedIds().iterator().next();
         Agency agency;
    -    agency = transitService.getAgencyForId(new FeedScopedId(feedId, "azerty"));
    +    agency = transitService.getAgency(new FeedScopedId(feedId, "azerty"));
         assertNull(agency);
    -    agency = transitService.getAgencyForId(new FeedScopedId(feedId, "agency"));
    +    agency = transitService.getAgency(new FeedScopedId(feedId, "agency"));
         assertEquals(feedId + ":" + "agency", agency.getId().toString());
         assertEquals("Fake Agency", agency.getName());
     
    @@ -79,18 +79,18 @@ public void testIdLookup() {
        */
       @Test
       public void testPatternsCoherent() {
    -    for (Trip trip : transitService.getAllTrips()) {
    -      TripPattern pattern = transitService.getPatternForTrip(trip);
    +    for (Trip trip : transitService.listTrips()) {
    +      TripPattern pattern = transitService.findPattern(trip);
           assertTrue(pattern.scheduledTripsAsStream().anyMatch(t -> t.equals(trip)));
         }
         /* This one depends on a feed where each TripPattern appears on only one route. */
    -    for (Route route : transitService.getAllRoutes()) {
    -      for (TripPattern pattern : transitService.getPatternsForRoute(route)) {
    +    for (Route route : transitService.listRoutes()) {
    +      for (TripPattern pattern : transitService.findPatterns(route)) {
             assertEquals(pattern.getRoute(), route);
           }
         }
         for (var stop : transitService.listStopLocations()) {
    -      for (TripPattern pattern : transitService.getPatternsForStop(stop)) {
    +      for (TripPattern pattern : transitService.findPatterns(stop)) {
             int stopPos = pattern.findStopPosition(stop);
             assertTrue(stopPos >= 0, "Stop position exist");
           }
    @@ -99,7 +99,7 @@ public void testPatternsCoherent() {
     
       @Test
       public void testSpatialIndex() {
    -    String feedId = transitService.getFeedIds().iterator().next();
    +    String feedId = transitService.listFeedIds().iterator().next();
         FeedScopedId idJ = new FeedScopedId(feedId, "J");
         var stopJ = transitService.getRegularStop(idJ);
         FeedScopedId idL = new FeedScopedId(feedId, "L");
    diff --git a/src/test/java/org/opentripplanner/routing/graph/EdgeTest.java b/application/src/test/java/org/opentripplanner/routing/graph/EdgeTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/graph/EdgeTest.java
    rename to application/src/test/java/org/opentripplanner/routing/graph/EdgeTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/graph/GraphSerializationTest.java b/application/src/test/java/org/opentripplanner/routing/graph/GraphSerializationTest.java
    similarity index 87%
    rename from src/test/java/org/opentripplanner/routing/graph/GraphSerializationTest.java
    rename to application/src/test/java/org/opentripplanner/routing/graph/GraphSerializationTest.java
    index f1f9ff8bfe6..400a9eba2ba 100644
    --- a/src/test/java/org/opentripplanner/routing/graph/GraphSerializationTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/graph/GraphSerializationTest.java
    @@ -23,13 +23,15 @@
     import org.opentripplanner.ext.emissions.EmissionsDataModel;
     import org.opentripplanner.framework.geometry.HashGridSpatialIndex;
     import org.opentripplanner.graph_builder.issue.api.DataImportIssueSummary;
    +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository;
    +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository;
     import org.opentripplanner.service.worldenvelope.WorldEnvelopeRepository;
     import org.opentripplanner.service.worldenvelope.internal.DefaultWorldEnvelopeRepository;
     import org.opentripplanner.standalone.config.BuildConfig;
     import org.opentripplanner.standalone.config.RouterConfig;
     import org.opentripplanner.street.model.StreetLimitationParameters;
     import org.opentripplanner.transit.model.framework.Deduplicator;
    -import org.opentripplanner.transit.service.TransitModel;
    +import org.opentripplanner.transit.service.TimetableRepository;
     
     /**
      * Tests that saving a graph and reloading it (round trip through serialization and deserialization)
    @@ -67,7 +69,14 @@ public void testRoundTripSerializationForGTFSGraph() throws Exception {
         TestOtpModel model = ConstantsForTests.buildNewPortlandGraph(true);
         var weRepo = new DefaultWorldEnvelopeRepository();
         var emissionsDataModel = new EmissionsDataModel();
    -    testRoundTrip(model.graph(), model.transitModel(), weRepo, emissionsDataModel);
    +    var parkingRepository = new DefaultVehicleParkingRepository();
    +    testRoundTrip(
    +      model.graph(),
    +      model.timetableRepository(),
    +      weRepo,
    +      parkingRepository,
    +      emissionsDataModel
    +    );
       }
     
       /**
    @@ -78,7 +87,14 @@ public void testRoundTripSerializationForNetexGraph() throws Exception {
         TestOtpModel model = ConstantsForTests.buildNewMinimalNetexGraph();
         var worldEnvelopeRepository = new DefaultWorldEnvelopeRepository();
         var emissionsDataModel = new EmissionsDataModel();
    -    testRoundTrip(model.graph(), model.transitModel(), worldEnvelopeRepository, emissionsDataModel);
    +    var parkingRepository = new DefaultVehicleParkingRepository();
    +    testRoundTrip(
    +      model.graph(),
    +      model.timetableRepository(),
    +      worldEnvelopeRepository,
    +      parkingRepository,
    +      emissionsDataModel
    +    );
       }
     
       // Ideally we'd also test comparing two separate but identical complex graphs, built separately from the same inputs.
    @@ -175,8 +191,9 @@ private static void assertNoDifferences(Graph g1, Graph g2) {
        */
       private void testRoundTrip(
         Graph originalGraph,
    -    TransitModel originalTransitModel,
    +    TimetableRepository originalTimetableRepository,
         WorldEnvelopeRepository worldEnvelopeRepository,
    +    VehicleParkingRepository vehicleParkingRepository,
         EmissionsDataModel emissionsDataModel
       ) throws Exception {
         // Now round-trip the graph through serialization.
    @@ -185,8 +202,9 @@ private void testRoundTrip(
         streetLimitationParameters.initMaxCarSpeed(40);
         SerializedGraphObject serializedObj = new SerializedGraphObject(
           originalGraph,
    -      originalTransitModel,
    +      originalTimetableRepository,
           worldEnvelopeRepository,
    +      vehicleParkingRepository,
           BuildConfig.DEFAULT,
           RouterConfig.DEFAULT,
           DataImportIssueSummary.empty(),
    @@ -197,23 +215,23 @@ private void testRoundTrip(
         serializedObj.save(new FileDataSource(tempFile, FileType.GRAPH));
         SerializedGraphObject deserializedGraph = SerializedGraphObject.load(tempFile);
         Graph copiedGraph1 = deserializedGraph.graph;
    -    TransitModel copiedTransitModel1 = deserializedGraph.transitModel;
    +    TimetableRepository copiedTimetableRepository1 = deserializedGraph.timetableRepository;
         // Index both graph - we do no know if the original is indexed, because it is cached and
         // might be indexed by other tests.
     
    -    originalTransitModel.index();
    -    originalGraph.index(originalTransitModel.getStopModel());
    +    originalTimetableRepository.index();
    +    originalGraph.index(originalTimetableRepository.getSiteRepository());
     
    -    copiedTransitModel1.index();
    -    copiedGraph1.index(copiedTransitModel1.getStopModel());
    +    copiedTimetableRepository1.index();
    +    copiedGraph1.index(copiedTimetableRepository1.getSiteRepository());
     
         assertNoDifferences(originalGraph, copiedGraph1);
     
         SerializedGraphObject deserializedGraph2 = SerializedGraphObject.load(tempFile);
         Graph copiedGraph2 = deserializedGraph2.graph;
    -    TransitModel copiedTransitModel2 = deserializedGraph2.transitModel;
    -    copiedTransitModel2.index();
    -    copiedGraph2.index(copiedTransitModel2.getStopModel());
    +    TimetableRepository copiedTimetableRepository2 = deserializedGraph2.timetableRepository;
    +    copiedTimetableRepository2.index();
    +    copiedGraph2.index(copiedTimetableRepository2.getSiteRepository());
         assertNoDifferences(copiedGraph1, copiedGraph2);
       }
     }
    diff --git a/src/test/java/org/opentripplanner/routing/graph/SimpleConcreteEdge.java b/application/src/test/java/org/opentripplanner/routing/graph/SimpleConcreteEdge.java
    similarity index 96%
    rename from src/test/java/org/opentripplanner/routing/graph/SimpleConcreteEdge.java
    rename to application/src/test/java/org/opentripplanner/routing/graph/SimpleConcreteEdge.java
    index 0a3fccccda7..f36300de9ef 100644
    --- a/src/test/java/org/opentripplanner/routing/graph/SimpleConcreteEdge.java
    +++ b/application/src/test/java/org/opentripplanner/routing/graph/SimpleConcreteEdge.java
    @@ -1,6 +1,5 @@
     package org.opentripplanner.routing.graph;
     
    -import javax.annotation.Nonnull;
     import org.locationtech.jts.geom.LineString;
     import org.opentripplanner.framework.geometry.SphericalDistanceLibrary;
     import org.opentripplanner.framework.i18n.I18NString;
    @@ -24,7 +23,6 @@ public static SimpleConcreteEdge createSimpleConcreteEdge(Vertex v1, Vertex v2)
       }
     
       @Override
    -  @Nonnull
       public State[] traverse(State s0) {
         double d = getDistanceMeters();
         TraverseMode mode = s0.currentMode();
    diff --git a/src/test/java/org/opentripplanner/routing/graph/TemporaryConcreteEdge.java b/application/src/test/java/org/opentripplanner/routing/graph/TemporaryConcreteEdge.java
    similarity index 97%
    rename from src/test/java/org/opentripplanner/routing/graph/TemporaryConcreteEdge.java
    rename to application/src/test/java/org/opentripplanner/routing/graph/TemporaryConcreteEdge.java
    index 44f6b6f7298..19020fc3f4f 100644
    --- a/src/test/java/org/opentripplanner/routing/graph/TemporaryConcreteEdge.java
    +++ b/application/src/test/java/org/opentripplanner/routing/graph/TemporaryConcreteEdge.java
    @@ -1,6 +1,5 @@
     package org.opentripplanner.routing.graph;
     
    -import javax.annotation.Nonnull;
     import org.opentripplanner.framework.geometry.SphericalDistanceLibrary;
     import org.opentripplanner.framework.i18n.I18NString;
     import org.opentripplanner.street.model.edge.Edge;
    @@ -36,7 +35,6 @@ public static TemporaryConcreteEdge createTemporaryConcreteEdge(Vertex v1, Tempo
       }
     
       @Override
    -  @Nonnull
       public State[] traverse(State s0) {
         double d = getDistanceMeters();
         TraverseMode mode = s0.currentMode();
    diff --git a/src/test/java/org/opentripplanner/routing/graphfinder/DirectGraphFinderTest.java b/application/src/test/java/org/opentripplanner/routing/graphfinder/DirectGraphFinderTest.java
    similarity index 83%
    rename from src/test/java/org/opentripplanner/routing/graphfinder/DirectGraphFinderTest.java
    rename to application/src/test/java/org/opentripplanner/routing/graphfinder/DirectGraphFinderTest.java
    index cb439a9cea3..215bd317335 100644
    --- a/src/test/java/org/opentripplanner/routing/graphfinder/DirectGraphFinderTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/graphfinder/DirectGraphFinderTest.java
    @@ -9,11 +9,11 @@
     import org.opentripplanner.TestOtpModel;
     import org.opentripplanner.routing.algorithm.GraphRoutingTest;
     import org.opentripplanner.street.model.vertex.TransitStopVertex;
    -import org.opentripplanner.transit.service.StopModel;
    +import org.opentripplanner.transit.service.SiteRepository;
     
     class DirectGraphFinderTest extends GraphRoutingTest {
     
    -  private StopModel stopModel;
    +  private SiteRepository siteRepository;
     
       private TransitStopVertex S1, S2, S3;
     
    @@ -29,7 +29,7 @@ public void build() {
             }
           }
         );
    -    stopModel = model.transitModel().getStopModel();
    +    siteRepository = model.timetableRepository().getSiteRepository();
       }
     
       @Test
    @@ -37,7 +37,7 @@ void findClosestStops() {
         var ns1 = new NearbyStop(S1.getStop(), 0, null, null);
         var ns2 = new NearbyStop(S2.getStop(), 1112, null, null);
     
    -    var subject = new DirectGraphFinder(stopModel::findRegularStops);
    +    var subject = new DirectGraphFinder(siteRepository::findRegularStops);
         var coordinate = new Coordinate(19.000, 47.500);
         assertEquals(List.of(ns1), subject.findClosestStops(coordinate, 100));
     
    diff --git a/src/test/java/org/opentripplanner/routing/graphfinder/NearbyStopTest.java b/application/src/test/java/org/opentripplanner/routing/graphfinder/NearbyStopTest.java
    similarity index 84%
    rename from src/test/java/org/opentripplanner/routing/graphfinder/NearbyStopTest.java
    rename to application/src/test/java/org/opentripplanner/routing/graphfinder/NearbyStopTest.java
    index a81d7c39c5e..6f5fe5c3760 100644
    --- a/src/test/java/org/opentripplanner/routing/graphfinder/NearbyStopTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/graphfinder/NearbyStopTest.java
    @@ -4,11 +4,11 @@
     import static org.junit.jupiter.api.Assertions.assertTrue;
     
     import org.junit.jupiter.api.Test;
    -import org.opentripplanner.transit.model._data.TransitModelForTest;
    +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
     
     class NearbyStopTest {
     
    -  private static TransitModelForTest MODEL = TransitModelForTest.of();
    +  private static TimetableRepositoryForTest MODEL = TimetableRepositoryForTest.of();
     
       // TODO Add tests for all public methods in NearbyStop here
     
    diff --git a/src/test/java/org/opentripplanner/routing/graphfinder/PlaceFinderTraverseVisitorTest.java b/application/src/test/java/org/opentripplanner/routing/graphfinder/PlaceFinderTraverseVisitorTest.java
    similarity index 94%
    rename from src/test/java/org/opentripplanner/routing/graphfinder/PlaceFinderTraverseVisitorTest.java
    rename to application/src/test/java/org/opentripplanner/routing/graphfinder/PlaceFinderTraverseVisitorTest.java
    index b69a6533334..95ad1aa316e 100644
    --- a/src/test/java/org/opentripplanner/routing/graphfinder/PlaceFinderTraverseVisitorTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/graphfinder/PlaceFinderTraverseVisitorTest.java
    @@ -4,9 +4,9 @@
     import static org.opentripplanner.model.plan.PlanTestConstants.T11_00;
     import static org.opentripplanner.model.plan.PlanTestConstants.T11_05;
     import static org.opentripplanner.model.plan.PlanTestConstants.T11_10;
    -import static org.opentripplanner.transit.model._data.TransitModelForTest.id;
    -import static org.opentripplanner.transit.model._data.TransitModelForTest.route;
    -import static org.opentripplanner.transit.model._data.TransitModelForTest.tripPattern;
    +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id;
    +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.route;
    +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.tripPattern;
     
     import java.util.List;
     import org.junit.jupiter.api.Test;
    @@ -15,7 +15,7 @@
     import org.opentripplanner.model.StopTime;
     import org.opentripplanner.service.vehiclerental.model.TestVehicleRentalStationBuilder;
     import org.opentripplanner.street.search.state.TestStateBuilder;
    -import org.opentripplanner.transit.model._data.TransitModelForTest;
    +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
     import org.opentripplanner.transit.model.basic.TransitMode;
     import org.opentripplanner.transit.model.network.Route;
     import org.opentripplanner.transit.model.network.StopPattern;
    @@ -23,11 +23,11 @@
     import org.opentripplanner.transit.model.site.RegularStop;
     import org.opentripplanner.transit.model.site.Station;
     import org.opentripplanner.transit.service.DefaultTransitService;
    -import org.opentripplanner.transit.service.TransitModel;
    +import org.opentripplanner.transit.service.TimetableRepository;
     
     public class PlaceFinderTraverseVisitorTest {
     
    -  static TransitModelForTest model = TransitModelForTest.of();
    +  static TimetableRepositoryForTest model = TimetableRepositoryForTest.of();
       static final Station STATION1 = Station
         .of(id("S1"))
         .withName(new NonLocalizedString("Station 1"))
    @@ -55,7 +55,7 @@ public class PlaceFinderTraverseVisitorTest {
     
       static final Route r = route("r").build();
     
    -  static TransitModel a = new TransitModel();
    +  static TimetableRepository a = new TimetableRepository();
     
       static {
         a.addTransitMode(TransitMode.BUS);
    diff --git a/src/test/java/org/opentripplanner/routing/graphfinder/StopFinderTraverseVisitorTest.java b/application/src/test/java/org/opentripplanner/routing/graphfinder/StopFinderTraverseVisitorTest.java
    similarity index 87%
    rename from src/test/java/org/opentripplanner/routing/graphfinder/StopFinderTraverseVisitorTest.java
    rename to application/src/test/java/org/opentripplanner/routing/graphfinder/StopFinderTraverseVisitorTest.java
    index 428e476babd..92bafe8e36b 100644
    --- a/src/test/java/org/opentripplanner/routing/graphfinder/StopFinderTraverseVisitorTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/graphfinder/StopFinderTraverseVisitorTest.java
    @@ -6,12 +6,12 @@
     import org.junit.jupiter.api.Test;
     import org.opentripplanner.street.model.vertex.TransitStopVertex;
     import org.opentripplanner.street.search.state.TestStateBuilder;
    -import org.opentripplanner.transit.model._data.TransitModelForTest;
    +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
     import org.opentripplanner.transit.model.site.RegularStop;
     
     class StopFinderTraverseVisitorTest {
     
    -  static final RegularStop STOP = TransitModelForTest.of().stop("a-stop", 1, 1).build();
    +  static final RegularStop STOP = TimetableRepositoryForTest.of().stop("a-stop", 1, 1).build();
     
       @Test
       void deduplicateStops() {
    diff --git a/src/test/java/org/opentripplanner/routing/graphfinder/StreetGraphFinderTest.java b/application/src/test/java/org/opentripplanner/routing/graphfinder/StreetGraphFinderTest.java
    similarity index 96%
    rename from src/test/java/org/opentripplanner/routing/graphfinder/StreetGraphFinderTest.java
    rename to application/src/test/java/org/opentripplanner/routing/graphfinder/StreetGraphFinderTest.java
    index 76f231577dd..2c787bc682c 100644
    --- a/src/test/java/org/opentripplanner/routing/graphfinder/StreetGraphFinderTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/graphfinder/StreetGraphFinderTest.java
    @@ -8,12 +8,12 @@
     import org.junit.jupiter.api.Test;
     import org.locationtech.jts.geom.Coordinate;
     import org.opentripplanner.routing.algorithm.GraphRoutingTest;
    -import org.opentripplanner.routing.vehicle_parking.VehicleParking;
    +import org.opentripplanner.service.vehicleparking.model.VehicleParking;
     import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex;
     import org.opentripplanner.street.model.StreetTraversalPermission;
     import org.opentripplanner.street.model.vertex.IntersectionVertex;
     import org.opentripplanner.street.model.vertex.TransitStopVertex;
    -import org.opentripplanner.transit.model._data.TransitModelForTest;
    +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
     import org.opentripplanner.transit.model.basic.TransitMode;
     import org.opentripplanner.transit.model.network.Route;
     import org.opentripplanner.transit.model.network.StopPattern;
    @@ -39,7 +39,7 @@ protected void setUp() throws Exception {
           new Builder() {
             @Override
             public void build() {
    -          var a = TransitModelForTest.agency("Agency");
    +          var a = TimetableRepositoryForTest.agency("Agency");
     
               R1 = route("R1", TransitMode.BUS, a);
               R2 = route("R2", TransitMode.TRAM, a);
    @@ -99,7 +99,7 @@ public void build() {
               tripPattern(
                 TP1 =
                   TripPattern
    -                .of(TransitModelForTest.id("TP1"))
    +                .of(TimetableRepositoryForTest.id("TP1"))
                     .withRoute(R1)
                     .withStopPattern(new StopPattern(List.of(st(S1), st(S2))))
                     .build()
    @@ -107,7 +107,7 @@ public void build() {
               tripPattern(
                 TP2 =
                   TripPattern
    -                .of(TransitModelForTest.id("TP2"))
    +                .of(TimetableRepositoryForTest.id("TP2"))
                     .withRoute(R2)
                     .withStopPattern(new StopPattern(List.of(st(S1), st(S3))))
                     .build()
    @@ -116,7 +116,7 @@ public void build() {
           }
         );
     
    -    transitService = new DefaultTransitService(otpModel.transitModel());
    +    transitService = new DefaultTransitService(otpModel.timetableRepository());
         graphFinder = new StreetGraphFinder(otpModel.graph());
       }
     
    diff --git a/src/test/java/org/opentripplanner/routing/linking/LinkStopToPlatformTest.java b/application/src/test/java/org/opentripplanner/routing/linking/LinkStopToPlatformTest.java
    similarity index 95%
    rename from src/test/java/org/opentripplanner/routing/linking/LinkStopToPlatformTest.java
    rename to application/src/test/java/org/opentripplanner/routing/linking/LinkStopToPlatformTest.java
    index 23607d2e0b3..e37ced70721 100644
    --- a/src/test/java/org/opentripplanner/routing/linking/LinkStopToPlatformTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/linking/LinkStopToPlatformTest.java
    @@ -29,11 +29,11 @@
     import org.opentripplanner.street.model.vertex.Vertex;
     import org.opentripplanner.street.search.TraverseMode;
     import org.opentripplanner.street.search.TraverseModeSet;
    -import org.opentripplanner.transit.model._data.TransitModelForTest;
    +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
     import org.opentripplanner.transit.model.framework.Deduplicator;
     import org.opentripplanner.transit.model.site.RegularStop;
    -import org.opentripplanner.transit.service.StopModel;
    -import org.opentripplanner.transit.service.TransitModel;
    +import org.opentripplanner.transit.service.SiteRepository;
    +import org.opentripplanner.transit.service.TimetableRepository;
     import org.slf4j.Logger;
     import org.slf4j.LoggerFactory;
     
    @@ -41,13 +41,13 @@ public class LinkStopToPlatformTest {
     
       private static final Logger LOG = LoggerFactory.getLogger(LinkStopToPlatformTest.class);
       private static final GeometryFactory geometryFactory = GeometryUtils.getGeometryFactory();
    -  private final TransitModelForTest testModel = TransitModelForTest.of();
    +  private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of();
     
       private Graph prepareTest(Coordinate[] platform, int[] visible, Coordinate[] stops) {
         var deduplicator = new Deduplicator();
    -    var stopModel = new StopModel();
    +    var siteRepository = new SiteRepository();
         Graph graph = new Graph(deduplicator);
    -    var transitModel = new TransitModel(stopModel, deduplicator);
    +    var timetableRepository = new TimetableRepository(siteRepository, deduplicator);
         ArrayList vertices = new ArrayList<>();
         Coordinate[] closedGeom = new Coordinate[platform.length + 1];
     
    @@ -106,8 +106,8 @@ private Graph prepareTest(Coordinate[] platform, int[] visible, Coordinate[] sto
           transitStops[i] = testModel.stop("TestStop " + i).withCoordinate(stop.y, stop.x).build();
         }
     
    -    transitModel.index();
    -    graph.index(transitModel.getStopModel());
    +    timetableRepository.index();
    +    graph.index(timetableRepository.getSiteRepository());
     
         for (RegularStop s : transitStops) {
           var v = TransitStopVertex.of().withStop(s).build();
    diff --git a/src/test/java/org/opentripplanner/routing/stoptimes/AlternativeLegsTest.java b/application/src/test/java/org/opentripplanner/routing/stoptimes/AlternativeLegsTest.java
    similarity index 80%
    rename from src/test/java/org/opentripplanner/routing/stoptimes/AlternativeLegsTest.java
    rename to application/src/test/java/org/opentripplanner/routing/stoptimes/AlternativeLegsTest.java
    index fde87776909..65e99825a9e 100644
    --- a/src/test/java/org/opentripplanner/routing/stoptimes/AlternativeLegsTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/stoptimes/AlternativeLegsTest.java
    @@ -12,6 +12,7 @@
     import org.opentripplanner.model.plan.legreference.ScheduledTransitLegReference;
     import org.opentripplanner.routing.alternativelegs.AlternativeLegs;
     import org.opentripplanner.routing.alternativelegs.AlternativeLegsFilter;
    +import org.opentripplanner.routing.alternativelegs.NavigationDirection;
     import org.opentripplanner.transit.model.framework.FeedScopedId;
     import org.opentripplanner.transit.service.DefaultTransitService;
     
    @@ -34,7 +35,7 @@ public String getFeedName() {
     
       @Test
       void testPreviousLegs() {
    -    var transitService = new DefaultTransitService(transitModel);
    +    var transitService = new DefaultTransitService(timetableRepository);
     
         var originalLeg = new ScheduledTransitLegReference(
           new FeedScopedId(this.feedId.getId(), "1.2"),
    @@ -51,13 +52,11 @@ void testPreviousLegs() {
           originalLeg,
           3,
           transitService,
    -      true,
    +      NavigationDirection.PREVIOUS,
           AlternativeLegsFilter.NO_FILTER
         );
     
    -    var legs = Itinerary.toStr(
    -      alternativeLegs.stream().map(Leg.class::cast).map(List::of).map(Itinerary::new).toList()
    -    );
    +    var legs = toString(alternativeLegs);
     
         var expected =
           "B ~ BUS 2 0:20 0:30 ~ C [C₁-1], " +
    @@ -70,7 +69,7 @@ void testPreviousLegs() {
     
       @Test
       void testNextLegs() {
    -    var transitService = new DefaultTransitService(transitModel);
    +    var transitService = new DefaultTransitService(timetableRepository);
     
         var originalLeg = new ScheduledTransitLegReference(
           new FeedScopedId(this.feedId.getId(), "2.2"),
    @@ -87,13 +86,11 @@ void testNextLegs() {
           originalLeg,
           3,
           transitService,
    -      false,
    +      NavigationDirection.NEXT,
           AlternativeLegsFilter.NO_FILTER
         );
     
    -    var legs = Itinerary.toStr(
    -      alternativeLegs.stream().map(Leg.class::cast).map(List::of).map(Itinerary::new).toList()
    -    );
    +    var legs = toString(alternativeLegs);
     
         var expected =
           "B ~ BUS 3 1:00 1:10 ~ C [C₁-1], " +
    @@ -106,7 +103,7 @@ void testNextLegs() {
     
       @Test
       void testCircularRoutes() {
    -    var transitService = new DefaultTransitService(transitModel);
    +    var transitService = new DefaultTransitService(timetableRepository);
     
         var originalLeg = new ScheduledTransitLegReference(
           new FeedScopedId(this.feedId.getId(), "19.1"),
    @@ -123,19 +120,18 @@ void testCircularRoutes() {
           originalLeg,
           2,
           transitService,
    -      false,
    +      NavigationDirection.NEXT,
           AlternativeLegsFilter.NO_FILTER
         );
    -    var legs = Itinerary.toStr(
    -      alternativeLegs.stream().map(Leg.class::cast).map(List::of).map(Itinerary::new).toList()
    -    );
    +
    +    var legs = toString(alternativeLegs);
     
         assertEquals("X ~ BUS 19 10:30 10:40 ~ Y [C₁-1], X ~ BUS 19 10:00 10:10 ~ Y [C₁-1]", legs);
       }
     
       @Test
       void testComplexCircularRoutes() {
    -    var transitService = new DefaultTransitService(transitModel);
    +    var transitService = new DefaultTransitService(timetableRepository);
     
         var originalLeg = new ScheduledTransitLegReference(
           new FeedScopedId(this.feedId.getId(), "19.1"),
    @@ -152,14 +148,23 @@ void testComplexCircularRoutes() {
           originalLeg,
           2,
           transitService,
    -      false,
    +      NavigationDirection.NEXT,
           AlternativeLegsFilter.NO_FILTER
         );
    -    var legs = Itinerary.toStr(
    -      alternativeLegs.stream().map(Leg.class::cast).map(List::of).map(Itinerary::new).toList()
    -    );
    +    var legs = toString(alternativeLegs);
     
         var expected = String.join(", ", List.of("X ~ BUS 19 10:30 11:00 ~ B [C₁-1]"));
         assertEquals(expected, legs);
       }
    +
    +  private static String toString(List alternativeLegs) {
    +    return Itinerary.toStr(
    +      alternativeLegs
    +        .stream()
    +        .map(Leg.class::cast)
    +        .map(List::of)
    +        .map(Itinerary::createScheduledTransitItinerary)
    +        .toList()
    +    );
    +  }
     }
    diff --git a/src/test/java/org/opentripplanner/routing/stoptimes/StopTimesHelperTest.java b/application/src/test/java/org/opentripplanner/routing/stoptimes/StopTimesHelperTest.java
    similarity index 91%
    rename from src/test/java/org/opentripplanner/routing/stoptimes/StopTimesHelperTest.java
    rename to application/src/test/java/org/opentripplanner/routing/stoptimes/StopTimesHelperTest.java
    index 1432c68fd49..52ddaf86d91 100644
    --- a/src/test/java/org/opentripplanner/routing/stoptimes/StopTimesHelperTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/stoptimes/StopTimesHelperTest.java
    @@ -16,7 +16,7 @@
     import org.opentripplanner.transit.model.framework.FeedScopedId;
     import org.opentripplanner.transit.model.network.TripPattern;
     import org.opentripplanner.transit.service.DefaultTransitService;
    -import org.opentripplanner.transit.service.TransitModel;
    +import org.opentripplanner.transit.service.TimetableRepository;
     
     class StopTimesHelperTest {
     
    @@ -29,18 +29,25 @@ class StopTimesHelperTest {
       @BeforeAll
       public static void setUp() throws Exception {
         TestOtpModel model = ConstantsForTests.buildGtfsGraph(ConstantsForTests.SIMPLE_GTFS);
    -    TransitModel transitModel = model.transitModel();
    -    transitService = new DefaultTransitService(transitModel);
    -    feedId = transitModel.getFeedIds().iterator().next();
    +    TimetableRepository timetableRepository = model.timetableRepository();
    +    transitService = new DefaultTransitService(timetableRepository);
    +    feedId = timetableRepository.getFeedIds().iterator().next();
         stopId = new FeedScopedId(feedId, "J");
    -    pattern =
    -      transitService.getPatternForTrip(
    -        transitService.getTripForId(new FeedScopedId(feedId, "5.1"))
    -      );
    -    var tt = transitService.getTimetableForTripPattern(pattern, LocalDate.now());
    +    var originalPattern = transitService.findPattern(
    +      transitService.getTrip(new FeedScopedId(feedId, "5.1"))
    +    );
    +    var tt = originalPattern.getScheduledTimetable();
         var newTripTimes = tt.getTripTimes(0).copyScheduledTimes();
         newTripTimes.cancelTrip();
    -    tt.setTripTimes(0, newTripTimes);
    +    pattern =
    +      originalPattern
    +        .copy()
    +        .withScheduledTimeTableBuilder(builder -> builder.addOrUpdateTripTimes(newTripTimes))
    +        .build();
    +    // replace the original pattern by the updated pattern in the transit model
    +    timetableRepository.addTripPattern(pattern.getId(), pattern);
    +    timetableRepository.index();
    +    transitService = new DefaultTransitService(timetableRepository);
       }
     
       /**
    diff --git a/src/test/java/org/opentripplanner/routing/trippattern/DeduplicatorTest.java b/application/src/test/java/org/opentripplanner/routing/trippattern/DeduplicatorTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/trippattern/DeduplicatorTest.java
    rename to application/src/test/java/org/opentripplanner/routing/trippattern/DeduplicatorTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/trippattern/FrequencyEntryTest.java b/application/src/test/java/org/opentripplanner/routing/trippattern/FrequencyEntryTest.java
    similarity index 93%
    rename from src/test/java/org/opentripplanner/routing/trippattern/FrequencyEntryTest.java
    rename to application/src/test/java/org/opentripplanner/routing/trippattern/FrequencyEntryTest.java
    index 49ca6d9221b..130438eb75b 100644
    --- a/src/test/java/org/opentripplanner/routing/trippattern/FrequencyEntryTest.java
    +++ b/application/src/test/java/org/opentripplanner/routing/trippattern/FrequencyEntryTest.java
    @@ -7,7 +7,7 @@
     import org.junit.jupiter.api.Test;
     import org.opentripplanner.model.Frequency;
     import org.opentripplanner.model.StopTime;
    -import org.opentripplanner.transit.model._data.TransitModelForTest;
    +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
     import org.opentripplanner.transit.model.framework.Deduplicator;
     import org.opentripplanner.transit.model.framework.FeedScopedId;
     import org.opentripplanner.transit.model.site.RegularStop;
    @@ -22,15 +22,15 @@ public class FrequencyEntryTest {
       private static final TripTimes tripTimes;
     
       static {
    -    Trip trip = TransitModelForTest.trip("testtrip").build();
    +    Trip trip = TimetableRepositoryForTest.trip("testtrip").build();
     
         List stopTimes = new ArrayList<>();
     
         int time = 0;
         for (int i = 0; i < STOP_NUM; ++i) {
    -      FeedScopedId id = TransitModelForTest.id(i + "");
    +      FeedScopedId id = TimetableRepositoryForTest.id(i + "");
     
    -      RegularStop stop = TransitModelForTest.of().stop(id.getId(), 0.0, 0.0).build();
    +      RegularStop stop = TimetableRepositoryForTest.of().stop(id.getId(), 0.0, 0.0).build();
     
           StopTime stopTime = new StopTime();
           stopTime.setStop(stop);
    diff --git a/src/test/java/org/opentripplanner/routing/util/DiffToolTest.java b/application/src/test/java/org/opentripplanner/routing/util/DiffToolTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/util/DiffToolTest.java
    rename to application/src/test/java/org/opentripplanner/routing/util/DiffToolTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/util/FastDistanceTest.java b/application/src/test/java/org/opentripplanner/routing/util/FastDistanceTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/util/FastDistanceTest.java
    rename to application/src/test/java/org/opentripplanner/routing/util/FastDistanceTest.java
    diff --git a/src/test/java/org/opentripplanner/routing/util/TestElevationUtils.java b/application/src/test/java/org/opentripplanner/routing/util/TestElevationUtils.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/util/TestElevationUtils.java
    rename to application/src/test/java/org/opentripplanner/routing/util/TestElevationUtils.java
    diff --git a/src/test/java/org/opentripplanner/routing/util/elevation/ToblersHikingFunctionTest.java b/application/src/test/java/org/opentripplanner/routing/util/elevation/ToblersHikingFunctionTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/routing/util/elevation/ToblersHikingFunctionTest.java
    rename to application/src/test/java/org/opentripplanner/routing/util/elevation/ToblersHikingFunctionTest.java
    diff --git a/src/test/java/org/opentripplanner/service/paging/PS1_LegacyMetaDataTest.java b/application/src/test/java/org/opentripplanner/service/paging/PS1_LegacyMetaDataTest.java
    similarity index 98%
    rename from src/test/java/org/opentripplanner/service/paging/PS1_LegacyMetaDataTest.java
    rename to application/src/test/java/org/opentripplanner/service/paging/PS1_LegacyMetaDataTest.java
    index 609607d84ff..e87e2a5e406 100644
    --- a/src/test/java/org/opentripplanner/service/paging/PS1_LegacyMetaDataTest.java
    +++ b/application/src/test/java/org/opentripplanner/service/paging/PS1_LegacyMetaDataTest.java
    @@ -5,7 +5,7 @@
     
     import java.time.Duration;
     import org.junit.jupiter.api.Test;
    -import org.opentripplanner.framework.time.TimeUtils;
    +import org.opentripplanner.utils.time.TimeUtils;
     
     /**
      * This tests the entire paging service module.
    diff --git a/src/test/java/org/opentripplanner/service/paging/PS2_ManyParetoOptimalItinerariesTest.java b/application/src/test/java/org/opentripplanner/service/paging/PS2_ManyParetoOptimalItinerariesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/service/paging/PS2_ManyParetoOptimalItinerariesTest.java
    rename to application/src/test/java/org/opentripplanner/service/paging/PS2_ManyParetoOptimalItinerariesTest.java
    diff --git a/src/test/java/org/opentripplanner/service/paging/PS3_FewItinerariesOnSearchWindowLimitTest.java b/application/src/test/java/org/opentripplanner/service/paging/PS3_FewItinerariesOnSearchWindowLimitTest.java
    similarity index 99%
    rename from src/test/java/org/opentripplanner/service/paging/PS3_FewItinerariesOnSearchWindowLimitTest.java
    rename to application/src/test/java/org/opentripplanner/service/paging/PS3_FewItinerariesOnSearchWindowLimitTest.java
    index 4db61579a47..fffcf93e5fb 100644
    --- a/src/test/java/org/opentripplanner/service/paging/PS3_FewItinerariesOnSearchWindowLimitTest.java
    +++ b/application/src/test/java/org/opentripplanner/service/paging/PS3_FewItinerariesOnSearchWindowLimitTest.java
    @@ -11,12 +11,12 @@
     import org.junit.jupiter.params.ParameterizedTest;
     import org.junit.jupiter.params.provider.Arguments;
     import org.junit.jupiter.params.provider.MethodSource;
    -import org.opentripplanner.framework.time.TimeUtils;
     import org.opentripplanner.model.plan.Itinerary;
     import org.opentripplanner.model.plan.ItinerarySortKey;
     import org.opentripplanner.model.plan.SortOrder;
     import org.opentripplanner.model.plan.paging.cursor.PageCursor;
     import org.opentripplanner.model.plan.paging.cursor.PageType;
    +import org.opentripplanner.utils.time.TimeUtils;
     
     /**
      * This test focus on testing the paging with few itineraries. There should be no page-cuts. The
    diff --git a/src/test/java/org/opentripplanner/service/paging/TestDriver.java b/application/src/test/java/org/opentripplanner/service/paging/TestDriver.java
    similarity index 97%
    rename from src/test/java/org/opentripplanner/service/paging/TestDriver.java
    rename to application/src/test/java/org/opentripplanner/service/paging/TestDriver.java
    index 928fbaaf01d..e5cbb02012d 100644
    --- a/src/test/java/org/opentripplanner/service/paging/TestDriver.java
    +++ b/application/src/test/java/org/opentripplanner/service/paging/TestDriver.java
    @@ -5,8 +5,6 @@
     import java.util.List;
     import javax.annotation.Nullable;
     import org.opentripplanner._support.debug.TestDebug;
    -import org.opentripplanner.framework.collection.ListSection;
    -import org.opentripplanner.framework.lang.Box;
     import org.opentripplanner.model.plan.Itinerary;
     import org.opentripplanner.model.plan.ItinerarySortKey;
     import org.opentripplanner.model.plan.SortOrder;
    @@ -15,6 +13,8 @@
     import org.opentripplanner.routing.algorithm.filterchain.filters.system.NumItinerariesFilter;
     import org.opentripplanner.routing.algorithm.filterchain.filters.system.OutsideSearchWindowFilter;
     import org.opentripplanner.routing.algorithm.filterchain.filters.system.PagingFilter;
    +import org.opentripplanner.utils.collection.ListSection;
    +import org.opentripplanner.utils.lang.Box;
     
     /**
      * This class simulate/mock the context the paging is operating in.
    diff --git a/src/test/java/org/opentripplanner/service/paging/TestPagingModel.java b/application/src/test/java/org/opentripplanner/service/paging/TestPagingModel.java
    similarity index 96%
    rename from src/test/java/org/opentripplanner/service/paging/TestPagingModel.java
    rename to application/src/test/java/org/opentripplanner/service/paging/TestPagingModel.java
    index 938a201576f..9a30b5e8a90 100644
    --- a/src/test/java/org/opentripplanner/service/paging/TestPagingModel.java
    +++ b/application/src/test/java/org/opentripplanner/service/paging/TestPagingModel.java
    @@ -1,20 +1,20 @@
     package org.opentripplanner.service.paging;
     
    -import static org.opentripplanner.framework.time.TimeUtils.hm2time;
     import static org.opentripplanner.model.plan.SortOrder.STREET_AND_ARRIVAL_TIME;
     import static org.opentripplanner.model.plan.SortOrder.STREET_AND_DEPARTURE_TIME;
    +import static org.opentripplanner.utils.time.TimeUtils.hm2time;
     
     import java.time.Duration;
     import java.time.Instant;
     import java.util.List;
    -import org.opentripplanner.framework.time.TimeUtils;
     import org.opentripplanner.model.plan.Itinerary;
     import org.opentripplanner.model.plan.Place;
     import org.opentripplanner.model.plan.SortOrder;
     import org.opentripplanner.model.plan.TestItineraryBuilder;
     import org.opentripplanner.model.plan.paging.cursor.PageCursor;
     import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator;
    -import org.opentripplanner.transit.model._data.TransitModelForTest;
    +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
    +import org.opentripplanner.utils.time.TimeUtils;
     
     class TestPagingModel {
     
    @@ -54,7 +54,7 @@ class TestPagingModel {
     
       private static final Instant TRANSIT_START_TIME = TestItineraryBuilder.newTime(0).toInstant();
     
    -  private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of();
    +  private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of();
       private static final Place A = Place.forStop(TEST_MODEL.stop("A").build());
       private static final Place B = Place.forStop(TEST_MODEL.stop("B").build());
     
    diff --git a/src/test/java/org/opentripplanner/service/paging/TestPagingUtils.java b/application/src/test/java/org/opentripplanner/service/paging/TestPagingUtils.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/service/paging/TestPagingUtils.java
    rename to application/src/test/java/org/opentripplanner/service/paging/TestPagingUtils.java
    diff --git a/src/test/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleServiceTest.java b/application/src/test/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleServiceTest.java
    similarity index 69%
    rename from src/test/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleServiceTest.java
    rename to application/src/test/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleServiceTest.java
    index a1c9dddaab0..7ca1ac6a760 100644
    --- a/src/test/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleServiceTest.java
    +++ b/application/src/test/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleServiceTest.java
    @@ -2,25 +2,25 @@
     
     import static org.junit.jupiter.api.Assertions.assertEquals;
     import static org.opentripplanner.framework.geometry.WgsCoordinate.GREENWICH;
    -import static org.opentripplanner.transit.model._data.TransitModelForTest.route;
    -import static org.opentripplanner.transit.model._data.TransitModelForTest.tripPattern;
    +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.route;
    +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.tripPattern;
     
     import java.time.Instant;
     import java.util.List;
     import org.junit.jupiter.api.Test;
     import org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle;
    -import org.opentripplanner.transit.model._data.TransitModelForTest;
    +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
     import org.opentripplanner.transit.model.network.Route;
     import org.opentripplanner.transit.model.network.StopPattern;
     import org.opentripplanner.transit.model.network.TripPattern;
     import org.opentripplanner.transit.service.DefaultTransitService;
    -import org.opentripplanner.transit.service.TransitModel;
    +import org.opentripplanner.transit.service.TimetableRepository;
     
     class DefaultRealtimeVehicleServiceTest {
     
       private static final Route ROUTE = route("r1").build();
    -  private static final TransitModelForTest MODEL = TransitModelForTest.of();
    -  private static final StopPattern STOP_PATTERN = TransitModelForTest.stopPattern(
    +  private static final TimetableRepositoryForTest MODEL = TimetableRepositoryForTest.of();
    +  private static final StopPattern STOP_PATTERN = TimetableRepositoryForTest.stopPattern(
         MODEL.stop("1").build(),
         MODEL.stop("2").build()
       );
    @@ -34,7 +34,9 @@ class DefaultRealtimeVehicleServiceTest {
     
       @Test
       void originalPattern() {
    -    var service = new DefaultRealtimeVehicleService(new DefaultTransitService(new TransitModel()));
    +    var service = new DefaultRealtimeVehicleService(
    +      new DefaultTransitService(new TimetableRepository())
    +    );
         service.setRealtimeVehicles(ORIGINAL, VEHICLES);
         var updates = service.getRealtimeVehicles(ORIGINAL);
         assertEquals(VEHICLES, updates);
    @@ -42,7 +44,9 @@ void originalPattern() {
     
       @Test
       void realtimeAddedPattern() {
    -    var service = new DefaultRealtimeVehicleService(new DefaultTransitService(new TransitModel()));
    +    var service = new DefaultRealtimeVehicleService(
    +      new DefaultTransitService(new TimetableRepository())
    +    );
         var realtimePattern = tripPattern("realtime-added", ROUTE)
           .withStopPattern(STOP_PATTERN)
           .withOriginalTripPattern(ORIGINAL)
    diff --git a/src/test/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingHelperTest.java b/application/src/test/java/org/opentripplanner/service/vehicleparking/VehicleParkingHelperTest.java
    similarity index 92%
    rename from src/test/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingHelperTest.java
    rename to application/src/test/java/org/opentripplanner/service/vehicleparking/VehicleParkingHelperTest.java
    index 90bdeb015a4..34b48bfe051 100644
    --- a/src/test/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingHelperTest.java
    +++ b/application/src/test/java/org/opentripplanner/service/vehicleparking/VehicleParkingHelperTest.java
    @@ -1,4 +1,4 @@
    -package org.opentripplanner.routing.vehicle_parking;
    +package org.opentripplanner.service.vehicleparking;
     
     import static org.junit.jupiter.api.Assertions.assertEquals;
     import static org.junit.jupiter.api.Assertions.assertTrue;
    @@ -9,7 +9,9 @@
     import org.opentripplanner.framework.geometry.WgsCoordinate;
     import org.opentripplanner.framework.i18n.NonLocalizedString;
     import org.opentripplanner.routing.graph.Graph;
    -import org.opentripplanner.routing.vehicle_parking.VehicleParking.VehicleParkingEntranceCreator;
    +import org.opentripplanner.service.vehicleparking.model.VehicleParking;
    +import org.opentripplanner.service.vehicleparking.model.VehicleParking.VehicleParkingEntranceCreator;
    +import org.opentripplanner.service.vehicleparking.model.VehicleParkingHelper;
     import org.opentripplanner.street.model._data.StreetModelForTest;
     import org.opentripplanner.street.model.edge.VehicleParkingEdge;
     import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex;
    diff --git a/src/test/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingTestGraphData.java b/application/src/test/java/org/opentripplanner/service/vehicleparking/VehicleParkingTestGraphData.java
    similarity index 69%
    rename from src/test/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingTestGraphData.java
    rename to application/src/test/java/org/opentripplanner/service/vehicleparking/VehicleParkingTestGraphData.java
    index 9fe74c66353..b2a847d267d 100644
    --- a/src/test/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingTestGraphData.java
    +++ b/application/src/test/java/org/opentripplanner/service/vehicleparking/VehicleParkingTestGraphData.java
    @@ -1,4 +1,4 @@
    -package org.opentripplanner.routing.vehicle_parking;
    +package org.opentripplanner.service.vehicleparking;
     
     import org.opentripplanner.routing.graph.Graph;
     import org.opentripplanner.street.model.StreetTraversalPermission;
    @@ -6,8 +6,8 @@
     import org.opentripplanner.street.model.vertex.IntersectionVertex;
     import org.opentripplanner.street.model.vertex.VertexFactory;
     import org.opentripplanner.transit.model.framework.Deduplicator;
    -import org.opentripplanner.transit.service.StopModel;
    -import org.opentripplanner.transit.service.TransitModel;
    +import org.opentripplanner.transit.service.SiteRepository;
    +import org.opentripplanner.transit.service.TimetableRepository;
     
     public class VehicleParkingTestGraphData {
     
    @@ -15,13 +15,13 @@ public class VehicleParkingTestGraphData {
     
       protected Graph graph;
     
    -  protected TransitModel transitModel;
    +  protected TimetableRepository timetableRepository;
     
       public void initGraph() {
         var deduplicator = new Deduplicator();
    -    var stopModel = new StopModel();
    +    var siteRepository = new SiteRepository();
         graph = new Graph(deduplicator);
    -    transitModel = new TransitModel(stopModel, deduplicator);
    +    timetableRepository = new TimetableRepository(siteRepository, deduplicator);
         graph.hasStreets = true;
     
         var factory = new VertexFactory(graph);
    @@ -36,8 +36,8 @@ public Graph getGraph() {
         return graph;
       }
     
    -  public TransitModel getTransitModel() {
    -    return transitModel;
    +  public TimetableRepository getTimetableRepository() {
    +    return timetableRepository;
       }
     
       public IntersectionVertex getAVertex() {
    diff --git a/src/test/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingTestUtil.java b/application/src/test/java/org/opentripplanner/service/vehicleparking/VehicleParkingTestUtil.java
    similarity index 85%
    rename from src/test/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingTestUtil.java
    rename to application/src/test/java/org/opentripplanner/service/vehicleparking/VehicleParkingTestUtil.java
    index fca20322ebe..aebd422cf81 100644
    --- a/src/test/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingTestUtil.java
    +++ b/application/src/test/java/org/opentripplanner/service/vehicleparking/VehicleParkingTestUtil.java
    @@ -1,7 +1,9 @@
    -package org.opentripplanner.routing.vehicle_parking;
    +package org.opentripplanner.service.vehicleparking;
     
     import org.opentripplanner.framework.geometry.WgsCoordinate;
     import org.opentripplanner.framework.i18n.NonLocalizedString;
    +import org.opentripplanner.service.vehicleparking.model.VehicleParking;
    +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces;
     import org.opentripplanner.street.model._data.StreetModelForTest;
     import org.opentripplanner.transit.model.framework.FeedScopedId;
     
    diff --git a/src/test/java/org/opentripplanner/service/vehiclerental/internal/DefaultVehicleRentalServiceTest.java b/application/src/test/java/org/opentripplanner/service/vehiclerental/internal/DefaultVehicleRentalServiceTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/service/vehiclerental/internal/DefaultVehicleRentalServiceTest.java
    rename to application/src/test/java/org/opentripplanner/service/vehiclerental/internal/DefaultVehicleRentalServiceTest.java
    diff --git a/src/test/java/org/opentripplanner/service/vehiclerental/model/TestFreeFloatingRentalVehicleBuilder.java b/application/src/test/java/org/opentripplanner/service/vehiclerental/model/TestFreeFloatingRentalVehicleBuilder.java
    similarity index 98%
    rename from src/test/java/org/opentripplanner/service/vehiclerental/model/TestFreeFloatingRentalVehicleBuilder.java
    rename to application/src/test/java/org/opentripplanner/service/vehiclerental/model/TestFreeFloatingRentalVehicleBuilder.java
    index c3837942426..a9b2398f686 100644
    --- a/src/test/java/org/opentripplanner/service/vehiclerental/model/TestFreeFloatingRentalVehicleBuilder.java
    +++ b/application/src/test/java/org/opentripplanner/service/vehiclerental/model/TestFreeFloatingRentalVehicleBuilder.java
    @@ -1,6 +1,5 @@
     package org.opentripplanner.service.vehiclerental.model;
     
    -import javax.annotation.Nonnull;
     import org.opentripplanner.framework.i18n.NonLocalizedString;
     import org.opentripplanner.street.model.RentalFormFactor;
     import org.opentripplanner.transit.model.framework.FeedScopedId;
    @@ -65,7 +64,6 @@ public TestFreeFloatingRentalVehicleBuilder withVehicleCar() {
         return buildVehicleType(RentalFormFactor.CAR);
       }
     
    -  @Nonnull
       private TestFreeFloatingRentalVehicleBuilder buildVehicleType(RentalFormFactor rentalFormFactor) {
         this.vehicleType =
           new RentalVehicleType(
    diff --git a/src/test/java/org/opentripplanner/service/vehiclerental/model/TestVehicleRentalStationBuilder.java b/application/src/test/java/org/opentripplanner/service/vehiclerental/model/TestVehicleRentalStationBuilder.java
    similarity index 99%
    rename from src/test/java/org/opentripplanner/service/vehiclerental/model/TestVehicleRentalStationBuilder.java
    rename to application/src/test/java/org/opentripplanner/service/vehiclerental/model/TestVehicleRentalStationBuilder.java
    index 0fb9f8b620f..ea8af5ade6f 100644
    --- a/src/test/java/org/opentripplanner/service/vehiclerental/model/TestVehicleRentalStationBuilder.java
    +++ b/application/src/test/java/org/opentripplanner/service/vehiclerental/model/TestVehicleRentalStationBuilder.java
    @@ -2,7 +2,6 @@
     
     import java.util.HashMap;
     import java.util.Map;
    -import javax.annotation.Nonnull;
     import org.opentripplanner.framework.i18n.NonLocalizedString;
     import org.opentripplanner.street.model.RentalFormFactor;
     import org.opentripplanner.transit.model.framework.FeedScopedId;
    @@ -105,7 +104,6 @@ public TestVehicleRentalStationBuilder withVehicleTypeCar(int numAvailable, int
         );
       }
     
    -  @Nonnull
       private TestVehicleRentalStationBuilder buildVehicleType(
         RentalFormFactor rentalFormFactor,
         RentalVehicleType.PropulsionType propulsionType,
    diff --git a/src/test/java/org/opentripplanner/service/worldenvelope/internal/WorldEnvelopeRepositoryTest.java b/application/src/test/java/org/opentripplanner/service/worldenvelope/internal/WorldEnvelopeRepositoryTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/service/worldenvelope/internal/WorldEnvelopeRepositoryTest.java
    rename to application/src/test/java/org/opentripplanner/service/worldenvelope/internal/WorldEnvelopeRepositoryTest.java
    diff --git a/src/test/java/org/opentripplanner/service/worldenvelope/internal/WorldEnvelopeServiceTest.java b/application/src/test/java/org/opentripplanner/service/worldenvelope/internal/WorldEnvelopeServiceTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/service/worldenvelope/internal/WorldEnvelopeServiceTest.java
    rename to application/src/test/java/org/opentripplanner/service/worldenvelope/internal/WorldEnvelopeServiceTest.java
    diff --git a/src/test/java/org/opentripplanner/service/worldenvelope/model/MedianCalcForDoublesTest.java b/application/src/test/java/org/opentripplanner/service/worldenvelope/model/MedianCalcForDoublesTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/service/worldenvelope/model/MedianCalcForDoublesTest.java
    rename to application/src/test/java/org/opentripplanner/service/worldenvelope/model/MedianCalcForDoublesTest.java
    diff --git a/src/test/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelopeTest.java b/application/src/test/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelopeTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelopeTest.java
    rename to application/src/test/java/org/opentripplanner/service/worldenvelope/model/WorldEnvelopeTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/BuildConfigTest.java b/application/src/test/java/org/opentripplanner/standalone/config/BuildConfigTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/BuildConfigTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/BuildConfigTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/CommandLineParametersTest.java b/application/src/test/java/org/opentripplanner/standalone/config/CommandLineParametersTest.java
    similarity index 88%
    rename from src/test/java/org/opentripplanner/standalone/config/CommandLineParametersTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/CommandLineParametersTest.java
    index 82c3589202c..0551d9e7056 100644
    --- a/src/test/java/org/opentripplanner/standalone/config/CommandLineParametersTest.java
    +++ b/application/src/test/java/org/opentripplanner/standalone/config/CommandLineParametersTest.java
    @@ -41,6 +41,8 @@ public void everyThingOffByDefault() {
         assertFalse(subject.doLoadStreetGraph());
         assertFalse(subject.doSaveGraph());
         assertFalse(subject.doServe());
    +    var ex = assertThrows(ParameterException.class, () -> subject.inferAndValidate());
    +    assertEquals("Nothing to do. Use --help to see available options.", ex.getMessage());
       }
     
       @Test
    @@ -50,6 +52,7 @@ public void build() {
         assertTrue(subject.doBuildTransit());
         assertFalse(subject.doSaveGraph());
         assertFalse(subject.doServe());
    +    assertEquals("Build Street & Transit Graph", subject.logTaskInfo());
     
         subject.save = true;
         subject.serve = false;
    @@ -58,6 +61,7 @@ public void build() {
         assertTrue(subject.doSaveGraph());
         assertFalse(subject.doServe());
         subject.inferAndValidate();
    +    assertEquals("Build Street & Transit Graph", subject.logTaskInfo());
     
         subject.save = false;
         subject.serve = true;
    @@ -66,6 +70,7 @@ public void build() {
         assertFalse(subject.doSaveGraph());
         assertTrue(subject.doServe());
         subject.inferAndValidate();
    +    assertEquals("Build Street & Transit Graph, Run Server", subject.logTaskInfo());
     
         subject.save = true;
         subject.serve = true;
    @@ -74,6 +79,7 @@ public void build() {
         assertTrue(subject.doSaveGraph());
         assertTrue(subject.doServe());
         subject.inferAndValidate();
    +    assertEquals("Build Street & Transit Graph, Run Server", subject.logTaskInfo());
       }
     
       @Test
    @@ -83,6 +89,7 @@ public void buildStreet() {
         assertFalse(subject.doBuildTransit());
         assertTrue(subject.doSaveStreetGraph());
         assertFalse(subject.doSaveGraph());
    +    assertEquals("Build Street Graph", subject.logTaskInfo());
       }
     
       @Test
    @@ -90,6 +97,7 @@ public void doLoadGraph() {
         subject.load = true;
         assertTrue(subject.doLoadGraph());
         assertTrue(subject.doServe());
    +    assertEquals("Run Server", subject.logTaskInfo());
       }
     
       @Test
    @@ -99,6 +107,7 @@ public void doLoadStreetGraph() {
         assertFalse(subject.doBuildStreet());
         assertFalse(subject.doSaveStreetGraph());
         assertFalse(subject.doSaveGraph());
    +    assertEquals("Build Transit Graph", subject.logTaskInfo());
     
         subject.save = true;
         subject.serve = true;
    @@ -119,6 +128,7 @@ public void validateLoad() {
     
         // Implicit given, but should be ok to set
         subject.serve = true;
    +    assertEquals("Run Server", subject.logTaskInfo());
     
         // No exception thrown
         subject.inferAndValidate();
    diff --git a/src/test/java/org/opentripplanner/standalone/config/ExampleConfigTest.java b/application/src/test/java/org/opentripplanner/standalone/config/ExampleConfigTest.java
    similarity index 77%
    rename from src/test/java/org/opentripplanner/standalone/config/ExampleConfigTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/ExampleConfigTest.java
    index 12b8749c1fe..934da6f923d 100644
    --- a/src/test/java/org/opentripplanner/standalone/config/ExampleConfigTest.java
    +++ b/application/src/test/java/org/opentripplanner/standalone/config/ExampleConfigTest.java
    @@ -2,6 +2,7 @@
     
     import static org.junit.jupiter.api.Assertions.fail;
     import static org.opentripplanner.framework.application.OtpFileNames.BUILD_CONFIG_FILENAME;
    +import static org.opentripplanner.framework.application.OtpFileNames.DEBUG_UI_CONFIG_FILENAME;
     import static org.opentripplanner.framework.application.OtpFileNames.OTP_CONFIG_FILENAME;
     import static org.opentripplanner.framework.application.OtpFileNames.ROUTER_CONFIG_FILENAME;
     
    @@ -22,7 +23,12 @@
     @GeneratesDocumentation
     public class ExampleConfigTest {
     
    -  @FilePatternSource(pattern = "doc/user/examples/**/" + ROUTER_CONFIG_FILENAME)
    +  @FilePatternSource(
    +    pattern = {
    +      "doc/user/examples/**/" + ROUTER_CONFIG_FILENAME,
    +      "application/src/test/resources/standalone/config/**/" + ROUTER_CONFIG_FILENAME,
    +    }
    +  )
       @ParameterizedTest(name = "Check validity of {0}")
       void routerConfig(Path filename) {
         testConfig(filename, a -> new RouterConfig(a, true));
    @@ -31,7 +37,7 @@ void routerConfig(Path filename) {
       @FilePatternSource(
         pattern = {
           "doc/user/examples/**/" + BUILD_CONFIG_FILENAME,
    -      "test/performance/**/" + BUILD_CONFIG_FILENAME,
    +      "application/src/test/resources/standalone/config/**/" + BUILD_CONFIG_FILENAME,
         }
       )
       @ParameterizedTest(name = "Check validity of {0}")
    @@ -55,7 +61,20 @@ void otpConfig(Path filename) {
         testConfig(filename, nodeAdapter -> new OtpConfig(nodeAdapter, true));
       }
     
    -  @FilePatternSource(pattern = { "src/test/resources/standalone/config/invalid-config.json" })
    +  @FilePatternSource(
    +    pattern = {
    +      "doc/user/examples/**/" + DEBUG_UI_CONFIG_FILENAME,
    +      "application/src/test/resources/standalone/config/" + DEBUG_UI_CONFIG_FILENAME,
    +    }
    +  )
    +  @ParameterizedTest(name = "Check validity of {0}")
    +  void debugUiConfig(Path filename) {
    +    testConfig(filename, nodeAdapter -> new DebugUiConfig(nodeAdapter, true));
    +  }
    +
    +  @FilePatternSource(
    +    pattern = { "application/src/test/resources/standalone/config/invalid-config.json" }
    +  )
       @ParameterizedTest(name = "Fail when parsing an invalid config from {0}")
       void failInvalidConfig(Path filename) {
         Assertions.assertThrows(
    diff --git a/src/test/java/org/opentripplanner/standalone/config/OtpConfigLoaderTest.java b/application/src/test/java/org/opentripplanner/standalone/config/OtpConfigLoaderTest.java
    similarity index 98%
    rename from src/test/java/org/opentripplanner/standalone/config/OtpConfigLoaderTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/OtpConfigLoaderTest.java
    index c67983355e1..8dae448e2c6 100644
    --- a/src/test/java/org/opentripplanner/standalone/config/OtpConfigLoaderTest.java
    +++ b/application/src/test/java/org/opentripplanner/standalone/config/OtpConfigLoaderTest.java
    @@ -15,8 +15,8 @@
     import org.junit.jupiter.api.AfterEach;
     import org.junit.jupiter.api.BeforeEach;
     import org.junit.jupiter.api.Test;
    -import org.opentripplanner.framework.lang.StringUtils;
     import org.opentripplanner.standalone.config.framework.file.ConfigFileLoader;
    +import org.opentripplanner.utils.lang.StringUtils;
     
     public class OtpConfigLoaderTest {
     
    diff --git a/src/test/java/org/opentripplanner/standalone/config/RouterConfigDocTest.java b/application/src/test/java/org/opentripplanner/standalone/config/RouterConfigDocTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/RouterConfigDocTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/RouterConfigDocTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/RouterConfigTest.java b/application/src/test/java/org/opentripplanner/standalone/config/RouterConfigTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/RouterConfigTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/RouterConfigTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/buildconfig/DemConfigTest.java b/application/src/test/java/org/opentripplanner/standalone/config/buildconfig/DemConfigTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/buildconfig/DemConfigTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/buildconfig/DemConfigTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/buildconfig/GtfsConfigTest.java b/application/src/test/java/org/opentripplanner/standalone/config/buildconfig/GtfsConfigTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/buildconfig/GtfsConfigTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/buildconfig/GtfsConfigTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/buildconfig/NetexConfigTest.java b/application/src/test/java/org/opentripplanner/standalone/config/buildconfig/NetexConfigTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/buildconfig/NetexConfigTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/buildconfig/NetexConfigTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/buildconfig/OsmConfigTest.java b/application/src/test/java/org/opentripplanner/standalone/config/buildconfig/OsmConfigTest.java
    similarity index 98%
    rename from src/test/java/org/opentripplanner/standalone/config/buildconfig/OsmConfigTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/buildconfig/OsmConfigTest.java
    index 41c3dc186a1..c771655bdbb 100644
    --- a/src/test/java/org/opentripplanner/standalone/config/buildconfig/OsmConfigTest.java
    +++ b/application/src/test/java/org/opentripplanner/standalone/config/buildconfig/OsmConfigTest.java
    @@ -7,7 +7,7 @@
     import org.junit.jupiter.api.Test;
     import org.opentripplanner._support.time.ZoneIds;
     import org.opentripplanner.graph_builder.module.osm.parameters.OsmExtractParametersList;
    -import org.opentripplanner.openstreetmap.tagmapping.OsmTagMapperSource;
    +import org.opentripplanner.osm.tagmapping.OsmTagMapperSource;
     import org.opentripplanner.standalone.config.framework.json.NodeAdapter;
     
     class OsmConfigTest {
    diff --git a/src/test/java/org/opentripplanner/standalone/config/framework/file/ConfigFileLoaderTest.java b/application/src/test/java/org/opentripplanner/standalone/config/framework/file/ConfigFileLoaderTest.java
    similarity index 98%
    rename from src/test/java/org/opentripplanner/standalone/config/framework/file/ConfigFileLoaderTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/framework/file/ConfigFileLoaderTest.java
    index 6cdba6e4b51..2e698efb64d 100644
    --- a/src/test/java/org/opentripplanner/standalone/config/framework/file/ConfigFileLoaderTest.java
    +++ b/application/src/test/java/org/opentripplanner/standalone/config/framework/file/ConfigFileLoaderTest.java
    @@ -14,8 +14,8 @@
     import org.junit.jupiter.api.BeforeEach;
     import org.junit.jupiter.api.Test;
     import org.opentripplanner.framework.application.OtpAppException;
    -import org.opentripplanner.framework.lang.StringUtils;
     import org.opentripplanner.standalone.config.OtpConfigLoader;
    +import org.opentripplanner.utils.lang.StringUtils;
     
     class ConfigFileLoaderTest {
     
    diff --git a/src/test/java/org/opentripplanner/standalone/config/framework/file/IncludeFileDirectiveTest.java b/application/src/test/java/org/opentripplanner/standalone/config/framework/file/IncludeFileDirectiveTest.java
    similarity index 97%
    rename from src/test/java/org/opentripplanner/standalone/config/framework/file/IncludeFileDirectiveTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/framework/file/IncludeFileDirectiveTest.java
    index cfdda47c160..0fc1199236d 100644
    --- a/src/test/java/org/opentripplanner/standalone/config/framework/file/IncludeFileDirectiveTest.java
    +++ b/application/src/test/java/org/opentripplanner/standalone/config/framework/file/IncludeFileDirectiveTest.java
    @@ -8,7 +8,7 @@
     import java.nio.file.Files;
     import org.junit.jupiter.api.AfterAll;
     import org.junit.jupiter.api.Test;
    -import org.opentripplanner.framework.lang.StringUtils;
    +import org.opentripplanner.utils.lang.StringUtils;
     
     public class IncludeFileDirectiveTest {
     
    diff --git a/src/test/java/org/opentripplanner/standalone/config/framework/json/ConfigTypeTest.java b/application/src/test/java/org/opentripplanner/standalone/config/framework/json/ConfigTypeTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/framework/json/ConfigTypeTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/framework/json/ConfigTypeTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/framework/json/EnumMapperTest.java b/application/src/test/java/org/opentripplanner/standalone/config/framework/json/EnumMapperTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/framework/json/EnumMapperTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/framework/json/EnumMapperTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/framework/json/JsonSupport.java b/application/src/test/java/org/opentripplanner/standalone/config/framework/json/JsonSupport.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/framework/json/JsonSupport.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/framework/json/JsonSupport.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/framework/json/NodeAdapterTest.java b/application/src/test/java/org/opentripplanner/standalone/config/framework/json/NodeAdapterTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/framework/json/NodeAdapterTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/framework/json/NodeAdapterTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/framework/json/NodeInfoTest.java b/application/src/test/java/org/opentripplanner/standalone/config/framework/json/NodeInfoTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/framework/json/NodeInfoTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/framework/json/NodeInfoTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/framework/project/EnvironmentVariableReplacerTest.java b/application/src/test/java/org/opentripplanner/standalone/config/framework/project/EnvironmentVariableReplacerTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/framework/project/EnvironmentVariableReplacerTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/framework/project/EnvironmentVariableReplacerTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/routerconfig/ServerConfigTest.java b/application/src/test/java/org/opentripplanner/standalone/config/routerconfig/ServerConfigTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/routerconfig/ServerConfigTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/routerconfig/ServerConfigTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfigTest.java b/application/src/test/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfigTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfigTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfigTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/routerequest/TimeAndCostPenaltyMapperTest.java b/application/src/test/java/org/opentripplanner/standalone/config/routerequest/TimeAndCostPenaltyMapperTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/routerequest/TimeAndCostPenaltyMapperTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/routerequest/TimeAndCostPenaltyMapperTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/routerequest/WheelchairConfigTest.java b/application/src/test/java/org/opentripplanner/standalone/config/routerequest/WheelchairConfigTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/routerequest/WheelchairConfigTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/routerequest/WheelchairConfigTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/sandbox/DataOverlayConfigMapperTest.java b/application/src/test/java/org/opentripplanner/standalone/config/sandbox/DataOverlayConfigMapperTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/sandbox/DataOverlayConfigMapperTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/sandbox/DataOverlayConfigMapperTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/config/services/RideHailingServicesConfigTest.java b/application/src/test/java/org/opentripplanner/standalone/config/services/RideHailingServicesConfigTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/config/services/RideHailingServicesConfigTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/config/services/RideHailingServicesConfigTest.java
    diff --git a/src/test/java/org/opentripplanner/standalone/server/EtagRequestFilterTest.java b/application/src/test/java/org/opentripplanner/standalone/server/EtagRequestFilterTest.java
    similarity index 98%
    rename from src/test/java/org/opentripplanner/standalone/server/EtagRequestFilterTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/server/EtagRequestFilterTest.java
    index ae19643db72..100edd8f5ae 100644
    --- a/src/test/java/org/opentripplanner/standalone/server/EtagRequestFilterTest.java
    +++ b/application/src/test/java/org/opentripplanner/standalone/server/EtagRequestFilterTest.java
    @@ -7,7 +7,6 @@
     import java.io.IOException;
     import java.nio.charset.StandardCharsets;
     import java.util.stream.Stream;
    -import javax.annotation.Nonnull;
     import org.glassfish.jersey.message.internal.OutboundJaxrsResponse;
     import org.glassfish.jersey.message.internal.OutboundMessageContext;
     import org.glassfish.jersey.message.internal.Statuses;
    @@ -84,7 +83,6 @@ void ifNoneMatch(String ifNoneMatch, int expectedStatus, byte[] expectedEntity)
         assertArrayEquals(expectedEntity, (byte[]) response.getEntity());
       }
     
    -  @Nonnull
       private static ContainerResponse response(int status, ContainerRequest request) {
         return new ContainerResponse(
           request,
    @@ -92,7 +90,6 @@ private static ContainerResponse response(int status, ContainerRequest request)
         );
       }
     
    -  @Nonnull
       private static byte[] bytes(String input) {
         return input.getBytes(StandardCharsets.UTF_8);
       }
    diff --git a/src/test/java/org/opentripplanner/standalone/server/RequestTraceFilterTest.java b/application/src/test/java/org/opentripplanner/standalone/server/RequestTraceFilterTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/standalone/server/RequestTraceFilterTest.java
    rename to application/src/test/java/org/opentripplanner/standalone/server/RequestTraceFilterTest.java
    diff --git a/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java b/application/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java
    similarity index 98%
    rename from src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java
    rename to application/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java
    index d1ea3c8e59d..8092ab62bc3 100644
    --- a/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java
    @@ -45,7 +45,7 @@ public static void createGraph() {
           ResourceLoader.of(BarrierRoutingTest.class).file("herrenberg-barrier-gates.osm.pbf")
         );
         graph = model.graph();
    -    graph.index(model.transitModel().getStopModel());
    +    graph.index(model.timetableRepository().getSiteRepository());
       }
     
       /**
    @@ -179,7 +179,7 @@ private static String computePolyline(
     
         options.accept(request);
     
    -    var temporaryVertices = new TemporaryVerticesContainer(graph, request, streetMode, streetMode);
    +    var temporaryVertices = new TemporaryVerticesContainer(graph, from, to, streetMode, streetMode);
         var gpf = new GraphPathFinder(null);
         var paths = gpf.graphPathFinderEntryPoint(request, temporaryVertices);
     
    diff --git a/src/test/java/org/opentripplanner/street/integration/BicycleParkAndRideTest.java b/application/src/test/java/org/opentripplanner/street/integration/BicycleParkAndRideTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/integration/BicycleParkAndRideTest.java
    rename to application/src/test/java/org/opentripplanner/street/integration/BicycleParkAndRideTest.java
    diff --git a/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java b/application/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java
    similarity index 96%
    rename from src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java
    rename to application/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java
    index db937ff2a6e..60dc43aa3f9 100644
    --- a/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java
    @@ -34,8 +34,8 @@ public class BicycleRoutingTest {
         );
         herrenbergGraph = model.graph();
     
    -    model.transitModel().index();
    -    herrenbergGraph.index(model.transitModel().getStopModel());
    +    model.timetableRepository().index();
    +    herrenbergGraph.index(model.timetableRepository().getSiteRepository());
       }
     
       /**
    @@ -82,7 +82,8 @@ private static String computePolyline(Graph graph, GenericLocation from, Generic
         request.journey().direct().setMode(StreetMode.BIKE);
         var temporaryVertices = new TemporaryVerticesContainer(
           graph,
    -      request,
    +      request.from(),
    +      request.to(),
           request.journey().direct().mode(),
           request.journey().direct().mode()
         );
    diff --git a/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java b/application/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java
    rename to application/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java
    diff --git a/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java b/application/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java
    rename to application/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java
    diff --git a/src/test/java/org/opentripplanner/street/integration/CarParkAndRideTest.java b/application/src/test/java/org/opentripplanner/street/integration/CarParkAndRideTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/integration/CarParkAndRideTest.java
    rename to application/src/test/java/org/opentripplanner/street/integration/CarParkAndRideTest.java
    diff --git a/src/test/java/org/opentripplanner/street/integration/CarPickupTest.java b/application/src/test/java/org/opentripplanner/street/integration/CarPickupTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/integration/CarPickupTest.java
    rename to application/src/test/java/org/opentripplanner/street/integration/CarPickupTest.java
    diff --git a/src/test/java/org/opentripplanner/street/integration/CarRoutingTest.java b/application/src/test/java/org/opentripplanner/street/integration/CarRoutingTest.java
    similarity index 99%
    rename from src/test/java/org/opentripplanner/street/integration/CarRoutingTest.java
    rename to application/src/test/java/org/opentripplanner/street/integration/CarRoutingTest.java
    index 471d6bf80ce..caddf972e86 100644
    --- a/src/test/java/org/opentripplanner/street/integration/CarRoutingTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/integration/CarRoutingTest.java
    @@ -133,7 +133,8 @@ private static String computePolyline(Graph graph, GenericLocation from, Generic
         request.journey().direct().setMode(StreetMode.CAR);
         var temporaryVertices = new TemporaryVerticesContainer(
           graph,
    -      request,
    +      from,
    +      to,
           StreetMode.CAR,
           StreetMode.CAR
         );
    diff --git a/src/test/java/org/opentripplanner/street/integration/ParkAndRideTest.java b/application/src/test/java/org/opentripplanner/street/integration/ParkAndRideTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/integration/ParkAndRideTest.java
    rename to application/src/test/java/org/opentripplanner/street/integration/ParkAndRideTest.java
    diff --git a/src/test/java/org/opentripplanner/street/integration/SplitEdgeTurnRestrictionsTest.java b/application/src/test/java/org/opentripplanner/street/integration/SplitEdgeTurnRestrictionsTest.java
    similarity index 99%
    rename from src/test/java/org/opentripplanner/street/integration/SplitEdgeTurnRestrictionsTest.java
    rename to application/src/test/java/org/opentripplanner/street/integration/SplitEdgeTurnRestrictionsTest.java
    index 28ab5e91725..e664b3fe2b7 100644
    --- a/src/test/java/org/opentripplanner/street/integration/SplitEdgeTurnRestrictionsTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/integration/SplitEdgeTurnRestrictionsTest.java
    @@ -156,7 +156,8 @@ private static String computeCarPolyline(Graph graph, GenericLocation from, Gene
         request.journey().direct().setMode(StreetMode.CAR);
         var temporaryVertices = new TemporaryVerticesContainer(
           graph,
    -      request,
    +      from,
    +      to,
           StreetMode.CAR,
           StreetMode.CAR
         );
    diff --git a/src/test/java/org/opentripplanner/street/integration/WalkRoutingTest.java b/application/src/test/java/org/opentripplanner/street/integration/WalkRoutingTest.java
    similarity index 93%
    rename from src/test/java/org/opentripplanner/street/integration/WalkRoutingTest.java
    rename to application/src/test/java/org/opentripplanner/street/integration/WalkRoutingTest.java
    index 3fbb546c3f7..6f3f47ba6e6 100644
    --- a/src/test/java/org/opentripplanner/street/integration/WalkRoutingTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/integration/WalkRoutingTest.java
    @@ -29,8 +29,8 @@ class WalkRoutingTest {
         );
         roundabout = model.graph();
     
    -    model.transitModel().index();
    -    roundabout.index(model.transitModel().getStopModel());
    +    model.timetableRepository().index();
    +    roundabout.index(model.timetableRepository().getSiteRepository());
       }
     
       /**
    @@ -62,7 +62,8 @@ private static List> route(
         try (
           var temporaryVertices = new TemporaryVerticesContainer(
             graph,
    -        request,
    +        request.from(),
    +        request.to(),
             request.journey().direct().mode(),
             request.journey().direct().mode()
           )
    diff --git a/src/test/java/org/opentripplanner/street/model/StreetTraversalPermissionTest.java b/application/src/test/java/org/opentripplanner/street/model/StreetTraversalPermissionTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/StreetTraversalPermissionTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/StreetTraversalPermissionTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/TurnRestrictionTest.java b/application/src/test/java/org/opentripplanner/street/model/TurnRestrictionTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/TurnRestrictionTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/TurnRestrictionTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java b/application/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java
    similarity index 95%
    rename from src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java
    index 4a0a0d1b848..08710fe0599 100644
    --- a/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java
    @@ -1,15 +1,14 @@
     package org.opentripplanner.street.model._data;
     
    -import static org.opentripplanner.transit.model._data.TransitModelForTest.id;
    +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id;
     
    -import javax.annotation.Nonnull;
     import org.locationtech.jts.geom.Coordinate;
     import org.locationtech.jts.geom.LineString;
     import org.opentripplanner.framework.geometry.GeometryUtils;
     import org.opentripplanner.framework.geometry.SphericalDistanceLibrary;
     import org.opentripplanner.framework.geometry.WgsCoordinate;
     import org.opentripplanner.framework.i18n.I18NString;
    -import org.opentripplanner.routing.vehicle_parking.VehicleParking;
    +import org.opentripplanner.service.vehicleparking.model.VehicleParking;
     import org.opentripplanner.service.vehiclerental.model.TestFreeFloatingRentalVehicleBuilder;
     import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex;
     import org.opentripplanner.street.model.RentalFormFactor;
    @@ -42,7 +41,6 @@ public static IntersectionVertex intersectionVertex(String label, double lat, do
         return new LabelledIntersectionVertex(label, lon, lat, false, false);
       }
     
    -  @Nonnull
       public static TransitEntranceVertex transitEntranceVertex(String id, double lat, double lon) {
         var entrance = Entrance
           .of(id(id))
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/AreaEdgeBuilderTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/AreaEdgeBuilderTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/edge/AreaEdgeBuilderTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/AreaEdgeBuilderTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/ElevatorHopEdgeTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/ElevatorHopEdgeTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/edge/ElevatorHopEdgeTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/ElevatorHopEdgeTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/EscalatorEdgeTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/EscalatorEdgeTest.java
    similarity index 88%
    rename from src/test/java/org/opentripplanner/street/model/edge/EscalatorEdgeTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/EscalatorEdgeTest.java
    index 60859290646..1cfff635c45 100644
    --- a/src/test/java/org/opentripplanner/street/model/edge/EscalatorEdgeTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/edge/EscalatorEdgeTest.java
    @@ -1,5 +1,6 @@
     package org.opentripplanner.street.model.edge;
     
    +import static com.google.common.truth.Truth.assertThat;
     import static org.junit.jupiter.api.Assertions.assertEquals;
     
     import java.util.Locale;
    @@ -42,7 +43,7 @@ void testCycling() {
         var edge = EscalatorEdge.createEscalatorEdge(from, to, 10);
         var req = StreetSearchRequest.of().withMode(StreetMode.BIKE);
         var res = edge.traverse(new State(from, req.build()));
    -    assertEquals(res.length, 0);
    +    assertThat(res).isEmpty();
       }
     
       @Test
    @@ -50,7 +51,7 @@ void testWheelchair() {
         var edge = EscalatorEdge.createEscalatorEdge(from, to, 10);
         var req = StreetSearchRequest.of().withMode(StreetMode.WALK).withWheelchair(true);
         var res = edge.traverse(new State(from, req.build()));
    -    assertEquals(res.length, 0);
    +    assertThat(res).isEmpty();
       }
     
       @Test
    @@ -59,4 +60,10 @@ void name() {
         assertEquals("Rolltreppe", edge.getName().toString(Locale.GERMANY));
         assertEquals("escalator", edge.getName().toString(Locale.ENGLISH));
       }
    +
    +  @Test
    +  void geometry() {
    +    var edge = EscalatorEdge.createEscalatorEdge(from, to, 10);
    +    assertThat(edge.getGeometry().getCoordinates()).isNotEmpty();
    +  }
     }
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/PathwayEdgeTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/PathwayEdgeTest.java
    similarity index 99%
    rename from src/test/java/org/opentripplanner/street/model/edge/PathwayEdgeTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/PathwayEdgeTest.java
    index 6929f665938..6d5574b8027 100644
    --- a/src/test/java/org/opentripplanner/street/model/edge/PathwayEdgeTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/edge/PathwayEdgeTest.java
    @@ -7,7 +7,6 @@
     
     import java.util.Optional;
     import java.util.stream.Stream;
    -import javax.annotation.Nonnull;
     import org.junit.jupiter.api.Nested;
     import org.junit.jupiter.api.Test;
     import org.junit.jupiter.params.ParameterizedTest;
    @@ -241,7 +240,6 @@ void emptySignpostedAs() {
           assertEquals(PathwayEdge.DEFAULT_NAME, edge.getName());
         }
     
    -    @Nonnull
         private PathwayEdge pathwayEdge(I18NString sign) {
           return PathwayEdge.createPathwayEdge(
             from,
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/RentalRestrictionExtensionTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/RentalRestrictionExtensionTest.java
    similarity index 99%
    rename from src/test/java/org/opentripplanner/street/model/edge/RentalRestrictionExtensionTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/RentalRestrictionExtensionTest.java
    index 2a5589d58bf..41b648cea64 100644
    --- a/src/test/java/org/opentripplanner/street/model/edge/RentalRestrictionExtensionTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/edge/RentalRestrictionExtensionTest.java
    @@ -13,7 +13,6 @@
     import static org.opentripplanner.street.search.state.VehicleRentalState.RENTING_FLOATING;
     
     import java.util.Set;
    -import javax.annotation.Nonnull;
     import org.junit.jupiter.api.Nested;
     import org.junit.jupiter.api.Test;
     import org.opentripplanner.routing.api.request.StreetMode;
    @@ -167,7 +166,6 @@ private State[] traverse(StreetEdge edge) {
         return edge.traverse(state);
       }
     
    -  @Nonnull
       private State state(String network) {
         var req = StreetSearchRequest.of().withMode(StreetMode.SCOOTER_RENTAL).build();
         var editor = new StateEditor(V1, req);
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeBuilderTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeBuilderTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/edge/StreetEdgeBuilderTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeBuilderTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeGeofencingTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeGeofencingTest.java
    similarity index 61%
    rename from src/test/java/org/opentripplanner/street/model/edge/StreetEdgeGeofencingTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeGeofencingTest.java
    index cc38b04230a..0a9dfa44440 100644
    --- a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeGeofencingTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeGeofencingTest.java
    @@ -13,8 +13,9 @@
     import static org.opentripplanner.street.search.state.VehicleRentalState.HAVE_RENTED;
     import static org.opentripplanner.street.search.state.VehicleRentalState.RENTING_FLOATING;
     
    +import java.util.Arrays;
    +import java.util.Collections;
     import java.util.Set;
    -import javax.annotation.Nonnull;
     import org.junit.jupiter.api.Nested;
     import org.junit.jupiter.api.Test;
     import org.opentripplanner.routing.api.request.StreetMode;
    @@ -214,14 +215,7 @@ public void backwardsDontEnterNoTraversalZone() {
         public void pickupFloatingVehicleWhenLeavingAZone() {
           var req = defaultArriveByRequest();
     
    -      // this is the state that starts inside a restricted zone (no drop off, no traversal or outside business area)
    -      // and is walking towards finding a rental vehicle
    -      var haveRentedState = State
    -        .getInitialStates(Set.of(V2), req)
    -        .stream()
    -        .filter(s -> s.getVehicleRentalState() == HAVE_RENTED)
    -        .findAny()
    -        .get();
    +      var haveRentedState = makeHaveRentedState(V2, req);
     
           var edge = streetEdge(V1, V2);
           V2.addRentalRestriction(NO_TRAVERSAL);
    @@ -245,25 +239,23 @@ public void pickupFloatingVehiclesWhenStartedInNoDropOffZone() {
           V2.addRentalRestriction(NO_DROP_OFF_TIER);
           V2.addRentalRestriction(noDropOffRestriction(NETWORK_BIRD));
     
    -      // this is the state that starts inside a no drop off
    -      // and is walking towards finding a rental vehicle
    -      var haveRentedState = State
    -        .getInitialStates(Set.of(V2), req)
    -        .stream()
    -        .filter(s -> s.getVehicleRentalState() == HAVE_RENTED)
    -        .findAny()
    -        .get();
    +      var haveRentedState = makeHaveRentedState(V2, req);
     
           var edge = streetEdge(V1, V2);
     
           var states = edge.traverse(haveRentedState);
     
    -      // we return 3 states: one for the speculative renting of a vehicle, but with the information
    -      // of which networks' no-drop-off zones it started in
    +      // we return 3 states: one for continuing walking, one for the speculative renting of
    +      // a vehicle, but with the information of which networks' no-drop-off zones it started in
           assertEquals(3, states.length);
     
    -      // first the speculative renting case
    -      final State speculativeRenting = states[0];
    +      // first the fallback walk state
    +      final State walkState = states[0];
    +      assertEquals(HAVE_RENTED, walkState.getVehicleRentalState());
    +      assertEquals(WALK, walkState.currentMode());
    +
    +      // then the speculative renting case for unknown rental network
    +      final State speculativeRenting = states[2];
           assertEquals(RENTING_FLOATING, speculativeRenting.getVehicleRentalState());
           assertEquals(BICYCLE, speculativeRenting.currentMode());
           // null means that the vehicle has been rented speculatively and the rest of the backwards search
    @@ -274,30 +266,188 @@ public void pickupFloatingVehiclesWhenStartedInNoDropOffZone() {
             speculativeRenting.stateData.noRentalDropOffZonesAtStartOfReverseSearch
           );
     
    -      // first the speculative renting case
    +      // then the speculative renting cases for specific rental networks
           final State tierState = states[1];
           assertEquals(RENTING_FLOATING, tierState.getVehicleRentalState());
           assertEquals(BICYCLE, tierState.currentMode());
           assertEquals(NETWORK_TIER, tierState.getVehicleRentalNetwork());
           assertEquals(Set.of(), tierState.stateData.noRentalDropOffZonesAtStartOfReverseSearch);
    +    }
    +
    +    @Test
    +    public void pickupFloatingVehiclesWhenStartedInNoDropOffZoneAllNetworksAllowedByDefault() {
    +      var states = runTraverse(Collections.emptySet(), Collections.emptySet());
    +
    +      // Walking, unknown, Tier, Bird. (Order of last two not guaranteed)
    +      assertEquals(4, states.length);
    +      final State walkState = states[0];
    +      assertEquals(HAVE_RENTED, walkState.getVehicleRentalState());
    +      assertEquals(WALK, walkState.currentMode());
    +
    +      final State unknownNetworkState = states[3];
    +      assertEquals(RENTING_FLOATING, unknownNetworkState.getVehicleRentalState());
    +      assertEquals(BICYCLE, unknownNetworkState.currentMode());
    +      assertNull(unknownNetworkState.getVehicleRentalNetwork());
    +
    +      final State tierState = Arrays
    +        .stream(states)
    +        .filter(s -> NETWORK_TIER.equals(s.getVehicleRentalNetwork()))
    +        .findFirst()
    +        .get();
    +      assertEquals(RENTING_FLOATING, tierState.getVehicleRentalState());
    +      assertEquals(BICYCLE, tierState.currentMode());
    +
    +      final State birdState = Arrays
    +        .stream(states)
    +        .filter(s -> NETWORK_BIRD.equals(s.getVehicleRentalNetwork()))
    +        .findFirst()
    +        .get();
    +      assertEquals(RENTING_FLOATING, birdState.getVehicleRentalState());
    +      assertEquals(BICYCLE, birdState.currentMode());
    +    }
    +
    +    @Test
    +    public void pickupFloatingVehiclesWhenStartedInNoDropOffZoneAllNetworksAllowed() {
    +      var states = runTraverse(Set.of(NETWORK_TIER, NETWORK_BIRD), Collections.emptySet());
    +
    +      // Walking, unknown, Tier, Bird. (Order of last two not guaranteed)
    +      assertEquals(4, states.length);
    +      final State walkState = states[0];
    +      assertEquals(HAVE_RENTED, walkState.getVehicleRentalState());
    +      assertEquals(WALK, walkState.currentMode());
    +
    +      final State unknownNetworkState = states[3];
    +      assertEquals(RENTING_FLOATING, unknownNetworkState.getVehicleRentalState());
    +      assertEquals(BICYCLE, unknownNetworkState.currentMode());
    +      assertNull(unknownNetworkState.getVehicleRentalNetwork());
    +
    +      final State tierState = Arrays
    +        .stream(states)
    +        .filter(s -> NETWORK_TIER.equals(s.getVehicleRentalNetwork()))
    +        .findFirst()
    +        .get();
    +      assertEquals(RENTING_FLOATING, tierState.getVehicleRentalState());
    +      assertEquals(BICYCLE, tierState.currentMode());
     
    -      final State birdState = states[2];
    +      final State birdState = Arrays
    +        .stream(states)
    +        .filter(s -> NETWORK_BIRD.equals(s.getVehicleRentalNetwork()))
    +        .findFirst()
    +        .get();
           assertEquals(RENTING_FLOATING, birdState.getVehicleRentalState());
           assertEquals(BICYCLE, birdState.currentMode());
    -      assertEquals(NETWORK_BIRD, birdState.getVehicleRentalNetwork());
    -      assertEquals(Set.of(), birdState.stateData.noRentalDropOffZonesAtStartOfReverseSearch);
    +    }
    +
    +    @Test
    +    public void pickupFloatingVehiclesWhenStartedInNoDropOffZoneSomeNetworksAllowed() {
    +      var states = runTraverse(Set.of(NETWORK_TIER), Collections.emptySet());
    +
    +      // Walking, unknown, Tier.
    +      assertEquals(3, states.length);
    +      final State walkState = states[0];
    +      assertEquals(HAVE_RENTED, walkState.getVehicleRentalState());
    +      assertEquals(WALK, walkState.currentMode());
    +
    +      final State unknownNetworkState = states[2];
    +      assertEquals(RENTING_FLOATING, unknownNetworkState.getVehicleRentalState());
    +      assertEquals(BICYCLE, unknownNetworkState.currentMode());
    +      assertNull(unknownNetworkState.getVehicleRentalNetwork());
    +
    +      final State tierState = states[1];
    +      assertEquals(RENTING_FLOATING, tierState.getVehicleRentalState());
    +      assertEquals(BICYCLE, tierState.currentMode());
    +      assertEquals(NETWORK_TIER, tierState.getVehicleRentalNetwork());
    +    }
    +
    +    @Test
    +    public void pickupFloatingVehiclesWhenStartedInNoDropOffZoneAllNetworksBanned() {
    +      var states = runTraverse(Collections.emptySet(), Set.of(NETWORK_TIER, NETWORK_BIRD));
    +
    +      // Should only have a walking state. The unknown network state should only be
    +      // generated if there are known network states.
    +      assertEquals(1, states.length);
    +      final State walkState = states[0];
    +      assertEquals(HAVE_RENTED, walkState.getVehicleRentalState());
    +      assertEquals(WALK, walkState.currentMode());
    +    }
    +
    +    @Test
    +    public void pickupFloatingVehiclesWhenStartedInNoDropOffZoneSomeNetworksBanned() {
    +      var states = runTraverse(Collections.emptySet(), Set.of(NETWORK_BIRD));
    +
    +      // Walking state, unknown network state, known network state for Tier (which wasn't banned)
    +      assertEquals(3, states.length);
    +
    +      final State walkState = states[0];
    +      assertEquals(HAVE_RENTED, walkState.getVehicleRentalState());
    +      assertEquals(WALK, walkState.currentMode());
    +
    +      final State unknownNetworkState = states[2];
    +      assertEquals(RENTING_FLOATING, unknownNetworkState.getVehicleRentalState());
    +      assertEquals(BICYCLE, unknownNetworkState.currentMode());
    +      assertNull(unknownNetworkState.getVehicleRentalNetwork());
    +
    +      final State tierState = states[1];
    +      assertEquals(RENTING_FLOATING, tierState.getVehicleRentalState());
    +      assertEquals(BICYCLE, tierState.currentMode());
    +      assertEquals(NETWORK_TIER, tierState.getVehicleRentalNetwork());
    +    }
    +
    +    private State[] runTraverse(Set allowedNetworks, Set bannedNetworks) {
    +      var req = makeArriveByRequest(allowedNetworks, bannedNetworks);
    +
    +      V2.addRentalRestriction(NO_DROP_OFF_TIER);
    +      V2.addRentalRestriction(noDropOffRestriction(NETWORK_BIRD));
    +
    +      var haveRentedState = makeHaveRentedState(V2, req);
    +
    +      var edge = streetEdge(V1, V2);
    +
    +      return edge.traverse(haveRentedState);
    +    }
    +
    +    private static State makeHaveRentedState(Vertex vertex, StreetSearchRequest req) {
    +      // this is the state that starts inside a restricted zone
    +      // (no drop off, no traversal or outside business area)
    +      // and is walking towards finding a rental vehicle
    +      return State
    +        .getInitialStates(Set.of(vertex), req)
    +        .stream()
    +        .filter(s -> s.getVehicleRentalState() == HAVE_RENTED)
    +        .findAny()
    +        .get();
         }
     
         private static StreetSearchRequest defaultArriveByRequest() {
           return StreetSearchRequest
             .of()
    +        .withPreferences(p ->
    +          p.withBike(b -> b.withRental(r -> r.withAllowedNetworks(Set.of(NETWORK_TIER))))
    +        )
    +        .withMode(StreetMode.SCOOTER_RENTAL)
    +        .withArriveBy(true)
    +        .build();
    +    }
    +
    +    private static StreetSearchRequest makeArriveByRequest(
    +      Set allowedNetworks,
    +      Set bannedNetworks
    +    ) {
    +      return StreetSearchRequest
    +        .of()
    +        .withPreferences(p ->
    +          p.withBike(b ->
    +            b.withRental(r ->
    +              r.withAllowedNetworks(allowedNetworks).withBannedNetworks(bannedNetworks)
    +            )
    +          )
    +        )
             .withMode(StreetMode.SCOOTER_RENTAL)
             .withArriveBy(true)
             .build();
         }
       }
     
    -  @Nonnull
       private static GeofencingZoneExtension noDropOffRestriction(String networkTier) {
         return new GeofencingZoneExtension(
           new GeofencingZone(new FeedScopedId(networkTier, "a-park"), null, true, false)
    @@ -309,12 +459,10 @@ private State[] traverseFromV1(StreetEdge edge) {
         return edge.traverse(state);
       }
     
    -  @Nonnull
       private State forwardState(String network) {
         return initialState(V1, network, false);
       }
     
    -  @Nonnull
       private State initialState(Vertex startVertex, String network, boolean arriveBy) {
         var req = StreetSearchRequest
           .of()
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeRentalTraversalTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeRentalTraversalTest.java
    similarity index 98%
    rename from src/test/java/org/opentripplanner/street/model/edge/StreetEdgeRentalTraversalTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeRentalTraversalTest.java
    index 44de661f327..e2187acad18 100644
    --- a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeRentalTraversalTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeRentalTraversalTest.java
    @@ -14,7 +14,6 @@
     import static org.opentripplanner.street.model._data.StreetModelForTest.streetEdge;
     
     import java.util.stream.Stream;
    -import javax.annotation.Nonnull;
     import org.junit.jupiter.params.ParameterizedTest;
     import org.junit.jupiter.params.provider.Arguments;
     import org.junit.jupiter.params.provider.MethodSource;
    @@ -31,7 +30,6 @@ public class StreetEdgeRentalTraversalTest {
       StreetVertex v0 = intersectionVertex(0.0, 0.0);
       StreetVertex v1 = intersectionVertex(2.0, 2.0);
     
    -  @Nonnull
       private static Stream baseCases(StreetTraversalPermission p) {
         return Stream.of(
           of(SCOOTER, SCOOTER_RENTAL, p),
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeScooterTraversalTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeScooterTraversalTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/edge/StreetEdgeScooterTraversalTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeScooterTraversalTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeSplittingTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeSplittingTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/edge/StreetEdgeSplittingTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeSplittingTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeWheelchairCostTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeWheelchairCostTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/edge/StreetEdgeWheelchairCostTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeWheelchairCostTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetElevationExtensionBuilderTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/StreetElevationExtensionBuilderTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/edge/StreetElevationExtensionBuilderTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/StreetElevationExtensionBuilderTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetTransitEntityLinkTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/StreetTransitEntityLinkTest.java
    similarity index 97%
    rename from src/test/java/org/opentripplanner/street/model/edge/StreetTransitEntityLinkTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/StreetTransitEntityLinkTest.java
    index 6ba4dea0216..748e3b608fe 100644
    --- a/src/test/java/org/opentripplanner/street/model/edge/StreetTransitEntityLinkTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/edge/StreetTransitEntityLinkTest.java
    @@ -25,7 +25,7 @@
     import org.opentripplanner.street.search.request.StreetSearchRequest;
     import org.opentripplanner.street.search.state.State;
     import org.opentripplanner.street.search.state.TestStateBuilder;
    -import org.opentripplanner.transit.model._data.TransitModelForTest;
    +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
     import org.opentripplanner.transit.model.basic.Accessibility;
     import org.opentripplanner.transit.model.basic.TransitMode;
     import org.opentripplanner.transit.model.site.RegularStop;
    @@ -33,7 +33,7 @@
     
     class StreetTransitEntityLinkTest {
     
    -  private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of();
    +  private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of();
     
       private static final RegularStop ACCESSIBLE_STOP = stopForTest(
         "A:accessible",
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetTransitEntranceLinkTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/StreetTransitEntranceLinkTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/edge/StreetTransitEntranceLinkTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/StreetTransitEntranceLinkTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLinkTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLinkTest.java
    similarity index 94%
    rename from src/test/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLinkTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLinkTest.java
    index 8a3316e44e0..a44bed87bdf 100644
    --- a/src/test/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLinkTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLinkTest.java
    @@ -5,7 +5,7 @@
     import static org.junit.jupiter.api.Assertions.assertTrue;
     import static org.junit.jupiter.params.provider.Arguments.of;
     import static org.opentripplanner.street.model._data.StreetModelForTest.intersectionVertex;
    -import static org.opentripplanner.transit.model._data.TransitModelForTest.id;
    +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id;
     
     import java.util.Set;
     import java.util.stream.Stream;
    @@ -16,8 +16,8 @@
     import org.opentripplanner.framework.geometry.WgsCoordinate;
     import org.opentripplanner.framework.i18n.NonLocalizedString;
     import org.opentripplanner.routing.api.request.StreetMode;
    -import org.opentripplanner.routing.vehicle_parking.VehicleParking;
    -import org.opentripplanner.routing.vehicle_parking.VehicleParkingEntrance;
    +import org.opentripplanner.service.vehicleparking.model.VehicleParking;
    +import org.opentripplanner.service.vehicleparking.model.VehicleParkingEntrance;
     import org.opentripplanner.street.model._data.StreetModelForTest;
     import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex;
     import org.opentripplanner.street.model.vertex.Vertex;
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeBuilderTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeBuilderTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeBuilderTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeBuilderTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/TemporaryPartialStreetEdgeTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingEdgeTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingEdgeTest.java
    similarity index 91%
    rename from src/test/java/org/opentripplanner/street/model/edge/VehicleParkingEdgeTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingEdgeTest.java
    index 81bee23ad54..4fa7f682dfb 100644
    --- a/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingEdgeTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingEdgeTest.java
    @@ -8,13 +8,13 @@
     import org.opentripplanner.framework.geometry.WgsCoordinate;
     import org.opentripplanner.framework.i18n.NonLocalizedString;
     import org.opentripplanner.routing.api.request.StreetMode;
    -import org.opentripplanner.routing.vehicle_parking.VehicleParking;
    -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces;
    +import org.opentripplanner.service.vehicleparking.model.VehicleParking;
    +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces;
     import org.opentripplanner.street.model._data.StreetModelForTest;
     import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex;
     import org.opentripplanner.street.search.request.StreetSearchRequest;
     import org.opentripplanner.street.search.state.State;
    -import org.opentripplanner.transit.model._data.TransitModelForTest;
    +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
     
     class VehicleParkingEdgeTest {
     
    @@ -133,7 +133,7 @@ private VehicleParking createVehicleParking(
       ) {
         return StreetModelForTest
           .vehicleParking()
    -      .id(TransitModelForTest.id("VehicleParking"))
    +      .id(TimetableRepositoryForTest.id("VehicleParking"))
           .bicyclePlaces(bicyclePlaces)
           .carPlaces(carPlaces)
           .availability(availability)
    @@ -145,7 +145,7 @@ private VehicleParking.VehicleParkingEntranceCreator vehicleParkingEntrance() {
         String id = "Entrance";
         return builder ->
           builder
    -        .entranceId(TransitModelForTest.id(id))
    +        .entranceId(TimetableRepositoryForTest.id(id))
             .name(new NonLocalizedString(id))
             .coordinate(new WgsCoordinate(0, 0));
       }
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingPreferredTagsTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingPreferredTagsTest.java
    similarity index 96%
    rename from src/test/java/org/opentripplanner/street/model/edge/VehicleParkingPreferredTagsTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingPreferredTagsTest.java
    index 579ae4e964d..2f18f02b89b 100644
    --- a/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingPreferredTagsTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingPreferredTagsTest.java
    @@ -11,8 +11,8 @@
     import org.opentripplanner.framework.geometry.WgsCoordinate;
     import org.opentripplanner.framework.i18n.NonLocalizedString;
     import org.opentripplanner.routing.api.request.StreetMode;
    -import org.opentripplanner.routing.vehicle_parking.VehicleParkingEntrance;
    -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces;
    +import org.opentripplanner.service.vehicleparking.model.VehicleParkingEntrance;
    +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces;
     import org.opentripplanner.street.model._data.StreetModelForTest;
     import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex;
     import org.opentripplanner.street.model.vertex.Vertex;
    diff --git a/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java b/application/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java
    similarity index 99%
    rename from src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java
    index a3fbfcb018e..e8a1282327c 100644
    --- a/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java
    @@ -6,7 +6,6 @@
     import static org.junit.jupiter.api.Assertions.fail;
     
     import java.util.Set;
    -import javax.annotation.Nonnull;
     import org.junit.jupiter.api.Nested;
     import org.junit.jupiter.api.Test;
     import org.opentripplanner.routing.api.request.StreetMode;
    @@ -254,7 +253,6 @@ void startedOutsideNoDropOffZone() {
           assertEquals(VehicleRentalState.BEFORE_RENTING, afterTraversal.getVehicleRentalState());
         }
     
    -    @Nonnull
         private GeofencingZoneExtension noDropOffZone() {
           return new GeofencingZoneExtension(
             new GeofencingZone(new FeedScopedId(NETWORK, "zone"), null, true, false)
    diff --git a/src/test/java/org/opentripplanner/street/model/vertex/BarrierVertexTest.java b/application/src/test/java/org/opentripplanner/street/model/vertex/BarrierVertexTest.java
    similarity index 97%
    rename from src/test/java/org/opentripplanner/street/model/vertex/BarrierVertexTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/vertex/BarrierVertexTest.java
    index a92d69b39f0..a4bef911312 100644
    --- a/src/test/java/org/opentripplanner/street/model/vertex/BarrierVertexTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/vertex/BarrierVertexTest.java
    @@ -8,7 +8,7 @@
     import org.locationtech.jts.geom.Coordinate;
     import org.locationtech.jts.geom.LineString;
     import org.opentripplanner.framework.geometry.GeometryUtils;
    -import org.opentripplanner.openstreetmap.model.OSMNode;
    +import org.opentripplanner.osm.model.OsmNode;
     import org.opentripplanner.routing.graph.Graph;
     import org.opentripplanner.street.model.StreetTraversalPermission;
     import org.opentripplanner.street.model._data.StreetModelForTest;
    @@ -24,7 +24,7 @@ public class BarrierVertexTest {
     
       @Test
       public void testBarrierPermissions() {
    -    OSMNode simpleBarrier = new OSMNode();
    +    OsmNode simpleBarrier = new OsmNode();
         assertFalse(simpleBarrier.isMotorVehicleBarrier());
         simpleBarrier.addTag("barrier", "bollard");
         assertTrue(simpleBarrier.isMotorVehicleBarrier());
    @@ -63,7 +63,7 @@ public void testBarrierPermissions() {
         );
         assertEquals(StreetTraversalPermission.PEDESTRIAN, bv.getBarrierPermissions());
     
    -    OSMNode complexBarrier = new OSMNode();
    +    OsmNode complexBarrier = new OsmNode();
         complexBarrier.addTag("barrier", "bollard");
         complexBarrier.addTag("access", "no");
     
    @@ -72,7 +72,7 @@ public void testBarrierPermissions() {
         );
         assertEquals(StreetTraversalPermission.NONE, bv.getBarrierPermissions());
     
    -    OSMNode noBikeBollard = new OSMNode();
    +    OsmNode noBikeBollard = new OsmNode();
         noBikeBollard.addTag("barrier", "bollard");
         noBikeBollard.addTag("bicycle", "no");
     
    @@ -82,7 +82,7 @@ public void testBarrierPermissions() {
         assertEquals(StreetTraversalPermission.PEDESTRIAN, bv.getBarrierPermissions());
     
         /* test that traversal limitations work also without barrier tag  */
    -    OSMNode accessBarrier = new OSMNode();
    +    OsmNode accessBarrier = new OsmNode();
         accessBarrier.addTag("access", "no");
     
         bv.setBarrierPermissions(
    diff --git a/src/test/java/org/opentripplanner/street/model/vertex/IntersectionVertexTest.java b/application/src/test/java/org/opentripplanner/street/model/vertex/IntersectionVertexTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/vertex/IntersectionVertexTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/vertex/IntersectionVertexTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/vertex/OsmVertexTest.java b/application/src/test/java/org/opentripplanner/street/model/vertex/OsmVertexTest.java
    similarity index 85%
    rename from src/test/java/org/opentripplanner/street/model/vertex/OsmVertexTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/vertex/OsmVertexTest.java
    index b3a2b0baebb..298e4fe467f 100644
    --- a/src/test/java/org/opentripplanner/street/model/vertex/OsmVertexTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/vertex/OsmVertexTest.java
    @@ -5,14 +5,13 @@
     import static org.junit.jupiter.api.Assertions.assertTrue;
     
     import java.util.List;
    -import javax.annotation.Nonnull;
     import org.junit.jupiter.api.Test;
    -import org.opentripplanner.transit.model._data.TransitModelForTest;
    +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
     import org.opentripplanner.transit.model.site.AreaStop;
     
     class OsmVertexTest {
     
    -  private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of();
    +  private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of();
     
       private static final AreaStop AREA_STOP1 = TEST_MODEL.areaStop("flex-zone-1").build();
       private static final AreaStop AREA_STOP2 = TEST_MODEL.areaStop("flex-zone-2").build();
    @@ -38,7 +37,6 @@ void addAreaStop() {
         assertEquals(2, vertex.areaStops().size());
       }
     
    -  @Nonnull
       private static OsmVertex vertex() {
         return new OsmVertex(1, 2, 1);
       }
    diff --git a/src/test/java/org/opentripplanner/street/model/vertex/RentalRestrictionExtensionTest.java b/application/src/test/java/org/opentripplanner/street/model/vertex/RentalRestrictionExtensionTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/model/vertex/RentalRestrictionExtensionTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/vertex/RentalRestrictionExtensionTest.java
    diff --git a/src/test/java/org/opentripplanner/street/model/vertex/SimpleVertex.java b/application/src/test/java/org/opentripplanner/street/model/vertex/SimpleVertex.java
    similarity index 91%
    rename from src/test/java/org/opentripplanner/street/model/vertex/SimpleVertex.java
    rename to application/src/test/java/org/opentripplanner/street/model/vertex/SimpleVertex.java
    index 294bed335cc..b2df8bc6d16 100644
    --- a/src/test/java/org/opentripplanner/street/model/vertex/SimpleVertex.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/vertex/SimpleVertex.java
    @@ -1,6 +1,5 @@
     package org.opentripplanner.street.model.vertex;
     
    -import javax.annotation.Nonnull;
     import org.opentripplanner.framework.i18n.I18NString;
     
     public class SimpleVertex extends StreetVertex {
    @@ -12,7 +11,6 @@ public SimpleVertex(String label, double lat, double lon) {
         this.label = label;
       }
     
    -  @Nonnull
       @Override
       public I18NString getName() {
         return I18NString.of(label);
    diff --git a/src/test/java/org/opentripplanner/street/model/vertex/TemporaryVertexDisposeTest.java b/application/src/test/java/org/opentripplanner/street/model/vertex/TemporaryVertexDisposeTest.java
    similarity index 99%
    rename from src/test/java/org/opentripplanner/street/model/vertex/TemporaryVertexDisposeTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/vertex/TemporaryVertexDisposeTest.java
    index 7f559f2ad35..e4880f891e2 100644
    --- a/src/test/java/org/opentripplanner/street/model/vertex/TemporaryVertexDisposeTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/vertex/TemporaryVertexDisposeTest.java
    @@ -2,7 +2,6 @@
     
     import static org.junit.jupiter.api.Assertions.assertEquals;
     
    -import javax.annotation.Nonnull;
     import org.junit.jupiter.api.Test;
     import org.opentripplanner.framework.i18n.I18NString;
     import org.opentripplanner.street.model.edge.FreeEdge;
    @@ -232,7 +231,6 @@ public String toString() {
           return getLabelString();
         }
     
    -    @Nonnull
         @Override
         public I18NString getName() {
           return NO_NAME;
    diff --git a/src/test/java/org/opentripplanner/street/model/vertex/VertexTest.java b/application/src/test/java/org/opentripplanner/street/model/vertex/VertexTest.java
    similarity index 74%
    rename from src/test/java/org/opentripplanner/street/model/vertex/VertexTest.java
    rename to application/src/test/java/org/opentripplanner/street/model/vertex/VertexTest.java
    index 62194fdbc41..c839386f872 100644
    --- a/src/test/java/org/opentripplanner/street/model/vertex/VertexTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/model/vertex/VertexTest.java
    @@ -1,9 +1,11 @@
     package org.opentripplanner.street.model.vertex;
     
    +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 org.junit.jupiter.api.Test;
    +import org.opentripplanner.framework.geometry.WgsCoordinate;
     
     class VertexTest {
     
    @@ -25,4 +27,10 @@ void testDifferentLocation() {
         Vertex v2 = new SimpleVertex("", LAT + EPSILON_10_E_MINUS_7, LON);
         assertFalse(v1.sameLocation(v2));
       }
    +
    +  @Test
    +  void testWgsCoordinate() {
    +    Vertex v1 = new SimpleVertex("", LAT, LON);
    +    assertEquals(new WgsCoordinate(LAT, LON), v1.toWgsCoordinate());
    +  }
     }
    diff --git a/src/test/java/org/opentripplanner/street/search/TraverseModeSetTest.java b/application/src/test/java/org/opentripplanner/street/search/TraverseModeSetTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/search/TraverseModeSetTest.java
    rename to application/src/test/java/org/opentripplanner/street/search/TraverseModeSetTest.java
    diff --git a/src/test/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculatorTest.java b/application/src/test/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculatorTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculatorTest.java
    rename to application/src/test/java/org/opentripplanner/street/search/intersection_model/SimpleIntersectionTraversalCalculatorTest.java
    diff --git a/src/test/java/org/opentripplanner/street/search/request/StreetSearchRequestMapperTest.java b/application/src/test/java/org/opentripplanner/street/search/request/StreetSearchRequestMapperTest.java
    similarity index 89%
    rename from src/test/java/org/opentripplanner/street/search/request/StreetSearchRequestMapperTest.java
    rename to application/src/test/java/org/opentripplanner/street/search/request/StreetSearchRequestMapperTest.java
    index 3c33573621e..4e7f222a26f 100644
    --- a/src/test/java/org/opentripplanner/street/search/request/StreetSearchRequestMapperTest.java
    +++ b/application/src/test/java/org/opentripplanner/street/search/request/StreetSearchRequestMapperTest.java
    @@ -10,7 +10,7 @@
     import org.opentripplanner.routing.api.request.RequestModes;
     import org.opentripplanner.routing.api.request.RouteRequest;
     import org.opentripplanner.routing.api.request.StreetMode;
    -import org.opentripplanner.transit.model._data.TransitModelForTest;
    +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
     
     class StreetSearchRequestMapperTest {
     
    @@ -20,7 +20,7 @@ void map() {
     
         Instant dateTime = Instant.parse("2022-11-10T10:00:00Z");
         routeRequest.setDateTime(dateTime);
    -    var from = new GenericLocation(null, TransitModelForTest.id("STOP"), null, null);
    +    var from = new GenericLocation(null, TimetableRepositoryForTest.id("STOP"), null, null);
         routeRequest.setFrom(from);
         var to = new GenericLocation(60.0, 20.0);
         routeRequest.setTo(to);
    @@ -44,7 +44,7 @@ void mapToTransferRequest() {
     
         Instant dateTime = Instant.parse("2022-11-10T10:00:00Z");
         routeRequest.setDateTime(dateTime);
    -    var from = new GenericLocation(null, TransitModelForTest.id("STOP"), null, null);
    +    var from = new GenericLocation(null, TimetableRepositoryForTest.id("STOP"), null, null);
         routeRequest.setFrom(from);
         var to = new GenericLocation(60.0, 20.0);
         routeRequest.setTo(to);
    diff --git a/application/src/test/java/org/opentripplanner/street/search/state/EdgeTraverserTest.java b/application/src/test/java/org/opentripplanner/street/search/state/EdgeTraverserTest.java
    new file mode 100644
    index 00000000000..a2cd7e61b62
    --- /dev/null
    +++ b/application/src/test/java/org/opentripplanner/street/search/state/EdgeTraverserTest.java
    @@ -0,0 +1,191 @@
    +package org.opentripplanner.street.search.state;
    +
    +import static org.junit.jupiter.api.Assertions.assertEquals;
    +import static org.junit.jupiter.api.Assertions.assertSame;
    +import static org.junit.jupiter.api.Assertions.assertTrue;
    +import static org.opentripplanner.street.model._data.StreetModelForTest.intersectionVertex;
    +
    +import java.time.Instant;
    +import java.util.ArrayList;
    +import java.util.List;
    +import java.util.Set;
    +import java.util.function.Function;
    +import org.junit.jupiter.api.Test;
    +import org.opentripplanner._support.geometry.Coordinates;
    +import org.opentripplanner.routing.api.request.StreetMode;
    +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.vertex.IntersectionVertex;
    +import org.opentripplanner.street.search.TraverseMode;
    +import org.opentripplanner.street.search.request.StreetSearchRequest;
    +
    +class EdgeTraverserTest {
    +
    +  private static final IntersectionVertex BERLIN_V = intersectionVertex(Coordinates.BERLIN);
    +  private static final IntersectionVertex BRANDENBURG_GATE_V = intersectionVertex(
    +    Coordinates.BERLIN_BRANDENBURG_GATE
    +  );
    +  private static final IntersectionVertex FERNSEHTURM_V = intersectionVertex(
    +    Coordinates.BERLIN_FERNSEHTURM
    +  );
    +  private static final IntersectionVertex ADMIRALBRUCKE_V = intersectionVertex(
    +    Coordinates.BERLIN_ADMIRALBRUCKE
    +  );
    +
    +  @Test
    +  void emptyEdges() {
    +    var request = StreetSearchRequest
    +      .of()
    +      .withStartTime(Instant.EPOCH)
    +      .withMode(StreetMode.WALK)
    +      .build();
    +    var initialStates = State.getInitialStates(Set.of(BERLIN_V), request);
    +    var traversedState = EdgeTraverser.traverseEdges(initialStates, List.of());
    +
    +    assertSame(initialStates.iterator().next(), traversedState.get());
    +  }
    +
    +  @Test
    +  void failedTraversal() {
    +    var edge = StreetModelForTest
    +      .streetEdge(BERLIN_V, BRANDENBURG_GATE_V)
    +      .toBuilder()
    +      .withPermission(StreetTraversalPermission.NONE)
    +      .buildAndConnect();
    +
    +    var edges = List.of(edge);
    +    var request = StreetSearchRequest
    +      .of()
    +      .withStartTime(Instant.EPOCH)
    +      .withMode(StreetMode.WALK)
    +      .build();
    +    var initialStates = State.getInitialStates(Set.of(edge.getFromVertex()), request);
    +    var traversedState = EdgeTraverser.traverseEdges(initialStates, edges);
    +
    +    assertTrue(traversedState.isEmpty());
    +  }
    +
    +  @Test
    +  void withSingleState() {
    +    var edge = StreetModelForTest
    +      .streetEdge(BERLIN_V, BRANDENBURG_GATE_V)
    +      .toBuilder()
    +      .withPermission(StreetTraversalPermission.ALL)
    +      .buildAndConnect();
    +
    +    var edges = List.of(edge);
    +    var request = StreetSearchRequest
    +      .of()
    +      .withStartTime(Instant.EPOCH)
    +      .withMode(StreetMode.WALK)
    +      .build();
    +    var initialStates = State.getInitialStates(Set.of(edge.getFromVertex()), request);
    +    var traversedState = EdgeTraverser.traverseEdges(initialStates, edges).get();
    +
    +    assertEquals(List.of(TraverseMode.WALK), stateValues(traversedState, State::getBackMode));
    +    assertEquals(1719, traversedState.getElapsedTimeSeconds());
    +  }
    +
    +  @Test
    +  void withSingleArriveByState() {
    +    var edge = StreetModelForTest
    +      .streetEdge(BERLIN_V, BRANDENBURG_GATE_V)
    +      .toBuilder()
    +      .withPermission(StreetTraversalPermission.ALL)
    +      .buildAndConnect();
    +
    +    var edges = List.of(edge);
    +    var request = StreetSearchRequest
    +      .of()
    +      .withStartTime(Instant.EPOCH)
    +      .withMode(StreetMode.WALK)
    +      .withArriveBy(true)
    +      .build();
    +    var initialStates = State.getInitialStates(Set.of(edge.getToVertex()), request);
    +    var traversedState = EdgeTraverser.traverseEdges(initialStates, edges).get();
    +
    +    assertSame(BERLIN_V, traversedState.getVertex());
    +    assertEquals(List.of(TraverseMode.WALK), stateValues(traversedState, State::getBackMode));
    +    assertEquals(1719, traversedState.getElapsedTimeSeconds());
    +  }
    +
    +  @Test
    +  void withMultipleStates() {
    +    // CAR_PICKUP creates parallel walking and driving states
    +    // This tests that of the two states (WALKING, CAR) the least weight (CAR) is selected
    +    var edge = StreetModelForTest
    +      .streetEdge(BERLIN_V, BRANDENBURG_GATE_V)
    +      .toBuilder()
    +      .withPermission(StreetTraversalPermission.ALL)
    +      .buildAndConnect();
    +
    +    var edges = List.of(edge);
    +    var request = StreetSearchRequest
    +      .of()
    +      .withStartTime(Instant.EPOCH)
    +      .withMode(StreetMode.CAR_PICKUP)
    +      .build();
    +    var initialStates = State.getInitialStates(Set.of(edge.getFromVertex()), request);
    +    var traversedState = EdgeTraverser.traverseEdges(initialStates, edges).get();
    +
    +    assertEquals(List.of(TraverseMode.CAR), stateValues(traversedState, State::getBackMode));
    +    assertEquals(205, traversedState.getElapsedTimeSeconds());
    +  }
    +
    +  @Test
    +  void withDominatedStates() {
    +    // CAR_PICKUP creates parallel walking and driving states
    +    // This tests that the most optimal (walking and driving the last stretch) is found after
    +    // discarding the initial driving state for edge1
    +    var edge1 = StreetModelForTest
    +      .streetEdge(FERNSEHTURM_V, BERLIN_V)
    +      .toBuilder()
    +      .withPermission(StreetTraversalPermission.ALL)
    +      .buildAndConnect();
    +    var edge2 = StreetModelForTest
    +      .streetEdge(BERLIN_V, BRANDENBURG_GATE_V)
    +      .toBuilder()
    +      .withPermission(StreetTraversalPermission.PEDESTRIAN)
    +      .buildAndConnect();
    +    var edge3 = StreetModelForTest
    +      .streetEdge(BRANDENBURG_GATE_V, ADMIRALBRUCKE_V)
    +      .toBuilder()
    +      .withPermission(StreetTraversalPermission.ALL)
    +      .buildAndConnect();
    +
    +    var edges = List.of(edge1, edge2, edge3);
    +    var request = StreetSearchRequest
    +      .of()
    +      .withStartTime(Instant.EPOCH)
    +      .withMode(StreetMode.CAR_PICKUP)
    +      .build();
    +    var initialStates = State.getInitialStates(Set.of(edge1.getFromVertex()), request);
    +    var traversedState = EdgeTraverser.traverseEdges(initialStates, edges).get();
    +
    +    assertEquals(
    +      List.of(88.103, 2286.029, 3444.28),
    +      stateValues(
    +        traversedState,
    +        state -> state.getBackEdge() != null ? state.getBackEdge().getDistanceMeters() : null
    +      )
    +    );
    +    assertEquals(
    +      List.of(TraverseMode.WALK, TraverseMode.WALK, TraverseMode.CAR),
    +      stateValues(traversedState, State::getBackMode)
    +    );
    +    assertEquals(2169, traversedState.getElapsedTimeSeconds());
    +  }
    +
    +  private  List stateValues(State state, Function extractor) {
    +    var values = new ArrayList();
    +    while (state != null) {
    +      var value = extractor.apply(state);
    +      if (value != null) {
    +        values.add(value);
    +      }
    +      state = state.getBackState();
    +    }
    +    return values.reversed();
    +  }
    +}
    diff --git a/src/test/java/org/opentripplanner/street/search/state/StateDataTest.java b/application/src/test/java/org/opentripplanner/street/search/state/StateDataTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/search/state/StateDataTest.java
    rename to application/src/test/java/org/opentripplanner/street/search/state/StateDataTest.java
    diff --git a/src/test/java/org/opentripplanner/street/search/state/StateEditorTest.java b/application/src/test/java/org/opentripplanner/street/search/state/StateEditorTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/search/state/StateEditorTest.java
    rename to application/src/test/java/org/opentripplanner/street/search/state/StateEditorTest.java
    diff --git a/src/test/java/org/opentripplanner/street/search/state/StateTest.java b/application/src/test/java/org/opentripplanner/street/search/state/StateTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/search/state/StateTest.java
    rename to application/src/test/java/org/opentripplanner/street/search/state/StateTest.java
    diff --git a/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java b/application/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java
    similarity index 97%
    rename from src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java
    rename to application/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java
    index 3750c4619b9..7ea56f66145 100644
    --- a/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java
    +++ b/application/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java
    @@ -8,7 +8,6 @@
     import java.time.OffsetDateTime;
     import java.util.Arrays;
     import java.util.List;
    -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;
    @@ -36,7 +35,7 @@
     import org.opentripplanner.street.model.vertex.TransitStopVertex;
     import org.opentripplanner.street.search.TraverseMode;
     import org.opentripplanner.street.search.request.StreetSearchRequest;
    -import org.opentripplanner.transit.model._data.TransitModelForTest;
    +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
     import org.opentripplanner.transit.model.basic.Accessibility;
     import org.opentripplanner.transit.model.site.RegularStop;
     
    @@ -45,7 +44,7 @@
      */
     public class TestStateBuilder {
     
    -  private final TransitModelForTest testModel = TransitModelForTest.of();
    +  private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of();
     
       private static final Instant DEFAULT_START_TIME = OffsetDateTime
         .parse("2023-04-18T12:00:00+02:00")
    @@ -203,7 +202,7 @@ public TestStateBuilder elevator() {
     
         currentState =
           EdgeTraverser
    -        .traverseEdges(currentState, List.of(link, boardEdge, hopEdge, alightEdge))
    +        .traverseEdges(new State[] { currentState }, List.of(link, boardEdge, hopEdge, alightEdge))
             .orElseThrow();
         return this;
       }
    @@ -277,7 +276,6 @@ public TestStateBuilder pathway(String s) {
         return this;
       }
     
    -  @Nonnull
       private TestStateBuilder arriveAtStop(RegularStop stop) {
         var from = (StreetVertex) currentState.vertex;
         var to = TransitStopVertex.of().withStop(stop).build();
    @@ -296,7 +294,6 @@ private TestStateBuilder arriveAtStop(RegularStop stop) {
         return this;
       }
     
    -  @Nonnull
       private static ElevatorOffboardVertex elevatorOffBoard(int count, String suffix) {
         return new ElevatorOffboardVertex(
           StreetModelForTest.intersectionVertex(count, count),
    @@ -305,7 +302,6 @@ private static ElevatorOffboardVertex elevatorOffBoard(int count, String suffix)
         );
       }
     
    -  @Nonnull
       private static ElevatorOnboardVertex elevatorOnBoard(int count, String suffix) {
         return new ElevatorOnboardVertex(
           StreetModelForTest.intersectionVertex(count, count),
    diff --git a/src/test/java/org/opentripplanner/street/search/strategy/DominanceFunctionTest.java b/application/src/test/java/org/opentripplanner/street/search/strategy/DominanceFunctionTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/search/strategy/DominanceFunctionTest.java
    rename to application/src/test/java/org/opentripplanner/street/search/strategy/DominanceFunctionTest.java
    diff --git a/src/test/java/org/opentripplanner/street/service/DefaultStreetLimitationParametersServiceTest.java b/application/src/test/java/org/opentripplanner/street/service/DefaultStreetLimitationParametersServiceTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/street/service/DefaultStreetLimitationParametersServiceTest.java
    rename to application/src/test/java/org/opentripplanner/street/service/DefaultStreetLimitationParametersServiceTest.java
    diff --git a/src/test/java/org/opentripplanner/test/support/FilePatternArgumentsProvider.java b/application/src/test/java/org/opentripplanner/test/support/FilePatternArgumentsProvider.java
    similarity index 97%
    rename from src/test/java/org/opentripplanner/test/support/FilePatternArgumentsProvider.java
    rename to application/src/test/java/org/opentripplanner/test/support/FilePatternArgumentsProvider.java
    index c084a81a73f..9c0887c1da7 100644
    --- a/src/test/java/org/opentripplanner/test/support/FilePatternArgumentsProvider.java
    +++ b/application/src/test/java/org/opentripplanner/test/support/FilePatternArgumentsProvider.java
    @@ -35,12 +35,12 @@ public Stream provideArguments(ExtensionContext context) {
       }
     
       private static Stream resolvePaths(String pattern) {
    -    var pathMatcher = FileSystems.getDefault().getPathMatcher("glob:./" + pattern);
    +    var pathMatcher = FileSystems.getDefault().getPathMatcher("glob:../" + pattern);
     
         var pathsFound = new ArrayList();
         try {
           Files.walkFileTree(
    -        Paths.get("."),
    +        Paths.get(".."),
             new SimpleFileVisitor<>() {
               @Override
               public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
    diff --git a/src/test/java/org/opentripplanner/test/support/FilePatternSource.java b/application/src/test/java/org/opentripplanner/test/support/FilePatternSource.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/test/support/FilePatternSource.java
    rename to application/src/test/java/org/opentripplanner/test/support/FilePatternSource.java
    diff --git a/src/test/java/org/opentripplanner/test/support/GeoJsonIo.java b/application/src/test/java/org/opentripplanner/test/support/GeoJsonIo.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/test/support/GeoJsonIo.java
    rename to application/src/test/java/org/opentripplanner/test/support/GeoJsonIo.java
    diff --git a/src/test/java/org/opentripplanner/test/support/HttpForTest.java b/application/src/test/java/org/opentripplanner/test/support/HttpForTest.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/test/support/HttpForTest.java
    rename to application/src/test/java/org/opentripplanner/test/support/HttpForTest.java
    diff --git a/src/test/java/org/opentripplanner/test/support/JsonAssertions.java b/application/src/test/java/org/opentripplanner/test/support/JsonAssertions.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/test/support/JsonAssertions.java
    rename to application/src/test/java/org/opentripplanner/test/support/JsonAssertions.java
    diff --git a/src/test/java/org/opentripplanner/test/support/PolylineAssert.java b/application/src/test/java/org/opentripplanner/test/support/PolylineAssert.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/test/support/PolylineAssert.java
    rename to application/src/test/java/org/opentripplanner/test/support/PolylineAssert.java
    diff --git a/src/test/java/org/opentripplanner/test/support/ResourceLoader.java b/application/src/test/java/org/opentripplanner/test/support/ResourceLoader.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/test/support/ResourceLoader.java
    rename to application/src/test/java/org/opentripplanner/test/support/ResourceLoader.java
    diff --git a/src/test/java/org/opentripplanner/test/support/TestTableParser.java b/application/src/test/java/org/opentripplanner/test/support/TestTableParser.java
    similarity index 100%
    rename from src/test/java/org/opentripplanner/test/support/TestTableParser.java
    rename to application/src/test/java/org/opentripplanner/test/support/TestTableParser.java
    diff --git a/application/src/test/java/org/opentripplanner/transit/api/model/FilterValuesEmptyIsEverythingTest.java b/application/src/test/java/org/opentripplanner/transit/api/model/FilterValuesEmptyIsEverythingTest.java
    new file mode 100644
    index 00000000000..95e8f2ca292
    --- /dev/null
    +++ b/application/src/test/java/org/opentripplanner/transit/api/model/FilterValuesEmptyIsEverythingTest.java
    @@ -0,0 +1,22 @@
    +package org.opentripplanner.transit.api.model;
    +
    +import static org.junit.jupiter.api.Assertions.assertTrue;
    +
    +import java.util.List;
    +import org.junit.jupiter.api.Test;
    +
    +public class FilterValuesEmptyIsEverythingTest {
    +
    +  @Test
    +  void testEmptyIncludeEverything() {
    +    FilterValues filterValues = FilterValues.ofEmptyIsEverything("null", List.of());
    +    assertTrue(filterValues.includeEverything());
    +  }
    +
    +  @Test
    +  void testNullIncludeEverything() {
    +    List nullList = null;
    +    FilterValues filterValues2 = FilterValues.ofEmptyIsEverything("null", nullList);
    +    assertTrue(filterValues2.includeEverything());
    +  }
    +}
    diff --git a/application/src/test/java/org/opentripplanner/transit/api/model/RequiredFilterValuesTest.java b/application/src/test/java/org/opentripplanner/transit/api/model/RequiredFilterValuesTest.java
    new file mode 100644
    index 00000000000..7c06128c7bf
    --- /dev/null
    +++ b/application/src/test/java/org/opentripplanner/transit/api/model/RequiredFilterValuesTest.java
    @@ -0,0 +1,32 @@
    +package org.opentripplanner.transit.api.model;
    +
    +import static org.junit.jupiter.api.Assertions.*;
    +
    +import java.util.List;
    +import org.junit.jupiter.api.Test;
    +
    +class RequiredFilterValuesTest {
    +
    +  @Test
    +  void testEmptyIsInvalid() {
    +    IllegalArgumentException e = assertThrows(
    +      IllegalArgumentException.class,
    +      () -> {
    +        FilterValues.ofRequired("empty", List.of());
    +      }
    +    );
    +    assertEquals("Filter empty values must not be empty.", e.getMessage());
    +  }
    +
    +  @Test
    +  void testNullIsInvalid() {
    +    List nullList = null;
    +    IllegalArgumentException e = assertThrows(
    +      IllegalArgumentException.class,
    +      () -> {
    +        FilterValues.ofRequired("null", nullList);
    +      }
    +    );
    +    assertEquals("Filter null values must not be empty.", e.getMessage());
    +  }
    +}
    diff --git a/src/test/java/org/opentripplanner/transit/model/TransitModelArchitectureTest.java b/application/src/test/java/org/opentripplanner/transit/model/TimetableRepositoryArchitectureTest.java
    similarity index 98%
    rename from src/test/java/org/opentripplanner/transit/model/TransitModelArchitectureTest.java
    rename to application/src/test/java/org/opentripplanner/transit/model/TimetableRepositoryArchitectureTest.java
    index 11db763d97f..d2ae7e2e47d 100644
    --- a/src/test/java/org/opentripplanner/transit/model/TransitModelArchitectureTest.java
    +++ b/application/src/test/java/org/opentripplanner/transit/model/TimetableRepositoryArchitectureTest.java
    @@ -15,7 +15,7 @@
     import org.opentripplanner._support.arch.ArchComponent;
     import org.opentripplanner._support.arch.Package;
     
    -public class TransitModelArchitectureTest {
    +public class TimetableRepositoryArchitectureTest {
     
       private static final Package TRANSIT_FRAMEWORK = TRANSIT_MODEL.subPackage("framework");
       private static final Package BASIC = TRANSIT_MODEL.subPackage("basic");
    diff --git a/application/src/test/java/org/opentripplanner/transit/model/_data/PatternTestModel.java b/application/src/test/java/org/opentripplanner/transit/model/_data/PatternTestModel.java
    new file mode 100644
    index 00000000000..e046ea42247
    --- /dev/null
    +++ b/application/src/test/java/org/opentripplanner/transit/model/_data/PatternTestModel.java
    @@ -0,0 +1,50 @@
    +package org.opentripplanner.transit.model._data;
    +
    +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id;
    +
    +import org.opentripplanner.transit.model.framework.FeedScopedId;
    +import org.opentripplanner.transit.model.network.Route;
    +import org.opentripplanner.transit.model.network.StopPattern;
    +import org.opentripplanner.transit.model.network.TripPattern;
    +import org.opentripplanner.transit.model.site.RegularStop;
    +import org.opentripplanner.transit.model.timetable.ScheduledTripTimes;
    +import org.opentripplanner.transit.model.timetable.Trip;
    +import org.opentripplanner.transit.service.SiteRepository;
    +
    +public class PatternTestModel {
    +
    +  public static final Route ROUTE_1 = TimetableRepositoryForTest.route("1").build();
    +
    +  private static final FeedScopedId SERVICE_ID = id("service");
    +  private static final Trip TRIP = TimetableRepositoryForTest
    +    .trip("t1")
    +    .withRoute(ROUTE_1)
    +    .withServiceId(SERVICE_ID)
    +    .build();
    +  private static final TimetableRepositoryForTest MODEL = new TimetableRepositoryForTest(
    +    SiteRepository.of()
    +  );
    +  private static final RegularStop STOP_1 = MODEL.stop("1").build();
    +  private static final StopPattern STOP_PATTERN = TimetableRepositoryForTest.stopPattern(
    +    STOP_1,
    +    STOP_1
    +  );
    +
    +  /**
    +   * Creates a trip pattern that has a stop pattern, trip times and a trip with a service id.
    +   */
    +  public static TripPattern pattern() {
    +    var tt = ScheduledTripTimes
    +      .of()
    +      .withTrip(TRIP)
    +      .withArrivalTimes("10:00 10:05")
    +      .withDepartureTimes("10:00 10:05")
    +      .build();
    +
    +    return TimetableRepositoryForTest
    +      .tripPattern("1", ROUTE_1)
    +      .withStopPattern(STOP_PATTERN)
    +      .withScheduledTimeTableBuilder(builder -> builder.addTripTimes(tt))
    +      .build();
    +  }
    +}
    diff --git a/src/test/java/org/opentripplanner/transit/model/_data/TransitModelForTest.java b/application/src/test/java/org/opentripplanner/transit/model/_data/TimetableRepositoryForTest.java
    similarity index 91%
    rename from src/test/java/org/opentripplanner/transit/model/_data/TransitModelForTest.java
    rename to application/src/test/java/org/opentripplanner/transit/model/_data/TimetableRepositoryForTest.java
    index 0f6d872c639..f8dbf97efb9 100644
    --- a/src/test/java/org/opentripplanner/transit/model/_data/TransitModelForTest.java
    +++ b/application/src/test/java/org/opentripplanner/transit/model/_data/TimetableRepositoryForTest.java
    @@ -38,19 +38,20 @@
     import org.opentripplanner.transit.model.site.StopTransferPriority;
     import org.opentripplanner.transit.model.timetable.Trip;
     import org.opentripplanner.transit.model.timetable.TripBuilder;
    -import org.opentripplanner.transit.service.StopModel;
    -import org.opentripplanner.transit.service.StopModelBuilder;
    +import org.opentripplanner.transit.service.SiteRepository;
    +import org.opentripplanner.transit.service.SiteRepositoryBuilder;
    +import org.opentripplanner.utils.time.TimeUtils;
     
     /**
      * Test utility class to help construct valid transit model objects.
      * 

    * TODO: This need cleanup - it has static factory methods. This is not safe, since * all objects created will be created in the same context. All stops are created - * withing the context of a StopModel, mixing more than one model in a test is sharing + * withing the context of a SiteRepository, mixing more than one model in a test is sharing * state between tests. For now, it is just the stop index - but we want to - * use this to encapsulate the StopModel completely. + * use this to encapsulate the SiteRepository completely. */ -public class TransitModelForTest { +public class TimetableRepositoryForTest { public static final String FEED_ID = "F"; public static final String TIME_ZONE_ID = "Europe/Paris"; @@ -89,14 +90,14 @@ public class TransitModelForTest { .withUrl("https:/www.otherfeedagency.com") .build(); - private final StopModelBuilder stopModelBuilder; + private final SiteRepositoryBuilder siteRepositoryBuilder; - public TransitModelForTest(StopModelBuilder stopModelBuilder) { - this.stopModelBuilder = stopModelBuilder; + public TimetableRepositoryForTest(SiteRepositoryBuilder siteRepositoryBuilder) { + this.siteRepositoryBuilder = siteRepositoryBuilder; } - public static TransitModelForTest of() { - return new TransitModelForTest(StopModel.of()); + public static TimetableRepositoryForTest of() { + return new TimetableRepositoryForTest(SiteRepository.of()); } public static FeedScopedId id(String id) { @@ -137,15 +138,15 @@ public static TripBuilder trip(String feedId, String tripId) { return Trip.of(FeedScopedId.ofNullable(feedId, tripId)).withRoute(route("R" + tripId).build()); } - public StopModelBuilder stopModelBuilder() { - return stopModelBuilder; + public SiteRepositoryBuilder siteRepositoryBuilder() { + return siteRepositoryBuilder; } /** * Create a stop with all required fields set. */ public RegularStopBuilder stop(String idAndName) { - return stopModelBuilder + return siteRepositoryBuilder .regularStop(id(idAndName)) .withName(new NonLocalizedString(idAndName)) .withCode(idAndName) @@ -167,7 +168,7 @@ public StationBuilder station(String idAndName) { } public GroupStop groupStop(String idAndName, RegularStop... stops) { - var builder = stopModelBuilder + var builder = siteRepositoryBuilder .groupStop(id(idAndName)) .withName(new NonLocalizedString(idAndName)); @@ -177,7 +178,7 @@ public GroupStop groupStop(String idAndName, RegularStop... stops) { } public AreaStopBuilder areaStop(String idAndName) { - return stopModelBuilder + return siteRepositoryBuilder .areaStop(id(idAndName)) .withName(new NonLocalizedString(idAndName)) .withGeometry(ANY_POLYGON); @@ -227,7 +228,8 @@ public Place place(String name, double lat, double lon) { *

    * The first stop has stop sequence 10, the following one has 20 and so on. */ - public List stopTimesEvery5Minutes(int count, Trip trip, int startTime) { + public List stopTimesEvery5Minutes(int count, Trip trip, String time) { + var startTime = TimeUtils.time(time); return IntStream .range(0, count) .mapToObj(seq -> stopTime(trip, (seq + 1) * 10, startTime + (seq * 60 * 5))) diff --git a/src/test/java/org/opentripplanner/transit/model/basic/MainAndSubModeTest.java b/application/src/test/java/org/opentripplanner/transit/model/basic/MainAndSubModeTest.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/model/basic/MainAndSubModeTest.java rename to application/src/test/java/org/opentripplanner/transit/model/basic/MainAndSubModeTest.java diff --git a/src/test/java/org/opentripplanner/transit/model/basic/NoticeTest.java b/application/src/test/java/org/opentripplanner/transit/model/basic/NoticeTest.java similarity index 87% rename from src/test/java/org/opentripplanner/transit/model/basic/NoticeTest.java rename to application/src/test/java/org/opentripplanner/transit/model/basic/NoticeTest.java index 5cdd6f37e5c..5306d31077a 100644 --- a/src/test/java/org/opentripplanner/transit/model/basic/NoticeTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/basic/NoticeTest.java @@ -7,7 +7,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; class NoticeTest { @@ -16,7 +16,7 @@ class NoticeTest { private static final String PUBLIC_CODE = "public code"; private static final Notice subject = Notice - .of(TransitModelForTest.id(ID)) + .of(TimetableRepositoryForTest.id(ID)) .withPublicCode(PUBLIC_CODE) .withText(TEXT) .build(); @@ -45,7 +45,7 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withPublicCode("X").build())); assertFalse(subject.sameAs(subject.copy().withText("X").build())); } diff --git a/application/src/test/java/org/opentripplanner/transit/model/filter/expr/AndMatcherTest.java b/application/src/test/java/org/opentripplanner/transit/model/filter/expr/AndMatcherTest.java new file mode 100644 index 00000000000..c79260193ff --- /dev/null +++ b/application/src/test/java/org/opentripplanner/transit/model/filter/expr/AndMatcherTest.java @@ -0,0 +1,39 @@ +package org.opentripplanner.transit.model.filter.expr; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class AndMatcherTest { + + @Test + void testMatchSingleMatcher() { + var matcher = AndMatcher.of(List.of(new EqualityMatcher<>("int", 42, i -> i))); + assertTrue(matcher.match(42)); + assertFalse(matcher.match(43)); + } + + @Test + void testMatchMultiple() { + var matcher = AndMatcher.of( + List.of(new EqualityMatcher<>("int", 42, i -> i), new EqualityMatcher<>("int", 43, i -> i)) + ); + assertFalse(matcher.match(42)); + assertFalse(matcher.match(43)); + assertFalse(matcher.match(44)); + } + + @Test + void testMatchComposites() { + var matcher = AndMatcher.of( + List.of( + OrMatcher.of(List.of(new EqualityMatcher<>("int", 42, i -> i))), + OrMatcher.of(List.of(new EqualityMatcher<>("int", 43, i -> i))) + ) + ); + assertFalse(matcher.match(42)); + assertFalse(matcher.match(43)); + assertFalse(matcher.match(44)); + } +} diff --git a/application/src/test/java/org/opentripplanner/transit/model/filter/expr/ContainsMatcherTest.java b/application/src/test/java/org/opentripplanner/transit/model/filter/expr/ContainsMatcherTest.java new file mode 100644 index 00000000000..1709fc7bf86 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/transit/model/filter/expr/ContainsMatcherTest.java @@ -0,0 +1,33 @@ +package org.opentripplanner.transit.model.filter.expr; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class ContainsMatcherTest { + + private static final Map> integerListMap = Map.of( + 1, + List.of("foo"), + 2, + List.of("bar"), + 3, + List.of("foo", "bar") + ); + + @Test + void testMatch() { + var matcher = new ContainsMatcher<>( + "contains", + integerListMap::get, + new EqualityMatcher<>("string", "foo", s -> s) + ); + + assertTrue(matcher.match(1)); + assertFalse(matcher.match(2)); + assertTrue(matcher.match(3)); + assertFalse(matcher.match(4)); + } +} diff --git a/application/src/test/java/org/opentripplanner/transit/model/filter/expr/EqualityMatcherTest.java b/application/src/test/java/org/opentripplanner/transit/model/filter/expr/EqualityMatcherTest.java new file mode 100644 index 00000000000..31d208a768a --- /dev/null +++ b/application/src/test/java/org/opentripplanner/transit/model/filter/expr/EqualityMatcherTest.java @@ -0,0 +1,22 @@ +package org.opentripplanner.transit.model.filter.expr; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class EqualityMatcherTest { + + @Test + void testMatchesPrimitive() { + var matcher = new EqualityMatcher<>("int", 42, i -> i); + assertTrue(matcher.match(42)); + assertFalse(matcher.match(43)); + } + + @Test + void testMatchesObject() { + var matcher = new EqualityMatcher<>("string", "foo", s -> s); + assertTrue(matcher.match("foo")); + assertFalse(matcher.match("bar")); + } +} diff --git a/application/src/test/java/org/opentripplanner/transit/model/filter/expr/OrMatcherTest.java b/application/src/test/java/org/opentripplanner/transit/model/filter/expr/OrMatcherTest.java new file mode 100644 index 00000000000..415f64e40ed --- /dev/null +++ b/application/src/test/java/org/opentripplanner/transit/model/filter/expr/OrMatcherTest.java @@ -0,0 +1,31 @@ +package org.opentripplanner.transit.model.filter.expr; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class OrMatcherTest { + + @Test + void testMatch() { + var matcher = OrMatcher.of( + new EqualityMatcher<>("int", 42, i -> i), + new EqualityMatcher<>("int", 43, i -> i) + ); + assertTrue(matcher.match(42)); + assertTrue(matcher.match(43)); + assertFalse(matcher.match(44)); + } + + @Test + void testMatchComposites() { + var matcher = OrMatcher.of( + AndMatcher.of(List.of(new EqualityMatcher<>("int", 42, i -> i))), + AndMatcher.of(List.of(new EqualityMatcher<>("int", 43, i -> i))) + ); + assertTrue(matcher.match(42)); + assertTrue(matcher.match(43)); + assertFalse(matcher.match(44)); + } +} diff --git a/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TripMatcherFactoryTest.java b/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TripMatcherFactoryTest.java new file mode 100644 index 00000000000..ec4b3241dd5 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TripMatcherFactoryTest.java @@ -0,0 +1,157 @@ +package org.opentripplanner.transit.model.filter.transit; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.time.LocalDate; +import java.util.List; +import java.util.Set; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.opentripplanner.transit.api.model.FilterValues; +import org.opentripplanner.transit.api.request.TripRequest; +import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.transit.model.filter.expr.Matcher; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.transit.model.organization.Agency; +import org.opentripplanner.transit.model.timetable.Trip; + +public class TripMatcherFactoryTest { + + private Trip tripRut; + private Trip tripRut2; + private Trip tripAkt; + + @BeforeEach + void setup() { + tripRut = + Trip + .of(new FeedScopedId("F", "RUT:route:trip:1")) + .withRoute( + Route + .of(new FeedScopedId("F", "RUT:route:1")) + .withAgency( + Agency + .of(new FeedScopedId("F", "RUT:1")) + .withName("RUT") + .withTimezone("Europe/Oslo") + .build() + ) + .withMode(TransitMode.BUS) + .withShortName("BUS") + .build() + ) + .withServiceId(new FeedScopedId("F", "RUT:route:trip:1")) + .build(); + tripRut2 = + Trip + .of(new FeedScopedId("F", "RUT:route:trip:2")) + .withRoute( + Route + .of(new FeedScopedId("F", "RUT:route:2")) + .withAgency( + Agency + .of(new FeedScopedId("F", "RUT:2")) + .withName("RUT") + .withTimezone("Europe/Oslo") + .build() + ) + .withMode(TransitMode.BUS) + .withShortName("BUS") + .build() + ) + .withServiceId(new FeedScopedId("F", "RUT:route:trip:2")) + .build(); + tripAkt = + Trip + .of(new FeedScopedId("F", "AKT:route:trip:1")) + .withRoute( + Route + .of(new FeedScopedId("F", "AKT:route:1")) + .withAgency( + Agency + .of(new FeedScopedId("F", "AKT")) + .withName("AKT") + .withTimezone("Europe/Oslo") + .build() + ) + .withMode(TransitMode.BUS) + .withShortName("BUS") + .build() + ) + .withServiceId(new FeedScopedId("F", "AKT:route:trip:1")) + .build(); + } + + @Test + void testMatchRouteId() { + TripRequest request = TripRequest + .of() + .withRoutes( + FilterValues.ofEmptyIsEverything("routes", List.of(new FeedScopedId("F", "RUT:route:1"))) + ) + .build(); + + Matcher matcher = TripMatcherFactory.of(request, feedScopedId -> Set.of()); + + assertTrue(matcher.match(tripRut)); + assertFalse(matcher.match(tripRut2)); + assertFalse(matcher.match(tripAkt)); + } + + @Test + void testMatchDefaultAll() { + TripRequest request = TripRequest.of().build(); + + Matcher matcher = TripMatcherFactory.of(request, feedScopedId -> Set.of()); + + assertTrue(matcher.match(tripRut)); + assertTrue(matcher.match(tripRut2)); + assertTrue(matcher.match(tripAkt)); + } + + @Test + void testMatchAgencyId() { + TripRequest request = TripRequest + .of() + .withAgencies( + FilterValues.ofEmptyIsEverything("agencies", List.of(new FeedScopedId("F", "RUT:1"))) + ) + .build(); + + Matcher matcher = TripMatcherFactory.of(request, feedScopedId -> Set.of()); + + assertTrue(matcher.match(tripRut)); + assertFalse(matcher.match(tripRut2)); + assertFalse(matcher.match(tripAkt)); + } + + @Test + void testMatchServiceDates() { + TripRequest request = TripRequest + .of() + .withServiceDates( + FilterValues.ofEmptyIsEverything( + "operatingDays", + List.of(LocalDate.of(2024, 2, 22), LocalDate.of(2024, 2, 23)) + ) + ) + .build(); + + Matcher matcher = TripMatcherFactory.of(request, this::dummyServiceDateProvider); + + assertTrue(matcher.match(tripRut)); + assertTrue(matcher.match(tripRut2)); + assertFalse(matcher.match(tripAkt)); + } + + private Set dummyServiceDateProvider(FeedScopedId feedScopedId) { + if (feedScopedId.equals(new FeedScopedId("F", "RUT:route:trip:1"))) { + return Set.of(LocalDate.of(2024, 2, 22), LocalDate.of(2024, 2, 23)); + } else if (feedScopedId.equals(new FeedScopedId("F", "RUT:route:trip:2"))) { + return Set.of(LocalDate.of(2024, 2, 23)); + } + return Set.of(); + } +} diff --git a/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactoryTest.java b/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactoryTest.java new file mode 100644 index 00000000000..dcfb10b5947 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactoryTest.java @@ -0,0 +1,174 @@ +package org.opentripplanner.transit.model.filter.transit; + +import static org.junit.jupiter.api.Assertions.*; + +import java.time.LocalDate; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.opentripplanner.transit.api.model.FilterValues; +import org.opentripplanner.transit.api.request.TripOnServiceDateRequest; +import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.transit.model.filter.expr.Matcher; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.transit.model.organization.Agency; +import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.transit.model.timetable.TripOnServiceDate; + +class TripOnServiceDateMatcherFactoryTest { + + private TripOnServiceDate tripOnServiceDateRut; + private TripOnServiceDate tripOnServiceDateRut2; + private TripOnServiceDate tripOnServiceDateAkt; + + @BeforeEach + void setup() { + tripOnServiceDateRut = + TripOnServiceDate + .of(new FeedScopedId("F", "RUT:route:trip:date:1")) + .withTrip( + Trip + .of(new FeedScopedId("F", "RUT:route:trip:1")) + .withRoute( + Route + .of(new FeedScopedId("F", "RUT:route:1")) + .withAgency( + Agency + .of(new FeedScopedId("F", "RUT:1")) + .withName("RUT") + .withTimezone("Europe/Oslo") + .build() + ) + .withMode(TransitMode.BUS) + .withShortName("BUS") + .build() + ) + .build() + ) + .withServiceDate(LocalDate.of(2024, 2, 22)) + .build(); + + tripOnServiceDateRut2 = + TripOnServiceDate + .of(new FeedScopedId("F", "RUT:route:trip:date:2")) + .withTrip( + Trip + .of(new FeedScopedId("F", "RUT:route:trip:2")) + .withRoute( + Route + .of(new FeedScopedId("F", "RUT:route:2")) + .withAgency( + Agency + .of(new FeedScopedId("F", "RUT:2")) + .withName("RUT") + .withTimezone("Europe/Oslo") + .build() + ) + .withMode(TransitMode.BUS) + .withShortName("BUS") + .build() + ) + .build() + ) + .withServiceDate(LocalDate.of(2024, 2, 22)) + .build(); + + tripOnServiceDateAkt = + TripOnServiceDate + .of(new FeedScopedId("F", "AKT:route:trip:date:1")) + .withTrip( + Trip + .of(new FeedScopedId("F", "AKT:route:trip:1")) + .withRoute( + Route + .of(new FeedScopedId("F", "AKT:route:1")) + .withAgency( + Agency + .of(new FeedScopedId("F", "AKT:1")) + .withName("AKT") + .withTimezone("Europe/Oslo") + .build() + ) + .withMode(TransitMode.BUS) + .withShortName("BUS") + .build() + ) + .build() + ) + .withServiceDate(LocalDate.of(2024, 2, 22)) + .build(); + } + + @Test + void testMatchOperatingDays() { + TripOnServiceDateRequest request = TripOnServiceDateRequest + .of(FilterValues.ofRequired("serviceDates", List.of(LocalDate.of(2024, 2, 22)))) + .build(); + + Matcher matcher = TripOnServiceDateMatcherFactory.of(request); + + assertTrue(matcher.match(tripOnServiceDateRut)); + assertTrue(matcher.match(tripOnServiceDateRut2)); + assertTrue(matcher.match(tripOnServiceDateAkt)); + } + + @Test + void testMatchMultiple() { + TripOnServiceDateRequest request = TripOnServiceDateRequest + .of(FilterValues.ofRequired("serviceDates", List.of(LocalDate.of(2024, 2, 22)))) + .withAgencies( + FilterValues.ofEmptyIsEverything("agencies", List.of(new FeedScopedId("F", "RUT:1"))) + ) + .withRoutes( + FilterValues.ofEmptyIsEverything("routes", List.of(new FeedScopedId("F", "RUT:route:1"))) + ) + .withServiceJourneys( + FilterValues.ofEmptyIsEverything( + "serviceJourneys", + List.of(new FeedScopedId("F", "RUT:route:trip:1")) + ) + ) + .build(); + + Matcher matcher = TripOnServiceDateMatcherFactory.of(request); + + assertTrue(matcher.match(tripOnServiceDateRut)); + assertFalse(matcher.match(tripOnServiceDateRut2)); + assertFalse(matcher.match(tripOnServiceDateAkt)); + } + + @Test + void testMatchMultipleServiceJourneyMatchers() { + TripOnServiceDateRequest request = TripOnServiceDateRequest + .of(FilterValues.ofRequired("serviceDates", List.of(LocalDate.of(2024, 2, 22)))) + .withAgencies( + FilterValues.ofEmptyIsEverything( + "agencies", + List.of(new FeedScopedId("F", "RUT:1"), new FeedScopedId("F", "RUT:2")) + ) + ) + .withRoutes( + FilterValues.ofEmptyIsEverything( + "routes", + List.of(new FeedScopedId("F", "RUT:route:1"), new FeedScopedId("F", "RUT:route:2")) + ) + ) + .withServiceJourneys( + FilterValues.ofEmptyIsEverything( + "serviceJourneys", + List.of( + new FeedScopedId("F", "RUT:route:trip:1"), + new FeedScopedId("F", "RUT:route:trip:2") + ) + ) + ) + .build(); + + Matcher matcher = TripOnServiceDateMatcherFactory.of(request); + + assertTrue(matcher.match(tripOnServiceDateRut)); + assertTrue(matcher.match(tripOnServiceDateRut2)); + assertFalse(matcher.match(tripOnServiceDateAkt)); + } +} diff --git a/src/test/java/org/opentripplanner/transit/model/framework/EntityByIdTest.java b/application/src/test/java/org/opentripplanner/transit/model/framework/EntityByIdTest.java similarity index 89% rename from src/test/java/org/opentripplanner/transit/model/framework/EntityByIdTest.java rename to application/src/test/java/org/opentripplanner/transit/model/framework/EntityByIdTest.java index 146c2c9e5ae..c89d45cc036 100644 --- a/src/test/java/org/opentripplanner/transit/model/framework/EntityByIdTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/framework/EntityByIdTest.java @@ -5,18 +5,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Collections; -import javax.annotation.Nonnull; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; public class EntityByIdTest { - private static final FeedScopedId ID = TransitModelForTest.id("99"); + private static final FeedScopedId ID = TimetableRepositoryForTest.id("99"); private static final TestEntity E = TestEntity.of(ID).build(); private static final String E_TO_STRING = E.toString(); private static final String LIST_OF_E_TO_STRING = String.format("[%s]", E_TO_STRING); private static final String MAP_OF_E_TO_STRING = String.format("{%s=%s}", ID, E_TO_STRING); - private static final FeedScopedId FAKE_ID = TransitModelForTest.id("77"); + private static final FeedScopedId FAKE_ID = TimetableRepositoryForTest.id("77"); private final EntityById subject = new DefaultEntityById<>(); @Test @@ -84,11 +83,10 @@ public static TestEntityBuilder of(FeedScopedId id) { } @Override - public boolean sameAs(@Nonnull TestEntity other) { + public boolean sameAs(TestEntity other) { return getId().equals(other.getId()); } - @Nonnull @Override public TransitBuilder copy() { return new TestEntityBuilder(this); diff --git a/application/src/test/java/org/opentripplanner/transit/model/framework/EntityNotFoundExceptionTest.java b/application/src/test/java/org/opentripplanner/transit/model/framework/EntityNotFoundExceptionTest.java new file mode 100644 index 00000000000..f33eb389a37 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/transit/model/framework/EntityNotFoundExceptionTest.java @@ -0,0 +1,22 @@ +package org.opentripplanner.transit.model.framework; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class EntityNotFoundExceptionTest { + + private static final FeedScopedId ID = FeedScopedId.ofNullable("F", "1"); + + @Test + void getMessage() { + assertEquals( + "Integer entity not found: F:1", + new EntityNotFoundException(Integer.class, ID).getMessage() + ); + assertEquals( + "Stop or Station entity not found: F:1", + new EntityNotFoundException("Stop or Station", ID).getMessage() + ); + } +} diff --git a/src/test/java/org/opentripplanner/transit/model/framework/FeedScopedIdTest.java b/application/src/test/java/org/opentripplanner/transit/model/framework/FeedScopedIdTest.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/model/framework/FeedScopedIdTest.java rename to application/src/test/java/org/opentripplanner/transit/model/framework/FeedScopedIdTest.java diff --git a/src/test/java/org/opentripplanner/transit/model/framework/ResultTest.java b/application/src/test/java/org/opentripplanner/transit/model/framework/ResultTest.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/model/framework/ResultTest.java rename to application/src/test/java/org/opentripplanner/transit/model/framework/ResultTest.java diff --git a/src/test/java/org/opentripplanner/transit/model/network/GroupOfRoutesTest.java b/application/src/test/java/org/opentripplanner/transit/model/network/GroupOfRoutesTest.java similarity index 90% rename from src/test/java/org/opentripplanner/transit/model/network/GroupOfRoutesTest.java rename to application/src/test/java/org/opentripplanner/transit/model/network/GroupOfRoutesTest.java index ca61e3c30f3..2788b62bae9 100644 --- a/src/test/java/org/opentripplanner/transit/model/network/GroupOfRoutesTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/network/GroupOfRoutesTest.java @@ -7,7 +7,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; public class GroupOfRoutesTest { @@ -18,7 +18,7 @@ public class GroupOfRoutesTest { private static final String DESCRIPTION = "description"; private static final GroupOfRoutes subject = GroupOfRoutes - .of(TransitModelForTest.id(ID)) + .of(TimetableRepositoryForTest.id(ID)) .withPrivateCode(PRIVATE_CODE) .withShortName(SHORT_NAME) .withName(NAME) @@ -52,7 +52,7 @@ public void sameValue() { // Make a copy, and set the same name (nothing is changed) var other = subject.copy().build(); assertTrue(subject.sameAs(other)); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withName("X").build())); assertFalse(subject.sameAs(subject.copy().withDescription("X").build())); assertFalse(subject.sameAs(subject.copy().withShortName("X").build())); diff --git a/src/test/java/org/opentripplanner/transit/model/network/RouteTest.java b/application/src/test/java/org/opentripplanner/transit/model/network/RouteTest.java similarity index 92% rename from src/test/java/org/opentripplanner/transit/model/network/RouteTest.java rename to application/src/test/java/org/opentripplanner/transit/model/network/RouteTest.java index e21465547a1..65bc3bb53a9 100644 --- a/src/test/java/org/opentripplanner/transit/model/network/RouteTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/network/RouteTest.java @@ -8,7 +8,7 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.SubMode; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -39,9 +39,9 @@ class RouteTest { private static final String FLEXIBLE_LINE_TYPE = "flexible line type"; private static final Integer GTFS_SORT_ORDER = 0; private static final String URL = "url"; - public static final Agency AGENCY = TransitModelForTest.AGENCY; + public static final Agency AGENCY = TimetableRepositoryForTest.AGENCY; private static final Route subject = Route - .of(TransitModelForTest.id(ID)) + .of(TimetableRepositoryForTest.id(ID)) .withShortName(SHORT_NAME) .withLongName(LONG_NAME) .withDescription(DESCRIPTION) @@ -96,7 +96,7 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withShortName("X").build())); assertFalse(subject.sameAs(subject.copy().withLongName(new NonLocalizedString("X")).build())); assertFalse(subject.sameAs(subject.copy().withDescription("X").build())); @@ -116,7 +116,9 @@ void sameAs() { .build() ) ); - assertFalse(subject.sameAs(subject.copy().withAgency(TransitModelForTest.agency("X")).build())); + assertFalse( + subject.sameAs(subject.copy().withAgency(TimetableRepositoryForTest.agency("X")).build()) + ); assertFalse( subject.sameAs( subject diff --git a/src/test/java/org/opentripplanner/transit/model/network/StopPatternTest.java b/application/src/test/java/org/opentripplanner/transit/model/network/StopPatternTest.java similarity index 87% rename from src/test/java/org/opentripplanner/transit/model/network/StopPatternTest.java rename to application/src/test/java/org/opentripplanner/transit/model/network/StopPatternTest.java index 1bce2edf9dc..2b3a59cefab 100644 --- a/src/test/java/org/opentripplanner/transit/model/network/StopPatternTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/network/StopPatternTest.java @@ -6,12 +6,12 @@ import java.util.List; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.timetable.Trip; class StopPatternTest { - private final TransitModelForTest testModel = TransitModelForTest.of(); + private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of(); @Test void boardingAlightingConditions() { @@ -25,7 +25,7 @@ void boardingAlightingConditions() { var areaStop = testModel.areaStop("area").build(); - Trip t = TransitModelForTest.trip("trip").build(); + Trip t = TimetableRepositoryForTest.trip("trip").build(); StopPattern stopPattern = new StopPattern( List.of( @@ -54,7 +54,7 @@ void replaceStop() { var s3 = testModel.stop("3").build(); var s4 = testModel.stop("4").build(); - var pattern = TransitModelForTest.stopPattern(s1, s2, s3); + var pattern = TimetableRepositoryForTest.stopPattern(s1, s2, s3); assertEquals(List.of(s1, s2, s3), pattern.getStops()); diff --git a/src/test/java/org/opentripplanner/transit/model/network/SubModeTest.java b/application/src/test/java/org/opentripplanner/transit/model/network/SubModeTest.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/model/network/SubModeTest.java rename to application/src/test/java/org/opentripplanner/transit/model/network/SubModeTest.java diff --git a/src/test/java/org/opentripplanner/transit/model/network/TripPatternTest.java b/application/src/test/java/org/opentripplanner/transit/model/network/TripPatternTest.java similarity index 70% rename from src/test/java/org/opentripplanner/transit/model/network/TripPatternTest.java rename to application/src/test/java/org/opentripplanner/transit/model/network/TripPatternTest.java index b2adc7544a3..32563545694 100644 --- a/src/test/java/org/opentripplanner/transit/model/network/TripPatternTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/network/TripPatternTest.java @@ -6,13 +6,13 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.framework.geometry.GeometryUtils.makeLineString; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.locationtech.jts.geom.LineString; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.site.RegularStop; @@ -20,21 +20,23 @@ class TripPatternTest { private static final String ID = "1"; private static final String NAME = "short name"; - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); - private static final Route ROUTE = TransitModelForTest.route("routeId").build(); + private static final Route ROUTE = TimetableRepositoryForTest.route("routeId").build(); public static final RegularStop STOP_A = TEST_MODEL.stop("A").build(); + public static final RegularStop STOP_X = TEST_MODEL.stop("X").build(); public static final RegularStop STOP_B = TEST_MODEL.stop("B").build(); + public static final RegularStop STOP_Y = TEST_MODEL.stop("Y").build(); public static final RegularStop STOP_C = TEST_MODEL.stop("C").build(); - private static final StopPattern STOP_PATTERN = TransitModelForTest.stopPattern( + private static final StopPattern STOP_PATTERN = TimetableRepositoryForTest.stopPattern( STOP_A, STOP_B, STOP_C ); private static final List HOP_GEOMETRIES = List.of( - makeLineString(STOP_A.getCoordinate(), STOP_B.getCoordinate()), - makeLineString(STOP_B.getCoordinate(), STOP_C.getCoordinate()) + makeLineString(STOP_A.getCoordinate(), STOP_X.getCoordinate(), STOP_B.getCoordinate()), + makeLineString(STOP_B.getCoordinate(), STOP_Y.getCoordinate(), STOP_C.getCoordinate()) ); private static final TripPattern subject = TripPattern @@ -70,6 +72,27 @@ void copy() { assertEquals(HOP_GEOMETRIES.get(1), copy.getHopGeometry(1)); } + @Test + void hopGeometryForReplacementPattern() { + var pattern = TripPattern + .of(id("replacement")) + .withName("replacement") + .withRoute(ROUTE) + .withStopPattern(TimetableRepositoryForTest.stopPattern(STOP_A, STOP_B, STOP_X, STOP_Y)) + .withOriginalTripPattern(subject) + .build(); + + assertEquals(HOP_GEOMETRIES.get(0), pattern.getHopGeometry(0)); + assertEquals( + makeLineString(STOP_B.getCoordinate(), STOP_X.getCoordinate()), + pattern.getHopGeometry(1) + ); + assertEquals( + makeLineString(STOP_X.getCoordinate(), STOP_Y.getCoordinate()), + pattern.getHopGeometry(2) + ); + } + @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); @@ -77,7 +100,7 @@ void sameAs() { assertFalse(subject.sameAs(subject.copy().withName("X").build())); assertFalse( subject.sameAs( - subject.copy().withRoute(TransitModelForTest.route("anotherId").build()).build() + subject.copy().withRoute(TimetableRepositoryForTest.route("anotherId").build()).build() ) ); assertFalse(subject.sameAs(subject.copy().withMode(TransitMode.RAIL).build())); diff --git a/src/test/java/org/opentripplanner/transit/model/network/grouppriority/DefaultTransitGroupPriorityCalculatorTest.java b/application/src/test/java/org/opentripplanner/transit/model/network/grouppriority/DefaultTransitGroupPriorityCalculatorTest.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/model/network/grouppriority/DefaultTransitGroupPriorityCalculatorTest.java rename to application/src/test/java/org/opentripplanner/transit/model/network/grouppriority/DefaultTransitGroupPriorityCalculatorTest.java diff --git a/src/test/java/org/opentripplanner/transit/model/network/grouppriority/MatchersTest.java b/application/src/test/java/org/opentripplanner/transit/model/network/grouppriority/MatchersTest.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/model/network/grouppriority/MatchersTest.java rename to application/src/test/java/org/opentripplanner/transit/model/network/grouppriority/MatchersTest.java diff --git a/src/test/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriority32nTest.java b/application/src/test/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriority32nTest.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriority32nTest.java rename to application/src/test/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriority32nTest.java diff --git a/src/test/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriorityServiceTest.java b/application/src/test/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriorityServiceTest.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriorityServiceTest.java rename to application/src/test/java/org/opentripplanner/transit/model/network/grouppriority/TransitGroupPriorityServiceTest.java diff --git a/src/test/java/org/opentripplanner/transit/model/network/grouppriority/TripAdapterTest.java b/application/src/test/java/org/opentripplanner/transit/model/network/grouppriority/TripAdapterTest.java similarity index 81% rename from src/test/java/org/opentripplanner/transit/model/network/grouppriority/TripAdapterTest.java rename to application/src/test/java/org/opentripplanner/transit/model/network/grouppriority/TripAdapterTest.java index c1aeeea1a59..997d16bcff8 100644 --- a/src/test/java/org/opentripplanner/transit/model/network/grouppriority/TripAdapterTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/network/grouppriority/TripAdapterTest.java @@ -3,12 +3,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.timetable.Trip; class TripAdapterTest { - private final Trip trip = TransitModelForTest.trip("Trip").build(); + private final Trip trip = TimetableRepositoryForTest.trip("Trip").build(); private final TripAdapter subject = new TripAdapter(trip); diff --git a/src/test/java/org/opentripplanner/transit/model/organization/AgencyTest.java b/application/src/test/java/org/opentripplanner/transit/model/organization/AgencyTest.java similarity index 83% rename from src/test/java/org/opentripplanner/transit/model/organization/AgencyTest.java rename to application/src/test/java/org/opentripplanner/transit/model/organization/AgencyTest.java index b2cf1a57db3..2eff9b5d112 100644 --- a/src/test/java/org/opentripplanner/transit/model/organization/AgencyTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/organization/AgencyTest.java @@ -7,12 +7,11 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; class AgencyTest { private static final String ID = "1"; - private static final String BRANDING_URL = "http://branding.aaa.com"; private static final String NAME = "name"; private static final String URL = "http://info.aaa.com"; private static final String TIMEZONE = "Europe/Oslo"; @@ -21,12 +20,11 @@ class AgencyTest { private static final String LANG = "image"; private static final Agency subject = Agency - .of(TransitModelForTest.id(ID)) + .of(TimetableRepositoryForTest.id(ID)) .withName(NAME) .withUrl(URL) .withTimezone(TIMEZONE) .withPhone(PHONE) - .withBrandingUrl(BRANDING_URL) .withFareUrl(FARE_URL) .withLang(LANG) .build(); @@ -52,7 +50,6 @@ void copy() { assertEquals(URL, copy.getUrl()); assertEquals(TIMEZONE, copy.getTimezone().getId()); assertEquals(PHONE, copy.getPhone()); - assertEquals(BRANDING_URL, copy.getBrandingUrl()); assertEquals(FARE_URL, copy.getFareUrl()); assertEquals(LANG, copy.getLang()); } @@ -60,12 +57,11 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withName("X").build())); assertFalse(subject.sameAs(subject.copy().withUrl("X").build())); assertFalse(subject.sameAs(subject.copy().withTimezone("CET").build())); assertFalse(subject.sameAs(subject.copy().withPhone("X").build())); - assertFalse(subject.sameAs(subject.copy().withBrandingUrl("X").build())); assertFalse(subject.sameAs(subject.copy().withFareUrl("X").build())); assertFalse(subject.sameAs(subject.copy().withLang("X").build())); } diff --git a/src/test/java/org/opentripplanner/transit/model/organization/BrandingTest.java b/application/src/test/java/org/opentripplanner/transit/model/organization/BrandingTest.java similarity index 90% rename from src/test/java/org/opentripplanner/transit/model/organization/BrandingTest.java rename to application/src/test/java/org/opentripplanner/transit/model/organization/BrandingTest.java index 39b081fc6d8..37e6217cd15 100644 --- a/src/test/java/org/opentripplanner/transit/model/organization/BrandingTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/organization/BrandingTest.java @@ -7,7 +7,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; public class BrandingTest { @@ -19,7 +19,7 @@ public class BrandingTest { private static final String IMAGE = "test_image"; Branding subject = Branding - .of(TransitModelForTest.id(ID)) + .of(TimetableRepositoryForTest.id(ID)) .withShortName(SHORT_NAME) .withName(NAME) .withUrl(URL) @@ -53,7 +53,7 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withName("X").build())); assertFalse(subject.sameAs(subject.copy().withShortName("X").build())); assertFalse(subject.sameAs(subject.copy().withUrl("X").build())); diff --git a/src/test/java/org/opentripplanner/transit/model/organization/ContactInfoTest.java b/application/src/test/java/org/opentripplanner/transit/model/organization/ContactInfoTest.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/model/organization/ContactInfoTest.java rename to application/src/test/java/org/opentripplanner/transit/model/organization/ContactInfoTest.java diff --git a/src/test/java/org/opentripplanner/transit/model/organization/OperatorTest.java b/application/src/test/java/org/opentripplanner/transit/model/organization/OperatorTest.java similarity index 88% rename from src/test/java/org/opentripplanner/transit/model/organization/OperatorTest.java rename to application/src/test/java/org/opentripplanner/transit/model/organization/OperatorTest.java index 44374f54e91..12decb1fc82 100644 --- a/src/test/java/org/opentripplanner/transit/model/organization/OperatorTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/organization/OperatorTest.java @@ -7,7 +7,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; class OperatorTest { @@ -17,7 +17,7 @@ class OperatorTest { private static final String PHONE = "+47 95566333"; private static final Operator subject = Operator - .of(TransitModelForTest.id(ID)) + .of(TimetableRepositoryForTest.id(ID)) .withName(NAME) .withUrl(URL) .withPhone(PHONE) @@ -46,7 +46,7 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withName("X").build())); assertFalse(subject.sameAs(subject.copy().withUrl("X").build())); assertFalse(subject.sameAs(subject.copy().withPhone("X").build())); diff --git a/src/test/java/org/opentripplanner/transit/model/site/AreaStopTest.java b/application/src/test/java/org/opentripplanner/transit/model/site/AreaStopTest.java similarity index 87% rename from src/test/java/org/opentripplanner/transit/model/site/AreaStopTest.java rename to application/src/test/java/org/opentripplanner/transit/model/site/AreaStopTest.java index a36b6611368..cf68a51ae5a 100644 --- a/src/test/java/org/opentripplanner/transit/model/site/AreaStopTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/site/AreaStopTest.java @@ -13,8 +13,8 @@ import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.transit.model._data.TransitModelForTest; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.transit.service.SiteRepository; class AreaStopTest { @@ -24,7 +24,7 @@ class AreaStopTest { private static final I18NString URL = new NonLocalizedString("url"); - private static final String ZONE_ID = TransitModelForTest.TIME_ZONE_ID; + private static final String ZONE_ID = TimetableRepositoryForTest.TIME_ZONE_ID; private static final Geometry GEOMETRY = Polygons.OSLO; @@ -33,9 +33,9 @@ class AreaStopTest { private static final AreaStop subject = areaStopBuilder().withGeometry(GEOMETRY).build(); private static AreaStopBuilder areaStopBuilder() { - return StopModel + return SiteRepository .of() - .areaStop(TransitModelForTest.id(ID)) + .areaStop(TimetableRepositoryForTest.id(ID)) .withName(NAME) .withDescription(DESCRIPTION) .withUrl(URL) @@ -70,7 +70,7 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withName(new NonLocalizedString("X")).build())); assertFalse( subject.sameAs(subject.copy().withDescription(new NonLocalizedString("X")).build()) diff --git a/src/test/java/org/opentripplanner/transit/model/site/BoardingAreaTest.java b/application/src/test/java/org/opentripplanner/transit/model/site/BoardingAreaTest.java similarity index 85% rename from src/test/java/org/opentripplanner/transit/model/site/BoardingAreaTest.java rename to application/src/test/java/org/opentripplanner/transit/model/site/BoardingAreaTest.java index bc7c3455c24..235f4c089ff 100644 --- a/src/test/java/org/opentripplanner/transit/model/site/BoardingAreaTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/site/BoardingAreaTest.java @@ -10,17 +10,20 @@ import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; class BoardingAreaTest { private static final String ID = "1"; private static final I18NString NAME = new NonLocalizedString("name"); private static final I18NString DESCRIPTION = new NonLocalizedString("description"); - private static final RegularStop PARENT_STOP = TransitModelForTest.of().stop("stopId").build(); + private static final RegularStop PARENT_STOP = TimetableRepositoryForTest + .of() + .stop("stopId") + .build(); private static final BoardingArea subject = BoardingArea - .of(TransitModelForTest.id(ID)) + .of(TimetableRepositoryForTest.id(ID)) .withName(NAME) .withDescription(DESCRIPTION) .withParentStop(PARENT_STOP) @@ -52,7 +55,7 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withName(new NonLocalizedString("X")).build())); assertFalse( subject.sameAs(subject.copy().withDescription(new NonLocalizedString("X")).build()) diff --git a/src/test/java/org/opentripplanner/transit/model/site/EntranceTest.java b/application/src/test/java/org/opentripplanner/transit/model/site/EntranceTest.java similarity index 89% rename from src/test/java/org/opentripplanner/transit/model/site/EntranceTest.java rename to application/src/test/java/org/opentripplanner/transit/model/site/EntranceTest.java index 738238caa0f..0a9bb5cb5a4 100644 --- a/src/test/java/org/opentripplanner/transit/model/site/EntranceTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/site/EntranceTest.java @@ -10,7 +10,7 @@ import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Accessibility; class EntranceTest { @@ -23,11 +23,11 @@ class EntranceTest { public static final WgsCoordinate COORDINATE = new WgsCoordinate(0, 0); private static final StopLevel LEVEL = new StopLevel("level", 0); private static final Accessibility WHEELCHAIR_ACCESSIBILITY = Accessibility.POSSIBLE; - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final Station PARENT_STATION = TEST_MODEL.station("stationId").build(); private static final Entrance subject = Entrance - .of(TransitModelForTest.id(ID)) + .of(TimetableRepositoryForTest.id(ID)) .withName(NAME) .withDescription(DESCRIPTION) .withCode(CODE) @@ -67,7 +67,7 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withName(new NonLocalizedString("X")).build())); assertFalse( subject.sameAs(subject.copy().withDescription(new NonLocalizedString("X")).build()) diff --git a/src/test/java/org/opentripplanner/transit/model/site/FareZoneTest.java b/application/src/test/java/org/opentripplanner/transit/model/site/FareZoneTest.java similarity index 85% rename from src/test/java/org/opentripplanner/transit/model/site/FareZoneTest.java rename to application/src/test/java/org/opentripplanner/transit/model/site/FareZoneTest.java index 442ca61377f..c98f18d7aec 100644 --- a/src/test/java/org/opentripplanner/transit/model/site/FareZoneTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/site/FareZoneTest.java @@ -7,14 +7,14 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; class FareZoneTest { private static final String ID = "1"; private static final String NAME = "name"; private static final FareZone subject = FareZone - .of(TransitModelForTest.id(ID)) + .of(TimetableRepositoryForTest.id(ID)) .withName(NAME) .build(); @@ -41,7 +41,7 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withName("X").build())); } } diff --git a/src/test/java/org/opentripplanner/transit/model/site/GroupOfStationsTest.java b/application/src/test/java/org/opentripplanner/transit/model/site/GroupOfStationsTest.java similarity index 86% rename from src/test/java/org/opentripplanner/transit/model/site/GroupOfStationsTest.java rename to application/src/test/java/org/opentripplanner/transit/model/site/GroupOfStationsTest.java index 9b340f3d331..f1816e5a4b7 100644 --- a/src/test/java/org/opentripplanner/transit/model/site/GroupOfStationsTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/site/GroupOfStationsTest.java @@ -9,11 +9,11 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; class GroupOfStationsTest { - private static TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final String ID = "1"; private static final I18NString NAME = new NonLocalizedString("name"); @@ -26,7 +26,7 @@ class GroupOfStationsTest { .build(); private static final GroupOfStations subject = GroupOfStations - .of(TransitModelForTest.id(ID)) + .of(TimetableRepositoryForTest.id(ID)) .withName(NAME) .addChildStation(STATION) .build(); @@ -55,7 +55,7 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withName(new NonLocalizedString("X")).build())); assertFalse( subject.sameAs( diff --git a/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java b/application/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java similarity index 81% rename from src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java rename to application/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java index b57566b68ed..06c7a7dff1c 100644 --- a/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java @@ -14,12 +14,12 @@ import org.opentripplanner._support.geometry.Polygons; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.transit.model._data.TransitModelForTest; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.transit.service.SiteRepository; class GroupStopTest { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final String ID = "1"; private static final I18NString NAME = new NonLocalizedString("name"); @@ -27,9 +27,9 @@ class GroupStopTest { private static final StopLocation STOP_LOCATION = TEST_MODEL .stop("1:stop", Coordinates.BERLIN.getX(), Coordinates.BERLIN.getY()) .build(); - private static final GroupStop subject = StopModel + private static final GroupStop subject = SiteRepository .of() - .groupStop(TransitModelForTest.id(ID)) + .groupStop(TimetableRepositoryForTest.id(ID)) .withName(NAME) .addLocation(STOP_LOCATION) .build(); @@ -43,9 +43,9 @@ void testGroupStopGeometry() { .stop("2:stop", Coordinates.HAMBURG.getX(), Coordinates.HAMBURG.getY()) .build(); - GroupStop groupStop = StopModel + GroupStop groupStop = SiteRepository .of() - .groupStop(TransitModelForTest.id(ID)) + .groupStop(TimetableRepositoryForTest.id(ID)) .withName(NAME) .addLocation(stopLocation1) .addLocation(stopLocation2) @@ -64,9 +64,9 @@ void testGroupStopEncompassingAreaGeometry() { .stop("1:stop", Coordinates.BERLIN.getX(), Coordinates.BERLIN.getY()) .build(); - GroupStop groupStop = StopModel + GroupStop groupStop = SiteRepository .of() - .groupStop(TransitModelForTest.id(ID)) + .groupStop(TimetableRepositoryForTest.id(ID)) .withName(NAME) .addLocation(stopLocation) .withEncompassingAreaGeometries(List.of(Polygons.BERLIN)) @@ -105,11 +105,14 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withName(new NonLocalizedString("X")).build())); assertFalse( subject.sameAs( - subject.copy().addLocation(TransitModelForTest.of().stop("2:stop", 1d, 2d).build()).build() + subject + .copy() + .addLocation(TimetableRepositoryForTest.of().stop("2:stop", 1d, 2d).build()) + .build() ) ); } diff --git a/src/test/java/org/opentripplanner/transit/model/site/MultiModalStationTest.java b/application/src/test/java/org/opentripplanner/transit/model/site/MultiModalStationTest.java similarity index 87% rename from src/test/java/org/opentripplanner/transit/model/site/MultiModalStationTest.java rename to application/src/test/java/org/opentripplanner/transit/model/site/MultiModalStationTest.java index 615b0c49674..93be75e5c13 100644 --- a/src/test/java/org/opentripplanner/transit/model/site/MultiModalStationTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/site/MultiModalStationTest.java @@ -11,20 +11,20 @@ import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; class MultiModalStationTest { private static final String ID = "1"; private static final I18NString NAME = new NonLocalizedString("name"); - private static TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final Station STATION_1 = TEST_MODEL.station("1:1").build(); private static final Station STATION_2 = TEST_MODEL.station("1:2").build(); public static final Set CHILD_STATIONS = Set.of(STATION_1, STATION_2); private static final MultiModalStation subject = MultiModalStation - .of(TransitModelForTest.id(ID)) + .of(TimetableRepositoryForTest.id(ID)) .withName(NAME) .withChildStations(CHILD_STATIONS) .withCoordinate(new WgsCoordinate(1, 1)) @@ -54,7 +54,7 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withName(new NonLocalizedString("X")).build())); assertFalse(subject.sameAs(subject.copy().withChildStations(Set.of(STATION_1)).build())); } diff --git a/src/test/java/org/opentripplanner/transit/model/site/PathwayNodeTest.java b/application/src/test/java/org/opentripplanner/transit/model/site/PathwayNodeTest.java similarity index 89% rename from src/test/java/org/opentripplanner/transit/model/site/PathwayNodeTest.java rename to application/src/test/java/org/opentripplanner/transit/model/site/PathwayNodeTest.java index c5cdae2b54b..77de36ceb71 100644 --- a/src/test/java/org/opentripplanner/transit/model/site/PathwayNodeTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/site/PathwayNodeTest.java @@ -10,7 +10,7 @@ import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Accessibility; class PathwayNodeTest { @@ -18,7 +18,7 @@ class PathwayNodeTest { private static final String ID = "1"; private static final I18NString NAME = new NonLocalizedString("name"); private static final I18NString DESCRIPTION = new NonLocalizedString("description"); - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final Station PARENT_STATION = TEST_MODEL.station("stationId").build(); private static final String CODE = "code"; @@ -26,7 +26,7 @@ class PathwayNodeTest { private static final StopLevel LEVEL = new StopLevel("level", 0); private static final Accessibility WHEELCHAIR_ACCESSIBILITY = Accessibility.POSSIBLE; private static final PathwayNode subject = PathwayNode - .of(TransitModelForTest.id(ID)) + .of(TimetableRepositoryForTest.id(ID)) .withName(NAME) .withDescription(DESCRIPTION) .withCode(CODE) @@ -66,7 +66,7 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withName(new NonLocalizedString("X")).build())); assertFalse( subject.sameAs(subject.copy().withDescription(new NonLocalizedString("X")).build()) diff --git a/src/test/java/org/opentripplanner/transit/model/site/PathwayTest.java b/application/src/test/java/org/opentripplanner/transit/model/site/PathwayTest.java similarity index 87% rename from src/test/java/org/opentripplanner/transit/model/site/PathwayTest.java rename to application/src/test/java/org/opentripplanner/transit/model/site/PathwayTest.java index 9b5e526b6dd..09bf034e6ba 100644 --- a/src/test/java/org/opentripplanner/transit/model/site/PathwayTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/site/PathwayTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.framework.geometry.WgsCoordinate; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; class PathwayTest { @@ -17,14 +17,14 @@ class PathwayTest { private static final String NAME = "name"; private static final PathwayMode MODE = PathwayMode.ESCALATOR; private static final PathwayNode FROM = PathwayNode - .of(TransitModelForTest.id("1:node")) + .of(TimetableRepositoryForTest.id("1:node")) .withCoordinate(new WgsCoordinate(20, 30)) .build(); - private static final RegularStop TO = TransitModelForTest.of().stop("1:stop").build(); + private static final RegularStop TO = TimetableRepositoryForTest.of().stop("1:stop").build(); public static final int TRAVERSAL_TIME = 120; private final Pathway subject = Pathway - .of(TransitModelForTest.id(ID)) + .of(TimetableRepositoryForTest.id(ID)) .withPathwayMode(MODE) .withSignpostedAs(NAME) .withFromStop(FROM) @@ -66,7 +66,7 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withSignpostedAs("X").build())); assertFalse(subject.sameAs(subject.copy().withReverseSignpostedAs("X").build())); assertFalse(subject.sameAs(subject.copy().withPathwayMode(PathwayMode.ELEVATOR).build())); diff --git a/src/test/java/org/opentripplanner/transit/model/site/RegularStopTest.java b/application/src/test/java/org/opentripplanner/transit/model/site/RegularStopTest.java similarity index 84% rename from src/test/java/org/opentripplanner/transit/model/site/RegularStopTest.java rename to application/src/test/java/org/opentripplanner/transit/model/site/RegularStopTest.java index 104d732e37e..cfcab8a0b13 100644 --- a/src/test/java/org/opentripplanner/transit/model/site/RegularStopTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/site/RegularStopTest.java @@ -11,18 +11,18 @@ import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.basic.SubMode; import org.opentripplanner.transit.model.basic.TransitMode; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; class RegularStopTest { private static final String ID = "1"; private static final I18NString NAME = new NonLocalizedString("name"); private static final I18NString DESCRIPTION = new NonLocalizedString("description"); - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final Station PARENT_STATION = TEST_MODEL.station("stationId").build(); private static final String CODE = "code"; @@ -32,12 +32,12 @@ class RegularStopTest { private static final String NETEX_SUBMODE_NAME = "submode"; private static final SubMode NETEX_SUBMODE = SubMode.of(NETEX_SUBMODE_NAME); private static final TransitMode VEHICLE_TYPE = TransitMode.BUS; - public static final ZoneId TIME_ZONE = ZoneId.of(TransitModelForTest.TIME_ZONE_ID); + public static final ZoneId TIME_ZONE = ZoneId.of(TimetableRepositoryForTest.TIME_ZONE_ID); private static final String PLATFORM_CODE = "platformCode"; - private static final RegularStop subject = StopModel + private static final RegularStop subject = SiteRepository .of() - .regularStop(TransitModelForTest.id(ID)) + .regularStop(TimetableRepositoryForTest.id(ID)) .withName(NAME) .withDescription(DESCRIPTION) .withCode(CODE) @@ -78,7 +78,7 @@ void copy() { assertEquals(WHEELCHAIR_ACCESSIBILITY, copy.getWheelchairAccessibility()); // TODO inconsistent naming assertEquals(NETEX_SUBMODE, copy.getNetexVehicleSubmode()); - assertEquals(VEHICLE_TYPE, copy.getGtfsVehicleType()); + assertEquals(VEHICLE_TYPE, copy.getVehicleType()); assertEquals(TIME_ZONE, copy.getTimeZone()); assertEquals(PLATFORM_CODE, copy.getPlatformCode()); } @@ -86,7 +86,7 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withName(new NonLocalizedString("X")).build())); assertFalse( subject.sameAs(subject.copy().withDescription(new NonLocalizedString("X")).build()) @@ -97,7 +97,10 @@ void sameAs() { assertFalse(subject.sameAs(subject.copy().withVehicleType(TransitMode.TRAM).build())); assertFalse( subject.sameAs( - subject.copy().withTimeZone(ZoneId.of(TransitModelForTest.OTHER_TIME_ZONE_ID)).build() + subject + .copy() + .withTimeZone(ZoneId.of(TimetableRepositoryForTest.OTHER_TIME_ZONE_ID)) + .build() ) ); assertFalse(subject.sameAs(subject.copy().withPlatformCode("X").build())); diff --git a/src/test/java/org/opentripplanner/transit/model/site/StationTest.java b/application/src/test/java/org/opentripplanner/transit/model/site/StationTest.java similarity index 84% rename from src/test/java/org/opentripplanner/transit/model/site/StationTest.java rename to application/src/test/java/org/opentripplanner/transit/model/site/StationTest.java index 9ff75583bfc..958816bc74d 100644 --- a/src/test/java/org/opentripplanner/transit/model/site/StationTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/site/StationTest.java @@ -11,7 +11,7 @@ import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; class StationTest { @@ -22,13 +22,13 @@ class StationTest { public static final WgsCoordinate COORDINATE = new WgsCoordinate(0, 0); private static final StopTransferPriority PRIORITY = StopTransferPriority.ALLOWED; - private static final ZoneId TIMEZONE = ZoneId.of(TransitModelForTest.TIME_ZONE_ID); + private static final ZoneId TIMEZONE = ZoneId.of(TimetableRepositoryForTest.TIME_ZONE_ID); private static final I18NString URL = new NonLocalizedString("url"); - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final Station PARENT_STATION = TEST_MODEL.station("stationId").build(); private static final Station subject = Station - .of(TransitModelForTest.id(ID)) + .of(TimetableRepositoryForTest.id(ID)) .withName(NAME) .withDescription(DESCRIPTION) .withCode(CODE) @@ -67,7 +67,7 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withName(new NonLocalizedString("X")).build())); assertFalse(subject.sameAs(subject.copy().withCode("X").build())); assertFalse( @@ -80,7 +80,10 @@ void sameAs() { assertFalse(subject.sameAs(subject.copy().withUrl(new NonLocalizedString("X")).build())); assertFalse( subject.sameAs( - subject.copy().withTimezone(ZoneId.of(TransitModelForTest.OTHER_TIME_ZONE_ID)).build() + subject + .copy() + .withTimezone(ZoneId.of(TimetableRepositoryForTest.OTHER_TIME_ZONE_ID)) + .build() ) ); } diff --git a/src/test/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimesTest.java b/application/src/test/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimesTest.java similarity index 95% rename from src/test/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimesTest.java rename to application/src/test/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimesTest.java index 5b3a8f76052..29da6582d8f 100644 --- a/src/test/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimesTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/timetable/RealTimeTripTimesTest.java @@ -5,7 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import static org.opentripplanner.transit.model.timetable.TimetableValidationError.ErrorCode.NEGATIVE_DWELL_TIME; import static org.opentripplanner.transit.model.timetable.TimetableValidationError.ErrorCode.NEGATIVE_HOP_TIME; @@ -16,7 +16,7 @@ import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.model.StopTime; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.DataValidationException; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -24,7 +24,7 @@ class RealTimeTripTimesTest { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final String TRIP_ID = "testTripId"; @@ -40,7 +40,7 @@ class RealTimeTripTimesTest { ); static TripTimes createInitialTripTimes() { - Trip trip = TransitModelForTest.trip(TRIP_ID).build(); + Trip trip = TimetableRepositoryForTest.trip(TRIP_ID).build(); List stopTimes = new LinkedList<>(); @@ -69,7 +69,7 @@ class Headsign { @Test void shouldHandleBothNullScenario() { - Trip trip = TransitModelForTest.trip("TRIP").build(); + Trip trip = TimetableRepositoryForTest.trip("TRIP").build(); List stopTimes = List.of(EMPTY_STOPPOINT, EMPTY_STOPPOINT, EMPTY_STOPPOINT); TripTimes tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, new Deduplicator()); @@ -80,7 +80,7 @@ void shouldHandleBothNullScenario() { @Test void shouldHandleTripOnlyHeadSignScenario() { - Trip trip = TransitModelForTest.trip("TRIP").withHeadsign(DIRECTION).build(); + Trip trip = TimetableRepositoryForTest.trip("TRIP").withHeadsign(DIRECTION).build(); List stopTimes = List.of(EMPTY_STOPPOINT, EMPTY_STOPPOINT, EMPTY_STOPPOINT); TripTimes tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, new Deduplicator()); @@ -91,7 +91,7 @@ void shouldHandleTripOnlyHeadSignScenario() { @Test void shouldHandleStopsOnlyHeadSignScenario() { - Trip trip = TransitModelForTest.trip("TRIP").build(); + Trip trip = TimetableRepositoryForTest.trip("TRIP").build(); StopTime stopWithHeadsign = new StopTime(); stopWithHeadsign.setStopHeadsign(STOP_TEST_DIRECTION); List stopTimes = List.of(stopWithHeadsign, stopWithHeadsign, stopWithHeadsign); @@ -104,7 +104,7 @@ void shouldHandleStopsOnlyHeadSignScenario() { @Test void shouldHandleStopsEqualToTripHeadSignScenario() { - Trip trip = TransitModelForTest.trip("TRIP").withHeadsign(DIRECTION).build(); + Trip trip = TimetableRepositoryForTest.trip("TRIP").withHeadsign(DIRECTION).build(); StopTime stopWithHeadsign = new StopTime(); stopWithHeadsign.setStopHeadsign(DIRECTION); List stopTimes = List.of(stopWithHeadsign, stopWithHeadsign, stopWithHeadsign); @@ -117,7 +117,7 @@ void shouldHandleStopsEqualToTripHeadSignScenario() { @Test void shouldHandleDifferingTripAndStopHeadSignScenario() { - Trip trip = TransitModelForTest.trip("TRIP").withHeadsign(DIRECTION).build(); + Trip trip = TimetableRepositoryForTest.trip("TRIP").withHeadsign(DIRECTION).build(); StopTime stopWithHeadsign = new StopTime(); stopWithHeadsign.setStopHeadsign(STOP_TEST_DIRECTION); List stopTimes = List.of(stopWithHeadsign, EMPTY_STOPPOINT, EMPTY_STOPPOINT); diff --git a/src/test/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesTest.java b/application/src/test/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesTest.java similarity index 94% rename from src/test/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesTest.java rename to application/src/test/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesTest.java index e2c1148ef51..06469a34b2a 100644 --- a/src/test/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesTest.java @@ -5,20 +5,20 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.util.BitSet; import java.util.List; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.TimeUtils; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.framework.DataValidationException; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.time.TimeUtils; class ScheduledTripTimesTest { - private static final Trip TRIP = TransitModelForTest.trip("Trip-1").build(); + private static final Trip TRIP = TimetableRepositoryForTest.trip("Trip-1").build(); private static final List STOP_IDS = List.of(id("A"), id("B"), id("C")); private static final int SERVICE_CODE = 5; diff --git a/src/test/java/org/opentripplanner/transit/model/timetable/StopTimeKeyTest.java b/application/src/test/java/org/opentripplanner/transit/model/timetable/StopTimeKeyTest.java similarity index 76% rename from src/test/java/org/opentripplanner/transit/model/timetable/StopTimeKeyTest.java rename to application/src/test/java/org/opentripplanner/transit/model/timetable/StopTimeKeyTest.java index a4051211c51..e86b4133256 100644 --- a/src/test/java/org/opentripplanner/transit/model/timetable/StopTimeKeyTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/timetable/StopTimeKeyTest.java @@ -5,7 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; class StopTimeKeyTest { @@ -13,7 +13,7 @@ class StopTimeKeyTest { private static final int STOP_SEQUENCE_NUMBER = 1; private static final StopTimeKey subject = StopTimeKey - .of(TransitModelForTest.id(ID), STOP_SEQUENCE_NUMBER) + .of(TimetableRepositoryForTest.id(ID), STOP_SEQUENCE_NUMBER) .build(); @Test @@ -29,6 +29,6 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); } } diff --git a/src/test/java/org/opentripplanner/transit/model/timetable/TimetableValidationErrorTest.java b/application/src/test/java/org/opentripplanner/transit/model/timetable/TimetableValidationErrorTest.java similarity index 76% rename from src/test/java/org/opentripplanner/transit/model/timetable/TimetableValidationErrorTest.java rename to application/src/test/java/org/opentripplanner/transit/model/timetable/TimetableValidationErrorTest.java index 7dd67665e92..acccea2b531 100644 --- a/src/test/java/org/opentripplanner/transit/model/timetable/TimetableValidationErrorTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/timetable/TimetableValidationErrorTest.java @@ -3,7 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; class TimetableValidationErrorTest { @@ -11,7 +11,7 @@ class TimetableValidationErrorTest { private TimetableValidationError subject = new TimetableValidationError( TimetableValidationError.ErrorCode.NEGATIVE_HOP_TIME, 3, - TransitModelForTest.trip("A").withMode(TransitMode.BUS).withShortName("Line A").build() + TimetableRepositoryForTest.trip("A").withMode(TransitMode.BUS).withShortName("Line A").build() ); @Test diff --git a/src/test/java/org/opentripplanner/transit/model/timetable/TripOnServiceDateTest.java b/application/src/test/java/org/opentripplanner/transit/model/timetable/TripOnServiceDateTest.java similarity index 77% rename from src/test/java/org/opentripplanner/transit/model/timetable/TripOnServiceDateTest.java rename to application/src/test/java/org/opentripplanner/transit/model/timetable/TripOnServiceDateTest.java index c72d56b6aeb..d84af565fab 100644 --- a/src/test/java/org/opentripplanner/transit/model/timetable/TripOnServiceDateTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/timetable/TripOnServiceDateTest.java @@ -7,20 +7,20 @@ import java.time.LocalDate; import java.util.List; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; class TripOnServiceDateTest { private static final String ID = "1"; private static final TripAlteration TRIP_ALTERATION = TripAlteration.CANCELLATION; private static final List REPLACEMENT_FOR = List.of( - TripOnServiceDate.of(TransitModelForTest.id("id1")).build() + TripOnServiceDate.of(TimetableRepositoryForTest.id("id1")).build() ); public static final LocalDate SERVICE_DATE = LocalDate.now(); public static final String TRIP_ID = "tripId"; private static final TripOnServiceDate subject = TripOnServiceDate - .of(TransitModelForTest.id(ID)) - .withTrip(TransitModelForTest.trip(TRIP_ID).build()) + .of(TimetableRepositoryForTest.id(ID)) + .withTrip(TimetableRepositoryForTest.trip(TRIP_ID).build()) .withServiceDate(SERVICE_DATE) .withTripAlteration(TRIP_ALTERATION) .withReplacementFor(REPLACEMENT_FOR) @@ -43,7 +43,7 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse( subject.sameAs(subject.copy().withServiceDate(LocalDate.now().plusDays(1)).build()) ); @@ -52,7 +52,9 @@ void sameAs() { subject.sameAs( subject .copy() - .withReplacementFor(List.of(TripOnServiceDate.of(TransitModelForTest.id("id2")).build())) + .withReplacementFor( + List.of(TripOnServiceDate.of(TimetableRepositoryForTest.id("id2")).build()) + ) .build() ) ); diff --git a/src/test/java/org/opentripplanner/transit/model/timetable/TripTest.java b/application/src/test/java/org/opentripplanner/transit/model/timetable/TripTest.java similarity index 87% rename from src/test/java/org/opentripplanner/transit/model/timetable/TripTest.java rename to application/src/test/java/org/opentripplanner/transit/model/timetable/TripTest.java index 3a3f35643fa..441ce74927a 100644 --- a/src/test/java/org/opentripplanner/transit/model/timetable/TripTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/timetable/TripTest.java @@ -6,12 +6,13 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.basic.SubMode; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.BikeAccess; +import org.opentripplanner.transit.model.network.CarAccess; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Operator; @@ -20,10 +21,11 @@ class TripTest { private static final String ID = "1"; private static final String SHORT_NAME = "name"; private static final Accessibility WHEELCHAIR_ACCESSIBILITY = Accessibility.POSSIBLE; - public static final Route ROUTE = TransitModelForTest.route("routeId").build(); + public static final Route ROUTE = TimetableRepositoryForTest.route("routeId").build(); private static final Direction DIRECTION = Direction.INBOUND; public static final NonLocalizedString HEAD_SIGN = new NonLocalizedString("head sign"); private static final BikeAccess BIKE_ACCESS = BikeAccess.ALLOWED; + private static final CarAccess CAR_ACCESS = CarAccess.ALLOWED; private static final TransitMode TRANSIT_MODE = TransitMode.BUS; private static final String BLOCK_ID = "blockId"; private static final TripAlteration TRIP_ALTERATION = TripAlteration.CANCELLATION; @@ -37,12 +39,13 @@ class TripTest { private static final FeedScopedId SERVICE_ID = FeedScopedId.parse("x:serviceId"); private static final FeedScopedId SHAPE_ID = FeedScopedId.parse("x:shapeId"); private static final Trip subject = Trip - .of(TransitModelForTest.id(ID)) + .of(TimetableRepositoryForTest.id(ID)) .withShortName(SHORT_NAME) .withRoute(ROUTE) .withDirection(DIRECTION) .withHeadsign(HEAD_SIGN) .withBikesAllowed(BIKE_ACCESS) + .withCarsAllowed(CAR_ACCESS) .withMode(TRANSIT_MODE) .withGtfsBlockId(BLOCK_ID) .withNetexAlteration(TRIP_ALTERATION) @@ -63,7 +66,7 @@ void shouldCopyFieldsFromRoute() { .withBikesAllowed(BIKE_ACCESS) .build(); - var subject = Trip.of(TransitModelForTest.id(ID)).withRoute(routeWithModes).build(); + var subject = Trip.of(TimetableRepositoryForTest.id(ID)).withRoute(routeWithModes).build(); assertEquals(TRANSIT_MODE, subject.getMode()); assertEquals(NETEX_SUBMODE, subject.getNetexSubMode()); @@ -84,6 +87,7 @@ void copy() { assertEquals(DIRECTION, copy.getDirection()); assertEquals(HEAD_SIGN, copy.getHeadsign()); assertEquals(BIKE_ACCESS, copy.getBikesAllowed()); + assertEquals(CAR_ACCESS, copy.getCarsAllowed()); assertEquals(TRANSIT_MODE, copy.getMode()); assertEquals(BLOCK_ID, copy.getGtfsBlockId()); assertEquals(TRIP_ALTERATION, copy.getNetexAlteration()); @@ -97,19 +101,20 @@ void copy() { @Test void sameAs() { assertTrue(subject.sameAs(subject.copy().build())); - assertFalse(subject.sameAs(subject.copy().withId(TransitModelForTest.id("X")).build())); + assertFalse(subject.sameAs(subject.copy().withId(TimetableRepositoryForTest.id("X")).build())); assertFalse(subject.sameAs(subject.copy().withShortName("X").build())); assertFalse( subject.sameAs(subject.copy().withWheelchairBoarding(Accessibility.NOT_POSSIBLE).build()) ); assertFalse( subject.sameAs( - subject.copy().withRoute(TransitModelForTest.route("otherRouteId").build()).build() + subject.copy().withRoute(TimetableRepositoryForTest.route("otherRouteId").build()).build() ) ); assertFalse(subject.sameAs(subject.copy().withDirection(Direction.OUTBOUND).build())); assertFalse(subject.sameAs(subject.copy().withHeadsign(new NonLocalizedString("X")).build())); assertFalse(subject.sameAs(subject.copy().withBikesAllowed(BikeAccess.NOT_ALLOWED).build())); + assertFalse(subject.sameAs(subject.copy().withCarsAllowed(CarAccess.NOT_ALLOWED).build())); assertFalse(subject.sameAs(subject.copy().withMode(TransitMode.RAIL).build())); assertFalse(subject.sameAs(subject.copy().withGtfsBlockId("X").build())); assertFalse( diff --git a/src/test/java/org/opentripplanner/transit/model/timetable/booking/BookingInfoTest.java b/application/src/test/java/org/opentripplanner/transit/model/timetable/booking/BookingInfoTest.java similarity index 99% rename from src/test/java/org/opentripplanner/transit/model/timetable/booking/BookingInfoTest.java rename to application/src/test/java/org/opentripplanner/transit/model/timetable/booking/BookingInfoTest.java index 0bf189a1c29..36587e1f696 100644 --- a/src/test/java/org/opentripplanner/transit/model/timetable/booking/BookingInfoTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/timetable/booking/BookingInfoTest.java @@ -58,7 +58,7 @@ void testBookingInfoWithMinBookingNotice() { .build(); assertNull(subject.getLatestBookingTime()); - assertEquals(minimumBookingNotice, subject.getMinimumBookingNotice()); + assertEquals(minimumBookingNotice, subject.getMinimumBookingNotice().get()); assertEquals( "BookingInfo{bookingMethods: [CALL_DRIVER], minimumBookingNotice: 45m}", diff --git a/src/test/java/org/opentripplanner/transit/model/timetable/booking/BookingTimeTest.java b/application/src/test/java/org/opentripplanner/transit/model/timetable/booking/BookingTimeTest.java similarity index 96% rename from src/test/java/org/opentripplanner/transit/model/timetable/booking/BookingTimeTest.java rename to application/src/test/java/org/opentripplanner/transit/model/timetable/booking/BookingTimeTest.java index 5036defdb88..88b113aec53 100644 --- a/src/test/java/org/opentripplanner/transit/model/timetable/booking/BookingTimeTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/timetable/booking/BookingTimeTest.java @@ -5,7 +5,7 @@ import java.time.LocalTime; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.TimeUtils; +import org.opentripplanner.utils.time.TimeUtils; class BookingTimeTest { diff --git a/src/test/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfoTest.java b/application/src/test/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfoTest.java similarity index 99% rename from src/test/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfoTest.java rename to application/src/test/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfoTest.java index e0f507a7983..2b9dfaface8 100644 --- a/src/test/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfoTest.java +++ b/application/src/test/java/org/opentripplanner/transit/model/timetable/booking/RoutingBookingInfoTest.java @@ -13,7 +13,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.framework.time.TimeUtils; +import org.opentripplanner.utils.time.TimeUtils; class RoutingBookingInfoTest { diff --git a/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java b/application/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java similarity index 70% rename from src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java rename to application/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java index b04a1258984..c3086bcc61b 100644 --- a/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java +++ b/application/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java @@ -1,6 +1,7 @@ package org.opentripplanner.transit.service; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.opentripplanner.transit.model.basic.TransitMode.BUS; import static org.opentripplanner.transit.model.basic.TransitMode.FERRY; import static org.opentripplanner.transit.model.basic.TransitMode.RAIL; @@ -14,8 +15,9 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.model.RealTimeTripUpdate; import org.opentripplanner.model.TimetableSnapshot; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; +import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.StopPattern; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.RegularStop; @@ -26,7 +28,7 @@ class DefaultTransitServiceTest { - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); static TransitService service; static Station STATION = TEST_MODEL.station("C").build(); @@ -40,7 +42,10 @@ class DefaultTransitServiceTest { static TripPattern FERRY_PATTERN = TEST_MODEL.pattern(FERRY).build(); static TripPattern BUS_PATTERN = TEST_MODEL.pattern(BUS).build(); - static StopPattern REAL_TIME_STOP_PATTERN = TransitModelForTest.stopPattern(STOP_A, STOP_B); + static StopPattern REAL_TIME_STOP_PATTERN = TimetableRepositoryForTest.stopPattern( + STOP_A, + STOP_B + ); static TripPattern REAL_TIME_PATTERN = TEST_MODEL .pattern(BUS) .withStopPattern(REAL_TIME_STOP_PATTERN) @@ -49,23 +54,23 @@ class DefaultTransitServiceTest { @BeforeAll static void setup() { - var stopModel = TEST_MODEL - .stopModelBuilder() + var siteRepository = TEST_MODEL + .siteRepositoryBuilder() .withRegularStop(STOP_A) .withRegularStop(STOP_B) .withStation(STATION) .build(); - var transitModel = new TransitModel(stopModel, new Deduplicator()); - transitModel.addTripPattern(RAIL_PATTERN.getId(), RAIL_PATTERN); - transitModel.index(); + var timetableRepository = new TimetableRepository(siteRepository, new Deduplicator()); + timetableRepository.addTripPattern(RAIL_PATTERN.getId(), RAIL_PATTERN); + timetableRepository.index(); - transitModel.initTimetableSnapshotProvider(() -> { + timetableRepository.initTimetableSnapshotProvider(() -> { TimetableSnapshot timetableSnapshot = new TimetableSnapshot(); RealTimeTripTimes tripTimes = RealTimeTripTimes.of( ScheduledTripTimes .of() - .withTrip(TransitModelForTest.trip("REAL_TIME_TRIP").build()) + .withTrip(TimetableRepositoryForTest.trip("REAL_TIME_TRIP").build()) .withDepartureTimes(new int[] { 0, 1 }) .build() ); @@ -77,9 +82,9 @@ static void setup() { }); service = - new DefaultTransitService(transitModel) { + new DefaultTransitService(timetableRepository) { @Override - public Collection getPatternsForStop(StopLocation stop) { + public Collection findPatterns(StopLocation stop) { if (stop.equals(STOP_B)) { return List.of(FERRY_PATTERN, FERRY_PATTERN, RAIL_PATTERN, RAIL_PATTERN, RAIL_PATTERN); } else { @@ -91,31 +96,36 @@ public Collection getPatternsForStop(StopLocation stop) { @Test void modeFromGtfsVehicleType() { - var modes = service.getModesOfStopLocation(STOP_A); + var modes = service.findTransitModes(STOP_A); assertEquals(List.of(TRAM), modes); } @Test void modeFromPatterns() { - var modes = service.getModesOfStopLocation(STOP_B); + var modes = service.findTransitModes(STOP_B); assertEquals(List.of(RAIL, FERRY), modes); } @Test void stationModes() { - var modes = service.getModesOfStopLocationsGroup(STATION); + var modes = service.findTransitModes(STATION); assertEquals(List.of(RAIL, FERRY, TRAM), modes); } @Test void getPatternForStopsWithoutRealTime() { - Collection patternsForStop = service.getPatternsForStop(STOP_B, false); + Collection patternsForStop = service.findPatterns(STOP_B, false); assertEquals(Set.of(FERRY_PATTERN, RAIL_PATTERN), patternsForStop); } @Test void getPatternForStopsWithRealTime() { - Collection patternsForStop = service.getPatternsForStop(STOP_B, true); + Collection patternsForStop = service.findPatterns(STOP_B, true); assertEquals(Set.of(FERRY_PATTERN, RAIL_PATTERN, REAL_TIME_PATTERN), patternsForStop); } + + @Test + void containsTrip() { + assertFalse(service.containsTrip(new FeedScopedId("x", "x"))); + } } diff --git a/src/test/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilterTest.java b/application/src/test/java/org/opentripplanner/transit/service/PatternByServiceDatesFilterTest.java similarity index 66% rename from src/test/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilterTest.java rename to application/src/test/java/org/opentripplanner/transit/service/PatternByServiceDatesFilterTest.java index f01bac12006..93f50ce5b1e 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilterTest.java +++ b/application/src/test/java/org/opentripplanner/transit/service/PatternByServiceDatesFilterTest.java @@ -1,12 +1,12 @@ -package org.opentripplanner.apis.gtfs; +package org.opentripplanner.transit.service; import static java.time.LocalDate.parse; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.opentripplanner.apis.gtfs.PatternByServiceDatesFilterTest.FilterExpectation.NOT_REMOVED; -import static org.opentripplanner.apis.gtfs.PatternByServiceDatesFilterTest.FilterExpectation.REMOVED; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.PatternTestModel.ROUTE_1; +import static org.opentripplanner.transit.service.PatternByServiceDatesFilterTest.FilterExpectation.NOT_REMOVED; +import static org.opentripplanner.transit.service.PatternByServiceDatesFilterTest.FilterExpectation.REMOVED; import java.time.LocalDate; import java.util.List; @@ -14,51 +14,18 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.apis.gtfs.model.LocalDateRange; -import org.opentripplanner.transit.model._data.TransitModelForTest; -import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.model.network.Route; -import org.opentripplanner.transit.model.network.StopPattern; +import org.opentripplanner.transit.model._data.PatternTestModel; import org.opentripplanner.transit.model.network.TripPattern; -import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.model.timetable.ScheduledTripTimes; -import org.opentripplanner.transit.model.timetable.Trip; -import org.opentripplanner.transit.service.StopModel; class PatternByServiceDatesFilterTest { - private static final Route ROUTE_1 = TransitModelForTest.route("1").build(); - private static final FeedScopedId SERVICE_ID = id("service"); - private static final Trip TRIP = TransitModelForTest - .trip("t1") - .withRoute(ROUTE_1) - .withServiceId(SERVICE_ID) - .build(); - private static final TransitModelForTest MODEL = new TransitModelForTest(StopModel.of()); - private static final RegularStop STOP_1 = MODEL.stop("1").build(); - private static final StopPattern STOP_PATTERN = TransitModelForTest.stopPattern(STOP_1, STOP_1); - private static final TripPattern PATTERN_1 = pattern(); + private static final TripPattern PATTERN_1 = PatternTestModel.pattern(); enum FilterExpectation { REMOVED, NOT_REMOVED, } - private static TripPattern pattern() { - var pattern = TransitModelForTest - .tripPattern("1", ROUTE_1) - .withStopPattern(STOP_PATTERN) - .build(); - - var tt = ScheduledTripTimes - .of() - .withTrip(TRIP) - .withArrivalTimes("10:00 10:05") - .withDepartureTimes("10:00 10:05") - .build(); - pattern.add(tt); - return pattern; - } - static List invalidRangeCases() { return List.of( Arguments.of(null, null), @@ -140,7 +107,7 @@ void filterRoutes(LocalDate start, LocalDate end, FilterExpectation expectation) var filter = defaultFilter(start, end); var filterInput = List.of(ROUTE_1); - var filterOutput = filter.filterRoutes(filterInput.stream()); + var filterOutput = filter.filterRoutes(filterInput); if (expectation == NOT_REMOVED) { assertEquals(filterOutput, filterInput); diff --git a/src/test/java/org/opentripplanner/transit/service/StopModelMock.java b/application/src/test/java/org/opentripplanner/transit/service/SiteRepositoryMock.java similarity index 76% rename from src/test/java/org/opentripplanner/transit/service/StopModelMock.java rename to application/src/test/java/org/opentripplanner/transit/service/SiteRepositoryMock.java index 8677f7b9dec..34884664b6d 100644 --- a/src/test/java/org/opentripplanner/transit/service/StopModelMock.java +++ b/application/src/test/java/org/opentripplanner/transit/service/SiteRepositoryMock.java @@ -3,11 +3,11 @@ import java.util.List; import org.opentripplanner.transit.model.site.StopLocation; -public class StopModelMock extends StopModel { +public class SiteRepositoryMock extends SiteRepository { private final List stops; - public StopModelMock(List stops) { + public SiteRepositoryMock(List stops) { this.stops = stops; } diff --git a/src/test/java/org/opentripplanner/transit/service/StopModelTest.java b/application/src/test/java/org/opentripplanner/transit/service/SiteRepositoryTest.java similarity index 84% rename from src/test/java/org/opentripplanner/transit/service/StopModelTest.java rename to application/src/test/java/org/opentripplanner/transit/service/SiteRepositoryTest.java index b24b547a07e..8e7b4e6f78f 100644 --- a/src/test/java/org/opentripplanner/transit/service/StopModelTest.java +++ b/application/src/test/java/org/opentripplanner/transit/service/SiteRepositoryTest.java @@ -11,7 +11,7 @@ import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.model.site.GroupOfStations; @@ -20,7 +20,7 @@ import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; -class StopModelTest { +class SiteRepositoryTest { private static final WgsCoordinate COOR_A = new WgsCoordinate(60.0, 11.0); private static final WgsCoordinate COOR_B = new WgsCoordinate(62.0, 12.0); @@ -28,7 +28,7 @@ class StopModelTest { .getGeometryFactory() .createPoint(COOR_A.asJtsCoordinate()); public static final NonLocalizedString NAME = NonLocalizedString.ofNullable("Name"); - private static final FeedScopedId ID = TransitModelForTest.id("A"); + private static final FeedScopedId ID = TimetableRepositoryForTest.id("A"); private static final Station STATION = Station .of(ID) .withName(NAME) @@ -36,20 +36,20 @@ class StopModelTest { .build(); private static final String EXP_STATIONS = List.of(STATION).toString(); - private final StopModelBuilder stopModelBuilder = StopModel.of(); - private final RegularStop stop = stopModelBuilder + private final SiteRepositoryBuilder siteRepositoryBuilder = SiteRepository.of(); + private final RegularStop stop = siteRepositoryBuilder .regularStop(ID) .withCoordinate(COOR_A) .withName(NAME) .withParentStation(STATION) .build(); private final String expStops = List.of(stop).toString(); - private final AreaStop STOP_AREA = stopModelBuilder + private final AreaStop STOP_AREA = siteRepositoryBuilder .areaStop(ID) .withName(NAME) .withGeometry(GEOMETRY) .build(); - private final GroupStop stopGroup = stopModelBuilder.groupStop(ID).addLocation(stop).build(); + private final GroupStop stopGroup = siteRepositoryBuilder.groupStop(ID).addLocation(stop).build(); private final MultiModalStation mmStation = MultiModalStation .of(ID) .withName(NAME) @@ -67,7 +67,7 @@ class StopModelTest { @Test void testStop() { - var m = stopModelBuilder.withRegularStop(stop).build(); + var m = siteRepositoryBuilder.withRegularStop(stop).build(); assertEquals(stop, m.getRegularStop(ID)); assertEquals(stop, m.getStopLocation(ID)); assertEquals(expStops, m.listRegularStops().toString()); @@ -79,7 +79,7 @@ void testStop() { @Test void testAreaStop() { - var m = stopModelBuilder.withAreaStop(STOP_AREA).build(); + var m = siteRepositoryBuilder.withAreaStop(STOP_AREA).build(); assertEquals(STOP_AREA, m.getAreaStop(ID)); assertEquals(STOP_AREA, m.getStopLocation(ID)); assertEquals("[AreaStop{F:A Name}]", m.listAreaStops().toString()); @@ -91,7 +91,7 @@ void testAreaStop() { @Test void testStopGroup() { - var m = stopModelBuilder.withGroupStop(stopGroup).build(); + var m = siteRepositoryBuilder.withGroupStop(stopGroup).build(); assertEquals("[GroupStop{F:A}]", m.listGroupStops().toString()); assertEquals("[GroupStop{F:A}]", m.listStopLocations().toString()); assertEquals(stopGroup, m.stopByIndex(stopGroup.getIndex())); @@ -101,7 +101,7 @@ void testStopGroup() { @Test void testStations() { - var m = stopModelBuilder.withStation(STATION).build(); + var m = siteRepositoryBuilder.withStation(STATION).build(); assertEquals(STATION, m.getStationById(ID)); assertEquals(EXP_STATIONS, m.listStations().toString()); assertEquals(STATION, m.getStopLocationsGroup(ID)); @@ -113,7 +113,7 @@ void testStations() { @Test void testMultiModalStation() { - var m = stopModelBuilder.withMultiModalStation(mmStation).build(); + var m = siteRepositoryBuilder.withMultiModalStation(mmStation).build(); assertEquals(mmStation, m.getMultiModalStation(ID)); assertEquals(mmStation, m.getMultiModalStationForStation(STATION)); assertEquals(expMmStations, m.listMultiModalStations().toString()); @@ -126,7 +126,7 @@ void testMultiModalStation() { @Test void testGroupOfStations() { - var m = stopModelBuilder.withGroupOfStation(groupOfStations).build(); + var m = siteRepositoryBuilder.withGroupOfStation(groupOfStations).build(); assertEquals(expGroupOfStation, m.listGroupOfStations().toString()); assertEquals(groupOfStations, m.getStopLocationsGroup(ID)); assertEquals(expStops, m.findStopOrChildStops(ID).toString()); @@ -137,7 +137,7 @@ void testGroupOfStations() { @Test void testNullStopLocationId() { - var m = StopModel.of().build(); + var m = SiteRepository.of().build(); assertNull(m.getStopLocation(null)); } } diff --git a/src/test/java/org/opentripplanner/transit/service/TransitModelTest.java b/application/src/test/java/org/opentripplanner/transit/service/TimetableRepositoryTest.java similarity index 69% rename from src/test/java/org/opentripplanner/transit/service/TransitModelTest.java rename to application/src/test/java/org/opentripplanner/transit/service/TimetableRepositoryTest.java index 95c20245f9a..94af8e20a95 100644 --- a/src/test/java/org/opentripplanner/transit/service/TransitModelTest.java +++ b/application/src/test/java/org/opentripplanner/transit/service/TimetableRepositoryTest.java @@ -16,34 +16,36 @@ import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.timetable.Trip; -class TransitModelTest { +class TimetableRepositoryTest { public static final String FAKE_FEED_ID = "FAKE"; public static final FeedScopedId SAMPLE_TRIP_ID = new FeedScopedId(FAKE_FEED_ID, "1.2"); - private static final ResourceLoader RESOURCE_LOADER = ResourceLoader.of(TransitModelTest.class); + private static final ResourceLoader RESOURCE_LOADER = ResourceLoader.of( + TimetableRepositoryTest.class + ); @Test void validateTimeZones() { // First GTFS bundle should be added successfully var deduplicator = new Deduplicator(); - var stopModel = new StopModel(); + var siteRepository = new SiteRepository(); var graph = new Graph(deduplicator); - var transitModel = new TransitModel(stopModel, deduplicator); + var timetableRepository = new TimetableRepository(siteRepository, deduplicator); ConstantsForTests.addGtfsToGraph( graph, - transitModel, + timetableRepository, ConstantsForTests.SIMPLE_GTFS, new DefaultFareServiceFactory(), FAKE_FEED_ID ); // Then time zone should match the one provided in the feed - assertEquals("America/New_York", transitModel.getTimeZone().getId()); + assertEquals("America/New_York", timetableRepository.getTimeZone().getId()); // Then trip times should be same as in input data - TransitModelIndex transitModelIndex = transitModel.getTransitModelIndex(); - Trip trip = transitModelIndex.getTripForId().get(SAMPLE_TRIP_ID); - Timetable timetable = transitModelIndex.getPatternForTrip().get(trip).getScheduledTimetable(); + TimetableRepositoryIndex timetableRepositoryIndex = timetableRepository.getTimetableRepositoryIndex(); + Trip trip = timetableRepositoryIndex.getTripForId(SAMPLE_TRIP_ID); + Timetable timetable = timetableRepositoryIndex.getPatternForTrip(trip).getScheduledTimetable(); assertEquals(20 * 60, timetable.getTripTimes(trip).getDepartureTime(0)); // Should throw on second bundle, with different agency time zone @@ -52,7 +54,7 @@ void validateTimeZones() { () -> ConstantsForTests.addGtfsToGraph( graph, - transitModel, + timetableRepository, RESOURCE_LOADER.file("kcm_gtfs.zip"), new DefaultFareServiceFactory(), null @@ -68,17 +70,17 @@ void validateTimeZones() { @Test void validateTimeZonesWithExplicitTimeZone() { var deduplicator = new Deduplicator(); - var stopModel = new StopModel(); + var siteRepository = new SiteRepository(); var graph = new Graph(deduplicator); - var transitModel = new TransitModel(stopModel, deduplicator); + var timetableRepository = new TimetableRepository(siteRepository, deduplicator); // Whit explicit time zone - transitModel.initTimeZone(ZoneIds.CHICAGO); + timetableRepository.initTimeZone(ZoneIds.CHICAGO); // First GTFS bundle should be added successfully ConstantsForTests.addGtfsToGraph( graph, - transitModel, + timetableRepository, ConstantsForTests.SIMPLE_GTFS, new DefaultFareServiceFactory(), FAKE_FEED_ID @@ -87,22 +89,22 @@ void validateTimeZonesWithExplicitTimeZone() { // Should load second bundle, with different agency time zone ConstantsForTests.addGtfsToGraph( graph, - transitModel, + timetableRepository, RESOURCE_LOADER.file("kcm_gtfs.zip"), new DefaultFareServiceFactory(), null ); - new TimeZoneAdjusterModule(transitModel).buildGraph(); + new TimeZoneAdjusterModule(timetableRepository).buildGraph(); - TransitModelIndex transitModelIndex = transitModel.getTransitModelIndex(); + TimetableRepositoryIndex timetableRepositoryIndex = timetableRepository.getTimetableRepositoryIndex(); // Then time zone should match the one provided in the feed - assertEquals("America/Chicago", transitModel.getTimeZone().getId()); + assertEquals("America/Chicago", timetableRepository.getTimeZone().getId()); // Then trip times should be on hour less than in input data - Trip trip = transitModelIndex.getTripForId().get(SAMPLE_TRIP_ID); - Timetable timetable = transitModelIndex.getPatternForTrip().get(trip).getScheduledTimetable(); + Trip trip = timetableRepositoryIndex.getTripForId(SAMPLE_TRIP_ID); + Timetable timetable = timetableRepositoryIndex.getPatternForTrip(trip).getScheduledTimetable(); assertEquals(20 * 60 - 60 * 60, timetable.getTripTimes(trip).getDepartureTime(0)); } } diff --git a/src/test/java/org/opentripplanner/transit/speed_test/ResultPrinter.java b/application/src/test/java/org/opentripplanner/transit/speed_test/ResultPrinter.java similarity index 97% rename from src/test/java/org/opentripplanner/transit/speed_test/ResultPrinter.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/ResultPrinter.java index 29348a7e911..1d34c88f08e 100644 --- a/src/test/java/org/opentripplanner/transit/speed_test/ResultPrinter.java +++ b/application/src/test/java/org/opentripplanner/transit/speed_test/ResultPrinter.java @@ -1,17 +1,17 @@ package org.opentripplanner.transit.speed_test; -import static org.opentripplanner.framework.time.DurationUtils.msToSecondsStr; +import static org.opentripplanner.utils.time.DurationUtils.msToSecondsStr; import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.opentripplanner.framework.lang.IntUtils; -import org.opentripplanner.framework.text.Table; import org.opentripplanner.transit.speed_test.model.SpeedTestProfile; import org.opentripplanner.transit.speed_test.model.testcase.TestCase; import org.opentripplanner.transit.speed_test.model.testcase.TestCaseFailedException; import org.opentripplanner.transit.speed_test.model.testcase.TestCases; import org.opentripplanner.transit.speed_test.model.timer.SpeedTestTimer; +import org.opentripplanner.utils.lang.IntUtils; +import org.opentripplanner.utils.text.Table; /** * Printing stuff clutters up the code, so it is convenient to put printing and formatting output diff --git a/src/test/java/org/opentripplanner/transit/speed_test/SpeedIntegrationTest.java b/application/src/test/java/org/opentripplanner/transit/speed_test/SpeedIntegrationTest.java similarity index 94% rename from src/test/java/org/opentripplanner/transit/speed_test/SpeedIntegrationTest.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/SpeedIntegrationTest.java index e5006d949b6..fe847aa9efc 100644 --- a/src/test/java/org/opentripplanner/transit/speed_test/SpeedIntegrationTest.java +++ b/application/src/test/java/org/opentripplanner/transit/speed_test/SpeedIntegrationTest.java @@ -24,14 +24,14 @@ import org.opentripplanner.transit.speed_test.options.SpeedTestConfig; /** - * This test run the SpeedTest on the Portland dataset. It tests all SpeedTest + * This test runs the SpeedTest on the Portland dataset. It tests all SpeedTest * profiles. This is also a good integration-test for the OTP routing query. */ public class SpeedIntegrationTest { /** - * We need to use a relative path here, because the test will update the results files in case - * the results differ. This make it easy to maintain the test. + * We need to use a relative path here, because the test will update the result files in case + * the results differ. This makes it easy to maintain the test. */ private static final File BASE_DIR = Path.of("src", "test", "resources", "speedtest").toFile(); @@ -90,7 +90,7 @@ void runMultiCriteriaWithDestinationPruning() { private static void runProfile(SpeedTestProfile profile) { var opts = speedTestOptions(profile); var config = SpeedTestConfig.config(opts.rootDir()); - var speedTest = new SpeedTest(opts, config, model.graph(), model.transitModel()); + var speedTest = new SpeedTest(opts, config, model.graph(), model.timetableRepository()); // We want to validate the Raptor paths without changes done by the OptimizeTransfers // and itinerary filter chain(set to debug in config) diff --git a/src/test/java/org/opentripplanner/transit/speed_test/SpeedTest.java b/application/src/test/java/org/opentripplanner/transit/speed_test/SpeedTest.java similarity index 84% rename from src/test/java/org/opentripplanner/transit/speed_test/SpeedTest.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/SpeedTest.java index 85a33281f81..ca4e85eed84 100644 --- a/src/test/java/org/opentripplanner/transit/speed_test/SpeedTest.java +++ b/application/src/test/java/org/opentripplanner/transit/speed_test/SpeedTest.java @@ -23,16 +23,19 @@ import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.graph.SerializedGraphObject; import org.opentripplanner.service.realtimevehicles.internal.DefaultRealtimeVehicleService; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; import org.opentripplanner.service.vehiclerental.internal.DefaultVehicleRentalService; import org.opentripplanner.standalone.OtpStartupInfo; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.standalone.config.BuildConfig; import org.opentripplanner.standalone.config.ConfigModel; +import org.opentripplanner.standalone.config.DebugUiConfig; import org.opentripplanner.standalone.config.OtpConfigLoader; +import org.opentripplanner.standalone.config.routerconfig.RaptorEnvironmentFactory; import org.opentripplanner.standalone.config.routerconfig.VectorTileConfig; import org.opentripplanner.standalone.server.DefaultServerRequestContext; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.transit.speed_test.model.SpeedTestProfile; import org.opentripplanner.transit.speed_test.model.testcase.CsvFileSupport; import org.opentripplanner.transit.speed_test.model.testcase.ExpectedResults; @@ -53,7 +56,7 @@ public class SpeedTest { private static final String TRAVEL_SEARCH_FILENAME = "travelSearch"; - private final TransitModel transitModel; + private final TimetableRepository timetableRepository; private final SpeedTestTimer timer = new SpeedTestTimer(); @@ -73,11 +76,11 @@ public SpeedTest( SpeedTestCmdLineOpts opts, SpeedTestConfig config, Graph graph, - TransitModel transitModel + TimetableRepository timetableRepository ) { this.opts = opts; this.config = config; - this.transitModel = transitModel; + this.timetableRepository = timetableRepository; this.tcIO = new CsvFileSupport( @@ -91,44 +94,51 @@ public SpeedTest( this.testCaseDefinitions = tcIO.readTestCaseDefinitions(); this.expectedResultsByTcId = tcIO.readExpectedResults(); - var transitService = new DefaultTransitService(transitModel); + var transitService = new DefaultTransitService(timetableRepository); UpdaterConfigurator.configure( graph, new DefaultRealtimeVehicleService(transitService), new DefaultVehicleRentalService(), - transitModel, + new DefaultVehicleParkingRepository(), + timetableRepository, config.updatersConfig ); - if (transitModel.getUpdaterManager() != null) { - transitModel.getUpdaterManager().startUpdaters(); + if (timetableRepository.getUpdaterManager() != null) { + timetableRepository.getUpdaterManager().startUpdaters(); } this.serverContext = DefaultServerRequestContext.create( config.transitRoutingParams, config.request, - new RaptorConfig<>(config.transitRoutingParams), + new RaptorConfig<>( + config.transitRoutingParams, + RaptorEnvironmentFactory.create(config.transitRoutingParams.searchThreadPoolSize()) + ), graph, - new DefaultTransitService(transitModel), + new DefaultTransitService(timetableRepository), timer.getRegistry(), VectorTileConfig.DEFAULT, TestServerContext.createWorldEnvelopeService(), TestServerContext.createRealtimeVehicleService(transitService), TestServerContext.createVehicleRentalService(), + TestServerContext.createVehicleParkingService(), TestServerContext.createEmissionsService(), + null, config.flexConfig, List.of(), null, TestServerContext.createStreetLimitationParametersService(), null, - null + null, + DebugUiConfig.DEFAULT ); - // Creating transitLayerForRaptor should be integrated into the TransitModel, but for now + // Creating transitLayerForRaptor should be integrated into the TimetableRepository, but for now // we do it manually here - creatTransitLayerForRaptor(transitModel, config.transitRoutingParams); + creatTransitLayerForRaptor(timetableRepository, config.transitRoutingParams); - initializeTransferCache(config.transitRoutingParams, transitModel); + initializeTransferCache(config.transitRoutingParams, timetableRepository); timer.setUp(opts.groupResultsByCategory()); } @@ -139,26 +149,26 @@ public TestStatus status() { public static void main(String[] args) { try { - OtpStartupInfo.logInfo(); + OtpStartupInfo.logInfo("Run Speed Test"); // Given the following setup SpeedTestCmdLineOpts opts = new SpeedTestCmdLineOpts(args); var config = SpeedTestConfig.config(opts.rootDir()); loadOtpFeatures(opts); var model = loadGraph(opts.rootDir(), config.graph); - var transitModel = model.transitModel(); + var timetableRepository = model.timetableRepository(); var buildConfig = model.buildConfig(); var graph = model.graph(); // create a new test - var speedTest = new SpeedTest(opts, config, graph, transitModel); + var speedTest = new SpeedTest(opts, config, graph, timetableRepository); - assertTestDateHasData(transitModel, config, buildConfig); + assertTestDateHasData(timetableRepository, config, buildConfig); // and run it speedTest.runTest(); - if (speedTest.transitModel.getUpdaterManager() != null) { - speedTest.transitModel.getUpdaterManager().stop(); + if (speedTest.timetableRepository.getUpdaterManager() != null) { + speedTest.timetableRepository.getUpdaterManager().stop(); } } catch (OtpAppException ae) { System.err.println(ae.getMessage()); @@ -249,7 +259,7 @@ private RoutingResponse performRouting(TestCase testCase) { opts, config, profile, - transitModel.getTimeZone() + timetableRepository.getTimeZone() ); var routingRequest = speedTestRequest.toRouteRequest(); return serverContext.routingService().route(routingRequest); @@ -272,10 +282,10 @@ private static LoadModel loadGraph(File baseDir, URI path) { throw new IllegalStateException(); } - TransitModel transitModel = serializedGraphObject.transitModel; - transitModel.index(); - graph.index(transitModel.getStopModel()); - return new LoadModel(graph, transitModel, serializedGraphObject.buildConfig); + TimetableRepository timetableRepository = serializedGraphObject.timetableRepository; + timetableRepository.index(); + graph.index(timetableRepository.getSiteRepository()); + return new LoadModel(graph, timetableRepository, serializedGraphObject.buildConfig); } private void initProfileStatistics() { @@ -331,8 +341,8 @@ private void saveTestCasesToResultFile() { private void updateTimersWithGlobalCounters() { final var transitService = serverContext.transitService(); timer.globalCount("transitdata_stops", transitService.listStopLocations().size()); - timer.globalCount("transitdata_patterns", transitService.getAllTripPatterns().size()); - timer.globalCount("transitdata_trips", transitService.getAllTrips().size()); + timer.globalCount("transitdata_patterns", transitService.listTripPatterns().size()); + timer.globalCount("transitdata_trips", transitService.listTrips().size()); // we want to get the numbers after the garbage collection forceGCToAvoidGCLater(); @@ -361,5 +371,5 @@ private List trimItineraries(RoutingResponse routingResponse) { /* inline classes */ - record LoadModel(Graph graph, TransitModel transitModel, BuildConfig buildConfig) {} + record LoadModel(Graph graph, TimetableRepository timetableRepository, BuildConfig buildConfig) {} } diff --git a/src/test/java/org/opentripplanner/transit/speed_test/SpeedTestRequest.java b/application/src/test/java/org/opentripplanner/transit/speed_test/SpeedTestRequest.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/SpeedTestRequest.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/SpeedTestRequest.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/SpeedTestProfile.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/SpeedTestProfile.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/model/SpeedTestProfile.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/SpeedTestProfile.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/CsvFileSupport.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/CsvFileSupport.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/model/testcase/CsvFileSupport.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/CsvFileSupport.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/ExpectedResults.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/ExpectedResults.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/model/testcase/ExpectedResults.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/ExpectedResults.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/ItineraryResultMapper.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/ItineraryResultMapper.java similarity index 99% rename from src/test/java/org/opentripplanner/transit/speed_test/model/testcase/ItineraryResultMapper.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/ItineraryResultMapper.java index 24cbea4aaa0..18d742b895f 100644 --- a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/ItineraryResultMapper.java +++ b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/ItineraryResultMapper.java @@ -9,7 +9,6 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; import org.opentripplanner.model.plan.StreetLeg; @@ -19,6 +18,7 @@ import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.utils.lang.IntUtils; /** * Map an Itinerary to a result instance. We do this to normalize the Itinerary for the purpose of diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/Result.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/Result.java similarity index 94% rename from src/test/java/org/opentripplanner/transit/speed_test/model/testcase/Result.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/Result.java index d44c8e4d8cb..34c63d49dfb 100644 --- a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/Result.java +++ b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/Result.java @@ -4,10 +4,10 @@ import java.util.Collection; import java.util.Comparator; import java.util.List; -import org.opentripplanner.framework.collection.CompositeComparator; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.utils.collection.CompositeComparator; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; /** * This class is responsible for holding information about a test result - a single itinerary. The diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TableTestReport.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TableTestReport.java similarity index 85% rename from src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TableTestReport.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TableTestReport.java index 7534529492f..a746e744a96 100644 --- a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TableTestReport.java +++ b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TableTestReport.java @@ -1,16 +1,16 @@ package org.opentripplanner.transit.speed_test.model.testcase; -import static org.opentripplanner.framework.text.Table.Align.Center; -import static org.opentripplanner.framework.text.Table.Align.Left; -import static org.opentripplanner.framework.text.Table.Align.Right; +import static org.opentripplanner.utils.text.Table.Align.Center; +import static org.opentripplanner.utils.text.Table.Align.Left; +import static org.opentripplanner.utils.text.Table.Align.Right; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.framework.text.Table; -import org.opentripplanner.framework.text.TableBuilder; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.routing.util.DiffEntry; +import org.opentripplanner.utils.text.Table; +import org.opentripplanner.utils.text.TableBuilder; +import org.opentripplanner.utils.time.TimeUtils; /** * This class is responsible for creating a test report as a table. The Table is easy to read and diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCase.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCase.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCase.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCase.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCaseDefinition.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCaseDefinition.java similarity index 89% rename from src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCaseDefinition.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCaseDefinition.java index 4a99798b10e..604a4bd1743 100644 --- a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCaseDefinition.java +++ b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCaseDefinition.java @@ -2,10 +2,10 @@ import java.time.Duration; import org.opentripplanner.api.parameter.QualifiedModeSet; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; -import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; import org.opentripplanner.model.GenericLocation; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; +import org.opentripplanner.utils.tostring.ValueObjectToStringBuilder; public record TestCaseDefinition( String id, diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCaseFailedException.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCaseFailedException.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCaseFailedException.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCaseFailedException.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCaseResults.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCaseResults.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCaseResults.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCaseResults.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCases.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCases.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCases.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestCases.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestStatus.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestStatus.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestStatus.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestStatus.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestStatusTest.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestStatusTest.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestStatusTest.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/TestStatusTest.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/io/AbstractCsvFile.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/io/AbstractCsvFile.java similarity index 97% rename from src/test/java/org/opentripplanner/transit/speed_test/model/testcase/io/AbstractCsvFile.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/io/AbstractCsvFile.java index c703476290e..fe5287b13c3 100644 --- a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/io/AbstractCsvFile.java +++ b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/io/AbstractCsvFile.java @@ -14,9 +14,9 @@ import java.util.function.Function; import java.util.regex.Pattern; import java.util.stream.Collectors; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.transit.speed_test.model.testcase.TestCase; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/io/ResultCsvFile.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/io/ResultCsvFile.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/model/testcase/io/ResultCsvFile.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/io/ResultCsvFile.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/io/TestCaseDefinitionCsvFile.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/io/TestCaseDefinitionCsvFile.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/model/testcase/io/TestCaseDefinitionCsvFile.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/testcase/io/TestCaseDefinitionCsvFile.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/timer/MeterRegistrySetup.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/timer/MeterRegistrySetup.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/model/timer/MeterRegistrySetup.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/timer/MeterRegistrySetup.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/model/timer/SpeedTestTimer.java b/application/src/test/java/org/opentripplanner/transit/speed_test/model/timer/SpeedTestTimer.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/model/timer/SpeedTestTimer.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/model/timer/SpeedTestTimer.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/options/SpeedTestCmdLineOpts.java b/application/src/test/java/org/opentripplanner/transit/speed_test/options/SpeedTestCmdLineOpts.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/options/SpeedTestCmdLineOpts.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/options/SpeedTestCmdLineOpts.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/options/SpeedTestCmdLineOptsBuilder.java b/application/src/test/java/org/opentripplanner/transit/speed_test/options/SpeedTestCmdLineOptsBuilder.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/options/SpeedTestCmdLineOptsBuilder.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/options/SpeedTestCmdLineOptsBuilder.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/options/SpeedTestConfig.java b/application/src/test/java/org/opentripplanner/transit/speed_test/options/SpeedTestConfig.java similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/options/SpeedTestConfig.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/options/SpeedTestConfig.java diff --git a/src/test/java/org/opentripplanner/transit/speed_test/package.md b/application/src/test/java/org/opentripplanner/transit/speed_test/package.md similarity index 100% rename from src/test/java/org/opentripplanner/transit/speed_test/package.md rename to application/src/test/java/org/opentripplanner/transit/speed_test/package.md diff --git a/src/test/java/org/opentripplanner/transit/speed_test/support/AssertSpeedTestSetup.java b/application/src/test/java/org/opentripplanner/transit/speed_test/support/AssertSpeedTestSetup.java similarity index 89% rename from src/test/java/org/opentripplanner/transit/speed_test/support/AssertSpeedTestSetup.java rename to application/src/test/java/org/opentripplanner/transit/speed_test/support/AssertSpeedTestSetup.java index 4113d5979b1..82db561bddf 100644 --- a/src/test/java/org/opentripplanner/transit/speed_test/support/AssertSpeedTestSetup.java +++ b/application/src/test/java/org/opentripplanner/transit/speed_test/support/AssertSpeedTestSetup.java @@ -3,17 +3,17 @@ import org.opentripplanner.framework.application.OtpAppException; import org.opentripplanner.framework.application.OtpFileNames; import org.opentripplanner.standalone.config.BuildConfig; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.transit.speed_test.options.SpeedTestConfig; public class AssertSpeedTestSetup { public static void assertTestDateHasData( - TransitModel transitModel, + TimetableRepository timetableRepository, SpeedTestConfig config, BuildConfig buildConfig ) { - int numberOfPatternForTestDate = transitModel + int numberOfPatternForTestDate = timetableRepository .getTransitLayer() .getTripPatternsForRunningDate(config.testDate) .size(); diff --git a/application/src/test/java/org/opentripplanner/updater/GtfsRealtimeFuzzyTripMatcherTest.java b/application/src/test/java/org/opentripplanner/updater/GtfsRealtimeFuzzyTripMatcherTest.java new file mode 100644 index 00000000000..fb1e196f7ae --- /dev/null +++ b/application/src/test/java/org/opentripplanner/updater/GtfsRealtimeFuzzyTripMatcherTest.java @@ -0,0 +1,183 @@ +package org.opentripplanner.updater; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; + +import com.google.transit.realtime.GtfsRealtime.TripDescriptor; +import java.time.LocalDate; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; +import org.opentripplanner.model.calendar.CalendarServiceData; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.transit.model.framework.Deduplicator; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.transit.model.timetable.RealTimeTripTimes; +import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.transit.model.timetable.TripTimesFactory; +import org.opentripplanner.transit.service.DefaultTransitService; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.SiteRepositoryBuilder; +import org.opentripplanner.transit.service.TimetableRepository; + +public class GtfsRealtimeFuzzyTripMatcherTest { + + private static final String ROUTE_ID = "r1"; + private static final String FEED_ID = TimetableRepositoryForTest.FEED_ID; + private static final LocalDate SERVICE_DATE = LocalDate.of(2024, 11, 13); + private static final String GTFS_SERVICE_DATE = SERVICE_DATE.toString().replaceAll("-", ""); + private static final int SERVICE_CODE = 555; + private static final SiteRepositoryBuilder siteRepositoryBuilder = SiteRepository.of(); + private static final TimetableRepositoryForTest TEST_MODEL = new TimetableRepositoryForTest( + siteRepositoryBuilder + ); + private static final RegularStop STOP_1 = TEST_MODEL.stop("s1").build(); + private static final RegularStop STOP_2 = TEST_MODEL.stop("s2").build(); + private static final TimetableRepository TIMETABLE_REPOSITORY = new TimetableRepository( + siteRepositoryBuilder.build(), + new Deduplicator() + ); + private static final Route ROUTE = TimetableRepositoryForTest.route(id(ROUTE_ID)).build(); + private static final String TRIP_ID = "t1"; + private static final Trip TRIP = TimetableRepositoryForTest.trip(TRIP_ID).build(); + + private static final FeedScopedId SERVICE_ID = TimetableRepositoryForTest.id("sid1"); + private static final String START_TIME = "07:30:00"; + private static final RealTimeTripTimes TRIP_TIMES = TripTimesFactory.tripTimes( + TRIP, + TEST_MODEL.stopTimesEvery5Minutes(5, TRIP, START_TIME), + new Deduplicator() + ); + private static final TripPattern TRIP_PATTERN = TimetableRepositoryForTest + .tripPattern("tp1", ROUTE) + .withStopPattern(TimetableRepositoryForTest.stopPattern(STOP_1, STOP_2)) + .withScheduledTimeTableBuilder(builder -> builder.addTripTimes(TRIP_TIMES)) + .build(); + + @BeforeAll + static void setup() { + TRIP_TIMES.setServiceCode(SERVICE_CODE); + CalendarServiceData calendarServiceData = new CalendarServiceData(); + calendarServiceData.putServiceDatesForServiceId(SERVICE_ID, List.of(SERVICE_DATE)); + TIMETABLE_REPOSITORY.addTripPattern(TRIP_PATTERN.getId(), TRIP_PATTERN); + TIMETABLE_REPOSITORY.getServiceCodes().put(SERVICE_ID, SERVICE_CODE); + TIMETABLE_REPOSITORY.updateCalendarServiceData( + true, + calendarServiceData, + DataImportIssueStore.NOOP + ); + TIMETABLE_REPOSITORY.index(); + } + + @Test + void noTripId() { + var matcher = matcher(); + TripDescriptor trip = matchingTripUpdate().build(); + assertEquals(TRIP_ID, matcher.match(FEED_ID, trip).getTripId()); + } + + @Test + void tripIdSetButNotInSchedule() { + var matcher = matcher(); + TripDescriptor trip = matchingTripUpdate().setTripId("does-not-exist-in-schedule").build(); + assertEquals(TRIP_ID, matcher.match(FEED_ID, trip).getTripId()); + } + + @Test + void tripIdExistsInSchedule() { + var matcher = matcher(); + TripDescriptor trip = matchingTripUpdate().setTripId(TRIP_ID).build(); + assertEquals(TRIP_ID, matcher.match(FEED_ID, trip).getTripId()); + } + + @Test + void incorrectRoute() { + var matcher = matcher(); + TripDescriptor trip = matchingTripUpdate().setRouteId("does-not-exists").build(); + assertFalse(matcher.match(FEED_ID, trip).hasTripId()); + } + + @Test + void incorrectDateFormat() { + var matcher = matcher(); + TripDescriptor trip = matchingTripUpdate().setStartDate("ZZZ").build(); + assertFalse(matcher.match(FEED_ID, trip).hasTripId()); + } + + @Test + void incorrectDirection() { + var matcher = matcher(); + TripDescriptor trip = matchingTripUpdate().setDirectionId(1).build(); + assertFalse(matcher.match(FEED_ID, trip).hasTripId()); + } + + @Test + void noMatch() { + // Test matching with "real time", when schedule uses time greater than 24:00 + var trip = TripDescriptor + .newBuilder() + .setRouteId("4") + .setDirectionId(0) + .setStartTime("12:00:00") + .setStartDate("20090915") + .build(); + // No departure at this time + assertFalse(trip.hasTripId()); + trip = + TripDescriptor + .newBuilder() + .setRouteId("1") + .setStartTime("06:47:00") + .setStartDate("20090915") + .build(); + // Missing direction id + assertFalse(trip.hasTripId()); + } + + @Nested + class IncompleteData { + + @Test + void noRouteId() { + var td = matchingTripUpdate().clearRouteId().build(); + assertFalse(matcher().match(FEED_ID, td).hasTripId()); + } + + @Test + void noDirectionId() { + var td = matchingTripUpdate().clearDirectionId().build(); + assertFalse(matcher().match(FEED_ID, td).hasTripId()); + } + + @Test + void noStartDate() { + var td = matchingTripUpdate().clearStartDate().build(); + assertFalse(matcher().match(FEED_ID, td).hasTripId()); + } + + @Test + void noStartTime() { + var td = matchingTripUpdate().clearStartTime().build(); + assertFalse(matcher().match(FEED_ID, td).hasTripId()); + } + } + + private static GtfsRealtimeFuzzyTripMatcher matcher() { + return new GtfsRealtimeFuzzyTripMatcher(new DefaultTransitService(TIMETABLE_REPOSITORY)); + } + + private static TripDescriptor.Builder matchingTripUpdate() { + return TripDescriptor + .newBuilder() + .setRouteId(ROUTE_ID) + .setDirectionId(2) + .setStartTime(START_TIME) + .setStartDate(GTFS_SERVICE_DATE); + } +} diff --git a/src/test/java/org/opentripplanner/updater/alert/AlertsUpdateHandlerTest.java b/application/src/test/java/org/opentripplanner/updater/alert/AlertsUpdateHandlerTest.java similarity index 99% rename from src/test/java/org/opentripplanner/updater/alert/AlertsUpdateHandlerTest.java rename to application/src/test/java/org/opentripplanner/updater/alert/AlertsUpdateHandlerTest.java index 6e590ce4957..077de6d072d 100644 --- a/src/test/java/org/opentripplanner/updater/alert/AlertsUpdateHandlerTest.java +++ b/application/src/test/java/org/opentripplanner/updater/alert/AlertsUpdateHandlerTest.java @@ -25,13 +25,15 @@ import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.impl.TransitAlertServiceImpl; import org.opentripplanner.routing.services.TransitAlertService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; public class AlertsUpdateHandlerTest { private AlertsUpdateHandler handler; - private final TransitAlertService service = new TransitAlertServiceImpl(new TransitModel()); + private final TransitAlertService service = new TransitAlertServiceImpl( + new TimetableRepository() + ); @BeforeEach public void setUp() { diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/AddedTripBuilderTest.java b/application/src/test/java/org/opentripplanner/updater/siri/AddedTripBuilderTest.java similarity index 92% rename from src/ext-test/java/org/opentripplanner/ext/siri/AddedTripBuilderTest.java rename to application/src/test/java/org/opentripplanner/updater/siri/AddedTripBuilderTest.java index 364d6215252..abed2144982 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/AddedTripBuilderTest.java +++ b/application/src/test/java/org/opentripplanner/updater/siri/AddedTripBuilderTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -16,10 +16,9 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; -import org.opentripplanner.ext.siri.mapper.SiriTransportModeMapper; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.model.calendar.CalendarServiceData; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.SubMode; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; @@ -34,27 +33,28 @@ import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.transit.service.TransitEditorService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.updater.siri.mapper.SiriTransportModeMapper; import org.opentripplanner.updater.spi.UpdateError; import uk.org.siri.siri20.VehicleModesEnumeration; class AddedTripBuilderTest { - private static final Agency AGENCY = TransitModelForTest.AGENCY; + private static final Agency AGENCY = TimetableRepositoryForTest.AGENCY; private static final ZoneId TIME_ZONE = AGENCY.getTimezone(); private static final Operator OPERATOR = Operator - .of(TransitModelForTest.id("OPERATOR_ID")) + .of(TimetableRepositoryForTest.id("OPERATOR_ID")) .withName("OPERATOR_NAME") .build(); - private static final Route REPLACED_ROUTE = TransitModelForTest + private static final Route REPLACED_ROUTE = TimetableRepositoryForTest .route("REPLACED_ROUTE") .withAgency(AGENCY) .withOperator(OPERATOR) .build(); private static final String LINE_REF = "ROUTE_ID"; - private static final FeedScopedId TRIP_ID = TransitModelForTest.id("TRIP_ID"); + private static final FeedScopedId TRIP_ID = TimetableRepositoryForTest.id("TRIP_ID"); private static final LocalDate SERVICE_DATE = LocalDate.of(2023, 2, 17); private static final TransitMode TRANSIT_MODE = TransitMode.RAIL; private static final String SUB_MODE = "replacementRailService"; @@ -62,14 +62,14 @@ class AddedTripBuilderTest { private static final String HEADSIGN = "TEST TRIP TOWARDS TEST ISLAND"; /* Transit model */ - private static final TransitModelForTest MODEL_TEST = TransitModelForTest.of(); + private static final TimetableRepositoryForTest MODEL_TEST = TimetableRepositoryForTest.of(); private static final RegularStop STOP_A = MODEL_TEST.stop("A").build(); private static final RegularStop STOP_B = MODEL_TEST.stop("B").build(); private static final RegularStop STOP_C = MODEL_TEST.stop("C").build(); private static final RegularStop STOP_D = MODEL_TEST.stop("D").build(); - private final StopModel STOP_MODEL = MODEL_TEST - .stopModelBuilder() + private final SiteRepository SITE_REPOSITORY = MODEL_TEST + .siteRepositoryBuilder() .withRegularStop(STOP_A) .withRegularStop(STOP_B) .withRegularStop(STOP_C) @@ -77,7 +77,10 @@ class AddedTripBuilderTest { .build(); private final Deduplicator DEDUPLICATOR = new Deduplicator(); - private final TransitModel TRANSIT_MODEL = new TransitModel(STOP_MODEL, DEDUPLICATOR); + private final TimetableRepository TRANSIT_MODEL = new TimetableRepository( + SITE_REPOSITORY, + DEDUPLICATOR + ); private TransitEditorService transitService; private EntityResolver ENTITY_RESOLVER; @@ -85,15 +88,15 @@ class AddedTripBuilderTest { void setUp() { // Add entities to transit model for the entity resolver TRANSIT_MODEL.addAgency(AGENCY); - final TripPattern pattern = TransitModelForTest + final TripPattern pattern = TimetableRepositoryForTest .tripPattern("REPLACED_ROUTE_PATTERN_ID", REPLACED_ROUTE) - .withStopPattern(TransitModelForTest.stopPattern(STOP_A, STOP_B)) + .withStopPattern(TimetableRepositoryForTest.stopPattern(STOP_A, STOP_B)) .build(); TRANSIT_MODEL.addTripPattern(pattern.getId(), pattern); // Crate a scheduled calendar, to have the SERVICE_DATE be within the transit feed coverage CalendarServiceData calendarServiceData = new CalendarServiceData(); - var cal_id = TransitModelForTest.id("CAL_1"); + var cal_id = TimetableRepositoryForTest.id("CAL_1"); calendarServiceData.putServiceDatesForServiceId( cal_id, List.of(SERVICE_DATE.minusDays(1), SERVICE_DATE, SERVICE_DATE.plusDays(1)) @@ -107,7 +110,10 @@ void setUp() { // Create the entity resolver only after the model has been indexed ENTITY_RESOLVER = - new EntityResolver(new DefaultTransitService(TRANSIT_MODEL), TransitModelForTest.FEED_ID); + new EntityResolver( + new DefaultTransitService(TRANSIT_MODEL), + TimetableRepositoryForTest.FEED_ID + ); } @Test @@ -129,7 +135,8 @@ void testAddedTrip() { false, SHORT_NAME, HEADSIGN, - List.of() + List.of(), + "DATASOURCE" ) .build(); @@ -241,7 +248,8 @@ void testAddedTripOnAddedRoute() { false, SHORT_NAME, HEADSIGN, - List.of() + List.of(), + "DATASOURCE" ) .build(); @@ -250,7 +258,7 @@ void testAddedTripOnAddedRoute() { var firstTrip = firstAddedTrip.successValue().tripTimes().getTrip(); - var tripId2 = TransitModelForTest.id("TRIP_ID_2"); + var tripId2 = TimetableRepositoryForTest.id("TRIP_ID_2"); var secondAddedTrip = new AddedTripBuilder( transitService, @@ -269,7 +277,8 @@ void testAddedTripOnAddedRoute() { false, SHORT_NAME, HEADSIGN, - List.of() + List.of(), + "DATASOURCE" ) .build(); @@ -311,7 +320,8 @@ void testAddedTripOnExistingRoute() { false, SHORT_NAME, HEADSIGN, - List.of() + List.of(), + "DATASOURCE" ) .build(); @@ -345,7 +355,8 @@ void testAddedTripWithoutReplacedRoute() { false, SHORT_NAME, HEADSIGN, - List.of() + List.of(), + "DATASOURCE" ) .build(); @@ -389,7 +400,8 @@ void testAddedTripFailOnMissingServiceId() { false, SHORT_NAME, HEADSIGN, - List.of() + List.of(), + "DATASOURCE" ) .build(); @@ -444,7 +456,8 @@ void testAddedTripFailOnNonIncreasingDwellTime() { false, SHORT_NAME, HEADSIGN, - List.of() + List.of(), + "DATASOURCE" ) .build(); @@ -483,7 +496,8 @@ void testAddedTripFailOnTooFewCalls() { false, SHORT_NAME, HEADSIGN, - List.of() + List.of(), + "DATASOURCE" ) .build(); @@ -530,7 +544,8 @@ void testAddedTripFailOnUnknownStop() { false, SHORT_NAME, HEADSIGN, - List.of() + List.of(), + "DATASOURCE" ) .build(); @@ -559,7 +574,7 @@ void testGetTransportMode( ) { // Arrange var route = Route - .of(TransitModelForTest.id(LINE_REF)) + .of(TimetableRepositoryForTest.id(LINE_REF)) .withShortName(SHORT_NAME) .withAgency(AGENCY) .withMode(TransitMode.valueOf(replacedRouteMode)) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/ModifiedTripBuilderTest.java b/application/src/test/java/org/opentripplanner/updater/siri/ModifiedTripBuilderTest.java similarity index 91% rename from src/ext-test/java/org/opentripplanner/ext/siri/ModifiedTripBuilderTest.java rename to application/src/test/java/org/opentripplanner/updater/siri/ModifiedTripBuilderTest.java index 2bba22b3283..6c1797a24a2 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/ModifiedTripBuilderTest.java +++ b/application/src/test/java/org/opentripplanner/updater/siri/ModifiedTripBuilderTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -17,7 +17,7 @@ import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.StopTime; import org.opentripplanner.model.calendar.CalendarServiceData; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; @@ -31,8 +31,8 @@ import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.model.timetable.TripTimesFactory; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.SiteRepository; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.updater.spi.UpdateError; import uk.org.siri.siri20.DepartureBoardingActivityEnumeration; @@ -40,9 +40,9 @@ class ModifiedTripBuilderTest { /* Transit model */ - private static final Agency AGENCY = TransitModelForTest.AGENCY; + private static final Agency AGENCY = TimetableRepositoryForTest.AGENCY; private static final ZoneId TIME_ZONE = AGENCY.getTimezone(); - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); private static final Station STATION_A = TEST_MODEL.station("A").build(); private static final Station STATION_B = TEST_MODEL.station("B").build(); private static final Station STATION_C = TEST_MODEL.station("C").build(); @@ -65,19 +65,19 @@ class ModifiedTripBuilderTest { .build(); private static final RegularStop STOP_D = TEST_MODEL.stop("D").build(); - private static final Route ROUTE = TransitModelForTest + private static final Route ROUTE = TimetableRepositoryForTest .route("ROUTE_ID") .withAgency(AGENCY) .build(); - private static final TripPattern PATTERN = TransitModelForTest + private static final TripPattern PATTERN = TimetableRepositoryForTest .tripPattern("PATTERN_ID", ROUTE) - .withStopPattern(TransitModelForTest.stopPattern(STOP_A_1, STOP_B_1, STOP_C_1)) + .withStopPattern(TimetableRepositoryForTest.stopPattern(STOP_A_1, STOP_B_1, STOP_C_1)) .build(); - private static final FeedScopedId SERVICE_ID = TransitModelForTest.id("CAL_1"); + private static final FeedScopedId SERVICE_ID = TimetableRepositoryForTest.id("CAL_1"); - private static final Trip TRIP = TransitModelForTest + private static final Trip TRIP = TimetableRepositoryForTest .trip("TRIP") .withRoute(ROUTE) .withServiceId(SERVICE_ID) @@ -119,22 +119,25 @@ class ModifiedTripBuilderTest { ); private static final LocalDate SERVICE_DATE = LocalDate.of(2023, 2, 17); - private final StopModel stopModel = TEST_MODEL - .stopModelBuilder() + private final SiteRepository siteRepository = TEST_MODEL + .siteRepositoryBuilder() .withRegularStop(STOP_A_1) .withRegularStop(STOP_A_2) .withRegularStop(STOP_B_1) .withRegularStop(STOP_C_1) .withRegularStop(STOP_D) .build(); - private final TransitModel transitModel = new TransitModel(stopModel, DEDUPLICATOR); + private final TimetableRepository timetableRepository = new TimetableRepository( + siteRepository, + DEDUPLICATOR + ); private EntityResolver entityResolver; @BeforeEach void setUp() { // Add entities to transit model for the entity resolver - transitModel.addAgency(AGENCY); - transitModel.addTripPattern(PATTERN.getId(), PATTERN); + timetableRepository.addAgency(AGENCY); + timetableRepository.addTripPattern(PATTERN.getId(), PATTERN); // Crate a scheduled calendar, to have the SERVICE_DATE be within the transit feed coverage CalendarServiceData calendarServiceData = new CalendarServiceData(); @@ -142,15 +145,22 @@ void setUp() { SERVICE_ID, List.of(SERVICE_DATE.minusDays(1), SERVICE_DATE, SERVICE_DATE.plusDays(1)) ); - transitModel.getServiceCodes().put(SERVICE_ID, 0); - transitModel.updateCalendarServiceData(true, calendarServiceData, DataImportIssueStore.NOOP); + timetableRepository.getServiceCodes().put(SERVICE_ID, 0); + timetableRepository.updateCalendarServiceData( + true, + calendarServiceData, + DataImportIssueStore.NOOP + ); // Create transit model index - transitModel.index(); + timetableRepository.index(); // Create the entity resolver only after the model has been indexed entityResolver = - new EntityResolver(new DefaultTransitService(transitModel), TransitModelForTest.FEED_ID); + new EntityResolver( + new DefaultTransitService(timetableRepository), + TimetableRepositoryForTest.FEED_ID + ); } @Test @@ -159,12 +169,13 @@ void testUpdateNoCalls() { TRIP_TIMES, PATTERN, SERVICE_DATE, - transitModel.getTimeZone(), + timetableRepository.getTimeZone(), entityResolver, List.of(), false, null, - false + false, + "DATASOURCE" ) .build(); @@ -188,12 +199,13 @@ void testUpdateCancellation() { TRIP_TIMES, PATTERN, SERVICE_DATE, - transitModel.getTimeZone(), + timetableRepository.getTimeZone(), entityResolver, List.of(), true, null, - false + false, + "DATASOURCE" ) .build(); @@ -211,7 +223,7 @@ void testUpdateSameStops() { TRIP_TIMES, PATTERN, SERVICE_DATE, - transitModel.getTimeZone(), + timetableRepository.getTimeZone(), entityResolver, List.of( TestCall @@ -237,7 +249,8 @@ void testUpdateSameStops() { ), false, null, - false + false, + "DATASOURCE" ) .build(); @@ -261,7 +274,7 @@ void testUpdateValidationFailure() { TRIP_TIMES, PATTERN, SERVICE_DATE, - transitModel.getTimeZone(), + timetableRepository.getTimeZone(), entityResolver, List.of( TestCall @@ -287,7 +300,8 @@ void testUpdateValidationFailure() { ), false, null, - false + false, + "DATASOURCE" ) .build(); @@ -309,7 +323,7 @@ void testUpdateSameStopsDepartEarly() { TRIP_TIMES, PATTERN, SERVICE_DATE, - transitModel.getTimeZone(), + timetableRepository.getTimeZone(), entityResolver, List.of( TestCall @@ -335,7 +349,8 @@ void testUpdateSameStopsDepartEarly() { ), false, null, - false + false, + "DATASOURCE" ) .build(); @@ -359,7 +374,7 @@ void testUpdateUpdatedStop() { TRIP_TIMES, PATTERN, SERVICE_DATE, - transitModel.getTimeZone(), + timetableRepository.getTimeZone(), entityResolver, List.of( TestCall @@ -385,7 +400,8 @@ void testUpdateUpdatedStop() { ), false, null, - false + false, + "DATASOURCE" ) .build(); @@ -414,7 +430,7 @@ void testUpdateCascading() { TRIP_TIMES, PATTERN, SERVICE_DATE, - transitModel.getTimeZone(), + timetableRepository.getTimeZone(), entityResolver, List.of( TestCall @@ -441,7 +457,8 @@ void testUpdateCascading() { ), false, null, - false + false, + "DATASOURCE" ) .build(); @@ -464,7 +481,7 @@ void testUpdateCascading() { firstResult.successValue().tripTimes(), PATTERN, SERVICE_DATE, - transitModel.getTimeZone(), + timetableRepository.getTimeZone(), entityResolver, List.of( TestCall @@ -486,7 +503,8 @@ void testUpdateCascading() { ), false, null, - false + false, + "DATASOURCE" ) .build(); diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriAlertsUpdateHandlerTest.java b/application/src/test/java/org/opentripplanner/updater/siri/SiriAlertsUpdateHandlerTest.java similarity index 98% rename from src/ext-test/java/org/opentripplanner/ext/siri/SiriAlertsUpdateHandlerTest.java rename to application/src/test/java/org/opentripplanner/updater/siri/SiriAlertsUpdateHandlerTest.java index e861ca81c95..3cd8e50c000 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriAlertsUpdateHandlerTest.java +++ b/application/src/test/java/org/opentripplanner/updater/siri/SiriAlertsUpdateHandlerTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -80,15 +80,17 @@ public String getFeedName() { public void setUp() throws Exception { super.setUp(); - realTimeUpdateContext = new DefaultRealTimeUpdateContext(graph, transitModel); + realTimeUpdateContext = new DefaultRealTimeUpdateContext(graph, timetableRepository); if (transitService == null) { - transitService = new DefaultTransitService(transitModel); - transitModel.setUpdaterManager(new GraphUpdaterManager(realTimeUpdateContext, List.of())); + transitService = new DefaultTransitService(timetableRepository); + timetableRepository.setUpdaterManager( + new GraphUpdaterManager(realTimeUpdateContext, List.of()) + ); } else { transitAlertService.getAllAlerts().clear(); } if (alertsUpdateHandler == null) { - transitAlertService = new TransitAlertServiceImpl(transitModel); + transitAlertService = new TransitAlertServiceImpl(timetableRepository); alertsUpdateHandler = new SiriAlertsUpdateHandler(FEED_ID, transitAlertService, Duration.ZERO); } @@ -196,8 +198,8 @@ public void testSiriSxUpdateForStop() { final List alertUrlList = transitAlert.siriUrls(); AlertUrl alertUrl = alertUrlList.get(0); - assertEquals(infoLinkUri, alertUrl.uri); - assertEquals(infoLinkLabel, alertUrl.label); + assertEquals(infoLinkUri, alertUrl.uri()); + assertEquals(infoLinkLabel, alertUrl.label()); } @Test @@ -457,7 +459,7 @@ public void testSiriSxUpdateForTripByVehicleJourney() { assertTrue(transitAlertService.getAllAlerts().isEmpty()); - var modelZoneId = transitModel.getTimeZone(); + var modelZoneId = timetableRepository.getTimeZone(); var situationNumber = "TST:SituationNumber:1234"; var startTime = LocalDateTime.parse("2014-01-01T00:00:00").atZone(modelZoneId); var endTime = LocalDateTime.parse("2014-01-01T23:59:59").atZone(modelZoneId); @@ -496,7 +498,7 @@ public void testSiriSxUpdateForTripAndStopByVehicleJourney() { assertTrue(transitAlertService.getAllAlerts().isEmpty()); - ZoneId zoneId = transitModel.getTimeZone(); + ZoneId zoneId = timetableRepository.getTimeZone(); final String situationNumber = "TST:SituationNumber:1234"; final ZonedDateTime startTime = LocalDateTime.parse("2014-01-01T00:00:00").atZone(zoneId); final ZonedDateTime endTime = LocalDateTime.parse("2014-01-01T23:59:59").atZone(zoneId); diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriEtBuilder.java b/application/src/test/java/org/opentripplanner/updater/siri/SiriEtBuilder.java similarity index 97% rename from src/ext-test/java/org/opentripplanner/ext/siri/SiriEtBuilder.java rename to application/src/test/java/org/opentripplanner/updater/siri/SiriEtBuilder.java index 3b54809b0a3..737fb04917e 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriEtBuilder.java +++ b/application/src/test/java/org/opentripplanner/updater/siri/SiriEtBuilder.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import java.math.BigInteger; import java.time.LocalDate; @@ -39,6 +39,7 @@ public SiriEtBuilder(DateTimeHelper dateTimeHelper) { // Set default values evj.setMonitored(true); + evj.setDataSource("DATASOURCE"); } public List buildEstimatedTimetableDeliveries() { @@ -237,11 +238,15 @@ public EstimatedCallsBuilder(DateTimeHelper dateTimeHelper, int orderOffset) { } public EstimatedCallsBuilder call(StopLocation stop) { + return call(stop.getId().getId()); + } + + public EstimatedCallsBuilder call(String stopPointRef) { var call = new EstimatedCall(); call.setOrder(BigInteger.valueOf(orderOffset + calls.size())); var ref = new StopPointRef(); - ref.setValue(stop.getId().getId()); + ref.setValue(stopPointRef); call.setStopPointRef(ref); calls.add(call); diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/application/src/test/java/org/opentripplanner/updater/siri/SiriTimetableSnapshotSourceTest.java similarity index 68% rename from src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java rename to application/src/test/java/org/opentripplanner/updater/siri/SiriTimetableSnapshotSourceTest.java index cf29eec8f49..fea39f912db 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/application/src/test/java/org/opentripplanner/updater/siri/SiriTimetableSnapshotSourceTest.java @@ -1,13 +1,12 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertFailure; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.SERVICE_DATE; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.timetable.RealTimeState; @@ -15,34 +14,49 @@ import org.opentripplanner.transit.model.timetable.TripIdAndServiceDate; import org.opentripplanner.transit.service.TransitService; import org.opentripplanner.updater.spi.UpdateError; +import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; -import uk.org.siri.siri20.EstimatedTimetableDeliveryStructure; +import org.opentripplanner.updater.trip.TripInput; -class SiriTimetableSnapshotSourceTest { +class SiriTimetableSnapshotSourceTest implements RealtimeTestConstants { + + private static final TripInput TRIP_1_INPUT = TripInput + .of(TRIP_1_ID) + .withRoute(ROUTE_1.copy().withOperator(OPERATOR1).build()) + .addStop(STOP_A1, "0:00:10", "0:00:11") + .addStop(STOP_B1, "0:00:20", "0:00:21") + .build(); + + private static final TripInput TRIP_2_INPUT = TripInput + .of(TRIP_2_ID) + .addStop(STOP_A1, "0:01:00", "0:01:01") + .addStop(STOP_B1, "0:01:10", "0:01:11") + .addStop(STOP_C1, "0:01:20", "0:01:21") + .build(); @Test void testCancelTrip() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); - assertEquals(RealTimeState.SCHEDULED, env.getTripTimesForTrip(env.trip1).getRealTimeState()); + assertEquals(RealTimeState.SCHEDULED, env.getTripTimesForTrip(TRIP_1_ID).getRealTimeState()); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip1.getId().getId()) + .withDatedVehicleJourneyRef(TRIP_1_ID) .withCancellation(true) .buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); assertEquals(1, result.successful()); - assertEquals(RealTimeState.CANCELED, env.getTripTimesForTrip(env.trip1).getRealTimeState()); + assertEquals(RealTimeState.CANCELED, env.getTripTimesForTrip(TRIP_1_ID).getRealTimeState()); } @Test void testAddJourneyWithExistingRoute() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); - Route route = env.getTransitService().getRouteForId(env.route1Id); - int numPatternForRoute = env.getTransitService().getPatternsForRoute(route).size(); + Route route = ROUTE_1; + int numPatternForRoute = env.getTransitService().findPatterns(route).size(); String newJourneyId = "newJourney"; var updates = createValidAddedJourney(env).buildEstimatedTimetableDeliveries(); @@ -55,34 +69,33 @@ void testAddJourneyWithExistingRoute() { "SCHEDULED | C1 0:01 0:01 | D1 0:03 0:03", env.getScheduledTimetable(newJourneyId) ); - FeedScopedId tripId = TransitModelForTest.id(newJourneyId); + FeedScopedId tripId = id(newJourneyId); TransitService transitService = env.getTransitService(); - Trip trip = transitService.getTripForId(tripId); + Trip trip = transitService.getTrip(tripId); assertNotNull(trip); - assertNotNull(transitService.getPatternForTrip(trip)); - assertNotNull(transitService.getTripOnServiceDateById(tripId)); + assertNotNull(transitService.findPattern(trip)); + assertNotNull(transitService.getTripOnServiceDate(tripId)); assertNotNull( - transitService.getTripOnServiceDateForTripAndDay( - new TripIdAndServiceDate(tripId, SERVICE_DATE) - ) + transitService.getTripOnServiceDate(new TripIdAndServiceDate(tripId, SERVICE_DATE)) ); assertEquals( numPatternForRoute + 1, - transitService.getPatternsForRoute(route).size(), + transitService.findPatterns(route).size(), "The added trip should use a new pattern for this route" ); } @Test void testAddJourneyWithNewRoute() { - var env = RealtimeTestEnvironment.siri(); + // we actually don't need the trip, but it's the only way to add a route to the index + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); String newRouteRef = "new route ref"; var updates = createValidAddedJourney(env) .withLineRef(newRouteRef) .buildEstimatedTimetableDeliveries(); - int numRoutes = env.getTransitService().getAllRoutes().size(); + int numRoutes = env.getTransitService().listRoutes().size(); var result = env.applyEstimatedTimetable(updates); assertEquals(1, result.successful()); @@ -92,43 +105,45 @@ void testAddJourneyWithNewRoute() { env.getScheduledTimetable("newJourney") ); TransitService transitService = env.getTransitService(); - assertEquals(numRoutes + 1, transitService.getAllRoutes().size()); - FeedScopedId newRouteId = TransitModelForTest.id(newRouteRef); - Route newRoute = transitService.getRouteForId(newRouteId); + assertEquals(numRoutes + 1, transitService.listRoutes().size()); + FeedScopedId newRouteId = id(newRouteRef); + Route newRoute = transitService.getRoute(newRouteId); assertNotNull(newRoute); - assertEquals(1, transitService.getPatternsForRoute(newRoute).size()); + assertEquals(1, transitService.findPatterns(newRoute).size()); } @Test void testAddJourneyMultipleTimes() { - var env = RealtimeTestEnvironment.siri(); + // we actually don't need the trip, but it's the only way to add a route to the index + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = createValidAddedJourney(env).buildEstimatedTimetableDeliveries(); - int numTrips = env.getTransitService().getAllTrips().size(); + int numTrips = env.getTransitService().listTrips().size(); var result1 = env.applyEstimatedTimetable(updates); assertEquals(1, result1.successful()); - assertEquals(numTrips + 1, env.getTransitService().getAllTrips().size()); + assertEquals(numTrips + 1, env.getTransitService().listTrips().size()); var result2 = env.applyEstimatedTimetable(updates); assertEquals(1, result2.successful()); - assertEquals(numTrips + 1, env.getTransitService().getAllTrips().size()); + assertEquals(numTrips + 1, env.getTransitService().listTrips().size()); } @Test void testAddedJourneyWithInvalidScheduledData() { - var env = RealtimeTestEnvironment.siri(); + // we actually don't need the trip, but it's the only way to add a route to the index + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); // Create an extra journey with invalid planned data (travel back in time) // and valid real time data var createExtraJourney = new SiriEtBuilder(env.getDateTimeHelper()) .withEstimatedVehicleJourneyCode("newJourney") .withIsExtraJourney(true) - .withOperatorRef(env.operator1Id.getId()) - .withLineRef(env.route1Id.getId()) + .withOperatorRef(OPERATOR_1_ID) + .withLineRef(ROUTE_1_ID) .withEstimatedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedExpected("10:58", "10:48") - .call(env.stopB1) + .call(STOP_B1) .arriveAimedExpected("10:08", "10:58") ) .buildEstimatedTimetableDeliveries(); @@ -140,7 +155,7 @@ void testAddedJourneyWithInvalidScheduledData() { @Test void testAddedJourneyWithUnresolvableAgency() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().build(); // Create an extra journey with unknown line and operator var createExtraJourney = new SiriEtBuilder(env.getDateTimeHelper()) @@ -150,9 +165,9 @@ void testAddedJourneyWithUnresolvableAgency() { .withLineRef("unknown line") .withEstimatedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedExpected("10:58", "10:48") - .call(env.stopB1) + .call(STOP_B1) .arriveAimedExpected("10:08", "10:58") ) .buildEstimatedTimetableDeliveries(); @@ -164,17 +179,17 @@ void testAddedJourneyWithUnresolvableAgency() { @Test void testReplaceJourney() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withEstimatedVehicleJourneyCode("newJourney") .withIsExtraJourney(true) // replace trip1 - .withVehicleJourneyRef(env.trip1.getId().getId()) - .withOperatorRef(env.operator1Id.getId()) - .withLineRef(env.route1Id.getId()) - .withRecordedCalls(builder -> builder.call(env.stopA1).departAimedActual("00:01", "00:02")) - .withEstimatedCalls(builder -> builder.call(env.stopC1).arriveAimedExpected("00:03", "00:04")) + .withVehicleJourneyRef(TRIP_1_ID) + .withOperatorRef(OPERATOR_1_ID) + .withLineRef(ROUTE_1_ID) + .withRecordedCalls(builder -> builder.call(STOP_A1).departAimedActual("00:01", "00:02")) + .withEstimatedCalls(builder -> builder.call(STOP_C1).arriveAimedExpected("00:03", "00:04")) .buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); @@ -188,7 +203,7 @@ void testReplaceJourney() { ); // Original trip should not get canceled - var originalTripTimes = env.getTripTimesForTrip(env.trip1); + var originalTripTimes = env.getTripTimesForTrip(TRIP_1_ID); assertEquals(RealTimeState.SCHEDULED, originalTripTimes.getRealTimeState()); } @@ -197,17 +212,17 @@ void testReplaceJourney() { */ @Test void testUpdateJourneyWithDatedVehicleJourneyRef() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = updatedJourneyBuilder(env) - .withDatedVehicleJourneyRef(env.trip1.getId().getId()) + .withDatedVehicleJourneyRef(TRIP_1_ID) .buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); assertEquals(1, result.successful()); assertTripUpdated(env); assertEquals( "UPDATED | A1 0:00:15 0:00:15 | B1 0:00:25 0:00:25", - env.getRealtimeTimetable(env.trip1) + env.getRealtimeTimetable(TRIP_1_ID) ); } @@ -216,11 +231,11 @@ void testUpdateJourneyWithDatedVehicleJourneyRef() { */ @Test void testUpdateJourneyWithFramedVehicleJourneyRef() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = updatedJourneyBuilder(env) .withFramedVehicleJourneyRef(builder -> - builder.withServiceDate(SERVICE_DATE).withVehicleJourneyRef(env.trip1.getId().getId()) + builder.withServiceDate(SERVICE_DATE).withVehicleJourneyRef(TRIP_1_ID) ) .buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); @@ -233,7 +248,7 @@ void testUpdateJourneyWithFramedVehicleJourneyRef() { */ @Test void testUpdateJourneyWithoutJourneyRef() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = updatedJourneyBuilder(env).buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); @@ -246,7 +261,7 @@ void testUpdateJourneyWithoutJourneyRef() { */ @Test void testUpdateJourneyWithFuzzyMatching() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = updatedJourneyBuilder(env).buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetableWithFuzzyMatcher(updates); @@ -260,17 +275,17 @@ void testUpdateJourneyWithFuzzyMatching() { */ @Test void testUpdateJourneyWithFuzzyMatchingAndMissingAimedDepartureTime() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withFramedVehicleJourneyRef(builder -> - builder.withServiceDate(RealtimeTestEnvironment.SERVICE_DATE).withVehicleJourneyRef("XXX") + builder.withServiceDate(SERVICE_DATE).withVehicleJourneyRef("XXX") ) .withEstimatedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedExpected(null, "00:00:12") - .call(env.stopB1) + .call(STOP_B1) .arriveAimedExpected("00:00:20", "00:00:22") ) .buildEstimatedTimetableDeliveries(); @@ -285,15 +300,13 @@ void testUpdateJourneyWithFuzzyMatchingAndMissingAimedDepartureTime() { */ @Test void testChangeQuay() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip1.getId().getId()) - .withRecordedCalls(builder -> - builder.call(env.stopA1).departAimedActual("00:00:11", "00:00:15") - ) + .withDatedVehicleJourneyRef(TRIP_1_ID) + .withRecordedCalls(builder -> builder.call(STOP_A1).departAimedActual("00:00:11", "00:00:15")) .withEstimatedCalls(builder -> - builder.call(env.stopB2).arriveAimedExpected("00:00:20", "00:00:33") + builder.call(STOP_B2).arriveAimedExpected("00:00:20", "00:00:33") ) .buildEstimatedTimetableDeliveries(); @@ -302,23 +315,23 @@ void testChangeQuay() { assertEquals(1, result.successful()); assertEquals( "MODIFIED | A1 [R] 0:00:15 0:00:15 | B2 0:00:33 0:00:33", - env.getRealtimeTimetable(env.trip1) + env.getRealtimeTimetable(TRIP_1_ID) ); } @Test void testCancelStop() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_2_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip2.getId().getId()) + .withDatedVehicleJourneyRef(TRIP_2_ID) .withEstimatedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedExpected("00:01:01", "00:01:01") - .call(env.stopB1) + .call(STOP_B1) .withIsCancellation(true) - .call(env.stopC1) + .call(STOP_C1) .arriveAimedExpected("00:01:30", "00:01:30") ) .buildEstimatedTimetableDeliveries(); @@ -328,7 +341,7 @@ void testCancelStop() { assertEquals(1, result.successful()); assertEquals( "MODIFIED | A1 0:01:01 0:01:01 | B1 [C] 0:01:10 0:01:11 | C1 0:01:30 0:01:30", - env.getRealtimeTimetable(env.trip2) + env.getRealtimeTimetable(TRIP_2_ID) ); } @@ -336,20 +349,18 @@ void testCancelStop() { @Test @Disabled("Not supported yet") void testAddStop() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip1.getId().getId()) - .withRecordedCalls(builder -> - builder.call(env.stopA1).departAimedActual("00:00:11", "00:00:15") - ) + .withDatedVehicleJourneyRef(TRIP_1_ID) + .withRecordedCalls(builder -> builder.call(STOP_A1).departAimedActual("00:00:11", "00:00:15")) .withEstimatedCalls(builder -> builder - .call(env.stopD1) + .call(STOP_D1) .withIsExtraCall(true) .arriveAimedExpected("00:00:19", "00:00:20") .departAimedExpected("00:00:24", "00:00:25") - .call(env.stopB1) + .call(STOP_B1) .arriveAimedExpected("00:00:20", "00:00:33") ) .buildEstimatedTimetableDeliveries(); @@ -359,7 +370,7 @@ void testAddStop() { assertEquals(1, result.successful()); assertEquals( "MODIFIED | A1 0:00:15 0:00:15 | D1 [C] 0:00:20 0:00:25 | B1 0:00:33 0:00:33", - env.getRealtimeTimetable(env.trip1) + env.getRealtimeTimetable(TRIP_1_ID) ); } @@ -369,7 +380,7 @@ void testAddStop() { @Test void testNotMonitored() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withMonitored(false) @@ -382,19 +393,19 @@ void testNotMonitored() { @Test void testReplaceJourneyWithoutEstimatedVehicleJourneyCode() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withDatedVehicleJourneyRef("newJourney") .withIsExtraJourney(true) - .withVehicleJourneyRef(env.trip1.getId().getId()) - .withOperatorRef(env.operator1Id.getId()) - .withLineRef(env.route1Id.getId()) + .withVehicleJourneyRef(TRIP_1_ID) + .withOperatorRef(OPERATOR_1_ID) + .withLineRef(ROUTE_1_ID) .withEstimatedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedExpected("00:01", "00:02") - .call(env.stopC1) + .call(STOP_C1) .arriveAimedExpected("00:03", "00:04") ) .buildEstimatedTimetableDeliveries(); @@ -407,15 +418,15 @@ void testReplaceJourneyWithoutEstimatedVehicleJourneyCode() { @Test void testNegativeHopTime() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip1.getId().getId()) + .withDatedVehicleJourneyRef(TRIP_1_ID) .withRecordedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedActual("00:00:11", "00:00:15") - .call(env.stopB1) + .call(STOP_B1) .arriveAimedActual("00:00:20", "00:00:14") ) .buildEstimatedTimetableDeliveries(); @@ -427,18 +438,18 @@ void testNegativeHopTime() { @Test void testNegativeDwellTime() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_2_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip2.getId().getId()) + .withDatedVehicleJourneyRef(TRIP_2_ID) .withRecordedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedActual("00:01:01", "00:01:01") - .call(env.stopB1) + .call(STOP_B1) .arriveAimedActual("00:01:10", "00:01:13") .departAimedActual("00:01:11", "00:01:12") - .call(env.stopB1) + .call(STOP_B1) .arriveAimedActual("00:01:20", "00:01:20") ) .buildEstimatedTimetableDeliveries(); @@ -452,19 +463,19 @@ void testNegativeDwellTime() { @Test @Disabled("Not supported yet") void testExtraUnknownStop() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip1.getId().getId()) + .withDatedVehicleJourneyRef(TRIP_1_ID) .withEstimatedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedExpected("00:00:11", "00:00:15") // Unexpected extra stop without isExtraCall flag - .call(env.stopD1) + .call(STOP_D1) .arriveAimedExpected("00:00:19", "00:00:20") .departAimedExpected("00:00:24", "00:00:25") - .call(env.stopB1) + .call(STOP_B1) .arriveAimedExpected("00:00:20", "00:00:33") ) .buildEstimatedTimetableDeliveries(); @@ -478,20 +489,19 @@ private static SiriEtBuilder createValidAddedJourney(RealtimeTestEnvironment env return new SiriEtBuilder(env.getDateTimeHelper()) .withEstimatedVehicleJourneyCode("newJourney") .withIsExtraJourney(true) - .withOperatorRef(env.operator1Id.getId()) - .withLineRef(env.route1Id.getId()) - .withRecordedCalls(builder -> builder.call(env.stopC1).departAimedActual("00:01", "00:02")) - .withEstimatedCalls(builder -> builder.call(env.stopD1).arriveAimedExpected("00:03", "00:04") - ); + .withOperatorRef(OPERATOR_1_ID) + .withLineRef(ROUTE_1_ID) + .withRecordedCalls(builder -> builder.call(STOP_C1).departAimedActual("00:01", "00:02")) + .withEstimatedCalls(builder -> builder.call(STOP_D1).arriveAimedExpected("00:03", "00:04")); } private static SiriEtBuilder updatedJourneyBuilder(RealtimeTestEnvironment env) { return new SiriEtBuilder(env.getDateTimeHelper()) .withEstimatedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedExpected("00:00:11", "00:00:15") - .call(env.stopB1) + .call(STOP_B1) .arriveAimedExpected("00:00:20", "00:00:25") ); } @@ -499,7 +509,7 @@ private static SiriEtBuilder updatedJourneyBuilder(RealtimeTestEnvironment env) private static void assertTripUpdated(RealtimeTestEnvironment env) { assertEquals( "UPDATED | A1 0:00:15 0:00:15 | B1 0:00:25 0:00:25", - env.getRealtimeTimetable(env.trip1) + env.getRealtimeTimetable(TRIP_1_ID) ); } } diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/TestCall.java b/application/src/test/java/org/opentripplanner/updater/siri/TestCall.java similarity index 99% rename from src/ext-test/java/org/opentripplanner/ext/siri/TestCall.java rename to application/src/test/java/org/opentripplanner/updater/siri/TestCall.java index 55d1fa4591f..62e0f64d30f 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/TestCall.java +++ b/application/src/test/java/org/opentripplanner/updater/siri/TestCall.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import java.time.ZonedDateTime; import java.util.List; diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/TimetableHelperTest.java b/application/src/test/java/org/opentripplanner/updater/siri/TimetableHelperTest.java similarity index 98% rename from src/ext-test/java/org/opentripplanner/ext/siri/TimetableHelperTest.java rename to application/src/test/java/org/opentripplanner/updater/siri/TimetableHelperTest.java index dde2677a952..daa8b2382bb 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/TimetableHelperTest.java +++ b/application/src/test/java/org/opentripplanner/updater/siri/TimetableHelperTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri; +package org.opentripplanner.updater.siri; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -22,7 +22,7 @@ import org.opentripplanner.transit.model.timetable.RealTimeTripTimes; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimesFactory; -import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.SiteRepository; import uk.org.siri.siri20.OccupancyEnumeration; public class TimetableHelperTest { @@ -57,7 +57,7 @@ public void setUp() { .build(); var stopTime = new StopTime(); - RegularStop stop = StopModel + RegularStop stop = SiteRepository .of() .regularStop(SCOPED_STOP_ID) .withCoordinate(0.0, 0.0) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/mapper/PickDropMapperTest.java b/application/src/test/java/org/opentripplanner/updater/siri/mapper/PickDropMapperTest.java similarity index 98% rename from src/ext-test/java/org/opentripplanner/ext/siri/mapper/PickDropMapperTest.java rename to application/src/test/java/org/opentripplanner/updater/siri/mapper/PickDropMapperTest.java index c45ef87efea..9508709c36d 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/mapper/PickDropMapperTest.java +++ b/application/src/test/java/org/opentripplanner/updater/siri/mapper/PickDropMapperTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.siri.mapper; +package org.opentripplanner.updater.siri.mapper; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -9,8 +9,8 @@ import static uk.org.siri.siri20.DepartureBoardingActivityEnumeration.NO_BOARDING; import org.junit.jupiter.api.Test; -import org.opentripplanner.ext.siri.TestCall; import org.opentripplanner.model.PickDrop; +import org.opentripplanner.updater.siri.TestCall; import uk.org.siri.siri20.CallStatusEnumeration; class PickDropMapperTest { diff --git a/application/src/test/java/org/opentripplanner/updater/siri/moduletests/rejection/InvalidStopPointRefTest.java b/application/src/test/java/org/opentripplanner/updater/siri/moduletests/rejection/InvalidStopPointRefTest.java new file mode 100644 index 00000000000..820f44e3a86 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/updater/siri/moduletests/rejection/InvalidStopPointRefTest.java @@ -0,0 +1,48 @@ +package org.opentripplanner.updater.siri.moduletests.rejection; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertFailure; + +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.opentripplanner.updater.siri.SiriEtBuilder; +import org.opentripplanner.updater.spi.UpdateError; +import org.opentripplanner.updater.trip.RealtimeTestConstants; +import org.opentripplanner.updater.trip.RealtimeTestEnvironment; + +public class InvalidStopPointRefTest implements RealtimeTestConstants { + + private static Stream cases() { + return Stream + .of("", " ", " ", "\n", "null", "\t", null) + .flatMap(id -> Stream.of(Arguments.of(id, true), Arguments.of(id, false))); + } + + @ParameterizedTest(name = "invalid id of ''{0}'', extraJourney={1}") + @MethodSource("cases") + void rejectEmptyStopPointRef(String invalidRef, boolean extraJourney) { + var env = RealtimeTestEnvironment.siri().build(); + + // journey contains empty stop point ref elements + // happens in the South Tyrolian feed: https://github.com/noi-techpark/odh-mentor-otp/issues/213 + var invalidJourney = new SiriEtBuilder(env.getDateTimeHelper()) + .withEstimatedVehicleJourneyCode("invalid-journey") + .withOperatorRef("unknown-operator") + .withLineRef("unknown-line") + .withIsExtraJourney(extraJourney) + .withEstimatedCalls(builder -> + builder + .call(invalidRef) + .departAimedExpected("10:58", "10:48") + .call(invalidRef) + .arriveAimedExpected("10:08", "10:58") + ) + .buildEstimatedTimetableDeliveries(); + + var result = env.applyEstimatedTimetable(invalidJourney); + assertEquals(0, result.successful()); + assertFailure(UpdateError.UpdateErrorType.EMPTY_STOP_POINT_REF, result); + } +} diff --git a/src/test/java/org/opentripplanner/updater/spi/HttpHeadersTest.java b/application/src/test/java/org/opentripplanner/updater/spi/HttpHeadersTest.java similarity index 100% rename from src/test/java/org/opentripplanner/updater/spi/HttpHeadersTest.java rename to application/src/test/java/org/opentripplanner/updater/spi/HttpHeadersTest.java diff --git a/src/test/java/org/opentripplanner/updater/spi/UpdateResultAssertions.java b/application/src/test/java/org/opentripplanner/updater/spi/UpdateResultAssertions.java similarity index 100% rename from src/test/java/org/opentripplanner/updater/spi/UpdateResultAssertions.java rename to application/src/test/java/org/opentripplanner/updater/spi/UpdateResultAssertions.java diff --git a/src/test/java/org/opentripplanner/updater/trip/GtfsRealtimeTripUpdateSourceTest.java b/application/src/test/java/org/opentripplanner/updater/trip/GtfsRealtimeTripUpdateSourceTest.java similarity index 100% rename from src/test/java/org/opentripplanner/updater/trip/GtfsRealtimeTripUpdateSourceTest.java rename to application/src/test/java/org/opentripplanner/updater/trip/GtfsRealtimeTripUpdateSourceTest.java diff --git a/application/src/test/java/org/opentripplanner/updater/trip/RealtimeTestConstants.java b/application/src/test/java/org/opentripplanner/updater/trip/RealtimeTestConstants.java new file mode 100644 index 00000000000..87a9da83911 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/updater/trip/RealtimeTestConstants.java @@ -0,0 +1,48 @@ +package org.opentripplanner.updater.trip; + +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; + +import java.time.LocalDate; +import java.time.ZoneId; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.transit.model.organization.Operator; +import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.transit.model.site.Station; +import org.opentripplanner.transit.service.SiteRepository; + +public interface RealtimeTestConstants { + LocalDate SERVICE_DATE = LocalDate.of(2024, 5, 8); + FeedScopedId SERVICE_ID = TimetableRepositoryForTest.id("CAL_1"); + String STOP_A1_ID = "A1"; + String STOP_B1_ID = "B1"; + String STOP_C1_ID = "C1"; + String TRIP_1_ID = "TestTrip1"; + String TRIP_2_ID = "TestTrip2"; + String OPERATOR_1_ID = "TestOperator1"; + Operator OPERATOR1 = Operator.of(id(OPERATOR_1_ID)).withName(OPERATOR_1_ID).build(); + String ROUTE_1_ID = "TestRoute1"; + + TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); + ZoneId TIME_ZONE = ZoneId.of(TimetableRepositoryForTest.TIME_ZONE_ID); + Station STATION_A = TEST_MODEL.station("A").build(); + Station STATION_B = TEST_MODEL.station("B").build(); + Station STATION_C = TEST_MODEL.station("C").build(); + Station STATION_D = TEST_MODEL.station("D").build(); + RegularStop STOP_A1 = TEST_MODEL.stop(STOP_A1_ID).withParentStation(STATION_A).build(); + RegularStop STOP_B1 = TEST_MODEL.stop(STOP_B1_ID).withParentStation(STATION_B).build(); + RegularStop STOP_B2 = TEST_MODEL.stop("B2").withParentStation(STATION_B).build(); + RegularStop STOP_C1 = TEST_MODEL.stop(STOP_C1_ID).withParentStation(STATION_C).build(); + RegularStop STOP_D1 = TEST_MODEL.stop("D1").withParentStation(STATION_D).build(); + SiteRepository SITE_REPOSITORY = TEST_MODEL + .siteRepositoryBuilder() + .withRegularStop(STOP_A1) + .withRegularStop(STOP_B1) + .withRegularStop(STOP_B2) + .withRegularStop(STOP_C1) + .withRegularStop(STOP_D1) + .build(); + + Route ROUTE_1 = TimetableRepositoryForTest.route(ROUTE_1_ID).build(); +} diff --git a/application/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java b/application/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java new file mode 100644 index 00000000000..f20e58a7b62 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java @@ -0,0 +1,238 @@ +package org.opentripplanner.updater.trip; + +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; +import static org.opentripplanner.updater.trip.UpdateIncrementality.DIFFERENTIAL; +import static org.opentripplanner.updater.trip.UpdateIncrementality.FULL_DATASET; + +import com.google.transit.realtime.GtfsRealtime; +import java.time.Duration; +import java.time.LocalDate; +import java.util.List; +import java.util.Objects; +import org.opentripplanner.DateTimeHelper; +import org.opentripplanner.model.TimetableSnapshot; +import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.transit.model.timetable.TripTimesStringBuilder; +import org.opentripplanner.transit.service.DefaultTransitService; +import org.opentripplanner.transit.service.TimetableRepository; +import org.opentripplanner.transit.service.TransitService; +import org.opentripplanner.updater.DefaultRealTimeUpdateContext; +import org.opentripplanner.updater.TimetableSnapshotSourceParameters; +import org.opentripplanner.updater.siri.SiriTimetableSnapshotSource; +import org.opentripplanner.updater.siri.updater.EstimatedTimetableHandler; +import org.opentripplanner.updater.spi.UpdateResult; +import uk.org.siri.siri20.EstimatedTimetableDeliveryStructure; + +/** + * This class exists so that you can share the data building logic for GTFS and Siri tests. + * Since it's not possible to add a Siri and GTFS updater to the transit model at the same time, + * they each have their own test environment. + *

    + * It is however a goal to change that and then these two can be combined. + */ +public final class RealtimeTestEnvironment implements RealtimeTestConstants { + + // static constants + private static final TimetableSnapshotSourceParameters PARAMETERS = new TimetableSnapshotSourceParameters( + Duration.ZERO, + false + ); + + public final TimetableRepository timetableRepository; + private final SiriTimetableSnapshotSource siriSource; + private final TimetableSnapshotSource gtfsSource; + private final DateTimeHelper dateTimeHelper; + + enum SourceType { + GTFS_RT, + SIRI, + } + + /** + * Siri and GTFS-RT cannot be run at the same time, so you need to decide. + */ + public static RealtimeTestEnvironmentBuilder siri() { + return new RealtimeTestEnvironmentBuilder().withSourceType(SourceType.SIRI); + } + + /** + * Siri and GTFS-RT cannot be run at the same time, so you need to decide. + */ + public static RealtimeTestEnvironmentBuilder gtfs() { + return new RealtimeTestEnvironmentBuilder().withSourceType(SourceType.GTFS_RT); + } + + RealtimeTestEnvironment(SourceType sourceType, TimetableRepository timetableRepository) { + Objects.requireNonNull(sourceType); + this.timetableRepository = timetableRepository; + + this.timetableRepository.index(); + // SIRI and GTFS-RT cannot be registered with the transit model at the same time + // we are actively refactoring to remove this restriction + // for the time being you cannot run a SIRI and GTFS-RT test at the same time + if (sourceType == SourceType.SIRI) { + siriSource = new SiriTimetableSnapshotSource(PARAMETERS, timetableRepository); + gtfsSource = null; + } else { + gtfsSource = new TimetableSnapshotSource(PARAMETERS, timetableRepository); + siriSource = null; + } + dateTimeHelper = new DateTimeHelper(TIME_ZONE, SERVICE_DATE); + } + + /** + * Returns a new fresh TransitService + */ + public TransitService getTransitService() { + return new DefaultTransitService(timetableRepository); + } + + /** + * Find the current TripTimes for a trip id on a serviceDate + */ + public TripTimes getTripTimesForTrip(FeedScopedId tripId, LocalDate serviceDate) { + var transitService = getTransitService(); + var trip = transitService.getTripOnServiceDate(tripId).getTrip(); + var pattern = transitService.findPattern(trip, serviceDate); + var timetable = transitService.findTimetable(pattern, serviceDate); + return timetable.getTripTimes(trip); + } + + public String getFeedId() { + return TimetableRepositoryForTest.FEED_ID; + } + + private EstimatedTimetableHandler getEstimatedTimetableHandler(boolean fuzzyMatching) { + return new EstimatedTimetableHandler(siriSource, fuzzyMatching, getFeedId()); + } + + public TripPattern getPatternForTrip(FeedScopedId tripId) { + return getPatternForTrip(tripId, SERVICE_DATE); + } + + public TripPattern getPatternForTrip(String id) { + return getPatternForTrip(id(id)); + } + + public TripPattern getPatternForTrip(FeedScopedId tripId, LocalDate serviceDate) { + var transitService = getTransitService(); + var trip = transitService.getTripOnServiceDate(tripId); + return transitService.findPattern(trip.getTrip(), serviceDate); + } + + /** + * Find the current TripTimes for a trip id on the default serviceDate + */ + public TripTimes getTripTimesForTrip(String id) { + return getTripTimesForTrip(id(id), SERVICE_DATE); + } + + public DateTimeHelper getDateTimeHelper() { + return dateTimeHelper; + } + + public TimetableSnapshot getTimetableSnapshot() { + if (siriSource != null) { + return siriSource.getTimetableSnapshot(); + } else { + return gtfsSource.getTimetableSnapshot(); + } + } + + public String getRealtimeTimetable(String tripId) { + return getRealtimeTimetable(id(tripId), SERVICE_DATE); + } + + public String getRealtimeTimetable(FeedScopedId tripId, LocalDate serviceDate) { + var tt = getTripTimesForTrip(tripId, serviceDate); + var pattern = getPatternForTrip(tripId); + + return TripTimesStringBuilder.encodeTripTimes(tt, pattern); + } + + public String getScheduledTimetable(String tripId) { + return getScheduledTimetable(id(tripId)); + } + + public String getScheduledTimetable(FeedScopedId tripId) { + var pattern = getPatternForTrip(tripId); + var tt = pattern.getScheduledTimetable().getTripTimes(tripId); + + return TripTimesStringBuilder.encodeTripTimes(tt, pattern); + } + + // SIRI updates + + public UpdateResult applyEstimatedTimetableWithFuzzyMatcher( + List updates + ) { + return applyEstimatedTimetable(updates, true); + } + + public UpdateResult applyEstimatedTimetable(List updates) { + return applyEstimatedTimetable(updates, false); + } + + // GTFS-RT updates + + public UpdateResult applyTripUpdate(GtfsRealtime.TripUpdate update) { + return applyTripUpdates(List.of(update), FULL_DATASET); + } + + public UpdateResult applyTripUpdate( + GtfsRealtime.TripUpdate update, + UpdateIncrementality incrementality + ) { + return applyTripUpdates(List.of(update), incrementality); + } + + public UpdateResult applyTripUpdates( + List updates, + UpdateIncrementality incrementality + ) { + Objects.requireNonNull(gtfsSource, "Test environment is configured for SIRI only"); + UpdateResult updateResult = gtfsSource.applyTripUpdates( + null, + BackwardsDelayPropagationType.REQUIRED_NO_DATA, + incrementality, + updates, + getFeedId() + ); + commitTimetableSnapshot(); + return updateResult; + } + + // private methods + + private UpdateResult applyEstimatedTimetable( + List updates, + boolean fuzzyMatching + ) { + Objects.requireNonNull(siriSource, "Test environment is configured for GTFS-RT only"); + UpdateResult updateResult = getEstimatedTimetableHandler(fuzzyMatching) + .applyUpdate( + updates, + DIFFERENTIAL, + new DefaultRealTimeUpdateContext( + new Graph(), + timetableRepository, + siriSource.getTimetableSnapshotBuffer() + ) + ); + commitTimetableSnapshot(); + return updateResult; + } + + private void commitTimetableSnapshot() { + if (siriSource != null) { + siriSource.flushBuffer(); + } + if (gtfsSource != null) { + gtfsSource.flushBuffer(); + } + } +} diff --git a/application/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java b/application/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java new file mode 100644 index 00000000000..eb31a555e1d --- /dev/null +++ b/application/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java @@ -0,0 +1,121 @@ +package org.opentripplanner.updater.trip; + +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; + +import java.util.List; +import java.util.Objects; +import java.util.stream.IntStream; +import org.opentripplanner.framework.i18n.I18NString; +import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; +import org.opentripplanner.model.StopTime; +import org.opentripplanner.model.calendar.CalendarServiceData; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.transit.model.framework.Deduplicator; +import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.transit.model.timetable.TripOnServiceDate; +import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.transit.model.timetable.TripTimesFactory; +import org.opentripplanner.transit.service.TimetableRepository; + +public class RealtimeTestEnvironmentBuilder implements RealtimeTestConstants { + + private RealtimeTestEnvironment.SourceType sourceType; + private final TimetableRepository timetableRepository = new TimetableRepository( + SITE_REPOSITORY, + new Deduplicator() + ); + + RealtimeTestEnvironmentBuilder withSourceType(RealtimeTestEnvironment.SourceType sourceType) { + this.sourceType = sourceType; + return this; + } + + public RealtimeTestEnvironmentBuilder addTrip(TripInput trip) { + createTrip(trip); + timetableRepository.index(); + return this; + } + + public RealtimeTestEnvironment build() { + Objects.requireNonNull(sourceType, "sourceType cannot be null"); + timetableRepository.initTimeZone(TIME_ZONE); + timetableRepository.addAgency(TimetableRepositoryForTest.AGENCY); + + CalendarServiceData calendarServiceData = new CalendarServiceData(); + calendarServiceData.putServiceDatesForServiceId( + SERVICE_ID, + List.of(SERVICE_DATE.minusDays(1), SERVICE_DATE, SERVICE_DATE.plusDays(1)) + ); + timetableRepository.getServiceCodes().put(SERVICE_ID, 0); + timetableRepository.updateCalendarServiceData( + true, + calendarServiceData, + DataImportIssueStore.NOOP + ); + + return new RealtimeTestEnvironment(sourceType, timetableRepository); + } + + private Trip createTrip(TripInput tripInput) { + var trip = Trip + .of(id(tripInput.id())) + .withRoute(tripInput.route()) + .withHeadsign(I18NString.of("Headsign of %s".formatted(tripInput.id()))) + .withServiceId(SERVICE_ID) + .build(); + + var tripOnServiceDate = TripOnServiceDate + .of(trip.getId()) + .withTrip(trip) + .withServiceDate(SERVICE_DATE) + .build(); + + timetableRepository.addTripOnServiceDate(tripOnServiceDate); + + if (tripInput.route().getOperator() != null) { + timetableRepository.addOperators(List.of(tripInput.route().getOperator())); + } + + var stopTimes = IntStream + .range(0, tripInput.stops().size()) + .mapToObj(i -> { + var stop = tripInput.stops().get(i); + return createStopTime(trip, i, stop.stop(), stop.arrivalTime(), stop.departureTime()); + }) + .toList(); + + TripTimes tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, null); + + final TripPattern pattern = TimetableRepositoryForTest + .tripPattern(tripInput.id() + "Pattern", tripInput.route()) + .withStopPattern( + TimetableRepositoryForTest.stopPattern( + tripInput.stops().stream().map(TripInput.StopCall::stop).toList() + ) + ) + .withScheduledTimeTableBuilder(builder -> builder.addTripTimes(tripTimes)) + .build(); + + timetableRepository.addTripPattern(pattern.getId(), pattern); + + return trip; + } + + private static StopTime createStopTime( + Trip trip, + int stopSequence, + StopLocation stop, + int arrivalTime, + int departureTime + ) { + var st = new StopTime(); + st.setTrip(trip); + st.setStopSequence(stopSequence); + st.setStop(stop); + st.setArrivalTime(arrivalTime); + st.setDepartureTime(departureTime); + return st; + } +} diff --git a/src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotManagerTest.java b/application/src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotManagerTest.java similarity index 88% rename from src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotManagerTest.java rename to application/src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotManagerTest.java index 1f3f71a2588..93c5ddbdc55 100644 --- a/src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotManagerTest.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotManagerTest.java @@ -15,7 +15,7 @@ import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.model.RealTimeTripUpdate; import org.opentripplanner.model.TimetableSnapshot; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.RealTimeTripTimes; import org.opentripplanner.transit.model.timetable.ScheduledTripTimes; @@ -27,18 +27,21 @@ class TimetableSnapshotManagerTest { private static final LocalDate TOMORROW = TODAY.plusDays(1); private static final LocalDate YESTERDAY = TODAY.minusDays(1); - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); - private static final TripPattern PATTERN = TransitModelForTest - .tripPattern("pattern", TransitModelForTest.route("r1").build()) + private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of(); + private static final TripPattern PATTERN = TimetableRepositoryForTest + .tripPattern("pattern", TimetableRepositoryForTest.route("r1").build()) .withStopPattern( - TransitModelForTest.stopPattern(TEST_MODEL.stop("1").build(), TEST_MODEL.stop("2").build()) + TimetableRepositoryForTest.stopPattern( + TEST_MODEL.stop("1").build(), + TEST_MODEL.stop("2").build() + ) ) .build(); private static final RealTimeTripTimes TRIP_TIMES = RealTimeTripTimes.of( ScheduledTripTimes .of() .withArrivalTimes("00:00 00:01") - .withTrip(TransitModelForTest.trip("trip").build()) + .withTrip(TimetableRepositoryForTest.trip("trip").build()) .build() ); diff --git a/src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotSourceTest.java b/application/src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotSourceTest.java similarity index 94% rename from src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotSourceTest.java rename to application/src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotSourceTest.java index e53ba07cbcf..d0e6f19a156 100644 --- a/src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotSourceTest.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotSourceTest.java @@ -19,13 +19,11 @@ import java.time.Duration; import java.time.LocalDate; import java.util.List; -import javax.annotation.Nonnull; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.opentripplanner.ConstantsForTests; import org.opentripplanner.TestOtpModel; import org.opentripplanner._support.time.ZoneIds; -import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.Timetable; import org.opentripplanner.model.TimetableSnapshot; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -34,10 +32,11 @@ import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.transit.service.TransitService; import org.opentripplanner.updater.GtfsRealtimeFuzzyTripMatcher; import org.opentripplanner.updater.TimetableSnapshotSourceParameters; +import org.opentripplanner.utils.time.ServiceDateUtils; public class TimetableSnapshotSourceTest { @@ -49,7 +48,7 @@ public class TimetableSnapshotSourceTest { ZoneIds.NEW_YORK ) .build(); - private TransitModel transitModel; + private TimetableRepository timetableRepository; private TransitService transitService; private final GtfsRealtimeFuzzyTripMatcher TRIP_MATCHER_NOOP = null; @@ -59,10 +58,10 @@ public class TimetableSnapshotSourceTest { @BeforeEach public void setUp() { TestOtpModel model = ConstantsForTests.buildGtfsGraph(ConstantsForTests.SIMPLE_GTFS); - transitModel = model.transitModel(); - transitService = new DefaultTransitService(transitModel); + timetableRepository = model.timetableRepository(); + transitService = new DefaultTransitService(timetableRepository); - feedId = transitService.getFeedIds().stream().findFirst().get(); + feedId = transitService.listFeedIds().stream().findFirst().get(); } @Test @@ -207,8 +206,8 @@ public void testHandleModifiedTrip() { // Original trip pattern { final FeedScopedId tripId = new FeedScopedId(feedId, modifiedTripId); - final Trip trip = transitService.getTripForId(tripId); - final TripPattern originalTripPattern = transitService.getPatternForTrip(trip); + final Trip trip = transitService.getTrip(tripId); + final TripPattern originalTripPattern = transitService.findPattern(trip); final Timetable originalTimetableForToday = snapshot.resolve( originalTripPattern, @@ -251,7 +250,7 @@ public void testHandleModifiedTrip() { // New trip pattern { - final TripPattern newTripPattern = snapshot.getRealtimeAddedTripPattern( + final TripPattern newTripPattern = snapshot.getNewTripPatternForModifiedTrip( new FeedScopedId(feedId, modifiedTripId), SERVICE_DATE ); @@ -282,11 +281,10 @@ public void testHandleModifiedTrip() { } } - @Nonnull private TimetableSnapshotSource defaultUpdater() { return new TimetableSnapshotSource( new TimetableSnapshotSourceParameters(Duration.ZERO, true), - transitModel, + timetableRepository, () -> SERVICE_DATE ); } diff --git a/application/src/test/java/org/opentripplanner/updater/trip/TripInput.java b/application/src/test/java/org/opentripplanner/updater/trip/TripInput.java new file mode 100644 index 00000000000..eb4f3685659 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/updater/trip/TripInput.java @@ -0,0 +1,47 @@ +package org.opentripplanner.updater.trip; + +import java.util.ArrayList; +import java.util.List; +import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.utils.time.TimeUtils; + +/** + * A simple data structure that is used by the {@link RealtimeTestEnvironment} to create + * trips, trips on date and patterns. + */ +public record TripInput(String id, Route route, List stops) { + public static TripInputBuilder of(String id) { + return new TripInputBuilder(id); + } + + public static class TripInputBuilder implements RealtimeTestConstants { + + private final String id; + private final List stops = new ArrayList<>(); + // can be made configurable if needed + private Route route = ROUTE_1; + + TripInputBuilder(String id) { + this.id = id; + } + + public TripInputBuilder addStop(RegularStop stopId, String arrivalTime, String departureTime) { + this.stops.add( + new StopCall(stopId, TimeUtils.time(arrivalTime), TimeUtils.time(departureTime)) + ); + return this; + } + + public TripInput build() { + return new TripInput(id, route, stops); + } + + public TripInputBuilder withRoute(Route route) { + this.route = route; + return this; + } + } + + record StopCall(RegularStop stop, int arrivalTime, int departureTime) {} +} diff --git a/src/test/java/org/opentripplanner/updater/trip/TripUpdateBuilder.java b/application/src/test/java/org/opentripplanner/updater/trip/TripUpdateBuilder.java similarity index 98% rename from src/test/java/org/opentripplanner/updater/trip/TripUpdateBuilder.java rename to application/src/test/java/org/opentripplanner/updater/trip/TripUpdateBuilder.java index 2960d92a9cd..e8218edfc1f 100644 --- a/src/test/java/org/opentripplanner/updater/trip/TripUpdateBuilder.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/TripUpdateBuilder.java @@ -7,7 +7,7 @@ import java.time.LocalDate; import java.time.ZoneId; import java.time.ZonedDateTime; -import org.opentripplanner.framework.time.ServiceDateUtils; +import org.opentripplanner.utils.time.ServiceDateUtils; public class TripUpdateBuilder { diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java b/application/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java similarity index 82% rename from src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java rename to application/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java index 2e0b9d3d88e..e926361f4ea 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java @@ -7,34 +7,31 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertSuccess; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.SERVICE_DATE; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.STOP_A1_ID; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.STOP_B1_ID; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.STOP_C1_ID; import de.mfdz.MfdzRealtimeExtensions.StopTimePropertiesExtension.DropOffPickupType; import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner.model.PickDrop; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.service.TransitService; import org.opentripplanner.updater.spi.UpdateSuccess; +import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; import org.opentripplanner.updater.trip.TripUpdateBuilder; -class AddedTest { +class AddedTest implements RealtimeTestConstants { final String ADDED_TRIP_ID = "added_trip"; @Test void addedTrip() { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().build(); - var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, env.timeZone) + var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, TIME_ZONE) .addStopTime(STOP_A1_ID, 30) .addStopTime(STOP_B1_ID, 40) .addStopTime(STOP_C1_ID, 55) @@ -46,8 +43,8 @@ void addedTrip() { @Test void addedTripWithNewRoute() { - var env = RealtimeTestEnvironment.gtfs(); - var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, env.timeZone) + var env = RealtimeTestEnvironment.gtfs().build(); + var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, TIME_ZONE) .addTripExtension() .addStopTime(STOP_A1_ID, 30, DropOffPickupType.PHONE_AGENCY) .addStopTime(STOP_B1_ID, 40, DropOffPickupType.COORDINATE_WITH_DRIVER) @@ -66,9 +63,9 @@ void addedTripWithNewRoute() { assertEquals(TransitMode.RAIL, route.getMode()); TransitService transitService = env.getTransitService(); - var fromTransitModel = transitService.getRouteForId(route.getId()); - assertEquals(fromTransitModel, route); - var patternsForRoute = transitService.getPatternsForRoute(route); + var fromTimetableRepository = transitService.getRoute(route.getId()); + assertEquals(fromTimetableRepository, route); + var patternsForRoute = transitService.findPatterns(route); assertEquals(1, patternsForRoute.size()); assertEquals(pattern, patternsForRoute.stream().findFirst().orElseThrow()); @@ -81,8 +78,8 @@ void addedTripWithNewRoute() { @Test void addedWithUnknownStop() { - var env = RealtimeTestEnvironment.gtfs(); - var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, env.timeZone) + var env = RealtimeTestEnvironment.gtfs().build(); + var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, TIME_ZONE) // add extension to set route name, url, mode .addTripExtension() .addStopTime(STOP_A1_ID, 30, DropOffPickupType.PHONE_AGENCY) @@ -105,8 +102,8 @@ void addedWithUnknownStop() { @Test void repeatedlyAddedTripWithNewRoute() { - var env = RealtimeTestEnvironment.gtfs(); - var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, env.timeZone) + var env = RealtimeTestEnvironment.gtfs().build(); + var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, TIME_ZONE) // add extension to set route name, url, mode .addTripExtension() .addStopTime(STOP_A1_ID, 30, DropOffPickupType.PHONE_AGENCY) @@ -124,18 +121,18 @@ void repeatedlyAddedTripWithNewRoute() { var secondRoute = secondPattern.getRoute(); assertSame(firstRoute, secondRoute); - assertNotNull(env.getTransitService().getRouteForId(firstRoute.getId())); + assertNotNull(env.getTransitService().getRoute(firstRoute.getId())); } private TripPattern assertAddedTrip(String tripId, RealtimeTestEnvironment env) { var snapshot = env.getTimetableSnapshot(); TransitService transitService = env.getTransitService(); - Trip trip = transitService.getTripForId(TransitModelForTest.id(ADDED_TRIP_ID)); + Trip trip = transitService.getTrip(TimetableRepositoryForTest.id(ADDED_TRIP_ID)); assertNotNull(trip); - assertNotNull(transitService.getPatternForTrip(trip)); + assertNotNull(transitService.findPattern(trip)); - var stopA = env.transitModel.getStopModel().getRegularStop(env.stopA1.getId()); + var stopA = env.timetableRepository.getSiteRepository().getRegularStop(STOP_A1.getId()); // Get the trip pattern of the added trip which goes through stopA var patternsAtA = env.getTimetableSnapshot().getPatternsForStop(stopA); diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java b/application/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java similarity index 77% rename from src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java rename to application/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java index c85225b7828..e79ca7f6ce5 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java @@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertSuccess; import static org.opentripplanner.updater.trip.UpdateIncrementality.DIFFERENTIAL; @@ -13,14 +14,16 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.transit.model.timetable.RealTimeState; +import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; +import org.opentripplanner.updater.trip.TripInput; import org.opentripplanner.updater.trip.TripUpdateBuilder; /** * Cancellations and deletions should end up in the internal data model and make trips unavailable * for routing. */ -public class CancellationDeletionTest { +public class CancellationDeletionTest implements RealtimeTestConstants { static List cases() { return List.of( @@ -32,22 +35,25 @@ static List cases() { @ParameterizedTest @MethodSource("cases") void cancelledTrip(ScheduleRelationship relationship, RealTimeState state) { - var env = RealtimeTestEnvironment.gtfs(); - var pattern1 = env.getPatternForTrip(env.trip1); + var env = RealtimeTestEnvironment + .gtfs() + .addTrip( + TripInput + .of(TRIP_1_ID) + .addStop(STOP_A1, "0:00:10", "0:00:11") + .addStop(STOP_B1, "0:00:20", "0:00:21") + .build() + ) + .build(); + var pattern1 = env.getPatternForTrip(TRIP_1_ID); - final int tripIndex1 = pattern1.getScheduledTimetable().getTripIndex(env.trip1.getId()); + final int tripIndex1 = pattern1.getScheduledTimetable().getTripIndex(id(TRIP_1_ID)); - var update = new TripUpdateBuilder( - env.trip1.getId().getId(), - RealtimeTestEnvironment.SERVICE_DATE, - relationship, - env.timeZone - ) - .build(); + var update = new TripUpdateBuilder(TRIP_1_ID, SERVICE_DATE, relationship, TIME_ZONE).build(); assertSuccess(env.applyTripUpdate(update)); var snapshot = env.getTimetableSnapshot(); - var forToday = snapshot.resolve(pattern1, RealtimeTestEnvironment.SERVICE_DATE); + var forToday = snapshot.resolve(pattern1, SERVICE_DATE); var schedule = snapshot.resolve(pattern1, null); assertNotSame(forToday, schedule); assertNotSame(forToday.getTripTimes(tripIndex1), schedule.getTripTimes(tripIndex1)); @@ -71,41 +77,34 @@ void cancelledTrip(ScheduleRelationship relationship, RealTimeState state) { @ParameterizedTest @MethodSource("cases") void cancelingAddedTrip(ScheduleRelationship relationship, RealTimeState state) { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().build(); var addedTripId = "added-trip"; // First add ADDED trip var update = new TripUpdateBuilder( addedTripId, - RealtimeTestEnvironment.SERVICE_DATE, + SERVICE_DATE, ScheduleRelationship.ADDED, - env.timeZone + TIME_ZONE ) - .addStopTime(env.stopA1.getId().getId(), 30) - .addStopTime(env.stopB1.getId().getId(), 40) - .addStopTime(env.stopC1.getId().getId(), 55) + .addStopTime(STOP_A1_ID, 30) + .addStopTime(STOP_B1_ID, 40) + .addStopTime(STOP_C1_ID, 55) .build(); assertSuccess(env.applyTripUpdate(update, DIFFERENTIAL)); // Cancel or delete the added trip - update = - new TripUpdateBuilder( - addedTripId, - RealtimeTestEnvironment.SERVICE_DATE, - relationship, - env.timeZone - ) - .build(); + update = new TripUpdateBuilder(addedTripId, SERVICE_DATE, relationship, TIME_ZONE).build(); assertSuccess(env.applyTripUpdate(update, DIFFERENTIAL)); var snapshot = env.getTimetableSnapshot(); // Get the trip pattern of the added trip which goes through stopA - var patternsAtA = snapshot.getPatternsForStop(env.stopA1); + var patternsAtA = snapshot.getPatternsForStop(STOP_A1); assertNotNull(patternsAtA, "Added trip pattern should be found"); var tripPattern = patternsAtA.stream().findFirst().get(); - var forToday = snapshot.resolve(tripPattern, RealtimeTestEnvironment.SERVICE_DATE); + var forToday = snapshot.resolve(tripPattern, SERVICE_DATE); var schedule = snapshot.resolve(tripPattern, null); assertNotSame(forToday, schedule); diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java b/application/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java similarity index 69% rename from src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java rename to application/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java index 5298853f36d..665c79d193c 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java @@ -5,34 +5,34 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertSuccess; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.SERVICE_DATE; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.RealTimeState; -import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; +import org.opentripplanner.updater.trip.TripInput; import org.opentripplanner.updater.trip.TripUpdateBuilder; /** * Delays should be applied to the first trip but should leave the second trip untouched. */ -class DelayedTest { +class DelayedTest implements RealtimeTestConstants { private static final int DELAY = 1; private static final int STOP_SEQUENCE = 1; @Test void singleStopDelay() { - var env = RealtimeTestEnvironment.gtfs(); - - var tripUpdate = new TripUpdateBuilder( - env.trip1.getId().getId(), - RealtimeTestEnvironment.SERVICE_DATE, - SCHEDULED, - env.timeZone - ) + var TRIP_INPUT = TripInput + .of(TRIP_1_ID) + .addStop(STOP_A1, "0:00:10", "0:00:11") + .addStop(STOP_B1, "0:00:20", "0:00:21") + .build(); + var env = RealtimeTestEnvironment.gtfs().addTrip(TRIP_INPUT).build(); + + var tripUpdate = new TripUpdateBuilder(TRIP_1_ID, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(STOP_SEQUENCE, DELAY) .build(); @@ -40,11 +40,11 @@ void singleStopDelay() { assertEquals(1, result.successful()); - var pattern1 = env.getPatternForTrip(env.trip1); - int trip1Index = pattern1.getScheduledTimetable().getTripIndex(env.trip1.getId()); + var pattern1 = env.getPatternForTrip(TRIP_1_ID); + int trip1Index = pattern1.getScheduledTimetable().getTripIndex(id(TRIP_1_ID)); var snapshot = env.getTimetableSnapshot(); - var trip1Realtime = snapshot.resolve(pattern1, RealtimeTestEnvironment.SERVICE_DATE); + var trip1Realtime = snapshot.resolve(pattern1, SERVICE_DATE); var trip1Scheduled = snapshot.resolve(pattern1, null); assertNotSame(trip1Realtime, trip1Scheduled); @@ -59,11 +59,11 @@ void singleStopDelay() { assertEquals( "SCHEDULED | A1 0:00:10 0:00:11 | B1 0:00:20 0:00:21", - env.getScheduledTimetable(env.trip1.getId()) + env.getScheduledTimetable(TRIP_1_ID) ); assertEquals( "UPDATED | A1 [ND] 0:00:10 0:00:11 | B1 0:00:21 0:00:22", - env.getRealtimeTimetable(env.trip1.getId().getId()) + env.getRealtimeTimetable(TRIP_1_ID) ); } @@ -72,11 +72,15 @@ void singleStopDelay() { */ @Test void complexDelay() { - var env = RealtimeTestEnvironment.gtfs(); - - var tripId = env.trip2.getId().getId(); + var tripInput = TripInput + .of(TRIP_2_ID) + .addStop(STOP_A1, "0:01:00", "0:01:01") + .addStop(STOP_B1, "0:01:10", "0:01:11") + .addStop(STOP_C1, "0:01:20", "0:01:21") + .build(); + var env = RealtimeTestEnvironment.gtfs().addTrip(tripInput).build(); - var tripUpdate = new TripUpdateBuilder(tripId, SERVICE_DATE, SCHEDULED, env.timeZone) + var tripUpdate = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) .addDelayedStopTime(1, 60, 80) .addDelayedStopTime(2, 90, 90) @@ -86,19 +90,20 @@ void complexDelay() { var snapshot = env.getTimetableSnapshot(); - final TripPattern originalTripPattern = env.getTransitService().getPatternForTrip(env.trip2); + var trip2 = env.getTransitService().getTrip(id(TRIP_2_ID)); + var originalTripPattern = env.getTransitService().findPattern(trip2); var originalTimetableForToday = snapshot.resolve(originalTripPattern, SERVICE_DATE); var originalTimetableScheduled = snapshot.resolve(originalTripPattern, null); assertNotSame(originalTimetableForToday, originalTimetableScheduled); - final int originalTripIndexScheduled = originalTimetableScheduled.getTripIndex(tripId); + final int originalTripIndexScheduled = originalTimetableScheduled.getTripIndex(TRIP_2_ID); assertTrue( originalTripIndexScheduled > -1, "Original trip should be found in scheduled time table" ); - final TripTimes originalTripTimesScheduled = originalTimetableScheduled.getTripTimes( + var originalTripTimesScheduled = originalTimetableScheduled.getTripTimes( originalTripIndexScheduled ); assertFalse( @@ -107,7 +112,7 @@ void complexDelay() { ); assertEquals(RealTimeState.SCHEDULED, originalTripTimesScheduled.getRealTimeState()); - final int originalTripIndexForToday = originalTimetableForToday.getTripIndex(tripId); + final int originalTripIndexForToday = originalTimetableForToday.getTripIndex(TRIP_2_ID); assertTrue( originalTripIndexForToday > -1, "Original trip should be found in time table for service date" @@ -115,11 +120,11 @@ void complexDelay() { assertEquals( "SCHEDULED | A1 0:01 0:01:01 | B1 0:01:10 0:01:11 | C1 0:01:20 0:01:21", - env.getScheduledTimetable(env.trip2.getId()) + env.getScheduledTimetable(TRIP_2_ID) ); assertEquals( "UPDATED | A1 0:01 0:01:01 | B1 0:02:10 0:02:31 | C1 0:02:50 0:02:51", - env.getRealtimeTimetable(env.trip2) + env.getRealtimeTimetable(TRIP_2_ID) ); } } diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java b/application/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java similarity index 76% rename from src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java rename to application/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java index de699324bb6..e10b86797b8 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java @@ -6,28 +6,35 @@ import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertSuccess; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.SERVICE_DATE; import static org.opentripplanner.updater.trip.UpdateIncrementality.DIFFERENTIAL; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.transit.model.timetable.TripTimesStringBuilder; +import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; +import org.opentripplanner.updater.trip.TripInput; import org.opentripplanner.updater.trip.TripUpdateBuilder; /** * A mixture of delayed and skipped stops should result in both delayed and cancelled stops. */ -public class SkippedTest { +class SkippedTest implements RealtimeTestConstants { + + private static final TripInput TRIP_INPUT = TripInput + .of(TRIP_2_ID) + .addStop(STOP_A1, "0:01:00", "0:01:01") + .addStop(STOP_B1, "0:01:10", "0:01:11") + .addStop(STOP_C1, "0:01:20", "0:01:21") + .build(); @Test void scheduledTripWithSkippedAndScheduled() { - var env = RealtimeTestEnvironment.gtfs(); - String scheduledTripId = env.trip2.getId().getId(); + var env = RealtimeTestEnvironment.gtfs().addTrip(TRIP_INPUT).build(); - var tripUpdate = new TripUpdateBuilder(scheduledTripId, SERVICE_DATE, SCHEDULED, env.timeZone) + var tripUpdate = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) .addSkippedStop(1) .addDelayedStopTime(2, 90) @@ -35,13 +42,13 @@ void scheduledTripWithSkippedAndScheduled() { assertSuccess(env.applyTripUpdate(tripUpdate)); - assertOriginalTripPatternIsDeleted(env, env.trip2.getId()); + assertOriginalTripPatternIsDeleted(env, TRIP_2_ID); - assertNewTripTimesIsUpdated(env, env.trip2.getId()); + assertNewTripTimesIsUpdated(env, TRIP_2_ID); assertEquals( "UPDATED | A1 0:01 0:01:01 | B1 [C] 0:01:52 0:01:58 | C1 0:02:50 0:02:51", - env.getRealtimeTimetable(scheduledTripId) + env.getRealtimeTimetable(TRIP_2_ID) ); } @@ -56,10 +63,9 @@ void scheduledTripWithSkippedAndScheduled() { */ @Test void scheduledTripWithPreviouslySkipped() { - var env = RealtimeTestEnvironment.gtfs(); - var tripId = env.trip2.getId(); + var env = RealtimeTestEnvironment.gtfs().addTrip(TRIP_INPUT).build(); - var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, env.timeZone) + var tripUpdate = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) .addSkippedStop(1) .addDelayedStopTime(2, 90) @@ -68,12 +74,7 @@ void scheduledTripWithPreviouslySkipped() { assertSuccess(env.applyTripUpdate(tripUpdate, DIFFERENTIAL)); // Create update to the same trip but now the skipped stop is no longer skipped - var scheduledBuilder = new TripUpdateBuilder( - tripId.getId(), - SERVICE_DATE, - SCHEDULED, - env.timeZone - ) + var scheduledBuilder = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) .addDelayedStopTime(1, 50) .addDelayedStopTime(2, 90); @@ -87,17 +88,17 @@ void scheduledTripWithPreviouslySkipped() { // stoptime updates have gone through var snapshot = env.getTimetableSnapshot(); - assertNull(snapshot.getRealtimeAddedTripPattern(tripId, SERVICE_DATE)); + assertNull(snapshot.getNewTripPatternForModifiedTrip(id(TRIP_2_ID), SERVICE_DATE)); - assertNewTripTimesIsUpdated(env, tripId); + assertNewTripTimesIsUpdated(env, TRIP_2_ID); assertEquals( "SCHEDULED | A1 0:01 0:01:01 | B1 0:01:10 0:01:11 | C1 0:01:20 0:01:21", - env.getScheduledTimetable(tripId) + env.getScheduledTimetable(TRIP_2_ID) ); assertEquals( "UPDATED | A1 0:01 0:01:01 | B1 0:02 0:02:01 | C1 0:02:50 0:02:51", - env.getRealtimeTimetable(tripId, SERVICE_DATE) + env.getRealtimeTimetable(id(TRIP_2_ID), SERVICE_DATE) ); } @@ -106,11 +107,11 @@ void scheduledTripWithPreviouslySkipped() { */ @Test void skippedNoData() { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().addTrip(TRIP_INPUT).build(); - final FeedScopedId tripId = env.trip2.getId(); + String tripId = TRIP_2_ID; - var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, env.timeZone) + var tripUpdate = new TripUpdateBuilder(tripId, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addNoDataStop(0) .addSkippedStop(1) .addNoDataStop(2) @@ -124,16 +125,16 @@ void skippedNoData() { assertEquals( "UPDATED | A1 [ND] 0:01 0:01:01 | B1 [C] 0:01:10 0:01:11 | C1 [ND] 0:01:20 0:01:21", - env.getRealtimeTimetable(env.trip2) + env.getRealtimeTimetable(tripId) ); } private static void assertOriginalTripPatternIsDeleted( RealtimeTestEnvironment env, - FeedScopedId tripId + String tripId ) { - var trip = env.getTransitService().getTripForId(tripId); - var originalTripPattern = env.getTransitService().getPatternForTrip(trip); + var trip = env.getTransitService().getTrip(id(tripId)); + var originalTripPattern = env.getTransitService().findPattern(trip); var snapshot = env.getTimetableSnapshot(); var originalTimetableForToday = snapshot.resolve(originalTripPattern, SERVICE_DATE); var originalTimetableScheduled = snapshot.resolve(originalTripPattern, null); @@ -174,11 +175,9 @@ private static void assertOriginalTripPatternIsDeleted( assertEquals(RealTimeState.DELETED, originalTripTimesForToday.getRealTimeState()); } - private static void assertNewTripTimesIsUpdated( - RealtimeTestEnvironment env, - FeedScopedId tripId - ) { - var originalTripPattern = env.getTransitService().getPatternForTrip(env.trip2); + private static void assertNewTripTimesIsUpdated(RealtimeTestEnvironment env, String tripId) { + var trip = env.getTransitService().getTrip(id(tripId)); + var originalTripPattern = env.getTransitService().findPattern(trip); var snapshot = env.getTimetableSnapshot(); var originalTimetableForToday = snapshot.resolve(originalTripPattern, SERVICE_DATE); diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java b/application/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java similarity index 72% rename from src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java rename to application/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java index da362451753..2ba6749b4b0 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java @@ -4,20 +4,21 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.updater.spi.UpdateError.UpdateErrorType.NO_SERVICE_ON_DATE; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertFailure; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.SERVICE_DATE; import java.time.LocalDate; import java.util.List; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; +import org.opentripplanner.updater.trip.TripInput; import org.opentripplanner.updater.trip.TripUpdateBuilder; /** * A trip with start date that is outside the service period shouldn't throw an exception and is * ignored instead. */ -class InvalidInputTest { +class InvalidInputTest implements RealtimeTestConstants { public static List cases() { return List.of(SERVICE_DATE.minusYears(10), SERVICE_DATE.plusYears(10)); @@ -26,9 +27,14 @@ public static List cases() { @ParameterizedTest @MethodSource("cases") void invalidTripDate(LocalDate date) { - var env = RealtimeTestEnvironment.gtfs(); + var tripInput = TripInput + .of(TRIP_1_ID) + .addStop(STOP_A1, "0:00:10", "0:00:11") + .addStop(STOP_B1, "0:00:20", "0:00:21") + .build(); + var env = RealtimeTestEnvironment.gtfs().addTrip(tripInput).build(); - var update = new TripUpdateBuilder(env.trip1.getId().getId(), date, SCHEDULED, env.timeZone) + var update = new TripUpdateBuilder(TRIP_1_ID, date, SCHEDULED, TIME_ZONE) .addDelayedStopTime(2, 60, 80) .build(); diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidTripIdTest.java b/application/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidTripIdTest.java similarity index 96% rename from src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidTripIdTest.java rename to application/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidTripIdTest.java index 83c2547dbc7..699e8fe865c 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidTripIdTest.java +++ b/application/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidTripIdTest.java @@ -22,7 +22,7 @@ static Stream invalidCases() { @ParameterizedTest(name = "tripId=\"{0}\"") @MethodSource("invalidCases") void invalidTripId(String tripId) { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().build(); var tripDescriptorBuilder = GtfsRealtime.TripDescriptor.newBuilder(); if (tripId != null) { tripDescriptorBuilder.setTripId(tripId); diff --git a/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java b/application/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java similarity index 76% rename from src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java rename to application/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java index 33455cf9b9a..ecf7904de4a 100644 --- a/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java +++ b/application/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java @@ -3,7 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.newNodeAdapterForTest; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import com.google.common.util.concurrent.Futures; import java.util.List; @@ -12,12 +12,13 @@ import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; import org.opentripplanner.standalone.config.routerconfig.updaters.VehicleParkingUpdaterConfig; import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.updater.DefaultRealTimeUpdateContext; import org.opentripplanner.updater.GraphUpdaterManager; import org.opentripplanner.updater.GraphWriterRunnable; @@ -46,7 +47,7 @@ class VehicleParkingAvailabilityUpdaterTest { @Test void updateCarAvailability() { - var service = buildParkingService(VehicleParkingSpaces.builder().carSpaces(10).build()); + var service = buildParkingRepository(VehicleParkingSpaces.builder().carSpaces(10).build()); var updater = new VehicleParkingAvailabilityUpdater( PARAMETERS, new StubDatasource(DEFAULT_UPDATE), @@ -55,7 +56,7 @@ void updateCarAvailability() { runUpdaterOnce(updater); - var updated = service.getVehicleParkings().toList().getFirst(); + var updated = List.copyOf(service.listVehicleParkings()).getFirst(); assertEquals(ID, updated.getId()); assertEquals(8, updated.getAvailability().getCarSpaces()); assertNull(updated.getAvailability().getBicycleSpaces()); @@ -63,7 +64,7 @@ void updateCarAvailability() { @Test void updateBicycleAvailability() { - var service = buildParkingService(VehicleParkingSpaces.builder().bicycleSpaces(15).build()); + var service = buildParkingRepository(VehicleParkingSpaces.builder().bicycleSpaces(15).build()); var updater = new VehicleParkingAvailabilityUpdater( PARAMETERS, new StubDatasource(DEFAULT_UPDATE), @@ -72,7 +73,7 @@ void updateBicycleAvailability() { runUpdaterOnce(updater); - var updated = service.getVehicleParkings().toList().getFirst(); + var updated = List.copyOf(service.listVehicleParkings()).getFirst(); assertEquals(ID, updated.getId()); assertEquals(8, updated.getAvailability().getBicycleSpaces()); assertNull(updated.getAvailability().getCarSpaces()); @@ -80,7 +81,7 @@ void updateBicycleAvailability() { @Test void notFound() { - var service = buildParkingService(VehicleParkingSpaces.builder().bicycleSpaces(15).build()); + var service = buildParkingRepository(VehicleParkingSpaces.builder().bicycleSpaces(15).build()); var updater = new VehicleParkingAvailabilityUpdater( PARAMETERS, new StubDatasource(new AvailabiltyUpdate(id("not-found"), 100)), @@ -89,21 +90,21 @@ void notFound() { runUpdaterOnce(updater); - var updated = service.getVehicleParkings().toList().getFirst(); + var updated = List.copyOf(service.listVehicleParkings()).getFirst(); assertEquals(ID, updated.getId()); assertNull(updated.getAvailability()); } - private static VehicleParkingService buildParkingService(VehicleParkingSpaces capacity) { - var service = new VehicleParkingService(); + private static VehicleParkingRepository buildParkingRepository(VehicleParkingSpaces capacity) { + var repo = new DefaultVehicleParkingRepository(); var parking = parkingBuilder() .carPlaces(capacity.getCarSpaces() != null) .bicyclePlaces(capacity.getBicycleSpaces() != null) .capacity(capacity) .build(); - service.updateVehicleParking(List.of(parking), List.of()); - return service; + repo.updateVehicleParking(List.of(parking), List.of()); + return repo; } private static VehicleParking.VehicleParkingBuilder parkingBuilder() { @@ -118,7 +119,7 @@ private void runUpdaterOnce(VehicleParkingAvailabilityUpdater updater) { class GraphUpdaterMock extends GraphUpdaterManager { private static final Graph GRAPH = new Graph(); - private static final TransitModel TRANSIT_MODEL = new TransitModel(); + private static final TimetableRepository TRANSIT_MODEL = new TimetableRepository(); public static final DefaultRealTimeUpdateContext REAL_TIME_UPDATE_CONTEXT = new DefaultRealTimeUpdateContext( GRAPH, TRANSIT_MODEL diff --git a/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterTest.java b/application/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterTest.java similarity index 78% rename from src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterTest.java rename to application/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterTest.java index e504e42eb6c..261cd55011d 100644 --- a/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterTest.java +++ b/application/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterTest.java @@ -11,16 +11,18 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingState; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingTestGraphData; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingTestUtil; +import org.opentripplanner.service.vehicleparking.VehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.VehicleParkingTestGraphData; +import org.opentripplanner.service.vehicleparking.VehicleParkingTestUtil; +import org.opentripplanner.service.vehicleparking.internal.DefaultVehicleParkingRepository; +import org.opentripplanner.service.vehicleparking.model.VehicleParking; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingSpaces; +import org.opentripplanner.service.vehicleparking.model.VehicleParkingState; import org.opentripplanner.street.model._data.StreetModelForTest; import org.opentripplanner.street.model.edge.StreetVehicleParkingLink; import org.opentripplanner.street.model.edge.VehicleParkingEdge; import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.updater.DefaultRealTimeUpdateContext; import org.opentripplanner.updater.GraphUpdaterManager; import org.opentripplanner.updater.GraphWriterRunnable; @@ -31,10 +33,10 @@ class VehicleParkingUpdaterTest { private DataSource dataSource; private Graph graph; - private TransitModel transitModel; private DefaultRealTimeUpdateContext realTimeUpdateContext; private VehicleParkingUpdater vehicleParkingUpdater; + private VehicleParkingRepository parkingRepository; @BeforeEach @SuppressWarnings("unchecked") @@ -42,14 +44,15 @@ public void setup() { VehicleParkingTestGraphData graphData = new VehicleParkingTestGraphData(); graphData.initGraph(); graph = graphData.getGraph(); - transitModel = graphData.getTransitModel(); - realTimeUpdateContext = new DefaultRealTimeUpdateContext(graph, transitModel); + TimetableRepository timetableRepository = graphData.getTimetableRepository(); + parkingRepository = new DefaultVehicleParkingRepository(); + realTimeUpdateContext = new DefaultRealTimeUpdateContext(graph, timetableRepository); dataSource = (DataSource) Mockito.mock(DataSource.class); when(dataSource.update()).thenReturn(true); - transitModel.index(); - graph.index(transitModel.getStopModel()); + timetableRepository.index(); + graph.index(timetableRepository.getSiteRepository()); var parameters = new VehicleParkingUpdaterParameters() { @Override @@ -73,12 +76,7 @@ public String configRef() { } }; vehicleParkingUpdater = - new VehicleParkingUpdater( - parameters, - dataSource, - graph.getLinker(), - graph.getVehicleParkingService() - ); + new VehicleParkingUpdater(parameters, dataSource, graph.getLinker(), parkingRepository); } @Test @@ -106,9 +104,9 @@ void updateVehicleParkingTest() { assertVehicleParkingsInGraph(1); - var vehicleParkingInGraph = graph - .getVehicleParkingService() - .getVehicleParkings() + var vehicleParkingInGraph = parkingRepository + .listVehicleParkings() + .stream() .findFirst() .orElseThrow(); assertEquals(vehiclePlaces, vehicleParkingInGraph.getAvailability()); @@ -124,7 +122,7 @@ void updateVehicleParkingTest() { assertVehicleParkingsInGraph(1); vehicleParkingInGraph = - graph.getVehicleParkingService().getVehicleParkings().findFirst().orElseThrow(); + parkingRepository.listVehicleParkings().stream().findFirst().orElseThrow(); assertEquals(vehiclePlaces, vehicleParkingInGraph.getAvailability()); assertEquals(vehiclePlaces, vehicleParkingInGraph.getCapacity()); } @@ -159,7 +157,7 @@ void addNotOperatingVehicleParkingTest() { when(dataSource.getUpdates()).thenReturn(List.of(vehicleParking)); runUpdaterOnce(); - assertEquals(1, graph.getVehicleParkingService().getVehicleParkings().count()); + assertEquals(1, parkingRepository.listVehicleParkings().size()); assertVehicleParkingNotLinked(); } @@ -176,11 +174,10 @@ void updateNotOperatingVehicleParkingTest() { when(dataSource.getUpdates()).thenReturn(List.of(vehicleParking)); runUpdaterOnce(); - var vehicleParkingService = graph.getVehicleParkingService(); - assertEquals(1, vehicleParkingService.getVehicleParkings().count()); + assertEquals(1, parkingRepository.listVehicleParkings().size()); assertEquals( vehiclePlaces, - vehicleParkingService.getVehicleParkings().findFirst().orElseThrow().getAvailability() + parkingRepository.listVehicleParkings().stream().findFirst().orElseThrow().getAvailability() ); assertVehicleParkingNotLinked(); @@ -196,10 +193,10 @@ void updateNotOperatingVehicleParkingTest() { when(dataSource.getUpdates()).thenReturn(List.of(vehicleParking)); runUpdaterOnce(); - assertEquals(1, vehicleParkingService.getVehicleParkings().count()); + assertEquals(1, parkingRepository.listVehicleParkings().size()); assertEquals( vehiclePlaces, - vehicleParkingService.getVehicleParkings().findFirst().orElseThrow().getAvailability() + parkingRepository.listVehicleParkings().stream().findFirst().orElseThrow().getAvailability() ); assertVehicleParkingNotLinked(); } @@ -214,13 +211,12 @@ void deleteNotOperatingVehicleParkingTest() { when(dataSource.getUpdates()).thenReturn(List.of(vehicleParking)); runUpdaterOnce(); - var vehicleParkingService = graph.getVehicleParkingService(); - assertEquals(1, vehicleParkingService.getVehicleParkings().count()); + assertEquals(1, parkingRepository.listVehicleParkings().size()); when(dataSource.getUpdates()).thenReturn(List.of()); runUpdaterOnce(); - assertEquals(0, vehicleParkingService.getVehicleParkings().count()); + assertEquals(0, parkingRepository.listVehicleParkings().size()); } private void assertVehicleParkingsInGraph(int vehicleParkingNumber) { @@ -261,16 +257,13 @@ private void assertVehicleParkingsInGraph(int vehicleParkingNumber) { ); } - assertEquals( - vehicleParkingNumber, - graph.getVehicleParkingService().getVehicleParkings().count() - ); + assertEquals(vehicleParkingNumber, parkingRepository.listVehicleParkings().size()); } private void runUpdaterOnce() { class GraphUpdaterMock extends GraphUpdaterManager { - public GraphUpdaterMock(Graph graph, TransitModel transitModel, List updaters) { + public GraphUpdaterMock(List updaters) { super(realTimeUpdateContext, updaters); } @@ -281,11 +274,7 @@ public Future execute(GraphWriterRunnable runnable) { } } - var graphUpdaterManager = new GraphUpdaterMock( - graph, - transitModel, - List.of(vehicleParkingUpdater) - ); + var graphUpdaterManager = new GraphUpdaterMock(List.of(vehicleParkingUpdater)); graphUpdaterManager.startUpdaters(); graphUpdaterManager.stop(false); } diff --git a/src/test/java/org/opentripplanner/updater/vehicle_position/RealtimeVehicleMatcherTest.java b/application/src/test/java/org/opentripplanner/updater/vehicle_position/RealtimeVehicleMatcherTest.java similarity index 89% rename from src/test/java/org/opentripplanner/updater/vehicle_position/RealtimeVehicleMatcherTest.java rename to application/src/test/java/org/opentripplanner/updater/vehicle_position/RealtimeVehicleMatcherTest.java index ea5d86cd0e1..9cdeba6ec3d 100644 --- a/src/test/java/org/opentripplanner/updater/vehicle_position/RealtimeVehicleMatcherTest.java +++ b/application/src/test/java/org/opentripplanner/updater/vehicle_position/RealtimeVehicleMatcherTest.java @@ -1,7 +1,6 @@ package org.opentripplanner.updater.vehicle_position; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.model.plan.PlanTestConstants.T11_00; import static org.opentripplanner.standalone.config.routerconfig.updaters.VehiclePositionsUpdaterConfig.VehiclePositionFeature.OCCUPANCY; import static org.opentripplanner.standalone.config.routerconfig.updaters.VehiclePositionsUpdaterConfig.VehiclePositionFeature.POSITION; import static org.opentripplanner.standalone.config.routerconfig.updaters.VehiclePositionsUpdaterConfig.VehiclePositionFeature.STOP_POSITION; @@ -29,7 +28,7 @@ import org.opentripplanner.model.StopTime; import org.opentripplanner.service.realtimevehicles.internal.DefaultRealtimeVehicleService; import org.opentripplanner.standalone.config.routerconfig.updaters.VehiclePositionsUpdaterConfig; -import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; @@ -41,9 +40,9 @@ public class RealtimeVehicleMatcherTest { - private final TransitModelForTest testModel = TransitModelForTest.of(); + private final TimetableRepositoryForTest testModel = TimetableRepositoryForTest.of(); - private static final Route ROUTE = TransitModelForTest.route("1").build(); + private static final Route ROUTE = TimetableRepositoryForTest.route("1").build(); private static final Set FEATURES = Set.of( POSITION, STOP_POSITION, @@ -51,7 +50,7 @@ public class RealtimeVehicleMatcherTest { ); ZoneId zoneId = ZoneIds.BERLIN; String tripId = "trip1"; - FeedScopedId scopedTripId = TransitModelForTest.id(tripId); + FeedScopedId scopedTripId = TimetableRepositoryForTest.id(tripId); @Test public void matchRealtimeVehiclesToTrip() { @@ -89,15 +88,15 @@ public void tripNotFoundInPattern() { final String secondTripId = "trip2"; - var trip1 = TransitModelForTest.trip(tripId).build(); - var trip2 = TransitModelForTest.trip(secondTripId).build(); + var trip1 = TimetableRepositoryForTest.trip(tripId).build(); + var trip2 = TimetableRepositoryForTest.trip(secondTripId).build(); - var stopTimes = testModel.stopTimesEvery5Minutes(3, trip1, T11_00); + var stopTimes = testModel.stopTimesEvery5Minutes(3, trip1, "11:00"); var pattern = tripPattern(trip1, stopTimes); // Map positions to trips in feed RealtimeVehiclePatternMatcher matcher = new RealtimeVehiclePatternMatcher( - TransitModelForTest.FEED_ID, + TimetableRepositoryForTest.FEED_ID, ignored -> trip2, ignored -> pattern, (id, time) -> pattern, @@ -119,8 +118,8 @@ public void sequenceId() { var service = new DefaultRealtimeVehicleService(null); var tripId = "trip1"; - var scopedTripId = TransitModelForTest.id(tripId); - var trip1 = TransitModelForTest.trip(tripId).build(); + var scopedTripId = TimetableRepositoryForTest.id(tripId); + var trip1 = TimetableRepositoryForTest.trip(tripId).build(); var stopTimes = List.of( testModel.stopTime(trip1, 10), @@ -134,7 +133,7 @@ public void sequenceId() { // Map positions to trips in feed RealtimeVehiclePatternMatcher matcher = new RealtimeVehiclePatternMatcher( - TransitModelForTest.FEED_ID, + TimetableRepositoryForTest.FEED_ID, tripForId::get, patternForTrip::get, (id, time) -> patternForTrip.get(id), @@ -176,7 +175,7 @@ void invalidStopSequence() { private void testVehiclePositions(VehiclePosition pos) { var service = new DefaultRealtimeVehicleService(null); - var trip = TransitModelForTest.trip(tripId).build(); + var trip = TimetableRepositoryForTest.trip(tripId).build(); var stopTimes = List.of( testModel.stopTime(trip, 0), testModel.stopTime(trip, 1), @@ -193,7 +192,7 @@ private void testVehiclePositions(VehiclePosition pos) { // Map positions to trips in feed var matcher = new RealtimeVehiclePatternMatcher( - TransitModelForTest.FEED_ID, + TimetableRepositoryForTest.FEED_ID, tripForId::get, patternForTrip::get, (id, time) -> patternForTrip.get(id), @@ -224,7 +223,7 @@ private void testVehiclePositions(VehiclePosition pos) { private void testVehiclePositionOccupancy(VehiclePosition pos) { var service = new DefaultRealtimeVehicleService(null); - var trip = TransitModelForTest.trip(tripId).build(); + var trip = TimetableRepositoryForTest.trip(tripId).build(); var stopTimes = List.of( testModel.stopTime(trip, 0), testModel.stopTime(trip, 1), @@ -241,7 +240,7 @@ private void testVehiclePositionOccupancy(VehiclePosition pos) { // Map positions to trips in feed RealtimeVehiclePatternMatcher matcher = new RealtimeVehiclePatternMatcher( - TransitModelForTest.FEED_ID, + TimetableRepositoryForTest.FEED_ID, tripForId::get, patternForTrip::get, (id, time) -> patternForTrip.get(id), @@ -267,11 +266,11 @@ public void clearOldTrips() { var tripId1 = "trip1"; var tripId2 = "trip2"; - var scopedTripId1 = TransitModelForTest.id(tripId1); - var scopedTripId2 = TransitModelForTest.id(tripId2); + var scopedTripId1 = TimetableRepositoryForTest.id(tripId1); + var scopedTripId2 = TimetableRepositoryForTest.id(tripId2); - var trip1 = TransitModelForTest.trip(tripId1).build(); - var trip2 = TransitModelForTest.trip(tripId2).build(); + var trip1 = TimetableRepositoryForTest.trip(tripId1).build(); + var trip2 = TimetableRepositoryForTest.trip(tripId2).build(); var stopTimes1 = List.of( testModel.stopTime(trip1, 0), @@ -297,7 +296,7 @@ public void clearOldTrips() { // Map positions to trips in feed RealtimeVehiclePatternMatcher matcher = new RealtimeVehiclePatternMatcher( - TransitModelForTest.FEED_ID, + TimetableRepositoryForTest.FEED_ID, tripForId::get, patternForTrip::get, (id, time) -> patternForTrip.get(id), @@ -337,7 +336,7 @@ static Stream inferenceTestCases() { @ParameterizedTest(name = "{0} should resolve to {1}") @MethodSource("inferenceTestCases") void inferServiceDayOfTripAt6(String time, String expectedDate) { - var trip = TransitModelForTest.trip(tripId).build(); + var trip = TimetableRepositoryForTest.trip(tripId).build(); var sixOclock = (int) Duration.ofHours(18).toSeconds(); var fivePast6 = sixOclock + 300; @@ -357,7 +356,7 @@ void inferServiceDayOfTripAt6(String time, String expectedDate) { @Test void inferServiceDateCloseToMidnight() { - var trip = TransitModelForTest.trip(tripId).build(); + var trip = TimetableRepositoryForTest.trip(tripId).build(); var fiveToMidnight = LocalTime.parse("23:55").toSecondOfDay(); var fivePastMidnight = fiveToMidnight + (10 * 60); @@ -383,10 +382,10 @@ private static TripPattern tripPattern(Trip trip, List stopTimes) { .of(trip.getId()) .withStopPattern(stopPattern) .withRoute(ROUTE) + .withScheduledTimeTableBuilder(builder -> + builder.addTripTimes(TripTimesFactory.tripTimes(trip, stopTimes, new Deduplicator())) + ) .build(); - pattern - .getScheduledTimetable() - .addTripTimes(TripTimesFactory.tripTimes(trip, stopTimes, new Deduplicator())); return pattern; } diff --git a/src/test/java/org/opentripplanner/updater/vehicle_position/VehiclePositionParsingTest.java b/application/src/test/java/org/opentripplanner/updater/vehicle_position/VehiclePositionParsingTest.java similarity index 100% rename from src/test/java/org/opentripplanner/updater/vehicle_position/VehiclePositionParsingTest.java rename to application/src/test/java/org/opentripplanner/updater/vehicle_position/VehiclePositionParsingTest.java diff --git a/src/test/java/org/opentripplanner/updater/vehicle_rental/GeofencingVertexUpdaterTest.java b/application/src/test/java/org/opentripplanner/updater/vehicle_rental/GeofencingVertexUpdaterTest.java similarity index 97% rename from src/test/java/org/opentripplanner/updater/vehicle_rental/GeofencingVertexUpdaterTest.java rename to application/src/test/java/org/opentripplanner/updater/vehicle_rental/GeofencingVertexUpdaterTest.java index 99910e04f7c..4eea85b4dc9 100644 --- a/src/test/java/org/opentripplanner/updater/vehicle_rental/GeofencingVertexUpdaterTest.java +++ b/application/src/test/java/org/opentripplanner/updater/vehicle_rental/GeofencingVertexUpdaterTest.java @@ -4,7 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.opentripplanner.street.model._data.StreetModelForTest.intersectionVertex; import static org.opentripplanner.street.model._data.StreetModelForTest.streetEdge; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id; import java.util.List; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdaterTest.java b/application/src/test/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdaterTest.java similarity index 88% rename from src/test/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdaterTest.java rename to application/src/test/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdaterTest.java index 0016bf4c00c..f48faef3180 100644 --- a/src/test/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdaterTest.java +++ b/application/src/test/java/org/opentripplanner/updater/vehicle_rental/VehicleRentalUpdaterTest.java @@ -9,18 +9,18 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.junit.jupiter.api.Test; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.service.vehiclerental.internal.DefaultVehicleRentalService; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TimetableRepository; import org.opentripplanner.updater.DefaultRealTimeUpdateContext; import org.opentripplanner.updater.GraphUpdaterManager; import org.opentripplanner.updater.GraphWriterRunnable; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.vehicle_rental.datasources.VehicleRentalDatasource; +import org.opentripplanner.updater.vehicle_rental.datasources.params.RentalPickupType; import org.opentripplanner.updater.vehicle_rental.datasources.params.VehicleRentalDataSourceParameters; class VehicleRentalUpdaterTest { @@ -46,7 +46,10 @@ void failingDatasourceCountsAsPrimed() { static class MockManager extends GraphUpdaterManager { public MockManager(VehicleRentalUpdater updater) { - super(new DefaultRealTimeUpdateContext(new Graph(), new TransitModel()), List.of(updater)); + super( + new DefaultRealTimeUpdateContext(new Graph(), new TimetableRepository()), + List.of(updater) + ); } @Override @@ -81,7 +84,6 @@ private boolean hasFailed() { static class FakeParams implements VehicleRentalDataSourceParameters { - @Nonnull @Override public String url() { return "https://example.com"; @@ -93,16 +95,19 @@ public String network() { return "Test"; } - @Nonnull @Override public VehicleRentalSourceType sourceType() { return VehicleRentalSourceType.GBFS; } - @Nonnull @Override public HttpHeaders httpHeaders() { return HttpHeaders.empty(); } + + @Override + public boolean allowRentalType(RentalPickupType rentalPickupType) { + return true; + } } } diff --git a/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoaderTest.java b/application/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoaderTest.java similarity index 100% rename from src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoaderTest.java rename to application/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFeedLoaderTest.java diff --git a/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFreeVehicleStatusMapperTest.java b/application/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFreeVehicleStatusMapperTest.java similarity index 100% rename from src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFreeVehicleStatusMapperTest.java rename to application/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsFreeVehicleStatusMapperTest.java diff --git a/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSourceTest.java b/application/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSourceTest.java similarity index 97% rename from src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSourceTest.java rename to application/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSourceTest.java index 7b062bcc17c..b238b22f305 100644 --- a/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSourceTest.java +++ b/application/src/test/java/org/opentripplanner/updater/vehicle_rental/datasources/GbfsVehicleRentalDataSourceTest.java @@ -16,6 +16,7 @@ import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.vehicle_rental.datasources.params.GbfsVehicleRentalDataSourceParameters; +import org.opentripplanner.updater.vehicle_rental.datasources.params.RentalPickupType; /** * This tests the mapping between data coming from a {@link GbfsFeedLoader} to OTP station models. @@ -32,7 +33,8 @@ void makeStationFromV22() { HttpHeaders.empty(), null, false, - false + false, + RentalPickupType.ALL ), new OtpHttpClientFactory() ); @@ -123,7 +125,8 @@ void geofencing() { HttpHeaders.empty(), null, true, - false + false, + RentalPickupType.ALL ), new OtpHttpClientFactory() ); @@ -165,7 +168,8 @@ void makeStationFromV10() { HttpHeaders.empty(), network, false, - true + true, + RentalPickupType.ALL ), new OtpHttpClientFactory() ); diff --git a/src/test/resources/gbfs/helsinki/gbfs.json b/application/src/test/resources/gbfs/helsinki/gbfs.json similarity index 99% rename from src/test/resources/gbfs/helsinki/gbfs.json rename to application/src/test/resources/gbfs/helsinki/gbfs.json index cad3f88a286..7f4fda298d3 100644 --- a/src/test/resources/gbfs/helsinki/gbfs.json +++ b/application/src/test/resources/gbfs/helsinki/gbfs.json @@ -19,4 +19,4 @@ ] } } -} \ No newline at end of file +} diff --git a/src/test/resources/gbfs/helsinki/station_information.json b/application/src/test/resources/gbfs/helsinki/station_information.json similarity index 99% rename from src/test/resources/gbfs/helsinki/station_information.json rename to application/src/test/resources/gbfs/helsinki/station_information.json index 7b39eb6c096..bb20c0ae1c9 100644 --- a/src/test/resources/gbfs/helsinki/station_information.json +++ b/application/src/test/resources/gbfs/helsinki/station_information.json @@ -75,4 +75,4 @@ } ] } -} \ No newline at end of file +} diff --git a/src/test/resources/gbfs/helsinki/station_status.json b/application/src/test/resources/gbfs/helsinki/station_status.json similarity index 99% rename from src/test/resources/gbfs/helsinki/station_status.json rename to application/src/test/resources/gbfs/helsinki/station_status.json index a97734b8b0b..375043145cc 100644 --- a/src/test/resources/gbfs/helsinki/station_status.json +++ b/application/src/test/resources/gbfs/helsinki/station_status.json @@ -105,4 +105,4 @@ } ] } -} \ No newline at end of file +} diff --git a/src/test/resources/gbfs/helsinki/system_information.json b/application/src/test/resources/gbfs/helsinki/system_information.json similarity index 98% rename from src/test/resources/gbfs/helsinki/system_information.json rename to application/src/test/resources/gbfs/helsinki/system_information.json index 2bb380d81a2..0215fd78268 100644 --- a/src/test/resources/gbfs/helsinki/system_information.json +++ b/application/src/test/resources/gbfs/helsinki/system_information.json @@ -7,4 +7,4 @@ "name": "HSL Bikes Share", "timezone": "Europe/Helsinki" } -} \ No newline at end of file +} diff --git a/src/test/resources/gbfs/lillestrombysykkel/gbfs.json b/application/src/test/resources/gbfs/lillestrombysykkel/gbfs.json similarity index 100% rename from src/test/resources/gbfs/lillestrombysykkel/gbfs.json rename to application/src/test/resources/gbfs/lillestrombysykkel/gbfs.json diff --git a/src/test/resources/gbfs/lillestrombysykkel/station_information.json b/application/src/test/resources/gbfs/lillestrombysykkel/station_information.json similarity index 99% rename from src/test/resources/gbfs/lillestrombysykkel/station_information.json rename to application/src/test/resources/gbfs/lillestrombysykkel/station_information.json index 785a96c3b7a..d65fc587e9d 100644 --- a/src/test/resources/gbfs/lillestrombysykkel/station_information.json +++ b/application/src/test/resources/gbfs/lillestrombysykkel/station_information.json @@ -54,4 +54,4 @@ } ] } -} \ No newline at end of file +} diff --git a/src/test/resources/gbfs/lillestrombysykkel/station_status.json b/application/src/test/resources/gbfs/lillestrombysykkel/station_status.json similarity index 99% rename from src/test/resources/gbfs/lillestrombysykkel/station_status.json rename to application/src/test/resources/gbfs/lillestrombysykkel/station_status.json index 0bd92fb6088..f3cac10ee59 100644 --- a/src/test/resources/gbfs/lillestrombysykkel/station_status.json +++ b/application/src/test/resources/gbfs/lillestrombysykkel/station_status.json @@ -114,4 +114,4 @@ } ] } -} \ No newline at end of file +} diff --git a/src/test/resources/gbfs/lillestrombysykkel/system_information.json b/application/src/test/resources/gbfs/lillestrombysykkel/system_information.json similarity index 99% rename from src/test/resources/gbfs/lillestrombysykkel/system_information.json rename to application/src/test/resources/gbfs/lillestrombysykkel/system_information.json index 0ea3c6a3bbc..f8331cb1f8c 100644 --- a/src/test/resources/gbfs/lillestrombysykkel/system_information.json +++ b/application/src/test/resources/gbfs/lillestrombysykkel/system_information.json @@ -8,4 +8,4 @@ "name": "Lillestrøm bysykkel", "timezone": "Europe/Oslo" } -} \ No newline at end of file +} diff --git a/src/test/resources/gbfs/lillestrombysykkel/system_pricing_plans.json b/application/src/test/resources/gbfs/lillestrombysykkel/system_pricing_plans.json similarity index 99% rename from src/test/resources/gbfs/lillestrombysykkel/system_pricing_plans.json rename to application/src/test/resources/gbfs/lillestrombysykkel/system_pricing_plans.json index 84aba1c609a..82eb22e4e44 100644 --- a/src/test/resources/gbfs/lillestrombysykkel/system_pricing_plans.json +++ b/application/src/test/resources/gbfs/lillestrombysykkel/system_pricing_plans.json @@ -24,4 +24,4 @@ } ] } -} \ No newline at end of file +} diff --git a/src/test/resources/gbfs/lillestrombysykkel/vehicle_types.json b/application/src/test/resources/gbfs/lillestrombysykkel/vehicle_types.json similarity index 99% rename from src/test/resources/gbfs/lillestrombysykkel/vehicle_types.json rename to application/src/test/resources/gbfs/lillestrombysykkel/vehicle_types.json index 834380fd87a..3145a2b1672 100644 --- a/src/test/resources/gbfs/lillestrombysykkel/vehicle_types.json +++ b/application/src/test/resources/gbfs/lillestrombysykkel/vehicle_types.json @@ -11,4 +11,4 @@ } ] } -} \ No newline at end of file +} diff --git a/src/test/resources/gbfs/tieroslo/gbfs.json b/application/src/test/resources/gbfs/tieroslo/gbfs.json similarity index 99% rename from src/test/resources/gbfs/tieroslo/gbfs.json rename to application/src/test/resources/gbfs/tieroslo/gbfs.json index 6ba0c62d3e8..72fd1309db5 100644 --- a/src/test/resources/gbfs/tieroslo/gbfs.json +++ b/application/src/test/resources/gbfs/tieroslo/gbfs.json @@ -16,4 +16,4 @@ ] } } -} \ No newline at end of file +} diff --git a/application/src/test/resources/gbfs/tieroslo/geofencing_zones.json b/application/src/test/resources/gbfs/tieroslo/geofencing_zones.json new file mode 100644 index 00000000000..26700ae9e35 --- /dev/null +++ b/application/src/test/resources/gbfs/tieroslo/geofencing_zones.json @@ -0,0 +1,624 @@ +{ + "last_updated": 1669995505, + "ttl": 0, + "version": "2.3", + "data": { + "geofencing_zones": { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "name": "OSLO Summer 2021", + "rules": [ + { + "vehicle_type_id": [ + "YTI:VehicleType:escooter_oslo", + "YTI:VehicleType:ebicycle_oslo" + ], + "ride_allowed": true, + "ride_through_allowed": true + } + ] + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [10.687577, 59.917346], + [10.689719, 59.91757], + [10.693149, 59.915496], + [10.693549, 59.915603], + [10.695344, 59.915406], + [10.696433, 59.9152], + [10.697358, 59.914945], + [10.703902, 59.910901], + [10.704973, 59.910023], + [10.706125, 59.910367], + [10.708318, 59.90981], + [10.709048, 59.90921], + [10.709194, 59.907373], + [10.709308, 59.906807], + [10.710676, 59.906546], + [10.712482, 59.906047], + [10.715777, 59.906964], + [10.717585, 59.907176], + [10.718362, 59.907068], + [10.720131, 59.906389], + [10.722097, 59.906165], + [10.724074, 59.907995], + [10.725487, 59.908637], + [10.726011, 59.908948], + [10.727579, 59.909715], + [10.729922, 59.910772], + [10.731534, 59.910969], + [10.734022, 59.910463], + [10.734379, 59.909063], + [10.734218, 59.907531], + [10.735753, 59.905218], + [10.738504, 59.903317], + [10.741168, 59.902322], + [10.743451, 59.902637], + [10.744563, 59.903929], + [10.74708, 59.906759], + [10.749004, 59.907773], + [10.751673, 59.907154], + [10.75142, 59.904713], + [10.752924, 59.904548], + [10.753226, 59.904059], + [10.753523, 59.903061], + [10.750778, 59.901725], + [10.752392, 59.900919], + [10.75685, 59.902768], + [10.757897, 59.902216], + [10.75732, 59.901444], + [10.756139, 59.900651], + [10.754918, 59.898621], + [10.754512, 59.897874], + [10.754745, 59.897098], + [10.755141, 59.896554], + [10.755718, 59.895909], + [10.755684, 59.895421], + [10.75486, 59.894861], + [10.75628, 59.894047], + [10.757165221094933, 59.89390175879156], + [10.759106447045964, 59.89147857906161], + [10.761746326879063, 59.88890934390498], + [10.764488740333803, 59.886756017380435], + [10.767790076895182, 59.884918153072604], + [10.768649096133226, 59.883717148821795], + [10.774173632442148, 59.883563457076114], + [10.774906116394662, 59.88327546158081], + [10.774591630458728, 59.88282789499579], + [10.776189, 59.882927], + [10.776783, 59.882649], + [10.778223, 59.88239], + [10.779364, 59.88221], + [10.78106, 59.88226], + [10.78352, 59.881761], + [10.784643, 59.88144], + [10.78564, 59.880914], + [10.786738, 59.880499], + [10.78852, 59.879795], + [10.788919, 59.879665], + [10.789433, 59.879383], + [10.790716, 59.879292], + [10.792192, 59.879244], + [10.799489, 59.879952], + [10.80197, 59.879402], + [10.806901, 59.87959], + [10.810856, 59.880185], + [10.805831, 59.887359], + [10.801735, 59.892648], + [10.803608, 59.894296], + [10.804989, 59.894104], + [10.805318, 59.893477], + [10.80519, 59.892795], + [10.805487, 59.89217], + [10.805705, 59.891759], + [10.806059, 59.891418], + [10.80841, 59.888222], + [10.815093, 59.887873], + [10.821355, 59.890048], + [10.822055, 59.891379], + [10.821592, 59.894541], + [10.820849, 59.897019], + [10.82081, 59.898294], + [10.820285, 59.899129], + [10.820063, 59.900453], + [10.819054, 59.90147], + [10.821037, 59.903571], + [10.821163, 59.903519], + [10.822416, 59.903528], + [10.822439, 59.903451], + [10.823081, 59.903455], + [10.823077, 59.903521], + [10.822077, 59.904421], + [10.822345, 59.904619], + [10.82239, 59.904733], + [10.821725, 59.905312], + [10.820101, 59.907008], + [10.820445, 59.908342], + [10.818684, 59.911458], + [10.818111, 59.912228], + [10.823407, 59.912687], + [10.824883, 59.913119], + [10.822054, 59.914982], + [10.820256, 59.916701], + [10.818784, 59.917621], + [10.818894, 59.917652], + [10.818823, 59.917706], + [10.8184, 59.917827], + [10.818414, 59.917968], + [10.818182, 59.918099], + [10.818195, 59.918179], + [10.818002, 59.918324], + [10.818065, 59.918537], + [10.817746, 59.918747], + [10.817771853184778, 59.919060015777795], + [10.817641535436191, 59.919334313241], + [10.817253369762122, 59.92016471317217], + [10.817067537520016, 59.921261284050956], + [10.817737023934322, 59.922733200931205], + [10.814197529700122, 59.92460810083015], + [10.810978161382877, 59.9264397852684], + [10.812405069001775, 59.92660364907742], + [10.813117506743577, 59.92712347193087], + [10.813882519011425, 59.92802623695317], + [10.81558560488797, 59.92881325879451], + [10.819868304249026, 59.930211473383615], + [10.824304829920784, 59.9316174994396], + [10.83025248260097, 59.93448904912082], + [10.832611785455912, 59.936347545299554], + [10.829367317734333, 59.93953928328541], + [10.819790907558911, 59.940711418196614], + [10.81881548029232, 59.941866346895225], + [10.81031703932274, 59.943246252399135], + [10.802510433894849, 59.94232820122942], + [10.800143, 59.94264], + [10.797091, 59.943181], + [10.794973, 59.947701], + [10.792395, 59.948248], + [10.794348, 59.950349], + [10.795747, 59.9514], + [10.797669, 59.952565], + [10.79768, 59.953333], + [10.793784, 59.95392], + [10.79339, 59.956074], + [10.797104, 59.956691], + [10.795132, 59.959956], + [10.794082, 59.960799], + [10.793441, 59.960794], + [10.791472, 59.960936], + [10.788484, 59.960297], + [10.786342, 59.960273], + [10.784512, 59.96229], + [10.784255, 59.96301], + [10.785606, 59.964267], + [10.785628, 59.965209], + [10.783802, 59.966468], + [10.781205, 59.965769], + [10.780721, 59.966028], + [10.780177, 59.966117], + [10.77965, 59.966055], + [10.778763, 59.965858], + [10.778379, 59.965797], + [10.777944, 59.965853], + [10.777004, 59.966234], + [10.769503, 59.967927], + [10.766244, 59.967631], + [10.765191, 59.965302], + [10.76122, 59.965685], + [10.754526, 59.965425], + [10.751988, 59.9647], + [10.750515, 59.964404], + [10.748898, 59.964421], + [10.746719, 59.964153], + [10.744433, 59.963341], + [10.739722, 59.963308], + [10.737243, 59.963478], + [10.73483, 59.963531], + [10.734494, 59.967231], + [10.73258, 59.968011], + [10.73374, 59.964376], + [10.733217, 59.962427], + [10.734604, 59.961139], + [10.732683, 59.959511], + [10.732454, 59.957576], + [10.732339, 59.956654], + [10.731767, 59.955778], + [10.729022, 59.9544], + [10.727162, 59.953346], + [10.727, 59.952709], + [10.726269, 59.951945], + [10.724372, 59.949613], + [10.722744, 59.948744], + [10.720964, 59.947867], + [10.719147, 59.947458], + [10.716952, 59.947768], + [10.717625, 59.950161], + [10.716953304599347, 59.95123857393473], + [10.716361743887454, 59.951196807911636], + [10.714308, 59.950961], + [10.7123, 59.950721], + [10.711077, 59.950103], + [10.710495, 59.950611], + [10.70858, 59.950256], + [10.706861, 59.949741], + [10.708201, 59.952176], + [10.708676, 59.954882], + [10.708067, 59.95738], + [10.7072, 59.958238], + [10.705126, 59.958376], + [10.703478, 59.958013], + [10.700792, 59.957345], + [10.697309, 59.957191], + [10.695678, 59.955528], + [10.694974, 59.954029], + [10.694844, 59.953168], + [10.693603, 59.952752], + [10.692661, 59.953666], + [10.691528, 59.95491], + [10.690429, 59.956215], + [10.690447, 59.959074], + [10.689576, 59.959484], + [10.685242, 59.959649], + [10.680987, 59.959724], + [10.678302, 59.959411], + [10.676037, 59.958745], + [10.674125216549873, 59.957909368938346], + [10.67322992850205, 59.95743845698356], + [10.672213433099746, 59.957073737876684], + [10.666666, 59.956539], + [10.664284, 59.956772], + [10.662673, 59.956543], + [10.65942, 59.955745], + [10.658216, 59.955569], + [10.654555, 59.956926], + [10.65292, 59.957484], + [10.651637, 59.958384], + [10.651486, 59.959286], + [10.650796, 59.95996], + [10.647778, 59.961542], + [10.64712, 59.962482], + [10.646076, 59.9629], + [10.640822, 59.96219], + [10.639926, 59.961995], + [10.630801, 59.961333], + [10.632761, 59.954949], + [10.634492, 59.952681], + [10.634186, 59.952483], + [10.633764, 59.952135], + [10.634263, 59.951901], + [10.634572, 59.951578], + [10.63479, 59.95062], + [10.635518, 59.949692], + [10.635869, 59.947503], + [10.635935, 59.946419], + [10.636382, 59.945364], + [10.635548, 59.944527], + [10.634821, 59.94371], + [10.633683, 59.943055], + [10.633628, 59.942171], + [10.633083, 59.941489], + [10.63261, 59.940036], + [10.632291, 59.938903], + [10.633838, 59.937789], + [10.634985, 59.936781], + [10.635825, 59.935926], + [10.634147, 59.933758], + [10.633299, 59.93226], + [10.631951, 59.931097], + [10.629841, 59.93033], + [10.627535, 59.929842], + [10.627202, 59.929558], + [10.62783, 59.928948], + [10.62824, 59.928668], + [10.627808, 59.927866], + [10.62595, 59.927039], + [10.625788, 59.926851], + [10.626434, 59.926353], + [10.62701, 59.926144], + [10.627806, 59.925847], + [10.628272, 59.925301], + [10.627081, 59.92463], + [10.626299, 59.924299], + [10.625889, 59.923806], + [10.625752, 59.923353], + [10.625976, 59.922638], + [10.627122, 59.922431], + [10.627907, 59.922338], + [10.628355, 59.922162], + [10.628967, 59.922014], + [10.629751, 59.921695], + [10.630176, 59.921335], + [10.629969, 59.920491], + [10.63008, 59.920209], + [10.630297, 59.91959], + [10.63057, 59.919256], + [10.630619, 59.918453], + [10.631062, 59.918122], + [10.631561, 59.918051], + [10.632437, 59.918529], + [10.632973, 59.918476], + [10.633472, 59.918293], + [10.634406, 59.917735], + [10.634705, 59.917042], + [10.634257, 59.916489], + [10.633487, 59.916275], + [10.63336, 59.916172], + [10.63331, 59.91598], + [10.633315, 59.914699], + [10.634435, 59.914175], + [10.635022, 59.914218], + [10.635022, 59.914623], + [10.635539, 59.914922], + [10.63602, 59.914995], + [10.636347, 59.914927], + [10.638346, 59.914527], + [10.640538, 59.914083], + [10.64214, 59.911986], + [10.64676, 59.91294], + [10.649693, 59.91406], + [10.649041, 59.91244], + [10.65145, 59.912597], + [10.652128, 59.913311], + [10.654842, 59.914189], + [10.656544, 59.914563], + [10.65577, 59.915611], + [10.655881, 59.91591], + [10.657296, 59.916305], + [10.660673, 59.916977], + [10.66344, 59.917713], + [10.664669, 59.917915], + [10.666225, 59.918045], + [10.667923, 59.918365], + [10.671949, 59.919449], + [10.672596, 59.919468], + [10.67297, 59.919106], + [10.67254, 59.918542], + [10.67034, 59.916935], + [10.667644, 59.915772], + [10.666052, 59.91499], + [10.66424, 59.914329], + [10.662968, 59.913975], + [10.662679, 59.912894], + [10.662802, 59.91271], + [10.662855, 59.912525], + [10.662892, 59.912248], + [10.663268, 59.912123], + [10.663674, 59.911903], + [10.663718, 59.911682], + [10.666089, 59.911342], + [10.666437, 59.911073], + [10.666612, 59.910603], + [10.667331, 59.910313], + [10.666122, 59.909331], + [10.665722, 59.908822], + [10.664803, 59.908294], + [10.663568, 59.907353], + [10.664236, 59.90647], + [10.664365, 59.905735], + [10.664373, 59.90399], + [10.664338, 59.902448], + [10.666901, 59.90081], + [10.668391, 59.899236], + [10.668717, 59.898815], + [10.669702, 59.89854], + [10.670936, 59.898469], + [10.671516, 59.89844], + [10.672208, 59.898521], + [10.672678, 59.898752], + [10.673036, 59.898886], + [10.672998, 59.898393], + [10.673574, 59.898072], + [10.674904, 59.898919], + [10.675568, 59.898951], + [10.676719, 59.900216], + [10.677554, 59.900122], + [10.678753, 59.898899], + [10.677605, 59.89743], + [10.677497, 59.896483], + [10.682677, 59.897315], + [10.684746, 59.897508], + [10.685371, 59.898127], + [10.685312, 59.898734], + [10.688495, 59.899716], + [10.694208, 59.901146], + [10.698902, 59.902867], + [10.697001, 59.904053], + [10.692517, 59.902632], + [10.691911, 59.902705], + [10.687294, 59.901715], + [10.686957, 59.902824], + [10.687309, 59.90323], + [10.689902, 59.903918], + [10.693765, 59.90566], + [10.694209, 59.906718], + [10.696105, 59.90734], + [10.695788, 59.907558], + [10.694281, 59.907216], + [10.693907, 59.907558], + [10.693459, 59.907877], + [10.693087, 59.908858], + [10.690732, 59.909233], + [10.691793, 59.909689], + [10.692658, 59.910216], + [10.692771, 59.910641], + [10.693086, 59.910997], + [10.693085, 59.91143], + [10.69305, 59.911802], + [10.692947, 59.912254], + [10.692032, 59.913482], + [10.68968, 59.915085], + [10.687044, 59.915443], + [10.687544, 59.916644], + [10.687577, 59.917346] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "name": "NP Frogner og vigelandsparken", + "rules": [ + { + "vehicle_type_id": [ + "YTI:VehicleType:escooter_oslo", + "YTI:VehicleType:ebicycle_oslo" + ], + "ride_allowed": false, + "ride_through_allowed": true + } + ] + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [10.708611, 59.925037], + [10.710421, 59.926146], + [10.711554, 59.926854], + [10.708529, 59.927892], + [10.707201, 59.92841], + [10.706745, 59.928559], + [10.706106, 59.928492], + [10.706014, 59.928846], + [10.706405, 59.929097], + [10.70664, 59.92958], + [10.706775, 59.929681], + [10.706859, 59.929941], + [10.707147, 59.930235], + [10.70715, 59.930376], + [10.70715, 59.930477], + [10.706916, 59.930666], + [10.706978, 59.930341], + [10.706758, 59.930177], + [10.706167, 59.93003], + [10.705945, 59.930157], + [10.704796, 59.930488], + [10.703563, 59.930424], + [10.701887, 59.930109], + [10.701477, 59.930108], + [10.701197, 59.93012], + [10.700728, 59.930271], + [10.700423, 59.930114], + [10.699743, 59.929839], + [10.698705, 59.929562], + [10.697002, 59.929257], + [10.695299, 59.929069], + [10.693864, 59.9301], + [10.693765, 59.929788], + [10.69312, 59.929715], + [10.692991, 59.929577], + [10.692781, 59.929426], + [10.692649, 59.929149], + [10.690892, 59.928511], + [10.689455, 59.928667], + [10.689256, 59.928503], + [10.688056, 59.928913], + [10.688308, 59.928455], + [10.688322, 59.927437], + [10.6882, 59.92726], + [10.687977, 59.927132], + [10.686372, 59.926403], + [10.685361, 59.925709], + [10.685413, 59.925398], + [10.686845, 59.924708], + [10.687428, 59.924598], + [10.68836, 59.924319], + [10.689365, 59.92514], + [10.690181, 59.924913], + [10.691551, 59.926037], + [10.691175, 59.926257], + [10.691406, 59.926521], + [10.691672, 59.926558], + [10.691904, 59.92651], + [10.691996, 59.926328], + [10.692174, 59.926046], + [10.692962, 59.925435], + [10.695119, 59.925454], + [10.695092, 59.926223], + [10.696203, 59.927011], + [10.697195, 59.927393], + [10.697659, 59.927373], + [10.697755, 59.927388], + [10.697895, 59.927363], + [10.697938, 59.927109], + [10.697925, 59.926836], + [10.698022, 59.926771], + [10.698009, 59.926638], + [10.698007, 59.926075], + [10.697944, 59.925487], + [10.698123, 59.925005], + [10.698141, 59.924788], + [10.697858, 59.924587], + [10.697884, 59.924382], + [10.69796, 59.924008], + [10.697985, 59.923959], + [10.697985, 59.923924], + [10.697971, 59.923892], + [10.698013, 59.923875], + [10.698029, 59.923859], + [10.698038, 59.923818], + [10.69804, 59.923801], + [10.698029, 59.92378], + [10.698014, 59.923748], + [10.697866, 59.92372], + [10.69693, 59.923741], + [10.695022, 59.923042], + [10.693212, 59.922751], + [10.69208, 59.922151], + [10.690058, 59.921156], + [10.691843, 59.920241], + [10.69467, 59.921056], + [10.695619, 59.921537], + [10.696359, 59.922142], + [10.697861, 59.923276], + [10.69825, 59.923495], + [10.698502, 59.923519], + [10.6986, 59.92353], + [10.698673, 59.923527], + [10.698737, 59.923521], + [10.698789, 59.92351], + [10.698868, 59.92348], + [10.699029, 59.923386], + [10.699408, 59.923512], + [10.699998, 59.923536], + [10.700497, 59.923551], + [10.700976, 59.923514], + [10.701528, 59.923438], + [10.702418, 59.923253], + [10.703044, 59.923132], + [10.703605, 59.923008], + [10.704098, 59.922928], + [10.704186, 59.922934], + [10.704307, 59.922921], + [10.704602, 59.922899], + [10.70489, 59.922898], + [10.705659, 59.923388], + [10.706335, 59.923788], + [10.706632, 59.92394], + [10.707189, 59.924234], + [10.70738, 59.924331], + [10.707741, 59.924549], + [10.707929, 59.924627], + [10.708104, 59.924722], + [10.708288, 59.924831], + [10.708416, 59.924911], + [10.708509, 59.924953], + [10.70854, 59.92499], + [10.708611, 59.925037] + ] + ] + ] + } + } + ] + } + } +} diff --git a/src/test/resources/gbfs/tieroslo/system_information.json b/application/src/test/resources/gbfs/tieroslo/system_information.json similarity index 99% rename from src/test/resources/gbfs/tieroslo/system_information.json rename to application/src/test/resources/gbfs/tieroslo/system_information.json index e3227e3f8f0..b8d6e9eea50 100644 --- a/src/test/resources/gbfs/tieroslo/system_information.json +++ b/application/src/test/resources/gbfs/tieroslo/system_information.json @@ -19,4 +19,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/test/resources/gtfs/caltrain_gtfs.zip b/application/src/test/resources/gtfs/caltrain_gtfs.zip similarity index 100% rename from src/test/resources/gtfs/caltrain_gtfs.zip rename to application/src/test/resources/gtfs/caltrain_gtfs.zip diff --git a/src/test/resources/gtfs/interlining/agency.txt b/application/src/test/resources/gtfs/interlining/agency.txt similarity index 100% rename from src/test/resources/gtfs/interlining/agency.txt rename to application/src/test/resources/gtfs/interlining/agency.txt diff --git a/src/test/resources/gtfs/interlining/calendar_dates.txt b/application/src/test/resources/gtfs/interlining/calendar_dates.txt similarity index 100% rename from src/test/resources/gtfs/interlining/calendar_dates.txt rename to application/src/test/resources/gtfs/interlining/calendar_dates.txt diff --git a/src/test/resources/gtfs/interlining/description.txt b/application/src/test/resources/gtfs/interlining/description.txt similarity index 100% rename from src/test/resources/gtfs/interlining/description.txt rename to application/src/test/resources/gtfs/interlining/description.txt diff --git a/src/test/resources/gtfs/interlining/routes.txt b/application/src/test/resources/gtfs/interlining/routes.txt similarity index 100% rename from src/test/resources/gtfs/interlining/routes.txt rename to application/src/test/resources/gtfs/interlining/routes.txt diff --git a/src/test/resources/gtfs/interlining/stop_times.txt b/application/src/test/resources/gtfs/interlining/stop_times.txt similarity index 100% rename from src/test/resources/gtfs/interlining/stop_times.txt rename to application/src/test/resources/gtfs/interlining/stop_times.txt diff --git a/src/test/resources/gtfs/interlining/stops.txt b/application/src/test/resources/gtfs/interlining/stops.txt similarity index 100% rename from src/test/resources/gtfs/interlining/stops.txt rename to application/src/test/resources/gtfs/interlining/stops.txt diff --git a/src/test/resources/gtfs/interlining/transfers.txt b/application/src/test/resources/gtfs/interlining/transfers.txt similarity index 100% rename from src/test/resources/gtfs/interlining/transfers.txt rename to application/src/test/resources/gtfs/interlining/transfers.txt diff --git a/src/test/resources/gtfs/interlining/trips.txt b/application/src/test/resources/gtfs/interlining/trips.txt similarity index 100% rename from src/test/resources/gtfs/interlining/trips.txt rename to application/src/test/resources/gtfs/interlining/trips.txt diff --git a/src/test/resources/gtfs/shape_dist_traveled/agency.txt b/application/src/test/resources/gtfs/shape_dist_traveled/agency.txt similarity index 100% rename from src/test/resources/gtfs/shape_dist_traveled/agency.txt rename to application/src/test/resources/gtfs/shape_dist_traveled/agency.txt diff --git a/src/test/resources/gtfs/shape_dist_traveled/calendar.txt b/application/src/test/resources/gtfs/shape_dist_traveled/calendar.txt similarity index 100% rename from src/test/resources/gtfs/shape_dist_traveled/calendar.txt rename to application/src/test/resources/gtfs/shape_dist_traveled/calendar.txt diff --git a/src/test/resources/gtfs/shape_dist_traveled/routes.txt b/application/src/test/resources/gtfs/shape_dist_traveled/routes.txt similarity index 100% rename from src/test/resources/gtfs/shape_dist_traveled/routes.txt rename to application/src/test/resources/gtfs/shape_dist_traveled/routes.txt diff --git a/src/test/resources/gtfs/shape_dist_traveled/shapes.txt b/application/src/test/resources/gtfs/shape_dist_traveled/shapes.txt similarity index 100% rename from src/test/resources/gtfs/shape_dist_traveled/shapes.txt rename to application/src/test/resources/gtfs/shape_dist_traveled/shapes.txt diff --git a/src/test/resources/gtfs/shape_dist_traveled/stop_times.txt b/application/src/test/resources/gtfs/shape_dist_traveled/stop_times.txt similarity index 100% rename from src/test/resources/gtfs/shape_dist_traveled/stop_times.txt rename to application/src/test/resources/gtfs/shape_dist_traveled/stop_times.txt diff --git a/src/test/resources/gtfs/shape_dist_traveled/stops.txt b/application/src/test/resources/gtfs/shape_dist_traveled/stops.txt similarity index 100% rename from src/test/resources/gtfs/shape_dist_traveled/stops.txt rename to application/src/test/resources/gtfs/shape_dist_traveled/stops.txt diff --git a/src/test/resources/gtfs/shape_dist_traveled/trips.txt b/application/src/test/resources/gtfs/shape_dist_traveled/trips.txt similarity index 100% rename from src/test/resources/gtfs/shape_dist_traveled/trips.txt rename to application/src/test/resources/gtfs/shape_dist_traveled/trips.txt diff --git a/src/test/resources/gtfs/simple/agency.txt b/application/src/test/resources/gtfs/simple/agency.txt similarity index 100% rename from src/test/resources/gtfs/simple/agency.txt rename to application/src/test/resources/gtfs/simple/agency.txt diff --git a/src/test/resources/gtfs/simple/calendar.txt b/application/src/test/resources/gtfs/simple/calendar.txt similarity index 100% rename from src/test/resources/gtfs/simple/calendar.txt rename to application/src/test/resources/gtfs/simple/calendar.txt diff --git a/src/test/resources/gtfs/simple/frequencies.txt b/application/src/test/resources/gtfs/simple/frequencies.txt similarity index 100% rename from src/test/resources/gtfs/simple/frequencies.txt rename to application/src/test/resources/gtfs/simple/frequencies.txt diff --git a/src/test/resources/gtfs/simple/pathways.txt b/application/src/test/resources/gtfs/simple/pathways.txt similarity index 100% rename from src/test/resources/gtfs/simple/pathways.txt rename to application/src/test/resources/gtfs/simple/pathways.txt diff --git a/src/test/resources/gtfs/simple/routes.txt b/application/src/test/resources/gtfs/simple/routes.txt similarity index 62% rename from src/test/resources/gtfs/simple/routes.txt rename to application/src/test/resources/gtfs/simple/routes.txt index ba2bb397941..2957341851e 100755 --- a/src/test/resources/gtfs/simple/routes.txt +++ b/application/src/test/resources/gtfs/simple/routes.txt @@ -1,13 +1,13 @@ -route_id,route_short_name,route_long_name,route_type,route_bikes_allowed -1,1,1,3,2 -2,2,2,3,1 +route_id,route_short_name,route_long_name,route_type,bikes_allowed +1,1,1,3,1 +2,2,2,3,2 3,3,3,3, 4,4,4,7, 5,5,5,2, 6,6,6,2, 7,7,7,2, 8,8,8,3, -9,9,9,2,2 +9,9,9,2,1 10,10,10,2, 11,11,11,2, 12,12,12,2, diff --git a/src/test/resources/gtfs/simple/shapes.txt b/application/src/test/resources/gtfs/simple/shapes.txt similarity index 100% rename from src/test/resources/gtfs/simple/shapes.txt rename to application/src/test/resources/gtfs/simple/shapes.txt diff --git a/src/test/resources/gtfs/simple/stop_times.txt b/application/src/test/resources/gtfs/simple/stop_times.txt similarity index 100% rename from src/test/resources/gtfs/simple/stop_times.txt rename to application/src/test/resources/gtfs/simple/stop_times.txt diff --git a/src/test/resources/gtfs/simple/stops.txt b/application/src/test/resources/gtfs/simple/stops.txt similarity index 100% rename from src/test/resources/gtfs/simple/stops.txt rename to application/src/test/resources/gtfs/simple/stops.txt diff --git a/src/test/resources/gtfs/simple/transfers.txt b/application/src/test/resources/gtfs/simple/transfers.txt similarity index 100% rename from src/test/resources/gtfs/simple/transfers.txt rename to application/src/test/resources/gtfs/simple/transfers.txt diff --git a/src/test/resources/gtfs/simple/trips.txt b/application/src/test/resources/gtfs/simple/trips.txt similarity index 87% rename from src/test/resources/gtfs/simple/trips.txt rename to application/src/test/resources/gtfs/simple/trips.txt index d18b02d6896..ca826df2c5c 100755 --- a/src/test/resources/gtfs/simple/trips.txt +++ b/application/src/test/resources/gtfs/simple/trips.txt @@ -1,9 +1,9 @@ -route_id,service_id,trip_id,shape_id,block_id,wheelchair_accessible,trip_bikes_allowed,direction_id,trip_headsign +route_id,service_id,trip_id,shape_id,block_id,wheelchair_accessible,bikes_allowed,direction_id,trip_headsign 1,alldays,1.1,,,1,,,foo 1,alldays,1.2,,,1,,,foo 1,alldays,1.3,,,1,,,foo -2,alldays,2.1,,,0,2,,foo -2,alldays,2.2,,,0,2,,foo +2,alldays,2.1,,,0,1,,foo +2,alldays,2.2,,,0,1,,foo 3,alldays,3.1,,,1,,,foo 3,alldays,3.2,,,1,,,foo 4,weekdays,4.1,4,,,,,foo @@ -15,7 +15,7 @@ route_id,service_id,trip_id,shape_id,block_id,wheelchair_accessible,trip_bikes_a 6,alldays,6.2,,block.2,,,,foo 7,alldays,7.2,,block.2,,,,foo 8,alldays,8.1,,block.2,,,,foo -9,alldays,9.1,,,,1,,foo +9,alldays,9.1,,,,2,,foo 10,alldays,10.1,,,,,,foo 10,alldays,10.2,,,,,,foo 10,alldays,10.3,,,,,,foo diff --git a/src/test/resources/gtfs/stopgen.py b/application/src/test/resources/gtfs/stopgen.py similarity index 100% rename from src/test/resources/gtfs/stopgen.py rename to application/src/test/resources/gtfs/stopgen.py diff --git a/src/test/resources/logback.xml b/application/src/test/resources/logback.xml similarity index 100% rename from src/test/resources/logback.xml rename to application/src/test/resources/logback.xml diff --git a/src/test/resources/mmri/1g/agency.txt b/application/src/test/resources/mmri/1g/agency.txt similarity index 100% rename from src/test/resources/mmri/1g/agency.txt rename to application/src/test/resources/mmri/1g/agency.txt diff --git a/src/test/resources/mmri/1g/calendar_dates.txt b/application/src/test/resources/mmri/1g/calendar_dates.txt similarity index 100% rename from src/test/resources/mmri/1g/calendar_dates.txt rename to application/src/test/resources/mmri/1g/calendar_dates.txt diff --git a/src/test/resources/mmri/1g/routes.txt b/application/src/test/resources/mmri/1g/routes.txt similarity index 100% rename from src/test/resources/mmri/1g/routes.txt rename to application/src/test/resources/mmri/1g/routes.txt diff --git a/src/test/resources/mmri/1g/stop_times.txt b/application/src/test/resources/mmri/1g/stop_times.txt similarity index 100% rename from src/test/resources/mmri/1g/stop_times.txt rename to application/src/test/resources/mmri/1g/stop_times.txt diff --git a/src/test/resources/mmri/1g/stops.txt b/application/src/test/resources/mmri/1g/stops.txt similarity index 100% rename from src/test/resources/mmri/1g/stops.txt rename to application/src/test/resources/mmri/1g/stops.txt diff --git a/src/test/resources/mmri/1g/trips.txt b/application/src/test/resources/mmri/1g/trips.txt similarity index 100% rename from src/test/resources/mmri/1g/trips.txt rename to application/src/test/resources/mmri/1g/trips.txt diff --git a/src/test/resources/mmri/2a1/agency.txt b/application/src/test/resources/mmri/2a1/agency.txt similarity index 100% rename from src/test/resources/mmri/2a1/agency.txt rename to application/src/test/resources/mmri/2a1/agency.txt diff --git a/src/test/resources/mmri/2a1/calendar_dates.txt b/application/src/test/resources/mmri/2a1/calendar_dates.txt similarity index 100% rename from src/test/resources/mmri/2a1/calendar_dates.txt rename to application/src/test/resources/mmri/2a1/calendar_dates.txt diff --git a/src/test/resources/mmri/2a1/routes.txt b/application/src/test/resources/mmri/2a1/routes.txt similarity index 100% rename from src/test/resources/mmri/2a1/routes.txt rename to application/src/test/resources/mmri/2a1/routes.txt diff --git a/src/test/resources/mmri/2a1/stop_times.txt b/application/src/test/resources/mmri/2a1/stop_times.txt similarity index 100% rename from src/test/resources/mmri/2a1/stop_times.txt rename to application/src/test/resources/mmri/2a1/stop_times.txt diff --git a/src/test/resources/mmri/2a1/stops.txt b/application/src/test/resources/mmri/2a1/stops.txt similarity index 100% rename from src/test/resources/mmri/2a1/stops.txt rename to application/src/test/resources/mmri/2a1/stops.txt diff --git a/src/test/resources/mmri/2a1/trips.txt b/application/src/test/resources/mmri/2a1/trips.txt similarity index 100% rename from src/test/resources/mmri/2a1/trips.txt rename to application/src/test/resources/mmri/2a1/trips.txt diff --git a/src/test/resources/mmri/2b/agency.txt b/application/src/test/resources/mmri/2b/agency.txt similarity index 100% rename from src/test/resources/mmri/2b/agency.txt rename to application/src/test/resources/mmri/2b/agency.txt diff --git a/src/test/resources/mmri/2b/calendar_dates.txt b/application/src/test/resources/mmri/2b/calendar_dates.txt similarity index 100% rename from src/test/resources/mmri/2b/calendar_dates.txt rename to application/src/test/resources/mmri/2b/calendar_dates.txt diff --git a/src/test/resources/mmri/2b/routes.txt b/application/src/test/resources/mmri/2b/routes.txt similarity index 100% rename from src/test/resources/mmri/2b/routes.txt rename to application/src/test/resources/mmri/2b/routes.txt diff --git a/src/test/resources/mmri/2b/stop_times.txt b/application/src/test/resources/mmri/2b/stop_times.txt similarity index 100% rename from src/test/resources/mmri/2b/stop_times.txt rename to application/src/test/resources/mmri/2b/stop_times.txt diff --git a/src/test/resources/mmri/2b/stops.txt b/application/src/test/resources/mmri/2b/stops.txt similarity index 100% rename from src/test/resources/mmri/2b/stops.txt rename to application/src/test/resources/mmri/2b/stops.txt diff --git a/src/test/resources/mmri/2b/trips.txt b/application/src/test/resources/mmri/2b/trips.txt similarity index 100% rename from src/test/resources/mmri/2b/trips.txt rename to application/src/test/resources/mmri/2b/trips.txt diff --git a/src/test/resources/mmri/2c/agency.txt b/application/src/test/resources/mmri/2c/agency.txt similarity index 100% rename from src/test/resources/mmri/2c/agency.txt rename to application/src/test/resources/mmri/2c/agency.txt diff --git a/src/test/resources/mmri/2c/calendar_dates.txt b/application/src/test/resources/mmri/2c/calendar_dates.txt similarity index 100% rename from src/test/resources/mmri/2c/calendar_dates.txt rename to application/src/test/resources/mmri/2c/calendar_dates.txt diff --git a/src/test/resources/mmri/2c/routes.txt b/application/src/test/resources/mmri/2c/routes.txt similarity index 100% rename from src/test/resources/mmri/2c/routes.txt rename to application/src/test/resources/mmri/2c/routes.txt diff --git a/src/test/resources/mmri/2c/stop_times.txt b/application/src/test/resources/mmri/2c/stop_times.txt similarity index 100% rename from src/test/resources/mmri/2c/stop_times.txt rename to application/src/test/resources/mmri/2c/stop_times.txt diff --git a/src/test/resources/mmri/2c/stops.txt b/application/src/test/resources/mmri/2c/stops.txt similarity index 100% rename from src/test/resources/mmri/2c/stops.txt rename to application/src/test/resources/mmri/2c/stops.txt diff --git a/src/test/resources/mmri/2c/transfers.txt b/application/src/test/resources/mmri/2c/transfers.txt similarity index 100% rename from src/test/resources/mmri/2c/transfers.txt rename to application/src/test/resources/mmri/2c/transfers.txt diff --git a/src/test/resources/mmri/2c/trips.txt b/application/src/test/resources/mmri/2c/trips.txt similarity index 100% rename from src/test/resources/mmri/2c/trips.txt rename to application/src/test/resources/mmri/2c/trips.txt diff --git a/src/test/resources/mmri/2d/agency.txt b/application/src/test/resources/mmri/2d/agency.txt similarity index 100% rename from src/test/resources/mmri/2d/agency.txt rename to application/src/test/resources/mmri/2d/agency.txt diff --git a/src/test/resources/mmri/2d/calendar_dates.txt b/application/src/test/resources/mmri/2d/calendar_dates.txt similarity index 100% rename from src/test/resources/mmri/2d/calendar_dates.txt rename to application/src/test/resources/mmri/2d/calendar_dates.txt diff --git a/src/test/resources/mmri/2d/routes.txt b/application/src/test/resources/mmri/2d/routes.txt similarity index 100% rename from src/test/resources/mmri/2d/routes.txt rename to application/src/test/resources/mmri/2d/routes.txt diff --git a/src/test/resources/mmri/2d/stop_times.txt b/application/src/test/resources/mmri/2d/stop_times.txt similarity index 100% rename from src/test/resources/mmri/2d/stop_times.txt rename to application/src/test/resources/mmri/2d/stop_times.txt diff --git a/src/test/resources/mmri/2d/stops.txt b/application/src/test/resources/mmri/2d/stops.txt similarity index 100% rename from src/test/resources/mmri/2d/stops.txt rename to application/src/test/resources/mmri/2d/stops.txt diff --git a/src/test/resources/mmri/2d/transfers.txt b/application/src/test/resources/mmri/2d/transfers.txt similarity index 100% rename from src/test/resources/mmri/2d/transfers.txt rename to application/src/test/resources/mmri/2d/transfers.txt diff --git a/src/test/resources/mmri/2d/trips.txt b/application/src/test/resources/mmri/2d/trips.txt similarity index 100% rename from src/test/resources/mmri/2d/trips.txt rename to application/src/test/resources/mmri/2d/trips.txt diff --git a/src/test/resources/mmri/2e1/agency.txt b/application/src/test/resources/mmri/2e1/agency.txt similarity index 100% rename from src/test/resources/mmri/2e1/agency.txt rename to application/src/test/resources/mmri/2e1/agency.txt diff --git a/src/test/resources/mmri/2e1/calendar_dates.txt b/application/src/test/resources/mmri/2e1/calendar_dates.txt similarity index 100% rename from src/test/resources/mmri/2e1/calendar_dates.txt rename to application/src/test/resources/mmri/2e1/calendar_dates.txt diff --git a/src/test/resources/mmri/2e1/routes.txt b/application/src/test/resources/mmri/2e1/routes.txt similarity index 100% rename from src/test/resources/mmri/2e1/routes.txt rename to application/src/test/resources/mmri/2e1/routes.txt diff --git a/src/test/resources/mmri/2e1/stop_times.txt b/application/src/test/resources/mmri/2e1/stop_times.txt similarity index 100% rename from src/test/resources/mmri/2e1/stop_times.txt rename to application/src/test/resources/mmri/2e1/stop_times.txt diff --git a/src/test/resources/mmri/2e1/stops.txt b/application/src/test/resources/mmri/2e1/stops.txt similarity index 100% rename from src/test/resources/mmri/2e1/stops.txt rename to application/src/test/resources/mmri/2e1/stops.txt diff --git a/src/test/resources/mmri/2e1/transfers.txt b/application/src/test/resources/mmri/2e1/transfers.txt similarity index 100% rename from src/test/resources/mmri/2e1/transfers.txt rename to application/src/test/resources/mmri/2e1/transfers.txt diff --git a/src/test/resources/mmri/2e1/trips.txt b/application/src/test/resources/mmri/2e1/trips.txt similarity index 100% rename from src/test/resources/mmri/2e1/trips.txt rename to application/src/test/resources/mmri/2e1/trips.txt diff --git a/src/test/resources/mmri/2e2/agency.txt b/application/src/test/resources/mmri/2e2/agency.txt similarity index 100% rename from src/test/resources/mmri/2e2/agency.txt rename to application/src/test/resources/mmri/2e2/agency.txt diff --git a/src/test/resources/mmri/2e2/calendar_dates.txt b/application/src/test/resources/mmri/2e2/calendar_dates.txt similarity index 100% rename from src/test/resources/mmri/2e2/calendar_dates.txt rename to application/src/test/resources/mmri/2e2/calendar_dates.txt diff --git a/src/test/resources/mmri/2e2/routes.txt b/application/src/test/resources/mmri/2e2/routes.txt similarity index 100% rename from src/test/resources/mmri/2e2/routes.txt rename to application/src/test/resources/mmri/2e2/routes.txt diff --git a/src/test/resources/mmri/2e2/stop_times.txt b/application/src/test/resources/mmri/2e2/stop_times.txt similarity index 100% rename from src/test/resources/mmri/2e2/stop_times.txt rename to application/src/test/resources/mmri/2e2/stop_times.txt diff --git a/src/test/resources/mmri/2e2/stops.txt b/application/src/test/resources/mmri/2e2/stops.txt similarity index 100% rename from src/test/resources/mmri/2e2/stops.txt rename to application/src/test/resources/mmri/2e2/stops.txt diff --git a/src/test/resources/mmri/2e2/transfers.txt b/application/src/test/resources/mmri/2e2/transfers.txt similarity index 100% rename from src/test/resources/mmri/2e2/transfers.txt rename to application/src/test/resources/mmri/2e2/transfers.txt diff --git a/src/test/resources/mmri/2e2/trips.txt b/application/src/test/resources/mmri/2e2/trips.txt similarity index 100% rename from src/test/resources/mmri/2e2/trips.txt rename to application/src/test/resources/mmri/2e2/trips.txt diff --git a/src/test/resources/mmri/2e3/agency.txt b/application/src/test/resources/mmri/2e3/agency.txt similarity index 100% rename from src/test/resources/mmri/2e3/agency.txt rename to application/src/test/resources/mmri/2e3/agency.txt diff --git a/src/test/resources/mmri/2e3/calendar_dates.txt b/application/src/test/resources/mmri/2e3/calendar_dates.txt similarity index 100% rename from src/test/resources/mmri/2e3/calendar_dates.txt rename to application/src/test/resources/mmri/2e3/calendar_dates.txt diff --git a/src/test/resources/mmri/2e3/routes.txt b/application/src/test/resources/mmri/2e3/routes.txt similarity index 100% rename from src/test/resources/mmri/2e3/routes.txt rename to application/src/test/resources/mmri/2e3/routes.txt diff --git a/src/test/resources/mmri/2e3/stop_times.txt b/application/src/test/resources/mmri/2e3/stop_times.txt similarity index 100% rename from src/test/resources/mmri/2e3/stop_times.txt rename to application/src/test/resources/mmri/2e3/stop_times.txt diff --git a/src/test/resources/mmri/2e3/stops.txt b/application/src/test/resources/mmri/2e3/stops.txt similarity index 100% rename from src/test/resources/mmri/2e3/stops.txt rename to application/src/test/resources/mmri/2e3/stops.txt diff --git a/src/test/resources/mmri/2e3/transfers.txt b/application/src/test/resources/mmri/2e3/transfers.txt similarity index 100% rename from src/test/resources/mmri/2e3/transfers.txt rename to application/src/test/resources/mmri/2e3/transfers.txt diff --git a/src/test/resources/mmri/2e3/trips.txt b/application/src/test/resources/mmri/2e3/trips.txt similarity index 100% rename from src/test/resources/mmri/2e3/trips.txt rename to application/src/test/resources/mmri/2e3/trips.txt diff --git a/src/test/resources/mmri/2e4/agency.txt b/application/src/test/resources/mmri/2e4/agency.txt similarity index 100% rename from src/test/resources/mmri/2e4/agency.txt rename to application/src/test/resources/mmri/2e4/agency.txt diff --git a/src/test/resources/mmri/2e4/calendar_dates.txt b/application/src/test/resources/mmri/2e4/calendar_dates.txt similarity index 100% rename from src/test/resources/mmri/2e4/calendar_dates.txt rename to application/src/test/resources/mmri/2e4/calendar_dates.txt diff --git a/src/test/resources/mmri/2e4/routes.txt b/application/src/test/resources/mmri/2e4/routes.txt similarity index 100% rename from src/test/resources/mmri/2e4/routes.txt rename to application/src/test/resources/mmri/2e4/routes.txt diff --git a/src/test/resources/mmri/2e4/stop_times.txt b/application/src/test/resources/mmri/2e4/stop_times.txt similarity index 100% rename from src/test/resources/mmri/2e4/stop_times.txt rename to application/src/test/resources/mmri/2e4/stop_times.txt diff --git a/src/test/resources/mmri/2e4/stops.txt b/application/src/test/resources/mmri/2e4/stops.txt similarity index 100% rename from src/test/resources/mmri/2e4/stops.txt rename to application/src/test/resources/mmri/2e4/stops.txt diff --git a/src/test/resources/mmri/2e4/transfers.txt b/application/src/test/resources/mmri/2e4/transfers.txt similarity index 100% rename from src/test/resources/mmri/2e4/transfers.txt rename to application/src/test/resources/mmri/2e4/transfers.txt diff --git a/src/test/resources/mmri/2e4/trips.txt b/application/src/test/resources/mmri/2e4/trips.txt similarity index 100% rename from src/test/resources/mmri/2e4/trips.txt rename to application/src/test/resources/mmri/2e4/trips.txt diff --git a/src/test/resources/mmri/3b.pb b/application/src/test/resources/mmri/3b.pb similarity index 100% rename from src/test/resources/mmri/3b.pb rename to application/src/test/resources/mmri/3b.pb diff --git a/src/test/resources/mmri/3b/agency.txt b/application/src/test/resources/mmri/3b/agency.txt similarity index 100% rename from src/test/resources/mmri/3b/agency.txt rename to application/src/test/resources/mmri/3b/agency.txt diff --git a/src/test/resources/mmri/3b/calendar_dates.txt b/application/src/test/resources/mmri/3b/calendar_dates.txt similarity index 100% rename from src/test/resources/mmri/3b/calendar_dates.txt rename to application/src/test/resources/mmri/3b/calendar_dates.txt diff --git a/src/test/resources/mmri/3b/routes.txt b/application/src/test/resources/mmri/3b/routes.txt similarity index 100% rename from src/test/resources/mmri/3b/routes.txt rename to application/src/test/resources/mmri/3b/routes.txt diff --git a/src/test/resources/mmri/3b/stop_times.txt b/application/src/test/resources/mmri/3b/stop_times.txt similarity index 100% rename from src/test/resources/mmri/3b/stop_times.txt rename to application/src/test/resources/mmri/3b/stop_times.txt diff --git a/src/test/resources/mmri/3b/stops.txt b/application/src/test/resources/mmri/3b/stops.txt similarity index 100% rename from src/test/resources/mmri/3b/stops.txt rename to application/src/test/resources/mmri/3b/stops.txt diff --git a/src/test/resources/mmri/3b/trips.txt b/application/src/test/resources/mmri/3b/trips.txt similarity index 100% rename from src/test/resources/mmri/3b/trips.txt rename to application/src/test/resources/mmri/3b/trips.txt diff --git a/src/test/resources/mmri/3c.pb b/application/src/test/resources/mmri/3c.pb similarity index 100% rename from src/test/resources/mmri/3c.pb rename to application/src/test/resources/mmri/3c.pb diff --git a/src/test/resources/mmri/3c/agency.txt b/application/src/test/resources/mmri/3c/agency.txt similarity index 100% rename from src/test/resources/mmri/3c/agency.txt rename to application/src/test/resources/mmri/3c/agency.txt diff --git a/src/test/resources/mmri/3c/calendar_dates.txt b/application/src/test/resources/mmri/3c/calendar_dates.txt similarity index 100% rename from src/test/resources/mmri/3c/calendar_dates.txt rename to application/src/test/resources/mmri/3c/calendar_dates.txt diff --git a/src/test/resources/mmri/3c/routes.txt b/application/src/test/resources/mmri/3c/routes.txt similarity index 100% rename from src/test/resources/mmri/3c/routes.txt rename to application/src/test/resources/mmri/3c/routes.txt diff --git a/src/test/resources/mmri/3c/stop_times.txt b/application/src/test/resources/mmri/3c/stop_times.txt similarity index 100% rename from src/test/resources/mmri/3c/stop_times.txt rename to application/src/test/resources/mmri/3c/stop_times.txt diff --git a/src/test/resources/mmri/3c/stops.txt b/application/src/test/resources/mmri/3c/stops.txt similarity index 100% rename from src/test/resources/mmri/3c/stops.txt rename to application/src/test/resources/mmri/3c/stops.txt diff --git a/src/test/resources/mmri/3c/trips.txt b/application/src/test/resources/mmri/3c/trips.txt similarity index 100% rename from src/test/resources/mmri/3c/trips.txt rename to application/src/test/resources/mmri/3c/trips.txt diff --git a/src/test/resources/mmri/3d/agency.txt b/application/src/test/resources/mmri/3d/agency.txt similarity index 100% rename from src/test/resources/mmri/3d/agency.txt rename to application/src/test/resources/mmri/3d/agency.txt diff --git a/src/test/resources/mmri/3d/calendar_dates.txt b/application/src/test/resources/mmri/3d/calendar_dates.txt similarity index 100% rename from src/test/resources/mmri/3d/calendar_dates.txt rename to application/src/test/resources/mmri/3d/calendar_dates.txt diff --git a/src/test/resources/mmri/3d/routes.txt b/application/src/test/resources/mmri/3d/routes.txt similarity index 100% rename from src/test/resources/mmri/3d/routes.txt rename to application/src/test/resources/mmri/3d/routes.txt diff --git a/src/test/resources/mmri/3d/stop_times.txt b/application/src/test/resources/mmri/3d/stop_times.txt similarity index 100% rename from src/test/resources/mmri/3d/stop_times.txt rename to application/src/test/resources/mmri/3d/stop_times.txt diff --git a/src/test/resources/mmri/3d/stops.txt b/application/src/test/resources/mmri/3d/stops.txt similarity index 100% rename from src/test/resources/mmri/3d/stops.txt rename to application/src/test/resources/mmri/3d/stops.txt diff --git a/src/test/resources/mmri/3d/trips.txt b/application/src/test/resources/mmri/3d/trips.txt similarity index 100% rename from src/test/resources/mmri/3d/trips.txt rename to application/src/test/resources/mmri/3d/trips.txt diff --git a/src/test/resources/mmri/3e.pb b/application/src/test/resources/mmri/3e.pb similarity index 100% rename from src/test/resources/mmri/3e.pb rename to application/src/test/resources/mmri/3e.pb diff --git a/src/test/resources/mmri/3e/agency.txt b/application/src/test/resources/mmri/3e/agency.txt similarity index 100% rename from src/test/resources/mmri/3e/agency.txt rename to application/src/test/resources/mmri/3e/agency.txt diff --git a/src/test/resources/mmri/3e/calendar_dates.txt b/application/src/test/resources/mmri/3e/calendar_dates.txt similarity index 100% rename from src/test/resources/mmri/3e/calendar_dates.txt rename to application/src/test/resources/mmri/3e/calendar_dates.txt diff --git a/src/test/resources/mmri/3e/routes.txt b/application/src/test/resources/mmri/3e/routes.txt similarity index 100% rename from src/test/resources/mmri/3e/routes.txt rename to application/src/test/resources/mmri/3e/routes.txt diff --git a/src/test/resources/mmri/3e/stop_times.txt b/application/src/test/resources/mmri/3e/stop_times.txt similarity index 100% rename from src/test/resources/mmri/3e/stop_times.txt rename to application/src/test/resources/mmri/3e/stop_times.txt diff --git a/src/test/resources/mmri/3e/stops.txt b/application/src/test/resources/mmri/3e/stops.txt similarity index 100% rename from src/test/resources/mmri/3e/stops.txt rename to application/src/test/resources/mmri/3e/stops.txt diff --git a/src/test/resources/mmri/3e/trips.txt b/application/src/test/resources/mmri/3e/trips.txt similarity index 100% rename from src/test/resources/mmri/3e/trips.txt rename to application/src/test/resources/mmri/3e/trips.txt diff --git a/src/test/resources/mmri/3g1/agency.txt b/application/src/test/resources/mmri/3g1/agency.txt similarity index 100% rename from src/test/resources/mmri/3g1/agency.txt rename to application/src/test/resources/mmri/3g1/agency.txt diff --git a/src/test/resources/mmri/3g1/calendar_dates.txt b/application/src/test/resources/mmri/3g1/calendar_dates.txt similarity index 100% rename from src/test/resources/mmri/3g1/calendar_dates.txt rename to application/src/test/resources/mmri/3g1/calendar_dates.txt diff --git a/src/test/resources/mmri/3g1/routes.txt b/application/src/test/resources/mmri/3g1/routes.txt similarity index 100% rename from src/test/resources/mmri/3g1/routes.txt rename to application/src/test/resources/mmri/3g1/routes.txt diff --git a/src/test/resources/mmri/3g1/stop_times.txt b/application/src/test/resources/mmri/3g1/stop_times.txt similarity index 100% rename from src/test/resources/mmri/3g1/stop_times.txt rename to application/src/test/resources/mmri/3g1/stop_times.txt diff --git a/src/test/resources/mmri/3g1/stops.txt b/application/src/test/resources/mmri/3g1/stops.txt similarity index 100% rename from src/test/resources/mmri/3g1/stops.txt rename to application/src/test/resources/mmri/3g1/stops.txt diff --git a/src/test/resources/mmri/3g1/transfers.txt b/application/src/test/resources/mmri/3g1/transfers.txt similarity index 100% rename from src/test/resources/mmri/3g1/transfers.txt rename to application/src/test/resources/mmri/3g1/transfers.txt diff --git a/src/test/resources/mmri/3g1/trips.txt b/application/src/test/resources/mmri/3g1/trips.txt similarity index 100% rename from src/test/resources/mmri/3g1/trips.txt rename to application/src/test/resources/mmri/3g1/trips.txt diff --git a/src/test/resources/mmri/3g2/agency.txt b/application/src/test/resources/mmri/3g2/agency.txt similarity index 100% rename from src/test/resources/mmri/3g2/agency.txt rename to application/src/test/resources/mmri/3g2/agency.txt diff --git a/src/test/resources/mmri/3g2/calendar_dates.txt b/application/src/test/resources/mmri/3g2/calendar_dates.txt similarity index 100% rename from src/test/resources/mmri/3g2/calendar_dates.txt rename to application/src/test/resources/mmri/3g2/calendar_dates.txt diff --git a/src/test/resources/mmri/3g2/routes.txt b/application/src/test/resources/mmri/3g2/routes.txt similarity index 100% rename from src/test/resources/mmri/3g2/routes.txt rename to application/src/test/resources/mmri/3g2/routes.txt diff --git a/src/test/resources/mmri/3g2/stop_times.txt b/application/src/test/resources/mmri/3g2/stop_times.txt similarity index 100% rename from src/test/resources/mmri/3g2/stop_times.txt rename to application/src/test/resources/mmri/3g2/stop_times.txt diff --git a/src/test/resources/mmri/3g2/stops.txt b/application/src/test/resources/mmri/3g2/stops.txt similarity index 100% rename from src/test/resources/mmri/3g2/stops.txt rename to application/src/test/resources/mmri/3g2/stops.txt diff --git a/src/test/resources/mmri/3g2/transfers.txt b/application/src/test/resources/mmri/3g2/transfers.txt similarity index 100% rename from src/test/resources/mmri/3g2/transfers.txt rename to application/src/test/resources/mmri/3g2/transfers.txt diff --git a/src/test/resources/mmri/3g2/trips.txt b/application/src/test/resources/mmri/3g2/trips.txt similarity index 100% rename from src/test/resources/mmri/3g2/trips.txt rename to application/src/test/resources/mmri/3g2/trips.txt diff --git a/src/test/resources/netex/epip/build-config.json b/application/src/test/resources/netex/epip/build-config.json similarity index 100% rename from src/test/resources/netex/epip/build-config.json rename to application/src/test/resources/netex/epip/build-config.json diff --git a/src/test/resources/netex/epip/netex_epip_minimal/NX-PI-01_DE_NAP_LINE_HHA-B-HHA-B-X86_20230203.xml b/application/src/test/resources/netex/epip/netex_epip_minimal/NX-PI-01_DE_NAP_LINE_HHA-B-HHA-B-X86_20230203.xml similarity index 100% rename from src/test/resources/netex/epip/netex_epip_minimal/NX-PI-01_DE_NAP_LINE_HHA-B-HHA-B-X86_20230203.xml rename to application/src/test/resources/netex/epip/netex_epip_minimal/NX-PI-01_DE_NAP_LINE_HHA-B-HHA-B-X86_20230203.xml diff --git a/src/test/resources/netex/epip/netex_epip_minimal/NX-PI-01_DE_NAP_LINE_VHH-VHH-688_20230203.xml b/application/src/test/resources/netex/epip/netex_epip_minimal/NX-PI-01_DE_NAP_LINE_VHH-VHH-688_20230203.xml similarity index 100% rename from src/test/resources/netex/epip/netex_epip_minimal/NX-PI-01_DE_NAP_LINE_VHH-VHH-688_20230203.xml rename to application/src/test/resources/netex/epip/netex_epip_minimal/NX-PI-01_DE_NAP_LINE_VHH-VHH-688_20230203.xml diff --git a/application/src/test/resources/netex/nordic/build-config.json b/application/src/test/resources/netex/nordic/build-config.json new file mode 100644 index 00000000000..e7b24ca138b --- /dev/null +++ b/application/src/test/resources/netex/nordic/build-config.json @@ -0,0 +1,11 @@ +{ + "transitServiceStart": "2017-12-21", + "transitServiceEnd": "2018-01-31", + "netexDefaults": { + "moduleFilePattern": "netex_.*\\.zip", + "sharedFilePattern": "_stops.xml", + "sharedGroupFilePattern": "_(\\w{3})_shared_data.xml", + "groupFilePattern": "(\\w{3})_.*\\.xml", + "feedId": "EN" + } +} diff --git a/src/test/resources/netex/nordic/netex_minimal.zip b/application/src/test/resources/netex/nordic/netex_minimal.zip similarity index 100% rename from src/test/resources/netex/nordic/netex_minimal.zip rename to application/src/test/resources/netex/nordic/netex_minimal.zip diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/alerts.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/alerts.json new file mode 100644 index 00000000000..80d8d57fdda --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/alerts.json @@ -0,0 +1,42 @@ +{ + "data": { + "alerts": [ + { + "id": "QWxlcnQ6RjpuZWl0aGVyLWhlYWRlci1ub3ItZGVzY3JpcHRpb24", + "headerDefault": "", + "headerDe": "", + "descriptionDefault": "", + "descriptionDe": "", + "urlDefault": null, + "urlDe": null + }, + { + "id": "QWxlcnQ6Rjpuby1oZWFkZXI", + "headerDefault": "Second string", + "headerDe": "Zweite Zeichenabfolge", + "descriptionDefault": "Second string", + "descriptionDe": "Zweite Zeichenabfolge", + "urlDefault": null, + "urlDe": null + }, + { + "id": "QWxlcnQ6Rjphbi1hbGVydA", + "headerDefault": "A header", + "headerDe": "A header", + "descriptionDefault": "A description", + "descriptionDe": "A description", + "urlDefault": "https://example.com", + "urlDe": "https://example.com" + }, + { + "id": "QWxlcnQ6Rjpuby1kZXNjcmlwdGlvbg", + "headerDefault": "First string", + "headerDe": "Erste Zeichenabfolge", + "descriptionDefault": "First string", + "descriptionDe": "Erste Zeichenabfolge", + "urlDefault": null, + "urlDe": null + } + ] + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/feedinfo.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/feedinfo.json new file mode 100644 index 00000000000..f5ed39d1af1 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/feedinfo.json @@ -0,0 +1,18 @@ +{ + "data": { + "feeds": [ + { + "agencies": [ + { + "name": "speedtransit", + "url": "www.otp-foo.bar" + } + ], + "publisher": { + "name": "publisher", + "url": "www.z.org" + } + } + ] + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/nearest.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/nearest.json new file mode 100644 index 00000000000..c430fdb6a30 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/nearest.json @@ -0,0 +1,31 @@ +{ + "data": { + "nearest": { + "edges": [ + { + "node": { + "place": { + "id": "U3RvcDpGOkE", + "gtfsId": "F:A", + "parentStation": null + } + } + }, + { + "node": { + "place": { + "stationId": "Network-1:FooStation" + } + } + }, + { + "node": { + "place": { + "vehicleId": "Network-1:free-floating-bicycle" + } + } + } + ] + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/node-alert.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/node-alert.json new file mode 100644 index 00000000000..63c731a8945 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/node-alert.json @@ -0,0 +1,10 @@ +{ + "data": { + "node": { + "id": "QWxlcnQ6Rjpuby1oZWFkZXI", + "alertHeaderText": "Second string", + "alertDescriptionText": "Second string", + "alertUrl": null + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/patterns.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/patterns.json new file mode 100644 index 00000000000..73ee8b0495e --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/patterns.json @@ -0,0 +1,95 @@ +{ + "data": { + "patterns": [ + { + "code": "F:BUS", + "headsign": "Trip Headsign", + "trips": [ + { + "gtfsId": "F:123", + "stoptimes": [ + { + "stop": { + "gtfsId": "F:Stop_0", + "name": "Stop_0" + }, + "headsign": "Stop headsign at stop 10", + "scheduledArrival": 39600, + "scheduledDeparture": 39600, + "stopPosition": 10, + "stopPositionInPattern": 0, + "realtimeState": "SCHEDULED", + "pickupType": "SCHEDULED", + "dropoffType": "SCHEDULED" + }, + { + "stop": { + "gtfsId": "F:Stop_1", + "name": "Stop_1" + }, + "headsign": "Stop headsign at stop 20", + "scheduledArrival": 39900, + "scheduledDeparture": 39900, + "stopPosition": 20, + "stopPositionInPattern": 1, + "realtimeState": "SCHEDULED", + "pickupType": "SCHEDULED", + "dropoffType": "SCHEDULED" + }, + { + "stop": { + "gtfsId": "F:Stop_2", + "name": "Stop_2" + }, + "headsign": "Stop headsign at stop 30", + "scheduledArrival": 40200, + "scheduledDeparture": 40200, + "stopPosition": 30, + "stopPositionInPattern": 2, + "realtimeState": "SCHEDULED", + "pickupType": "SCHEDULED", + "dropoffType": "SCHEDULED" + } + ], + "occupancy": { + "occupancyStatus": "FEW_SEATS_AVAILABLE" + } + } + ], + "vehiclePositions": [ + { + "vehicleId": "F:vehicle-1", + "label": null, + "lat": null, + "lon": null, + "stopRelationship": null, + "speed": null, + "heading": null, + "lastUpdated": 31556889864403199, + "trip": { + "gtfsId": "F:123" + } + }, + { + "vehicleId": "F:vehicle-2", + "label": "vehicle2", + "lat": 60.0, + "lon": 80.0, + "stopRelationship": { + "status": "IN_TRANSIT_TO", + "stop": { + "gtfsId": "F:Stop_0" + } + }, + "speed": 10.2, + "heading": 80.0, + "lastUpdated": -31557014167219200, + "trip": { + "gtfsId": "F:123" + } + } + ] + } + ] + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan.json new file mode 100644 index 00000000000..817754b79ca --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan.json @@ -0,0 +1,74 @@ +{ + "data": { + "plan": { + "itineraries": [ + { + "start": "2020-02-02T11:00:00Z", + "end": "2020-02-02T12:00:00Z", + "legs": [ + { + "mode": "WALK", + "start": { + "scheduledTime": "2020-02-02T11:00:00Z" + }, + "end": { + "scheduledTime": "2020-02-02T11:00:20Z" + }, + "from": { + "name": "A" + }, + "to": { + "name": "B" + } + }, + { + "mode": "BUS", + "start": { + "scheduledTime": "2020-02-02T10:51:00Z" + }, + "end": { + "scheduledTime": "2020-02-02T11:05:00Z" + }, + "from": { + "name": "B" + }, + "to": { + "name": "C" + } + }, + { + "mode": "RAIL", + "start": { + "scheduledTime": "2020-02-02T11:20:00Z" + }, + "end": { + "scheduledTime": "2020-02-02T11:40:00Z" + }, + "from": { + "name": "C" + }, + "to": { + "name": "D" + } + }, + { + "mode": "CAR", + "start": { + "scheduledTime": "2020-02-02T11:50:00Z" + }, + "end": { + "scheduledTime": "2020-02-02T12:00:00Z" + }, + "from": { + "name": "D" + }, + "to": { + "name": "E" + } + } + ] + } + ] + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/planConnection-extended.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/planConnection-extended.json new file mode 100644 index 00000000000..ab29f172b6f --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/planConnection-extended.json @@ -0,0 +1,364 @@ +{ + "data": { + "planConnection": { + "searchDateTime": "2023-01-27T21:08:35+01:00", + "routingErrors": [], + "pageInfo": { + "hasNextPage": false, + "hasPreviousPage": false, + "startCursor": null, + "endCursor": null, + "searchWindowUsed": null + }, + "edges": [ + { + "cursor": "NoCursor", + "node": { + "start": "2020-02-02T11:00:00Z", + "end": "2020-02-02T12:00:00Z", + "startTime": 1580641200000, + "endTime": 1580644800000, + "generalizedCost": 4072, + "accessibilityScore": 0.5, + "emissionsPerPerson": { + "co2": 123.0 + }, + "numberOfTransfers": 1, + "walkDistance": 28.0, + "walkTime": 20, + "legs": [ + { + "mode": "WALK", + "start": { + "scheduledTime": "2020-02-02T11:00:00Z", + "estimated": null + }, + "end": { + "scheduledTime": "2020-02-02T11:00:20Z", + "estimated": null + }, + "from": { + "name": "A", + "lat": 5.0, + "lon": 8.0, + "arrival": { + "scheduledTime": "2020-02-02T11:00:00Z", + "estimated": null + }, + "departure": { + "scheduledTime": "2020-02-02T11:00:00Z", + "estimated": null + }, + "departureTime": 1580641200000, + "arrivalTime": 1580641200000 + }, + "to": { + "name": "B", + "lat": 6.0, + "lon": 8.5, + "arrival": { + "scheduledTime": "2020-02-02T11:00:20Z", + "estimated": null + }, + "departure": { + "scheduledTime": "2020-02-02T11:00:20Z", + "estimated": null + }, + "departureTime": 1580641220000, + "arrivalTime": 1580641220000 + }, + "startTime": 1580641200000, + "endTime": 1580641220000, + "generalizedCost": 40, + "headsign": null, + "trip": null, + "intermediatePlaces": null, + "alerts": [], + "rideHailingEstimate": null, + "accessibilityScore": null, + "id": null, + "realtimeState": null + }, + { + "mode": "BUS", + "start": { + "scheduledTime": "2020-02-02T10:51:00Z", + "estimated": { + "time": "2020-02-02T11:01:00Z", + "delay": "PT10M" + } + }, + "end": { + "scheduledTime": "2020-02-02T11:05:00Z", + "estimated": { + "time": "2020-02-02T11:15:00Z", + "delay": "PT10M" + } + }, + "from": { + "name": "B", + "lat": 6.0, + "lon": 8.5, + "arrival": { + "scheduledTime": "2020-02-02T10:51:00Z", + "estimated": { + "delay": "PT10M", + "time": "2020-02-02T11:01:00Z" + } + }, + "departure": { + "scheduledTime": "2020-02-02T10:51:00Z", + "estimated": { + "delay": "PT10M", + "time": "2020-02-02T11:01:00Z" + } + }, + "departureTime": 1580641260000, + "arrivalTime": 1580641260000 + }, + "to": { + "name": "C", + "lat": 7.0, + "lon": 9.0, + "arrival": { + "scheduledTime": "2020-02-02T11:05:00Z", + "estimated": { + "delay": "PT10M", + "time": "2020-02-02T11:15:00Z" + } + }, + "departure": { + "scheduledTime": "2020-02-02T11:05:00Z", + "estimated": { + "delay": "PT10M", + "time": "2020-02-02T11:15:00Z" + } + }, + "departureTime": 1580642100000, + "arrivalTime": 1580642100000 + }, + "startTime": 1580641260000, + "endTime": 1580642100000, + "generalizedCost": 992, + "headsign": "Headsign at boarding (stop index 5)", + "trip": { + "tripHeadsign": "Trip headsign 122" + }, + "intermediatePlaces": [ + { + "arrival": { + "scheduledTime": "2020-02-02T11:01:00Z", + "estimated": { + "time": "2020-02-02T11:11:00Z", + "delay": "PT10M" + } + }, + "departure": { + "scheduledTime": "2020-02-02T11:01:00Z", + "estimated": { + "time": "2020-02-02T11:11:00Z", + "delay": "PT10M" + } + }, + "stop": { + "name": "B" + } + } + ], + "alerts": [], + "rideHailingEstimate": null, + "accessibilityScore": null, + "id": "rO0ABXdBABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMABUY6MTIyAAoyMDIwLTAyLTAyAAAABQAAAAcAA0Y6QgADRjpDAAA=", + "realtimeState": "UPDATED" + }, + { + "mode": "RAIL", + "start": { + "scheduledTime": "2020-02-02T11:20:00Z", + "estimated": { + "time": "2020-02-02T11:30:00Z", + "delay": "PT10M" + } + }, + "end": { + "scheduledTime": "2020-02-02T11:40:00Z", + "estimated": { + "time": "2020-02-02T11:50:00Z", + "delay": "PT10M" + } + }, + "from": { + "name": "C", + "lat": 7.0, + "lon": 9.0, + "arrival": { + "scheduledTime": "2020-02-02T11:20:00Z", + "estimated": { + "delay": "PT10M", + "time": "2020-02-02T11:30:00Z" + } + }, + "departure": { + "scheduledTime": "2020-02-02T11:20:00Z", + "estimated": { + "delay": "PT10M", + "time": "2020-02-02T11:30:00Z" + } + }, + "departureTime": 1580643000000, + "arrivalTime": 1580643000000 + }, + "to": { + "name": "D", + "lat": 8.0, + "lon": 9.5, + "arrival": { + "scheduledTime": "2020-02-02T11:40:00Z", + "estimated": { + "delay": "PT10M", + "time": "2020-02-02T11:50:00Z" + } + }, + "departure": { + "scheduledTime": "2020-02-02T11:40:00Z", + "estimated": { + "delay": "PT10M", + "time": "2020-02-02T11:50:00Z" + } + }, + "departureTime": 1580644200000, + "arrivalTime": 1580644200000 + }, + "startTime": 1580643000000, + "endTime": 1580644200000, + "generalizedCost": 2040, + "headsign": "Headsign at boarding (stop index 5)", + "trip": { + "tripHeadsign": "Trip headsign 439" + }, + "intermediatePlaces": [ + { + "arrival": { + "scheduledTime": "2020-02-02T11:30:00Z", + "estimated": { + "time": "2020-02-02T11:40:00Z", + "delay": "PT10M" + } + }, + "departure": { + "scheduledTime": "2020-02-02T11:30:00Z", + "estimated": { + "time": "2020-02-02T11:40:00Z", + "delay": "PT10M" + } + }, + "stop": { + "name": "C" + } + } + ], + "alerts": [ + { + "id": "QWxlcnQ6Rjphbi1hbGVydA", + "alertHeaderText": "A header", + "alertDescriptionText": "A description", + "alertEffect": "REDUCED_SERVICE", + "alertCause": "MAINTENANCE", + "alertSeverityLevel": "SEVERE", + "alertUrl": "https://example.com", + "effectiveStartDate": 1676459008, + "effectiveEndDate": 1676545408, + "entities": [ + { + "name": "A", + "gtfsId": "F:A", + "lat": 5.0, + "lon": 8.0 + } + ] + } + ], + "rideHailingEstimate": null, + "accessibilityScore": null, + "id": "rO0ABXdBABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMABUY6NDM5AAoyMDIwLTAyLTAyAAAABQAAAAcAA0Y6QwADRjpEAAA=", + "realtimeState": "UPDATED" + }, + { + "mode": "CAR", + "start": { + "scheduledTime": "2020-02-02T11:50:00Z", + "estimated": null + }, + "end": { + "scheduledTime": "2020-02-02T12:00:00Z", + "estimated": null + }, + "from": { + "name": "D", + "lat": 8.0, + "lon": 9.5, + "arrival": { + "scheduledTime": "2020-02-02T11:50:00Z", + "estimated": null + }, + "departure": { + "scheduledTime": "2020-02-02T11:50:00Z", + "estimated": null + }, + "departureTime": 1580644200000, + "arrivalTime": 1580644200000 + }, + "to": { + "name": "E", + "lat": 9.0, + "lon": 10.0, + "arrival": { + "scheduledTime": "2020-02-02T12:00:00Z", + "estimated": null + }, + "departure": { + "scheduledTime": "2020-02-02T12:00:00Z", + "estimated": null + }, + "departureTime": 1580644800000, + "arrivalTime": 1580644800000 + }, + "startTime": 1580644200000, + "endTime": 1580644800000, + "generalizedCost": 1000, + "headsign": null, + "trip": null, + "intermediatePlaces": null, + "alerts": [], + "rideHailingEstimate": { + "provider": { + "id": "uber" + }, + "productName": "UberX", + "minPrice": { + "currency": { + "code": "EUR", + "digits": 2 + }, + "amount": 10.0 + }, + "maxPrice": { + "currency": { + "code": "EUR", + "digits": 2 + }, + "amount": 20.0 + }, + "arrival": "PT10M" + }, + "accessibilityScore": null, + "id": null, + "realtimeState": null + } + ] + } + } + ] + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/planConnection-fares.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/planConnection-fares.json new file mode 100644 index 00000000000..748fc668e63 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/planConnection-fares.json @@ -0,0 +1,168 @@ +{ + "data": { + "planConnection": { + "edges": [ + { + "node": { + "legs": [ + { + "mode": "WALK", + "from": { + "name": "A", + "lat": 5.0, + "lon": 8.0 + }, + "to": { + "name": "B", + "lat": 6.0, + "lon": 8.5 + }, + "generalizedCost": 40, + "fareProducts": [] + }, + { + "mode": "BUS", + "from": { + "name": "B", + "lat": 6.0, + "lon": 8.5 + }, + "to": { + "name": "C", + "lat": 7.0, + "lon": 9.0 + }, + "generalizedCost": 992, + "fareProducts": [ + { + "id": "5d8f889c-42cb-3bcc-89d5-480b995c78c8", + "product": { + "id": "F:day-pass", + "name": "day-pass", + "__typename": "DefaultFareProduct", + "price": { + "currency": { + "digits": 2, + "code": "EUR" + }, + "amount": 10.0 + }, + "riderCategory": { + "id": "F:senior-citizens", + "name": "Senior citizens" + }, + "medium": { + "id": "F:oyster", + "name": "TfL Oyster Card" + } + } + }, + { + "id": "09bb5f2b-6af9-3355-8b5d-5e93a27ce280", + "product": { + "id": "F:single-ticket", + "name": "single-ticket", + "__typename": "DefaultFareProduct", + "price": { + "currency": { + "digits": 2, + "code": "EUR" + }, + "amount": 10.0 + }, + "riderCategory": { + "id": "F:senior-citizens", + "name": "Senior citizens" + }, + "medium": { + "id": "F:oyster", + "name": "TfL Oyster Card" + } + } + } + ] + }, + { + "mode": "RAIL", + "from": { + "name": "C", + "lat": 7.0, + "lon": 9.0 + }, + "to": { + "name": "D", + "lat": 8.0, + "lon": 9.5 + }, + "generalizedCost": 2040, + "fareProducts": [ + { + "id": "5d8f889c-42cb-3bcc-89d5-480b995c78c8", + "product": { + "id": "F:day-pass", + "name": "day-pass", + "__typename": "DefaultFareProduct", + "price": { + "currency": { + "digits": 2, + "code": "EUR" + }, + "amount": 10.0 + }, + "riderCategory": { + "id": "F:senior-citizens", + "name": "Senior citizens" + }, + "medium": { + "id": "F:oyster", + "name": "TfL Oyster Card" + } + } + }, + { + "id": "46190ddd-93b0-3136-adb7-a18394f8b0ef", + "product": { + "id": "F:single-ticket", + "name": "single-ticket", + "__typename": "DefaultFareProduct", + "price": { + "currency": { + "digits": 2, + "code": "EUR" + }, + "amount": 10.0 + }, + "riderCategory": { + "id": "F:senior-citizens", + "name": "Senior citizens" + }, + "medium": { + "id": "F:oyster", + "name": "TfL Oyster Card" + } + } + } + ] + }, + { + "mode": "CAR", + "from": { + "name": "D", + "lat": 8.0, + "lon": 9.5 + }, + "to": { + "name": "E", + "lat": 9.0, + "lon": 10.0 + }, + "generalizedCost": 1000, + "fareProducts": [] + } + ] + } + } + ] + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/planConnection-stop-positions.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/planConnection-stop-positions.json new file mode 100644 index 00000000000..f197dcefe1c --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/planConnection-stop-positions.json @@ -0,0 +1,94 @@ +{ + "data": { + "planConnection": { + "edges": [ + { + "node": { + "start": "2020-02-02T11:00:00Z", + "end": "2020-02-02T12:00:00Z", + "generalizedCost": 4072, + "accessibilityScore": 0.5, + "legs": [ + { + "mode": "WALK", + "from": { + "name": "A", + "lat": 5.0, + "lon": 8.0, + "stopPosition": null + }, + "to": { + "name": "B", + "lat": 6.0, + "lon": 8.5, + "stopPosition": null + }, + "generalizedCost": 40 + }, + { + "mode": "BUS", + "from": { + "name": "B", + "lat": 6.0, + "lon": 8.5, + "stopPosition": { + "__typename": "PositionAtStop", + "position": 0 + } + }, + "to": { + "name": "C", + "lat": 7.0, + "lon": 9.0, + "stopPosition": { + "__typename": "PositionAtStop", + "position": 0 + } + }, + "generalizedCost": 992 + }, + { + "mode": "RAIL", + "from": { + "name": "C", + "lat": 7.0, + "lon": 9.0, + "stopPosition": { + "__typename": "PositionAtStop", + "position": 0 + } + }, + "to": { + "name": "D", + "lat": 8.0, + "lon": 9.5, + "stopPosition": { + "__typename": "PositionAtStop", + "position": 0 + } + }, + "generalizedCost": 2040 + }, + { + "mode": "CAR", + "from": { + "name": "D", + "lat": 8.0, + "lon": 9.5, + "stopPosition": null + }, + "to": { + "name": "E", + "lat": 9.0, + "lon": 10.0, + "stopPosition": null + }, + "generalizedCost": 1000 + } + ] + } + } + ] + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/planConnection-tutorial.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/planConnection-tutorial.json new file mode 100644 index 00000000000..caafc57375d --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/planConnection-tutorial.json @@ -0,0 +1,132 @@ +{ + "data": { + "planConnection": { + "edges": [ + { + "node": { + "start": "2020-02-02T11:00:00Z", + "end": "2020-02-02T12:00:00Z", + "legs": [ + { + "mode": "WALK", + "from": { + "name": "A", + "lat": 5.0, + "lon": 8.0, + "departure": { + "scheduledTime": "2020-02-02T11:00:00Z", + "estimated": null + } + }, + "to": { + "name": "B", + "lat": 6.0, + "lon": 8.5, + "arrival": { + "scheduledTime": "2020-02-02T11:00:20Z", + "estimated": null + } + }, + "route": null, + "legGeometry": null + }, + { + "mode": "BUS", + "from": { + "name": "B", + "lat": 6.0, + "lon": 8.5, + "departure": { + "scheduledTime": "2020-02-02T10:51:00Z", + "estimated": { + "time": "2020-02-02T11:01:00Z", + "delay": "PT10M" + } + } + }, + "to": { + "name": "C", + "lat": 7.0, + "lon": 9.0, + "arrival": { + "scheduledTime": "2020-02-02T11:05:00Z", + "estimated": { + "time": "2020-02-02T11:15:00Z", + "delay": "PT10M" + } + } + }, + "route": { + "gtfsId": "F:BUS", + "longName": "Long name for BUS", + "shortName": "RBUS" + }, + "legGeometry": { + "points": "_{rc@_d{r@????_ibE_t`B" + } + }, + { + "mode": "RAIL", + "from": { + "name": "C", + "lat": 7.0, + "lon": 9.0, + "departure": { + "scheduledTime": "2020-02-02T11:20:00Z", + "estimated": { + "time": "2020-02-02T11:30:00Z", + "delay": "PT10M" + } + } + }, + "to": { + "name": "D", + "lat": 8.0, + "lon": 9.5, + "arrival": { + "scheduledTime": "2020-02-02T11:40:00Z", + "estimated": { + "time": "2020-02-02T11:50:00Z", + "delay": "PT10M" + } + } + }, + "route": { + "gtfsId": "F:2", + "longName": null, + "shortName": "R2" + }, + "legGeometry": { + "points": "_evi@_y|u@????_ibE_t`B" + } + }, + { + "mode": "CAR", + "from": { + "name": "D", + "lat": 8.0, + "lon": 9.5, + "departure": { + "scheduledTime": "2020-02-02T11:50:00Z", + "estimated": null + } + }, + "to": { + "name": "E", + "lat": 9.0, + "lon": 10.0, + "arrival": { + "scheduledTime": "2020-02-02T12:00:00Z", + "estimated": null + } + }, + "route": null, + "legGeometry": null + } + ] + } + } + ] + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/rental-vehicle.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/rental-vehicle.json new file mode 100644 index 00000000000..bcff74d0413 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/rental-vehicle.json @@ -0,0 +1,21 @@ +{ + "data": { + "rentalVehicle": { + "vehicleId": "Network-1:free-floating-bicycle", + "name": "free-floating-bicycle", + "allowPickupNow": true, + "lon": 19.01, + "lat": 47.52, + "rentalUris": null, + "operative": true, + "vehicleType": { + "formFactor": "BICYCLE", + "propulsionType": "HUMAN" + }, + "rentalNetwork": { + "networkId": "Network-1", + "url": "https://foo.bar" + } + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/routes-extended.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/routes-extended.json new file mode 100644 index 00000000000..be772736fc5 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/routes-extended.json @@ -0,0 +1,188 @@ +{ + "data": { + "routes": [ + { + "longName": "Long name for CARPOOL", + "shortName": "RCARPOOL", + "gtfsId": "F:CARPOOL", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "CARPOOL", + "sortOrder": 12, + "bikesAllowed": "ALLOWED", + "patterns": [] + }, + { + "longName": "Long name for SUBWAY", + "shortName": "RSUBWAY", + "gtfsId": "F:SUBWAY", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "SUBWAY", + "sortOrder": 2, + "bikesAllowed": "NO_INFORMATION", + "patterns": [] + }, + { + "longName": "Long name for BUS", + "shortName": "RBUS", + "gtfsId": "F:BUS", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "BUS", + "sortOrder": 3, + "bikesAllowed": "ALLOWED", + "patterns": [] + }, + { + "longName": "Long name for FERRY", + "shortName": "RFERRY", + "gtfsId": "F:FERRY", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "FERRY", + "sortOrder": 5, + "bikesAllowed": "NO_INFORMATION", + "patterns": [] + }, + { + "longName": "Long name for COACH", + "shortName": "RCOACH", + "gtfsId": "F:COACH", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "COACH", + "sortOrder": 1, + "bikesAllowed": "NOT_ALLOWED", + "patterns": [] + }, + { + "longName": "Long name for TRAM", + "shortName": "RTRAM", + "gtfsId": "F:TRAM", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "TRAM", + "sortOrder": 4, + "bikesAllowed": "NOT_ALLOWED", + "patterns": [] + }, + { + "longName": "Long name for CABLE_CAR", + "shortName": "RCABLE_CAR", + "gtfsId": "F:CABLE_CAR", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "CABLE_CAR", + "sortOrder": 7, + "bikesAllowed": "NOT_ALLOWED", + "patterns": [] + }, + { + "longName": "Long name for FUNICULAR", + "shortName": "RFUNICULAR", + "gtfsId": "F:FUNICULAR", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "FUNICULAR", + "sortOrder": 9, + "bikesAllowed": "ALLOWED", + "patterns": [] + }, + { + "longName": "Long name for RAIL", + "shortName": "RRAIL", + "gtfsId": "F:RAIL", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "RAIL", + "sortOrder": null, + "bikesAllowed": "ALLOWED", + "patterns": [] + }, + { + "longName": "Long name for MONORAIL", + "shortName": "RMONORAIL", + "gtfsId": "F:MONORAIL", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "MONORAIL", + "sortOrder": 11, + "bikesAllowed": "NO_INFORMATION", + "patterns": [] + }, + { + "longName": "Long name for GONDOLA", + "shortName": "RGONDOLA", + "gtfsId": "F:GONDOLA", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "GONDOLA", + "sortOrder": 8, + "bikesAllowed": "NO_INFORMATION", + "patterns": [] + }, + { + "longName": "Long name for TROLLEYBUS", + "shortName": "RTROLLEYBUS", + "gtfsId": "F:TROLLEYBUS", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "TROLLEYBUS", + "sortOrder": 10, + "bikesAllowed": "NOT_ALLOWED", + "patterns": [] + }, + { + "longName": "Long name for AIRPLANE", + "shortName": "RAIRPLANE", + "gtfsId": "F:AIRPLANE", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "AIRPLANE", + "sortOrder": 6, + "bikesAllowed": "ALLOWED", + "patterns": [] + }, + { + "longName": "Long name for TAXI", + "shortName": "RTAXI", + "gtfsId": "F:TAXI", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "TAXI", + "sortOrder": 13, + "bikesAllowed": "NOT_ALLOWED", + "patterns": [] + } + ] + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/routes-tutorial.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/routes-tutorial.json new file mode 100644 index 00000000000..f775b2d9d8a --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/routes-tutorial.json @@ -0,0 +1,146 @@ +{ + "data": { + "routes": [ + { + "longName": "Long name for CARPOOL", + "shortName": "RCARPOOL", + "gtfsId": "F:CARPOOL", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "CARPOOL" + }, + { + "longName": "Long name for SUBWAY", + "shortName": "RSUBWAY", + "gtfsId": "F:SUBWAY", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "SUBWAY" + }, + { + "longName": "Long name for BUS", + "shortName": "RBUS", + "gtfsId": "F:BUS", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "BUS" + }, + { + "longName": "Long name for FERRY", + "shortName": "RFERRY", + "gtfsId": "F:FERRY", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "FERRY" + }, + { + "longName": "Long name for COACH", + "shortName": "RCOACH", + "gtfsId": "F:COACH", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "COACH" + }, + { + "longName": "Long name for TRAM", + "shortName": "RTRAM", + "gtfsId": "F:TRAM", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "TRAM" + }, + { + "longName": "Long name for CABLE_CAR", + "shortName": "RCABLE_CAR", + "gtfsId": "F:CABLE_CAR", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "CABLE_CAR" + }, + { + "longName": "Long name for FUNICULAR", + "shortName": "RFUNICULAR", + "gtfsId": "F:FUNICULAR", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "FUNICULAR" + }, + { + "longName": "Long name for RAIL", + "shortName": "RRAIL", + "gtfsId": "F:RAIL", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "RAIL" + }, + { + "longName": "Long name for MONORAIL", + "shortName": "RMONORAIL", + "gtfsId": "F:MONORAIL", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "MONORAIL" + }, + { + "longName": "Long name for GONDOLA", + "shortName": "RGONDOLA", + "gtfsId": "F:GONDOLA", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "GONDOLA" + }, + { + "longName": "Long name for TROLLEYBUS", + "shortName": "RTROLLEYBUS", + "gtfsId": "F:TROLLEYBUS", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "TROLLEYBUS" + }, + { + "longName": "Long name for AIRPLANE", + "shortName": "RAIRPLANE", + "gtfsId": "F:AIRPLANE", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "AIRPLANE" + }, + { + "longName": "Long name for TAXI", + "shortName": "RTAXI", + "gtfsId": "F:TAXI", + "agency": { + "gtfsId": "F:A1", + "name": "Agency Test" + }, + "mode": "TAXI" + } + ] + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/stops.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/stops.json new file mode 100644 index 00000000000..b4d54806efe --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/stops.json @@ -0,0 +1,126 @@ +{ + "data": { + "stops": [ + { + "gtfsId": "F:A", + "lat": 5.0, + "lon": 8.0, + "name": "A", + "vehicleMode": "BUS", + "allRoutes": [ + { + "gtfsId": "F:a-route", + "longName": null, + "shortName": "Ra-route" + } + ], + "routesWithinRange": [] + }, + { + "gtfsId": "F:B", + "lat": 6.0, + "lon": 8.5, + "name": "B", + "vehicleMode": "BUS", + "allRoutes": [ + { + "gtfsId": "F:a-route", + "longName": null, + "shortName": "Ra-route" + } + ], + "routesWithinRange": [] + }, + { + "gtfsId": "F:C", + "lat": 7.0, + "lon": 9.0, + "name": "C", + "vehicleMode": "BUS", + "allRoutes": [ + { + "gtfsId": "F:a-route", + "longName": null, + "shortName": "Ra-route" + } + ], + "routesWithinRange": [] + }, + { + "gtfsId": "F:D", + "lat": 8.0, + "lon": 9.5, + "name": "D", + "vehicleMode": "BUS", + "allRoutes": [ + { + "gtfsId": "F:a-route", + "longName": null, + "shortName": "Ra-route" + } + ], + "routesWithinRange": [] + }, + { + "gtfsId": "F:E", + "lat": 9.0, + "lon": 10.0, + "name": "E", + "vehicleMode": "BUS", + "allRoutes": [ + { + "gtfsId": "F:a-route", + "longName": null, + "shortName": "Ra-route" + } + ], + "routesWithinRange": [] + }, + { + "gtfsId": "F:F", + "lat": 9.0, + "lon": 10.5, + "name": "F", + "vehicleMode": "BUS", + "allRoutes": [ + { + "gtfsId": "F:a-route", + "longName": null, + "shortName": "Ra-route" + } + ], + "routesWithinRange": [] + }, + { + "gtfsId": "F:G", + "lat": 9.5, + "lon": 11.0, + "name": "G", + "vehicleMode": "BUS", + "allRoutes": [ + { + "gtfsId": "F:a-route", + "longName": null, + "shortName": "Ra-route" + } + ], + "routesWithinRange": [] + }, + { + "gtfsId": "F:H", + "lat": 10.0, + "lon": 11.5, + "name": "H", + "vehicleMode": "BUS", + "allRoutes": [ + { + "gtfsId": "F:a-route", + "longName": null, + "shortName": "Ra-route" + } + ], + "routesWithinRange": [] + } + ] + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/vehicle-parking.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/vehicle-parking.json new file mode 100644 index 00000000000..549f0b29343 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/vehicle-parking.json @@ -0,0 +1,10 @@ +{ + "data": { + "vehicleParkings": [ + { + "name": "parking", + "vehicleParkingId": "F:parking-1" + } + ] + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/vehicle-rental-station.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/vehicle-rental-station.json new file mode 100644 index 00000000000..e7c1e52770f --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/vehicle-rental-station.json @@ -0,0 +1,62 @@ +{ + "data": { + "vehicleRentalStation": { + "stationId": "Network-1:FooStation", + "name": "FooStation", + "vehiclesAvailable": 10, + "availableVehicles": { + "byType": [ + { + "vehicleType": { + "formFactor": "BICYCLE", + "propulsionType": "ELECTRIC" + }, + "count": 5 + }, + { + "vehicleType": { + "formFactor": "BICYCLE", + "propulsionType": "HUMAN" + }, + "count": 5 + } + ], + "total": 10 + }, + "spacesAvailable": 10, + "availableSpaces": { + "byType": [ + { + "vehicleType": { + "formFactor": "BICYCLE", + "propulsionType": "ELECTRIC" + }, + "count": 3 + }, + { + "vehicleType": { + "formFactor": "BICYCLE", + "propulsionType": "HUMAN" + }, + "count": 7 + } + ], + "total": 10 + }, + "allowDropoff": false, + "allowPickup": false, + "allowDropoffNow": false, + "allowPickupNow": false, + "lon": 18.99, + "lat": 47.51, + "capacity": null, + "allowOverloading": false, + "rentalUris": null, + "operative": false, + "rentalNetwork": { + "networkId": "Network-1", + "url": "https://foo.bar" + } + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/vehicle-rentals-bybbox.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/vehicle-rentals-bybbox.json new file mode 100644 index 00000000000..d28e62f8d93 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/vehicle-rentals-bybbox.json @@ -0,0 +1,83 @@ +{ + "data": { + "vehicleRentalsByBbox": [ + { + "__typename": "VehicleRentalStation", + "stationId": "Network-1:FooStation", + "name": "FooStation", + "vehiclesAvailable": 10, + "availableVehicles": { + "byType": [ + { + "vehicleType": { + "formFactor": "BICYCLE", + "propulsionType": "ELECTRIC" + }, + "count": 5 + }, + { + "vehicleType": { + "formFactor": "BICYCLE", + "propulsionType": "HUMAN" + }, + "count": 5 + } + ], + "total": 10 + }, + "spacesAvailable": 10, + "availableSpaces": { + "byType": [ + { + "vehicleType": { + "formFactor": "BICYCLE", + "propulsionType": "ELECTRIC" + }, + "count": 3 + }, + { + "vehicleType": { + "formFactor": "BICYCLE", + "propulsionType": "HUMAN" + }, + "count": 7 + } + ], + "total": 10 + }, + "allowDropoff": false, + "allowPickup": false, + "allowDropoffNow": false, + "allowPickupNow": false, + "lon": 18.99, + "lat": 47.51, + "capacity": null, + "allowOverloading": false, + "rentalUris": null, + "operative": false, + "rentalNetwork": { + "networkId": "Network-1", + "url": "https://foo.bar" + } + }, + { + "__typename": "RentalVehicle", + "vehicleId": "Network-1:free-floating-bicycle", + "name": "free-floating-bicycle", + "allowPickupNow": true, + "lon": 19.01, + "lat": 47.52, + "rentalUris": null, + "operative": true, + "vehicleType": { + "formFactor": "BICYCLE", + "propulsionType": "HUMAN" + }, + "rentalNetwork": { + "networkId": "Network-1", + "url": "https://foo.bar" + } + } + ] + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json new file mode 100644 index 00000000000..49908207d44 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json @@ -0,0 +1,39 @@ +{ + "data": { + "planConnection": { + "edges": [ + { + "node": { + "legs": [ + { + "steps": [ + { + "streetName": "street", + "area": false, + "relativeDirection": "DEPART", + "absoluteDirection": "NORTHEAST" + }, + { + "streetName": "elevator", + "area": false, + "relativeDirection": "ELEVATOR", + "absoluteDirection": null + } + ] + }, + { + "steps": [] + }, + { + "steps": [] + }, + { + "steps": [] + } + ] + } + } + ] + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/alerts.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/alerts.graphql new file mode 100644 index 00000000000..3a5d438e8ef --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/alerts.graphql @@ -0,0 +1,11 @@ +{ + alerts { + id + headerDefault: alertHeaderText + headerDe: alertHeaderText(language: "de") + descriptionDefault: alertDescriptionText + descriptionDe: alertDescriptionText(language: "de") + urlDefault: alertUrl + urlDe: alertUrl(language: "de") + } +} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/feedinfo.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/feedinfo.graphql similarity index 100% rename from src/test/resources/org/opentripplanner/apis/gtfs/queries/feedinfo.graphql rename to application/src/test/resources/org/opentripplanner/apis/gtfs/queries/feedinfo.graphql diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/nearest.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/nearest.graphql similarity index 100% rename from src/test/resources/org/opentripplanner/apis/gtfs/queries/nearest.graphql rename to application/src/test/resources/org/opentripplanner/apis/gtfs/queries/nearest.graphql diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/node-alert.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/node-alert.graphql new file mode 100644 index 00000000000..533595e0d5f --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/node-alert.graphql @@ -0,0 +1,10 @@ +{ + node(id: "QWxlcnQ6Rjpuby1oZWFkZXI") { + id + ... on Alert { + alertHeaderText + alertDescriptionText + alertUrl + } + } +} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/patterns.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/patterns.graphql similarity index 95% rename from src/test/resources/org/opentripplanner/apis/gtfs/queries/patterns.graphql rename to application/src/test/resources/org/opentripplanner/apis/gtfs/queries/patterns.graphql index 090473cfc7a..b5af7df47d4 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/queries/patterns.graphql +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/patterns.graphql @@ -13,6 +13,7 @@ scheduledArrival scheduledDeparture stopPosition + stopPositionInPattern realtimeState pickupType dropoffType diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan.graphql new file mode 100644 index 00000000000..5de2d2fdfef --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan.graphql @@ -0,0 +1,45 @@ +{ + plan( + from: { lat: 52.3092, lon: 13.0291 } + to: { lat: 52.5147, lon: 13.3927 } + date: "2023-02-15" + time: "11:37" + parking: { + unpreferredCost: 555 + preferred: [{ not: [{ tags: ["a", "b", "c"] }] }] + filters: [{ select: [{ tags: ["e"] }] }] + } + transportModes: [{ mode: CAR, qualifier: HAIL }] + via: [ + { passThrough: { label: "via1", stopLocationIds: ["F:BUS"] } } + { + visit: { + label: "via2" + stopLocationIds: ["F:RAIL"] + minimumWaitTime: "1h" + } + } + ] + ) { + itineraries { + start + end + legs { + mode + start { + scheduledTime + } + end { + scheduledTime + } + from { + name + } + to { + name + } + mode + } + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/planConnection-extended.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/planConnection-extended.graphql new file mode 100644 index 00000000000..1bbf9135321 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/planConnection-extended.graphql @@ -0,0 +1,250 @@ +{ + planConnection( + dateTime: { earliestDeparture: "2023-06-13T14:30+03:00" } + searchWindow: "PT2H30M" + first: 5 + origin: { + location: { coordinate: { latitude: 45.5552, longitude: -122.6534 } } + label: "Home" + } + destination: { + location: { coordinate: { latitude: 45.4908, longitude: -122.5519 } } + label: "Work" + } + via: [ + { passThrough: { label: "via1", stopLocationIds: ["F:BUS"] } } + { + visit: { + label: "via2" + stopLocationIds: ["F:RAIL"] + minimumWaitTime: "1h" + } + } + ] + modes: { + directOnly: false + transitOnly: false + direct: [WALK] + transit: { + access: [BICYCLE_RENTAL, WALK] + transfer: [WALK] + egress: [BICYCLE_RENTAL, WALK] + transit: [{ mode: TRAM, cost: { reluctance: 1.3 } }, { mode: BUS }] + } + } + preferences: { + accessibility: { wheelchair: { enabled: true } } + street: { + car: { + reluctance: 6.5 + rental: { + allowedNetworks: ["foo", "bar"] + bannedNetworks: ["foobar"] + } + parking: { + unpreferredCost: 200 + preferred: [{ select: [{ tags: ["best-park"] }] }] + filters: [{ not: [{ tags: ["worst-park"] }] }] + } + } + bicycle: { + reluctance: 3.0 + speed: 7.4 + optimization: { type: SAFEST_STREETS } + boardCost: 200 + walk: { + speed: 1.3 + cost: { mountDismountCost: 100, reluctance: 3.5 } + mountDismountTime: "PT5S" + } + rental: { + destinationBicyclePolicy: { allowKeeping: true, keepingCost: 300 } + allowedNetworks: ["foo", "bar"] + bannedNetworks: ["foobar"] + } + parking: { + unpreferredCost: 200 + preferred: [{ select: [{ tags: ["best-park"] }] }] + filters: [{ not: [{ tags: ["worst-park"] }] }] + } + } + walk: { speed: 2.4, reluctance: 1.5, safetyFactor: 0.5, boardCost: 200 } + } + transit: { + board: { waitReluctance: 3.2, slack: "PT1M30S" } + alight: { slack: "PT0S" } + transfer: { + cost: 200 + slack: "PT2M" + maximumAdditionalTransfers: 2 + maximumTransfers: 5 + } + timetable: { + excludeRealTimeUpdates: false + includePlannedCancellations: false + includeRealTimeCancellations: true + } + } + } + locale: "en" + ) { + searchDateTime + routingErrors { + code + } + pageInfo { + hasNextPage + hasPreviousPage + startCursor + endCursor + searchWindowUsed + } + edges { + cursor + node { + start + end + # next two are deprecated + startTime + endTime + generalizedCost + accessibilityScore + emissionsPerPerson { + co2 + } + numberOfTransfers + walkDistance + walkTime + legs { + mode + start { + scheduledTime + estimated { + time + delay + } + } + end { + scheduledTime + estimated { + time + delay + } + } + from { + name + lat + lon + arrival { + scheduledTime + estimated { + delay + time + } + } + departure { + scheduledTime + estimated { + delay + time + } + } + departureTime + arrivalTime + } + to { + name + lat + lon + arrival { + scheduledTime + estimated { + delay + time + } + } + departure { + scheduledTime + estimated { + delay + time + } + } + departureTime + arrivalTime + } + startTime + endTime + mode + generalizedCost + headsign + trip { + tripHeadsign + } + intermediatePlaces { + arrival { + scheduledTime + estimated { + time + delay + } + } + departure { + scheduledTime + estimated { + time + delay + } + } + stop { + name + } + } + alerts { + id + alertHeaderText + alertDescriptionText + alertEffect + alertCause + alertSeverityLevel + alertUrl + effectiveStartDate + effectiveEndDate + entities { + ... on Stop { + name + gtfsId + lat + lon + } + } + } + rideHailingEstimate { + provider { + id + } + productName + minPrice { + currency { + code + digits + } + amount + } + maxPrice { + currency { + code + digits + } + amount + } + arrival + } + accessibilityScore + id + realtimeState + } + } + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/planConnection-fares.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/planConnection-fares.graphql new file mode 100644 index 00000000000..7f8972ff208 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/planConnection-fares.graphql @@ -0,0 +1,60 @@ +{ + planConnection( + origin: { + location: { coordinate: { latitude: 45.5552, longitude: -122.6534 } } + } + destination: { + location: { coordinate: { latitude: 45.4908, longitude: -122.5519 } } + } + dateTime: { earliestDeparture: "2023-06-13T14:30-07:00" } + modes: { + direct: [WALK] + transit: { transit: [{ mode: BUS }, { mode: RAIL }] } + } + ) { + edges { + node { + legs { + mode + from { + name + lat + lon + } + to { + name + lat + lon + } + mode + generalizedCost + fareProducts { + id + product { + id + name + __typename + ... on DefaultFareProduct { + price { + currency { + digits + code + } + amount + } + } + riderCategory { + id + name + } + medium { + id + name + } + } + } + } + } + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/planConnection-stop-positions.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/planConnection-stop-positions.graphql new file mode 100644 index 00000000000..74063a93d81 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/planConnection-stop-positions.graphql @@ -0,0 +1,51 @@ +{ + planConnection( + origin: { + location: { coordinate: { latitude: 45.5552, longitude: -122.6534 } } + } + destination: { + location: { coordinate: { latitude: 45.4908, longitude: -122.5519 } } + } + dateTime: { earliestDeparture: "2023-06-13T14:30-07:00" } + modes: { + direct: [WALK] + transit: { transit: [{ mode: BUS }, { mode: RAIL }] } + } + ) { + edges { + node { + start + end + generalizedCost + accessibilityScore + legs { + mode + from { + name + lat + lon + stopPosition { + __typename + ... on PositionAtStop { + position + } + } + } + to { + name + lat + lon + stopPosition { + __typename + ... on PositionAtStop { + position + } + } + } + mode + generalizedCost + } + } + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/planConnection-tutorial.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/planConnection-tutorial.graphql new file mode 100644 index 00000000000..43b0be615c5 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/planConnection-tutorial.graphql @@ -0,0 +1,61 @@ +{ + planConnection( + origin: { + # these coordinates are in Portland, change this to YOUR origin + location: { coordinate: { latitude: 45.5552, longitude: -122.6534 } } + } + destination: { + # these coordinates are in Portland, change this to YOUR destination + location: { coordinate: { latitude: 45.4908, longitude: -122.5519 } } + } + # use the correct date and time of your request + dateTime: { earliestDeparture: "2023-06-13T14:30-07:00" } + # choose the transport modes you need + modes: { + direct: [WALK] + transit: { transit: [{ mode: BUS }, { mode: RAIL }] } + } + ) { + edges { + node { + start + end + legs { + mode + from { + name + lat + lon + departure { + scheduledTime + estimated { + time + delay + } + } + } + to { + name + lat + lon + arrival { + scheduledTime + estimated { + time + delay + } + } + } + route { + gtfsId + longName + shortName + } + legGeometry { + points + } + } + } + } + } +} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/rental-vehicle.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/rental-vehicle.graphql similarity index 100% rename from src/test/resources/org/opentripplanner/apis/gtfs/queries/rental-vehicle.graphql rename to application/src/test/resources/org/opentripplanner/apis/gtfs/queries/rental-vehicle.graphql diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/routes-extended.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/routes-extended.graphql similarity index 100% rename from src/test/resources/org/opentripplanner/apis/gtfs/queries/routes-extended.graphql rename to application/src/test/resources/org/opentripplanner/apis/gtfs/queries/routes-extended.graphql diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/routes-tutorial.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/routes-tutorial.graphql similarity index 100% rename from src/test/resources/org/opentripplanner/apis/gtfs/queries/routes-tutorial.graphql rename to application/src/test/resources/org/opentripplanner/apis/gtfs/queries/routes-tutorial.graphql diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql new file mode 100644 index 00000000000..af4fd904096 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql @@ -0,0 +1,21 @@ +{ + stops { + gtfsId + lat + lon + name + vehicleMode + allRoutes: routes { + gtfsId + longName + shortName + } + routesWithinRange: routes( + serviceDates: { start: "2024-09-10", end: "2024-09-10" } + ) { + gtfsId + longName + shortName + } + } +} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/vehicle-parking.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/vehicle-parking.graphql similarity index 100% rename from src/test/resources/org/opentripplanner/apis/gtfs/queries/vehicle-parking.graphql rename to application/src/test/resources/org/opentripplanner/apis/gtfs/queries/vehicle-parking.graphql diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/vehicle-rental-station.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/vehicle-rental-station.graphql similarity index 100% rename from src/test/resources/org/opentripplanner/apis/gtfs/queries/vehicle-rental-station.graphql rename to application/src/test/resources/org/opentripplanner/apis/gtfs/queries/vehicle-rental-station.graphql diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/vehicle-rentals-bybbox.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/vehicle-rentals-bybbox.graphql new file mode 100644 index 00000000000..26209f427f9 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/vehicle-rentals-bybbox.graphql @@ -0,0 +1,75 @@ +{ + vehicleRentalsByBbox( + maximumLatitude: 48.00 + maximumLongitude: 19.10 + minimumLatitude: 47.50 + minimumLongitude: 18.80 + ) { + __typename + ... on RentalVehicle { + vehicleId + name + allowPickupNow + lon + lat + rentalUris { + android + ios + web + } + operative + vehicleType { + formFactor + propulsionType + } + rentalNetwork { + networkId + url + } + } + ... on VehicleRentalStation { + stationId + name + vehiclesAvailable + availableVehicles { + byType { + vehicleType { + formFactor + propulsionType + } + count + } + total + } + spacesAvailable + availableSpaces { + byType { + vehicleType { + formFactor + propulsionType + } + count + } + total + } + allowDropoff + allowPickup + allowDropoffNow + allowPickupNow + lon + lat + capacity + allowOverloading + rentalUris { + android + ios + web + } + operative + rentalNetwork { + networkId + url + } + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql new file mode 100644 index 00000000000..dd2b96395ad --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql @@ -0,0 +1,28 @@ +{ + planConnection( + origin: { + location: { coordinate: { latitude: 45.5552, longitude: -122.6534 } } + } + destination: { + location: { coordinate: { latitude: 45.4908, longitude: -122.5519 } } + } + dateTime: { earliestDeparture: "2023-06-13T14:30-07:00" } + modes: { + direct: [WALK] + transit: { transit: [{ mode: BUS }, { mode: RAIL }] } + } + ) { + edges { + node { + legs { + steps { + streetName + area + relativeDirection + absoluteDirection + } + } + } + } + } +} diff --git a/application/src/test/resources/org/opentripplanner/apis/vectortiles/style.json b/application/src/test/resources/org/opentripplanner/apis/vectortiles/style.json new file mode 100644 index 00000000000..66858390ab5 --- /dev/null +++ b/application/src/test/resources/org/opentripplanner/apis/vectortiles/style.json @@ -0,0 +1,688 @@ +{ + "name": "OTP Debug Tiles", + "sources": { + "positron": { + "name": "Positron", + "tiles": [ + "https://cartodb-basemaps-a.global.ssl.fastly.net/light_all/{z}/{x}/{y}{ratio}.png" + ], + "maxzoom": 19, + "tileSize": 256, + "attribution": "© OpenStreetMap, © CARTO", + "type": "raster" + }, + "vectorSource": { + "id": "vectorSource", + "url": "https://example.com", + "type": "vector" + }, + "osm-carto": { + "name": "OSM Carto", + "tiles": ["https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"], + "maxzoom": 19, + "tileSize": 256, + "attribution": "© OpenStreetMap Contributors", + "type": "raster" + } + }, + "layers": [ + { + "id": "osm-carto", + "type": "raster", + "source": "osm-carto", + "minzoom": 0, + "metadata": { + "group": "Other", + "name": "OSM Carto" + } + }, + { + "id": "positron", + "type": "raster", + "source": "positron", + "minzoom": 0, + "layout": { + "visibility": "none" + }, + "metadata": { + "group": "Other", + "name": "Positron" + } + }, + { + "id": "wheelchair-accessible", + "source": "vectorSource", + "source-layer": "edges", + "type": "line", + "minzoom": 6, + "maxzoom": 23, + "paint": { + "line-color": "#136b04", + "line-width": ["interpolate", ["linear"], ["zoom"], 13, 0.2, 23, 8.0], + "line-offset": ["interpolate", ["linear"], ["zoom"], 13, 0.4, 23, 7.0] + }, + "filter": ["==", "wheelchairAccessible", true], + "layout": { + "line-cap": "round", + "visibility": "none" + }, + "metadata": { + "group": "Wheelchair accessibility" + } + }, + { + "id": "wheelchair-inaccessible", + "source": "vectorSource", + "source-layer": "edges", + "type": "line", + "minzoom": 6, + "maxzoom": 23, + "paint": { + "line-color": "#fc0f2a", + "line-width": ["interpolate", ["linear"], ["zoom"], 13, 0.2, 23, 8.0], + "line-offset": ["interpolate", ["linear"], ["zoom"], 13, 0.4, 23, 7.0] + }, + "filter": ["==", "wheelchairAccessible", false], + "layout": { + "line-cap": "round", + "visibility": "none" + }, + "metadata": { + "group": "Wheelchair accessibility" + } + }, + { + "id": "no-thru-traffic PEDESTRIAN", + "source": "vectorSource", + "source-layer": "edges", + "type": "line", + "minzoom": 13, + "maxzoom": 23, + "paint": { + "line-color": [ + "match", + ["get", "noThruTraffic"], + "NONE", + "#140d0e", + "PEDESTRIAN", + "#2ba812", + "BICYCLE", + "#10d3b6", + "PEDESTRIAN BICYCLE", + "#10d3b6", + "CAR", + "#f92e13", + "PEDESTRIAN CAR", + "#e25f8f", + "BICYCLE CAR", + "#e25f8f", + "ALL", + "#adb2b0", + "#140d0e" + ], + "line-width": ["interpolate", ["linear"], ["zoom"], 13, 0.2, 23, 8.0], + "line-offset": ["interpolate", ["linear"], ["zoom"], 13, 0.4, 23, 7.0] + }, + "filter": [ + "any", + ["in", "PEDESTRIAN", ["string", ["get", "noThruTraffic"]]], + ["in", "ALL", ["string", ["get", "noThruTraffic"]]] + ], + "layout": { + "line-cap": "butt", + "visibility": "none" + }, + "metadata": { + "group": "No-thru traffic" + } + }, + { + "id": "no-thru-traffic BICYCLE", + "source": "vectorSource", + "source-layer": "edges", + "type": "line", + "minzoom": 13, + "maxzoom": 23, + "paint": { + "line-color": [ + "match", + ["get", "noThruTraffic"], + "NONE", + "#140d0e", + "PEDESTRIAN", + "#2ba812", + "BICYCLE", + "#10d3b6", + "PEDESTRIAN BICYCLE", + "#10d3b6", + "CAR", + "#f92e13", + "PEDESTRIAN CAR", + "#e25f8f", + "BICYCLE CAR", + "#e25f8f", + "ALL", + "#adb2b0", + "#140d0e" + ], + "line-width": ["interpolate", ["linear"], ["zoom"], 13, 0.2, 23, 8.0], + "line-offset": ["interpolate", ["linear"], ["zoom"], 13, 0.4, 23, 7.0] + }, + "filter": [ + "any", + ["in", "BICYCLE", ["string", ["get", "noThruTraffic"]]], + ["in", "ALL", ["string", ["get", "noThruTraffic"]]] + ], + "layout": { + "line-cap": "butt", + "visibility": "none" + }, + "metadata": { + "group": "No-thru traffic" + } + }, + { + "id": "no-thru-traffic CAR", + "source": "vectorSource", + "source-layer": "edges", + "type": "line", + "minzoom": 13, + "maxzoom": 23, + "paint": { + "line-color": [ + "match", + ["get", "noThruTraffic"], + "NONE", + "#140d0e", + "PEDESTRIAN", + "#2ba812", + "BICYCLE", + "#10d3b6", + "PEDESTRIAN BICYCLE", + "#10d3b6", + "CAR", + "#f92e13", + "PEDESTRIAN CAR", + "#e25f8f", + "BICYCLE CAR", + "#e25f8f", + "ALL", + "#adb2b0", + "#140d0e" + ], + "line-width": ["interpolate", ["linear"], ["zoom"], 13, 0.2, 23, 8.0], + "line-offset": ["interpolate", ["linear"], ["zoom"], 13, 0.4, 23, 7.0] + }, + "filter": [ + "any", + ["in", "CAR", ["string", ["get", "noThruTraffic"]]], + ["in", "ALL", ["string", ["get", "noThruTraffic"]]] + ], + "layout": { + "line-cap": "butt", + "visibility": "none" + }, + "metadata": { + "group": "No-thru traffic" + } + }, + { + "id": "no-thru-traffic-text", + "source": "vectorSource", + "source-layer": "edges", + "type": "symbol", + "minzoom": 17, + "maxzoom": 23, + "paint": { + "text-color": "#000", + "text-halo-color": "#fff", + "text-halo-blur": 4, + "text-halo-width": 3 + }, + "filter": [ + "in", + "class", + "StreetEdge", + "AreaEdge", + "EscalatorEdge", + "PathwayEdge", + "ElevatorHopEdge", + "TemporaryPartialStreetEdge", + "TemporaryFreeEdge" + ], + "layout": { + "symbol-placement": "line-center", + "symbol-spacing": 1000, + "text-field": "{noThruTraffic}", + "text-font": ["KlokanTech Noto Sans Regular"], + "text-size": ["interpolate", ["linear"], ["zoom"], 10, 6.0, 24, 12.0], + "text-max-width": 100, + "text-keep-upright": true, + "text-rotation-alignment": "map", + "text-overlap": "never", + "text-offset": [0, 1.0], + "visibility": "none" + }, + "metadata": { + "group": "No-thru traffic" + } + }, + { + "id": "permission PEDESTRIAN", + "source": "vectorSource", + "source-layer": "edges", + "type": "line", + "minzoom": 13, + "maxzoom": 23, + "paint": { + "line-color": [ + "match", + ["get", "permission"], + "NONE", + "#140d0e", + "PEDESTRIAN", + "#2ba812", + "BICYCLE", + "#10d3b6", + "PEDESTRIAN BICYCLE", + "#10d3b6", + "CAR", + "#f92e13", + "PEDESTRIAN CAR", + "#e25f8f", + "BICYCLE CAR", + "#e25f8f", + "ALL", + "#adb2b0", + "#140d0e" + ], + "line-width": ["interpolate", ["linear"], ["zoom"], 13, 0.2, 23, 8.0], + "line-offset": ["interpolate", ["linear"], ["zoom"], 13, 0.4, 23, 7.0] + }, + "filter": [ + "any", + ["in", "PEDESTRIAN", ["string", ["get", "permission"]]], + ["in", "ALL", ["string", ["get", "permission"]]] + ], + "layout": { + "line-cap": "butt", + "visibility": "none" + }, + "metadata": { + "group": "Permissions" + } + }, + { + "id": "permission BICYCLE", + "source": "vectorSource", + "source-layer": "edges", + "type": "line", + "minzoom": 13, + "maxzoom": 23, + "paint": { + "line-color": [ + "match", + ["get", "permission"], + "NONE", + "#140d0e", + "PEDESTRIAN", + "#2ba812", + "BICYCLE", + "#10d3b6", + "PEDESTRIAN BICYCLE", + "#10d3b6", + "CAR", + "#f92e13", + "PEDESTRIAN CAR", + "#e25f8f", + "BICYCLE CAR", + "#e25f8f", + "ALL", + "#adb2b0", + "#140d0e" + ], + "line-width": ["interpolate", ["linear"], ["zoom"], 13, 0.2, 23, 8.0], + "line-offset": ["interpolate", ["linear"], ["zoom"], 13, 0.4, 23, 7.0] + }, + "filter": [ + "any", + ["in", "BICYCLE", ["string", ["get", "permission"]]], + ["in", "ALL", ["string", ["get", "permission"]]] + ], + "layout": { + "line-cap": "butt", + "visibility": "none" + }, + "metadata": { + "group": "Permissions" + } + }, + { + "id": "permission CAR", + "source": "vectorSource", + "source-layer": "edges", + "type": "line", + "minzoom": 13, + "maxzoom": 23, + "paint": { + "line-color": [ + "match", + ["get", "permission"], + "NONE", + "#140d0e", + "PEDESTRIAN", + "#2ba812", + "BICYCLE", + "#10d3b6", + "PEDESTRIAN BICYCLE", + "#10d3b6", + "CAR", + "#f92e13", + "PEDESTRIAN CAR", + "#e25f8f", + "BICYCLE CAR", + "#e25f8f", + "ALL", + "#adb2b0", + "#140d0e" + ], + "line-width": ["interpolate", ["linear"], ["zoom"], 13, 0.2, 23, 8.0], + "line-offset": ["interpolate", ["linear"], ["zoom"], 13, 0.4, 23, 7.0] + }, + "filter": [ + "any", + ["in", "CAR", ["string", ["get", "permission"]]], + ["in", "ALL", ["string", ["get", "permission"]]] + ], + "layout": { + "line-cap": "butt", + "visibility": "none" + }, + "metadata": { + "group": "Permissions" + } + }, + { + "id": "permission-text", + "source": "vectorSource", + "source-layer": "edges", + "type": "symbol", + "minzoom": 17, + "maxzoom": 23, + "paint": { + "text-color": "#000", + "text-halo-color": "#fff", + "text-halo-blur": 4, + "text-halo-width": 3 + }, + "filter": [ + "in", + "class", + "StreetEdge", + "AreaEdge", + "EscalatorEdge", + "PathwayEdge", + "ElevatorHopEdge", + "TemporaryPartialStreetEdge", + "TemporaryFreeEdge" + ], + "layout": { + "symbol-placement": "line-center", + "symbol-spacing": 1000, + "text-field": "{permission}", + "text-font": ["KlokanTech Noto Sans Regular"], + "text-size": ["interpolate", ["linear"], ["zoom"], 10, 6.0, 24, 12.0], + "text-max-width": 100, + "text-keep-upright": true, + "text-rotation-alignment": "map", + "text-overlap": "never", + "text-offset": [0, 1.0], + "visibility": "none" + }, + "metadata": { + "group": "Permissions" + } + }, + { + "id": "edge", + "type": "line", + "source": "vectorSource", + "source-layer": "edges", + "minzoom": 6, + "maxzoom": 23, + "paint": { + "line-color": "#f21d52", + "line-width": ["interpolate", ["linear"], ["zoom"], 13, 0.1, 23, 6.0], + "line-offset": ["interpolate", ["linear"], ["zoom"], 13, 0.4, 23, 7.0] + }, + "filter": [ + "in", + "class", + "StreetEdge", + "AreaEdge", + "EscalatorEdge", + "PathwayEdge", + "ElevatorHopEdge", + "TemporaryPartialStreetEdge", + "TemporaryFreeEdge" + ], + "layout": { + "line-cap": "round", + "visibility": "none" + }, + "metadata": { + "group": "Edges" + } + }, + { + "id": "edge-name", + "type": "symbol", + "source": "vectorSource", + "source-layer": "edges", + "minzoom": 17, + "maxzoom": 23, + "paint": { + "text-color": "#000", + "text-halo-color": "#fff", + "text-halo-blur": 4, + "text-halo-width": 3 + }, + "filter": [ + "in", + "class", + "StreetEdge", + "AreaEdge", + "EscalatorEdge", + "PathwayEdge", + "ElevatorHopEdge", + "TemporaryPartialStreetEdge", + "TemporaryFreeEdge" + ], + "layout": { + "symbol-placement": "line-center", + "symbol-spacing": 1000, + "text-field": "{name}", + "text-font": ["KlokanTech Noto Sans Regular"], + "text-size": ["interpolate", ["linear"], ["zoom"], 10, 6.0, 24, 12.0], + "text-max-width": 100, + "text-keep-upright": true, + "text-rotation-alignment": "map", + "text-overlap": "never", + "visibility": "none" + }, + "metadata": { + "group": "Edges" + } + }, + { + "id": "link", + "type": "line", + "source": "vectorSource", + "source-layer": "edges", + "minzoom": 13, + "maxzoom": 23, + "paint": { + "line-color": "#22DD9E", + "line-width": ["interpolate", ["linear"], ["zoom"], 13, 0.2, 23, 8.0], + "line-offset": ["interpolate", ["linear"], ["zoom"], 13, 0.4, 23, 7.0] + }, + "filter": [ + "in", + "class", + "StreetTransitStopLink", + "StreetTransitEntranceLink", + "BoardingLocationToStopLink", + "StreetVehicleRentalLink", + "StreetVehicleParkingLink", + "StreetStationCentroidLink" + ], + "layout": { + "line-cap": "round", + "visibility": "none" + }, + "metadata": { + "group": "Edges" + } + }, + { + "id": "vertex", + "type": "circle", + "source": "vectorSource", + "source-layer": "vertices", + "minzoom": 15, + "maxzoom": 23, + "paint": { + "circle-stroke-color": "#140d0e", + "circle-stroke-width": [ + "interpolate", + ["linear"], + ["zoom"], + 15, + 0.2, + 23, + 3.0 + ], + "circle-radius": [ + "interpolate", + ["linear"], + ["zoom"], + 15, + 1.0, + 23, + 7.0 + ], + "circle-color": "#BC55F2" + }, + "layout": { + "visibility": "none" + }, + "metadata": { + "group": "Vertices" + } + }, + { + "id": "parking-vertex", + "type": "circle", + "source": "vectorSource", + "source-layer": "vertices", + "minzoom": 13, + "maxzoom": 23, + "paint": { + "circle-stroke-color": "#140d0e", + "circle-stroke-width": [ + "interpolate", + ["linear"], + ["zoom"], + 15, + 0.2, + 23, + 3.0 + ], + "circle-radius": [ + "interpolate", + ["linear"], + ["zoom"], + 13, + 1.4, + 23, + 10.0 + ], + "circle-color": "#136b04" + }, + "filter": ["in", "class", "VehicleParkingEntranceVertex"], + "layout": { + "visibility": "none" + }, + "metadata": { + "group": "Vertices" + } + }, + { + "id": "area-stop", + "type": "fill", + "source": "vectorSource", + "source-layer": "stops", + "minzoom": 6, + "maxzoom": 23, + "paint": { + "fill-color": "#22DD9E", + "fill-opacity": 0.5, + "fill-outline-color": "#140d0e" + }, + "metadata": { + "group": "Stops" + } + }, + { + "id": "group-stop", + "type": "fill", + "source": "vectorSource", + "source-layer": "stops", + "minzoom": 6, + "maxzoom": 23, + "paint": { + "fill-color": "#22DD9E", + "fill-opacity": 0.5, + "fill-outline-color": "#140d0e" + }, + "metadata": { + "group": "Stops" + } + }, + { + "id": "regular-stop", + "type": "circle", + "source": "vectorSource", + "source-layer": "stops", + "minzoom": 10, + "maxzoom": 23, + "paint": { + "circle-stroke-color": "#140d0e", + "circle-stroke-width": [ + "interpolate", + ["linear"], + ["zoom"], + 11, + 0.5, + 23, + 5.0 + ], + "circle-radius": [ + "interpolate", + ["linear"], + ["zoom"], + 11, + 0.5, + 23, + 10.0 + ], + "circle-color": "#fcf9fa" + }, + "metadata": { + "group": "Stops" + } + } + ], + "version": 8, + "glyphs": "https://cdn.jsdelivr.net/gh/klokantech/klokantech-gl-fonts@master/{fontstack}/{range}.pbf" +} diff --git a/src/test/resources/org/opentripplanner/datastore/file/umlaut-cp437.zip b/application/src/test/resources/org/opentripplanner/datastore/file/umlaut-cp437.zip similarity index 100% rename from src/test/resources/org/opentripplanner/datastore/file/umlaut-cp437.zip rename to application/src/test/resources/org/opentripplanner/datastore/file/umlaut-cp437.zip diff --git a/src/test/resources/org/opentripplanner/datastore/file/umlaut-utf8-no-efs.zip b/application/src/test/resources/org/opentripplanner/datastore/file/umlaut-utf8-no-efs.zip similarity index 100% rename from src/test/resources/org/opentripplanner/datastore/file/umlaut-utf8-no-efs.zip rename to application/src/test/resources/org/opentripplanner/datastore/file/umlaut-utf8-no-efs.zip diff --git a/src/test/resources/org/opentripplanner/datastore/file/umlaut-utf8.zip b/application/src/test/resources/org/opentripplanner/datastore/file/umlaut-utf8.zip similarity index 100% rename from src/test/resources/org/opentripplanner/datastore/file/umlaut-utf8.zip rename to application/src/test/resources/org/opentripplanner/datastore/file/umlaut-utf8.zip diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/herrenberg-minimal.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/herrenberg-minimal.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/herrenberg-minimal.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/herrenberg-minimal.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/islandpruning/herrenberg-island-prune-nothru.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/islandpruning/herrenberg-island-prune-nothru.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/islandpruning/herrenberg-island-prune-nothru.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/islandpruning/herrenberg-island-prune-nothru.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/islandpruning/isoiiluoto.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/islandpruning/isoiiluoto.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/islandpruning/isoiiluoto.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/islandpruning/isoiiluoto.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/islandpruning/matinkyla-escalator.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/islandpruning/matinkyla-escalator.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/islandpruning/matinkyla-escalator.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/islandpruning/matinkyla-escalator.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/linking/columbus.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/linking/columbus.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/linking/columbus.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/linking/columbus.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/B+R.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/B+R.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/B+R.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/B+R.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/NYC_small.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/NYC_small.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/NYC_small.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/NYC_small.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/P+R.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/P+R.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/P+R.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/P+R.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/accessno-at-end.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/accessno-at-end.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/accessno-at-end.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/accessno-at-end.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/brenner-invalid-relation-reference.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/brenner-invalid-relation-reference.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/brenner-invalid-relation-reference.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/brenner-invalid-relation-reference.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/bridge_construction.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/bridge_construction.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/bridge_construction.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/bridge_construction.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr_dupl.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr_dupl.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr_dupl.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr_dupl.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr_overlap.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr_overlap.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr_overlap.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr_overlap.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr_reverse.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr_reverse.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr_reverse.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/coincident_pr_reverse.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/ehningen-minimal.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/ehningen-minimal.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/ehningen-minimal.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/ehningen-minimal.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/hackett_pr.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/hackett_pr.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/hackett_pr.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/hackett_pr.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/lund-station-sweden.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/lund-station-sweden.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/lund-station-sweden.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/lund-station-sweden.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/map.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/map.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/map.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/map.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/skoyen.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/skoyen.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/skoyen.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/skoyen.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/stopareas.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/stopareas.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/stopareas.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/stopareas.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/usf_area.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/usf_area.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/usf_area.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/usf_area.osm.pbf diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/osm/wendlingen-bahnhof.osm.pbf b/application/src/test/resources/org/opentripplanner/graph_builder/module/osm/wendlingen-bahnhof.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/graph_builder/module/osm/wendlingen-bahnhof.osm.pbf rename to application/src/test/resources/org/opentripplanner/graph_builder/module/osm/wendlingen-bahnhof.osm.pbf diff --git a/src/test/resources/org/opentripplanner/oslo-east-filtered.osm.pbf b/application/src/test/resources/org/opentripplanner/oslo-east-filtered.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/oslo-east-filtered.osm.pbf rename to application/src/test/resources/org/opentripplanner/oslo-east-filtered.osm.pbf diff --git a/src/test/resources/org/opentripplanner/street/integration/boeblingen-minimal.osm.pbf b/application/src/test/resources/org/opentripplanner/street/integration/boeblingen-minimal.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/street/integration/boeblingen-minimal.osm.pbf rename to application/src/test/resources/org/opentripplanner/street/integration/boeblingen-minimal.osm.pbf diff --git a/src/test/resources/org/opentripplanner/street/integration/deufringen-minimal.osm.pbf b/application/src/test/resources/org/opentripplanner/street/integration/deufringen-minimal.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/street/integration/deufringen-minimal.osm.pbf rename to application/src/test/resources/org/opentripplanner/street/integration/deufringen-minimal.osm.pbf diff --git a/src/test/resources/org/opentripplanner/street/integration/herrenberg-barrier-gates.osm.pbf b/application/src/test/resources/org/opentripplanner/street/integration/herrenberg-barrier-gates.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/street/integration/herrenberg-barrier-gates.osm.pbf rename to application/src/test/resources/org/opentripplanner/street/integration/herrenberg-barrier-gates.osm.pbf diff --git a/src/test/resources/org/opentripplanner/street/integration/herrenberg-hindenburgstr-under-construction.osm.pbf b/application/src/test/resources/org/opentripplanner/street/integration/herrenberg-hindenburgstr-under-construction.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/street/integration/herrenberg-hindenburgstr-under-construction.osm.pbf rename to application/src/test/resources/org/opentripplanner/street/integration/herrenberg-hindenburgstr-under-construction.osm.pbf diff --git a/src/test/resources/org/opentripplanner/street/integration/herrenberg-minimal.osm.pbf b/application/src/test/resources/org/opentripplanner/street/integration/herrenberg-minimal.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/street/integration/herrenberg-minimal.osm.pbf rename to application/src/test/resources/org/opentripplanner/street/integration/herrenberg-minimal.osm.pbf diff --git a/src/test/resources/org/opentripplanner/street/integration/roundabout.osm.pbf b/application/src/test/resources/org/opentripplanner/street/integration/roundabout.osm.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/street/integration/roundabout.osm.pbf rename to application/src/test/resources/org/opentripplanner/street/integration/roundabout.osm.pbf diff --git a/src/test/resources/org/opentripplanner/street/integration/vvs-bus-751-only.gtfs.zip b/application/src/test/resources/org/opentripplanner/street/integration/vvs-bus-751-only.gtfs.zip similarity index 100% rename from src/test/resources/org/opentripplanner/street/integration/vvs-bus-751-only.gtfs.zip rename to application/src/test/resources/org/opentripplanner/street/integration/vvs-bus-751-only.gtfs.zip diff --git a/src/test/resources/org/opentripplanner/street/integration/vvs-bus-764-only.gtfs.zip b/application/src/test/resources/org/opentripplanner/street/integration/vvs-bus-764-only.gtfs.zip similarity index 100% rename from src/test/resources/org/opentripplanner/street/integration/vvs-bus-764-only.gtfs.zip rename to application/src/test/resources/org/opentripplanner/street/integration/vvs-bus-764-only.gtfs.zip diff --git a/src/test/resources/org/opentripplanner/transit/service/kcm_gtfs.zip b/application/src/test/resources/org/opentripplanner/transit/service/kcm_gtfs.zip similarity index 100% rename from src/test/resources/org/opentripplanner/transit/service/kcm_gtfs.zip rename to application/src/test/resources/org/opentripplanner/transit/service/kcm_gtfs.zip diff --git a/src/test/resources/org/opentripplanner/updater/trip/septa.pbf b/application/src/test/resources/org/opentripplanner/updater/trip/septa.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/updater/trip/septa.pbf rename to application/src/test/resources/org/opentripplanner/updater/trip/septa.pbf diff --git a/src/test/resources/org/opentripplanner/updater/vehicle_position/king-county-metro-1.pbf b/application/src/test/resources/org/opentripplanner/updater/vehicle_position/king-county-metro-1.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/updater/vehicle_position/king-county-metro-1.pbf rename to application/src/test/resources/org/opentripplanner/updater/vehicle_position/king-county-metro-1.pbf diff --git a/src/test/resources/org/opentripplanner/updater/vehicle_position/king-county-metro-2.pbf b/application/src/test/resources/org/opentripplanner/updater/vehicle_position/king-county-metro-2.pbf similarity index 100% rename from src/test/resources/org/opentripplanner/updater/vehicle_position/king-county-metro-2.pbf rename to application/src/test/resources/org/opentripplanner/updater/vehicle_position/king-county-metro-2.pbf diff --git a/src/test/resources/portland/build-config.json b/application/src/test/resources/portland/build-config.json similarity index 98% rename from src/test/resources/portland/build-config.json rename to application/src/test/resources/portland/build-config.json index 910f54d7211..96cfdec93a7 100644 --- a/src/test/resources/portland/build-config.json +++ b/application/src/test/resources/portland/build-config.json @@ -3,4 +3,4 @@ "transitServiceEnd": "2010-03-01", "staticBikeParkAndRide": true, "staticParkAndRide": true -} \ No newline at end of file +} diff --git a/src/test/resources/portland/portland-central-filtered.osm.pbf b/application/src/test/resources/portland/portland-central-filtered.osm.pbf similarity index 100% rename from src/test/resources/portland/portland-central-filtered.osm.pbf rename to application/src/test/resources/portland/portland-central-filtered.osm.pbf diff --git a/src/test/resources/portland/portland-ned-nodata.tif b/application/src/test/resources/portland/portland-ned-nodata.tif similarity index 100% rename from src/test/resources/portland/portland-ned-nodata.tif rename to application/src/test/resources/portland/portland-ned-nodata.tif diff --git a/src/test/resources/portland/portland-ned.tif b/application/src/test/resources/portland/portland-ned.tif similarity index 100% rename from src/test/resources/portland/portland-ned.tif rename to application/src/test/resources/portland/portland-ned.tif diff --git a/src/test/resources/portland/portland-vehicle-rental.csv b/application/src/test/resources/portland/portland-vehicle-rental.csv similarity index 100% rename from src/test/resources/portland/portland-vehicle-rental.csv rename to application/src/test/resources/portland/portland-vehicle-rental.csv diff --git a/src/test/resources/portland/portland.gtfs.zip b/application/src/test/resources/portland/portland.gtfs.zip similarity index 100% rename from src/test/resources/portland/portland.gtfs.zip rename to application/src/test/resources/portland/portland.gtfs.zip diff --git a/application/src/test/resources/portland/router-config.json b/application/src/test/resources/portland/router-config.json new file mode 100644 index 00000000000..0967ef424bc --- /dev/null +++ b/application/src/test/resources/portland/router-config.json @@ -0,0 +1 @@ +{} diff --git a/src/test/resources/speedtest/speed-test-config.json b/application/src/test/resources/speedtest/speed-test-config.json similarity index 77% rename from src/test/resources/speedtest/speed-test-config.json rename to application/src/test/resources/speedtest/speed-test-config.json index af5c0745ab0..ca8f9e02807 100644 --- a/src/test/resources/speedtest/speed-test-config.json +++ b/application/src/test/resources/speedtest/speed-test-config.json @@ -2,11 +2,11 @@ // Run all test-cases on the given date "testDate": "2009-12-17", "feedId": "1", - "ignoreStreetResults" : true, + "ignoreStreetResults": true, "routingDefaults": { - "itineraryFilters" : { + "itineraryFilters": { // We do not want the filter chain to remove itineraries "debug": "LIST_ALL" } } -} \ No newline at end of file +} diff --git a/application/src/test/resources/speedtest/travelSearch-expected-results-bd.csv b/application/src/test/resources/speedtest/travelSearch-expected-results-bd.csv new file mode 100644 index 00000000000..b38e60d5edb --- /dev/null +++ b/application/src/test/resources/speedtest/travelSearch-expected-results-bd.csv @@ -0,0 +1,3 @@ +tcId,nTransfers,duration,cost,walkDistance,startTime,endTime,agencies,modes,routes,stops,details +1,0,42m16s,-1,0,12:00:00,12:42:16,,,,,Unknown transit 0tx 42m16s +2,0,42m16s,-1,0,12:00:00,12:42:16,,,,,Unknown transit 0tx 42m16s diff --git a/src/test/resources/speedtest/travelSearch-expected-results-bdr.csv b/application/src/test/resources/speedtest/travelSearch-expected-results-bdr.csv similarity index 100% rename from src/test/resources/speedtest/travelSearch-expected-results-bdr.csv rename to application/src/test/resources/speedtest/travelSearch-expected-results-bdr.csv diff --git a/src/test/resources/speedtest/travelSearch-expected-results-bt.csv b/application/src/test/resources/speedtest/travelSearch-expected-results-bt.csv similarity index 100% rename from src/test/resources/speedtest/travelSearch-expected-results-bt.csv rename to application/src/test/resources/speedtest/travelSearch-expected-results-bt.csv diff --git a/application/src/test/resources/speedtest/travelSearch-expected-results-btr.csv b/application/src/test/resources/speedtest/travelSearch-expected-results-btr.csv new file mode 100644 index 00000000000..db49235d649 --- /dev/null +++ b/application/src/test/resources/speedtest/travelSearch-expected-results-btr.csv @@ -0,0 +1,3 @@ +tcId,nTransfers,duration,cost,walkDistance,startTime,endTime,agencies,modes,routes,stops,details +1,0,1h9m14s,-1,0,12:50:46,14:00:00,,,,,Unknown transit 0tx 1h9m14s +2,0,1h9m14s,-1,0,12:50:46,14:00:00,,,,,Unknown transit 0tx 1h9m14s diff --git a/src/test/resources/speedtest/travelSearch-expected-results-mc.csv b/application/src/test/resources/speedtest/travelSearch-expected-results-mc.csv similarity index 100% rename from src/test/resources/speedtest/travelSearch-expected-results-mc.csv rename to application/src/test/resources/speedtest/travelSearch-expected-results-mc.csv diff --git a/src/test/resources/speedtest/travelSearch-expected-results-md.csv b/application/src/test/resources/speedtest/travelSearch-expected-results-md.csv similarity index 100% rename from src/test/resources/speedtest/travelSearch-expected-results-md.csv rename to application/src/test/resources/speedtest/travelSearch-expected-results-md.csv diff --git a/src/test/resources/speedtest/travelSearch-expected-results-rr.csv b/application/src/test/resources/speedtest/travelSearch-expected-results-rr.csv similarity index 100% rename from src/test/resources/speedtest/travelSearch-expected-results-rr.csv rename to application/src/test/resources/speedtest/travelSearch-expected-results-rr.csv diff --git a/src/test/resources/speedtest/travelSearch-expected-results-sr.csv b/application/src/test/resources/speedtest/travelSearch-expected-results-sr.csv similarity index 100% rename from src/test/resources/speedtest/travelSearch-expected-results-sr.csv rename to application/src/test/resources/speedtest/travelSearch-expected-results-sr.csv diff --git a/src/test/resources/speedtest/travelSearch-expected-results-srr.csv b/application/src/test/resources/speedtest/travelSearch-expected-results-srr.csv similarity index 100% rename from src/test/resources/speedtest/travelSearch-expected-results-srr.csv rename to application/src/test/resources/speedtest/travelSearch-expected-results-srr.csv diff --git a/src/test/resources/speedtest/travelSearch-expected-results-tb.csv b/application/src/test/resources/speedtest/travelSearch-expected-results-tb.csv similarity index 100% rename from src/test/resources/speedtest/travelSearch-expected-results-tb.csv rename to application/src/test/resources/speedtest/travelSearch-expected-results-tb.csv diff --git a/src/test/resources/speedtest/travelSearch-expected-results-td.csv b/application/src/test/resources/speedtest/travelSearch-expected-results-td.csv similarity index 100% rename from src/test/resources/speedtest/travelSearch-expected-results-td.csv rename to application/src/test/resources/speedtest/travelSearch-expected-results-td.csv diff --git a/src/test/resources/speedtest/travelSearch-results.csv b/application/src/test/resources/speedtest/travelSearch-results.csv similarity index 100% rename from src/test/resources/speedtest/travelSearch-results.csv rename to application/src/test/resources/speedtest/travelSearch-results.csv diff --git a/src/test/resources/speedtest/travelSearch.csv b/application/src/test/resources/speedtest/travelSearch.csv similarity index 100% rename from src/test/resources/speedtest/travelSearch.csv rename to application/src/test/resources/speedtest/travelSearch.csv diff --git a/application/src/test/resources/standalone/config/build-config.json b/application/src/test/resources/standalone/config/build-config.json new file mode 100644 index 00000000000..11ea4a36b2e --- /dev/null +++ b/application/src/test/resources/standalone/config/build-config.json @@ -0,0 +1,86 @@ +{ + "transitServiceStart": "-P3M", + "transitServiceEnd": "P1Y", + "osmCacheDataInMem": true, + "localFileNamePatterns": { + "osm": "(i?)\\.osm\\.pbf$", + "dem": "(i?)\\.dem\\.tiff?$", + "gtfs": "(?i)gtfs", + "netex": "(?i)netex" + }, + + "osmDefaults": { + "timeZone": "Europe/Rome", + "osmTagMapping": "default" + }, + "osm": [ + { + "source": "gs://my-bucket/otp-work-dir/norway.osm.pbf", + "timeZone": "Europe/Oslo", + "osmTagMapping": "norway" + } + ], + "demDefaults": { + "elevationUnitMultiplier": 1.0 + }, + "dem": [ + { + "source": "gs://my-bucket/otp-work-dir/norway.dem.tiff", + "elevationUnitMultiplier": 2.5 + } + ], + "netexDefaults": { + "feedId": "EN", + "sharedFilePattern": "_stops.xml", + "sharedGroupFilePattern": "_(\\w{3})_shared_data.xml", + "groupFilePattern": "(\\w{3})_.*\\.xml", + "ignoreFilePattern": "(temp|tmp)", + "ferryIdsNotAllowedForBicycle": ["RUT:B107", "RUT:B209"] + }, + "gtfsDefaults": { + "stationTransferPreference": "recommended", + "removeRepeatedStops": true, + "discardMinTransferTimes": false, + "blockBasedInterlining": true, + "maxInterlineDistance": 200 + }, + "islandPruning": { + "islandWithStopsMaxSize": 2, + "islandWithoutStopsMaxSize": 10, + "adaptivePruningFactor": 50.0, + "adaptivePruningDistance": 250 + }, + "transitFeeds": [ + { + "type": "gtfs", + "feedId": "SE", + "source": "https://skanetrafiken.se/download/sweden.gtfs.zip" + }, + { + "type": "netex", + "feedId": "NO", + "source": "gs://BUCKET/OTP_GCS_WORK_DIR/norway-netex.obj", + "sharedFilePattern": "_stops.xml", + "sharedGroupFilePattern": "_(\\w{3})_shared_data.xml", + "groupFilePattern": "(\\w{3})_.*\\.xml", + "ignoreFilePattern": "(temp|tmp)" + //"ferryIdsNotAllowedForBicycle" : ["RUT:B107", "RUT:B209"] + } + ], + "transferRequests": [ + { + "modes": "WALK" + }, + { + "modes": "WALK", + "wheelchairAccessibility": { + "enabled": true + } + } + ], + "stopConsolidationFile": "consolidated-stops.csv", + "emissions": { + "carAvgCo2PerKm": 170, + "carAvgOccupancy": 1.3 + } +} diff --git a/application/src/test/resources/standalone/config/debug-ui-config.json b/application/src/test/resources/standalone/config/debug-ui-config.json new file mode 100644 index 00000000000..1ae690a4d37 --- /dev/null +++ b/application/src/test/resources/standalone/config/debug-ui-config.json @@ -0,0 +1,9 @@ +{ + "additionalBackgroundLayers": [ + { + "name": "TriMet aerial photos", + "templateUrl": "https://maps.trimet.org/wms/reflect?bbox={bbox-epsg-3857}&format=image/png&service=WMS&version=1.1.0&request=GetMap&srs=EPSG:3857&width=256&height=256&layers=aerials", + "attribution": "© TriMet" + } + ] +} diff --git a/src/test/resources/standalone/config/invalid-config.json b/application/src/test/resources/standalone/config/invalid-config.json similarity index 100% rename from src/test/resources/standalone/config/invalid-config.json rename to application/src/test/resources/standalone/config/invalid-config.json diff --git a/application/src/test/resources/standalone/config/netex-tutorial/build-config.json b/application/src/test/resources/standalone/config/netex-tutorial/build-config.json new file mode 100644 index 00000000000..5e2788aae5e --- /dev/null +++ b/application/src/test/resources/standalone/config/netex-tutorial/build-config.json @@ -0,0 +1,20 @@ +{ + "transitFeeds": [ + { + "type": "netex", + "feedId": "NO", + "source": "https://storage.googleapis.com/marduk-production/outbound/netex/rb_norway-aggregated-netex.zip", + "sharedFilePattern": "_stops.xml", + "sharedGroupFilePattern": "_(\\w{3})(_flexible)?_shared_data.xml", + "groupFilePattern": "(\\w{3})_.*\\.xml" + } + ], + "osm": [ + { + "source": "norway.osm.pbf", + "osmTagMapping": "norway", + "timeZone": "Europe/Oslo" + } + ], + "osmCacheDataInMem": true +} diff --git a/application/src/test/resources/standalone/config/netex-tutorial/router-config.json b/application/src/test/resources/standalone/config/netex-tutorial/router-config.json new file mode 100644 index 00000000000..46f36c8c453 --- /dev/null +++ b/application/src/test/resources/standalone/config/netex-tutorial/router-config.json @@ -0,0 +1,19 @@ +{ + "updaters": [ + { + "type": "siri-sx-updater", + "frequency": "1m", + "url": "https://api.entur.io/realtime/v1/services", + "feedId": "NO", + "blockReadinessUntilInitialized": true + }, + { + "type": "siri-et-updater", + "frequency": "1m", + "previewInterval": "1h30m", + "url": "https://api.entur.io/realtime/v1/services", + "feedId": "NO", + "blockReadinessUntilInitialized": true + } + ] +} diff --git a/src/test/resources/standalone/config/router-config.json b/application/src/test/resources/standalone/config/router-config.json similarity index 96% rename from src/test/resources/standalone/config/router-config.json rename to application/src/test/resources/standalone/config/router-config.json index c526de423c1..4b6cf30f45d 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/application/src/test/resources/standalone/config/router-config.json @@ -119,12 +119,8 @@ "geoidElevation": false, "maxJourneyDuration": "36h", "unpreferred": { - "agencies": [ - "HSL:123" - ], - "routes": [ - "HSL:456" - ] + "agencies": ["HSL:123"], + "routes": ["HSL:456"] }, "unpreferredCost": "10m + 2.0 x", "streetRoutingTimeout": "5s", @@ -320,9 +316,7 @@ "headers": { "Cache-Control": "max-age=604800" }, - "tags": [ - "source:parkapi" - ] + "tags": ["source:parkapi"] }, { "type": "vehicle-parking", @@ -334,12 +328,6 @@ "Authorization": "${BIKELY_AUTHORIZATION}" } }, - { - "type": "vehicle-parking", - "feedId": "noi", - "sourceType": "noi-open-data-hub", - "url": "https://parking.otp.opendatahub.com/parking/all.json" - }, { "type": "stop-time-updater", "frequency": "1m", @@ -368,9 +356,7 @@ "Header-Name": "Header-Value" }, "fuzzyTripMatching": false, - "features": [ - "position" - ] + "features": ["position"] }, // Siri-ET over HTTP { @@ -410,8 +396,8 @@ { "type": "siri-azure-et-updater", "topic": "some_topic", - "authenticationType": "SharedAccessKey", - "fullyQualifiedNamespace": "fully_qualified_namespace", + "authenticationType": "SharedAccessKey", + "fullyQualifiedNamespace": "fully_qualified_namespace", "servicebus-url": "service_bus_url", "feedId": "feed_id", "customMidnight": 4, @@ -460,4 +446,3 @@ } ] } - diff --git a/src/test/resources/standalone/config/sandbox/build-config-data-overlay.json b/application/src/test/resources/standalone/config/sandbox/build-config-data-overlay.json similarity index 97% rename from src/test/resources/standalone/config/sandbox/build-config-data-overlay.json rename to application/src/test/resources/standalone/config/sandbox/build-config-data-overlay.json index 41aac831646..ec348022dff 100644 --- a/src/test/resources/standalone/config/sandbox/build-config-data-overlay.json +++ b/application/src/test/resources/standalone/config/sandbox/build-config-data-overlay.json @@ -1,5 +1,5 @@ { - "dataOverlay" : { + "dataOverlay": { "fileName": "graphs/data-file.nc4", "latitudeVariable": "lat", "longitudeVariable": "lon", @@ -30,4 +30,4 @@ } ] } -} \ No newline at end of file +} diff --git a/client/.env.development b/client/.env.development index 1cb7d9235e3..e3b3585a5eb 100644 --- a/client/.env.development +++ b/client/.env.development @@ -1,3 +1,3 @@ VITE_API_URL=http://localhost:8080/otp/transmodel/v3 VITE_DEBUG_STYLE_URL=http://localhost:8080/otp/routers/default/inspector/vectortile/style.json -VITE_GRAPHIQL_URL=http://localhost:8080/graphiql?flavor=transmodel \ No newline at end of file +VITE_GRAPHIQL_URL=http://localhost:8080/graphiql?flavor=transmodel diff --git a/client/README.md b/client/README.md index 54971062971..a646cd1170c 100644 --- a/client/README.md +++ b/client/README.md @@ -22,7 +22,7 @@ generated during build and are not checked into the repository. Use latest LTS version of Node/npm (currently v18). Recommend using a version manager such as `nvm`. The dev and production builds require graphql schema to be present at -`../src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql`. +`../application/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql`. ## Getting started (development) diff --git a/client/codegen.ts b/client/codegen.ts index b5b68a0650a..a8ad1e40c49 100644 --- a/client/codegen.ts +++ b/client/codegen.ts @@ -2,13 +2,16 @@ import type { CodegenConfig } from '@graphql-codegen/cli'; const config: CodegenConfig = { overwrite: true, - schema: '../src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql', + schema: '../application/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql', documents: 'src/**/*.{ts,tsx}', generates: { 'src/gql/': { preset: 'client', plugins: [], }, + 'src/gql/types.generated.ts': { + plugins: ['typescript'], + }, }, }; diff --git a/client/index.html b/client/index.html index 77eb289e595..f09832636f0 100644 --- a/client/index.html +++ b/client/index.html @@ -4,7 +4,7 @@ - OTP Debug Client + OTP Debug

    diff --git a/client/package-lock.json b/client/package-lock.json index 4632899b38f..bbed0b8e4fa 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9,39 +9,40 @@ "version": "0.0.0", "dependencies": { "@googlemaps/polyline-codec": "1.0.28", + "@js-temporal/polyfill": "0.4.4", "bootstrap": "5.3.3", "graphql": "16.9.0", - "graphql-request": "7.1.0", - "maplibre-gl": "4.6.0", + "graphql-request": "7.1.2", + "maplibre-gl": "4.7.1", "react": "18.3.1", - "react-bootstrap": "2.10.4", + "react-bootstrap": "2.10.6", "react-dom": "18.3.1", "react-map-gl": "7.1.7" }, "devDependencies": { - "@graphql-codegen/cli": "5.0.2", - "@graphql-codegen/client-preset": "4.3.3", + "@graphql-codegen/cli": "5.0.3", + "@graphql-codegen/client-preset": "4.5.1", "@graphql-codegen/introspection": "4.0.3", - "@parcel/watcher": "2.4.1", + "@parcel/watcher": "2.5.0", "@testing-library/react": "16.0.1", - "@types/react": "18.3.5", - "@types/react-dom": "18.3.0", + "@types/react": "18.3.12", + "@types/react-dom": "18.3.1", "@typescript-eslint/eslint-plugin": "7.18.0", "@typescript-eslint/parser": "7.18.0", - "@vitejs/plugin-react": "4.3.1", - "@vitest/coverage-v8": "2.0.5", - "eslint": "8.57.0", + "@vitejs/plugin-react": "4.3.4", + "@vitest/coverage-v8": "2.1.8", + "eslint": "8.57.1", "eslint-config-prettier": "9.1.0", - "eslint-plugin-import": "2.30.0", - "eslint-plugin-jsx-a11y": "6.9.0", - "eslint-plugin-react": "7.35.1", - "eslint-plugin-react-hooks": "4.6.2", - "eslint-plugin-react-refresh": "0.4.11", - "jsdom": "25.0.0", - "prettier": "3.3.3", - "typescript": "5.5.4", - "vite": "5.4.2", - "vitest": "2.0.5" + "eslint-plugin-import": "2.31.0", + "eslint-plugin-jsx-a11y": "6.10.2", + "eslint-plugin-react": "7.37.2", + "eslint-plugin-react-hooks": "5.0.0", + "eslint-plugin-react-refresh": "0.4.16", + "jsdom": "25.0.1", + "prettier": "3.4.1", + "typescript": "5.7.2", + "vite": "6.0.2", + "vitest": "2.1.8" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -214,13 +215,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.6.tgz", - "integrity": "sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.6", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -228,32 +229,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.6.tgz", - "integrity": "sha512-aC2DGhBq5eEdyXWqrDInSqQjO0k8xtPRf5YylULqx8MCd6jBtzqfta/3ETMRpuKIc5hyswfO80ObyA1MvkCcUQ==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.6.tgz", - "integrity": "sha512-qAHSfAdVyFmIvl0VHELib8xar7ONuSHrE2hLnsaWkYNTI68dmi1x8GYDhJjMI/e7XWal9QBlZkwbOnkcw7Z8gQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.6", - "@babel/generator": "^7.24.6", - "@babel/helper-compilation-targets": "^7.24.6", - "@babel/helper-module-transforms": "^7.24.6", - "@babel/helpers": "^7.24.6", - "@babel/parser": "^7.24.6", - "@babel/template": "^7.24.6", - "@babel/traverse": "^7.24.6", - "@babel/types": "^7.24.6", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -269,16 +268,16 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.6.tgz", - "integrity": "sha512-S7m4eNa6YAPJRHmKsLHIDJhNAGNKoWNiWefz1MBbpnt8g9lvMDl1hir4P9bo/57bQEmuwEhnRU/AMWsD0G/Fbg==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.24.6", + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" @@ -297,15 +296,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.6.tgz", - "integrity": "sha512-VZQ57UsDGlX/5fFA7GkVPplZhHsVc+vuErWgdOiysI9Ksnw0Pbbd6pnPiR/mmJyKHgyIW0c7KT32gmhiF+cirg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.24.6", - "@babel/helper-validator-option": "^7.24.6", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -360,19 +358,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.6.tgz", - "integrity": "sha512-SF/EMrC3OD7dSta1bLJIlrsVxwtd0UpjRJqLno6125epQMJ/kyFmpTT4pbvPbdQHzCHg+biQ7Syo8lnDtbR+uA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.23.0", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", @@ -386,30 +371,27 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.6.tgz", - "integrity": "sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.24.6" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.6.tgz", - "integrity": "sha512-Y/YMPm83mV2HJTbX1Qh2sjgjqcacvOlhbzdCCsSlblOKjSYmQqEbO6rUniWQyRo9ncyfjT8hnUjlG06RXDEmcA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.6", - "@babel/helper-module-imports": "^7.24.6", - "@babel/helper-simple-access": "^7.24.6", - "@babel/helper-split-export-declaration": "^7.24.6", - "@babel/helper-validator-identifier": "^7.24.6" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -431,11 +413,10 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.6.tgz", - "integrity": "sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -458,13 +439,14 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.6.tgz", - "integrity": "sha512-nZzcMMD4ZhmB35MOOzQuiGO5RzL6tJbsT37Zx8M5L/i9KSrukGXWTjLe1knIbb/RmxoJE9GON9soq0c0VEMM5g==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", + "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.24.6" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -496,149 +478,53 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.6.tgz", - "integrity": "sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.6.tgz", - "integrity": "sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.6.tgz", - "integrity": "sha512-Jktc8KkF3zIkePb48QO+IapbXlSapOW9S+ogZZkcO6bABgYAxtZcjZ/O005111YLf+j4M84uEgwYoidDkXbCkQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.6.tgz", - "integrity": "sha512-V2PI+NqnyFu1i0GyTd/O/cTpxzQCYioSkUIRmgo7gFEHKKCg5w46+r/A6WeUR1+P3TeQ49dspGPNd/E3n9AnnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.24.6", - "@babel/types": "^7.24.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.6.tgz", - "integrity": "sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.6", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dev": true, - "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@babel/types": "^7.26.0" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.6.tgz", - "integrity": "sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==", - "dev": true, - "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -1027,13 +913,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.6.tgz", - "integrity": "sha512-FfZfHXtQ5jYPQsCRyLpOv2GeLIIJhs8aydpNh39vRDjhD411XcfWDni5i7OjP/Rs8GAtTn7sWFFELJSHqkIxYg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", + "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1043,12 +928,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.1.tgz", - "integrity": "sha512-1v202n7aUq4uXAieRTKcwPzNyphlCuqHHDcdSNc+vdhoTEZcFMh+L5yZuCmGaIO7bs1nJUNfHB89TZyoL48xNA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", + "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1104,9 +989,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -1116,35 +1001,30 @@ } }, "node_modules/@babel/template": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.6.tgz", - "integrity": "sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.6", - "@babel/parser": "^7.24.6", - "@babel/types": "^7.24.6" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.6.tgz", - "integrity": "sha512-OsNjaJwT9Zn8ozxcfoBc+RaHdj3gFmCmYoQLUII1o6ZrUwku0BMg80FoOTPx+Gi6XhcQxAYE4xyjPTo4SxEQqw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.6", - "@babel/generator": "^7.24.6", - "@babel/helper-environment-visitor": "^7.24.6", - "@babel/helper-function-name": "^7.24.6", - "@babel/helper-hoist-variables": "^7.24.6", - "@babel/helper-split-export-declaration": "^7.24.6", - "@babel/parser": "^7.24.6", - "@babel/types": "^7.24.6", + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1153,15 +1033,13 @@ } }, "node_modules/@babel/types": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.6.tgz", - "integrity": "sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.6", - "@babel/helper-validator-identifier": "^7.24.6", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1173,509 +1051,388 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@dprint/darwin-arm64": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.46.3.tgz", - "integrity": "sha512-1ycDpGvclGHF3UG5V6peymPDg6ouNTqM6BjhVELQ6zwr+X98AMhq/1slgO8hwHtPcaS5qhTAS+PkzOmBJRegow==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true - }, - "node_modules/@dprint/darwin-x64": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.46.3.tgz", - "integrity": "sha512-v5IpLmrY836Q5hJAxZuX097ZNQvoZgO6JKO4bK4l6XDhhHAw2XTIUr41+FM5r36ENxyASMk0NpHjhcHtih3o0g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true - }, - "node_modules/@dprint/formatter": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@dprint/formatter/-/formatter-0.3.0.tgz", - "integrity": "sha512-N9fxCxbaBOrDkteSOzaCqwWjso5iAe+WJPsHC021JfHNj2ThInPNEF13ORDKta3llq5D1TlclODCvOvipH7bWQ==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/@dprint/linux-arm64-glibc": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.46.3.tgz", - "integrity": "sha512-9P13g1vgV8RfQH2qBGa8YAfaOeWA42RIhj7lmWRpkDFtwau96reMKwnBBn8bHUnc5e6bSsbPUOMb/X1KMUKz/g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@dprint/linux-arm64-musl": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.46.3.tgz", - "integrity": "sha512-AAcdcMSZ6DEIoY9E0xQHjkZP+THP7EWsQge4TWzglSIjzn31YltglHAGYFcLB4CTJYpF0NsFDNFktzgkO+s0og==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@dprint/linux-x64-glibc": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.46.3.tgz", - "integrity": "sha512-c5cQ3G1rC64nBZ8Pd2LGWwzkEk4D7Ax9NrBbwYmNPvs6mFbGlJPC1+RD95x2WwIrIlMIciLG+Kxmt25PzBphmg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@dprint/linux-x64-musl": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.46.3.tgz", - "integrity": "sha512-ONtk2QtLcV0TqWOCOqzUFQixgk3JC+vnJLB5L6tQwT7BX5LzeircfE/1f4dg459iqejNC9MBXZkHnXqabvWSow==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@dprint/typescript": { - "version": "0.91.1", - "resolved": "https://registry.npmjs.org/@dprint/typescript/-/typescript-0.91.1.tgz", - "integrity": "sha512-BX3TneRLf3OuO/3tsxbseHqWbpCPOOb2vOm9OlKgSYIKqOsCHpz5kWx5iDuGrNwxWWMKife/1ccz87I5tBLaNA==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/@dprint/win32-x64": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.46.3.tgz", - "integrity": "sha512-xvj4DSEilf0gGdT7CqnwNEgfWNuWqT6eIBxHDEUbmcn1vZ7IwirtqRq/nm3lmYtQaJ4EbtMQZvACHZwxC7G96w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", + "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==", "cpu": [ "ppc64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz", + "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==", "cpu": [ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz", + "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz", + "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz", + "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", + "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz", + "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz", + "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz", + "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==", "cpu": [ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz", + "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz", + "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==", "cpu": [ "ia32" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz", + "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==", "cpu": [ "loong64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz", + "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==", "cpu": [ "mips64el" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz", + "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==", "cpu": [ "ppc64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz", + "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==", "cpu": [ "riscv64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz", + "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==", "cpu": [ "s390x" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz", + "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz", + "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz", + "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz", + "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz", + "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz", + "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz", + "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==", "cpu": [ "ia32" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz", + "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { @@ -1775,10 +1532,11 @@ } }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -1803,15 +1561,16 @@ } }, "node_modules/@graphql-codegen/cli": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@graphql-codegen/cli/-/cli-5.0.2.tgz", - "integrity": "sha512-MBIaFqDiLKuO4ojN6xxG9/xL9wmfD3ZjZ7RsPjwQnSHBCUXnEkdKvX+JVpx87Pq29Ycn8wTJUguXnTZ7Di0Mlw==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@graphql-codegen/cli/-/cli-5.0.3.tgz", + "integrity": "sha512-ULpF6Sbu2d7vNEOgBtE9avQp2oMgcPY/QBYcCqk0Xru5fz+ISjcovQX29V7CS7y5wWBRzNLoXwJQGeEyWbl05g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/generator": "^7.18.13", "@babel/template": "^7.18.10", "@babel/types": "^7.18.13", - "@graphql-codegen/client-preset": "^4.2.2", + "@graphql-codegen/client-preset": "^4.4.0", "@graphql-codegen/core": "^4.0.2", "@graphql-codegen/plugin-helpers": "^5.0.3", "@graphql-tools/apollo-engine-loader": "^8.0.0", @@ -1824,12 +1583,12 @@ "@graphql-tools/prisma-loader": "^8.0.0", "@graphql-tools/url-loader": "^8.0.0", "@graphql-tools/utils": "^10.0.0", - "@whatwg-node/fetch": "^0.8.0", + "@whatwg-node/fetch": "^0.9.20", "chalk": "^4.1.0", "cosmiconfig": "^8.1.3", "debounce": "^1.2.0", "detect-indent": "^6.0.0", - "graphql-config": "^5.0.2", + "graphql-config": "^5.1.1", "inquirer": "^8.0.0", "is-glob": "^4.0.1", "jiti": "^1.17.1", @@ -1850,6 +1609,9 @@ "graphql-codegen": "cjs/bin.js", "graphql-codegen-esm": "esm/bin.js" }, + "engines": { + "node": ">=16" + }, "peerDependencies": { "@parcel/watcher": "^2.1.0", "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" @@ -1861,26 +1623,29 @@ } }, "node_modules/@graphql-codegen/client-preset": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@graphql-codegen/client-preset/-/client-preset-4.3.3.tgz", - "integrity": "sha512-IrDsSVe8bkKtxgVfKPHzjL9tYlv7KEpA59R4gZLqx/t2WIJncW1i0OMvoz9tgoZsFEs8OKKgXZbnwPZ/Qf1kEw==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@graphql-codegen/client-preset/-/client-preset-4.5.1.tgz", + "integrity": "sha512-UE2/Kz2eaxv35HIXFwlm2QwoUH77am6+qp54aeEWYq+T+WPwmIc6+YzqtGiT/VcaXgoOUSgidREGm9R6jKcf9g==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/template": "^7.20.7", "@graphql-codegen/add": "^5.0.3", - "@graphql-codegen/gql-tag-operations": "4.0.9", - "@graphql-codegen/plugin-helpers": "^5.0.4", - "@graphql-codegen/typed-document-node": "^5.0.9", - "@graphql-codegen/typescript": "^4.0.9", - "@graphql-codegen/typescript-operations": "^4.2.3", - "@graphql-codegen/visitor-plugin-common": "^5.3.1", + "@graphql-codegen/gql-tag-operations": "4.0.12", + "@graphql-codegen/plugin-helpers": "^5.1.0", + "@graphql-codegen/typed-document-node": "^5.0.12", + "@graphql-codegen/typescript": "^4.1.2", + "@graphql-codegen/typescript-operations": "^4.4.0", + "@graphql-codegen/visitor-plugin-common": "^5.6.0", "@graphql-tools/documents": "^1.0.0", "@graphql-tools/utils": "^10.0.0", "@graphql-typed-document-node/core": "3.2.0", "tslib": "~2.6.0" }, + "engines": { + "node": ">=16" + }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } @@ -1901,18 +1666,21 @@ } }, "node_modules/@graphql-codegen/gql-tag-operations": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@graphql-codegen/gql-tag-operations/-/gql-tag-operations-4.0.9.tgz", - "integrity": "sha512-lVgu1HClel896HqZAEjynatlU6eJrYOw+rh05DPgM150xvmb7Gz5TnRHA2vfwlDNIXDaToAIpz5RFfkjjnYM1Q==", + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@graphql-codegen/gql-tag-operations/-/gql-tag-operations-4.0.12.tgz", + "integrity": "sha512-v279i49FJ5dMmQXIGUgm6FtnnkxtJjVJWDNYh9JK4ppvOixdHp+PmEzW227DkLN6avhVxNnYdp/1gdRBwdWypw==", "dev": true, "license": "MIT", "dependencies": { - "@graphql-codegen/plugin-helpers": "^5.0.4", - "@graphql-codegen/visitor-plugin-common": "5.3.1", + "@graphql-codegen/plugin-helpers": "^5.1.0", + "@graphql-codegen/visitor-plugin-common": "5.6.0", "@graphql-tools/utils": "^10.0.0", "auto-bind": "~4.0.0", "tslib": "~2.6.0" }, + "engines": { + "node": ">=16" + }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } @@ -1932,9 +1700,9 @@ } }, "node_modules/@graphql-codegen/plugin-helpers": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-5.0.4.tgz", - "integrity": "sha512-MOIuHFNWUnFnqVmiXtrI+4UziMTYrcquljaI5f/T/Bc7oO7sXcfkAvgkNWEEi9xWreYwvuer3VHCuPI/lAFWbw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-5.1.0.tgz", + "integrity": "sha512-Y7cwEAkprbTKzVIe436TIw4w03jorsMruvCvu0HJkavaKMQbWY+lQ1RIuROgszDbxAyM35twB5/sUvYG5oW+yg==", "dev": true, "license": "MIT", "dependencies": { @@ -1945,15 +1713,19 @@ "lodash": "~4.17.0", "tslib": "~2.6.0" }, + "engines": { + "node": ">=16" + }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/schema-ast": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@graphql-codegen/schema-ast/-/schema-ast-4.0.2.tgz", - "integrity": "sha512-5mVAOQQK3Oz7EtMl/l3vOQdc2aYClUzVDHHkMvZlunc+KlGgl81j8TLa+X7ANIllqU4fUEsQU3lJmk4hXP6K7Q==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@graphql-codegen/schema-ast/-/schema-ast-4.1.0.tgz", + "integrity": "sha512-kZVn0z+th9SvqxfKYgztA6PM7mhnSZaj4fiuBWvMTqA+QqQ9BBed6Pz41KuD/jr0gJtnlr2A4++/0VlpVbCTmQ==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-codegen/plugin-helpers": "^5.0.3", "@graphql-tools/utils": "^10.0.0", @@ -1964,64 +1736,73 @@ } }, "node_modules/@graphql-codegen/typed-document-node": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/@graphql-codegen/typed-document-node/-/typed-document-node-5.0.9.tgz", - "integrity": "sha512-Wx6fyA4vpfIbfNTMiWUECGnjqzKkJdEbZHxVMIegiCBPzBYPAJV4mZZcildLAfm2FtZcgW4YKtFoTbnbXqPB3w==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@graphql-codegen/typed-document-node/-/typed-document-node-5.0.12.tgz", + "integrity": "sha512-Wsbc1AqC+MFp3maWPzrmmyHLuWCPB63qBBFLTKtO6KSsnn0KnLocBp475wkfBZnFISFvzwpJ0e6LV71gKfTofQ==", "dev": true, "license": "MIT", "dependencies": { - "@graphql-codegen/plugin-helpers": "^5.0.4", - "@graphql-codegen/visitor-plugin-common": "5.3.1", + "@graphql-codegen/plugin-helpers": "^5.1.0", + "@graphql-codegen/visitor-plugin-common": "5.6.0", "auto-bind": "~4.0.0", "change-case-all": "1.0.15", "tslib": "~2.6.0" }, + "engines": { + "node": ">=16" + }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/typescript": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-4.0.9.tgz", - "integrity": "sha512-0O35DMR4d/ctuHL1Zo6mRUUzp0BoszKfeWsa6sCm/g70+S98+hEfTwZNDkQHylLxapiyjssF9uw/F+sXqejqLw==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-4.1.2.tgz", + "integrity": "sha512-GhPgfxgWEkBrvKR2y77OThus3K8B6U3ESo68l7+sHH1XiL2WapK5DdClViblJWKQerJRjfJu8tcaxQ8Wpk6Ogw==", "dev": true, "license": "MIT", "dependencies": { - "@graphql-codegen/plugin-helpers": "^5.0.4", + "@graphql-codegen/plugin-helpers": "^5.1.0", "@graphql-codegen/schema-ast": "^4.0.2", - "@graphql-codegen/visitor-plugin-common": "5.3.1", + "@graphql-codegen/visitor-plugin-common": "5.6.0", "auto-bind": "~4.0.0", "tslib": "~2.6.0" }, + "engines": { + "node": ">=16" + }, "peerDependencies": { "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/typescript-operations": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-operations/-/typescript-operations-4.2.3.tgz", - "integrity": "sha512-6z7avSSOr03l5SyKbeDs7MzRyGwnQFSCqQm8Om5wIuoIgXVu2gXRmcJAY/I7SLdAy9xbF4Sho7XNqieFM2CAFQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-operations/-/typescript-operations-4.4.0.tgz", + "integrity": "sha512-oVlos2ySx8xIbbe8r5ZI6mOpI+OTeP14RmS2MchBJ6DL+S9G16O6+9V3Y8V22fTnmBTZkTfAAaBv4HYhhDGWVA==", "dev": true, "license": "MIT", "dependencies": { - "@graphql-codegen/plugin-helpers": "^5.0.4", - "@graphql-codegen/typescript": "^4.0.9", - "@graphql-codegen/visitor-plugin-common": "5.3.1", + "@graphql-codegen/plugin-helpers": "^5.1.0", + "@graphql-codegen/typescript": "^4.1.2", + "@graphql-codegen/visitor-plugin-common": "5.6.0", "auto-bind": "~4.0.0", "tslib": "~2.6.0" }, + "engines": { + "node": ">=16" + }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/visitor-plugin-common": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-5.3.1.tgz", - "integrity": "sha512-MktoBdNZhSmugiDjmFl1z6rEUUaqyxtFJYWnDilE7onkPgyw//O0M+TuPBJPBWdyV6J2ond0Hdqtq+rkghgSIQ==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-5.6.0.tgz", + "integrity": "sha512-PowcVPJbUqMC9xTJ/ZRX1p/fsdMZREc+69CM1YY+AlFng2lL0zsdBskFJSRoviQk2Ch9IPhKGyHxlJCy9X22tg==", "dev": true, "license": "MIT", "dependencies": { - "@graphql-codegen/plugin-helpers": "^5.0.4", + "@graphql-codegen/plugin-helpers": "^5.1.0", "@graphql-tools/optimize": "^2.0.0", "@graphql-tools/relay-operation-optimizer": "^7.0.0", "@graphql-tools/utils": "^10.0.0", @@ -2032,6 +1813,9 @@ "parse-filepath": "^1.0.2", "tslib": "~2.6.0" }, + "engines": { + "node": ">=16" + }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } @@ -2054,50 +1838,6 @@ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/events": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", - "dev": true, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/fetch": { - "version": "0.9.17", - "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.17.tgz", - "integrity": "sha512-TDYP3CpCrxwxpiNY0UMNf096H5Ihf67BK1iKGegQl5u9SlpEDYrvnV71gWBGJm+Xm31qOy8ATgma9rm8Pe7/5Q==", - "dev": true, - "dependencies": { - "@whatwg-node/node-fetch": "^0.5.7", - "urlpattern-polyfill": "^10.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.10.tgz", - "integrity": "sha512-KIAHepie/T1PRkUfze4t+bPlyvpxlWiXTPtcGlbIZ0vWkBJMdRmCg4ZrJ2y4XaO1eTPo1HlWYUuj1WvoIpumqg==", - "dev": true, - "dependencies": { - "@kamilkisiela/fast-url-parser": "^1.1.4", - "@whatwg-node/events": "^0.1.0", - "busboy": "^1.6.0", - "fast-querystring": "^1.1.1", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/apollo-engine-loader/node_modules/urlpattern-polyfill": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", - "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", - "dev": true - }, "node_modules/@graphql-tools/batch-execute": { "version": "9.0.4", "resolved": "https://registry.npmjs.org/@graphql-tools/batch-execute/-/batch-execute-9.0.4.tgz", @@ -2231,50 +1971,6 @@ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/events": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", - "dev": true, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/fetch": { - "version": "0.9.17", - "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.17.tgz", - "integrity": "sha512-TDYP3CpCrxwxpiNY0UMNf096H5Ihf67BK1iKGegQl5u9SlpEDYrvnV71gWBGJm+Xm31qOy8ATgma9rm8Pe7/5Q==", - "dev": true, - "dependencies": { - "@whatwg-node/node-fetch": "^0.5.7", - "urlpattern-polyfill": "^10.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.10.tgz", - "integrity": "sha512-KIAHepie/T1PRkUfze4t+bPlyvpxlWiXTPtcGlbIZ0vWkBJMdRmCg4ZrJ2y4XaO1eTPo1HlWYUuj1WvoIpumqg==", - "dev": true, - "dependencies": { - "@kamilkisiela/fast-url-parser": "^1.1.4", - "@whatwg-node/events": "^0.1.0", - "busboy": "^1.6.0", - "fast-querystring": "^1.1.1", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/executor-http/node_modules/urlpattern-polyfill": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", - "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", - "dev": true - }, "node_modules/@graphql-tools/executor-legacy-ws": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@graphql-tools/executor-legacy-ws/-/executor-legacy-ws-1.0.6.tgz", @@ -2335,50 +2031,6 @@ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/events": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", - "dev": true, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/fetch": { - "version": "0.9.17", - "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.17.tgz", - "integrity": "sha512-TDYP3CpCrxwxpiNY0UMNf096H5Ihf67BK1iKGegQl5u9SlpEDYrvnV71gWBGJm+Xm31qOy8ATgma9rm8Pe7/5Q==", - "dev": true, - "dependencies": { - "@whatwg-node/node-fetch": "^0.5.7", - "urlpattern-polyfill": "^10.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.10.tgz", - "integrity": "sha512-KIAHepie/T1PRkUfze4t+bPlyvpxlWiXTPtcGlbIZ0vWkBJMdRmCg4ZrJ2y4XaO1eTPo1HlWYUuj1WvoIpumqg==", - "dev": true, - "dependencies": { - "@kamilkisiela/fast-url-parser": "^1.1.4", - "@whatwg-node/events": "^0.1.0", - "busboy": "^1.6.0", - "fast-querystring": "^1.1.1", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/github-loader/node_modules/urlpattern-polyfill": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", - "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", - "dev": true - }, "node_modules/@graphql-tools/graphql-file-loader": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-file-loader/-/graphql-file-loader-8.0.1.tgz", @@ -2535,44 +2187,6 @@ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/events": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", - "dev": true, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/fetch": { - "version": "0.9.17", - "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.17.tgz", - "integrity": "sha512-TDYP3CpCrxwxpiNY0UMNf096H5Ihf67BK1iKGegQl5u9SlpEDYrvnV71gWBGJm+Xm31qOy8ATgma9rm8Pe7/5Q==", - "dev": true, - "dependencies": { - "@whatwg-node/node-fetch": "^0.5.7", - "urlpattern-polyfill": "^10.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.10.tgz", - "integrity": "sha512-KIAHepie/T1PRkUfze4t+bPlyvpxlWiXTPtcGlbIZ0vWkBJMdRmCg4ZrJ2y4XaO1eTPo1HlWYUuj1WvoIpumqg==", - "dev": true, - "dependencies": { - "@kamilkisiela/fast-url-parser": "^1.1.4", - "@whatwg-node/events": "^0.1.0", - "busboy": "^1.6.0", - "fast-querystring": "^1.1.1", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, "node_modules/@graphql-tools/prisma-loader/node_modules/graphql-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-6.1.0.tgz", @@ -2587,12 +2201,6 @@ "graphql": "14 - 16" } }, - "node_modules/@graphql-tools/prisma-loader/node_modules/urlpattern-polyfill": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", - "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", - "dev": true - }, "node_modules/@graphql-tools/relay-operation-optimizer": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-7.0.1.tgz", @@ -2655,60 +2263,16 @@ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/events": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", - "dev": true, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/fetch": { - "version": "0.9.17", - "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.17.tgz", - "integrity": "sha512-TDYP3CpCrxwxpiNY0UMNf096H5Ihf67BK1iKGegQl5u9SlpEDYrvnV71gWBGJm+Xm31qOy8ATgma9rm8Pe7/5Q==", + "node_modules/@graphql-tools/utils": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.1.2.tgz", + "integrity": "sha512-fX13CYsDnX4yifIyNdiN0cVygz/muvkreWWem6BBw130+ODbRRgfiVveL0NizCEnKXkpvdeTy9Bxvo9LIKlhrw==", "dev": true, "dependencies": { - "@whatwg-node/node-fetch": "^0.5.7", - "urlpattern-polyfill": "^10.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.10.tgz", - "integrity": "sha512-KIAHepie/T1PRkUfze4t+bPlyvpxlWiXTPtcGlbIZ0vWkBJMdRmCg4ZrJ2y4XaO1eTPo1HlWYUuj1WvoIpumqg==", - "dev": true, - "dependencies": { - "@kamilkisiela/fast-url-parser": "^1.1.4", - "@whatwg-node/events": "^0.1.0", - "busboy": "^1.6.0", - "fast-querystring": "^1.1.1", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/url-loader/node_modules/urlpattern-polyfill": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", - "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", - "dev": true - }, - "node_modules/@graphql-tools/utils": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.1.2.tgz", - "integrity": "sha512-fX13CYsDnX4yifIyNdiN0cVygz/muvkreWWem6BBw130+ODbRRgfiVveL0NizCEnKXkpvdeTy9Bxvo9LIKlhrw==", - "dev": true, - "dependencies": { - "@graphql-typed-document-node/core": "^3.1.1", - "cross-inspect": "1.0.0", - "dset": "^3.1.2", - "tslib": "^2.4.0" + "@graphql-typed-document-node/core": "^3.1.1", + "cross-inspect": "1.0.0", + "dset": "^3.1.2", + "tslib": "^2.4.0" }, "engines": { "node": ">=16.0.0" @@ -2745,12 +2309,14 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" }, @@ -2794,10 +2360,12 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", - "dev": true + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@isaacs/cliui": { "version": "8.0.2", @@ -2937,10 +2505,11 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", @@ -2952,11 +2521,24 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@js-temporal/polyfill": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@js-temporal/polyfill/-/polyfill-0.4.4.tgz", + "integrity": "sha512-2X6bvghJ/JAoZO52lbgyAPFj8uCflhTo2g7nkFzEQdXd/D8rEeD4HtmTEpmtGCva260fcd66YNXBOYdnmHqSOg==", + "dependencies": { + "jsbi": "^4.3.0", + "tslib": "^2.4.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@kamilkisiela/fast-url-parser": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@kamilkisiela/fast-url-parser/-/fast-url-parser-1.1.4.tgz", "integrity": "sha512-gbkePEBupNydxCelHCESvFSFM8XPh1Zs/OAVRW/rKpEqPAl5PbOM90Si8mv9bvnR53uPD2s/FiRxdvSejpRJew==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@mapbox/geojson-rewind": { "version": "0.5.2", @@ -3030,85 +2612,6 @@ "gl-style-validate": "dist/gl-style-validate.mjs" } }, - "node_modules/@molt/command": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@molt/command/-/command-0.9.0.tgz", - "integrity": "sha512-1JI8dAlpqlZoXyKWVQggX7geFNPxBpocHIXQCsnxDjKy+3WX4SGyZVJXuLlqRRrX7FmQCuuMAfx642ovXmPA9g==", - "license": "MIT", - "dependencies": { - "@molt/types": "0.2.0", - "alge": "0.8.1", - "chalk": "^5.3.0", - "lodash.camelcase": "^4.3.0", - "lodash.snakecase": "^4.1.1", - "readline-sync": "^1.4.10", - "string-length": "^6.0.0", - "strip-ansi": "^7.1.0", - "ts-toolbelt": "^9.6.0", - "type-fest": "^4.3.1", - "zod": "^3.22.2" - } - }, - "node_modules/@molt/command/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@molt/command/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@molt/command/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@molt/command/node_modules/type-fest": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.18.2.tgz", - "integrity": "sha512-+suCYpfJLAe4OXS6+PPXjW3urOS4IoP9waSiLuXfLgqZODKw/aWwASvzqE886wA0kQgGy0mIWyhd87VpqIy6Xg==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@molt/types": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@molt/types/-/types-0.2.0.tgz", - "integrity": "sha512-p6ChnEZDGjg9PYPec9BK6Yp5/DdSrYQvXTBAtgrnqX6N36cZy37ql1c8Tc5LclfIYBNG7EZp8NBcRTYJwyi84g==", - "license": "MIT", - "dependencies": { - "ts-toolbelt": "^9.6.0" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3145,10 +2648,12 @@ } }, "node_modules/@parcel/watcher": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.4.1.tgz", - "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz", + "integrity": "sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==", "dev": true, + "hasInstallScript": true, + "license": "MIT", "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", @@ -3163,28 +2668,30 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.4.1", - "@parcel/watcher-darwin-arm64": "2.4.1", - "@parcel/watcher-darwin-x64": "2.4.1", - "@parcel/watcher-freebsd-x64": "2.4.1", - "@parcel/watcher-linux-arm-glibc": "2.4.1", - "@parcel/watcher-linux-arm64-glibc": "2.4.1", - "@parcel/watcher-linux-arm64-musl": "2.4.1", - "@parcel/watcher-linux-x64-glibc": "2.4.1", - "@parcel/watcher-linux-x64-musl": "2.4.1", - "@parcel/watcher-win32-arm64": "2.4.1", - "@parcel/watcher-win32-ia32": "2.4.1", - "@parcel/watcher-win32-x64": "2.4.1" + "@parcel/watcher-android-arm64": "2.5.0", + "@parcel/watcher-darwin-arm64": "2.5.0", + "@parcel/watcher-darwin-x64": "2.5.0", + "@parcel/watcher-freebsd-x64": "2.5.0", + "@parcel/watcher-linux-arm-glibc": "2.5.0", + "@parcel/watcher-linux-arm-musl": "2.5.0", + "@parcel/watcher-linux-arm64-glibc": "2.5.0", + "@parcel/watcher-linux-arm64-musl": "2.5.0", + "@parcel/watcher-linux-x64-glibc": "2.5.0", + "@parcel/watcher-linux-x64-musl": "2.5.0", + "@parcel/watcher-win32-arm64": "2.5.0", + "@parcel/watcher-win32-ia32": "2.5.0", + "@parcel/watcher-win32-x64": "2.5.0" } }, "node_modules/@parcel/watcher-android-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.4.1.tgz", - "integrity": "sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.0.tgz", + "integrity": "sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -3198,13 +2705,14 @@ } }, "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz", - "integrity": "sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz", + "integrity": "sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3218,13 +2726,14 @@ } }, "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.4.1.tgz", - "integrity": "sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.0.tgz", + "integrity": "sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3238,13 +2747,14 @@ } }, "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.4.1.tgz", - "integrity": "sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.0.tgz", + "integrity": "sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -3258,13 +2768,35 @@ } }, "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.4.1.tgz", - "integrity": "sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.0.tgz", + "integrity": "sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.0.tgz", + "integrity": "sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3278,13 +2810,14 @@ } }, "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.4.1.tgz", - "integrity": "sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.0.tgz", + "integrity": "sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3298,13 +2831,14 @@ } }, "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.4.1.tgz", - "integrity": "sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.0.tgz", + "integrity": "sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3318,13 +2852,14 @@ } }, "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz", - "integrity": "sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.0.tgz", + "integrity": "sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3338,13 +2873,14 @@ } }, "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.4.1.tgz", - "integrity": "sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.0.tgz", + "integrity": "sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3358,13 +2894,14 @@ } }, "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.4.1.tgz", - "integrity": "sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.0.tgz", + "integrity": "sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -3378,13 +2915,14 @@ } }, "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.4.1.tgz", - "integrity": "sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.0.tgz", + "integrity": "sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -3398,13 +2936,14 @@ } }, "node_modules/@parcel/watcher-win32-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz", - "integrity": "sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.0.tgz", + "integrity": "sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -3417,45 +2956,6 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@peculiar/asn1-schema": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.8.tgz", - "integrity": "sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA==", - "dev": true, - "dependencies": { - "asn1js": "^3.0.5", - "pvtsutils": "^1.3.5", - "tslib": "^2.6.2" - } - }, - "node_modules/@peculiar/json-schema": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", - "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", - "dev": true, - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@peculiar/webcrypto": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.5.tgz", - "integrity": "sha512-oDk93QCDGdxFRM8382Zdminzs44dg3M2+E5Np+JWkpqLDyJC9DviMh8F8mEJkYuUcUOGA5jHO5AJJ10MFWdbZw==", - "dev": true, - "dependencies": { - "@peculiar/asn1-schema": "^2.3.8", - "@peculiar/json-schema": "^1.1.12", - "pvtsutils": "^1.3.5", - "tslib": "^2.6.2", - "webcrypto-core": "^1.7.8" - }, - "engines": { - "node": ">=10.12.0" - } - }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -3508,19 +3008,19 @@ } }, "node_modules/@restart/ui": { - "version": "1.6.9", - "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.9.tgz", - "integrity": "sha512-mUbygUsJcRurjZCt1f77gg4DpheD1D+Sc7J3JjAkysUj7t8m4EBJVOqWC9788Qtbc69cJ+HlJc6jBguKwS8Mcw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.9.1.tgz", + "integrity": "sha512-qghR21ynHiUrpcIkKCoKYB+3rJtezY5Y7ikrwradCL+7hZHdQ2Ozc5ffxtpmpahoAGgc31gyXaSx2sXXaThmqA==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.21.0", - "@popperjs/core": "^2.11.6", + "@babel/runtime": "^7.26.0", + "@popperjs/core": "^2.11.8", "@react-aria/ssr": "^3.5.0", - "@restart/hooks": "^0.4.9", - "@types/warning": "^3.0.0", + "@restart/hooks": "^0.5.0", + "@types/warning": "^3.0.3", "dequal": "^2.0.3", "dom-helpers": "^5.2.0", - "uncontrollable": "^8.0.1", + "uncontrollable": "^8.0.4", "warning": "^4.0.3" }, "peerDependencies": { @@ -3528,6 +3028,18 @@ "react-dom": ">=16.14.0" } }, + "node_modules/@restart/ui/node_modules/@restart/hooks": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.5.0.tgz", + "integrity": "sha512-wS+h6IusJCPjTkmOOrRZxIPICD/mtFA3PRZviutoM23/b7akyDGfZF/WS+nIFk27u7JDhPE2+0GBdZxjSqHZkg==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/@restart/ui/node_modules/uncontrollable": { "version": "8.0.4", "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", @@ -3537,224 +3049,234 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz", - "integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.4.tgz", + "integrity": "sha512-2Y3JT6f5MrQkICUyRVCw4oa0sutfAsgaSsb0Lmmy1Wi2y7X5vT9Euqw4gOsCyy0YfKURBg35nhUKZS4mDcfULw==", "cpu": [ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz", - "integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.27.4.tgz", + "integrity": "sha512-wzKRQXISyi9UdCVRqEd0H4cMpzvHYt1f/C3CoIjES6cG++RHKhrBj2+29nPF0IB5kpy9MS71vs07fvrNGAl/iA==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz", - "integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.27.4.tgz", + "integrity": "sha512-PlNiRQapift4LNS8DPUHuDX/IdXiLjf8mc5vdEmUR0fF/pyy2qWwzdLjB+iZquGr8LuN4LnUoSEvKRwjSVYz3Q==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz", - "integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.27.4.tgz", + "integrity": "sha512-o9bH2dbdgBDJaXWJCDTNDYa171ACUdzpxSZt+u/AAeQ20Nk5x+IhA+zsGmrQtpkLiumRJEYef68gcpn2ooXhSQ==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" ] }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.27.4.tgz", + "integrity": "sha512-NBI2/i2hT9Q+HySSHTBh52da7isru4aAAo6qC3I7QFVsuhxi2gM8t/EI9EVcILiHLj1vfi+VGGPaLOUENn7pmw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.27.4.tgz", + "integrity": "sha512-wYcC5ycW2zvqtDYrE7deary2P2UFmSh85PUpAx+dwTCO9uw3sgzD6Gv9n5X4vLaQKsrfTSZZ7Z7uynQozPVvWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz", - "integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.27.4.tgz", + "integrity": "sha512-9OwUnK/xKw6DyRlgx8UizeqRFOfi9mf5TYCw1uolDaJSbUmBxP85DE6T4ouCMoN6pXw8ZoTeZCSEfSaYo+/s1w==", "cpu": [ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz", - "integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.27.4.tgz", + "integrity": "sha512-Vgdo4fpuphS9V24WOV+KwkCVJ72u7idTgQaBoLRD0UxBAWTF9GWurJO9YD9yh00BzbkhpeXtm6na+MvJU7Z73A==", "cpu": [ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz", - "integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.27.4.tgz", + "integrity": "sha512-pleyNgyd1kkBkw2kOqlBx+0atfIIkkExOTiifoODo6qKDSpnc6WzUY5RhHdmTdIJXBdSnh6JknnYTtmQyobrVg==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz", - "integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.27.4.tgz", + "integrity": "sha512-caluiUXvUuVyCHr5DxL8ohaaFFzPGmgmMvwmqAITMpV/Q+tPoaHZ/PWa3t8B2WyoRcIIuu1hkaW5KkeTDNSnMA==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz", - "integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.27.4.tgz", + "integrity": "sha512-FScrpHrO60hARyHh7s1zHE97u0KlT/RECzCKAdmI+LEoC1eDh/RDji9JgFqyO+wPDb86Oa/sXkily1+oi4FzJQ==", "cpu": [ "ppc64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz", - "integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.27.4.tgz", + "integrity": "sha512-qyyprhyGb7+RBfMPeww9FlHwKkCXdKHeGgSqmIXw9VSUtvyFZ6WZRtnxgbuz76FK7LyoN8t/eINRbPUcvXB5fw==", "cpu": [ "riscv64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz", - "integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.27.4.tgz", + "integrity": "sha512-PFz+y2kb6tbh7m3A7nA9++eInGcDVZUACulf/KzDtovvdTizHpZaJty7Gp0lFwSQcrnebHOqxF1MaKZd7psVRg==", "cpu": [ "s390x" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz", - "integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.27.4.tgz", + "integrity": "sha512-Ni8mMtfo+o/G7DVtweXXV/Ol2TFf63KYjTtoZ5f078AUgJTmaIJnj4JFU7TK/9SVWTaSJGxPi5zMDgK4w+Ez7Q==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz", - "integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.27.4.tgz", + "integrity": "sha512-5AeeAF1PB9TUzD+3cROzFTnAJAcVUGLuR8ng0E0WXGkYhp6RD6L+6szYVX+64Rs0r72019KHZS1ka1q+zU/wUw==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz", - "integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.27.4.tgz", + "integrity": "sha512-yOpVsA4K5qVwu2CaS3hHxluWIK5HQTjNV4tWjQXluMiiiu4pJj4BN98CvxohNCpcjMeTXk/ZMJBRbgRg8HBB6A==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz", - "integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.27.4.tgz", + "integrity": "sha512-KtwEJOaHAVJlxV92rNYiG9JQwQAdhBlrjNRp7P9L8Cb4Rer3in+0A+IPhJC9y68WAi9H0sX4AiG2NTsVlmqJeQ==", "cpu": [ "ia32" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz", - "integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.27.4.tgz", + "integrity": "sha512-3j4jx1TppORdTAoBJRd+/wJRGCPC0ETWkXOecJ6PPZLj6SptXkrXcNqdj0oclbKML6FkQltdz7bBA3rUSirZug==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" @@ -3872,9 +3394,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, "node_modules/@types/geojson": { @@ -3951,9 +3473,9 @@ "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" }, "node_modules/@types/react": { - "version": "18.3.5", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.5.tgz", - "integrity": "sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==", + "version": "18.3.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -3961,10 +3483,11 @@ } }, "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/react": "*" } @@ -4212,15 +3735,14 @@ "dev": true }, "node_modules/@vitejs/plugin-react": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz", - "integrity": "sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", + "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/core": "^7.24.5", - "@babel/plugin-transform-react-jsx-self": "^7.24.5", - "@babel/plugin-transform-react-jsx-source": "^7.24.1", + "@babel/core": "^7.26.0", + "@babel/plugin-transform-react-jsx-self": "^7.25.9", + "@babel/plugin-transform-react-jsx-source": "^7.25.9", "@types/babel__core": "^7.20.5", "react-refresh": "^0.14.2" }, @@ -4228,26 +3750,26 @@ "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0" + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, "node_modules/@vitest/coverage-v8": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.0.5.tgz", - "integrity": "sha512-qeFcySCg5FLO2bHHSa0tAZAOnAUbp4L6/A5JDuj9+bt53JREl8hpLjLHEWF0e/gWc8INVpJaqA7+Ene2rclpZg==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.8.tgz", + "integrity": "sha512-2Y7BPlKH18mAZYAW1tYByudlCYrQyl5RGvnnDYJKW5tCiO5qg3KSAy3XAxcxKz900a0ZXxWtKrMuZLe3lKBpJw==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.3.0", "@bcoe/v8-coverage": "^0.2.3", - "debug": "^4.3.5", + "debug": "^4.3.7", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-lib-source-maps": "^5.0.6", "istanbul-reports": "^3.1.7", - "magic-string": "^0.30.10", - "magicast": "^0.3.4", - "std-env": "^3.7.0", + "magic-string": "^0.30.12", + "magicast": "^0.3.5", + "std-env": "^3.8.0", "test-exclude": "^7.0.1", "tinyrainbow": "^1.2.0" }, @@ -4255,19 +3777,25 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "vitest": "2.0.5" + "@vitest/browser": "2.1.8", + "vitest": "2.1.8" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } } }, "node_modules/@vitest/expect": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz", - "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.8.tgz", + "integrity": "sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "2.0.5", - "@vitest/utils": "2.0.5", - "chai": "^5.1.1", + "@vitest/spy": "2.1.8", + "@vitest/utils": "2.1.8", + "chai": "^5.1.2", "tinyrainbow": "^1.2.0" }, "funding": { @@ -4275,9 +3803,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz", - "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.8.tgz", + "integrity": "sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4288,13 +3816,13 @@ } }, "node_modules/@vitest/runner": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.5.tgz", - "integrity": "sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.8.tgz", + "integrity": "sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "2.0.5", + "@vitest/utils": "2.1.8", "pathe": "^1.1.2" }, "funding": { @@ -4302,14 +3830,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.5.tgz", - "integrity": "sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.8.tgz", + "integrity": "sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.0.5", - "magic-string": "^0.30.10", + "@vitest/pretty-format": "2.1.8", + "magic-string": "^0.30.12", "pathe": "^1.1.2" }, "funding": { @@ -4317,66 +3845,70 @@ } }, "node_modules/@vitest/spy": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz", - "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.8.tgz", + "integrity": "sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==", "dev": true, "license": "MIT", "dependencies": { - "tinyspy": "^3.0.0" + "tinyspy": "^3.0.2" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz", - "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.8.tgz", + "integrity": "sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.0.5", - "estree-walker": "^3.0.3", - "loupe": "^3.1.1", + "@vitest/pretty-format": "2.1.8", + "loupe": "^3.1.2", "tinyrainbow": "^1.2.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@whatwg-node/events": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz", - "integrity": "sha512-IqnKIDWfXBJkvy/k6tzskWTc2NK3LcqHlb+KHGCrjOCH4jfQckRX0NAiIcC/vIqQkzLYw2r2CTSwAxcrtcD6lA==", - "dev": true - }, "node_modules/@whatwg-node/fetch": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.8.8.tgz", - "integrity": "sha512-CdcjGC2vdKhc13KKxgsc6/616BQ7ooDIgPeTuAiE8qfCnS0mGzcfCOoZXypQSz73nxI+GWc7ZReIAVhxoE1KCg==", + "version": "0.9.21", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.21.tgz", + "integrity": "sha512-Wt0jPb+04JjobK0pAAN7mEHxVHcGA9HoP3OyCsZtyAecNQeADXCZ1MihFwVwjsgaRYuGVmNlsCmLxlG6mor8Gw==", "dev": true, + "license": "MIT", "dependencies": { - "@peculiar/webcrypto": "^1.4.0", - "@whatwg-node/node-fetch": "^0.3.6", - "busboy": "^1.6.0", - "urlpattern-polyfill": "^8.0.0", - "web-streams-polyfill": "^3.2.1" + "@whatwg-node/node-fetch": "^0.5.23", + "urlpattern-polyfill": "^10.0.0" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@whatwg-node/node-fetch": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.3.6.tgz", - "integrity": "sha512-w9wKgDO4C95qnXZRwZTfCmLWqyRnooGjcIwG0wADWjw9/HN0p7dtvtgSvItZtUyNteEvgTrd8QojNEqV6DAGTA==", + "version": "0.5.26", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.26.tgz", + "integrity": "sha512-4jXDeZ4IH4bylZ6wu14VEx0aDXXhrN4TC279v9rPmn08g4EYekcYf8wdcOOnS9STjDkb6x77/6xBUTqxGgjr8g==", "dev": true, + "license": "MIT", "dependencies": { - "@whatwg-node/events": "^0.0.3", + "@kamilkisiela/fast-url-parser": "^1.1.4", "busboy": "^1.6.0", "fast-querystring": "^1.1.1", - "fast-url-parser": "^1.1.3", - "tslib": "^2.3.1" + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=18.0.0" } }, + "node_modules/@whatwg-node/node-fetch/node_modules/tslib": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "dev": true, + "license": "0BSD" + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", @@ -4439,18 +3971,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/alge": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/alge/-/alge-0.8.1.tgz", - "integrity": "sha512-kiV9nTt+XIauAXsowVygDxMZLplZxDWt0W8plE/nB32/V2ziM/P/TxDbSVK7FYIUt2Xo16h3/htDh199LNPCKQ==", - "license": "MIT", - "dependencies": { - "lodash.ismatch": "^4.4.0", - "remeda": "^1.0.0", - "ts-toolbelt": "^9.6.0", - "zod": "^3.17.3" - } - }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -4680,20 +4200,6 @@ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true }, - "node_modules/asn1js": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz", - "integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==", - "dev": true, - "dependencies": { - "pvtsutils": "^1.3.2", - "pvutils": "^1.1.3", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -4761,15 +4267,25 @@ } }, "node_modules/axe-core": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.9.1.tgz", - "integrity": "sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz", + "integrity": "sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==", "dev": true, "license": "MPL-2.0", "engines": { "node": ">=4" } }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/babel-plugin-syntax-trailing-function-commas": { "version": "7.0.0-beta.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", @@ -4892,9 +4408,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", "dev": true, "funding": [ { @@ -4910,11 +4426,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -5042,9 +4559,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001600", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz", - "integrity": "sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==", + "version": "1.0.30001669", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz", + "integrity": "sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==", "dev": true, "funding": [ { @@ -5059,7 +4576,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/capital-case": { "version": "1.0.4", @@ -5073,9 +4591,9 @@ } }, "node_modules/chai": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", - "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", + "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", "dev": true, "license": "MIT", "dependencies": { @@ -5392,12 +4910,13 @@ } }, "node_modules/cssstyle": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", - "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz", + "integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==", "dev": true, + "license": "MIT", "dependencies": { - "rrweb-cssom": "^0.6.0" + "rrweb-cssom": "^0.7.1" }, "engines": { "node": ">=18" @@ -5491,13 +5010,13 @@ "dev": true }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -5533,39 +5052,6 @@ "node": ">=6" } }, - "node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -5727,27 +5213,6 @@ "url": "https://dotenvx.com" } }, - "node_modules/dprint": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.46.3.tgz", - "integrity": "sha512-ACEd7B7sO/uvPvV/nsHbtkIeMqeD2a8XGO1DokROtKDUmI5WbuflGZOwyjFCYwy4rkX6FXoYBzGdEQ6um7BjCA==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "peer": true, - "bin": { - "dprint": "bin.js" - }, - "optionalDependencies": { - "@dprint/darwin-arm64": "0.46.3", - "@dprint/darwin-x64": "0.46.3", - "@dprint/linux-arm64-glibc": "0.46.3", - "@dprint/linux-arm64-musl": "0.46.3", - "@dprint/linux-x64-glibc": "0.46.3", - "@dprint/linux-x64-musl": "0.46.3", - "@dprint/win32-x64": "0.46.3" - } - }, "node_modules/dset": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.3.tgz", @@ -5771,10 +5236,11 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.717", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.717.tgz", - "integrity": "sha512-6Fmg8QkkumNOwuZ/5mIbMU9WI3H2fmn5ajcVya64I5Yr5CcNmO7vcLt0Y7c96DCiMO5/9G+4sI2r6eEvdg1F7A==", - "dev": true + "version": "1.5.40", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.40.tgz", + "integrity": "sha512-LYm78o6if4zTasnYclgQzxEcgMoIcybWOhkATWepN95uwVVWV0/IW10v+2sIeHE+bIYWipLneTftVyQm45UY7g==", + "dev": true, + "license": "ISC" }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -5885,31 +5351,10 @@ "node": ">= 0.4" } }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/es-iterator-helpers": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", - "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz", + "integrity": "sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==", "dev": true, "license": "MIT", "dependencies": { @@ -5920,18 +5365,25 @@ "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", + "globalthis": "^1.0.4", "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", "has-symbols": "^1.0.3", "internal-slot": "^1.0.7", - "iterator.prototype": "^1.1.2", + "iterator.prototype": "^1.1.3", "safe-array-concat": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true, + "license": "MIT" + }, "node_modules/es-object-atoms": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", @@ -5985,49 +5437,50 @@ } }, "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", + "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", "dev": true, "hasInstallScript": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@esbuild/aix-ppc64": "0.24.0", + "@esbuild/android-arm": "0.24.0", + "@esbuild/android-arm64": "0.24.0", + "@esbuild/android-x64": "0.24.0", + "@esbuild/darwin-arm64": "0.24.0", + "@esbuild/darwin-x64": "0.24.0", + "@esbuild/freebsd-arm64": "0.24.0", + "@esbuild/freebsd-x64": "0.24.0", + "@esbuild/linux-arm": "0.24.0", + "@esbuild/linux-arm64": "0.24.0", + "@esbuild/linux-ia32": "0.24.0", + "@esbuild/linux-loong64": "0.24.0", + "@esbuild/linux-mips64el": "0.24.0", + "@esbuild/linux-ppc64": "0.24.0", + "@esbuild/linux-riscv64": "0.24.0", + "@esbuild/linux-s390x": "0.24.0", + "@esbuild/linux-x64": "0.24.0", + "@esbuild/netbsd-x64": "0.24.0", + "@esbuild/openbsd-arm64": "0.24.0", + "@esbuild/openbsd-x64": "0.24.0", + "@esbuild/sunos-x64": "0.24.0", + "@esbuild/win32-arm64": "0.24.0", + "@esbuild/win32-ia32": "0.24.0", + "@esbuild/win32-x64": "0.24.0" } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -6045,16 +5498,17 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -6132,9 +5586,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.9.0.tgz", - "integrity": "sha512-McVbYmwA3NEKwRQY5g4aWMdcZE5xZxV8i8l7CqJSrameuGSQJtSWaL/LxTEzSKKaCcOhlpDR8XEfYXWPrdo/ZQ==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", "dev": true, "license": "MIT", "dependencies": { @@ -6159,9 +5613,9 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz", - "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==", + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", "dev": true, "license": "MIT", "dependencies": { @@ -6173,7 +5627,7 @@ "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.9.0", + "eslint-module-utils": "^2.12.0", "hasown": "^2.0.2", "is-core-module": "^2.15.1", "is-glob": "^4.0.3", @@ -6182,13 +5636,14 @@ "object.groupby": "^1.0.3", "object.values": "^1.2.0", "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "node_modules/eslint-plugin-import/node_modules/brace-expansion": { @@ -6239,54 +5694,43 @@ } }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.9.0.tgz", - "integrity": "sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", "dev": true, "license": "MIT", "dependencies": { - "aria-query": "~5.1.3", + "aria-query": "^5.3.2", "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", - "axe-core": "^4.9.1", - "axobject-query": "~3.1.1", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.19", "hasown": "^2.0.2", "jsx-ast-utils": "^3.3.5", "language-tags": "^1.0.9", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "safe-regex-test": "^1.0.3", - "string.prototype.includes": "^2.0.0" + "string.prototype.includes": "^2.0.1" }, "engines": { "node": ">=4.0" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "deep-equal": "^2.0.5" - } - }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/axobject-query": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", - "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", "dev": true, "license": "Apache-2.0", - "dependencies": { - "deep-equal": "^2.0.5" + "engines": { + "node": ">= 0.4" } }, "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { @@ -6314,9 +5758,9 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.35.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.1.tgz", - "integrity": "sha512-B5ok2JgbaaWn/zXbKCGgKDNL2tsID3Pd/c/yvjcpsd9HQDwyYc/TQv3AZMmOvrJgCs3AnYNUHRCQEMMQAYJ7Yg==", + "version": "7.37.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz", + "integrity": "sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==", "dev": true, "license": "MIT", "dependencies": { @@ -6325,7 +5769,7 @@ "array.prototype.flatmap": "^1.3.2", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.19", + "es-iterator-helpers": "^1.1.0", "estraverse": "^5.3.0", "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", @@ -6347,25 +5791,26 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0.tgz", + "integrity": "sha512-hIOwI+5hYGpJEc4uPRmz2ulCjAGD/N13Lukkh8cLV0i2IRk/bdZDYjgLVHj+U9Z704kLIdIO6iueGvxNur0sgw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.11.tgz", - "integrity": "sha512-wrAKxMbVr8qhXTtIKfXqAn5SAtRZt0aXxe5P23Fh4pUAdC6XEsybGLB8P0PI4j1yYqOgUEUlzKAGDfo7rJOjcw==", + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.16.tgz", + "integrity": "sha512-slterMlxAhov/DZO8NScf6mEeMBBXodFUolijDvrtTxyezyLoTQaa73FyYus/VbTdftd8wBgBxPMRk3poleXNQ==", "dev": true, "license": "MIT", "peerDependencies": { - "eslint": ">=7" + "eslint": ">=8.40" } }, "node_modules/eslint-plugin-react/node_modules/brace-expansion": { @@ -6456,6 +5901,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6466,6 +5912,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -6481,6 +5928,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6493,6 +5941,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -6555,7 +6004,6 @@ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, - "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" } @@ -6569,78 +6017,14 @@ "node": ">=0.10.0" } }, - "node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/execa/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/execa/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/execa/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/execa/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/expect-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", + "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=12.0.0" } }, "node_modules/extend-shallow": { @@ -6684,7 +6068,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -6737,19 +6122,11 @@ "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", "dev": true, + "license": "MIT", "dependencies": { "fast-decode-uri-component": "^1.0.1" } }, - "node_modules/fast-url-parser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", - "dev": true, - "dependencies": { - "punycode": "^1.3.2" - } - }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -7006,16 +6383,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -7178,12 +6545,14 @@ } }, "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, + "license": "MIT", "dependencies": { - "define-properties": "^1.1.3" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -7240,10 +6609,11 @@ } }, "node_modules/graphql-config": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-5.0.3.tgz", - "integrity": "sha512-BNGZaoxIBkv9yy6Y7omvsaBUHOzfFcII3UN++tpH8MGOKFPFkCPZuwx09ggANMt8FgyWP1Od8SWPmrUEZca4NQ==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-5.1.3.tgz", + "integrity": "sha512-RBhejsPjrNSuwtckRlilWzLVt2j8itl74W9Gke1KejDTz7oaA5kVd6wRn9zK9TS5mcmIYGxf7zN7a1ORMdxp1Q==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-tools/graphql-file-loader": "^8.0.0", "@graphql-tools/json-file-loader": "^8.0.0", @@ -7252,8 +6622,8 @@ "@graphql-tools/url-loader": "^8.0.0", "@graphql-tools/utils": "^10.0.0", "cosmiconfig": "^8.1.0", - "jiti": "^1.18.2", - "minimatch": "^4.2.3", + "jiti": "^2.0.0", + "minimatch": "^9.0.5", "string-env-interpolation": "^1.0.1", "tslib": "^2.4.0" }, @@ -7270,57 +6640,26 @@ } } }, - "node_modules/graphql-config/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/graphql-config/node_modules/minimatch": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.3.tgz", - "integrity": "sha512-lIUdtK5hdofgCTu3aT0sOaHsYR37viUuIc0rwnnDXImbwFRcumyLMeZaM0t0I/fgxS6s6JMfu0rLD1Wz9pv1ng==", + "node_modules/graphql-config/node_modules/jiti": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.3.3.tgz", + "integrity": "sha512-EX4oNDwcXSivPrw2qKH2LB5PoFxEvgtv2JgwW0bU858HoLQ+kutSvjLMUqBd0PeJYEinLWhoI9Ol0eYMqj/wNQ==", "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": ">=10" + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" } }, "node_modules/graphql-request": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-7.1.0.tgz", - "integrity": "sha512-Ouu/lYVFhARS1aXeZoVJWnGT6grFJXTLwXJuK4mUGGRo0EUk1JkyYp43mdGmRgUVezpRm6V5Sq3t8jBDQcajng==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-7.1.2.tgz", + "integrity": "sha512-+XE3iuC55C2di5ZUrB4pjgwe+nIQBuXVIK9J98wrVwojzDW3GMdSBZfxUk8l4j9TieIpjpggclxhNEU9ebGF8w==", "license": "MIT", "dependencies": { - "@graphql-typed-document-node/core": "^3.2.0", - "@molt/command": "^0.9.0", - "zod": "^3.23.8" - }, - "bin": { - "graffle": "build/cli/generate.js" + "@graphql-typed-document-node/core": "^3.2.0" }, "peerDependencies": { - "@dprint/formatter": "^0.3.0", - "@dprint/typescript": "^0.91.1", - "dprint": "^0.46.2", "graphql": "14 - 16" - }, - "peerDependenciesMeta": { - "@dprint/formatter": { - "optional": true - }, - "@dprint/typescript": { - "optional": true - }, - "dprint": { - "optional": true - } } }, "node_modules/graphql-tag": { @@ -7486,15 +6825,6 @@ "node": ">= 14" } }, - "node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -7685,23 +7015,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-array-buffer": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", @@ -7729,6 +7042,7 @@ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -7847,6 +7161,7 @@ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -7868,6 +7183,7 @@ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -8037,18 +7353,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -8257,16 +7561,20 @@ } }, "node_modules/iterator.prototype": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", - "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz", + "integrity": "sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==", "dev": true, + "license": "MIT", "dependencies": { "define-properties": "^1.2.1", "get-intrinsic": "^1.2.1", "has-symbols": "^1.0.3", "reflect.getprototypeof": "^1.0.4", "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/jackspeak": { @@ -8320,14 +7628,19 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbi": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-4.3.0.tgz", + "integrity": "sha512-SnZNcinB4RIcnEyZqFPdGPVgrg2AcnykiBy0sHVJQKHYeaLUvi3Exj+iaPpLnFVkDPZIV4U0yvgC9/R4uEAZ9g==" + }, "node_modules/jsdom": { - "version": "25.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.0.tgz", - "integrity": "sha512-OhoFVT59T7aEq75TVw9xxEfkXgacpqAhQaYgP9y/fDqWQCMB/b1H66RfmPm/MaeaAIU9nDwMOVTlPN51+ao6CQ==", + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", + "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", "dev": true, "license": "MIT", "dependencies": { - "cssstyle": "^4.0.1", + "cssstyle": "^4.1.0", "data-urls": "^5.0.0", "decimal.js": "^10.4.3", "form-data": "^4.0.0", @@ -8340,7 +7653,7 @@ "rrweb-cssom": "^0.7.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.4", + "tough-cookie": "^5.0.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", @@ -8361,23 +7674,17 @@ } } }, - "node_modules/jsdom/node_modules/rrweb-cssom": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", - "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", - "dev": true, - "license": "MIT" - }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-buffer": { @@ -8600,30 +7907,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "license": "MIT" - }, - "node_modules/lodash.ismatch": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", - "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", - "license": "MIT" - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "node_modules/lodash.snakecase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", - "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", - "license": "MIT" - }, "node_modules/lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", @@ -8693,14 +7982,11 @@ } }, "node_modules/loupe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", - "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", + "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", "dev": true, - "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.1" - } + "license": "MIT" }, "node_modules/lower-case": { "version": "2.0.2", @@ -8740,24 +8026,24 @@ } }, "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/magicast": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.4.tgz", - "integrity": "sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.24.4", - "@babel/types": "^7.24.0", + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", "source-map-js": "^1.2.0" } }, @@ -8819,9 +8105,9 @@ } }, "node_modules/maplibre-gl": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.6.0.tgz", - "integrity": "sha512-zobZK+fE+XM+7K81fk5pSBYWZlTGjGT0P96y2fR4DV2ry35ZBfAd0uWNatll69EgYeE+uOhN1MvEk+z1PCuyOQ==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.7.1.tgz", + "integrity": "sha512-lgL7XpIwsgICiL82ITplfS7IGwrB1OJIw/pCvprDp2dhmSSEBgmPzYRvwYYYvJGJD7fxUv1Tvpih4nZ6VrLuaA==", "license": "BSD-3-Clause", "dependencies": { "@mapbox/geojson-rewind": "^0.5.2", @@ -8865,12 +8151,6 @@ "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", "license": "ISC" }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -8975,10 +8255,11 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/murmurhash-js": { "version": "1.0.0", @@ -8992,9 +8273,9 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "dev": true, "funding": [ { @@ -9083,10 +8364,11 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "2.1.1", @@ -9100,33 +8382,6 @@ "node": ">=0.10.0" } }, - "node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/nullthrows": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", @@ -9157,23 +8412,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -9601,11 +8839,10 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true, - "license": "ISC" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", @@ -9629,9 +8866,9 @@ } }, "node_modules/postcss": { - "version": "8.4.41", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", - "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "dev": true, "funding": [ { @@ -9647,11 +8884,10 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -9672,9 +8908,9 @@ } }, "node_modules/prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.1.tgz", + "integrity": "sha512-G+YdqtITVZmOJje6QkXQWzl3fSfMxFwm1tjTyo9exhkmWSqC4Yhd1+lug++IlR2mvRVAxEDDWYkQdeSztajqgg==", "dev": true, "license": "MIT", "bin": { @@ -9761,42 +8997,6 @@ "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, - "node_modules/pvtsutils": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.5.tgz", - "integrity": "sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==", - "dev": true, - "dependencies": { - "tslib": "^2.6.1" - } - }, - "node_modules/pvutils": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz", - "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -9834,14 +9034,14 @@ } }, "node_modules/react-bootstrap": { - "version": "2.10.4", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.4.tgz", - "integrity": "sha512-W3398nBM2CBfmGP2evneEO3ZZwEMPtHs72q++eNw60uDGDAdiGn0f9yNys91eo7/y8CTF5Ke1C0QO8JFVPU40Q==", + "version": "2.10.6", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.6.tgz", + "integrity": "sha512-fNvKytSp0nHts1WRnRBJeBEt+I9/ZdrnhIjWOucEduRNvFRU1IXjZueDdWnBiqsTSJ7MckQJi9i/hxGolaRq+g==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.24.7", "@restart/hooks": "^0.4.9", - "@restart/ui": "^1.6.9", + "@restart/ui": "^1.9.0", "@types/react-transition-group": "^4.4.6", "classnames": "^2.3.2", "dom-helpers": "^5.2.1", @@ -9972,20 +9172,12 @@ "node": ">= 6" } }, - "node_modules/readline-sync": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", - "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==", - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/reflect.getprototypeof": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -10036,12 +9228,6 @@ "invariant": "^2.2.4" } }, - "node_modules/remeda": { - "version": "1.61.0", - "resolved": "https://registry.npmjs.org/remeda/-/remeda-1.61.0.tgz", - "integrity": "sha512-caKfSz9rDeSKBQQnlJnVW3mbVdFgxgGWQKq1XlFokqjf+hQD5gxutLGTTY2A/x24UxVyJe9gH5fAkFI63ULw4A==", - "license": "MIT" - }, "node_modules/remedial": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/remedial/-/remedial-1.0.8.tgz", @@ -10078,12 +9264,6 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -10163,13 +9343,12 @@ } }, "node_modules/rollup": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz", - "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.27.4.tgz", + "integrity": "sha512-RLKxqHEMjh/RGLsDxAEsaLO3mWgyoU6x9w6n1ikAzet4B3gI2/3yP6PWY2p9QzRTh6MfEIXB3MwsOY0Iv3vNrw==", "dev": true, - "license": "MIT", "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.6" }, "bin": { "rollup": "dist/bin/rollup" @@ -10179,30 +9358,33 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.21.2", - "@rollup/rollup-android-arm64": "4.21.2", - "@rollup/rollup-darwin-arm64": "4.21.2", - "@rollup/rollup-darwin-x64": "4.21.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.21.2", - "@rollup/rollup-linux-arm-musleabihf": "4.21.2", - "@rollup/rollup-linux-arm64-gnu": "4.21.2", - "@rollup/rollup-linux-arm64-musl": "4.21.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2", - "@rollup/rollup-linux-riscv64-gnu": "4.21.2", - "@rollup/rollup-linux-s390x-gnu": "4.21.2", - "@rollup/rollup-linux-x64-gnu": "4.21.2", - "@rollup/rollup-linux-x64-musl": "4.21.2", - "@rollup/rollup-win32-arm64-msvc": "4.21.2", - "@rollup/rollup-win32-ia32-msvc": "4.21.2", - "@rollup/rollup-win32-x64-msvc": "4.21.2", + "@rollup/rollup-android-arm-eabi": "4.27.4", + "@rollup/rollup-android-arm64": "4.27.4", + "@rollup/rollup-darwin-arm64": "4.27.4", + "@rollup/rollup-darwin-x64": "4.27.4", + "@rollup/rollup-freebsd-arm64": "4.27.4", + "@rollup/rollup-freebsd-x64": "4.27.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.27.4", + "@rollup/rollup-linux-arm-musleabihf": "4.27.4", + "@rollup/rollup-linux-arm64-gnu": "4.27.4", + "@rollup/rollup-linux-arm64-musl": "4.27.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.27.4", + "@rollup/rollup-linux-riscv64-gnu": "4.27.4", + "@rollup/rollup-linux-s390x-gnu": "4.27.4", + "@rollup/rollup-linux-x64-gnu": "4.27.4", + "@rollup/rollup-linux-x64-musl": "4.27.4", + "@rollup/rollup-win32-arm64-msvc": "4.27.4", + "@rollup/rollup-win32-ia32-msvc": "4.27.4", + "@rollup/rollup-win32-x64-msvc": "4.27.4", "fsevents": "~2.3.2" } }, "node_modules/rrweb-cssom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", - "dev": true + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", + "dev": true, + "license": "MIT" }, "node_modules/run-async": { "version": "2.4.1", @@ -10547,10 +9729,11 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -10605,23 +9788,11 @@ "dev": true }, "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "dev": true - }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", "dev": true, - "license": "MIT", - "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } + "license": "MIT" }, "node_modules/streamsearch": { "version": "1.1.0", @@ -10647,48 +9818,6 @@ "integrity": "sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==", "dev": true }, - "node_modules/string-length": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-6.0.0.tgz", - "integrity": "sha512-1U361pxZHEQ+FeSjzqRpV+cu2vTzYeWeafXFLykiFlv4Vc0n3njgU8HrMbyik5uwm77naWMuVG8fhEF+Ovb1Kg==", - "license": "MIT", - "dependencies": { - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-length/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-length/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -10733,14 +9862,18 @@ "dev": true }, "node_modules/string.prototype.includes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", - "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", "dev": true, "license": "MIT", "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/string.prototype.matchall": { @@ -10864,18 +9997,6 @@ "node": ">=4" } }, - "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -10984,16 +10105,23 @@ "dev": true }, "node_modules/tinybench": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", - "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", + "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", "dev": true, "license": "MIT" }, "node_modules/tinypool": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.0.tgz", - "integrity": "sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", + "integrity": "sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==", "dev": true, "license": "MIT", "engines": { @@ -11017,9 +10145,9 @@ } }, "node_modules/tinyspy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz", - "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", "dev": true, "license": "MIT", "engines": { @@ -11035,6 +10163,26 @@ "tslib": "^2.0.3" } }, + "node_modules/tldts": { + "version": "6.1.52", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.52.tgz", + "integrity": "sha512-fgrDJXDjbAverY6XnIt0lNfv8A0cf7maTEaZxNykLGsLG7XP+5xhjBTrt/ieAsFjAlZ+G5nmXomLcZDkxXnDzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.52" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.52", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.52.tgz", + "integrity": "sha512-j4OxQI5rc1Ve/4m/9o2WhWSC4jGc4uVbCINdOEJRAraCi0YqTqgMcxUx7DbmuP0G3PCixoof/RZB0Q5Kh9tagw==", + "dev": true, + "license": "MIT" + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -11047,15 +10195,6 @@ "node": ">=0.6.0" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -11069,28 +10208,16 @@ } }, "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", + "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" + "tldts": "^6.1.32" }, "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" + "node": ">=16" } }, "node_modules/tr46": { @@ -11132,12 +10259,6 @@ "integrity": "sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA==", "dev": true }, - "node_modules/ts-toolbelt": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", - "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==", - "license": "Apache-2.0" - }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -11265,9 +10386,9 @@ } }, "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -11372,15 +10493,6 @@ "node": ">=0.10.0" } }, - "node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/unixify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz", @@ -11394,9 +10506,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "funding": [ { @@ -11412,9 +10524,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -11459,21 +10572,12 @@ "node": ">=6" } }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, "node_modules/urlpattern-polyfill": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", - "integrity": "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==", - "dev": true + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true, + "license": "MIT" }, "node_modules/util-deprecate": { "version": "1.0.2", @@ -11491,21 +10595,21 @@ } }, "node_modules/vite": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz", - "integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.2.tgz", + "integrity": "sha512-XdQ+VsY2tJpBsKGs0wf3U/+azx8BBpYRHFAyKm5VeEZNOJZRB63q7Sc8Iup3k0TrN3KO6QgyzFf+opSbfY1y0g==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.41", - "rollup": "^4.20.0" + "esbuild": "^0.24.0", + "postcss": "^8.4.49", + "rollup": "^4.23.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -11514,19 +10618,25 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", - "terser": "^5.4.0" + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "jiti": { + "optional": true + }, "less": { "optional": true }, @@ -11547,20 +10657,26 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, "node_modules/vite-node": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.5.tgz", - "integrity": "sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.8.tgz", + "integrity": "sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==", "dev": true, "license": "MIT", "dependencies": { "cac": "^6.7.14", - "debug": "^4.3.5", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", "pathe": "^1.1.2", - "tinyrainbow": "^1.2.0", "vite": "^5.0.0" }, "bin": { @@ -11573,67 +10689,1050 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/vitest": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.5.tgz", - "integrity": "sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==", + "node_modules/vite-node/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.3.0", - "@vitest/expect": "2.0.5", - "@vitest/pretty-format": "^2.0.5", - "@vitest/runner": "2.0.5", - "@vitest/snapshot": "2.0.5", - "@vitest/spy": "2.0.5", - "@vitest/utils": "2.0.5", - "chai": "^5.1.1", - "debug": "^4.3.5", - "execa": "^8.0.1", - "magic-string": "^0.30.10", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vite-node/node_modules/vite": { + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.8.tgz", + "integrity": "sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.8", + "@vitest/mocker": "2.1.8", + "@vitest/pretty-format": "^2.1.8", + "@vitest/runner": "2.1.8", + "@vitest/snapshot": "2.1.8", + "@vitest/spy": "2.1.8", + "@vitest/utils": "2.1.8", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", "pathe": "^1.1.2", - "std-env": "^3.7.0", - "tinybench": "^2.8.0", - "tinypool": "^1.0.0", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", "tinyrainbow": "^1.2.0", "vite": "^5.0.0", - "vite-node": "2.0.5", + "vite-node": "2.1.8", "why-is-node-running": "^2.3.0" }, "bin": { - "vitest": "vitest.mjs" + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.8", + "@vitest/ui": "2.1.8", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@vitest/mocker": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.8.tgz", + "integrity": "sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.8", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vitest/node_modules/vite": { + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" }, "engines": { "node": "^18.0.0 || >=20.0.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" }, "peerDependencies": { - "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.0.5", - "@vitest/ui": "2.0.5", - "happy-dom": "*", - "jsdom": "*" + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" }, "peerDependenciesMeta": { - "@edge-runtime/vm": { + "@types/node": { "optional": true }, - "@types/node": { + "less": { "optional": true }, - "@vitest/browser": { + "lightningcss": { "optional": true }, - "@vitest/ui": { + "sass": { "optional": true }, - "happy-dom": { + "sass-embedded": { "optional": true }, - "jsdom": { + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { "optional": true } } @@ -11677,28 +11776,6 @@ "defaults": "^1.0.3" } }, - "node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/webcrypto-core": { - "version": "1.7.8", - "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.8.tgz", - "integrity": "sha512-eBR98r9nQXTqXt/yDRtInszPMjTaSAMJAFDg2AHsgrnczawT1asx9YNBX6k5p+MekbPF4+s/UJJrr88zsTqkSg==", - "dev": true, - "dependencies": { - "@peculiar/asn1-schema": "^2.3.8", - "@peculiar/json-schema": "^1.1.12", - "asn1js": "^3.0.1", - "pvtsutils": "^1.3.5", - "tslib": "^2.6.2" - } - }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -11786,13 +11863,14 @@ } }, "node_modules/which-builtin-type": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", - "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", + "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", "dev": true, + "license": "MIT", "dependencies": { - "function.prototype.name": "^1.1.5", - "has-tostringtag": "^1.0.0", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", "is-date-object": "^1.0.5", "is-finalizationregistry": "^1.0.2", @@ -11801,8 +11879,8 @@ "is-weakref": "^1.0.2", "isarray": "^2.0.5", "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.9" + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -11963,9 +12041,9 @@ "dev": true }, "node_modules/yaml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", - "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", + "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", "dev": true, "bin": { "yaml": "bin.mjs" @@ -12018,15 +12096,6 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/zod": { - "version": "3.23.8", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } } } } diff --git a/client/package.json b/client/package.json index 5b26215fe5f..f930bcd67d5 100644 --- a/client/package.json +++ b/client/package.json @@ -18,38 +18,39 @@ }, "dependencies": { "@googlemaps/polyline-codec": "1.0.28", + "@js-temporal/polyfill": "0.4.4", "bootstrap": "5.3.3", "graphql": "16.9.0", - "graphql-request": "7.1.0", - "maplibre-gl": "4.6.0", + "graphql-request": "7.1.2", + "maplibre-gl": "4.7.1", "react": "18.3.1", - "react-bootstrap": "2.10.4", + "react-bootstrap": "2.10.6", "react-dom": "18.3.1", "react-map-gl": "7.1.7" }, "devDependencies": { - "@graphql-codegen/cli": "5.0.2", - "@graphql-codegen/client-preset": "4.3.3", + "@graphql-codegen/cli": "5.0.3", + "@graphql-codegen/client-preset": "4.5.1", "@graphql-codegen/introspection": "4.0.3", - "@parcel/watcher": "2.4.1", + "@parcel/watcher": "2.5.0", "@testing-library/react": "16.0.1", - "@types/react": "18.3.5", - "@types/react-dom": "18.3.0", + "@types/react": "18.3.12", + "@types/react-dom": "18.3.1", "@typescript-eslint/eslint-plugin": "7.18.0", "@typescript-eslint/parser": "7.18.0", - "@vitejs/plugin-react": "4.3.1", - "@vitest/coverage-v8": "2.0.5", - "eslint": "8.57.0", + "@vitejs/plugin-react": "4.3.4", + "@vitest/coverage-v8": "2.1.8", + "eslint": "8.57.1", "eslint-config-prettier": "9.1.0", - "eslint-plugin-import": "2.30.0", - "eslint-plugin-jsx-a11y": "6.9.0", - "eslint-plugin-react": "7.35.1", - "eslint-plugin-react-hooks": "4.6.2", - "eslint-plugin-react-refresh": "0.4.11", - "jsdom": "25.0.0", - "prettier": "3.3.3", - "typescript": "5.5.4", - "vite": "5.4.2", - "vitest": "2.0.5" + "eslint-plugin-import": "2.31.0", + "eslint-plugin-jsx-a11y": "6.10.2", + "eslint-plugin-react": "7.37.2", + "eslint-plugin-react-hooks": "5.0.0", + "eslint-plugin-react-refresh": "0.4.16", + "jsdom": "25.0.1", + "prettier": "3.4.1", + "typescript": "5.7.2", + "vite": "6.0.2", + "vitest": "2.1.8" } } diff --git a/client/src/components/ItineraryList/ItineraryHeaderContent.tsx b/client/src/components/ItineraryList/ItineraryHeaderContent.tsx index 419b7a2ebb9..fdfea81e7e4 100644 --- a/client/src/components/ItineraryList/ItineraryHeaderContent.tsx +++ b/client/src/components/ItineraryList/ItineraryHeaderContent.tsx @@ -1,8 +1,9 @@ import { TripPattern } from '../../gql/graphql.ts'; import { TIME_BOX_WIDTH, useHeaderContentStyleCalculations } from './useHeaderContentStyleCalculations.ts'; import { ItineraryHeaderLegContent } from './ItineraryHeaderLegContent.tsx'; -import { useMemo } from 'react'; +import { useContext, useMemo } from 'react'; import { formatTime } from '../../util/formatTime.ts'; +import { TimeZoneContext } from '../../hooks/TimeZoneContext.ts'; export function ItineraryHeaderContent({ tripPattern, @@ -24,14 +25,16 @@ export function ItineraryHeaderContent({ latestEndTime, ); + const timeZone = useContext(TimeZoneContext); + const formattedStartTime = useMemo( - () => formatTime(tripPattern.expectedStartTime, 'short'), - [tripPattern.expectedStartTime], + () => formatTime(tripPattern.expectedStartTime, timeZone, 'short'), + [tripPattern.expectedStartTime, timeZone], ); const formattedEndTime = useMemo( - () => formatTime(tripPattern.expectedEndTime, 'short'), - [tripPattern.expectedEndTime], + () => formatTime(tripPattern.expectedEndTime, timeZone, 'short'), + [tripPattern.expectedEndTime, timeZone], ); return ( @@ -45,6 +48,7 @@ export function ItineraryHeaderContent({ }} />
    @@ -14,16 +24,16 @@ export function ItineraryLegDetails({ leg, isLast }: { leg: Leg; isLast: boolean {formatDistance(leg.distance)}, {formatDuration(leg.duration)}
    - -{' '} - + -
    {leg.mode}{' '} {leg.line && ( <> - + , )}{' '} diff --git a/client/src/components/ItineraryList/ItineraryListContainer.tsx b/client/src/components/ItineraryList/ItineraryListContainer.tsx index feaf29aa514..b474d2eb5ec 100644 --- a/client/src/components/ItineraryList/ItineraryListContainer.tsx +++ b/client/src/components/ItineraryList/ItineraryListContainer.tsx @@ -5,6 +5,8 @@ import { ItineraryHeaderContent } from './ItineraryHeaderContent.tsx'; import { useEarliestAndLatestTimes } from './useEarliestAndLatestTimes.ts'; import { ItineraryDetails } from './ItineraryDetails.tsx'; import { ItineraryPaginationControl } from './ItineraryPaginationControl.tsx'; +import { useContext } from 'react'; +import { TimeZoneContext } from '../../hooks/TimeZoneContext.ts'; export function ItineraryListContainer({ tripQueryResult, @@ -21,6 +23,7 @@ export function ItineraryListContainer({ }) { const [earliestStartTime, latestEndTime] = useEarliestAndLatestTimes(tripQueryResult); const { containerRef, containerWidth } = useContainerWidth(); + const timeZone = useContext(TimeZoneContext); return (
    @@ -56,6 +59,9 @@ export function ItineraryListContainer({ ))} +
    + All times in {timeZone} +
    ); } diff --git a/client/src/components/ItineraryList/ItineraryPaginationControl.tsx b/client/src/components/ItineraryList/ItineraryPaginationControl.tsx index ecc1ffd45db..bf74c83fbca 100644 --- a/client/src/components/ItineraryList/ItineraryPaginationControl.tsx +++ b/client/src/components/ItineraryList/ItineraryPaginationControl.tsx @@ -14,6 +14,8 @@ export function ItineraryPaginationControl({ return (
    {' '} -
    + ); } + export default GraphiQLRouteButton; diff --git a/client/src/components/SearchBar/ItineraryFilterDebugSelect.tsx b/client/src/components/SearchBar/ItineraryFilterDebugSelect.tsx index 636ba551541..6f479290947 100644 --- a/client/src/components/SearchBar/ItineraryFilterDebugSelect.tsx +++ b/client/src/components/SearchBar/ItineraryFilterDebugSelect.tsx @@ -11,11 +11,12 @@ export function ItineraryFilterDebugSelect({ return ( - Itinerary filter debug + Filter debug { setTripQueryVariables({ ...tripQueryVariables, diff --git a/client/src/components/SearchBar/LocationInputField.tsx b/client/src/components/SearchBar/LocationInputField.tsx index ffa66702e81..70584e0e6d8 100644 --- a/client/src/components/SearchBar/LocationInputField.tsx +++ b/client/src/components/SearchBar/LocationInputField.tsx @@ -1,8 +1,37 @@ import { Form } from 'react-bootstrap'; -import { COORDINATE_PRECISION } from './constants.ts'; -import { Location } from '../../gql/graphql.ts'; +import { toString, parseLocation } from '../../util/locationConverter.ts'; +import { Location, TripQueryVariables } from '../../gql/graphql.ts'; +import { useCallback, useEffect, useState } from 'react'; + +interface Props { + id: string; + label: string; + tripQueryVariables: TripQueryVariables; + setTripQueryVariables: (tripQueryVariables: TripQueryVariables) => void; + locationFieldKey: 'from' | 'to'; +} + +export function LocationInputField({ id, label, tripQueryVariables, setTripQueryVariables, locationFieldKey }: Props) { + const [value, setValue] = useState(''); + + useEffect(() => { + const initialLocation: Location = tripQueryVariables[locationFieldKey]; + + setValue(toString(initialLocation) || ''); + }, [tripQueryVariables, locationFieldKey]); + + const onLocationChange = useCallback( + (value: string) => { + const newLocation = parseLocation(value) || {}; + + setTripQueryVariables({ + ...tripQueryVariables, + [locationFieldKey]: newLocation, + }); + }, + [tripQueryVariables, setTripQueryVariables, locationFieldKey], + ); -export function LocationInputField({ location, id, label }: { location: Location; id: string; label: string }) { return ( @@ -13,16 +42,14 @@ export function LocationInputField({ location, id, label }: { location: Location id={id} size="sm" placeholder="[Click in map]" - // Intentionally empty for now, but needed because of - // https://react.dev/reference/react-dom/components/input#controlling-an-input-with-a-state-variable - onChange={() => {}} - value={ - location.coordinates - ? `${location.coordinates?.latitude.toPrecision( - COORDINATE_PRECISION, - )} ${location.coordinates?.longitude.toPrecision(COORDINATE_PRECISION)}` - : '' - } + className="input-medium" + onChange={(e) => { + setValue(e.target.value); + }} + onBlur={(event) => { + onLocationChange(event.target.value); + }} + value={value} /> ); diff --git a/client/src/components/SearchBar/NumTripPatternsInput.tsx b/client/src/components/SearchBar/NumTripPatternsInput.tsx index b77e70adb81..360ce1c2c73 100644 --- a/client/src/components/SearchBar/NumTripPatternsInput.tsx +++ b/client/src/components/SearchBar/NumTripPatternsInput.tsx @@ -11,7 +11,7 @@ export function NumTripPatternsInput({ return ( - Number of trip patterns + Num. results setTripQueryVariables({ diff --git a/client/src/components/SearchBar/SearchBar.tsx b/client/src/components/SearchBar/SearchBar.tsx index dfcbc6ac36e..e90a54eab80 100644 --- a/client/src/components/SearchBar/SearchBar.tsx +++ b/client/src/components/SearchBar/SearchBar.tsx @@ -1,9 +1,8 @@ -import { Button, Spinner } from 'react-bootstrap'; +import { Button, ButtonGroup, Spinner } from 'react-bootstrap'; import { ServerInfo, TripQueryVariables } from '../../gql/graphql.ts'; import { LocationInputField } from './LocationInputField.tsx'; import { DepartureArrivalSelect } from './DepartureArrivalSelect.tsx'; -import { TimeInputField } from './TimeInputField.tsx'; -import { DateInputField } from './DateInputField.tsx'; +import { DateTimeInputField } from './DateTimeInputField.tsx'; import { SearchWindowInput } from './SearchWindowInput.tsx'; import { AccessSelect } from './AccessSelect.tsx'; import { EgressSelect } from './EgressSelect.tsx'; @@ -16,6 +15,8 @@ import { ServerInfoTooltip } from './ServerInfoTooltip.tsx'; import { useRef, useState } from 'react'; import logo from '../../static/img/otp-logo.svg'; import GraphiQLRouteButton from './GraphiQLRouteButton.tsx'; +import WheelchairAccessibleCheckBox from './WheelchairAccessibleCheckBox.tsx'; +import { SwapLocationsButton } from './SwapLocationsButton.tsx'; type SearchBarProps = { onRoute: () => void; @@ -33,15 +34,27 @@ export function SearchBar({ onRoute, tripQueryVariables, setTripQueryVariables,
    setShowServerInfo((v) => !v)}>
    - OTP Debug Client + OTP Debug {showServerInfo && }
    - - + + + - - + @@ -52,17 +65,24 @@ export function SearchBar({ onRoute, tripQueryVariables, setTripQueryVariables, tripQueryVariables={tripQueryVariables} setTripQueryVariables={setTripQueryVariables} /> + +
    - + + + +
    -
    ); } diff --git a/client/src/components/SearchBar/SearchWindowInput.tsx b/client/src/components/SearchBar/SearchWindowInput.tsx index 5442784de8e..a04a08bed04 100644 --- a/client/src/components/SearchBar/SearchWindowInput.tsx +++ b/client/src/components/SearchBar/SearchWindowInput.tsx @@ -19,6 +19,7 @@ export function SearchWindowInput({ size="sm" placeholder="(in minutes)" min={1} + className="input-small" value={tripQueryVariables.searchWindow || ''} onChange={(event) => setTripQueryVariables({ diff --git a/client/src/components/SearchBar/SwapLocationsButton.tsx b/client/src/components/SearchBar/SwapLocationsButton.tsx new file mode 100644 index 00000000000..28d25f2fac7 --- /dev/null +++ b/client/src/components/SearchBar/SwapLocationsButton.tsx @@ -0,0 +1,24 @@ +import { TripQueryVariables } from '../../gql/graphql.ts'; +import icon from '../../static/img/swap.svg'; + +export function SwapLocationsButton({ + tripQueryVariables, + setTripQueryVariables, +}: { + tripQueryVariables: TripQueryVariables; + setTripQueryVariables: (tripQueryVariables: TripQueryVariables) => void; +}) { + const swapFromTo = () => { + setTripQueryVariables({ + ...tripQueryVariables, + from: tripQueryVariables.to, + to: tripQueryVariables.from, + }); + }; + + return ( + + ); +} diff --git a/client/src/components/SearchBar/TimeInputField.tsx b/client/src/components/SearchBar/TimeInputField.tsx deleted file mode 100644 index 71bb7325340..00000000000 --- a/client/src/components/SearchBar/TimeInputField.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { Form } from 'react-bootstrap'; -import { TripQueryVariables } from '../../gql/graphql.ts'; -import { ChangeEvent, useCallback, useMemo } from 'react'; - -export function TimeInputField({ - tripQueryVariables, - setTripQueryVariables, -}: { - tripQueryVariables: TripQueryVariables; - setTripQueryVariables: (tripQueryVariables: TripQueryVariables) => void; -}) { - const current = useMemo( - () => new Date(tripQueryVariables.dateTime).toTimeString().split(' ')[0], - [tripQueryVariables.dateTime], - ); - - const onChange = useCallback( - (event: ChangeEvent) => { - const timeComponents = event.target.value.split(':'); - const newDate = new Date(tripQueryVariables.dateTime); - newDate.setHours(Number(timeComponents[0]), Number(timeComponents[1]), Number(timeComponents[2])); - - setTripQueryVariables({ - ...tripQueryVariables, - dateTime: newDate.toISOString(), - }); - }, - [tripQueryVariables, setTripQueryVariables], - ); - - return ( - - - Time - - - - ); -} diff --git a/client/src/components/SearchBar/WheelchairAccessibleCheckBox.tsx b/client/src/components/SearchBar/WheelchairAccessibleCheckBox.tsx new file mode 100644 index 00000000000..b677e19049f --- /dev/null +++ b/client/src/components/SearchBar/WheelchairAccessibleCheckBox.tsx @@ -0,0 +1,35 @@ +import { Form } from 'react-bootstrap'; +import wheelchairIcon from '../../static/img/wheelchair.svg'; +import { TripQueryVariables } from '../../gql/graphql.ts'; + +export default function WheelchairAccessibleCheckBox({ + tripQueryVariables, + setTripQueryVariables, +}: { + tripQueryVariables: TripQueryVariables; + setTripQueryVariables: (tripQueryVariables: TripQueryVariables) => void; +}) { + return ( + + + Wheelchair Accessible Trip + + { + setTripQueryVariables({ + ...tripQueryVariables, + wheelchairAccessible: e.target.checked, + }); + }} + > + + ); +} diff --git a/client/src/hooks/TimeZoneContext.ts b/client/src/hooks/TimeZoneContext.ts new file mode 100644 index 00000000000..6a40921ebae --- /dev/null +++ b/client/src/hooks/TimeZoneContext.ts @@ -0,0 +1,3 @@ +import { createContext } from 'react'; + +export const TimeZoneContext = createContext('UTC'); diff --git a/client/src/hooks/useQuayCoordinateQuery.ts b/client/src/hooks/useQuayCoordinateQuery.ts new file mode 100644 index 00000000000..6d4655a6838 --- /dev/null +++ b/client/src/hooks/useQuayCoordinateQuery.ts @@ -0,0 +1,36 @@ +import { useEffect, useState } from 'react'; +import { request } from 'graphql-request'; +import { Location, QueryType } from '../gql/graphql.ts'; +import { getApiUrl } from '../util/getApiUrl.ts'; +import { graphql } from '../gql'; + +const query = graphql(` + query quayCoordinate($id: String!) { + quay(id: $id) { + latitude + longitude + } + } +`); + +export const useQuayCoordinateQuery = (location: Location) => { + const [data, setData] = useState(null); + + useEffect(() => { + const fetchData = async () => { + if (location.place) { + const variables = { id: location.place }; + try { + setData((await request(getApiUrl(), query, variables)) as QueryType); + } catch (e) { + console.error('Error at useQuayCoordinateQuery', e); + } + } else { + setData(null); + } + }; + fetchData(); + }, [location]); + + return data?.quay; +}; diff --git a/client/src/hooks/useServerInfo.ts b/client/src/hooks/useServerInfo.ts index 23ee23fc283..30107f336a5 100644 --- a/client/src/hooks/useServerInfo.ts +++ b/client/src/hooks/useServerInfo.ts @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; import { graphql } from '../gql'; -import { request } from 'graphql-request'; // eslint-disable-line import/no-unresolved +import { request } from 'graphql-request'; import { QueryType } from '../gql/graphql.ts'; import { getApiUrl } from '../util/getApiUrl.ts'; @@ -13,6 +13,7 @@ const query = graphql(` routerConfigVersion gitCommit gitBranch + internalTransitModelTimeZone } } `); diff --git a/client/src/hooks/useTripQuery.ts b/client/src/hooks/useTripQuery.ts index 5ff6fc80a1f..f1f8c859bd0 100644 --- a/client/src/hooks/useTripQuery.ts +++ b/client/src/hooks/useTripQuery.ts @@ -1,6 +1,6 @@ import { useCallback, useEffect, useState } from 'react'; -import { request } from 'graphql-request'; // eslint-disable-line import/no-unresolved -import { QueryType, TripQueryVariables } from '../gql/graphql.ts'; +import { request } from 'graphql-request'; +import { Location, QueryType, TripQueryVariables } from '../gql/graphql.ts'; import { getApiUrl } from '../util/getApiUrl.ts'; import { query } from '../static/query/tripQuery.tsx'; @@ -22,10 +22,14 @@ export const useTripQuery: TripQueryHook = (variables) => { } else { if (variables) { setLoading(true); - if (pageCursor) { - setData((await request(getApiUrl(), query, { ...variables, pageCursor })) as QueryType); - } else { - setData((await request(getApiUrl(), query, variables)) as QueryType); + try { + if (pageCursor) { + setData((await request(getApiUrl(), query, { ...variables, pageCursor })) as QueryType); + } else { + setData((await request(getApiUrl(), query, variables)) as QueryType); + } + } catch (e) { + console.error('Error at useTripQuery', e); } setLoading(false); } else { @@ -37,10 +41,14 @@ export const useTripQuery: TripQueryHook = (variables) => { ); useEffect(() => { - if (variables?.from.coordinates && variables?.to.coordinates) { + if (validLocation(variables?.from) && validLocation(variables?.to)) { callback(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [variables?.from, variables?.to]); return [data, loading, callback]; }; + +function validLocation(location: Location | undefined) { + return location && (location.coordinates || location.place); +} diff --git a/client/src/screens/App.tsx b/client/src/screens/App.tsx index 3e5744e5ad6..1b6b86b7a81 100644 --- a/client/src/screens/App.tsx +++ b/client/src/screens/App.tsx @@ -6,39 +6,43 @@ import { useState } from 'react'; import { useTripQuery } from '../hooks/useTripQuery.ts'; import { useServerInfo } from '../hooks/useServerInfo.ts'; import { useTripQueryVariables } from '../hooks/useTripQueryVariables.ts'; +import { TimeZoneContext } from '../hooks/TimeZoneContext.ts'; export function App() { + const serverInfo = useServerInfo(); const { tripQueryVariables, setTripQueryVariables } = useTripQueryVariables(); const [tripQueryResult, loading, callback] = useTripQuery(tripQueryVariables); - const serverInfo = useServerInfo(); const [selectedTripPatternIndex, setSelectedTripPatternIndex] = useState(0); + const timeZone = serverInfo?.internalTransitModelTimeZone || Intl.DateTimeFormat().resolvedOptions().timeZone; return (
    - - - - - + - + + + + + +
    ); } diff --git a/client/src/static/img/graphql-solid.svg b/client/src/static/img/graphql-solid.svg new file mode 100644 index 00000000000..32d6e5e0f00 --- /dev/null +++ b/client/src/static/img/graphql-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/client/src/static/img/graphql.svg b/client/src/static/img/graphql.svg new file mode 100644 index 00000000000..ef85915ffaa --- /dev/null +++ b/client/src/static/img/graphql.svg @@ -0,0 +1,4 @@ + + + + diff --git a/client/src/static/img/swap.svg b/client/src/static/img/swap.svg new file mode 100644 index 00000000000..858e5e99831 --- /dev/null +++ b/client/src/static/img/swap.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/client/src/static/img/wheelchair.svg b/client/src/static/img/wheelchair.svg new file mode 100644 index 00000000000..d8cf96ca995 --- /dev/null +++ b/client/src/static/img/wheelchair.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/client/src/static/query/tripQuery.tsx b/client/src/static/query/tripQuery.tsx index ccb19dc745e..57cca5d4056 100644 --- a/client/src/static/query/tripQuery.tsx +++ b/client/src/static/query/tripQuery.tsx @@ -11,6 +11,7 @@ export const query = graphql(` $searchWindow: Int $modes: Modes $itineraryFiltersDebug: ItineraryFilterDebugProfile + $wheelchairAccessible: Boolean $pageCursor: String ) { trip( @@ -22,6 +23,7 @@ export const query = graphql(` searchWindow: $searchWindow modes: $modes itineraryFilters: { debug: $itineraryFiltersDebug } + wheelchairAccessible: $wheelchairAccessible pageCursor: $pageCursor ) { previousPageCursor @@ -64,6 +66,9 @@ export const query = graphql(` publicCode name id + presentation { + colour + } } authority { name diff --git a/client/src/style.css b/client/src/style.css index 1a24ac2c072..f838dce2c7b 100644 --- a/client/src/style.css +++ b/client/src/style.css @@ -7,7 +7,7 @@ margin-right: 14px; } -@media (min-width: 2160px) { +@media (min-width: 1895px) { .top-content { height: 75px; } @@ -17,7 +17,7 @@ } } -@media (max-width: 2159px) { +@media (max-width: 1896px) { .top-content { height: 150px; } @@ -50,16 +50,44 @@ margin-right: 1rem; } +.search-bar input.input-small { + max-width: 100px; +} + +.search-bar input.input-medium { + max-width: 130px; +} + .search-bar-route-button-wrapper { height: 5rem; padding-top: 25px; } +.search-bar-route-button-wrapper a.btn img { + margin-top: -2px; +} + +.search-bar .swap-from-to { + border: none; + background: none; + margin: 30px 0 auto 0; +} + +.search-bar .swap-from-to img { + width: 15px; +} + .itinerary-list-container { width: 36rem; overflow-y: auto; } +.itinerary-list-container .time-zone-info { + margin: 10px 20px; + font-size: 12px; + text-align: right; +} + .itinerary-header-wrapper { position: relative; background: #0a53be; @@ -152,3 +180,24 @@ .maplibregl-ctrl-group.layer-select label { margin-left: 6px; } + +.maplibregl-ctrl-group.layer-select select { + margin-bottom: 14px; +} + +.maplibregl-ctrl-group.layer-select h4 { + font-size: 17px; +} + +.maplibregl-ctrl-group.layer-select .group-label { + font-size: 15px; + margin-bottom: 5px; +} + +.maplibregl-ctrl-group.layer-select div.group { + margin-top: 10px; +} + +.maplibregl-ctrl-group.layer-select div.layer { + margin-left: 17px; +} diff --git a/client/src/util/formatTime.ts b/client/src/util/formatTime.ts index 1849640fe3f..1818ced5cd1 100644 --- a/client/src/util/formatTime.ts +++ b/client/src/util/formatTime.ts @@ -4,10 +4,11 @@ * If style argument is provided formatted with ('medium') or without ('short') seconds, * otherwise seconds are shown if not 0. */ -export function formatTime(dateTime: string, style?: 'short' | 'medium') { +export function formatTime(dateTime: string, timeZone: string, style?: 'short' | 'medium') { const parsed = new Date(dateTime); return parsed.toLocaleTimeString('en-US', { timeStyle: style ? style : parsed.getSeconds() === 0 ? 'short' : 'medium', hourCycle: 'h24', + timeZone: timeZone, }); } diff --git a/client/src/util/getColorForMode.ts b/client/src/util/getColorForLeg.ts similarity index 60% rename from client/src/util/getColorForMode.ts rename to client/src/util/getColorForLeg.ts index cb1ad8b6981..64b5fc7776f 100644 --- a/client/src/util/getColorForMode.ts +++ b/client/src/util/getColorForLeg.ts @@ -1,6 +1,6 @@ -import { Mode } from '../gql/graphql.ts'; +import { Leg, Mode } from '../gql/graphql.ts'; -export const getColorForMode = function (mode: Mode) { +const getColorForMode = function (mode: Mode) { if (mode === Mode.Foot) return '#191616'; if (mode === Mode.Bicycle) return '#5076D9'; if (mode === Mode.Scooter) return '#253664'; @@ -8,7 +8,7 @@ export const getColorForMode = function (mode: Mode) { if (mode === Mode.Rail) return '#86BF8B'; if (mode === Mode.Coach) return '#25642A'; if (mode === Mode.Metro) return '#D9B250'; - if (mode === Mode.Bus) return '#25642A'; + if (mode === Mode.Bus) return '#fe0000'; if (mode === Mode.Tram) return '#D9B250'; if (mode === Mode.Trolleybus) return '#25642A'; if (mode === Mode.Water) return '#81304C'; @@ -19,3 +19,14 @@ export const getColorForMode = function (mode: Mode) { if (mode === Mode.Taxi) return '#81304C'; return '#aaa'; }; + +/** + * Extract a line color from a leg. If there isn't one given by its line, this method returns a fallback color. + */ +export const getColorForLeg = function (leg: Leg) { + if (leg.line?.presentation?.colour) { + return `#${leg.line.presentation.colour}`; + } else { + return getColorForMode(leg.mode); + } +}; diff --git a/client/src/util/locationConverter.ts b/client/src/util/locationConverter.ts new file mode 100644 index 00000000000..952a36a1dc4 --- /dev/null +++ b/client/src/util/locationConverter.ts @@ -0,0 +1,37 @@ +import { COORDINATE_PRECISION } from '../components/SearchBar/constants.ts'; +import { Location } from '../gql/graphql.ts'; + +const DOUBLE_PATTERN = '-{0,1}\\d+(\\.\\d+){0,1}'; + +const LAT_LON_PATTERN = '(' + DOUBLE_PATTERN + ')(\\s+)(' + DOUBLE_PATTERN + ')'; + +export function parseLocation(value: string): Location | null { + const latLonMatch = value.match(LAT_LON_PATTERN); + + if (latLonMatch) { + return { + coordinates: { + latitude: +latLonMatch[1], + longitude: +latLonMatch[4], + }, + }; + } + + return { + place: value, + }; +} + +export function toString(location: Location): string | null { + if (location.coordinates) { + return `${location.coordinates?.latitude.toPrecision( + COORDINATE_PRECISION, + )} ${location.coordinates?.longitude.toPrecision(COORDINATE_PRECISION)}`; + } + + if (location.place) { + return location.place; + } + + return null; +} diff --git a/doc/dev/decisionrecords/AnalysesAndDesign.md b/doc/dev/decisionrecords/AnalysesAndDesign.md new file mode 100644 index 00000000000..b6c585ba71f --- /dev/null +++ b/doc/dev/decisionrecords/AnalysesAndDesign.md @@ -0,0 +1,54 @@ +# Analysis and design + +We want to get better at design, so we want some documentation up front for large changes. If a +problem is complex, changes the core OTP model, and/or the API significantly, then the developer +requesting a change should be prepared to provide some design documentation. + +The analysis should be started and at least mapped out in an issue. The design can be documented +in the issue or the PR. + + +## Analysis & Design + +A discussion in a developer meeting is usually a good point to start. + +- Ask what is expected? +- Diagrams beat words in most cases, and help focus on the problem - not implementation details. + + +### Artifacts + +We usually do not require a long list of requirements and analyses documentation. But these +artifacts may help, but none of these are required. Ask in the developer meeting what to expect. + + - [ ] Summarise the discussion in the developer meeting in the issue or PR. + - [ ] List use-cases, one sentence per use-case is often enough. + - [ ] In/out matrix, list features you are NOT planning to implement. + - [ ] Draw diagrams + - [ ] **Domain model** — If the core model or APIs are significantly changed + - [ ] State diagram + - [ ] Collaboration diagram + +We recommend using [draw.io](https://www.drawio.com/). It is free and available as an Intellij +plugin (Diagrams.net), web application and desktop application. + + +## Domain model + +A domain model focusses on the language and the relationships. All implementation details can be left +out. Details which is not relevant for the problem you are solving can also be left out, focus on +the elements witch helps understand the problem. Use plain english and not tech to describe +the model. For example, only listing the field name, and not the type is ok if the type is obvious. + +Notation is not important, but try to follow the UML syntax below. You may use more advanced UML +syntax if you want, but keep in mind that you should be able to use the diagram to discuss the +problem with a non-developer. A product-owner or other person who knows the domain should with +a little help be able to understand the main parts of the drawing. + +When doing review, focus on the domain problem, not syntax — ask about things you do not understand. + + +### Domain model - notation cheat sheet + +![Domain Model Notation](../images/DomainModelNotation.svg) + diff --git a/doc/dev/decisionrecords/Codestyle.md b/doc/dev/decisionrecords/Codestyle.md index f9ffc1a9056..22f57eacbda 100644 --- a/doc/dev/decisionrecords/Codestyle.md +++ b/doc/dev/decisionrecords/Codestyle.md @@ -1,96 +1,96 @@ -# Codestyle +# Code Style We use the following code conventions for [Java](#Java) and [JavaScript](#JavaScript). ## Java The OpenTripPlanner Java code style is revised in OTP v2.2. We use the -[Prettier Java](https://github.com/jhipster/prettier-java) as is. Maven is setup to +[Prettier Java](https://github.com/jhipster/prettier-java) as is. Maven is set up to run `prettier-maven-plugin`. A check is run in the CI build, which fails the build preventing -merging a PR if the code-style is incorrect. +merging a PR if the code style is incorrect. -There is two ways to format the code before checkin it in. You may run a normal build with maven - -it takes a bit of time, but reformat the entire codebase. Only code you have changed should be -formatted, since the existing code is already formatted. The second way is to set up prettier and -run it manually or hick it into your IDE, so it runs every time a file is changed. +There are two ways to format the code before checking it in. You may run a normal build with +Maven; it takes a bit of time, but it reformats the entire codebase. Only code you have changed +should be formatted, since the existing code is already formatted. The second way is to set up +Prettier and run it manually or hick it into your IDE, so it runs every time a file is changed. -### How to run Prettier with Maven +### How to Run Prettier with Maven -Prettier will automatically format all code in the Maven "validate" phase, which runs before the test, package, and install phases. So formatting will happen for example when you run: +Prettier will automatically format all code in the Maven "validate" phase, which runs before the +test, package, and install phases. So formatting will happen for example when you run: -``` +```shell % mvn test ``` You can manually run _only_ the formatting process with: -``` +```shell % mvn prettier:write - ``` -To skip the prettier formating use profile `prettierSkip`: +To skip the Prettier formating, use the profile `prettierSkip`: -``` +```shell % mvn test -P prettierSkip ``` -The check for formatting errors use profile `prettierCheck`: +To check for formatting errors, use the profile `prettierCheck`: -``` +```shell % mvn test -P prettierCheck ``` The check is run by the CI server and will fail the build if the code is incorrectly formatted. -### IntellJ and Code Style Formatting +### IntelliJ and Code Style Formatting -You should use the prettier Maven plugin to reformat the code or run prettier with Node(faster). +You should use the Prettier Maven plugin to reformat the code or run Prettier with Node (faster). -The prettier does NOT format the doc and markdown files, only Java code. So, for other files you should -use the _project_ code-style. It is automatically imported when you first open the project. But, if -you have set a custom code-style in your settings (as we used until OTP v2.1), then you need to -change to the _Project_ Code Style. Open the `Preferences` from the menu and select _ -Editor > Code Style_. Then select **Project** in the \_Scheme drop down. +Prettier does _not_ format the doc and Markdown files, only Java code. So, for other files you +should use the _project_ code style. It is automatically imported when you first open the project. +But, if you have set a custom code style in your settings (as we used until OTP v2.1), then you need +to change to the _Project_ code style. Open the `Preferences` from the menu and select _Editor > +Code Style_. Then select **Project** in the \_Scheme drop down. -#### Run Prettier Maven Plugin as an external tool in IntelliJ +#### Run Prettier Maven Plugin as an External Tool in IntelliJ You can run the Prettier Maven plugin as an external tool in IntelliJ. Set it up as an -`External tool` and assign a key-shortcut to the tool execution. +`External tool` and assign a keyboard shortcut to the tool execution. ![External Tool Dialog](../images/ExternalToolDialog.png) -``` +```text Name: Prettier Format Current File Program: mvn Arguments: prettier:write -Dprettier.inputGlobs=$FilePathRelativeToProjectRoot$ Working Directory: $ProjectFileDir$ ``` -> **Tip!** Add a unused key shortcut to execute the external tool, then you can use the old -> short-cut to format other file types. - +> **Tip!** Add an unused key shortcut to execute the external tool. Then you can use the old +> shortcut to format other file types. #### Install File Watchers Plugin in IntelliJ -You can also configure IntelliJ to run the prettier every time IntelliJ save a Java file. But, -if you are editing the file at the same time you will get a warning that the file in memory and the -file on disk both changed - and asked to select one of them. +You can also configure IntelliJ to run Prettier every time IntelliJ saves a Java file. But if you +are editing the file at the same time, you will get a warning that the file in memory and the file +on disk both changed, and asked to select one of them. -1. In the menyopen _Prefernces..._ and select _Plugins_. -2. Search for "File Watchers" in Marketplace -3. Run _Install_ +1. In the menu, open _Preferences..._ and select _Plugins_. +2. Search for "File Watchers" in the Marketplace. +3. Run _Install_. -##### Configure File Watcher +##### Configure File Watchers -You can run Prettier on every file save in Intellij using the File Watcher plugin. There is several -ways to set it up. Below is hwo to configure it using Maven to run the formatter. The Maven way work -without any installation of other components, but might be a bit slow. So, you might want to install -[prettier-java](https://github.com/jhipster/prettier-java/) in your shell and run it instead. +You can run Prettier upon every file save in IntelliJ using the File Watchers plugin. There are +several ways to set it up. Below is how to configure it using Maven to run the formatter. The Maven +way works without any installation of other components but might be a bit slow. So you might want to +install [prettier-java](https://github.com/jhipster/prettier-java/) in your shell and run it +instead. -``` +```text Name: Format files with Prettier -File type: Java +File Type: Java Scope: Project Files Program: mvn Arguments: prettier:write -Dprettier.inputGlobs=$FilePathRelativeToProjectRoot$ @@ -99,74 +99,86 @@ Working Directory: $ProjectFileDir$ ### Other IDEs -We do not have support for other IDEs at the moment. If you use another editor and make one please +We do not have support for other IDEs at the moment. If you use another editor and make one, please feel free to share it. ### Sorting Class Members -Some of the classes in OTP have a lot of fields and methods. Keeping members sorted reduce the merge +Some of the classes in OTP have a lot of fields and methods. Keeping members sorted reduces merge conflicts. Adding fields and methods to the end of the list will cause merge conflicts more often than inserting methods and fields in an ordered list. Fields and methods can be sorted in "feature" sections or alphabetically, but stick to it and respect it when adding new methods and fields. The provided formatter will group class members in this order: -1. Getter and Setter methods are kept together -2. Overridden methods are kept together -3. Dependent methods are sorted in a breadth-first order. +1. Getter and setter methods are kept together. +2. Overridden methods are kept together. +3. Dependent methods are sorted in breadth-first order. 4. Members are sorted like this: - 1. `static` `final` fields - 2. `static` fields - 3. `static` initializer - 4. `final` fields - 5. fields - 6. class initializer (avoid using it) - 7. Constructor - 8. `static` methods - 9. `static` getter and setters - 10. methods - 11. getter and setters - 12. enums - 13. interfaces - 14. `static` classes - 15. classes -5. Each section of members are sorted by visibility: - 1. ´public´ - 2. package private - 3. ´protected´ - 4. ´private´ - -### JavaDoc Guidlines - -What to put in Javadoc: + 1. `static final` fields (constants) + 2. `static` fields (avoid) + 3. Instance fields + 4. Static initializers + 5. Class initializers + 6. Constructors + 7. `static` factory methods + 8. `public` methods + 9. Getter and setters + 10. `private`/package methods + 11. `private` enums (avoid `public`) + 12. Interfaces + 13. `private static` classes (avoid `public`) + 14. Instance classes (avoid) + +### Javadoc Guidelines + +As a matter of [policy](http://github.com/opentripplanner/OpenTripPlanner/issues/93), all new +methods, classes, and fields should include comments explaining what they are for and any other +pertinent information. For Java code, the comments should follow industry standards. It is best to +provide comments that explain not only *what* you did but also *why you did it* while providing some +context. Please avoid including trivial Javadoc or the empty Javadoc stubs added by IDEs, such as +`@param` annotations with no description. - On methods: - Side effects on instance state (is it a pure function) - Contract of the method - Input domain for which the logic is designed - Range of outputs produced from valid inputs - - Is behavior undefined or will fail when conditions are not met - - Are null values allowed as inputs - - Will null values occur as outputs (what do they mean) + - Is behavior undefined or will the method fail when conditions are not met? + - Are null values allowed as inputs? + - Will null values occur as outputs (and what do they mean)? - Invariants that hold if the preconditions are met - Concurrency - - Is method thread-safe + - Is the method thread-safe? - Usage constraints for multi-threaded use - On classes: - Initialization and teardown process - - Can instance be reused for multiple operations, or should it be discarded - - Is it immutable or should anything be treated as immutable - - Is it a utility class of static methods that should not be instantiated + - Can an instance be reused for multiple operations, or should it be discarded? + - Is it immutable, or should anything be treated as immutable? + - Is it a utility class of static methods that should not be instantiated? + +### Annotations + +- On methods: + - Method should be marked as `@Nullable` if they can return null values. + - Method parameters should be marked as `@Nullable` if they can take null values. +- On fields: + - Fields should be marked as `@Nullable` if they are nullable. + +Use of `@Nonnull` annotation is not allowed. It should be assumed methods/parameters/fields are +non-null if they are not marked as `@Nullable`. However, there are places where the `@Nullable` +annotation is missing even if it should have been used. Those can be updated to use the `@Nullable` +annotation. ## JavaScript -As of #206, we -follow [Crockford's JavaScript code conventions](http://javascript.crockford.com/code.html). Further +As of [#206](https://github.com/opentripplanner/OpenTripPlanner/issues/206), we follow +[Crockford's JavaScript code conventions](http://javascript.crockford.com/code.html). Further guidelines include: * All .js source files should contain one class only -* Capitalize the class name, as well as the source file name (a la Java) -* Include the namespace definition in each and every file: `otp.namespace("otp.configure");` +* Capitalize the class name, as well as the source file name (a la Java). +* Include the namespace definition in each and every file: `otp.namespace("otp.configure");`. * Include a class comment. For example, ```javascript @@ -175,8 +187,8 @@ guidelines include: * * Purpose is to allow a generic configuration object to be read via AJAX/JSON, and inserted into an * Ext Store - * The implementation is TriMet route map specific...but replacing ConfigureStore object (or member - * variables) with another implementation, will give this widget flexibility for other uses beyond + * The implementation is TriMet route map-specific...but replacing ConfigureStore object (or member + * variables) with another implementation will give this widget flexibility for other uses beyond * the iMap. * * @class diff --git a/doc/dev/decisionrecords/NamingConventions.md b/doc/dev/decisionrecords/NamingConventions.md index ed6175f4f4c..2cd4ed6d0cf 100644 --- a/doc/dev/decisionrecords/NamingConventions.md +++ b/doc/dev/decisionrecords/NamingConventions.md @@ -1,77 +1,90 @@ # Naming Conventions -In general, we use American English. We use the GTFS terminology inside OTP as the transit domain -specific language. In cases where GTFS does not provide an alternative we use NeTEx. The naming -should follow the Java standard naming conventions. For example a "real-time updater" class -is named `RealTimeUpdater`. If in doubt check the Oxford Dictionary(American). - +In general, we use American English. We use the GTFS terminology inside OTP as the transit +domain-specific language. In cases where GTFS does not provide an alternative, we use NeTEx. The +naming should follow the Java standard naming conventions. For example, a "real-time updater" class +is named `RealTimeUpdater`. If in doubt, check the Oxford Dictionary (American). ## Packages Try to arrange code by domain functionality, not technology. The main structure of a package should be `org.opentripplanner...`. -| Package | Description | -| ------------------------------- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `o.o.` | At the top level we should divide OTP into "domain"s like `apis`, `framework`, `transit`, `street`, `astar`, `raptor`, `feeds`, `updaters`, and `application`. | -| `component` and `sub-component` | A group of packages/classes which naturally belong together, think aggregate as in Domain Driven Design. | -| `component.api` | Used for components to define the programing interface for the component. If present, (see Raptor) all outside dependencies to the component should be through the `api`. | -| `component.model` | Used to create a model of a Entites, ValueObjects, ++. If exposed outside the component you should include an entry point like `xyz.model.XyzModel` and/or a Service (in api or component root package). | -| `component.service` | Implementation of the service like `DefaultTransitService`, may also contain use-case specific code. Note, the Service interface goes into the component root or `api`, not in the service package. | -| `component.configure` | Component creation/orchestration. Put Dependency Injection code here, like the Dagger Module. | -| `support` | Sometimes domain logic get complicated, then extracting/isolating it helps. `support` is used internally in a component, not outside. | -| `framework` | (Abstract) building blocks internal to a domain/parent package. In some cases accessed outside the component, e.g. `OptAppException`, `TransitEntity`. | -| `mapping` | Map between two domains/components. | -| `util` | General "util" functionality, often characterized by `static` methods. Dependencies to other OTP packages is NOT allowed, only 3rd party utils libs. | -| `o.o.apis` | OTP external endpoints. Note! Many apis are in the Sandbox where they are in the `o.o.ext` package. | - -> **Note!** The above is the goal, the current package structure needs cleanup. - -> **Note!** Util methods depending on an OTP type/component should go into that type/component, not in the -utils class. E.g. static factory methods. Warning the "pure" utilities right now are placed into -sub-packages of `o.o.util`, the root package needs cleanup. - +| Package | Description | +| ------------------------------- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `o.o.` | At the top level, we should divide OTP into "domains" like `apis`, `framework`, `transit`, `street`, `astar`, `raptor`, `feeds`, `updaters`, and `application`. | +| `component` and `sub-component` | A group of packages/classes that naturally belong together; think aggregate as in Domain-Driven Design. | +| `component.api` | Used for components to define the programing interface for the component. If present, (see Raptor) all outside dependencies to the component should be through the `api`. | +| `component.model` | Used to create a model of Entities, ValueObjects, etc. If exposed outside the component, you should include an entry point like `xyz.model.XyzModel` and/or a Service (in `api` or component root package). | +| `component.service` | Implementation of a service like `DefaultTransitService`; may also contain use case-specific code. Note: The Service interface goes into the component root or `api`, not in the service package. | +| `component.configure` | Component creation/orchestration. Put dependency injection code here, like the Dagger module. | +| `support` | Sometimes domain logic gets complicated; then extracting/isolating it helps. `support` is used internally in a component, not outside. | +| `framework` | (Abstract) building blocks internal to a domain/parent package. In some cases accessed outside the component; e.g., `OptAppException`, `TransitEntity`. | +| `mapping` | Map between two domains/components. | +| `util` | General "util" functionality, often characterized by `static` methods. Dependencies to other OTP packages are NOT allowed; only third-party utils libraries. | +| `o.o.apis` | OTP external endpoints. Note! Many APIs are in the Sandbox where they are in the `o.o.ext` package. | + +> **Note!** The above is the goal. The current package structure needs cleanup. + +> **Note!** Util methods depending on an OTP type/component should go into that type/component, not +> in the utils class; e.g., static factory methods. Warning: The "pure" utilities right now are +> placed into subpackages of `o.o.util`. The root package needs cleanup. ## Methods -Here are a list of common prefixes used, and what to expect. - -| Good method prefixes | Description | -|-------------------------------------------------------|-----------------------------------------------------------------------------| -| `stop() : Stop` | Field accessor, equivalent to `getStop` as in the Java Bean standard | -| `getStop(ID id) : Stop` | Get Stop by ID, throws exception if not found | -| `getStops(Collection id) : List/Collection` | Get ALL Stops by set of IDs, throws exception if not found | -| `findStop(Criteria criteria) : Optional` | Find one or zero stops, return `Optional` | -| `findStops(Criteria criteria) : List/Stream` | Find 0, 1 or many stops, return a collection or stream(List is preferred) | -| `listStops() : List/Stream` | List ALL stops in context, return a collection or stream(List is preferred) | -| `withStop(Stop stop) : Builder` | Set stop in builder, replacing existing value and return `this` builder | -| `initStop(Stop stop) : void` | Set property ONCE, a second call throws an exception | -| `addStop(Stop stop) : void/Builder` | Add a stop to a collection of stops. | -| `addStops(Collection stops) : void/Builder` | Add set of stops to existing set. | -| `withBike(Consumer body) : Builder` | For nested builders use lambdas. | - -These prefixes are also "allowed", but not preferred - they have some kind of negative "force" to them. - -| Ok method prefixes, but ... | Description | -| ------------------------------------------- | ----------------------------------------------------------------------------------------------------- | -| `withStops(Collection stops) : this`) | Replace all stops in builder with new set, consider using `addStops(...)` instead | -| `setStop(Stop stop)` | Set a mutable stop reference. Avoid if not part of natural lifecycle. Use `initStop(...)` if possible | -| `getStop() : Stop` | Old style accessor, use the shorter form `stop() : Stop` | +Here is a list of common prefixes used and what to expect. + +| Good method prefixes | Description | +|-------------------------------------------------------|-------------------------------------------------------------------------------| +| `stop() : Stop` | Field accessor, equivalent to `getStop` as in the Java Bean standard. | +| `getStop(ID id) : Stop` | Get Stop by ID; throws exception if not found. | +| `getStops(Collection id) : List/Collection` | Get _all_ Stops by set of IDs; throws exception if not found. | +| `findStop(Criteria criteria) : Optional` | Find one or zero stops; return `Optional`. | +| `findStops(Criteria criteria) : List/Stream` | Find 0, 1, or many stops; return a Collection or Stream (List is preferred). | +| `listStops() : List/Stream` | List ALL stops in context; return a Collection or Stream (List is preferred). | +| `initStop(Stop stop) : void` | Set property _once_; a second call throws an exception. | +| `createStop(String name, ...) : Stop` | Factory methods for creating objects should start with `create` prefix. | +| | See (Builder Conventions)[RecordsPOJOsBuilders.md#builder-conventions] for creating objects with builders. | +| `addStop(Stop stop) : void/Builder` | Add a Stop to a collection of Stops. | +| `addStops(Collection stops) : void/Builder` | Add set of Stops to existing set. | +| `withBike(Consumer body) : Builder` | For nested builders, use lambdas. | +| `withStop(Stop stop) : Builder` | Set Stop in builder, replacing existing value; return `this` builder. | +| `of(FeedScopedId id) : Builder` | Create new builder instance from `Stop` class. | +| `copyOf() : Builder` | Initialize a new builder instance from `Stop` instance with identical values. | +| `build() : Stop` | Finish building stop with a builder. | + +These prefixes are also "allowed" but not preferred; they have some kind of negative "force" to +them. + +| Okay method prefixes, but ... | Description | +|---------------------------------------------|--------------------------------------------------------------------------------------------------------| +| `withStops(Collection stops) : this`) | Replace all Stops in builder with new set. Consider using `addStops(...)` instead. | +| `setStop(Stop stop)` | Set a mutable Stop reference. Avoid if not part of natural lifecycle. Use `initStop(...)` if possible. | +| `getStop() : Stop` | Old style accessor. Use the shorter form `stop() : Stop`. | ## Service, Model and Repository ![MainModelOverview](../images/ServiceModelOverview.png) - - Naming convention for builders with and without a context. -#### Graph Build and tests run without a context +#### Graph Builds and Tests Run Without a Context -```Java +```java // Create a new Stop trip = Trip.of(id).withName("The Express").build(); // Modify and existing stop stop = stop.copyOf().withPrivateCode("TEX").build(); ``` + +## Referencing Established OTP Terminology in Documentation + +Use emphasis ("_dated service journey_") in markdown documentation, in API, and configuration +documentation. In this kind of documentation we usually talk about the concept, not the implementing +class. Use CamleCase (eg. TripOnServiceDate) if you need to reference the class. + +Use hyphen ("dated-service-journey") in plain text and JavaDoc. In JavaDoc we also use +{@link TripOnServiceDate} the first time we mention a class. Note that sometimes we want to talk +about the concept (dated-service-journey) and sometimes we reference a class +({@link DatedServiceJourney}). \ No newline at end of file diff --git a/doc/dev/decisionrecords/RecordsPOJOsBuilders.md b/doc/dev/decisionrecords/RecordsPOJOsBuilders.md index e0752fc70b0..d34fd3ab6b7 100644 --- a/doc/dev/decisionrecords/RecordsPOJOsBuilders.md +++ b/doc/dev/decisionrecords/RecordsPOJOsBuilders.md @@ -1,8 +1,8 @@ ## Records, POJOs and Builders -We prefer immutable typesafe types over flexibility and "short" class definitions. This makes -the code more robust and less error-prone. References to other entities might need to be mutable, -if so try to init them once, and throw an exception if set again. Example: +We prefer immutable typesafe types over flexibility and "short" class definitions. This makes the +code more robust and less error-prone. References to other entities might need to be mutable; if so, +try to init them once and throw an exception if set again. Example: ```java Builder initStop(Stop stop) { @@ -10,37 +10,46 @@ Builder initStop(Stop stop) { } ``` - ### Records -You may use records, but avoid using records if you cannot encapsulate them properly. Generally, records are considered appropriate and useful for throw-away compound types private to an implementation, such as hash table keys or compound values in a temporary list or set. On the other hand, records are generally not appropriate in the domain model where we insist on full encapsulation, which records cannot readily provide. Be especially -aware of array fields (which can not be protected) and collections (remember to make a defensive copy). Consider overriding `toString`. But if you need to override `equals` and `hashCode`, then it is probably not worth using a record. The implicit `equals()` and `hashCode()` implementations for records behave as if they call `equals` and `hashCode` on each field of the record, so their behavior will depend heavily on the types of these fields. +You may use records, but avoid using records if you cannot encapsulate them properly. Generally, +records are considered appropriate and useful for throwaway compound types private to an +implementation, such as hash table keys or compound values in a temporary list or set. On the other +hand, records are generally not appropriate in the domain model where we insist on full +encapsulation, which records cannot readily provide. Be especially aware of array fields (which +cannot be protected) and collections (remember to make a defensive copy). Consider overriding +`toString`. But if you need to override `equals` and `hashCode`, then it is probably not worth using +a record. The implicit `equals` and `hashCode` implementations for records behave as if they call +`equals` and `hashCode` on each field of the record, so their behavior will depend heavily on the +types of these fields. ### Builders OTP used a simple builder pattern in many places, especially when creating immutable types. -#### Builder conventions -- Use factory methods to create builder, either `of()` or `copyOf()`. The _copyOf_ uses an existing - instance as its base. The `of()` creates a builder with all default values set. All constructors - should be private (or package local) to enforce the use of the factory methods. -- If the class has more than 5 fields, then avoid using an inner class builder, instead create a +#### Builder Conventions + +- Use factory methods to create builder—either `of` or `copyOf`. The `copyOf` uses an existing + instance as its base. The `of` creates a builder with all default values set. All constructors + should be private (or package-local) to enforce use of the factory methods. +- If the class has more than 5 fields, then avoid using an inner class builder. Instead, create a builder in the same package. - Make all fields in the main class final to enforce immutability. - Consider using utility methods for parameter checking, like `Objects#requireNonNull` and - `ObjectUtils.ifNotNull`. -- Validate all fields in the main type constructor(i.e. not in the builder), especially null checks. - Prefer default values over null-checks. All business logic using the type can rely on its validity. + `ObjectUtils#ifNotNull`. +- Validate all fields in the main type constructor (i.e., not in the builder), especially null + checks. Prefer default values over null checks. All business logic using the type can rely on its + validity. - You may keep the original instance in the builder to avoid creating a new object if nothing - changed. This prevents polluting the heap for long-lived objects and make comparison very fast. -- There is no need to provide all get accessors in the Builder if not needed. + changed. This prevents polluting the heap for long-lived objects and makes comparison very fast. +- There is no need to provide all get accessors in the builder if not needed. - Unit-test builders and verify all fields are copied over. -- For nested builders see the field `nested` in the example. +- For nested builders, see the field `nested` in the example.
    - Builder example + Builder Example -```Java +```java /** * THIS CLASS IS IMMUTABLE AND THREAD-SAFE */ diff --git a/doc/dev/decisionrecords/UseDecisionRecords.md b/doc/dev/decisionrecords/UseDecisionRecords.md index a3520ea5133..0cdca42e16d 100644 --- a/doc/dev/decisionrecords/UseDecisionRecords.md +++ b/doc/dev/decisionrecords/UseDecisionRecords.md @@ -1,37 +1,36 @@ # Decision Records -An OTP Decision Record is a justified software design choice that addresses a significant -functional or non-functional requirement. [Architectural Decision Records](https://adr.github.io/) is a similar -concept, but we have widened the scope to include any relevant decision about OTP development. - +An OTP Decision Record is a justified software design choice that addresses a significant +functional or non-functional requirement. [Architectural Decision Records](https://adr.github.io/) +is a similar concept, but we have widened the scope to include any relevant decision about OTP +development. ## Process Decisions we make in the developer meetings are recorded in the [Developer Decision Records](/DEVELOPMENT_DECISION_RECORDS.md) -list. If the decision is small and uncontroversial, but yet important and can be expressed in +list. If the decision is small and uncontroversial, yet is important and can be expressed in maximum 2 sentences, we will list it here without any more documentation. If the decision requires -a bit more discussion and explanations, then we will create a PR with a document for it. - -Use the **[template](/doc/dev/decisionrecords/_TEMPLATE.md) as a starting point for documenting -the decision. +a bit more discussion and explanation, then we will create a PR with a document for it. +Use the [template](/doc/dev/decisionrecords/_TEMPLATE.md) as a starting point for documenting the +decision. -### How to discuss and document a Decision Record +### How to Discuss and Document a Decision Record -- Create a new pull-request and describe the decision record by adding a document to the +- Create a new pull request and describe the decision record by adding a document to the `/doc/dev/decisionrecords` folder. Use the [template](/doc/dev/decisionrecords/_TEMPLATE.md). - template. -- Present the decision record in a developer meeting. Make sure to update the main description - based on the feedback/discussion and decisions in the developer meeting. -- The final approval is done in the developer meeting, at least 3 developers representing 3 +- Present the decision record in a developer meeting. Make sure to update the main description based + on the feedback/discussion and decisions in the developer meeting. +- The final approval is done in the developer meeting. At least 3 developers representing 3 different organisations should approve it. No vote against the proposal. If the developers are not able to agree, the PLC can decide. - References to Development Decision Records in reviews can be done by linking or just typing. - For example `Use-Dependency-Injection` or [Use-Dependency-Injection](../../../DEVELOPMENT_DECISION_RECORDS.md#use-dependency-injection) + For example, `Use-Dependency-Injection` or [Use-Dependency-Injection](../../../DEVELOPMENT_DECISION_RECORDS.md#use-dependency-injection). ### Checklist + - [ ] Give it a meaningful title that quickly lets the reader understand what it is all about. - [ ] Get it approved in a developer meeting with 3 votes in favor (3 organisations). -- [ ] Add the name and description to the list in the [Development Decision Records](../../../DEVELOPMENT_DECISION_RECORDS.md) list. - Maximum two sentences should be used. Try to keep it as short as possible. +- [ ] Add the name and description to the list in the [Development Decision Records](../../../DEVELOPMENT_DECISION_RECORDS.md) + list. Maximum two sentences should be used. Try to keep it as short as possible. - [ ] Remember to link to the PR. diff --git a/doc/dev/decisionrecords/_TEMPLATE.md b/doc/dev/decisionrecords/_TEMPLATE.md index e184bdc6aaa..7ac4a960126 100644 --- a/doc/dev/decisionrecords/_TEMPLATE.md +++ b/doc/dev/decisionrecords/_TEMPLATE.md @@ -2,30 +2,29 @@ {DESCRIPTION} - ### Context and Problem Statement ### Other options - - +- -### Decision & Consequences +### Decision and Consequences #### Positive Consequences - - +- #### Negative Consequences - - +- diff --git a/doc/dev/images/DomainModelNotation.svg b/doc/dev/images/DomainModelNotation.svg new file mode 100644 index 00000000000..836363f4372 --- /dev/null +++ b/doc/dev/images/DomainModelNotation.svg @@ -0,0 +1,4 @@ + + + +ServicecanceledTrips(...) : TripOnDateEntityfield : basic type / scalarA<<interface>>Baseid : IDEvent/Moment/IntervalValueObjectvalue : String
    Colors
    Colors
    Types
    Types
    objectName : Type/Class<<interface>>Interface/abstract class
    Relationship
    Relation...
    Afield : basic type / scalarB
    b
    b
    ?
    ?
    AB
    b
    b
    B
    Inheritance
    Inherita...
    << use >>
    << use >>
    AB
    Dependency
    Dependen...
    [ Bike only ]
    [ Bike only ]
    Amode : Mode[ GTFS only ]B
    Constraint
    Constrai...
    • We usually provide a class name only, but you can provide an object name and/or class. 
    • If something is an abstract class or an interface is a implementation detail. Use the <<interface>>` qualifier to tag interfaces.
    We usually provide a class name only, but you can...
    • Relationship can be one way (arrow) or both-ways (no arrows).
    • Naming the relationship is optional.
    • Default cardinality is 1. Other values:
      • ? - optional
      • * - many
      • 2 - exact two
      • 3..n - three or more
    • A simple relationship is included as a field. A good indication when to use a field and not an arrow is when the type is a basic type(int, float, boolean, String), enumeration or ValueObject. PS! It is not wrong to use either, both forms are equivalent
    Relationship can be one way (arrow) or both-ways (...
    2..n
    2..n
    *
    *
    AB
    a
    a
    b
    b
    • If you are in doubt model things as relationships, do not use inheritance.
    • Interfaces exist:
      • if there is a reference to it - the named interface play a role.
      • if at least one shared operation/field/relationship exist.  
    If you are in doubt model things as relationships,...
    • We draw dependencies when they are important and not part of a relationship. For example if we want to map out the details of a ValueObject.
    • The qualifier text << use >> is optonal.
    We draw dependencies when they are important and n...
    • Use "[]" to add a constraint.
    • A constraint can be added to all arrows and types.
    • Be careful with constraints, they add a lot of noice to the diagram. It is sometimes better to just list tem in text.
    Use "[]" to add a constraint.A constraint can be a...
    A has a field b of type B.
    A has a field b of type B.
    A has a 2 or more b's of type B. B has many a's of type A.
    A has a 2 or more b's of type B. B has many a's of type...
    We use color for classify the a type by its life-cycle. A service is request or application scoped, an entity is sable - but may change, a ValueObject do not change, and a Event are temporary. A ValueObject can not reference a Entity, an Entity can not reference a Service and always pay close attention to the design of Events - they are hard to model.  
    We use color for classify the a type by its life-cycle. A service is request or application scoped, an entity is sable - but may c...
    A has a relationship b, if mode is Bike.
    B only exist for GTFS imported elements.
    A has a relationship b, if mode is Bike....
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/doc/dev/onboarding-checklist.md b/doc/dev/onboarding-checklist.md new file mode 100644 index 00000000000..4e39e887175 --- /dev/null +++ b/doc/dev/onboarding-checklist.md @@ -0,0 +1,23 @@ +# Onboarding Checklist + +* What is OTP? + * [Website](https://www.opentripplanner.org/) + * History + * [Timeline](https://github.com/opentripplanner/OpenTripPlanner/graphs/contributors) +* Community + * Dev meetings + * Gitter + * Issues/PRs + * Calendar +* OTP modules + * [Diagram](https://github.com/opentripplanner/OpenTripPlanner/issues/6155) +* Data standards + * Transit + * Map/Street network + * Rental + * Parking + * Elevation +* Transit model +* Street model +* How to run OTP +* Coding conventions diff --git a/doc/templates/BuildConfiguration.md b/doc/templates/BuildConfiguration.md index 7e768e30eb1..3d1cd5a1db3 100644 --- a/doc/templates/BuildConfiguration.md +++ b/doc/templates/BuildConfiguration.md @@ -2,7 +2,7 @@ NOTE! Part of this document is generated. Make sure you edit the template, not the generated doc. - Template directory is: /doc/templates - - Generated directory is: /docs + - Generated directory is: /doc/user --> # Graph Build Configuration @@ -163,7 +163,7 @@ OTP allows you to adjust the elevation values reported in API responses in two w is to store ellipsoid (GPS) elevation values internally, but apply a single geoid difference value in the OTP client where appropriate to display elevations above sea level. This ellipsoid to geoid difference is returned in each trip plan response in the -[ElevationMetadata](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/api/resource/ElevationMetadata.java) +[ElevationMetadata](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/application/src/ext/java/org/opentripplanner/ext/restapi/model/ElevationMetadata.java) field. Using a single value can be sufficient for smaller OTP deployments, but might result in incorrect values at the edges of larger OTP deployments. If your OTP instance uses this, it is recommended to set a default request value in the `router-config.json` file as follows: diff --git a/doc/templates/Configuration.md b/doc/templates/Configuration.md index 0ef96b8d4fa..39843b57077 100644 --- a/doc/templates/Configuration.md +++ b/doc/templates/Configuration.md @@ -2,7 +2,7 @@ NOTE! Part of this document is generated. Make sure you edit the template, not the generated doc. - Template directory is: /doc/templates - - Generated directory is: /docs + - Generated directory is: /doc/user --> # Configuring OpenTripPlanner @@ -41,9 +41,9 @@ default behavior of scanning the base directory for input files. Scanning is ove independently for each file type, and can point to remote cloud storage with arbitrary URIs. See [the storage section](Configuration.md#Storage) for further details. -## Three Scopes of Configuration +## Four scopes of configuration -OTP is configured via three configuration JSON files which are read from the directory specified on +OTP is configured via four configuration JSON files which are read from the directory specified on its command line. We try to provide sensible defaults for every option, so all three of these files are optional, as are all the options within each file. Each configuration file corresponds to options that are relevant at a particular phase of OTP usage. @@ -51,7 +51,8 @@ options that are relevant at a particular phase of OTP usage. Options and parameters that are taken into account during the graph building process will be "baked into" the graph, and cannot be changed later in a running server. These are specified in `build-config.json`. Other details of OTP operation can be modified without rebuilding the graph. -These run-time configuration options are found in `router-config.json`. Finally, `otp-config.json` +These run-time configuration options are found in `router-config.json`. If you want to configure +the built-in debug UI add `debug-ui-config.json`. Finally, `otp-config.json` contains simple switches that enable or disable system-wide features. ## Configuration types @@ -146,7 +147,7 @@ text inserted is valid JSON (starts with `{` and ends with `}`). Variable substitution is performed on configuration file after the include file directive; Hence variable substitution is also performed on the text in the injected file. -Here is an example including variable substitution, assuming version 2.5.0 of OTP: +Here is an example including variable substitution, assuming version 2.6.0 of OTP: ```JSON // build-config.json @@ -170,7 +171,7 @@ The result will look like this: { "transitFeeds": [ { - "source": "netex-v2.5.0.obj" + "source": "netex-v2.6.0.obj" } ] } diff --git a/doc/templates/DebugUiConfiguration.md b/doc/templates/DebugUiConfiguration.md new file mode 100644 index 00000000000..a54b1db8d2a --- /dev/null +++ b/doc/templates/DebugUiConfiguration.md @@ -0,0 +1,23 @@ + + +# Debug UI configuration + +The Debug UI is the standard interface that is bundled with OTP and available by visiting +[`http://localhost:8080`](http://localhost:8080). This page list the configuration options available +by placing a file `debug-ui-config.json` into OTP's working directory. + + + + +## Parameter Details + + + +## Config Example + + diff --git a/doc/templates/GraphQL-Tutorial.md b/doc/templates/GraphQL-Tutorial.md index 11a2e304119..b3a59b7d19e 100644 --- a/doc/templates/GraphQL-Tutorial.md +++ b/doc/templates/GraphQL-Tutorial.md @@ -2,7 +2,7 @@ NOTE! Part of this document is generated. Make sure you edit the template, not the generated doc. - Template directory is: /doc/templates - - Generated directory is: /docs + - Generated directory is: /doc/user --> # GraphQL tutorial @@ -51,4 +51,4 @@ Most people want to get routing results out of OTP, so lets see the query for th Again, please use the autocomplete and documentation viewers to figure out what each input parameter and property means. -More examples for a variety of queries can also be found [in the test code](https://github.com/opentripplanner/OpenTripPlanner/tree/dev-2.x/src/test/resources/org/opentripplanner/apis/gtfs/queries). \ No newline at end of file +More examples for a variety of queries can also be found [in the test code](https://github.com/opentripplanner/OpenTripPlanner/tree/dev-2.x/application/src/test/resources/org/opentripplanner/apis/gtfs/queries). \ No newline at end of file diff --git a/doc/templates/Netex-Tutorial.md b/doc/templates/Netex-Tutorial.md new file mode 100644 index 00000000000..2afa997ee73 --- /dev/null +++ b/doc/templates/Netex-Tutorial.md @@ -0,0 +1,80 @@ +# NeTEx & SIRI tutorial + +One important new feature of OTP2 is the ability to +load [NeTEx](https://en.wikipedia.org/wiki/NeTEx) and [SIRI](https://en.wikipedia.org/wiki/Service_Interface_for_Real_Time_Information) +data. NeTEx is a European [specification for transit data exchange](http://netex-cen.eu), comparable in purpose to +GTFS but broader in scope. + +First of all, you need to download a [bundled jar of OTP](Getting-OTP.md). + +Secondly, you will use the [Norwegian NeTEx file](https://developer.entur.org/pages-intro-files) as +well as the [Norwegian OSM data](http://download.geofabrik.de/europe/norway.html), but OTP can download the NeTEx one for you. + +## Configuring the build + +Create a working directory and place the OTP jar file in it and call it `otp.jar.` + +Since we download the OSM data from a free source, we don't want to put undue stress on the server. +Therefore we download it before building the graph, not during. + +``` +curl https://download.geofabrik.de/europe/norway-latest.osm.pbf -o norway.osm.pbf +``` + +Now create a file called `build-config.json` in the same folder and fill it with the following +content: + + + +Note the special section specifying how to find NeTEx XML files within the single ZIP archive that +OTP downloads. + +Now you can instruct OTP to build a graph from this configuration file: + +`java -Xmx16G -jar otp.jar --build --save .` + +This should produce a file `graph.obj` in the same directory as your `build-config.json`. + +Building the Norway graph requires downloading about 250MB of input data so stay patient at the beginning +particularly on a slow internet connection. +The actual build takes approximately 10 minutes (without elevation data, as is configured above), +and can be done within 16GB of heap memory (JVM switch `-Xmx16G`). The Graph file it produces is +about 1.1 GB. The server will take about 30 seconds to load this graph and start up, and will +consume about 6GB of heap memory under light use. + +You can then start up an OTP server with a command like this: + +`java -Xmx6G -jar otp.jar --load .` + +Once the server is started up, go to `http://localhost:8080` in a browser to try out your server +using OTP's built in testing web client. Try some long trips like Oslo to Bergen and see if you can +get long distance trains and flights as alternatives. You might need to increase the walking limit +above its very low default value. + +## Adding SIRI real time Data + +Another important feature in OTP version 2 is the ability to +use [SIRI real-time data](https://en.wikipedia.org/wiki/Service_Interface_for_Real_Time_Information). +Within the EU data standards, SIRI is analogous to GTFS-RT: a way to apply real-time updates on top +of schedule data. While technically a distinct specification from NeTEx, both NeTEx and SIRI use the +Transmodel vocabulary, allowing SIRI messages to reference entities in NeTEx schedule data. Like +GTFS-RT, SIRI is consumed by OTP2 using "graph updaters" which are configured in +the `router-config.json` file, which is placed in the same directory as the `graph.obj` file and +loaded at server startup. + + + +After saving the file in the working directory, restart OTP. + +The updaters fetch two different kinds of SIRI data: + +- Situation Exchange (SX, text notices analogous to GTFS-RT Alerts) +- Estimated Timetable (ET, predicted arrival times analogous to GTFS-RT TripUpdates) + +These updaters can handle differential updates, but they use a polling approach rather than the +message-oriented streaming approach of the GTFS-RT Websocket updater. The server keeps track of +clients, sending only the things that have changed since the last polling operation. + +Note that between these SIRI updaters and the GTFS-RT Websocket updater, we now have both polling +and streaming examples of GTFS-RT "incrementality" semantics, so should be able to finalize that +part of the specification. \ No newline at end of file diff --git a/doc/templates/RouteRequest.md b/doc/templates/RouteRequest.md index a452e1d1480..9b7cd6fd58f 100644 --- a/doc/templates/RouteRequest.md +++ b/doc/templates/RouteRequest.md @@ -2,7 +2,7 @@ NOTE! Part of this document is generated. Make sure you edit the template, not the generated doc. - Template directory is: /doc/templates - - Generated directory is: /docs + - Generated directory is: /doc/user --> # Route Request diff --git a/doc/templates/RouterConfiguration.md b/doc/templates/RouterConfiguration.md index b6c6ccf9c4b..42a78cc41ca 100644 --- a/doc/templates/RouterConfiguration.md +++ b/doc/templates/RouterConfiguration.md @@ -2,7 +2,7 @@ NOTE! Part of this document is generated. Make sure you edit the template, not the generated doc. - Template directory is: /doc/templates - - Generated directory is: /docs + - Generated directory is: /doc/user --> # Router configuration @@ -14,7 +14,7 @@ These options can be applied by the OTP server without rebuilding the graph. Certain settings can be provided on the command line, when starting OpenTripPlanner. See the `CommandLineParameters` class -for [a full list of arguments](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/standalone/config/CommandLineParameters.java) +for [a full list of arguments](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/application/src/main/java/org/opentripplanner/standalone/config/CommandLineParameters.java) . ## Routing defaults diff --git a/doc/templates/StopConsolidation.md b/doc/templates/StopConsolidation.md index 6817ee47d4c..70866882bd1 100644 --- a/doc/templates/StopConsolidation.md +++ b/doc/templates/StopConsolidation.md @@ -2,7 +2,7 @@ NOTE! Part of this document is generated. Make sure you edit the template, not the generated doc. - Template directory is: /doc/templates - - Generated directory is: /docs + - Generated directory is: /doc/user --> # Stop consolidation diff --git a/doc/templates/UpdaterConfig.md b/doc/templates/UpdaterConfig.md index 440cd96f733..aab5631e6e2 100644 --- a/doc/templates/UpdaterConfig.md +++ b/doc/templates/UpdaterConfig.md @@ -2,7 +2,7 @@ NOTE! Part of this document is generated. Make sure you edit the template, not the generated doc. - Template directory is: /doc/templates - - Generated directory is: /docs + - Generated directory is: /doc/user --> diff --git a/doc/templates/VehicleParking.md b/doc/templates/VehicleParking.md index 721cbc2657a..0eb561248a1 100644 --- a/doc/templates/VehicleParking.md +++ b/doc/templates/VehicleParking.md @@ -3,7 +3,7 @@ ## Contact Info - For HSL Park and Ride updater: Digitransit team, HSL, Helsinki, Finland -- For Bikely, NOI and Bikeep updater: Leonard Ehrenfried, [mail@leonard.io](mailto:mail@leonard.io) +- For Bikely, Bikeep and SIRI-FM updater: Leonard Ehrenfried, [mail@leonard.io](mailto:mail@leonard.io) ## Documentation @@ -16,7 +16,7 @@ Currently contains the following updaters: - [HSL Park and Ride](https://p.hsl.fi/docs/index.html) - [ParkAPI](https://github.com/offenesdresden/ParkAPI) - [Bikely](https://www.safebikely.com/) -- [NOI Open Data Hub](https://opendatahub.com/) +- SIRI-FM ### Configuration @@ -40,10 +40,6 @@ All updaters have the following parameters in common: -## NOI Open Data Hub - - - ## Bikeep diff --git a/doc/user/Basic-Tutorial.md b/doc/user/Basic-Tutorial.md index d6e46f3f1f5..64eeded6b01 100644 --- a/doc/user/Basic-Tutorial.md +++ b/doc/user/Basic-Tutorial.md @@ -18,9 +18,9 @@ JAR containing all other libraries needed for OTP to work, and is available from repository. You will be able to go to [the OTP directory at Maven Central](https://repo1.maven.org/maven2/org/opentripplanner/otp/), navigate to -the [directory of releases](https://repo1.maven.org/maven2/org/opentripplanner/otp/2.5.0/), +the [directory of releases](https://repo1.maven.org/maven2/org/opentripplanner/otp/2.6.0/), and download -the [file with `shaded.jar` suffix](https://repo1.maven.org/maven2/org/opentripplanner/otp/2.5.0/otp-2.5.0-shaded.jar) +the [file with `shaded.jar` suffix](https://repo1.maven.org/maven2/org/opentripplanner/otp/2.6.0/otp-2.6.0-shaded.jar) . You may also want to get your own copy of the OTP source code @@ -129,7 +129,7 @@ below and in other tutorials. The simplest way to use OTP is to build a graph in a single step and start a server immediately, without saving it to disk. The command to do so is: - $ java -Xmx2G -jar otp-2.5.0-shaded.jar --build --serve /home/username/otp + $ java -Xmx2G -jar otp-2.6.0-shaded.jar --build --serve /home/username/otp where `/home/username/otp` should be the directory where you put your configuration and input files. @@ -154,13 +154,13 @@ build a graph from street and transit data then save it to a file using the `--b command line parameters together. If for example your current working directory (`.`) contains the input files and the OTP JAR file, you can use this command: - $ java -Xmx2G -jar otp-2.5.0-shaded.jar --build --save . + $ java -Xmx2G -jar otp-2.6.0-shaded.jar --build --save . This will produce a file called `graph.obj` in the same directory as the inputs. The server can then be started later using the `--load` parameter, and will read this file instead of building the graph from scratch: - $ java -Xmx2G -jar otp-2.5.0-shaded.jar --load . + $ java -Xmx2G -jar otp-2.6.0-shaded.jar --load . Another reason to perform these two phases separately is that the building process loads the entire GTFS and OSM data sets into memory, so can require significantly more memory than just running a @@ -177,16 +177,16 @@ graph once, and then layer transit data on top of the streets to make the final Again assuming the input files and OTP JAR file are in the current working directory, you can build a street graph with OSM and elevation data only (ignoring transit input files) with this command: - $ java -Xmx2G -jar otp-2.5.0-shaded.jar --buildStreet . + $ java -Xmx2G -jar otp-2.6.0-shaded.jar --buildStreet . Then, to build a graph layering transit data on top of the saved street graph (built using the previous command): - $ java -Xmx2G -jar otp-2.5.0-shaded.jar --loadStreet --save . + $ java -Xmx2G -jar otp-2.6.0-shaded.jar --loadStreet --save . Finally, the server can be started using the `--load` parameter: - $ java -Xmx2G -jar otp-2.5.0-shaded.jar --load . + $ java -Xmx2G -jar otp-2.6.0-shaded.jar --load . ## Command Line Switches diff --git a/doc/user/BuildConfiguration.md b/doc/user/BuildConfiguration.md index b311991120e..99e98066e73 100644 --- a/doc/user/BuildConfiguration.md +++ b/doc/user/BuildConfiguration.md @@ -2,7 +2,7 @@ NOTE! Part of this document is generated. Make sure you edit the template, not the generated doc. - Template directory is: /doc/templates - - Generated directory is: /docs + - Generated directory is: /doc/user --> # Graph Build Configuration @@ -17,102 +17,103 @@ Sections follow that describe particular settings in more depth. -| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | -|--------------------------------------------------------------------------|:-----------:|----------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------:|-----------------------------------|:-----:| -| [areaVisibility](#areaVisibility) | `boolean` | Perform visibility calculations. | *Optional* | `false` | 1.5 | -| [buildReportDir](#buildReportDir) | `uri` | URI to the directory where the graph build report should be written to. | *Optional* | | 2.0 | -| [configVersion](#configVersion) | `string` | Deployment version of the *build-config.json*. | *Optional* | | 2.1 | -| [dataImportReport](#dataImportReport) | `boolean` | Generate nice HTML report of Graph errors/warnings | *Optional* | `false` | 2.0 | -| [distanceBetweenElevationSamples](#distanceBetweenElevationSamples) | `double` | The distance between elevation samples in meters. | *Optional* | `10.0` | 2.0 | -| embedRouterConfig | `boolean` | Embed the Router config in the graph, which allows it to be sent to a server fully configured over the wire. | *Optional* | `true` | 2.0 | -| [graph](#graph) | `uri` | URI to the graph object file for reading and writing. | *Optional* | | 2.0 | -| [gsCredentials](#gsCredentials) | `string` | Local file system path to Google Cloud Platform service accounts credentials file. | *Optional* | | 2.0 | -| [includeEllipsoidToGeoidDifference](#includeEllipsoidToGeoidDifference) | `boolean` | Include the Ellipsoid to Geoid difference in the calculations of every point along every StreetWithElevationEdge. | *Optional* | `false` | 2.0 | -| maxAreaNodes | `integer` | Visibility calculations for an area will not be done if there are more nodes than this limit. | *Optional* | `150` | 2.1 | -| [maxDataImportIssuesPerFile](#maxDataImportIssuesPerFile) | `integer` | When to split the import report. | *Optional* | `1000` | 2.0 | -| maxElevationPropagationMeters | `integer` | The maximum distance to propagate elevation to vertices which have no elevation. | *Optional* | `2000` | 1.5 | -| [maxStopToShapeSnapDistance](#maxStopToShapeSnapDistance) | `double` | Maximum distance between route shapes and their stops. | *Optional* | `150.0` | 2.1 | -| maxTransferDuration | `duration` | Transfers up to this duration with the default walk speed value will be pre-calculated and included in the Graph. | *Optional* | `"PT30M"` | 2.1 | -| [multiThreadElevationCalculations](#multiThreadElevationCalculations) | `boolean` | Configuring multi-threading during elevation calculations. | *Optional* | `false` | 2.0 | -| [osmCacheDataInMem](#osmCacheDataInMem) | `boolean` | If OSM data should be cached in memory during processing. | *Optional* | `false` | 2.0 | -| [osmNaming](#osmNaming) | `enum` | A custom OSM namer to use. | *Optional* | `"default"` | 1.5 | -| platformEntriesLinking | `boolean` | Link unconnected entries to public transport platforms. | *Optional* | `false` | 2.0 | -| [readCachedElevations](#readCachedElevations) | `boolean` | Whether to read cached elevation data. | *Optional* | `true` | 2.0 | -| staticBikeParkAndRide | `boolean` | Whether we should create bike P+R stations from OSM data. | *Optional* | `false` | 1.5 | -| staticParkAndRide | `boolean` | Whether we should create car P+R stations from OSM data. | *Optional* | `true` | 1.5 | -| stopConsolidationFile | `uri` | Name of the CSV-formatted file in the build directory which contains the configuration for stop consolidation. | *Optional* | | 2.5 | -| [streetGraph](#streetGraph) | `uri` | URI to the street graph object file for reading and writing. | *Optional* | | 2.0 | -| [subwayAccessTime](#subwayAccessTime) | `double` | Minutes necessary to reach stops served by trips on routes of route_type=1 (subway) from the street. | *Optional* | `2.0` | 1.5 | -| [transitModelTimeZone](#transitModelTimeZone) | `time-zone` | Time zone for the graph. | *Optional* | | 2.2 | -| [transitServiceEnd](#transitServiceEnd) | `duration` | Limit the import of transit services to the given end date. | *Optional* | `"P3Y"` | 2.0 | -| [transitServiceStart](#transitServiceStart) | `duration` | Limit the import of transit services to the given START date. | *Optional* | `"-P1Y"` | 2.0 | -| [writeCachedElevations](#writeCachedElevations) | `boolean` | Reusing elevation data from previous builds | *Optional* | `false` | 2.0 | -| [boardingLocationTags](#boardingLocationTags) | `string[]` | What OSM tags should be looked on for the source of matching stops to platforms and stops. | *Optional* | | 2.2 | -| [dataOverlay](sandbox/DataOverlay.md) | `object` | Config for the DataOverlay Sandbox module | *Optional* | | 2.2 | -| [dem](#dem) | `object[]` | Specify parameters for DEM extracts. | *Optional* | | 2.2 | -|       [elevationUnitMultiplier](#dem_0_elevationUnitMultiplier) | `double` | Specify a multiplier to convert elevation units from source to meters. Overrides the value specified in `demDefaults`. | *Optional* | `1.0` | 2.3 | -|       source | `uri` | The unique URI pointing to the data file. | *Required* | | 2.2 | -| demDefaults | `object` | Default properties for DEM extracts. | *Optional* | | 2.3 | -|    [elevationUnitMultiplier](#demDefaults_elevationUnitMultiplier) | `double` | Specify a multiplier to convert elevation units from source to meters. | *Optional* | `1.0` | 2.3 | -| [elevationBucket](#elevationBucket) | `object` | Used to download NED elevation tiles from the given AWS S3 bucket. | *Optional* | | na | -| [emissions](sandbox/Emissions.md) | `object` | Emissions configuration. | *Optional* | | 2.5 | -| [fares](sandbox/Fares.md) | `object` | Fare configuration. | *Optional* | | 2.0 | -| gtfsDefaults | `object` | The gtfsDefaults section allows you to specify default properties for GTFS files. | *Optional* | | 2.3 | -|    blockBasedInterlining | `boolean` | Whether to create stay-seated transfers in between two trips with the same block id. | *Optional* | `true` | 2.3 | -|    [discardMinTransferTimes](#gd_discardMinTransferTimes) | `boolean` | Should minimum transfer times in GTFS files be discarded. | *Optional* | `false` | 2.3 | -|    maxInterlineDistance | `integer` | Maximal distance between stops in meters that will connect consecutive trips that are made with same vehicle. | *Optional* | `200` | 2.3 | -|    removeRepeatedStops | `boolean` | Should consecutive identical stops be merged into one stop time entry. | *Optional* | `true` | 2.3 | -|    [stationTransferPreference](#gd_stationTransferPreference) | `enum` | Should there be some preference or aversion for transfers at stops that are part of a station. | *Optional* | `"allowed"` | 2.3 | -| islandPruning | `object` | Settings for fixing street graph connectivity errors | *Optional* | | 2.3 | -|    [adaptivePruningDistance](#islandPruning_adaptivePruningDistance) | `integer` | Search distance for analyzing islands in pruning. | *Optional* | `250` | 2.3 | -|    [adaptivePruningFactor](#islandPruning_adaptivePruningFactor) | `double` | Defines how much pruning thresholds grow maximally by distance. | *Optional* | `50.0` | 2.3 | -|    [islandWithStopsMaxSize](#islandPruning_islandWithStopsMaxSize) | `integer` | When a graph island with stops in it should be pruned. | *Optional* | `2` | 2.3 | -|    [islandWithoutStopsMaxSize](#islandPruning_islandWithoutStopsMaxSize) | `integer` | When a graph island without stops should be pruned. | *Optional* | `10` | 2.3 | -| [localFileNamePatterns](#localFileNamePatterns) | `object` | Patterns for matching OTP file types in the base directory | *Optional* | | 2.0 | -|    [dem](#lfp_dem) | `regexp` | Pattern for matching elevation DEM files. | *Optional* | `"(?i)\.tiff?$"` | 2.0 | -|    [gtfs](#lfp_gtfs) | `regexp` | Patterns for matching GTFS zip-files or directories. | *Optional* | `"(?i)gtfs"` | 2.0 | -|    [netex](#lfp_netex) | `regexp` | Patterns for matching NeTEx zip files or directories. | *Optional* | `"(?i)netex"` | 2.0 | -|    [osm](#lfp_osm) | `regexp` | Pattern for matching Open Street Map input files. | *Optional* | `"(?i)(\.pbf¦\.osm¦\.osm\.xml)$"` | 2.0 | -| netexDefaults | `object` | The netexDefaults section allows you to specify default properties for NeTEx files. | *Optional* | | 2.2 | -|    feedId | `string` | This field is used to identify the specific NeTEx feed. It is used instead of the feed_id field in GTFS file feed_info.txt. | *Optional* | `"NETEX"` | 2.2 | -|    [groupFilePattern](#nd_groupFilePattern) | `regexp` | Pattern for matching group NeTEx files. | *Optional* | `"(\w{3})-.*\.xml"` | 2.0 | -|    ignoreFareFrame | `boolean` | Ignore contents of the FareFrame | *Optional* | `false` | 2.3 | -|    [ignoreFilePattern](#nd_ignoreFilePattern) | `regexp` | Pattern for matching ignored files in a NeTEx bundle. | *Optional* | `"$^"` | 2.0 | -|    ignoreParking | `boolean` | Ignore Parking elements. | *Optional* | `true` | 2.6 | -|    noTransfersOnIsolatedStops | `boolean` | Whether we should allow transfers to and from StopPlaces marked with LimitedUse.ISOLATED | *Optional* | `false` | 2.2 | -|    [sharedFilePattern](#nd_sharedFilePattern) | `regexp` | Pattern for matching shared NeTEx files in a NeTEx bundle. | *Optional* | `"shared-data\.xml"` | 2.0 | -|    [sharedGroupFilePattern](#nd_sharedGroupFilePattern) | `regexp` | Pattern for matching shared group NeTEx files in a NeTEx bundle. | *Optional* | `"(\w{3})-.*-shared\.xml"` | 2.0 | -|    [ferryIdsNotAllowedForBicycle](#nd_ferryIdsNotAllowedForBicycle) | `string[]` | List ferries which do not allow bikes. | *Optional* | | 2.0 | -| [osm](#osm) | `object[]` | Configure properties for a given OpenStreetMap feed. | *Optional* | | 2.2 | -|       [osmTagMapping](#osm_0_osmTagMapping) | `enum` | The named set of mapping rules applied when parsing OSM tags. Overrides the value specified in `osmDefaults`. | *Optional* | `"default"` | 2.2 | -|       source | `uri` | The unique URI pointing to the data file. | *Required* | | 2.2 | -|       timeZone | `time-zone` | The timezone used to resolve opening hours in OSM data. Overrides the value specified in `osmDefaults`. | *Optional* | | 2.2 | -| osmDefaults | `object` | Default properties for OpenStreetMap feeds. | *Optional* | | 2.2 | -|    [osmTagMapping](#od_osmTagMapping) | `enum` | The named set of mapping rules applied when parsing OSM tags. | *Optional* | `"default"` | 2.2 | -|    timeZone | `time-zone` | The timezone used to resolve opening hours in OSM data. | *Optional* | | 2.2 | -| [transferRequests](RouteRequest.md) | `object[]` | Routing requests to use for pre-calculating stop-to-stop transfers. | *Optional* | | 2.1 | -| [transitFeeds](#transitFeeds) | `object[]` | Scan for transit data files | *Optional* | | 2.2 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.2 | -|       type = "gtfs" | `enum` | The feed input format. | *Required* | | 2.2 | -|       blockBasedInterlining | `boolean` | Whether to create stay-seated transfers in between two trips with the same block id. Overrides the value specified in `gtfsDefaults`. | *Optional* | `true` | 2.3 | -|       [discardMinTransferTimes](#tf_0_discardMinTransferTimes) | `boolean` | Should minimum transfer times in GTFS files be discarded. Overrides the value specified in `gtfsDefaults`. | *Optional* | `false` | 2.3 | -|       feedId | `string` | The unique ID for this feed. This overrides any feed ID defined within the feed itself. | *Optional* | | 2.2 | -|       maxInterlineDistance | `integer` | Maximal distance between stops in meters that will connect consecutive trips that are made with same vehicle. Overrides the value specified in `gtfsDefaults`. | *Optional* | `200` | 2.3 | -|       removeRepeatedStops | `boolean` | Should consecutive identical stops be merged into one stop time entry. Overrides the value specified in `gtfsDefaults`. | *Optional* | `true` | 2.3 | -|       source | `uri` | The unique URI pointing to the data file. | *Required* | | 2.2 | -|       [stationTransferPreference](#tf_0_stationTransferPreference) | `enum` | Should there be some preference or aversion for transfers at stops that are part of a station. Overrides the value specified in `gtfsDefaults`. | *Optional* | `"allowed"` | 2.3 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.2 | -|       type = "netex" | `enum` | The feed input format. | *Required* | | 2.2 | -|       feedId | `string` | This field is used to identify the specific NeTEx feed. It is used instead of the feed_id field in GTFS file feed_info.txt. | *Required* | | 2.2 | -|       [groupFilePattern](#tf_1_groupFilePattern) | `regexp` | Pattern for matching group NeTEx files. | *Optional* | `"(\w{3})-.*\.xml"` | 2.0 | -|       ignoreFareFrame | `boolean` | Ignore contents of the FareFrame | *Optional* | `false` | 2.3 | -|       [ignoreFilePattern](#tf_1_ignoreFilePattern) | `regexp` | Pattern for matching ignored files in a NeTEx bundle. | *Optional* | `"$^"` | 2.0 | -|       ignoreParking | `boolean` | Ignore Parking elements. | *Optional* | `true` | 2.6 | -|       noTransfersOnIsolatedStops | `boolean` | Whether we should allow transfers to and from StopPlaces marked with LimitedUse.ISOLATED | *Optional* | `false` | 2.2 | -|       [sharedFilePattern](#tf_1_sharedFilePattern) | `regexp` | Pattern for matching shared NeTEx files in a NeTEx bundle. | *Optional* | `"shared-data\.xml"` | 2.0 | -|       [sharedGroupFilePattern](#tf_1_sharedGroupFilePattern) | `regexp` | Pattern for matching shared group NeTEx files in a NeTEx bundle. | *Optional* | `"(\w{3})-.*-shared\.xml"` | 2.0 | -|       source | `uri` | The unique URI pointing to the data file. | *Required* | | 2.2 | -|       [ferryIdsNotAllowedForBicycle](#tf_1_ferryIdsNotAllowedForBicycle) | `string[]` | List ferries which do not allow bikes. | *Optional* | | 2.0 | +| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | +|--------------------------------------------------------------------------|:------------------:|----------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------:|-----------------------------------|:-----:| +| [areaVisibility](#areaVisibility) | `boolean` | Perform visibility calculations. | *Optional* | `false` | 1.5 | +| [buildReportDir](#buildReportDir) | `uri` | URI to the directory where the graph build report should be written to. | *Optional* | | 2.0 | +| [configVersion](#configVersion) | `string` | Deployment version of the *build-config.json*. | *Optional* | | 2.1 | +| [dataImportReport](#dataImportReport) | `boolean` | Generate nice HTML report of Graph errors/warnings | *Optional* | `false` | 2.0 | +| [distanceBetweenElevationSamples](#distanceBetweenElevationSamples) | `double` | The distance between elevation samples in meters. | *Optional* | `10.0` | 2.0 | +| embedRouterConfig | `boolean` | Embed the Router config in the graph, which allows it to be sent to a server fully configured over the wire. | *Optional* | `true` | 2.0 | +| [graph](#graph) | `uri` | URI to the graph object file for reading and writing. | *Optional* | | 2.0 | +| [gsCredentials](#gsCredentials) | `string` | Local file system path to Google Cloud Platform service accounts credentials file. | *Optional* | | 2.0 | +| [includeEllipsoidToGeoidDifference](#includeEllipsoidToGeoidDifference) | `boolean` | Include the Ellipsoid to Geoid difference in the calculations of every point along every StreetWithElevationEdge. | *Optional* | `false` | 2.0 | +| maxAreaNodes | `integer` | Visibility calculations for an area will not be done if there are more nodes than this limit. | *Optional* | `150` | 2.1 | +| [maxDataImportIssuesPerFile](#maxDataImportIssuesPerFile) | `integer` | When to split the import report. | *Optional* | `1000` | 2.0 | +| maxElevationPropagationMeters | `integer` | The maximum distance to propagate elevation to vertices which have no elevation. | *Optional* | `2000` | 1.5 | +| [maxStopToShapeSnapDistance](#maxStopToShapeSnapDistance) | `double` | Maximum distance between route shapes and their stops. | *Optional* | `150.0` | 2.1 | +| maxTransferDuration | `duration` | Transfers up to this duration with the default walk speed value will be pre-calculated and included in the Graph. | *Optional* | `"PT30M"` | 2.1 | +| [multiThreadElevationCalculations](#multiThreadElevationCalculations) | `boolean` | Configuring multi-threading during elevation calculations. | *Optional* | `false` | 2.0 | +| [osmCacheDataInMem](#osmCacheDataInMem) | `boolean` | If OSM data should be cached in memory during processing. | *Optional* | `false` | 2.0 | +| [osmNaming](#osmNaming) | `enum` | A custom OSM namer to use. | *Optional* | `"default"` | 1.5 | +| platformEntriesLinking | `boolean` | Link unconnected entries to public transport platforms. | *Optional* | `false` | 2.0 | +| [readCachedElevations](#readCachedElevations) | `boolean` | Whether to read cached elevation data. | *Optional* | `true` | 2.0 | +| staticBikeParkAndRide | `boolean` | Whether we should create bike P+R stations from OSM data. | *Optional* | `false` | 1.5 | +| staticParkAndRide | `boolean` | Whether we should create car P+R stations from OSM data. | *Optional* | `true` | 1.5 | +| stopConsolidationFile | `uri` | Name of the CSV-formatted file in the build directory which contains the configuration for stop consolidation. | *Optional* | | 2.5 | +| [streetGraph](#streetGraph) | `uri` | URI to the street graph object file for reading and writing. | *Optional* | | 2.0 | +| [subwayAccessTime](#subwayAccessTime) | `double` | Minutes necessary to reach stops served by trips on routes of route_type=1 (subway) from the street. | *Optional* | `2.0` | 1.5 | +| [transitModelTimeZone](#transitModelTimeZone) | `time-zone` | Time zone for the graph. | *Optional* | | 2.2 | +| [transitServiceEnd](#transitServiceEnd) | `duration` | Limit the import of transit services to the given end date. | *Optional* | `"P3Y"` | 2.0 | +| [transitServiceStart](#transitServiceStart) | `duration` | Limit the import of transit services to the given START date. | *Optional* | `"-P1Y"` | 2.0 | +| [writeCachedElevations](#writeCachedElevations) | `boolean` | Reusing elevation data from previous builds | *Optional* | `false` | 2.0 | +| [boardingLocationTags](#boardingLocationTags) | `string[]` | What OSM tags should be looked on for the source of matching stops to platforms and stops. | *Optional* | | 2.2 | +| [dataOverlay](sandbox/DataOverlay.md) | `object` | Config for the DataOverlay Sandbox module | *Optional* | | 2.2 | +| [dem](#dem) | `object[]` | Specify parameters for DEM extracts. | *Optional* | | 2.2 | +|       [elevationUnitMultiplier](#dem_0_elevationUnitMultiplier) | `double` | Specify a multiplier to convert elevation units from source to meters. Overrides the value specified in `demDefaults`. | *Optional* | `1.0` | 2.3 | +|       source | `uri` | The unique URI pointing to the data file. | *Required* | | 2.2 | +| demDefaults | `object` | Default properties for DEM extracts. | *Optional* | | 2.3 | +|    [elevationUnitMultiplier](#demDefaults_elevationUnitMultiplier) | `double` | Specify a multiplier to convert elevation units from source to meters. | *Optional* | `1.0` | 2.3 | +| [elevationBucket](#elevationBucket) | `object` | Used to download NED elevation tiles from the given AWS S3 bucket. | *Optional* | | na | +| [emissions](sandbox/Emissions.md) | `object` | Emissions configuration. | *Optional* | | 2.5 | +| [fares](sandbox/Fares.md) | `object` | Fare configuration. | *Optional* | | 2.0 | +| gtfsDefaults | `object` | The gtfsDefaults section allows you to specify default properties for GTFS files. | *Optional* | | 2.3 | +|    blockBasedInterlining | `boolean` | Whether to create stay-seated transfers in between two trips with the same block id. | *Optional* | `true` | 2.3 | +|    [discardMinTransferTimes](#gd_discardMinTransferTimes) | `boolean` | Should minimum transfer times in GTFS files be discarded. | *Optional* | `false` | 2.3 | +|    maxInterlineDistance | `integer` | Maximal distance between stops in meters that will connect consecutive trips that are made with same vehicle. | *Optional* | `200` | 2.3 | +|    removeRepeatedStops | `boolean` | Should consecutive identical stops be merged into one stop time entry. | *Optional* | `true` | 2.3 | +|    [stationTransferPreference](#gd_stationTransferPreference) | `enum` | Should there be some preference or aversion for transfers at stops that are part of a station. | *Optional* | `"allowed"` | 2.3 | +| islandPruning | `object` | Settings for fixing street graph connectivity errors | *Optional* | | 2.3 | +|    [adaptivePruningDistance](#islandPruning_adaptivePruningDistance) | `integer` | Search distance for analyzing islands in pruning. | *Optional* | `250` | 2.3 | +|    [adaptivePruningFactor](#islandPruning_adaptivePruningFactor) | `double` | Defines how much pruning thresholds grow maximally by distance. | *Optional* | `50.0` | 2.3 | +|    [islandWithStopsMaxSize](#islandPruning_islandWithStopsMaxSize) | `integer` | When a graph island with stops in it should be pruned. | *Optional* | `2` | 2.3 | +|    [islandWithoutStopsMaxSize](#islandPruning_islandWithoutStopsMaxSize) | `integer` | When a graph island without stops should be pruned. | *Optional* | `10` | 2.3 | +| [localFileNamePatterns](#localFileNamePatterns) | `object` | Patterns for matching OTP file types in the base directory | *Optional* | | 2.0 | +|    [dem](#lfp_dem) | `regexp` | Pattern for matching elevation DEM files. | *Optional* | `"(?i)\.tiff?$"` | 2.0 | +|    [gtfs](#lfp_gtfs) | `regexp` | Patterns for matching GTFS zip-files or directories. | *Optional* | `"(?i)gtfs"` | 2.0 | +|    [netex](#lfp_netex) | `regexp` | Patterns for matching NeTEx zip files or directories. | *Optional* | `"(?i)netex"` | 2.0 | +|    [osm](#lfp_osm) | `regexp` | Pattern for matching Open Street Map input files. | *Optional* | `"(?i)(\.pbf¦\.osm¦\.osm\.xml)$"` | 2.0 | +| netexDefaults | `object` | The netexDefaults section allows you to specify default properties for NeTEx files. | *Optional* | | 2.2 | +|    feedId | `string` | This field is used to identify the specific NeTEx feed. It is used instead of the feed_id field in GTFS file feed_info.txt. | *Optional* | `"NETEX"` | 2.2 | +|    [groupFilePattern](#nd_groupFilePattern) | `regexp` | Pattern for matching group NeTEx files. | *Optional* | `"(\w{3})-.*\.xml"` | 2.0 | +|    ignoreFareFrame | `boolean` | Ignore contents of the FareFrame | *Optional* | `false` | 2.3 | +|    [ignoreFilePattern](#nd_ignoreFilePattern) | `regexp` | Pattern for matching ignored files in a NeTEx bundle. | *Optional* | `"$^"` | 2.0 | +|    ignoreParking | `boolean` | Ignore Parking elements. | *Optional* | `true` | 2.6 | +|    noTransfersOnIsolatedStops | `boolean` | Whether we should allow transfers to and from StopPlaces marked with LimitedUse.ISOLATED | *Optional* | `false` | 2.2 | +|    [sharedFilePattern](#nd_sharedFilePattern) | `regexp` | Pattern for matching shared NeTEx files in a NeTEx bundle. | *Optional* | `"shared-data\.xml"` | 2.0 | +|    [sharedGroupFilePattern](#nd_sharedGroupFilePattern) | `regexp` | Pattern for matching shared group NeTEx files in a NeTEx bundle. | *Optional* | `"(\w{3})-.*-shared\.xml"` | 2.0 | +|    [ferryIdsNotAllowedForBicycle](#nd_ferryIdsNotAllowedForBicycle) | `string[]` | List ferries which do not allow bikes. | *Optional* | | 2.0 | +| [osm](#osm) | `object[]` | Configure properties for a given OpenStreetMap feed. | *Optional* | | 2.2 | +|       [osmTagMapping](#osm_0_osmTagMapping) | `enum` | The named set of mapping rules applied when parsing OSM tags. Overrides the value specified in `osmDefaults`. | *Optional* | `"default"` | 2.2 | +|       source | `uri` | The unique URI pointing to the data file. | *Required* | | 2.2 | +|       timeZone | `time-zone` | The timezone used to resolve opening hours in OSM data. Overrides the value specified in `osmDefaults`. | *Optional* | | 2.2 | +| osmDefaults | `object` | Default properties for OpenStreetMap feeds. | *Optional* | | 2.2 | +|    [osmTagMapping](#od_osmTagMapping) | `enum` | The named set of mapping rules applied when parsing OSM tags. | *Optional* | `"default"` | 2.2 | +|    timeZone | `time-zone` | The timezone used to resolve opening hours in OSM data. | *Optional* | | 2.2 | +| [transferRequests](RouteRequest.md) | `object[]` | Routing requests to use for pre-calculating stop-to-stop transfers. | *Optional* | | 2.1 | +| [transitFeeds](#transitFeeds) | `object[]` | Scan for transit data files | *Optional* | | 2.2 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.2 | +|       type = "gtfs" | `enum` | The feed input format. | *Required* | | 2.2 | +|       blockBasedInterlining | `boolean` | Whether to create stay-seated transfers in between two trips with the same block id. Overrides the value specified in `gtfsDefaults`. | *Optional* | `true` | 2.3 | +|       [discardMinTransferTimes](#tf_0_discardMinTransferTimes) | `boolean` | Should minimum transfer times in GTFS files be discarded. Overrides the value specified in `gtfsDefaults`. | *Optional* | `false` | 2.3 | +|       feedId | `string` | The unique ID for this feed. This overrides any feed ID defined within the feed itself. | *Optional* | | 2.2 | +|       maxInterlineDistance | `integer` | Maximal distance between stops in meters that will connect consecutive trips that are made with same vehicle. Overrides the value specified in `gtfsDefaults`. | *Optional* | `200` | 2.3 | +|       removeRepeatedStops | `boolean` | Should consecutive identical stops be merged into one stop time entry. Overrides the value specified in `gtfsDefaults`. | *Optional* | `true` | 2.3 | +|       source | `uri` | The unique URI pointing to the data file. | *Required* | | 2.2 | +|       [stationTransferPreference](#tf_0_stationTransferPreference) | `enum` | Should there be some preference or aversion for transfers at stops that are part of a station. Overrides the value specified in `gtfsDefaults`. | *Optional* | `"allowed"` | 2.3 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.2 | +|       type = "netex" | `enum` | The feed input format. | *Required* | | 2.2 | +|       feedId | `string` | This field is used to identify the specific NeTEx feed. It is used instead of the feed_id field in GTFS file feed_info.txt. | *Required* | | 2.2 | +|       [groupFilePattern](#tf_1_groupFilePattern) | `regexp` | Pattern for matching group NeTEx files. | *Optional* | `"(\w{3})-.*\.xml"` | 2.0 | +|       ignoreFareFrame | `boolean` | Ignore contents of the FareFrame | *Optional* | `false` | 2.3 | +|       [ignoreFilePattern](#tf_1_ignoreFilePattern) | `regexp` | Pattern for matching ignored files in a NeTEx bundle. | *Optional* | `"$^"` | 2.0 | +|       ignoreParking | `boolean` | Ignore Parking elements. | *Optional* | `true` | 2.6 | +|       noTransfersOnIsolatedStops | `boolean` | Whether we should allow transfers to and from StopPlaces marked with LimitedUse.ISOLATED | *Optional* | `false` | 2.2 | +|       [sharedFilePattern](#tf_1_sharedFilePattern) | `regexp` | Pattern for matching shared NeTEx files in a NeTEx bundle. | *Optional* | `"shared-data\.xml"` | 2.0 | +|       [sharedGroupFilePattern](#tf_1_sharedGroupFilePattern) | `regexp` | Pattern for matching shared group NeTEx files in a NeTEx bundle. | *Optional* | `"(\w{3})-.*-shared\.xml"` | 2.0 | +|       source | `uri` | The unique URI pointing to the data file. | *Required* | | 2.2 | +|       [ferryIdsNotAllowedForBicycle](#tf_1_ferryIdsNotAllowedForBicycle) | `string[]` | List ferries which do not allow bikes. | *Optional* | | 2.0 | +| [transitRouteToStationCentroid](#transitRouteToStationCentroid) | `feed-scoped-id[]` | List stations that should route to centroid. | *Optional* | | 2.7 | @@ -263,7 +264,7 @@ OTP allows you to adjust the elevation values reported in API responses in two w is to store ellipsoid (GPS) elevation values internally, but apply a single geoid difference value in the OTP client where appropriate to display elevations above sea level. This ellipsoid to geoid difference is returned in each trip plan response in the -[ElevationMetadata](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/api/resource/ElevationMetadata.java) +[ElevationMetadata](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/application/src/ext/java/org/opentripplanner/ext/restapi/model/ElevationMetadata.java) field. Using a single value can be sufficient for smaller OTP deployments, but might result in incorrect values at the edges of larger OTP deployments. If your OTP instance uses this, it is recommended to set a default request value in the `router-config.json` file as follows: @@ -1067,6 +1068,26 @@ For this reason we allow bicycles on ferries by default and allow to override th case where this is not the case. +

    transitRouteToStationCentroid

    + +**Since version:** `2.7` ∙ **Type:** `feed-scoped-id[]` ∙ **Cardinality:** `Optional` +**Path:** / + +List stations that should route to centroid. + +This field contains a list of station ids for which street legs will start/end at the station +centroid instead of the child stops. + +When searching from/to a station the default behaviour is to route from/to any of the stations child +stops. This can cause strange results for stations that have stops spread over a large area. + +For some stations you might instead wish to use the centroid of the station as the +origin/destination. In this case the centroid will be used both for direct street search and for +access/egress street search where the station is used as the start/end of the access/egress. But +transit that starts/ends at the station will work as usual without any additional street leg from/to +the centroid. + + diff --git a/doc/user/Changelog.md b/doc/user/Changelog.md index e81d5583134..7d96b53885c 100644 --- a/doc/user/Changelog.md +++ b/doc/user/Changelog.md @@ -3,67 +3,113 @@ The changelog lists most feature changes between each release. The list is automatically created based on merged pull requests. Search GitHub issues and pull requests for smaller issues. -## 2.6.0-SNAPSHOT (under development) +## 2.7.0-SNAPSHOT (under development) + +- Extra leg when transferring at the same stop [#5984](https://github.com/opentripplanner/OpenTripPlanner/pull/5984) +- Filter vector tiles stops by current service week [#6003](https://github.com/opentripplanner/OpenTripPlanner/pull/6003) +- Add a matcher API for filters in the transit service used for datedServiceJourneyQuery [#5713](https://github.com/opentripplanner/OpenTripPlanner/pull/5713) +- Refetch transit leg with a leg query of GTFS GraphQL API [#6045](https://github.com/opentripplanner/OpenTripPlanner/pull/6045) +- Remove deprecated support for GTFS flex stop areas [#6074](https://github.com/opentripplanner/OpenTripPlanner/pull/6074) +- Don't use elevation data directly for ways with cutting=*, location=underground or indoor=yes tags in the default mapper [#6093](https://github.com/opentripplanner/OpenTripPlanner/pull/6093) +- Un-deprecate GTFS API's `planConnection`, deprecate `plan` [#6110](https://github.com/opentripplanner/OpenTripPlanner/pull/6110) +- Support for routing to Station centroid instead of child stops [#6047](https://github.com/opentripplanner/OpenTripPlanner/pull/6047) +- Add via to the Transmodel trip query and make a proper Raptor implementation for it [#6084](https://github.com/opentripplanner/OpenTripPlanner/pull/6084) +- Fix GTFS-Flex duration offset and factor parsing when only one of them is set [#6138](https://github.com/opentripplanner/OpenTripPlanner/pull/6138) +- Fix arrive by filtering for on-street/flex itineraries [#6050](https://github.com/opentripplanner/OpenTripPlanner/pull/6050) +- Rename TransitModel to TransitRepository [#6148](https://github.com/opentripplanner/OpenTripPlanner/pull/6148) +- Clear added patterns in TimetableSnapshot [#6141](https://github.com/opentripplanner/OpenTripPlanner/pull/6141) +- Rename StopModel to SiteRepository [#6165](https://github.com/opentripplanner/OpenTripPlanner/pull/6165) +- Allow bike walking through bicycle no thru traffic areas [#6179](https://github.com/opentripplanner/OpenTripPlanner/pull/6179) +- update the description of mode to cable tram. [#6173](https://github.com/opentripplanner/OpenTripPlanner/pull/6173) +- Change GraphQL tooltip for searchWindowUsed to say minutes, instead of seconds [#6185](https://github.com/opentripplanner/OpenTripPlanner/pull/6185) +- Interpret GTFS extended route types 801-899 also as trolleybus service [#6170](https://github.com/opentripplanner/OpenTripPlanner/pull/6170) +- Disable protocol upgrades for the HTTP client by default. [#6194](https://github.com/opentripplanner/OpenTripPlanner/pull/6194) +- Fix max search-window when paging [#6189](https://github.com/opentripplanner/OpenTripPlanner/pull/6189) +- Add car ferry functionality [#5966](https://github.com/opentripplanner/OpenTripPlanner/pull/5966) +- Make indoor=area and indoor=corridor routable for UK OSM tag mapper [#6119](https://github.com/opentripplanner/OpenTripPlanner/pull/6119) +- Revert [#6214](https://github.com/opentripplanner/OpenTripPlanner/pull/6214) +- Remove reading agency and route brandingUrl from GTFS data [#6183](https://github.com/opentripplanner/OpenTripPlanner/pull/6183) +- Fix NullPointerException when searching backwards with a frequency-based trip [#6211](https://github.com/opentripplanner/OpenTripPlanner/pull/6211) +- Combine two multi-criteria searches in Raptor [#6182](https://github.com/opentripplanner/OpenTripPlanner/pull/6182) +- Implement alert node query in GTFS GraphQL API [#6225](https://github.com/opentripplanner/OpenTripPlanner/pull/6225) +- Fix hop geometries when one pattern is replaced by another with different number of stops [#6136](https://github.com/opentripplanner/OpenTripPlanner/pull/6136) +- Distinct coach from bus when reading in GTFS data and in GTFS GraphQL API [#6171](https://github.com/opentripplanner/OpenTripPlanner/pull/6171) +- Add provider of updates as a dimension to metrics. [#6199](https://github.com/opentripplanner/OpenTripPlanner/pull/6199) +- Return empty list if there is no siriUrls in situations/infoLinks [#6232](https://github.com/opentripplanner/OpenTripPlanner/pull/6232) +- OSM area processing obeys tag mapping [#6164](https://github.com/opentripplanner/OpenTripPlanner/pull/6164) +- Add `via` to GTFS GraphQL API [#5958](https://github.com/opentripplanner/OpenTripPlanner/pull/5958) +- Deprecate old alert translations in the GTFS API and add language param to a few alert fields [#6216](https://github.com/opentripplanner/OpenTripPlanner/pull/6216) +- add stopPositionInPattern in Stoptime in GTFS GraphQL API [#6204](https://github.com/opentripplanner/OpenTripPlanner/pull/6204) +- Fix parsing of wheelchair accessible parking, add wheelchair debug layer [#6229](https://github.com/opentripplanner/OpenTripPlanner/pull/6229) +- Add previousLegs into GTFS GraphQL API [#6142](https://github.com/opentripplanner/OpenTripPlanner/pull/6142) +- Fix stop index filtering on ServiceJourney Transmodel GraphQL API [#6251](https://github.com/opentripplanner/OpenTripPlanner/pull/6251) +- Fix rental searches when destination is in a no-drop-off zone [#6233](https://github.com/opentripplanner/OpenTripPlanner/pull/6233) +- Include empty rail stops in transfers [#6208](https://github.com/opentripplanner/OpenTripPlanner/pull/6208) +- Relax rejection of GTFS flex trips that also contain continuous stopping [#6231](https://github.com/opentripplanner/OpenTripPlanner/pull/6231) +- Remove legacy bike access mapping [#6248](https://github.com/opentripplanner/OpenTripPlanner/pull/6248) +- Filter import of rental data by pickup type [#6240](https://github.com/opentripplanner/OpenTripPlanner/pull/6240) +- Apply stricter motor vehicle nothrough traffic rules in Finland [#6254](https://github.com/opentripplanner/OpenTripPlanner/pull/6254) +- Add `vehicleRentalsByBbox` query to GTFS GraphQL API [#6186](https://github.com/opentripplanner/OpenTripPlanner/pull/6186) +- Improve performance of speculative rental vehicle use in reverse search [#6260](https://github.com/opentripplanner/OpenTripPlanner/pull/6260) +- Fix problem with relaxed-generalized-cost-at-destination [#6255](https://github.com/opentripplanner/OpenTripPlanner/pull/6255) +- Reject SIRI-ET updates with empty StopPointRefs [#6266](https://github.com/opentripplanner/OpenTripPlanner/pull/6266) +- Allow GTFS fuzzy trip matching even when trip descriptor has an id [#6250](https://github.com/opentripplanner/OpenTripPlanner/pull/6250) +- Make `motorroad=yes` car-only [#6288](https://github.com/opentripplanner/OpenTripPlanner/pull/6288) +- Add decision record for analysis and design documentation [#6281](https://github.com/opentripplanner/OpenTripPlanner/pull/6281) +- Switch GTFS flex `safe_duration_offset` back to seconds [#6298](https://github.com/opentripplanner/OpenTripPlanner/pull/6298) +- Remove unused GtfsGraphQlApiRentalStationFuzzyMatching feature [#6282](https://github.com/opentripplanner/OpenTripPlanner/pull/6282) +- Make debug UI background layers configurable with new file `debug-ui-config.json` [#6295](https://github.com/opentripplanner/OpenTripPlanner/pull/6295) +[](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) + +## 2.6.0 (2024-09-18) + +### Notable Changes + +- ISO-8601 date time for GTFS GraphQL API itinerary responses [#5660](https://github.com/opentripplanner/OpenTripPlanner/pull/5660) +- Add support for query parameter to enforce booking time in trip search for flexible services [#5606](https://github.com/opentripplanner/OpenTripPlanner/pull/5606) +- New GTFS GraphQL plan query [#5185](https://github.com/opentripplanner/OpenTripPlanner/pull/5185) +- Make new debug client the default, move old one to `classic-debug` [#5924](https://github.com/opentripplanner/OpenTripPlanner/pull/5924) [#5962](https://github.com/opentripplanner/OpenTripPlanner/pull/5962) [#6012](https://github.com/opentripplanner/OpenTripPlanner/pull/6012) [#6053](https://github.com/opentripplanner/OpenTripPlanner/pull/6053) +- Disable Legacy REST API by default [#5948](https://github.com/opentripplanner/OpenTripPlanner/pull/5948) + +### Detailed changes by Pull Request -- ISO-8601 date time for GTFS API itinerary responses [#5660](https://github.com/opentripplanner/OpenTripPlanner/pull/5660) +- SIRI real time improvements and bug fixes [#5867](https://github.com/opentripplanner/OpenTripPlanner/pull/5867) [#5931](https://github.com/opentripplanner/OpenTripPlanner/pull/5931) [#5865](https://github.com/opentripplanner/OpenTripPlanner/pull/5865) +- Real time improvements and bug fixes [#5726](https://github.com/opentripplanner/OpenTripPlanner/pull/5726) [#5941](https://github.com/opentripplanner/OpenTripPlanner/pull/5941) [#6007](https://github.com/opentripplanner/OpenTripPlanner/pull/6007) - Fix street routing on roundabout [#5732](https://github.com/opentripplanner/OpenTripPlanner/pull/5732) - Expose route sort order in GTFS API [#5764](https://github.com/opentripplanner/OpenTripPlanner/pull/5764) - Fix issue with cancellations on trip patterns that run after midnight [#5719](https://github.com/opentripplanner/OpenTripPlanner/pull/5719) -- Fix handling of null transport mode filter [#5789](https://github.com/opentripplanner/OpenTripPlanner/pull/5789) - Discourage instead of ban cycling on use_sidepath ways and do the same for walking on foot=use_sidepath [#5790](https://github.com/opentripplanner/OpenTripPlanner/pull/5790) - Prune islands with mode-less stop vertices [#5782](https://github.com/opentripplanner/OpenTripPlanner/pull/5782) - Overwrite default WALK directMode when it is not set in the request, but modes is set [#5779](https://github.com/opentripplanner/OpenTripPlanner/pull/5779) - Fix trip duplication in Graph Builder DSJ mapping [#5794](https://github.com/opentripplanner/OpenTripPlanner/pull/5794) -- Optionally abort startup when unknown configuration parameters were detected [#5676](https://github.com/opentripplanner/OpenTripPlanner/pull/5676) - Fix bug in heuristics cost calculation for egress legs [#5783](https://github.com/opentripplanner/OpenTripPlanner/pull/5783) -- Fix handling of implicit access and egress mode parameters. [#5821](https://github.com/opentripplanner/OpenTripPlanner/pull/5821) -- Make naming of stopTransferCosts/stopBoardAlightCosts consistent [#5822](https://github.com/opentripplanner/OpenTripPlanner/pull/5822) +- Fix handling of implicit access and egress mode parameters [#5821](https://github.com/opentripplanner/OpenTripPlanner/pull/5821) - Namer for applying street names to nearby sidewalks [#5774](https://github.com/opentripplanner/OpenTripPlanner/pull/5774) - Implement GTFS Flex safe duration spec draft [#5796](https://github.com/opentripplanner/OpenTripPlanner/pull/5796) -- Document and validate timeRange GraphQL parameter [#5834](https://github.com/opentripplanner/OpenTripPlanner/pull/5834) -- Log the origin of a request that causes a transfer cache addition. [#5874](https://github.com/opentripplanner/OpenTripPlanner/pull/5874) -- Fix handling of missing aimed departure time [#5865](https://github.com/opentripplanner/OpenTripPlanner/pull/5865) - Add OTP request timeout GraphQL instrumentation [#5881](https://github.com/opentripplanner/OpenTripPlanner/pull/5881) - Add feed publisher name and url to GTFS GraphQL API [#5835](https://github.com/opentripplanner/OpenTripPlanner/pull/5835) -- Add support for query parameter to enforce booking time in trip search for flexible services [#5606](https://github.com/opentripplanner/OpenTripPlanner/pull/5606) - Fix parsing of GBFS feeds [#5891](https://github.com/opentripplanner/OpenTripPlanner/pull/5891) -- Fix SIRI update travel back in time [#5867](https://github.com/opentripplanner/OpenTripPlanner/pull/5867) -- Limit result size and execution time in TransModel GraphQL API [#5883](https://github.com/opentripplanner/OpenTripPlanner/pull/5883) -- Fix real-time added patterns persistence with DIFFERENTIAL updates [#5726](https://github.com/opentripplanner/OpenTripPlanner/pull/5726) -- Add plan query that follows the relay connection specification [#5185](https://github.com/opentripplanner/OpenTripPlanner/pull/5185) -- Fix debug client after breaking change in dependency graphql-request [#5899](https://github.com/opentripplanner/OpenTripPlanner/pull/5899) +- Limit result size and execution time in Transmodel GraphQL API [#5883](https://github.com/opentripplanner/OpenTripPlanner/pull/5883) - Remove TravelTime API [#5890](https://github.com/opentripplanner/OpenTripPlanner/pull/5890) -- Improve cancellation of large response in TransModel API [#5908](https://github.com/opentripplanner/OpenTripPlanner/pull/5908) -- Refactor SIRI-ET updaters [#5904](https://github.com/opentripplanner/OpenTripPlanner/pull/5904) -- Update Google Pubsub updater configuration [#5927](https://github.com/opentripplanner/OpenTripPlanner/pull/5927) -- Make new debug client the default, move old one to `classic-debug` [#5924](https://github.com/opentripplanner/OpenTripPlanner/pull/5924) +- Improve cancellation of large response in Transmodel API [#5908](https://github.com/opentripplanner/OpenTripPlanner/pull/5908) - Require valid polygons for AreaStop [#5915](https://github.com/opentripplanner/OpenTripPlanner/pull/5915) - Fix NullPointerException in stop transfer priority cost vector generation [#5943](https://github.com/opentripplanner/OpenTripPlanner/pull/5943) - Convert transferSlack configuration to duration [#5897](https://github.com/opentripplanner/OpenTripPlanner/pull/5897) - Expose stop transfer priority in Transmodel API [#5942](https://github.com/opentripplanner/OpenTripPlanner/pull/5942) -- Add rental system to GraphQL API [#5909](https://github.com/opentripplanner/OpenTripPlanner/pull/5909) -- Improve handling of SIRI added trip with unresolvable agency [#5931](https://github.com/opentripplanner/OpenTripPlanner/pull/5931) -- Fix copy-on-write in TimetableSnapshot [#5941](https://github.com/opentripplanner/OpenTripPlanner/pull/5941) +- Add rental system to GTFS GraphQL API [#5909](https://github.com/opentripplanner/OpenTripPlanner/pull/5909) - Generate documentation for OSM tag mappers [#5929](https://github.com/opentripplanner/OpenTripPlanner/pull/5929) -- Disable Legacy REST API by default [#5948](https://github.com/opentripplanner/OpenTripPlanner/pull/5948) - Enforce non-null coordinates on multimodal station [#5971](https://github.com/opentripplanner/OpenTripPlanner/pull/5971) - Add car rental to Transmodel street mode options [#5977](https://github.com/opentripplanner/OpenTripPlanner/pull/5977) -- Add debug information for stop/quay ID and stay-seated transfers [#5962](https://github.com/opentripplanner/OpenTripPlanner/pull/5962) - Handle NeTEx `any` version [#5983](https://github.com/opentripplanner/OpenTripPlanner/pull/5983) - Keep at least one result for min-transfers and each transit-group in itinerary-group-filter [#5919](https://github.com/opentripplanner/OpenTripPlanner/pull/5919) - Extract parking lots from NeTEx feeds [#5946](https://github.com/opentripplanner/OpenTripPlanner/pull/5946) - Filter routes and patterns by service date in GTFS GraphQL API [#5869](https://github.com/opentripplanner/OpenTripPlanner/pull/5869) - SIRI-FM vehicle parking updates [#5979](https://github.com/opentripplanner/OpenTripPlanner/pull/5979) - Take realtime patterns into account when storing realtime vehicles [#5994](https://github.com/opentripplanner/OpenTripPlanner/pull/5994) -- Debug client itinerary list style improvements [#6012](https://github.com/opentripplanner/OpenTripPlanner/pull/6012) - Developer Decision Records [#5932](https://github.com/opentripplanner/OpenTripPlanner/pull/5932) - Allow NeTEx ServiceJourneyPatterns with stopUse=passthrough [#6037](https://github.com/opentripplanner/OpenTripPlanner/pull/6037) -- Additional SVG diagrams in updaters package.md [#5936](https://github.com/opentripplanner/OpenTripPlanner/pull/5936) -- Upgrade OBA, remove camsys-apps.com from Maven repos [#6041](https://github.com/opentripplanner/OpenTripPlanner/pull/6041) -- OSM data links added to the graph build report about ambiguous levels and layers [#6049](https://github.com/opentripplanner/OpenTripPlanner/pull/6049) -- Add links for Debug UI to GraphiQL [#6053](https://github.com/opentripplanner/OpenTripPlanner/pull/6053) -- Update indexes in timetable snapshot [#6007](https://github.com/opentripplanner/OpenTripPlanner/pull/6007) -[](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) +- Use correct HEAD request when fetching HTTP headers [#6063](https://github.com/opentripplanner/OpenTripPlanner/pull/6063) +- Fix incorrect mapping of flex safe duration offset [#6059](https://github.com/opentripplanner/OpenTripPlanner/pull/6059) ## 2.5.0 (2024-03-13) diff --git a/doc/user/Configuration.md b/doc/user/Configuration.md index 8e366e476a9..97c70594b78 100644 --- a/doc/user/Configuration.md +++ b/doc/user/Configuration.md @@ -2,7 +2,7 @@ NOTE! Part of this document is generated. Make sure you edit the template, not the generated doc. - Template directory is: /doc/templates - - Generated directory is: /docs + - Generated directory is: /doc/user --> # Configuring OpenTripPlanner @@ -41,9 +41,9 @@ default behavior of scanning the base directory for input files. Scanning is ove independently for each file type, and can point to remote cloud storage with arbitrary URIs. See [the storage section](Configuration.md#Storage) for further details. -## Three Scopes of Configuration +## Four scopes of configuration -OTP is configured via three configuration JSON files which are read from the directory specified on +OTP is configured via four configuration JSON files which are read from the directory specified on its command line. We try to provide sensible defaults for every option, so all three of these files are optional, as are all the options within each file. Each configuration file corresponds to options that are relevant at a particular phase of OTP usage. @@ -51,7 +51,8 @@ options that are relevant at a particular phase of OTP usage. Options and parameters that are taken into account during the graph building process will be "baked into" the graph, and cannot be changed later in a running server. These are specified in `build-config.json`. Other details of OTP operation can be modified without rebuilding the graph. -These run-time configuration options are found in `router-config.json`. Finally, `otp-config.json` +These run-time configuration options are found in `router-config.json`. If you want to configure +the built-in debug UI add `debug-ui-config.json`. Finally, `otp-config.json` contains simple switches that enable or disable system-wide features. ## Configuration types @@ -173,7 +174,7 @@ text inserted is valid JSON (starts with `{` and ends with `}`). Variable substitution is performed on configuration file after the include file directive; Hence variable substitution is also performed on the text in the injected file. -Here is an example including variable substitution, assuming version 2.5.0 of OTP: +Here is an example including variable substitution, assuming version 2.6.0 of OTP: ```JSON // build-config.json @@ -197,7 +198,7 @@ The result will look like this: { "transitFeeds": [ { - "source": "netex-v2.5.0.obj" + "source": "netex-v2.6.0.obj" } ] } @@ -219,37 +220,39 @@ Here is a list of all features which can be toggled on/off and their default val -| Feature | Description | Enabled by default | Sandbox | -|--------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------:|:-------:| -| `APIBikeRental` | Enable the bike rental endpoint. | ✓️ | | -| `APIServerInfo` | Enable the server info endpoint. | ✓️ | | -| `APIUpdaterStatus` | Enable endpoint for graph updaters status. | ✓️ | | -| `ConsiderPatternsForDirectTransfers` | Enable limiting transfers so that there is only a single transfer to each pattern. | ✓️ | | -| `DebugUi` | Enable the debug GraphQL client and web UI and located at the root of the web server as well as the debug map tiles it uses. Be aware that the map tiles are not a stable API and can change without notice. Use the [vector tiles feature if](sandbox/MapboxVectorTilesApi.md) you want a stable map tiles API. | ✓️ | | -| `FloatingBike` | Enable floating bike routing. | ✓️ | | -| `GtfsGraphQlApi` | Enable the [GTFS GraphQL API](apis/GTFS-GraphQL-API.md). | ✓️ | | -| `GtfsGraphQlApiRentalStationFuzzyMatching` | Does vehicleRentalStation query also allow ids that are not feed scoped. | | | -| `MinimumTransferTimeIsDefinitive` | If the minimum transfer time is a lower bound (default) or the definitive time for the transfer. Set this to `true` if you want to set a transfer time lower than what OTP derives from OSM data. | | | -| `OptimizeTransfers` | OTP will inspect all itineraries found and optimize where (which stops) the transfer will happen. Waiting time, priority and guaranteed transfers are taken into account. | ✓️ | | -| `ParallelRouting` | Enable performing parts of the trip planning in parallel. | | | -| `TransferConstraints` | Enforce transfers to happen according to the _transfers.txt_ (GTFS) and Interchanges (NeTEx). Turning this _off_ will increase the routing performance a little. | ✓️ | | -| `TransmodelGraphQlApi` | Enable the [Transmodel (NeTEx) GraphQL API](apis/TransmodelApi.md). | ✓️ | ✓️ | -| `ActuatorAPI` | Endpoint for actuators (service health status). | | ✓️ | -| `AsyncGraphQLFetchers` | Whether the @async annotation in the GraphQL schema should lead to the fetch being executed asynchronously. This allows batch or alias queries to run in parallel at the cost of consuming extra threads. | | | -| `Co2Emissions` | Enable the emissions sandbox module. | | ✓️ | -| `DataOverlay` | Enable usage of data overlay when calculating costs for the street network. | | ✓️ | -| `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. | | ✓️ | -| `MultiCriteriaGroupMaxFilter` | Keep the best itinerary with respect to each criteria used in the transit-routing search. For example the itinerary with the lowest cost, fewest transfers, and each unique transit-group (transit-group-priority) is kept, even if the max-limit is exceeded. This is turned off by default for now, until this feature is well tested. | | | -| `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! | | | -| `SandboxAPIGeocoder` | Enable the Geocoder API. | | ✓️ | -| `SandboxAPIMapboxVectorTilesApi` | Enable Mapbox vector tiles API. | | ✓️ | -| `SandboxAPIParkAndRideApi` | Enable park-and-ride endpoint. | | ✓️ | -| `TransferAnalyzer` | Analyze transfers during graph build. | | ✓️ | +| Feature | Description | Enabled by default | Sandbox | +|--------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------:|:-------:| +| `APIBikeRental` | Enable the bike rental endpoint. | ✓️ | | +| `APIServerInfo` | Enable the server info endpoint. | ✓️ | | +| `APIUpdaterStatus` | Enable endpoint for graph updaters status. | ✓️ | | +| `IncludeEmptyRailStopsInTransfers` | Turning this on guarantees that Rail stops without scheduled departures still get included when generating transfers using `ConsiderPatternsForDirectTransfers`. It is common for stops to be assign at real-time for Rail. Turning this on will help to avoid dropping transfers which are needed, when the stop is in use later. Turning this on, if ConsiderPatternsForDirectTransfers is off has no effect. | | | +| `ConsiderPatternsForDirectTransfers` | Enable limiting transfers so that there is only a single transfer to each pattern. | ✓️ | | +| `DebugUi` | Enable the debug GraphQL client and web UI and located at the root of the web server as well as the debug map tiles it uses. Be aware that the map tiles are not a stable API and can change without notice. Use the [vector tiles feature if](sandbox/MapboxVectorTilesApi.md) you want a stable map tiles API. | ✓️ | | +| `ExtraTransferLegOnSameStop` | Should there be a transfer leg when transferring on the very same stop. Note that for in-seat/interlined transfers no transfer leg will be generated. | | | +| `FloatingBike` | Enable floating bike routing. | ✓️ | | +| `GtfsGraphQlApi` | Enable the [GTFS GraphQL API](apis/GTFS-GraphQL-API.md). | ✓️ | | +| `MinimumTransferTimeIsDefinitive` | If the minimum transfer time is a lower bound (default) or the definitive time for the transfer. Set this to `true` if you want to set a transfer time lower than what OTP derives from OSM data. | | | +| `OptimizeTransfers` | OTP will inspect all itineraries found and optimize where (which stops) the transfer will happen. Waiting time, priority and guaranteed transfers are taken into account. | ✓️ | | +| `ParallelRouting` | Enable performing parts of the trip planning in parallel. | | | +| `TransferConstraints` | Enforce transfers to happen according to the _transfers.txt_ (GTFS) and Interchanges (NeTEx). Turning this _off_ will increase the routing performance a little. | ✓️ | | +| `TransmodelGraphQlApi` | Enable the [Transmodel (NeTEx) GraphQL API](apis/TransmodelApi.md). | ✓️ | ✓️ | +| `ActuatorAPI` | Endpoint for actuators (service health status). | | ✓️ | +| `AsyncGraphQLFetchers` | Whether the @async annotation in the GraphQL schema should lead to the fetch being executed asynchronously. This allows batch or alias queries to run in parallel at the cost of consuming extra threads. | | | +| `Co2Emissions` | Enable the emissions sandbox module. | | ✓️ | +| `DataOverlay` | Enable usage of data overlay when calculating costs for the street network. | | ✓️ | +| `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. | | ✓️ | +| `MultiCriteriaGroupMaxFilter` | Keep the best itinerary with respect to each criteria used in the transit-routing search. For example the itinerary with the lowest cost, fewest transfers, and each unique transit-group (transit-group-priority) is kept, even if the max-limit is exceeded. This is turned off by default for now, until this feature is well tested. | | | +| `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! | | | +| `SandboxAPIGeocoder` | Enable the Geocoder API. | | ✓️ | +| `SandboxAPIMapboxVectorTilesApi` | Enable Mapbox vector tiles API. | | ✓️ | +| `SandboxAPIParkAndRideApi` | Enable park-and-ride endpoint. | | ✓️ | +| `Sorlandsbanen` | Include train Sørlandsbanen in results when searching in south of Norway. Only relevant in Norway. | | ✓️ | +| `TransferAnalyzer` | Analyze transfers during graph build. | | ✓️ | diff --git a/doc/user/Container-Image.md b/doc/user/Container-Image.md index ed2441f5ac1..0c2a03b2b0f 100644 --- a/doc/user/Container-Image.md +++ b/doc/user/Container-Image.md @@ -20,9 +20,15 @@ curl -L https://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf -o be # download GTFS curl -L https://vbb.de/vbbgtfs -o berlin/vbb-gtfs.zip # build graph and save it onto the host system via the volume -docker run --rm -v "$(pwd)/berlin:/var/opentripplanner" docker.io/opentripplanner/opentripplanner:latest --build --save +docker run --rm \ + -e JAVA_TOOL_OPTIONS='-Xmx8g' \ + -v "$(pwd)/berlin:/var/opentripplanner" \ + docker.io/opentripplanner/opentripplanner:latest --build --save # load and serve graph -docker run -it --rm -p 8080:8080 -v "$(pwd)/berlin:/var/opentripplanner" docker.io/opentripplanner/opentripplanner:latest --load --serve +docker run -it --rm -p 8080:8080 \ + -e JAVA_TOOL_OPTIONS='-Xmx8g' \ + -v "$(pwd)/berlin:/var/opentripplanner" \ + docker.io/opentripplanner/opentripplanner:latest --load --serve ``` Now open [http://localhost:8080](http://localhost:8080) to see your running OTP instance. diff --git a/doc/user/DebugUiConfiguration.md b/doc/user/DebugUiConfiguration.md new file mode 100644 index 00000000000..a1657796fe0 --- /dev/null +++ b/doc/user/DebugUiConfiguration.md @@ -0,0 +1,66 @@ + + +# Debug UI configuration + +The Debug UI is the standard interface that is bundled with OTP and available by visiting +[`http://localhost:8080`](http://localhost:8080). This page list the configuration options available +by placing a file `debug-ui-config.json` into OTP's working directory. + + + + +| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | +|-----------------------------------------------------------|:----------:|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------:|-----------------------|:-----:| +| [additionalBackgroundLayers](#additionalBackgroundLayers) | `object[]` | Additional background raster map layers. | *Optional* | | 2.7 | +|       attribution | `string` | Attribution for the map data. | *Optional* | `"© OpenTripPlanner"` | 2.7 | +|       name | `string` | Name to appear in the layer selector. | *Required* | | 2.7 | +|       templateUrl | `string` | The [Maplibre-compatible template URL](https://maplibre.org/maplibre-native/ios/api/tile-url-templates.html) for the raster layer, for example `https://examples.com/tiles/{z}/{x}/{y}.png`. | *Required* | | 2.7 | +|       tileSize | `integer` | Size of the tile in pixels. | *Optional* | `256` | 2.7 | + + + + +## Parameter Details + + + + +

    additionalBackgroundLayers

    + +**Since version:** `2.7` ∙ **Type:** `object[]` ∙ **Cardinality:** `Optional` +**Path:** / + +Additional background raster map layers. + +Add additional background layers that will appear in the Debug UI as one of the choices. + +Currently only raster tile layers are supported. + + + + + +## Config Example + + + + +```JSON +// debug-ui-config.json +{ + "additionalBackgroundLayers" : [ + { + "name" : "TriMet aerial photos", + "templateUrl" : "https://maps.trimet.org/wms/reflect?bbox={bbox-epsg-3857}&format=image/png&service=WMS&version=1.1.0&request=GetMap&srs=EPSG:3857&width=256&height=256&layers=aerials", + "attribution" : "© TriMet" + } + ] +} +``` + + diff --git a/doc/user/Deployments.md b/doc/user/Deployments.md index 56ff23c113c..919ae331aaf 100644 --- a/doc/user/Deployments.md +++ b/doc/user/Deployments.md @@ -79,6 +79,7 @@ The following are known deployments of OTP in a government- or agency-sponsored * **Lower Saxony, Germany** The [VBN](https://www.vbn.de/en/) transportation authority offers an [OTP instance](https://www.vbn.de/en/service/developer-information/opendata-and-openservice) as alternative to the [Hafas](https://www.hacon.de/en/portfolio/information-ticketing/#section_8294) passenger information system. * **Leipzig, Germany** As of summer 2020 [Leipzig Move](https://leipzig-move.de/) has been using OpenTripPlanner. +* **Iceland (nationwide)** – [Strætó](https://www.straeto.is/en) has used OTP from 2015. ## Independent Production diff --git a/doc/user/Developers-Guide.md b/doc/user/Developers-Guide.md index 368a12edb62..f5633ff17b1 100644 --- a/doc/user/Developers-Guide.md +++ b/doc/user/Developers-Guide.md @@ -56,7 +56,7 @@ There are several ways to get involved: * Join the [Gitter chat room](https://gitter.im/opentripplanner/OpenTripPlanner) and the [user mailing list](http://groups.google.com/group/opentripplanner-users). -* Fix typos and improve the documentation within the `/docs` directory of the project (details +* Fix typos and improve the documentation within the `/doc/user` directory of the project (details below). * [File a bug or new feature request](http://github.com/openplans/OpenTripPlanner/issues/new). @@ -106,16 +106,6 @@ standards: 2. Strip out any unneeded information by using the `osmium filter-tags` as describe in [Preparing OSM](Preparing-OSM.md) -### Code Comments - -As a matter of [policy](http://github.com/opentripplanner/OpenTripPlanner/issues/93), all new -methods, classes, and fields should include comments explaining what they are for and any other -pertinent information. For Java code, the comments should use the -[JavaDoc conventions](http://java.sun.com/j2se/javadoc/writingdoccomments). It is best to provide -comments that not only explain *what* you did but also *why you did it* while providing some -context. Please avoid including trivial Javadoc or the empty Javadoc stubs added by IDEs, such as -`@param` annotations with no description. - ### Itinerary and API Snapshot Tests To test the itinerary generation, and the API there are snapshot test which save the result of the @@ -133,7 +123,7 @@ control to be applied to documentation as well as program source code. All pull how OTP is used or configured should include changes to the documentation alongside code modifications. -The documentation files are in Markdown format and are in the `/docs` directory under the root of +The documentation files are in Markdown format and are in the `/doc/user` directory under the root of the project. On every push to the `dev-2.x` branch the documentation will be rebuilt and deployed as static pages to our subdomain of [Github Pages](https://github.com/opentripplanner/docs). MkDocs is a Python program and should run on any major platform. @@ -143,7 +133,7 @@ how to generate a live local preview of the documentation while you're writing i In short: ``` -$ pip install -r docs/requirements.txt +$ pip install -r doc/user/requirements.txt $ mkdocs serve ``` @@ -205,7 +195,8 @@ so they are a bit easier to maintain that way. The primary audience is also acti that have the code checked out locally. - [Architecture](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/ARCHITECTURE.md) - - [Code Conventions](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/CODE_CONVENTIONS.md) + - [Code Style](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/doc/dev/decisionrecords/Codestyle.md) + - [Naming Conventions](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/doc/dev/decisionrecords/NamingConventions.md) - [Development Decision Records](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/DEVELOPMENT_DECISION_RECORDS.md) diff --git a/doc/user/Frontends.md b/doc/user/Frontends.md index b2f0b9d0b2e..ac793a4fc85 100644 --- a/doc/user/Frontends.md +++ b/doc/user/Frontends.md @@ -19,7 +19,7 @@ On the other hand, **production frontends** are intended to be a component of la The main OpenTripPlanner repository currently contains two debug web frontends: - new one currently under development at [`/client`](https://github.com/opentripplanner/OpenTripPlanner/tree/dev-2.x/client). -- the classic one in [`/src/client/classic-debug/`](https://github.com/opentripplanner/OpenTripPlanner/tree/dev-2.x/src/client/classic-debug) +- the classic one in [`/application/src/client/classic-debug/`](https://github.com/opentripplanner/OpenTripPlanner/tree/dev-2.x/application/src/client/classic-debug) The **new debug client** is a React/TypeScript Single Page App (SPA) that can be served locally or accessed over a content delivery network (CDN). Unlike the original debug client, it connects to the OTP Java backend via the GraphQL API using the Transmodel vocabulary. By default, it is available at the root URL (`http://localhost:8080/` in local operation). @@ -29,7 +29,7 @@ It connects to the OTP Java backend via a REST API using the GTFS vocabulary. Hi It is still available, but has been moved to `http://localhost:8080/classic-debug/` . There is a third piece of software that might qualify as an OTP client: a Java Swing application making use of the Processing visualization library, -located in the [GraphVisualizer class](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java). +located in the [GraphVisualizer class](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/application/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java). While it would not be accurate to call this a "native" desktop application (as it's cross-platform Java) it is not a web app. This very developer-centric UI is also over a decade old and has been very sparsely maintained, but continues to exist because it can visualize the progress of searches through the street network, providing some insight into the internals of the routing algorithms that are not otherwise visible. @@ -56,14 +56,16 @@ specified in terms of latitude and longitude coordinates. The debug frontend and Many different production OTP frontends exist. Any number of agencies and consultancies may have built new frontends, whether in Javascript or as native mobile apps, without the OpenTripPlanner development team even being aware of them. That said, there are two main Javascript-based web user interfaces that are generally recommended by members of the OTP development team who also work on professional, public-facing OpenTripPlanner deployments: + - The [Digitransit UI](https://github.com/HSLdevcom/digitransit-ui), part of the Finnish Digitransit project. - The [OpenTripPlanner React UI](https://github.com/opentripplanner/otp-react-redux), developed and maintained by [Arcadis IBI](https://www.ibigroup.com)'s [transit routing team](https://www.ibigroup.com/ibi-products/transit-routing/). **Digitransit** is an open-source public transportation project, originally created in Finland to replace existing nationwide and regional journey planning solutions in 2014. Digitransit has since been used around the world in other projects, for example in Germany. It is a joint project of Helsinki Regional Transport Authority (HSL), Fintraffic, and Waltti Solutions. **Arcadis IBI** has for several years actively developed, deployed, and maintained instances of the React-based OTP UI, systematically contributing their improvements back to the original repositories under the OpenTripPlanner organization: -- https://github.com/opentripplanner/otp-ui -- https://github.com/opentripplanner/otp-react-redux + +- [https://github.com/opentripplanner/otp-ui](https://github.com/opentripplanner/otp-ui) +- [https://github.com/opentripplanner/otp-react-redux](https://github.com/opentripplanner/otp-react-redux) Both major frontend projects mentioned above support internationalization and have several translations already available. diff --git a/doc/user/Getting-OTP.md b/doc/user/Getting-OTP.md index a71bc02b5d8..ea0bac0df90 100644 --- a/doc/user/Getting-OTP.md +++ b/doc/user/Getting-OTP.md @@ -9,8 +9,8 @@ the [release pages on GitHub](https://github.com/opentripplanner/OpenTripPlanner or [the OTP directory at Maven Central](https://repo1.maven.org/maven2/org/opentripplanner/otp/), navigate to the highest version number, and download the file whose name ends with `shaded.jar`. -Note that version numbers like `v2.1.0-rc1` or `v2.5.0-SNAPSHOT` refer to development builds _ -before_ the release version `v2.5.0`. The existence of a build `vX.Y.Z-SNAPSHOT` does not mean +Note that version numbers like `v2.1.0-rc1` or `v2.6.0-SNAPSHOT` refer to development builds _ +before_ the release version `v2.6.0`. The existence of a build `vX.Y.Z-SNAPSHOT` does not mean that `vX.Y.Z` has been released yet. We use the [Github Actions CI system](https://github.com/opentripplanner/OpenTripPlanner/actions) to @@ -64,13 +64,13 @@ OTP. If all goes well you should see a success message like the following: [INFO] ------------------------------------------------------------------------ ``` -This build process should produce a JAR file called `otp-x.y.z-shaded.jar` in the `target/` -directory which contains all the compiled OTP classes and their dependencies (the external libraries -they use). The shell script called 'otp' in the root of the cloned repository will start the main -class of that JAR file under a Java virtual machine, so after the Maven build completes you should -be able to run `./otp --help` and see an OTP help message including command line options. Due to the -way Maven works, this script is not executable by default, so you will need to do `chmod u+x ./otp` -before you run it to mark it as executable. +This build process should produce a JAR file called `otp-x.y.z-shaded.jar` in the +`shaded-jar/target/` directory which contains all the compiled OTP classes and their dependencies +(the external libraries they use). The shell script called 'otp' in the root of the cloned repository +will start the main class of that JAR file under a Java virtual machine, so after the Maven build +completes you should be able to run `./otp --help` and see an OTP help message including command line +options. Due to the way Maven works, this script is not executable by default, so you will need to do +`chmod u+x ./otp` before you run it to mark it as executable. The words "clean package" are the build steps you want to run. You're telling maven to clean up any extraneous junk in the directory, then perform all the build steps, including compilation, up to and @@ -87,7 +87,7 @@ For example, you could do the following: ```bash cd OpenTripPlanner -git checkout v2.5.0 +git checkout v2.6.0 git clean -df mvn clean package -DskipTests ``` @@ -110,8 +110,8 @@ file) to the Maven repository, from which it can be automatically included in ot This repository is machine-readable (by Maven or other build systems) and also provides human readable directory listings via HTTP. You can fetch an OTP JAR from this repository by constructing -the proper URL for the release you want. For example, release 2.5.0 will be found -at `https://repo1.maven.org/maven2/org/opentripplanner/otp/2.5.0/otp-2.5.0-shaded.jar`. +the proper URL for the release you want. For example, release 2.6.0 will be found +at `https://repo1.maven.org/maven2/org/opentripplanner/otp/2.6.0/otp-2.6.0-shaded.jar`. To make use of OTP in another Maven project, you must specify it as a dependency in that project's `pom.xml`: @@ -120,6 +120,6 @@ project's `pom.xml`: org.opentripplanner otp - 2.5.0 + 2.6.0 ``` diff --git a/doc/user/IslandPruning.md b/doc/user/IslandPruning.md index c33d31dd010..6570d36041a 100644 --- a/doc/user/IslandPruning.md +++ b/doc/user/IslandPruning.md @@ -38,12 +38,12 @@ to have the same access properties. ![](images/nothruisland.png) *Some regular (gray colored) streets are blocked behind access restricted (red colored) connections. Walk routing to them fails because it would be considered as pass through traffic. -The image on the right shows that pruning added walk nothrough restricition to those streets, and routing works again.* +The image on the right shows that pruning added walk nothrough restriction to those streets, and routing works again.* ## Pruning algorithm Pruning analyses the three traverse modes - walk, bike and car - separately. For example, a resting area by a motorway may include some walking paths, but the only way to get there is -to use car. Therefore, it represents a disconnected 'island' when considering the walk mode. Pruning does not erase disconnected graph geometry as long as it +to use a car. Therefore, it represents a disconnected 'island' when considering the walk mode. Pruning does not erase disconnected graph geometry as long as it can be reached using any of the traverse modes. Instead, pruning removes traversal permission for each disconnected mode from the island. Pruning uses four parameters and some heuristics to decide if a disconnected sub graph is a real island to be retained, or a harmful data error: diff --git a/doc/user/Localization.md b/doc/user/Localization.md deleted file mode 100644 index 75d21e96ce4..00000000000 --- a/doc/user/Localization.md +++ /dev/null @@ -1,229 +0,0 @@ -# Localization - -NOTE: This documentation pertains to the client included in the main OTP repository. THIS BUILT-IN -OTP CLIENT IS PROVIDED FOR TEST AND DEBUGGING PURPOSES. IT IS NOT MEANT FOR PRODUCTION USE. - -This page contains instructions for both developers and translators on how to make the OTP interface -usable by people who speak different languages. Developers will need to take certain steps to mark -translatable strings within the source code. Translators will need to edit specific files within the -project to create or revise the translation for their language. - -In OTP we use gettext for localization, for the following reasons: - -- [Plural suport](http://pology.nedohodnik.net/doc/user/en_US/ch-poformat.html#sec-poplurals) -- [Context support](http://pology.nedohodnik.net/doc/user/en_US/ch-poformat.html#sec-poautocmnt) -- Automatic extraction of translatable strings from source code -- [Translator comments](http://pology.nedohodnik.net/doc/user/en_US/ch-poformat.html#sec-poautocmnt) - support -- Source references (we can see where each translated string is used in the source code) - -In the Javascript UI the [i18next](http://i18next.com) library is used. - -Three types of files are used in the OTP localization process: - -- The `.pot` file is the message template. It is a starting point for creating new `.po` files. -- `.po` files are created and edited by translators based on the `.pot` file. -- `.json` files are generated from the `.po` files for each language. -- `.js` files are localization configuration files which specify units and time/date formats. - -Only the `.po` and `.js` files are directly edited. The `.pot` file is created from an automated -analysis of annotated source code. The `.json` files are also automatically generated as an easy way -for the Javascript UI to consume the contents of the `.po` files. - -All translation files are in the directory `/src/client/i18n`. - -## For Software Developers: Adding New Strings - -When you add a string to Javascript source that will be seen by the end user, wherever that string -is referenced you should surround it with a call to a special function. The name of the function -depends on what kind of string it is: - -- basic string: `_tr('string', parameters)` -- basic string with context: `ngettext('context', 'string')` -- string with plural: `ngettext('singular', 'plural', quantity)` -- string with plural and context: `npgettext('context', 'singular', 'plural', quantity)` - -For more detail, -see [Sprintf parameters](http://www.diveintojavascript.com/projects/javascript-sprintf). - -A "context" is any string (preferably short and without whitespace) that is used to disambiguate the -translation of the main string. It is used when developers get input from translators that some -string should be translated in different ways in different parts of the program. Each of those -distinct places will be assigned a different context string. - -When you add strings to the source code, if you think that translators might not understand how the -string is used or what parameters it requires, add translator comments like this: - -```javascript -//TRANSLATORS: Start: location at [time date] (Used in print itinerary -//when do you start your trip) -html += '

    ' + _tr('Start: %s at %s', this.getStartLocationStr(), this.getStartTimeStr()) + '

    '; -``` - -Translator comments must always start with `TRANSLATORS:` and must be in the line immediately before -translated string. Otherwise they won't be extracted together with the string. - -### Examples: - -#### Basic translated string - -```javascript -//TRANSLATORS: Board Public transit route name (agency name -//Stop ID ) start time -html += '
  • ' + _tr('Board') + ': ' + leg.from.name + ' (' + leg.from.stopId.agencyId + ' Stop ID #' + - -//With named sprintf parameters (our preferred option) - -//TRANSLATORS: Start: location at [time date] (Used in print itinerary -//when do you start your trip) -html += '

    ' + _tr('Start: %(location)s at %(time_date)s', { - 'location': this.getStartLocationStr(), - 'time_date': this.getStartTimeStr() -}) + '

    '; - -//With positional sprintf parameters (to be avoided because word order changes between languages) -html += '

    ' + _tr('End: %1$s at %2$s', this.getEndLocationStr(), this.getEndTimeStr()) + '

    '; -``` - -#### Normal string with context - -```javascript - if (leg.headsign) html += pgettext("bus_direction", " to ") + leg.headsign; - -//same string could be different translation -//TRANSLATORS: [distance] to [name of destination] -html += " " + otp.util.Itin.distanceString(leg.distance) + pgettext("direction", " to ") + leg.to.name; - -``` - -#### Plural strings - -```javascript -//TRANSLATORS: widget title -this.setTitle(ngettext("%d Itinerary Returned", "%d Itineraries Returned", this.itineraries.length)); -``` - -If you add new strings to the source code, it is good practice to also update the translation -template and the translations but it is not mandatory (these can be updated later). It is also -recommended to include "i18n string change" in the commit message. - -Updating translations ---------------------- -Translations are updated with the help of [Babel](http://babel.pocoo.org/) -and [i18next-conv](https://github.com/jamuhl/i18next-gettext-converter) (xgettext doesn't yet have -great Javascript support). - -Babel is used to extract strings from the Javascript source code into the shared `.POT` translation -template, and also for updating the existing `.PO` language translations when new strings are -introduced in the template. i18next-conv is used to convert the `.PO` translation files for the -individual languages to `.json` files which are used by the Javascript translation library. - -### Installing Babel - -You can install it from your operating system's package repository (if available) or you can -use [virtualenv](http://simononsoftware.com/virtualenv-tutorial/). - -1. Install virtualenv (This depends on your operating system) -2. Create virtualenv with name .venv in directory where src and other files resides (Root - OpenTripPlanner directory). `virtualenv2 .venv`(python 2) or `python3 -m venv .venv` (python 3) -3. Use virtualenv `source .venv/bin/activate` -4. Install babel `pip install babel` - -If you didn't install babel from virtualenv in root OpenTripPlanner directory you have to add path -to babel in Makefile. change `PYBABEL` variable to path to pybabel. - -### Installing i18next-conv - -i18next-conv requires [nodejs](http://nodejs.org/). - -Once you have NodeJS installed, use `npm install i18next-conv` to install i18next-conv in the same -directory where you created virtualenv. - -### Updating the `.pot` Template - -In the root of the OTP repo, run `make`. The commands in the `Makefile` will extract the -translatable strings from the Javascript files and update the translation template `messages.pot`, -as well as the `.po` translation files for all the different languages. - -Once this is done, you can translate the new strings in the `.po` files. After saving the -updated `.po` file, run -`make update_js` to transform to PO files into `.json`, which is used at runtime by the Javascript -translation library. After you rebuild OTP, all new strings should be visible in the UI. - -## For Translators: Creating New Translations - -The following can get a bit technical. If you want to do a translation but don't want to / know how -to install all this software, post to the [Gitter chat room](https://gitter.im/opentripplanner/OpenTripPlanner) -stating what language you want to translate, and someone will make you a corresponding `.po` file. - -### Creating a New Translation File - -New `.po` files are created from the `.pot` template with the help of `msginit`, which is run like -this: -`msginit init -l -i messages.pot -o .po`, where `` is a culture code. New `.po`files -can also be created with the help of `Poedit`. All translation files should be placed in the -directory `/src/client/i18n`. - -Please use the ISO language code as the culture code (e.g. `fr.po` for French). We will append -country codes in the following limited circumstances: - -- British versus US English (`en_GB.po` and `en_US.po`) -- Brazilian Portuguese `pt_BR.po`, as opposed to `pt.po` for European Portuguese -- Chinese: `zh_TW.po` for traditional characters as used in e.g. Taiwan and Hong Kong, - and `zh_CN.po` for simplified characters as used in mainland China, Singapore, etc. - -These conventions are based on -the [Launchpad Translation](https://help.launchpad.net/Translations/YourProject/ImportingTranslations) -page. - -In Linux you can see the culture codes for all the locales you have installed with the -command `locale -a`. A list of culture codes is also -availible [here](http://download1.parallels.com/SiteBuilder/Windows/docs/3.2/en_US/sitebulder-3.2-win-sdk-localization-pack-creation-guide/30801.htm) -. - -### Performing the Translation - -#### Configuration - -Copy the locale configuration script `English.js` from `/src/client/js/otp/locale` -to `YourLanguage.js` and customize it to your language. Change the name, units, locale_short and -datepicker_locale_short values. Translate infoWidgets and localize the time/date formats. - -Then take the following steps: - -- Add the culture code to the `LANGS` variable in the Makefile` -- Add the new `YourLanguage.js` to the locales variable in `/src/client/js/otp/config.js` -- Add a new datepicker translation to `/src/client/js/lib/jquery-ui/i18n` -- Load the new datepicker translation and `YourLanguage.js` in `/src/client/index.html` - -#### Translating Strings - -For translating the strings themselves, you can use any program that supports gettext files. You can -in theory use any text editor, but programs or plugins purpose-built for translating are -recommended. Most of them support checking parameter correctness, translation memory, web -translating services etc. to make the task easier. - -Here are some such programs (all free and open source): - -- [Poedit](http://poedit.net/) For Linux, Windows, and Mac. Use a version newer then 1.5. This is - the recommended choice for getting started with localization. It supports translation memory and - file context. -- [Web Poedit](https://localise.biz/free/poedit) Usable from within a web browser, you don't have to - install or register -- [Gted](http://www.gted.org/) A plugin for the Eclipse IDE. -- [Lokalize](http://userbase.kde.org/Lokalize) Runs under KDE on Linux, has some Windows support. - Supports translation memory and file context. -- [Virtaal](http://virtaal.translatehouse.org/index.html) For Linux, Windows, and beta for Mac. - Supports Google and Microsoft web translation and other translation memory services. - -All these programs support setting a string to "fuzzy", marking that it needs review etc. in case -you translate something but aren't sure of it's correctness. Sometimes those flags are set -automatically if the original string was changed and translators must check if the translation is -still correct. - -#### Caveats - -Be careful when translating that the translated strings have the same format as the original. If -spaces appear at the start or end of the strings, they must also appear in the translation. The -order of unnamed (positional) parameters may change depending on the target language. You can also -leave parameter out of the translation if it is irrelevant in the target language. diff --git a/doc/user/Netex-Norway.md b/doc/user/Netex-Norway.md deleted file mode 100644 index 0a447237592..00000000000 --- a/doc/user/Netex-Norway.md +++ /dev/null @@ -1,148 +0,0 @@ -# Using European Data Standards - -## Building with Netex Data - -One important new feature of OTP2 is the ability to -load [Netex](https://en.wikipedia.org/wiki/NeTEx) data. Netex is a -European [specification for transit data exchange](http://netex-cen.eu), comparable in purpose to -GTFS but broader in scope. An EU directive aims to have all EU countries sharing Netex data by the -end of 2019. - -Different countries are currently using different incompatible "profiles" of Netex, but an effort is -underway to converge on a single European standard profile. This is based in large part on the -Norwegian profile, and Norway's national passenger information and ticketing agency Entur has -contributed the OTP2 Netex loading code. Therefore if you'd like to try loading Netex data, Norway -is a good place to start. - -The Norwegian Netex data can be downloaded from -the [Entur developer pages](https://developer.entur.org/pages-intro-files). There is a column of -Netex download links partway down the page, and the first row is for all of Norway. - -Full OSM data for Norway can be downloaded from -the [Geofabrik Norway downloads page](http://download.geofabrik.de/europe/norway.html). Get -the `norway-latest.osm.pbf` file, which can then be filtered to remove buildings and other unused -data before loading into OTP using a command like the one below. This filtering step can be skipped -if you don't have the necessary Osmium tools installed. - -`osmium tags-filter norway-latest.osm.pbf w/highway w/public_transport=platform w/railway=platform w/park_ride=yes r/type=restriction -o norway-filtered.osm.pbf -f pbf,add_metadata=false,pbf_dense_nodes=true` - -Be sure to move the original unfiltered file out of your graph inputs directory (or rename it with a -suffix like `norway-latest.osm.pbf.ignore`) otherwise OTP2 will try to include both the filtered and -unfiltered OSM data in your graph. - -The `build-config.json` for a Norwegian graph using Netex data looks like this: - -```json -{ - "areaVisibility": true, - "platformEntriesLinking": true, - "islandWithoutStopsMaxSize": 5, - "islandWithStopsMaxSize": 5, - "dataImportReport": true, - "netexDefaults" : { - "moduleFilePattern" : ".*-netex\\.zip", - "sharedFilePattern": "_stops.xml", - "sharedGroupFilePattern": "_(\\w{3})(_flexible)?_shared_data.xml", - "groupFilePattern": "(\\w{3})_.*\\.xml", - "feedId": "EN", - "ferryIdsNotAllowedForBicycle": [ - "NYC:Line:1", - "NYC:Line:012fc5c4-131b-4dfc-8160-4e49136e531a", - "NYC:Line:8bfef12a-ac98-4376-8a2a-eb5a336d107b" - ] - }, - "osm": [ - { - "source": "norway-latest.osm.pbf", - "osmTagMapping": "norway", - "timeZone": "Europe/Oslo" - } - ] -} -``` - -Note the special section specifying how to find Netex XML files within the single ZIP archive you -downloaded. - -Once you have the graph inputs (the OSM PBF file, the Netex ZIP file, and the `build-config.json`) -saved together in a directory, you can instruct OTP2 to build a graph from these inputs: - -`java -Xmx10G otp2.jar --build --save /path/to/graph/inputs` - -This should produce a file `graph.obj` in the same directory as your inputs. Building this Norway -graph takes approximately 16 minutes (without elevation data, as configured above), and can be done -within 10GB of heap memory (JVM switch `-Xmx10G`). Increasing that to 12 or 14GB might speed it up a -bit if you have the space. The Graph file it produces is just under 600MB. The server will take -about 30 seconds to load this Graph and start up, and will consume about 4GB of heap memory under -light use. - -You can then start up an OTP server with a command like this: - -`java -Xmx6G otp2.jar --load /path/to/graph` - -Once the server is started up, go to `http://localhost:8080` in a browser to try out your server -using OTP's built in testing web client. Try some long trips like Oslo to Bergen and see if you can -get long distance trains and flights as alternatives. You might need to increase the walking limit -above its very low default value. - -## Adding SIRI Real-time Data - -Another important feature in OTP2 is the ability to -use [SIRI real-time data](https://en.wikipedia.org/wiki/Service_Interface_for_Real_Time_Information). -Within the EU data standards, SIRI is analogous to GTFS-RT: a way to apply real-time updates on top -of schedule data. While technically a distinct specification from Netex, both Netex and SIRI use the -Transmodel vocabulary, allowing SIRI messages to reference entities in Netex schedule data. Like -GTFS-RT, SIRI is consumed by OTP2 using "graph updaters" which are configured in -the `router-config.json` file, which is placed in the same directory as the `graph.obj` file and -loaded at server startup. - -```json -{ - "updaters": [ - { - "type": "siri-sx-updater", - "frequency": "1m", - "url": "https://api.example.com/siri", - "feedId": "siri-sx", - "blockReadinessUntilInitialized": true - }, - { - "type": "siri-et-updater", - "frequency": "20s", - "previewIntervalMinutes": 180, - "url": "https://api.example.com/siri", - "feedId": "siri-et", - "blockReadinessUntilInitialized": true - }, - { - "type": "siri-vm-updater", - "frequency": "1m", - "url": "https://api.example.com/siri", - "feedId": "siri-vm", - "blockReadinessUntilInitialized": true - }, - { - "type": "raptor-transit-layer", - "updateIntervalSeconds": 20 - } - ] -} -``` - -The first three updaters fetch three different kinds of SIRI data: - -- Situation Exchange (SX, text notices analogous to GTFS-RT Alerts) -- Estimated Timetable (ET, predicted arrival times analogous to GTFS-RT TripUpdates) -- Vehicle Monitoring (VM, location and status of vehicles analogous to GTFS-RT VehiclePositions) - -These updaters can handle differential updates, but they use a polling approach rather than the -message-oriented streaming approach of the GTFS-RT Websocket updater. The server keeps track of -clients, sending only the things that have changed since the last polling operation. - -Note that between these SIRI updaters and the GTFS-RT Websocket updater, we now have both polling -and streaming examples of GTFS-RT "incrementality" semantics, so should be able to finalize that -part of the specification. - -The final updater regularly performs a copy of the real-time data into a format suitable for use by -OTP2's new Raptor router. Without this updater the real-time data will be received and cataloged, but -not visible to the router. diff --git a/doc/user/Netex-Tutorial.md b/doc/user/Netex-Tutorial.md new file mode 100644 index 00000000000..3021f9c9674 --- /dev/null +++ b/doc/user/Netex-Tutorial.md @@ -0,0 +1,133 @@ +# NeTEx & SIRI tutorial + +One important new feature of OTP2 is the ability to +load [NeTEx](https://en.wikipedia.org/wiki/NeTEx) and [SIRI](https://en.wikipedia.org/wiki/Service_Interface_for_Real_Time_Information) +data. NeTEx is a European [specification for transit data exchange](http://netex-cen.eu), comparable in purpose to +GTFS but broader in scope. + +First of all, you need to download a [bundled jar of OTP](Getting-OTP.md). + +Secondly, you will use the [Norwegian NeTEx file](https://developer.entur.org/pages-intro-files) as +well as the [Norwegian OSM data](http://download.geofabrik.de/europe/norway.html), but OTP can download the NeTEx one for you. + +## Configuring the build + +Create a working directory and place the OTP jar file in it and call it `otp.jar.` + +Since we download the OSM data from a free source, we don't want to put undue stress on the server. +Therefore we download it before building the graph, not during. + +``` +curl https://download.geofabrik.de/europe/norway-latest.osm.pbf -o norway.osm.pbf +``` + +Now create a file called `build-config.json` in the same folder and fill it with the following +content: + + + + +```JSON +// build-config.json +{ + "transitFeeds" : [ + { + "type" : "netex", + "feedId" : "NO", + "source" : "https://storage.googleapis.com/marduk-production/outbound/netex/rb_norway-aggregated-netex.zip", + "sharedFilePattern" : "_stops.xml", + "sharedGroupFilePattern" : "_(\\w{3})(_flexible)?_shared_data.xml", + "groupFilePattern" : "(\\w{3})_.*\\.xml" + } + ], + "osm" : [ + { + "source" : "norway.osm.pbf", + "osmTagMapping" : "norway", + "timeZone" : "Europe/Oslo" + } + ], + "osmCacheDataInMem" : true +} +``` + + + +Note the special section specifying how to find NeTEx XML files within the single ZIP archive that +OTP downloads. + +Now you can instruct OTP to build a graph from this configuration file: + +`java -Xmx16G -jar otp.jar --build --save .` + +This should produce a file `graph.obj` in the same directory as your `build-config.json`. + +Building the Norway graph requires downloading about 250MB of input data so stay patient at the beginning +particularly on a slow internet connection. +The actual build takes approximately 10 minutes (without elevation data, as is configured above), +and can be done within 16GB of heap memory (JVM switch `-Xmx16G`). The Graph file it produces is +about 1.1 GB. The server will take about 30 seconds to load this graph and start up, and will +consume about 6GB of heap memory under light use. + +You can then start up an OTP server with a command like this: + +`java -Xmx6G -jar otp.jar --load .` + +Once the server is started up, go to `http://localhost:8080` in a browser to try out your server +using OTP's built in testing web client. Try some long trips like Oslo to Bergen and see if you can +get long distance trains and flights as alternatives. You might need to increase the walking limit +above its very low default value. + +## Adding SIRI real time Data + +Another important feature in OTP version 2 is the ability to +use [SIRI real-time data](https://en.wikipedia.org/wiki/Service_Interface_for_Real_Time_Information). +Within the EU data standards, SIRI is analogous to GTFS-RT: a way to apply real-time updates on top +of schedule data. While technically a distinct specification from NeTEx, both NeTEx and SIRI use the +Transmodel vocabulary, allowing SIRI messages to reference entities in NeTEx schedule data. Like +GTFS-RT, SIRI is consumed by OTP2 using "graph updaters" which are configured in +the `router-config.json` file, which is placed in the same directory as the `graph.obj` file and +loaded at server startup. + + + + +```JSON +// router-config.json +{ + "updaters" : [ + { + "type" : "siri-sx-updater", + "frequency" : "1m", + "url" : "https://api.entur.io/realtime/v1/services", + "feedId" : "NO", + "blockReadinessUntilInitialized" : true + }, + { + "type" : "siri-et-updater", + "frequency" : "1m", + "previewInterval" : "1h30m", + "url" : "https://api.entur.io/realtime/v1/services", + "feedId" : "NO", + "blockReadinessUntilInitialized" : true + } + ] +} +``` + + + +After saving the file in the working directory, restart OTP. + +The updaters fetch two different kinds of SIRI data: + +- Situation Exchange (SX, text notices analogous to GTFS-RT Alerts) +- Estimated Timetable (ET, predicted arrival times analogous to GTFS-RT TripUpdates) + +These updaters can handle differential updates, but they use a polling approach rather than the +message-oriented streaming approach of the GTFS-RT Websocket updater. The server keeps track of +clients, sending only the things that have changed since the last polling operation. + +Note that between these SIRI updaters and the GTFS-RT Websocket updater, we now have both polling +and streaming examples of GTFS-RT "incrementality" semantics, so should be able to finalize that +part of the specification. \ No newline at end of file diff --git a/doc/user/RouteRequest.md b/doc/user/RouteRequest.md index 674ab238888..ea3d0d12c74 100644 --- a/doc/user/RouteRequest.md +++ b/doc/user/RouteRequest.md @@ -2,7 +2,7 @@ NOTE! Part of this document is generated. Make sure you edit the template, not the generated doc. - Template directory is: /doc/templates - - Generated directory is: /docs + - Generated directory is: /doc/user --> # Route Request @@ -13,171 +13,172 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe -| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | -|--------------------------------------------------------------------------------------------------------------|:----------------------:|------------------------------------------------------------------------------------------------------------------------------------------------|:----------:|------------------|:-----:| -| [alightSlack](#rd_alightSlack) | `duration` | The time safety margin when alighting from a vehicle. | *Optional* | `"PT0S"` | 2.0 | -| arriveBy | `boolean` | Whether the trip should depart or arrive at the specified date and time. | *Optional* | `false` | 2.0 | -| [boardSlack](#rd_boardSlack) | `duration` | The time safety margin when boarding a vehicle. | *Optional* | `"PT0S"` | 2.0 | -| [drivingDirection](#rd_drivingDirection) | `enum` | The driving direction to use in the intersection traversal calculation | *Optional* | `"right"` | 2.2 | -| elevatorBoardCost | `integer` | What is the cost of boarding a elevator? | *Optional* | `90` | 2.0 | -| elevatorBoardTime | `integer` | How long does it take to get on an elevator, on average. | *Optional* | `90` | 2.0 | -| elevatorHopCost | `integer` | What is the cost of travelling one floor on an elevator? | *Optional* | `20` | 2.0 | -| elevatorHopTime | `integer` | How long does it take to advance one floor on an elevator? | *Optional* | `20` | 2.0 | -| geoidElevation | `boolean` | If true, the Graph's ellipsoidToGeoidDifference is applied to all elevations returned by this query. | *Optional* | `false` | 2.0 | -| ignoreRealtimeUpdates | `boolean` | When true, real-time updates are ignored during this search. | *Optional* | `false` | 2.0 | -| [intersectionTraversalModel](#rd_intersectionTraversalModel) | `enum` | The model that computes the costs of turns. | *Optional* | `"simple"` | 2.2 | -| locale | `locale` | TODO | *Optional* | `"en_US"` | 2.0 | -| [maxDirectStreetDuration](#rd_maxDirectStreetDuration) | `duration` | This is the maximum duration for a direct street search for each mode. | *Optional* | `"PT4H"` | 2.1 | -| [maxJourneyDuration](#rd_maxJourneyDuration) | `duration` | The expected maximum time a journey can last across all possible journeys for the current deployment. | *Optional* | `"PT24H"` | 2.1 | -| modes | `string` | The set of access/egress/direct/transit modes to be used for the route search. | *Optional* | `"TRANSIT,WALK"` | 2.0 | -| nonpreferredTransferPenalty | `integer` | Penalty (in seconds) for using a non-preferred transfer. | *Optional* | `180` | 2.0 | -| numItineraries | `integer` | The maximum number of itineraries to return. | *Optional* | `50` | 2.0 | -| [otherThanPreferredRoutesPenalty](#rd_otherThanPreferredRoutesPenalty) | `integer` | Penalty added for using every route that is not preferred if user set any route as preferred. | *Optional* | `300` | 2.0 | -| [relaxTransitGroupPriority](#rd_relaxTransitGroupPriority) | `string` | The relax function for transit-group-priority | *Optional* | `"0s + 1.00 t"` | 2.5 | -| [relaxTransitSearchGeneralizedCostAtDestination](#rd_relaxTransitSearchGeneralizedCostAtDestination) | `double` | Whether non-optimal transit paths at the destination should be returned | *Optional* | | 2.3 | -| [searchWindow](#rd_searchWindow) | `duration` | The duration of the search-window. | *Optional* | | 2.0 | -| [streetRoutingTimeout](#rd_streetRoutingTimeout) | `duration` | The maximum time a street routing request is allowed to take before returning the results. | *Optional* | `"PT5S"` | 2.2 | -| [transferPenalty](#rd_transferPenalty) | `integer` | An additional penalty added to boardings after the first. | *Optional* | `0` | 2.0 | -| [transferSlack](#rd_transferSlack) | `duration` | The extra time needed to make a safe transfer. | *Optional* | `"PT2M"` | 2.0 | -| turnReluctance | `double` | Multiplicative factor on expected turning time. | *Optional* | `1.0` | 2.0 | -| [unpreferredCost](#rd_unpreferredCost) | `cost-linear-function` | A cost function used to calculate penalty for an unpreferred route. | *Optional* | `"0s + 1.00 t"` | 2.2 | -| waitReluctance | `double` | How much worse is waiting for a transit vehicle than being on a transit vehicle, as a multiplier. | *Optional* | `1.0` | 2.0 | -| accessEgress | `object` | Parameters for access and egress routing. | *Optional* | | 2.4 | -|    [maxDuration](#rd_accessEgress_maxDuration) | `duration` | This is the maximum duration for access/egress for street searches. | *Optional* | `"PT45M"` | 2.1 | -|    [maxStopCount](#rd_accessEgress_maxStopCount) | `integer` | Maximal number of stops collected in access/egress routing | *Optional* | `500` | 2.4 | -|    [maxDurationForMode](#rd_accessEgress_maxDurationForMode) | `enum map of duration` | Limit access/egress per street mode. | *Optional* | | 2.1 | -|    [penalty](#rd_accessEgress_penalty) | `enum map of object` | Penalty for access/egress by street mode. | *Optional* | | 2.4 | -|       FLEXIBLE | `object` | NA | *Optional* | | 2.4 | -|          costFactor | `double` | A factor multiplied with the time-penalty to get the cost-penalty. | *Optional* | `0.0` | 2.4 | -|          timePenalty | `time-penalty` | Penalty added to the time of a path/leg. | *Optional* | `"0s + 0.00 t"` | 2.4 | -| [alightSlackForMode](#rd_alightSlackForMode) | `enum map of duration` | How much extra time should be given when alighting a vehicle for each given mode. | *Optional* | | 2.0 | -| bicycle | `object` | Bicycle preferences. | *Optional* | | 2.5 | -|    [boardCost](#rd_bicycle_boardCost) | `integer` | Prevents unnecessary transfers by adding a cost for boarding a transit vehicle. | *Optional* | `600` | 2.0 | -|    [optimization](#rd_bicycle_optimization) | `enum` | The set of characteristics that the user wants to optimize for. | *Optional* | `"safe-streets"` | 2.0 | -|    reluctance | `double` | A multiplier for how bad cycling is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | -|    speed | `double` | Max bicycle speed along streets, in meters per second | *Optional* | `5.0` | 2.0 | -|    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | -|       cost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | -|       time | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | -|       [unpreferredVehicleParkingTagCost](#rd_bicycle_parking_unpreferredVehicleParkingTagCost) | `integer` | What cost to add if a parking facility doesn't contain a preferred tag. | *Optional* | `300` | 2.3 | -|       [bannedVehicleParkingTags](#rd_bicycle_parking_bannedVehicleParkingTags) | `string[]` | Tags with which a vehicle parking will not be used. If empty, no tags are banned. | *Optional* | | 2.1 | -|       [preferredVehicleParkingTags](#rd_bicycle_parking_preferredVehicleParkingTags) | `string[]` | Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. | *Optional* | | 2.3 | -|       [requiredVehicleParkingTags](#rd_bicycle_parking_requiredVehicleParkingTags) | `string[]` | Tags without which a vehicle parking will not be used. If empty, no tags are required. | *Optional* | | 2.1 | -|    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | -|       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | -|       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | -|       dropOffTime | `duration` | Time to drop-off a rented vehicle. | *Optional* | `"PT30S"` | 2.0 | -|       keepingAtDestinationCost | `integer` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0` | 2.2 | -|       pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | -|       pickupTime | `duration` | Time to rent a vehicle. | *Optional* | `"PT1M"` | 2.0 | -|       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | -|       [allowedNetworks](#rd_bicycle_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | -|       [bannedNetworks](#rd_bicycle_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | -|    [triangle](#rd_bicycle_triangle) | `object` | Triangle optimization criteria. | *Optional* | | 2.5 | -|       flatness | `double` | Relative importance of flat terrain (range 0-1). | *Optional* | `0.0` | 2.0 | -|       [safety](#rd_bicycle_triangle_safety) | `double` | Relative importance of safety (range 0-1). | *Optional* | `0.0` | 2.0 | -|       time | `double` | Relative importance of duration of travel (range 0-1). | *Optional* | `0.0` | 2.0 | -|    walk | `object` | Preferences for walking a vehicle. | *Optional* | | 2.5 | -|       [mountDismountCost](#rd_bicycle_walk_mountDismountCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | -|       [mountDismountTime](#rd_bicycle_walk_mountDismountTime) | `duration` | The time it takes the user to hop on or off a vehicle. | *Optional* | `"PT0S"` | 2.0 | -|       reluctance | `double` | A multiplier for how bad walking with a vehicle is, compared to being in transit for equal lengths of time. | *Optional* | `5.0` | 2.1 | -|       speed | `double` | The user's vehicle walking speed in meters/second. Defaults to approximately 3 MPH. | *Optional* | `1.33` | 2.1 | -|       stairsReluctance | `double` | How bad is it to walk the vehicle up/down a flight of stairs compared to taking a detour. | *Optional* | `10.0` | 2.3 | -| [boardSlackForMode](#rd_boardSlackForMode) | `enum map of duration` | How much extra time should be given when boarding a vehicle for each given mode. | *Optional* | | 2.0 | -| car | `object` | Car preferences. | *Optional* | | 2.5 | -|    accelerationSpeed | `double` | The acceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | -|    decelerationSpeed | `double` | The deceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | -|    pickupCost | `integer` | Add a cost for car pickup changes when a pickup or drop off takes place | *Optional* | `120` | 2.1 | -|    pickupTime | `duration` | Add a time for car pickup changes when a pickup or drop off takes place | *Optional* | `"PT1M"` | 2.1 | -|    reluctance | `double` | A multiplier for how bad driving is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | -|    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | -|       cost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | -|       time | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | -|       [unpreferredVehicleParkingTagCost](#rd_car_parking_unpreferredVehicleParkingTagCost) | `integer` | What cost to add if a parking facility doesn't contain a preferred tag. | *Optional* | `300` | 2.3 | -|       [bannedVehicleParkingTags](#rd_car_parking_bannedVehicleParkingTags) | `string[]` | Tags with which a vehicle parking will not be used. If empty, no tags are banned. | *Optional* | | 2.1 | -|       [preferredVehicleParkingTags](#rd_car_parking_preferredVehicleParkingTags) | `string[]` | Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. | *Optional* | | 2.3 | -|       [requiredVehicleParkingTags](#rd_car_parking_requiredVehicleParkingTags) | `string[]` | Tags without which a vehicle parking will not be used. If empty, no tags are required. | *Optional* | | 2.1 | -|    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | -|       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | -|       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | -|       dropOffTime | `duration` | Time to drop-off a rented vehicle. | *Optional* | `"PT30S"` | 2.0 | -|       keepingAtDestinationCost | `integer` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0` | 2.2 | -|       pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | -|       pickupTime | `duration` | Time to rent a vehicle. | *Optional* | `"PT1M"` | 2.0 | -|       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | -|       [allowedNetworks](#rd_car_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | -|       [bannedNetworks](#rd_car_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | -| [itineraryFilters](#rd_itineraryFilters) | `object` | Configure itinerary filters that may modify itineraries, sort them, and filter away less preferable results. | *Optional* | | 2.0 | -|    [accessibilityScore](#rd_if_accessibilityScore) | `boolean` | An experimental feature contributed by IBI which adds a sandbox accessibility *score* between 0 and 1 for each leg and itinerary. | *Optional* | `false` | 2.2 | -|    [bikeRentalDistanceRatio](#rd_if_bikeRentalDistanceRatio) | `double` | Filter routes that consist of bike-rental and walking by the minimum fraction of the bike-rental leg using _distance_. | *Optional* | `0.0` | 2.1 | -|    [debug](#rd_if_debug) | `enum` | Enable this to attach a system notice to itineraries instead of removing them. This is very convenient when tuning the itinerary-filter-chain. | *Optional* | `"off"` | 2.0 | -|    [filterItinerariesWithSameFirstOrLastTrip](#rd_if_filterItinerariesWithSameFirstOrLastTrip) | `boolean` | If more than one itinerary begins or ends with same trip, filter out one of those itineraries so that only one remains. | *Optional* | `false` | 2.2 | -|    groupSimilarityKeepOne | `double` | Pick ONE itinerary from each group after putting itineraries that are 85% similar together. | *Optional* | `0.85` | 2.1 | -|    groupSimilarityKeepThree | `double` | Reduce the number of itineraries to three itineraries by reducing each group of itineraries grouped by 68% similarity. | *Optional* | `0.68` | 2.1 | -|    [groupedOtherThanSameLegsMaxCostMultiplier](#rd_if_groupedOtherThanSameLegsMaxCostMultiplier) | `double` | Filter grouped itineraries, where the non-grouped legs are more expensive than in the lowest cost one. | *Optional* | `2.0` | 2.1 | -|    [minBikeParkingDistance](#rd_if_minBikeParkingDistance) | `double` | Filter out bike park+ride results that have fewer meters of cycling than this value. | *Optional* | `0.0` | 2.3 | -|    [nonTransitGeneralizedCostLimit](#rd_if_nonTransitGeneralizedCostLimit) | `cost-linear-function` | The function define a max-limit for generalized-cost for non-transit itineraries. | *Optional* | `"1h + 2.0 t"` | 2.1 | -|    [parkAndRideDurationRatio](#rd_if_parkAndRideDurationRatio) | `double` | Filter P+R routes that consist of driving and walking by the minimum fraction of the driving using of _time_. | *Optional* | `0.0` | 2.1 | -|    [removeItinerariesWithSameRoutesAndStops](#rd_if_removeItinerariesWithSameRoutesAndStops) | `boolean` | Set to true if you want to list only the first itinerary which goes through the same stops and routes. | *Optional* | `false` | 2.2 | -|    [removeTransitWithHigherCostThanBestOnStreetOnly](#rd_if_removeTransitWithHigherCostThanBestOnStreetOnly) | `cost-linear-function` | Limit function for generalized-cost computed from street-only itineries applied to transit itineraries. | *Optional* | `"1m + 1.30 t"` | 2.4 | -|    [transitGeneralizedCostLimit](#rd_if_transitGeneralizedCostLimit) | `object` | A relative limit for the generalized-cost for transit itineraries. | *Optional* | | 2.1 | -|       [costLimitFunction](#rd_if_transitGeneralizedCostLimit_costLimitFunction) | `cost-linear-function` | The base function used by the filter. | *Optional* | `"15m + 1.50 t"` | 2.2 | -|       [intervalRelaxFactor](#rd_if_transitGeneralizedCostLimit_intervalRelaxFactor) | `double` | How much the filter should be relaxed for itineraries that do not overlap in time. | *Optional* | `0.4` | 2.2 | -| [maxDirectStreetDurationForMode](#rd_maxDirectStreetDurationForMode) | `enum map of duration` | Limit direct route duration per street mode. | *Optional* | | 2.2 | -| scooter | `object` | Scooter preferences. | *Optional* | | 2.5 | -|    [optimization](#rd_scooter_optimization) | `enum` | The set of characteristics that the user wants to optimize for. | *Optional* | `"safe-streets"` | 2.0 | -|    reluctance | `double` | A multiplier for how bad scooter travel is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | -|    speed | `double` | Max scooter speed along streets, in meters per second | *Optional* | `5.0` | 2.0 | -|    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | -|       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | -|       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | -|       dropOffTime | `duration` | Time to drop-off a rented vehicle. | *Optional* | `"PT30S"` | 2.0 | -|       keepingAtDestinationCost | `integer` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0` | 2.2 | -|       pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | -|       pickupTime | `duration` | Time to rent a vehicle. | *Optional* | `"PT1M"` | 2.0 | -|       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | -|       [allowedNetworks](#rd_scooter_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | -|       [bannedNetworks](#rd_scooter_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | -|    [triangle](#rd_scooter_triangle) | `object` | Triangle optimization criteria. | *Optional* | | 2.5 | -|       flatness | `double` | Relative importance of flat terrain (range 0-1). | *Optional* | `0.0` | 2.0 | -|       [safety](#rd_scooter_triangle_safety) | `double` | Relative importance of safety (range 0-1). | *Optional* | `0.0` | 2.0 | -|       time | `double` | Relative importance of duration of travel (range 0-1). | *Optional* | `0.0` | 2.0 | -| [transferOptimization](#rd_transferOptimization) | `object` | Optimize where a transfer between to trip happens. | *Optional* | | 2.1 | -|    [backTravelWaitTimeFactor](#rd_to_backTravelWaitTimeFactor) | `double` | To reduce back-travel we favor waiting, this reduces the cost of waiting. | *Optional* | `1.0` | 2.1 | -|    [extraStopBoardAlightCostsFactor](#rd_to_extraStopBoardAlightCostsFactor) | `double` | Add an extra board- and alight-cost for prioritized stops. | *Optional* | `0.0` | 2.1 | -|    [minSafeWaitTimeFactor](#rd_to_minSafeWaitTimeFactor) | `double` | Used to set a maximum wait-time cost, base on min-safe-transfer-time. | *Optional* | `5.0` | 2.1 | -|    [optimizeTransferWaitTime](#rd_to_optimizeTransferWaitTime) | `boolean` | This enables the transfer wait time optimization. | *Optional* | `true` | 2.1 | -| [transitGroupPriority](#rd_transitGroupPriority) | `object` | Group transit patterns and give each group a mutual advantage in the Raptor search. | *Optional* | | 2.5 | -| [transitReluctanceForMode](#rd_transitReluctanceForMode) | `enum map of double` | Transit reluctance for a given transport mode | *Optional* | | 2.1 | -| [unpreferred](#rd_unpreferred) | `object` | Parameters listing authorities or lines that preferably should not be used in trip patters. | *Optional* | | 2.2 | -|    [agencies](#rd_unpreferred_agencies) | `feed-scoped-id[]` | The ids of the agencies that incur an extra cost when being used. Format: `FeedId:AgencyId` | *Optional* | | 2.2 | -|    [routes](#rd_unpreferred_routes) | `feed-scoped-id[]` | The ids of the routes that incur an extra cost when being used. Format: `FeedId:RouteId` | *Optional* | | 2.2 | -| walk | `object` | Walking preferences. | *Optional* | | 2.5 | -|    boardCost | `integer` | Prevents unnecessary transfers by adding a cost for boarding a vehicle. This is the cost that is used when boarding while walking. | *Optional* | `600` | 2.0 | -|    escalatorReluctance | `double` | A multiplier for how bad being in an escalator is compared to being in transit for equal lengths of time | *Optional* | `1.5` | 2.4 | -|    [reluctance](#rd_walk_reluctance) | `double` | A multiplier for how bad walking is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | -|    [safetyFactor](#rd_walk_safetyFactor) | `double` | Factor for how much the walk safety is considered in routing. | *Optional* | `1.0` | 2.2 | -|    speed | `double` | The user's walking speed in meters/second. | *Optional* | `1.33` | 2.0 | -|    stairsReluctance | `double` | Used instead of walkReluctance for stairs. | *Optional* | `2.0` | 2.0 | -|    [stairsTimeFactor](#rd_walk_stairsTimeFactor) | `double` | How much more time does it take to walk a flight of stairs compared to walking a similar horizontal length. | *Optional* | `3.0` | 2.1 | -| wheelchairAccessibility | `object` | See [Wheelchair Accessibility](Accessibility.md) | *Optional* | | 2.2 | -|    enabled | `boolean` | Enable wheelchair accessibility. | *Optional* | `false` | 2.0 | -|    inaccessibleStreetReluctance | `double` | The factor to multiply the cost of traversing a street edge that is not wheelchair-accessible. | *Optional* | `25.0` | 2.2 | -|    [maxSlope](#rd_wheelchairAccessibility_maxSlope) | `double` | The maximum slope as a fraction of 1. | *Optional* | `0.083` | 2.0 | -|    [slopeExceededReluctance](#rd_wheelchairAccessibility_slopeExceededReluctance) | `double` | How much streets with high slope should be avoided. | *Optional* | `1.0` | 2.2 | -|    [stairsReluctance](#rd_wheelchairAccessibility_stairsReluctance) | `double` | How much stairs should be avoided. | *Optional* | `100.0` | 2.2 | -|    elevator | `object` | Configuration for when to use inaccessible elevators. | *Optional* | | 2.2 | -|       inaccessibleCost | `integer` | The cost to add when traversing an entity which is know to be inaccessible. | *Optional* | `3600` | 2.2 | -|       onlyConsiderAccessible | `boolean` | Whether to only use this entity if it is explicitly marked as wheelchair accessible. | *Optional* | `false` | 2.2 | -|       unknownCost | `integer` | The cost to add when traversing an entity with unknown accessibility information. | *Optional* | `20` | 2.2 | -|    stop | `object` | Configuration for when to use inaccessible stops. | *Optional* | | 2.2 | -|       inaccessibleCost | `integer` | The cost to add when traversing an entity which is know to be inaccessible. | *Optional* | `3600` | 2.2 | -|       onlyConsiderAccessible | `boolean` | Whether to only use this entity if it is explicitly marked as wheelchair accessible. | *Optional* | `true` | 2.2 | -|       unknownCost | `integer` | The cost to add when traversing an entity with unknown accessibility information. | *Optional* | `600` | 2.2 | -|    trip | `object` | Configuration for when to use inaccessible trips. | *Optional* | | 2.2 | -|       inaccessibleCost | `integer` | The cost to add when traversing an entity which is know to be inaccessible. | *Optional* | `3600` | 2.2 | -|       onlyConsiderAccessible | `boolean` | Whether to only use this entity if it is explicitly marked as wheelchair accessible. | *Optional* | `true` | 2.2 | -|       unknownCost | `integer` | The cost to add when traversing an entity with unknown accessibility information. | *Optional* | `600` | 2.2 | +| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | +|--------------------------------------------------------------------------------------------------------------|:----------------------:|----------------------------------------------------------------------------------------------------------------------------------------------------------|:----------:|------------------|:-----:| +| [alightSlack](#rd_alightSlack) | `duration` | The time safety margin when alighting from a vehicle. | *Optional* | `"PT0S"` | 2.0 | +| arriveBy | `boolean` | Whether the trip should depart or arrive at the specified date and time. | *Optional* | `false` | 2.0 | +| [boardSlack](#rd_boardSlack) | `duration` | The time safety margin when boarding a vehicle. | *Optional* | `"PT0S"` | 2.0 | +| [drivingDirection](#rd_drivingDirection) | `enum` | The driving direction to use in the intersection traversal calculation | *Optional* | `"right"` | 2.2 | +| elevatorBoardCost | `integer` | What is the cost of boarding a elevator? | *Optional* | `90` | 2.0 | +| elevatorBoardTime | `integer` | How long does it take to get on an elevator, on average. | *Optional* | `90` | 2.0 | +| elevatorHopCost | `integer` | What is the cost of travelling one floor on an elevator? | *Optional* | `20` | 2.0 | +| elevatorHopTime | `integer` | How long does it take to advance one floor on an elevator? | *Optional* | `20` | 2.0 | +| geoidElevation | `boolean` | If true, the Graph's ellipsoidToGeoidDifference is applied to all elevations returned by this query. | *Optional* | `false` | 2.0 | +| ignoreRealtimeUpdates | `boolean` | When true, real-time updates are ignored during this search. | *Optional* | `false` | 2.0 | +| [intersectionTraversalModel](#rd_intersectionTraversalModel) | `enum` | The model that computes the costs of turns. | *Optional* | `"simple"` | 2.2 | +| locale | `locale` | TODO | *Optional* | `"en_US"` | 2.0 | +| [maxDirectStreetDuration](#rd_maxDirectStreetDuration) | `duration` | This is the maximum duration for a direct street search for each mode. | *Optional* | `"PT4H"` | 2.1 | +| [maxJourneyDuration](#rd_maxJourneyDuration) | `duration` | The expected maximum time a journey can last across all possible journeys for the current deployment. | *Optional* | `"PT24H"` | 2.1 | +| modes | `string` | The set of access/egress/direct/transit modes to be used for the route search. | *Optional* | `"TRANSIT,WALK"` | 2.0 | +| nonpreferredTransferPenalty | `integer` | Penalty (in seconds) for using a non-preferred transfer. | *Optional* | `180` | 2.0 | +| numItineraries | `integer` | The maximum number of itineraries to return. | *Optional* | `50` | 2.0 | +| [otherThanPreferredRoutesPenalty](#rd_otherThanPreferredRoutesPenalty) | `integer` | Penalty added for using every route that is not preferred if user set any route as preferred. | *Optional* | `300` | 2.0 | +| [relaxTransitGroupPriority](#rd_relaxTransitGroupPriority) | `string` | The relax function for transit-group-priority | *Optional* | `"0s + 1.00 t"` | 2.5 | +| [relaxTransitSearchGeneralizedCostAtDestination](#rd_relaxTransitSearchGeneralizedCostAtDestination) | `double` | Whether non-optimal transit paths at the destination should be returned | *Optional* | | 2.3 | +| [searchWindow](#rd_searchWindow) | `duration` | The duration of the search-window. | *Optional* | | 2.0 | +| [streetRoutingTimeout](#rd_streetRoutingTimeout) | `duration` | The maximum time a street routing request is allowed to take before returning the results. | *Optional* | `"PT5S"` | 2.2 | +| [transferPenalty](#rd_transferPenalty) | `integer` | An additional penalty added to boardings after the first. | *Optional* | `0` | 2.0 | +| [transferSlack](#rd_transferSlack) | `duration` | The extra time needed to make a safe transfer. | *Optional* | `"PT2M"` | 2.0 | +| turnReluctance | `double` | Multiplicative factor on expected turning time. | *Optional* | `1.0` | 2.0 | +| [unpreferredCost](#rd_unpreferredCost) | `cost-linear-function` | A cost function used to calculate penalty for an unpreferred route. | *Optional* | `"0s + 1.00 t"` | 2.2 | +| waitReluctance | `double` | How much worse is waiting for a transit vehicle than being on a transit vehicle, as a multiplier. | *Optional* | `1.0` | 2.0 | +| accessEgress | `object` | Parameters for access and egress routing. | *Optional* | | 2.4 | +|    [maxDuration](#rd_accessEgress_maxDuration) | `duration` | This is the maximum duration for access/egress for street searches. | *Optional* | `"PT45M"` | 2.1 | +|    [maxStopCount](#rd_accessEgress_maxStopCount) | `integer` | Maximal number of stops collected in access/egress routing | *Optional* | `500` | 2.4 | +|    [maxDurationForMode](#rd_accessEgress_maxDurationForMode) | `enum map of duration` | Limit access/egress per street mode. | *Optional* | | 2.1 | +|    [penalty](#rd_accessEgress_penalty) | `enum map of object` | Penalty for access/egress by street mode. | *Optional* | | 2.4 | +|       FLEXIBLE | `object` | NA | *Optional* | | 2.4 | +|          costFactor | `double` | A factor multiplied with the time-penalty to get the cost-penalty. | *Optional* | `0.0` | 2.4 | +|          timePenalty | `time-penalty` | Penalty added to the time of a path/leg. | *Optional* | `"0s + 0.00 t"` | 2.4 | +| [alightSlackForMode](#rd_alightSlackForMode) | `enum map of duration` | How much extra time should be given when alighting a vehicle for each given mode. | *Optional* | | 2.0 | +| bicycle | `object` | Bicycle preferences. | *Optional* | | 2.5 | +|    [boardCost](#rd_bicycle_boardCost) | `integer` | Prevents unnecessary transfers by adding a cost for boarding a transit vehicle. | *Optional* | `600` | 2.0 | +|    [optimization](#rd_bicycle_optimization) | `enum` | The set of characteristics that the user wants to optimize for. | *Optional* | `"safe-streets"` | 2.0 | +|    reluctance | `double` | A multiplier for how bad cycling is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | +|    speed | `double` | Max bicycle speed along streets, in meters per second | *Optional* | `5.0` | 2.0 | +|    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | +|       cost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | +|       time | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | +|       [unpreferredVehicleParkingTagCost](#rd_bicycle_parking_unpreferredVehicleParkingTagCost) | `integer` | What cost to add if a parking facility doesn't contain a preferred tag. | *Optional* | `300` | 2.3 | +|       [bannedVehicleParkingTags](#rd_bicycle_parking_bannedVehicleParkingTags) | `string[]` | Tags with which a vehicle parking will not be used. If empty, no tags are banned. | *Optional* | | 2.1 | +|       [preferredVehicleParkingTags](#rd_bicycle_parking_preferredVehicleParkingTags) | `string[]` | Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. | *Optional* | | 2.3 | +|       [requiredVehicleParkingTags](#rd_bicycle_parking_requiredVehicleParkingTags) | `string[]` | Tags without which a vehicle parking will not be used. If empty, no tags are required. | *Optional* | | 2.1 | +|    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | +|       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | +|       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | +|       dropOffTime | `duration` | Time to drop-off a rented vehicle. | *Optional* | `"PT30S"` | 2.0 | +|       keepingAtDestinationCost | `integer` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0` | 2.2 | +|       pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | +|       pickupTime | `duration` | Time to rent a vehicle. | *Optional* | `"PT1M"` | 2.0 | +|       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | +|       [allowedNetworks](#rd_bicycle_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | +|       [bannedNetworks](#rd_bicycle_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | +|    [triangle](#rd_bicycle_triangle) | `object` | Triangle optimization criteria. | *Optional* | | 2.5 | +|       flatness | `double` | Relative importance of flat terrain (range 0-1). | *Optional* | `0.0` | 2.0 | +|       [safety](#rd_bicycle_triangle_safety) | `double` | Relative importance of safety (range 0-1). | *Optional* | `0.0` | 2.0 | +|       time | `double` | Relative importance of duration of travel (range 0-1). | *Optional* | `0.0` | 2.0 | +|    walk | `object` | Preferences for walking a vehicle. | *Optional* | | 2.5 | +|       [mountDismountCost](#rd_bicycle_walk_mountDismountCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | +|       [mountDismountTime](#rd_bicycle_walk_mountDismountTime) | `duration` | The time it takes the user to hop on or off a vehicle. | *Optional* | `"PT0S"` | 2.0 | +|       reluctance | `double` | A multiplier for how bad walking with a vehicle is, compared to being in transit for equal lengths of time. | *Optional* | `5.0` | 2.1 | +|       speed | `double` | The user's vehicle walking speed in meters/second. Defaults to approximately 3 MPH. | *Optional* | `1.33` | 2.1 | +|       stairsReluctance | `double` | How bad is it to walk the vehicle up/down a flight of stairs compared to taking a detour. | *Optional* | `10.0` | 2.3 | +| [boardSlackForMode](#rd_boardSlackForMode) | `enum map of duration` | How much extra time should be given when boarding a vehicle for each given mode. | *Optional* | | 2.0 | +| car | `object` | Car preferences. | *Optional* | | 2.5 | +|    accelerationSpeed | `double` | The acceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | +|    decelerationSpeed | `double` | The deceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | +|    pickupCost | `integer` | Add a cost for car pickup changes when a pickup or drop off takes place | *Optional* | `120` | 2.1 | +|    pickupTime | `duration` | Add a time for car pickup changes when a pickup or drop off takes place | *Optional* | `"PT1M"` | 2.1 | +|    reluctance | `double` | A multiplier for how bad driving is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | +|    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | +|       cost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | +|       time | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | +|       [unpreferredVehicleParkingTagCost](#rd_car_parking_unpreferredVehicleParkingTagCost) | `integer` | What cost to add if a parking facility doesn't contain a preferred tag. | *Optional* | `300` | 2.3 | +|       [bannedVehicleParkingTags](#rd_car_parking_bannedVehicleParkingTags) | `string[]` | Tags with which a vehicle parking will not be used. If empty, no tags are banned. | *Optional* | | 2.1 | +|       [preferredVehicleParkingTags](#rd_car_parking_preferredVehicleParkingTags) | `string[]` | Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. | *Optional* | | 2.3 | +|       [requiredVehicleParkingTags](#rd_car_parking_requiredVehicleParkingTags) | `string[]` | Tags without which a vehicle parking will not be used. If empty, no tags are required. | *Optional* | | 2.1 | +|    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | +|       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | +|       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | +|       dropOffTime | `duration` | Time to drop-off a rented vehicle. | *Optional* | `"PT30S"` | 2.0 | +|       keepingAtDestinationCost | `integer` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0` | 2.2 | +|       pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | +|       pickupTime | `duration` | Time to rent a vehicle. | *Optional* | `"PT1M"` | 2.0 | +|       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | +|       [allowedNetworks](#rd_car_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | +|       [bannedNetworks](#rd_car_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | +| [itineraryFilters](#rd_itineraryFilters) | `object` | Configure itinerary filters that may modify itineraries, sort them, and filter away less preferable results. | *Optional* | | 2.0 | +|    [accessibilityScore](#rd_if_accessibilityScore) | `boolean` | An experimental feature contributed by IBI which adds a sandbox accessibility *score* between 0 and 1 for each leg and itinerary. | *Optional* | `false` | 2.2 | +|    [bikeRentalDistanceRatio](#rd_if_bikeRentalDistanceRatio) | `double` | Filter routes that consist of bike-rental and walking by the minimum fraction of the bike-rental leg using _distance_. | *Optional* | `0.0` | 2.1 | +|    [debug](#rd_if_debug) | `enum` | Enable this to attach a system notice to itineraries instead of removing them. This is very convenient when tuning the itinerary-filter-chain. | *Optional* | `"off"` | 2.0 | +|    [filterDirectFlexBySearchWindow](#rd_if_filterDirectFlexBySearchWindow) | `boolean` | Filter direct flex results by the search window. The search-window is not used during flex routing, but we use one end to align it with transit results. | *Optional* | `true` | 2.7 | +|    [filterItinerariesWithSameFirstOrLastTrip](#rd_if_filterItinerariesWithSameFirstOrLastTrip) | `boolean` | If more than one itinerary begins or ends with same trip, filter out one of those itineraries so that only one remains. | *Optional* | `false` | 2.2 | +|    groupSimilarityKeepOne | `double` | Pick ONE itinerary from each group after putting itineraries that are 85% similar together. | *Optional* | `0.85` | 2.1 | +|    groupSimilarityKeepThree | `double` | Reduce the number of itineraries to three itineraries by reducing each group of itineraries grouped by 68% similarity. | *Optional* | `0.68` | 2.1 | +|    [groupedOtherThanSameLegsMaxCostMultiplier](#rd_if_groupedOtherThanSameLegsMaxCostMultiplier) | `double` | Filter grouped itineraries, where the non-grouped legs are more expensive than in the lowest cost one. | *Optional* | `2.0` | 2.1 | +|    [minBikeParkingDistance](#rd_if_minBikeParkingDistance) | `double` | Filter out bike park+ride results that have fewer meters of cycling than this value. | *Optional* | `0.0` | 2.3 | +|    [nonTransitGeneralizedCostLimit](#rd_if_nonTransitGeneralizedCostLimit) | `cost-linear-function` | The function define a max-limit for generalized-cost for non-transit itineraries. | *Optional* | `"1h + 2.0 t"` | 2.1 | +|    [parkAndRideDurationRatio](#rd_if_parkAndRideDurationRatio) | `double` | Filter P+R routes that consist of driving and walking by the minimum fraction of the driving using of _time_. | *Optional* | `0.0` | 2.1 | +|    [removeItinerariesWithSameRoutesAndStops](#rd_if_removeItinerariesWithSameRoutesAndStops) | `boolean` | Set to true if you want to list only the first itinerary which goes through the same stops and routes. | *Optional* | `false` | 2.2 | +|    [removeTransitWithHigherCostThanBestOnStreetOnly](#rd_if_removeTransitWithHigherCostThanBestOnStreetOnly) | `cost-linear-function` | Limit function for generalized-cost computed from street-only itineries applied to transit itineraries. | *Optional* | `"1m + 1.30 t"` | 2.4 | +|    [transitGeneralizedCostLimit](#rd_if_transitGeneralizedCostLimit) | `object` | A relative limit for the generalized-cost for transit itineraries. | *Optional* | | 2.1 | +|       [costLimitFunction](#rd_if_transitGeneralizedCostLimit_costLimitFunction) | `cost-linear-function` | The base function used by the filter. | *Optional* | `"15m + 1.50 t"` | 2.2 | +|       [intervalRelaxFactor](#rd_if_transitGeneralizedCostLimit_intervalRelaxFactor) | `double` | How much the filter should be relaxed for itineraries that do not overlap in time. | *Optional* | `0.4` | 2.2 | +| [maxDirectStreetDurationForMode](#rd_maxDirectStreetDurationForMode) | `enum map of duration` | Limit direct route duration per street mode. | *Optional* | | 2.2 | +| scooter | `object` | Scooter preferences. | *Optional* | | 2.5 | +|    [optimization](#rd_scooter_optimization) | `enum` | The set of characteristics that the user wants to optimize for. | *Optional* | `"safe-streets"` | 2.0 | +|    reluctance | `double` | A multiplier for how bad scooter travel is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | +|    speed | `double` | Max scooter speed along streets, in meters per second | *Optional* | `5.0` | 2.0 | +|    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | +|       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | +|       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | +|       dropOffTime | `duration` | Time to drop-off a rented vehicle. | *Optional* | `"PT30S"` | 2.0 | +|       keepingAtDestinationCost | `integer` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0` | 2.2 | +|       pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | +|       pickupTime | `duration` | Time to rent a vehicle. | *Optional* | `"PT1M"` | 2.0 | +|       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | +|       [allowedNetworks](#rd_scooter_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | +|       [bannedNetworks](#rd_scooter_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | +|    [triangle](#rd_scooter_triangle) | `object` | Triangle optimization criteria. | *Optional* | | 2.5 | +|       flatness | `double` | Relative importance of flat terrain (range 0-1). | *Optional* | `0.0` | 2.0 | +|       [safety](#rd_scooter_triangle_safety) | `double` | Relative importance of safety (range 0-1). | *Optional* | `0.0` | 2.0 | +|       time | `double` | Relative importance of duration of travel (range 0-1). | *Optional* | `0.0` | 2.0 | +| [transferOptimization](#rd_transferOptimization) | `object` | Optimize where a transfer between to trip happens. | *Optional* | | 2.1 | +|    [backTravelWaitTimeFactor](#rd_to_backTravelWaitTimeFactor) | `double` | To reduce back-travel we favor waiting, this reduces the cost of waiting. | *Optional* | `1.0` | 2.1 | +|    [extraStopBoardAlightCostsFactor](#rd_to_extraStopBoardAlightCostsFactor) | `double` | Add an extra board- and alight-cost for prioritized stops. | *Optional* | `0.0` | 2.1 | +|    [minSafeWaitTimeFactor](#rd_to_minSafeWaitTimeFactor) | `double` | Used to set a maximum wait-time cost, base on min-safe-transfer-time. | *Optional* | `5.0` | 2.1 | +|    [optimizeTransferWaitTime](#rd_to_optimizeTransferWaitTime) | `boolean` | This enables the transfer wait time optimization. | *Optional* | `true` | 2.1 | +| [transitGroupPriority](#rd_transitGroupPriority) | `object` | Group transit patterns and give each group a mutual advantage in the Raptor search. | *Optional* | | 2.5 | +| [transitReluctanceForMode](#rd_transitReluctanceForMode) | `enum map of double` | Transit reluctance for a given transport mode | *Optional* | | 2.1 | +| [unpreferred](#rd_unpreferred) | `object` | Parameters listing authorities or lines that preferably should not be used in trip patters. | *Optional* | | 2.2 | +|    [agencies](#rd_unpreferred_agencies) | `feed-scoped-id[]` | The ids of the agencies that incur an extra cost when being used. Format: `FeedId:AgencyId` | *Optional* | | 2.2 | +|    [routes](#rd_unpreferred_routes) | `feed-scoped-id[]` | The ids of the routes that incur an extra cost when being used. Format: `FeedId:RouteId` | *Optional* | | 2.2 | +| walk | `object` | Walking preferences. | *Optional* | | 2.5 | +|    boardCost | `integer` | Prevents unnecessary transfers by adding a cost for boarding a vehicle. This is the cost that is used when boarding while walking. | *Optional* | `600` | 2.0 | +|    escalatorReluctance | `double` | A multiplier for how bad being in an escalator is compared to being in transit for equal lengths of time | *Optional* | `1.5` | 2.4 | +|    [reluctance](#rd_walk_reluctance) | `double` | A multiplier for how bad walking is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | +|    [safetyFactor](#rd_walk_safetyFactor) | `double` | Factor for how much the walk safety is considered in routing. | *Optional* | `1.0` | 2.2 | +|    speed | `double` | The user's walking speed in meters/second. | *Optional* | `1.33` | 2.0 | +|    stairsReluctance | `double` | Used instead of walkReluctance for stairs. | *Optional* | `2.0` | 2.0 | +|    [stairsTimeFactor](#rd_walk_stairsTimeFactor) | `double` | How much more time does it take to walk a flight of stairs compared to walking a similar horizontal length. | *Optional* | `3.0` | 2.1 | +| wheelchairAccessibility | `object` | See [Wheelchair Accessibility](Accessibility.md) | *Optional* | | 2.2 | +|    enabled | `boolean` | Enable wheelchair accessibility. | *Optional* | `false` | 2.0 | +|    inaccessibleStreetReluctance | `double` | The factor to multiply the cost of traversing a street edge that is not wheelchair-accessible. | *Optional* | `25.0` | 2.2 | +|    [maxSlope](#rd_wheelchairAccessibility_maxSlope) | `double` | The maximum slope as a fraction of 1. | *Optional* | `0.083` | 2.0 | +|    [slopeExceededReluctance](#rd_wheelchairAccessibility_slopeExceededReluctance) | `double` | How much streets with high slope should be avoided. | *Optional* | `1.0` | 2.2 | +|    [stairsReluctance](#rd_wheelchairAccessibility_stairsReluctance) | `double` | How much stairs should be avoided. | *Optional* | `100.0` | 2.2 | +|    elevator | `object` | Configuration for when to use inaccessible elevators. | *Optional* | | 2.2 | +|       inaccessibleCost | `integer` | The cost to add when traversing an entity which is know to be inaccessible. | *Optional* | `3600` | 2.2 | +|       onlyConsiderAccessible | `boolean` | Whether to only use this entity if it is explicitly marked as wheelchair accessible. | *Optional* | `false` | 2.2 | +|       unknownCost | `integer` | The cost to add when traversing an entity with unknown accessibility information. | *Optional* | `20` | 2.2 | +|    stop | `object` | Configuration for when to use inaccessible stops. | *Optional* | | 2.2 | +|       inaccessibleCost | `integer` | The cost to add when traversing an entity which is know to be inaccessible. | *Optional* | `3600` | 2.2 | +|       onlyConsiderAccessible | `boolean` | Whether to only use this entity if it is explicitly marked as wheelchair accessible. | *Optional* | `true` | 2.2 | +|       unknownCost | `integer` | The cost to add when traversing an entity with unknown accessibility information. | *Optional* | `600` | 2.2 | +|    trip | `object` | Configuration for when to use inaccessible trips. | *Optional* | | 2.2 | +|       inaccessibleCost | `integer` | The cost to add when traversing an entity which is know to be inaccessible. | *Optional* | `3600` | 2.2 | +|       onlyConsiderAccessible | `boolean` | Whether to only use this entity if it is explicitly marked as wheelchair accessible. | *Optional* | `true` | 2.2 | +|       unknownCost | `integer` | The cost to add when traversing an entity with unknown accessibility information. | *Optional* | `600` | 2.2 | @@ -731,6 +732,23 @@ convenient when tuning the itinerary-filter-chain. moving to the next page. +

    filterDirectFlexBySearchWindow

    + +**Since version:** `2.7` ∙ **Type:** `boolean` ∙ **Cardinality:** `Optional` ∙ **Default value:** `true` +**Path:** /routingDefaults/itineraryFilters + +Filter direct flex results by the search window. The search-window is not used +during flex routing, but we use one end to align it with transit results. + +When direct flex is mixed with a transit search in the same request, then the direct +flex results are filtered by the search window of the transit results. + +Depart-at searches are filtered by latest-arrival-time and arrive-by searches are +filtered by earliest-departure-time. + +Use this configuration to turn this feature off. + +

    filterItinerariesWithSameFirstOrLastTrip

    **Since version:** `2.2` ∙ **Type:** `boolean` ∙ **Cardinality:** `Optional` ∙ **Default value:** `false` diff --git a/doc/user/RouterConfiguration.md b/doc/user/RouterConfiguration.md index 4e565cfe17d..6dbd1174397 100644 --- a/doc/user/RouterConfiguration.md +++ b/doc/user/RouterConfiguration.md @@ -2,7 +2,7 @@ NOTE! Part of this document is generated. Make sure you edit the template, not the generated doc. - Template directory is: /doc/templates - - Generated directory is: /docs + - Generated directory is: /doc/user --> # Router configuration @@ -14,7 +14,7 @@ These options can be applied by the OTP server without rebuilding the graph. Certain settings can be provided on the command line, when starting OpenTripPlanner. See the `CommandLineParameters` class -for [a full list of arguments](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/standalone/config/CommandLineParameters.java) +for [a full list of arguments](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/application/src/main/java/org/opentripplanner/standalone/config/CommandLineParameters.java) . ## Routing defaults @@ -237,7 +237,7 @@ few percents. Split a travel search in smaller jobs and run them in parallel to improve performance. Use this parameter to set the total number of executable threads available across all searches. -Multiple searches can run in parallel - this parameter have no effect with regard to that. If 0, +Multiple searches can run in parallel - this parameter has no effect with regard to that. If 0, no extra threads are started and the search is done in one thread. @@ -295,7 +295,7 @@ In addition there is an upper bound on the calculation of the search window: Upper limit for the search-window calculation. -Long search windows consumes a lot of resources and may take a long time. Use this parameter to +Long search windows consume a lot of resources and may take a long time. Use this parameter to tune the desired maximum search time. This is the parameter that affects the response time most, the downside is that a search is only @@ -778,12 +778,6 @@ Used to group requests when monitoring OTP. "Authorization" : "${BIKELY_AUTHORIZATION}" } }, - { - "type" : "vehicle-parking", - "feedId" : "noi", - "sourceType" : "noi-open-data-hub", - "url" : "https://parking.otp.opendatahub.com/parking/all.json" - }, { "type" : "stop-time-updater", "frequency" : "1m", diff --git a/doc/user/RoutingModes.md b/doc/user/RoutingModes.md index 0895e019716..c9b61712498 100644 --- a/doc/user/RoutingModes.md +++ b/doc/user/RoutingModes.md @@ -104,7 +104,7 @@ Used for short- and long-distance bus routes.

    CABLE_CAR

    -Used for street-level cable cars where the cable runs beneath the car. +Used for street-level rail cars where the cable runs beneath the vehicle.

    CARPOOL

    diff --git a/doc/user/Troubleshooting-Routing.md b/doc/user/Troubleshooting-Routing.md index 4e237baa9fc..cd7eaa04c88 100644 --- a/doc/user/Troubleshooting-Routing.md +++ b/doc/user/Troubleshooting-Routing.md @@ -148,7 +148,7 @@ props.setProperties("surface=mud", StreetTraversalPermission.ALL, 1.5, 1.5, true ``` The Javadoc -of [`OSMSpecifier.java`](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/graph_builder/module/osm/OSMSpecifier.java) +of [`OSMSpecifier.java`](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/application/src/main/java/org/opentripplanner/osm/wayproperty/specifier/OsmSpecifier.java) contains the precise documentation about the syntax of the matchers. There are a lot of rules for which tags results in a specific safety score so it's not easy to get diff --git a/doc/user/UpdaterConfig.md b/doc/user/UpdaterConfig.md index f3a0d982e68..f61cce12f54 100644 --- a/doc/user/UpdaterConfig.md +++ b/doc/user/UpdaterConfig.md @@ -2,7 +2,7 @@ NOTE! Part of this document is generated. Make sure you edit the template, not the generated doc. - Template directory is: /doc/templates - - Generated directory is: /docs + - Generated directory is: /doc/user --> @@ -92,20 +92,20 @@ The information is downloaded in a single HTTP request and polled regularly. | Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | |-----------------------------------------------------------------------|:---------------:|----------------------------------------------------------------------------|:----------:|----------------------|:-----:| | type = "stop-time-updater" | `enum` | The type of the updater. | *Required* | | 1.5 | -| [backwardsDelayPropagationType](#u__6__backwardsDelayPropagationType) | `enum` | How backwards propagation should be handled. | *Optional* | `"required-no-data"` | 2.2 | +| [backwardsDelayPropagationType](#u__5__backwardsDelayPropagationType) | `enum` | How backwards propagation should be handled. | *Optional* | `"required-no-data"` | 2.2 | | feedId | `string` | Which feed the updates apply to. | *Required* | | 1.5 | | frequency | `duration` | How often the data should be downloaded. | *Optional* | `"PT1M"` | 1.5 | | fuzzyTripMatching | `boolean` | If the trips should be matched fuzzily. | *Optional* | `false` | 1.5 | -| [url](#u__6__url) | `string` | The URL of the GTFS-RT resource. | *Required* | | 1.5 | -| [headers](#u__6__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | +| [url](#u__5__url) | `string` | The URL of the GTFS-RT resource. | *Required* | | 1.5 | +| [headers](#u__5__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | ##### Parameter details -

    backwardsDelayPropagationType

    +

    backwardsDelayPropagationType

    **Since version:** `2.2` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"required-no-data"` -**Path:** /updaters/[6] +**Path:** /updaters/[5] **Enum values:** `required-no-data` | `required` | `always` How backwards propagation should be handled. @@ -124,19 +124,19 @@ How backwards propagation should be handled. The updated times are exposed through APIs. -

    url

    +

    url

    **Since version:** `1.5` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /updaters/[6] +**Path:** /updaters/[5] The URL of the GTFS-RT resource. `file:` URLs are also supported if you want to read a file from the local disk. -

    headers

    +

    headers

    **Since version:** `2.3` ∙ **Type:** `map of string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[6] +**Path:** /updaters/[5] HTTP headers to add to the request. Any header key, value can be inserted. @@ -178,7 +178,7 @@ This system powers the realtime updates in Helsinki and more information can be | Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | |-----------------------------------------------------------------------|:---------:|----------------------------------------------|:----------:|----------------------|:-----:| | type = "mqtt-gtfs-rt-updater" | `enum` | The type of the updater. | *Required* | | 1.5 | -| [backwardsDelayPropagationType](#u__7__backwardsDelayPropagationType) | `enum` | How backwards propagation should be handled. | *Optional* | `"required-no-data"` | 2.2 | +| [backwardsDelayPropagationType](#u__6__backwardsDelayPropagationType) | `enum` | How backwards propagation should be handled. | *Optional* | `"required-no-data"` | 2.2 | | feedId | `string` | The feed id to apply the updates to. | *Required* | | 2.0 | | fuzzyTripMatching | `boolean` | Whether to match trips fuzzily. | *Optional* | `false` | 2.0 | | qos | `integer` | QOS level. | *Optional* | `0` | 2.0 | @@ -188,10 +188,10 @@ This system powers the realtime updates in Helsinki and more information can be ##### Parameter details -

    backwardsDelayPropagationType

    +

    backwardsDelayPropagationType

    **Since version:** `2.2` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"required-no-data"` -**Path:** /updaters/[7] +**Path:** /updaters/[6] **Enum values:** `required-no-data` | `required` | `always` How backwards propagation should be handled. @@ -247,24 +247,24 @@ The information is downloaded in a single HTTP request and polled regularly. | frequency | `duration` | How often the positions should be updated. | *Optional* | `"PT1M"` | 2.2 | | fuzzyTripMatching | `boolean` | Whether to match trips fuzzily. | *Optional* | `false` | 2.5 | | url | `uri` | The URL of GTFS-RT protobuf HTTP resource to download the positions from. | *Required* | | 2.2 | -| [features](#u__8__features) | `enum set` | Which features of GTFS RT vehicle positions should be loaded into OTP. | *Optional* | | 2.5 | -| [headers](#u__8__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | +| [features](#u__7__features) | `enum set` | Which features of GTFS RT vehicle positions should be loaded into OTP. | *Optional* | | 2.5 | +| [headers](#u__7__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | ##### Parameter details -

    features

    +

    features

    **Since version:** `2.5` ∙ **Type:** `enum set` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[8] +**Path:** /updaters/[7] **Enum values:** `position` | `stop-position` | `occupancy` Which features of GTFS RT vehicle positions should be loaded into OTP. -

    headers

    +

    headers

    **Since version:** `2.3` ∙ **Type:** `map of string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[8] +**Path:** /updaters/[7] HTTP headers to add to the request. Any header key, value can be inserted. @@ -313,18 +313,19 @@ GBFS form factors: -| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | -|---------------------------------------------------------------------------------------|:---------------:|---------------------------------------------------------------------------------|:----------:|---------------|:-----:| -| type = "vehicle-rental" | `enum` | The type of the updater. | *Required* | | 1.5 | -| [allowKeepingRentedVehicleAtDestination](#u_1_allowKeepingRentedVehicleAtDestination) | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.1 | -| frequency | `duration` | How often the data should be updated. | *Optional* | `"PT1M"` | 1.5 | -| [geofencingZones](#u_1_geofencingZones) | `boolean` | Compute rental restrictions based on GBFS 2.2 geofencing zones. | *Optional* | `false` | 2.3 | -| language | `string` | TODO | *Optional* | | 2.1 | -| [network](#u_1_network) | `string` | The name of the network to override the one derived from the source data. | *Optional* | | 1.5 | -| overloadingAllowed | `boolean` | Allow leaving vehicles at a station even though there are no free slots. | *Optional* | `false` | 2.2 | -| [sourceType](#u_1_sourceType) | `enum` | What source of vehicle rental updater to use. | *Required* | | 1.5 | -| url | `string` | The URL to download the data from. | *Required* | | 1.5 | -| [headers](#u_1_headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 1.5 | +| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | +|---------------------------------------------------------------------------------------|:---------------:|----------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------:|---------------|:-----:| +| type = "vehicle-rental" | `enum` | The type of the updater. | *Required* | | 1.5 | +| [allowKeepingRentedVehicleAtDestination](#u_1_allowKeepingRentedVehicleAtDestination) | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.1 | +| frequency | `duration` | How often the data should be updated. | *Optional* | `"PT1M"` | 1.5 | +| [geofencingZones](#u_1_geofencingZones) | `boolean` | Compute rental restrictions based on GBFS 2.2 geofencing zones. | *Optional* | `false` | 2.3 | +| language | `string` | TODO | *Optional* | | 2.1 | +| [network](#u_1_network) | `string` | The name of the network to override the one derived from the source data. | *Optional* | | 1.5 | +| overloadingAllowed | `boolean` | Allow leaving vehicles at a station even though there are no free slots. | *Optional* | `false` | 2.2 | +| [sourceType](#u_1_sourceType) | `enum` | What source of vehicle rental updater to use. | *Required* | | 1.5 | +| url | `string` | The URL to download the data from. | *Required* | | 1.5 | +| [headers](#u_1_headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 1.5 | +| [rentalPickupTypes](#u_1_rentalPickupTypes) | `enum set` | This is temporary and will be removed in a future version of OTP. Use this to specify the type of rental data that is allowed to be read from the data source. | *Optional* | | 2.7 | ##### Parameter details @@ -383,6 +384,18 @@ What source of vehicle rental updater to use. HTTP headers to add to the request. Any header key, value can be inserted. +

    rentalPickupTypes

    + +**Since version:** `2.7` ∙ **Type:** `enum set` ∙ **Cardinality:** `Optional` +**Path:** /updaters/[1] +**Enum values:** `station` | `free-floating` + +This is temporary and will be removed in a future version of OTP. Use this to specify the type of rental data that is allowed to be read from the data source. + + - `station` Stations are imported. + - `free-floating` Free-floating vehicles are imported. + + ##### Example configuration diff --git a/doc/user/apis/GraphQL-Tutorial.md b/doc/user/apis/GraphQL-Tutorial.md index d65fbc144ba..41695de304a 100644 --- a/doc/user/apis/GraphQL-Tutorial.md +++ b/doc/user/apis/GraphQL-Tutorial.md @@ -2,7 +2,7 @@ NOTE! Part of this document is generated. Make sure you edit the template, not the generated doc. - Template directory is: /doc/templates - - Generated directory is: /docs + - Generated directory is: /doc/user --> # GraphQL tutorial @@ -70,53 +70,61 @@ Most people want to get routing results out of OTP, so lets see the query for th ```graphql { - plan( - # these coordinates are in Portland, change this to YOUR origin - from: { lat: 45.5552, lon: -122.6534 } - # these coordinates are in Portland, change this to YOUR destination - to: { lat: 45.4908, lon: -122.5519 } + planConnection( + origin: { + # these coordinates are in Portland, change this to YOUR origin + location: { coordinate: { latitude: 45.5552, longitude: -122.6534 } } + } + destination: { + # these coordinates are in Portland, change this to YOUR destination + location: { coordinate: { latitude: 45.4908, longitude: -122.5519 } } + } # use the correct date and time of your request - date: "2023-02-15" - time: "11:37" + dateTime: { earliestDeparture: "2023-06-13T14:30-07:00" } # choose the transport modes you need - transportModes: [{ mode: WALK }, { mode: TRANSIT }] + modes: { + direct: [WALK] + transit: { transit: [{ mode: BUS }, { mode: RAIL }] } + } ) { - itineraries { - start - end - legs { - mode - from { - name - lat - lon - departure { - scheduledTime - estimated { - time - delay + edges { + node { + start + end + legs { + mode + from { + name + lat + lon + departure { + scheduledTime + estimated { + time + delay + } } } - } - to { - name - lat - lon - arrival { - scheduledTime - estimated { - time - delay + to { + name + lat + lon + arrival { + scheduledTime + estimated { + time + delay + } } } - } - route { - gtfsId - longName - shortName - } - legGeometry { - points + route { + gtfsId + longName + shortName + } + legGeometry { + points + } } } } @@ -130,4 +138,4 @@ Most people want to get routing results out of OTP, so lets see the query for th Again, please use the autocomplete and documentation viewers to figure out what each input parameter and property means. -More examples for a variety of queries can also be found [in the test code](https://github.com/opentripplanner/OpenTripPlanner/tree/dev-2.x/src/test/resources/org/opentripplanner/apis/gtfs/queries). \ No newline at end of file +More examples for a variety of queries can also be found [in the test code](https://github.com/opentripplanner/OpenTripPlanner/tree/dev-2.x/application/src/test/resources/org/opentripplanner/apis/gtfs/queries). \ No newline at end of file diff --git a/doc/user/css/magidoc-overrides.css b/doc/user/css/magidoc-overrides.css new file mode 100644 index 00000000000..dbf0cb2523d --- /dev/null +++ b/doc/user/css/magidoc-overrides.css @@ -0,0 +1,11 @@ +/* + * This file contains custom CSS overrides for the GraphQL documentation available at + * https://docs.opentripplanner.org/api/dev-2.x/graphql-gtfs/ + */ + +/* + * Hide the deprecated queries from the left hand navigation panel. + */ +nav ul li .deprecated { + display: none; +} diff --git a/doc/user/examples/ibi/portland/router-config.json b/doc/user/examples/ibi/portland/router-config.json index 0bf3547dbfd..acbcbc2e0a0 100644 --- a/doc/user/examples/ibi/portland/router-config.json +++ b/doc/user/examples/ibi/portland/router-config.json @@ -59,6 +59,62 @@ "url": "https://gbfs.spin.pm/api/gbfs/v2/portland" } ], + "vectorTiles": { + "basePath": "/rtp/routers/default/vectorTiles", + "attribution": "Regional Partners", + "layers": [ + { + "name": "stops", + "type": "Stop", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 600, + "filter": "sunday-to-sunday-service-week" + }, + { + "name": "areaStops", + "type": "AreaStop", + "mapper": "OTPRR", + "maxZoom": 30, + "minZoom": 8, + "cacheMaxSeconds": 600 + }, + { + "name": "stations", + "type": "Station", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 2, + "cacheMaxSeconds": 600 + }, + { + "name": "rentalVehicles", + "type": "VehicleRentalVehicle", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 2, + "cacheMaxSeconds": 60 + }, + { + "name": "rentalStations", + "type": "VehicleRentalStation", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 2, + "cacheMaxSeconds": 600 + }, + { + "name": "vehicleParking", + "type": "VehicleParking", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 10, + "cacheMaxSeconds": 60, + "expansionFactor": 0.25 + } + ] + }, "rideHailingServices": [ { "type": "uber-car-hailing", diff --git a/doc/user/features-explained/Netex-Siri-Compatibility.md b/doc/user/features-explained/Netex-Siri-Compatibility.md new file mode 100644 index 00000000000..731011be8e0 --- /dev/null +++ b/doc/user/features-explained/Netex-Siri-Compatibility.md @@ -0,0 +1,36 @@ +# NeTEx and SIRI compatibility + +NeTEx and SIRI are two European public transport data specifications that are comparable to GTFS and +GTFS-RT but have a broader scope. Support for both was added by Entur in OTP version 2 and you can +find examples of those in their [examples repo](https://github.com/entur/profile-examples). + +## Profiles + +### Nordic profile + +Different countries are currently using different incompatible "profiles" of NeTEx, but an effort is +underway to converge on a single European standard profile. This is based in large part on the +Nordic profile used by Entur. + +The Nordic profile is the only profile that has been thoroughly tested in production in OTP and is +used in Norway, Finland and Sweden. + +### EPIP + +The [European Passenger Information Profile](http://netex.uk/netex/doc/2019.05.07-v1.1_FinalDraft/prCEN_TS_16614-PI_Profile_FV_%28E%29-2019-Final-Draft-v3.pdf) +is an attempt to unify other country profiles and support in OTP is adequate, but it is difficult +to tell how much of EPIP is supported since it is a very large profile. The current status +of the support is tracked on [Github](https://github.com/opentripplanner/OpenTripPlanner/issues/3640). + +Sometimes it is difficult to tell if a file conforms to EPIP so to find out, you can run the following +commands: + +``` +git clone git@github.com:NeTEx-CEN/NeTEx-Profile-EPIP.git +xmllint --noout --schema NeTEx-Profile-EPIP/NeTEx_publication_EPIP.xsd your-filename.xml +``` + +### Other profiles + +It is the goal of the community to support both the Nordic profile and EPIP. If you have another +profile, we encourage to get in touch with the community to find a way forward. \ No newline at end of file diff --git a/doc/user/index.md b/doc/user/index.md index a8f00a3184c..89af4f31e2b 100644 --- a/doc/user/index.md +++ b/doc/user/index.md @@ -26,7 +26,8 @@ the selector in the upper left of the published documentation. **Releases** -- [Latest](http://docs.opentripplanner.org/en/latest) - Version 2.5 (the git master branch) +- [Latest](http://docs.opentripplanner.org/en/latest) - Version 2.6 (the git master branch) +- [v2.5.0](http://docs.opentripplanner.org/en/v2.5.0) - Version 2.5 - [v2.4.0](http://docs.opentripplanner.org/en/v2.4.0) - Version 2.4 - [v2.3.0](http://docs.opentripplanner.org/en/v2.3.0) - Version 2.3 - [v2.2.0](http://docs.opentripplanner.org/en/v2.2.0) - Version 2.2 diff --git a/doc/user/osm/Finland.md b/doc/user/osm/Finland.md index 8a60b5f0b13..a5a0341bf94 100644 --- a/doc/user/osm/Finland.md +++ b/doc/user/osm/Finland.md @@ -41,7 +41,6 @@ Lower safety values make an OSM way more desirable and higher values less desira | `highway=trunk_link` | `ALL` | 2.06 | | | `highway=trunk` | `ALL` | 7.47 | | | `highway=trunk; tunnel=yes` | `CAR` | 7.47 | | -| `motorroad=yes` | `CAR` | 7.47 | | | `present(highway); informal=yes` | `NONE` | | | | `highway=service; access=private` | `NONE` | | | | `highway=trail` | `NONE` | | | @@ -105,6 +104,7 @@ Lower safety values make an OSM way more desirable and higher values less desira | `highway=motorway_link` | `CAR` | 2.06 | | | `highway=trunk` | `CAR` | 7.47 | | | `highway=motorway` | `CAR` | 8.0 | | +| `motorroad=yes` | `CAR` | | | | `present(highway); cycleway=lane` | `PEDESTRIAN_AND_BICYCLE` | 0.87 | | | `highway=service; cycleway=lane` | `ALL` | 0.77 | | | `highway=residential; cycleway=lane` | `ALL` | 0.77 | | diff --git a/doc/user/osm/Germany.md b/doc/user/osm/Germany.md index 922aa3af836..ee9e3982362 100644 --- a/doc/user/osm/Germany.md +++ b/doc/user/osm/Germany.md @@ -70,6 +70,7 @@ Lower safety values make an OSM way more desirable and higher values less desira | `highway=motorway_link` | `CAR` | 2.06 | | | `highway=trunk` | `CAR` | 7.47 | | | `highway=motorway` | `CAR` | 8.0 | | +| `motorroad=yes` | `CAR` | | | | `present(highway); cycleway=lane` | `PEDESTRIAN_AND_BICYCLE` | 0.87 | | | `highway=service; cycleway=lane` | `ALL` | 0.77 | | | `highway=residential; cycleway=lane` | `ALL` | 0.77 | | diff --git a/doc/user/osm/Default.md b/doc/user/osm/OsmTag.md similarity index 99% rename from doc/user/osm/Default.md rename to doc/user/osm/OsmTag.md index 814420b791f..9456dbc9fa5 100644 --- a/doc/user/osm/Default.md +++ b/doc/user/osm/OsmTag.md @@ -61,6 +61,7 @@ Lower safety values make an OSM way more desirable and higher values less desira | `highway=motorway_link` | `CAR` | 2.06 | | | `highway=trunk` | `CAR` | 7.47 | | | `highway=motorway` | `CAR` | 8.0 | | +| `motorroad=yes` | `CAR` | | | | `present(highway); cycleway=lane` | `PEDESTRIAN_AND_BICYCLE` | 0.87 | | | `highway=service; cycleway=lane` | `ALL` | 0.77 | | | `highway=residential; cycleway=lane` | `ALL` | 0.77 | | diff --git a/doc/user/osm/UK.md b/doc/user/osm/UK.md index 4a640caf95c..f9d8678fd3c 100644 --- a/doc/user/osm/UK.md +++ b/doc/user/osm/UK.md @@ -38,6 +38,8 @@ Lower safety values make an OSM way more desirable and higher values less desira | `highway=trunk_link; cycleway=opposite_track` | `ALL` | forward: 2.06
    back: 0.85 | | | `highway=trunk; bicycle=designated` | `ALL` | 7.25 | | | `highway=trunk_link; bicycle=designated` | `ALL` | 2.0 | | +| `indoor=area` | `PEDESTRIAN` | | | +| `indoor=corridor` | `PEDESTRIAN` | | | | `mtb:scale=3` | `NONE` | | | | `mtb:scale=4` | `NONE` | | | | `mtb:scale=5` | `NONE` | | | @@ -75,6 +77,7 @@ Lower safety values make an OSM way more desirable and higher values less desira | `highway=motorway_link` | `CAR` | 2.06 | | | `highway=trunk` | `CAR` | 7.47 | | | `highway=motorway` | `CAR` | 8.0 | | +| `motorroad=yes` | `CAR` | | | | `present(highway); cycleway=lane` | `PEDESTRIAN_AND_BICYCLE` | 0.87 | | | `highway=service; cycleway=lane` | `ALL` | 0.77 | | | `highway=residential; cycleway=lane` | `ALL` | 0.77 | | diff --git a/doc/user/requirements.txt b/doc/user/requirements.txt index 4681f78c93f..ee0eb31d65c 100644 --- a/doc/user/requirements.txt +++ b/doc/user/requirements.txt @@ -1,4 +1,4 @@ -mkdocs==1.6.0 -mkdocs-material==9.5.27 +mkdocs==1.6.1 +mkdocs-material==9.5.39 mike@git+https://github.com/jimporter/mike.git@f0522f245e64687dd18384fbd86b721175711474 mkdocs-no-sitemap-plugin==0.0.1 diff --git a/doc/user/sandbox/GoogleCloudStorage.md b/doc/user/sandbox/GoogleCloudStorage.md index 2fdc688a247..4876857b727 100644 --- a/doc/user/sandbox/GoogleCloudStorage.md +++ b/doc/user/sandbox/GoogleCloudStorage.md @@ -14,7 +14,7 @@ To enable this turn on the feature `GoogleCloudStorage`. OTP can load or store artifacts from one or more Google Cloud Storge locations. Each artifact must be configured in the _build-config.json_: -See [`BuildConfig`](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/standalone/config/BuildConfig.java) +See [`BuildConfig`](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/application/src/main/java/org/opentripplanner/standalone/config/BuildConfig.java) on how to configure artifacts. Example (build-config.json): diff --git a/doc/user/sandbox/MapboxVectorTilesApi.md b/doc/user/sandbox/MapboxVectorTilesApi.md index 62f3bd36c38..4430a398a5d 100644 --- a/doc/user/sandbox/MapboxVectorTilesApi.md +++ b/doc/user/sandbox/MapboxVectorTilesApi.md @@ -173,6 +173,7 @@ For each layer, the configuration includes: |       type = "stop" | `enum` | Type of the layer. | *Required* | | 2.0 | |       [cacheMaxSeconds](#vectorTiles_layers_0_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | |       [expansionFactor](#vectorTiles_layers_0_expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [filter](#vectorTiles_layers_0_filter) | `enum` | Reduce the result set of a layer further by a specific filter. | *Optional* | `"none"` | 2.6 | |       [mapper](#vectorTiles_layers_0_mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | |       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | |       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | @@ -245,6 +246,18 @@ How far outside its boundaries should the tile contain information. The value is a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile edges, then increase this number. +

    filter

    + +**Since version:** `2.6` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"none"` +**Path:** /vectorTiles/layers/[0] +**Enum values:** `none` | `sunday-to-sunday-service-week` + +Reduce the result set of a layer further by a specific filter. + +This is useful for when the schema of a layer, say stops, should remain unchanged but some +elements should not be included in the result. + +

    mapper

    **Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` diff --git a/doc/user/sandbox/Sorlandsbanen.md b/doc/user/sandbox/Sorlandsbanen.md new file mode 100644 index 00000000000..13bc9163456 --- /dev/null +++ b/doc/user/sandbox/Sorlandsbanen.md @@ -0,0 +1,47 @@ +# Sørlandsbanen - The southern railroad in Norway + +**This sandbox module is only working in Norway**, in particular only in the south of Norway. The +feature flag to turn it *on* should only be enabled if you are routing using the norwegian data set. + +The railroad in southern Norway is very slow and does not go by the coast where most people live. It +is easily beaten by coaches in the area. Despite this, we need to include it in results where it is +relevant. + +When the feature flag is enabled, two Raptor searches are performed. The first is the regular +search - unmodified, as requested by the user. The second search is modified to include train +results with Sørlandsbanen. This is achieved by setting a high COACH reluctance. We then take any +rail results(if they exist) from the second search and add it two to the results from the first +search. The new set of results will contain everything we found in the first search, plus the train +results in the second results. + +Note! This looks at origin and destination coordinates in addition to the feature flag to enable +the second search. It is automatically enabled if: + - the `OTPFeature.Sorlandsbanen` is on. + - the origin and/or destination is in the south of Norway. + - the search is a long-distance search, origin and destination are fare apart from each other. + + +## Contact Info + +- Entur, Norway + +## Changelog + +- 2024-10-14: We have used this feature for some time, but now want it in the Sandbox so we do not + need to merge it everytime we create a new Entur release. + + +### Configuration + +This is turned _off_ by default. To turn it on enable the `Sorlandsbanen` feature. + +```json +// otp-config.json +{ + "otpFeatures": { + "Sorlandsbanen": true + } +} +``` + + diff --git a/doc/user/sandbox/StopConsolidation.md b/doc/user/sandbox/StopConsolidation.md index b36429b1f60..d0e18a9ce30 100644 --- a/doc/user/sandbox/StopConsolidation.md +++ b/doc/user/sandbox/StopConsolidation.md @@ -2,7 +2,7 @@ NOTE! Part of this document is generated. Make sure you edit the template, not the generated doc. - Template directory is: /doc/templates - - Generated directory is: /docs + - Generated directory is: /doc/user --> # Stop consolidation diff --git a/doc/user/sandbox/VehicleParking.md b/doc/user/sandbox/VehicleParking.md index db057bd9dbd..ccd56fc238c 100644 --- a/doc/user/sandbox/VehicleParking.md +++ b/doc/user/sandbox/VehicleParking.md @@ -3,7 +3,7 @@ ## Contact Info - For HSL Park and Ride updater: Digitransit team, HSL, Helsinki, Finland -- For Bikely, NOI and Bikeep updater: Leonard Ehrenfried, [mail@leonard.io](mailto:mail@leonard.io) +- For Bikely, Bikeep and SIRI-FM updater: Leonard Ehrenfried, [mail@leonard.io](mailto:mail@leonard.io) ## Documentation @@ -16,7 +16,7 @@ Currently contains the following updaters: - [HSL Park and Ride](https://p.hsl.fi/docs/index.html) - [ParkAPI](https://github.com/offenesdresden/ParkAPI) - [Bikely](https://www.safebikely.com/) -- [NOI Open Data Hub](https://opendatahub.com/) +- SIRI-FM ### Configuration @@ -61,7 +61,7 @@ This will end up in the API responses as the feed id of the parking lot. **Since version:** `2.2` ∙ **Type:** `enum` ∙ **Cardinality:** `Required` **Path:** /updaters/[2] -**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` | `siri-fm` +**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `bikeep` | `siri-fm` The source of the vehicle updates. @@ -131,7 +131,7 @@ This will end up in the API responses as the feed id of the parking lot. **Since version:** `2.2` ∙ **Type:** `enum` ∙ **Cardinality:** `Required` **Path:** /updaters/[3] -**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` | `siri-fm` +**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `bikeep` | `siri-fm` The source of the vehicle updates. @@ -216,7 +216,7 @@ This will end up in the API responses as the feed id of the parking lot. **Since version:** `2.2` ∙ **Type:** `enum` ∙ **Cardinality:** `Required` **Path:** /updaters/[4] -**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` | `siri-fm` +**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `bikeep` | `siri-fm` The source of the vehicle updates. @@ -251,67 +251,6 @@ HTTP headers to add to the request. Any header key, value can be inserted. -## NOI Open Data Hub - - - - -| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | -|---------------------------------|:---------------:|------------------------------------------------------------------------------|:----------:|---------------|:-----:| -| type = "vehicle-parking" | `enum` | The type of the updater. | *Required* | | 1.5 | -| [feedId](#u__5__feedId) | `string` | The id of the data source, which will be the prefix of the parking lot's id. | *Required* | | 2.2 | -| frequency | `duration` | How often to update the source. | *Optional* | `"PT1M"` | 2.6 | -| [sourceType](#u__5__sourceType) | `enum` | The source of the vehicle updates. | *Required* | | 2.2 | -| url | `uri` | URL of the locations endpoint. | *Required* | | 2.6 | -| [headers](#u__5__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.6 | - - -#### Details - -

    feedId

    - -**Since version:** `2.2` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /updaters/[5] - -The id of the data source, which will be the prefix of the parking lot's id. - -This will end up in the API responses as the feed id of the parking lot. - -

    sourceType

    - -**Since version:** `2.2` ∙ **Type:** `enum` ∙ **Cardinality:** `Required` -**Path:** /updaters/[5] -**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` | `siri-fm` - -The source of the vehicle updates. - -

    headers

    - -**Since version:** `2.6` ∙ **Type:** `map of string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[5] - -HTTP headers to add to the request. Any header key, value can be inserted. - - - -##### Example configuration - -```JSON -// router-config.json -{ - "updaters" : [ - { - "type" : "vehicle-parking", - "feedId" : "noi", - "sourceType" : "noi-open-data-hub", - "url" : "https://parking.otp.opendatahub.com/parking/all.json" - } - ] -} -``` - - - ## Bikeep @@ -320,36 +259,36 @@ HTTP headers to add to the request. Any header key, value can be inserted. | Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | |----------------------------------|:---------------:|------------------------------------------------------------------------------|:----------:|---------------|:-----:| | type = "vehicle-parking" | `enum` | The type of the updater. | *Required* | | 1.5 | -| [feedId](#u__14__feedId) | `string` | The id of the data source, which will be the prefix of the parking lot's id. | *Required* | | 2.2 | +| [feedId](#u__13__feedId) | `string` | The id of the data source, which will be the prefix of the parking lot's id. | *Required* | | 2.2 | | frequency | `duration` | How often to update the source. | *Optional* | `"PT1M"` | 2.6 | -| [sourceType](#u__14__sourceType) | `enum` | The source of the vehicle updates. | *Required* | | 2.2 | +| [sourceType](#u__13__sourceType) | `enum` | The source of the vehicle updates. | *Required* | | 2.2 | | url | `uri` | URL of the locations endpoint. | *Required* | | 2.6 | -| [headers](#u__14__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.6 | +| [headers](#u__13__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.6 | #### Details -

    feedId

    +

    feedId

    **Since version:** `2.2` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /updaters/[14] +**Path:** /updaters/[13] The id of the data source, which will be the prefix of the parking lot's id. This will end up in the API responses as the feed id of the parking lot. -

    sourceType

    +

    sourceType

    **Since version:** `2.2` ∙ **Type:** `enum` ∙ **Cardinality:** `Required` -**Path:** /updaters/[14] -**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` | `siri-fm` +**Path:** /updaters/[13] +**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `bikeep` | `siri-fm` The source of the vehicle updates. -

    headers

    +

    headers

    **Since version:** `2.6` ∙ **Type:** `map of string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[14] +**Path:** /updaters/[13] HTTP headers to add to the request. Any header key, value can be inserted. @@ -387,36 +326,36 @@ which requires SIRI 2.1. | Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | |----------------------------------|:---------------:|------------------------------------------------------------------------------|:----------:|---------------|:-----:| | type = "vehicle-parking" | `enum` | The type of the updater. | *Required* | | 1.5 | -| [feedId](#u__15__feedId) | `string` | The id of the data source, which will be the prefix of the parking lot's id. | *Required* | | 2.2 | +| [feedId](#u__14__feedId) | `string` | The id of the data source, which will be the prefix of the parking lot's id. | *Required* | | 2.2 | | frequency | `duration` | How often to update the source. | *Optional* | `"PT1M"` | 2.6 | -| [sourceType](#u__15__sourceType) | `enum` | The source of the vehicle updates. | *Required* | | 2.2 | -| [url](#u__15__url) | `uri` | URL of the SIRI-FM Light endpoint. | *Required* | | 2.6 | -| [headers](#u__15__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.6 | +| [sourceType](#u__14__sourceType) | `enum` | The source of the vehicle updates. | *Required* | | 2.2 | +| [url](#u__14__url) | `uri` | URL of the SIRI-FM Light endpoint. | *Required* | | 2.6 | +| [headers](#u__14__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.6 | #### Details -

    feedId

    +

    feedId

    **Since version:** `2.2` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /updaters/[15] +**Path:** /updaters/[14] The id of the data source, which will be the prefix of the parking lot's id. This will end up in the API responses as the feed id of the parking lot. -

    sourceType

    +

    sourceType

    **Since version:** `2.2` ∙ **Type:** `enum` ∙ **Cardinality:** `Required` -**Path:** /updaters/[15] -**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` | `siri-fm` +**Path:** /updaters/[14] +**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `bikeep` | `siri-fm` The source of the vehicle updates. -

    url

    +

    url

    **Since version:** `2.6` ∙ **Type:** `uri` ∙ **Cardinality:** `Required` -**Path:** /updaters/[15] +**Path:** /updaters/[14] URL of the SIRI-FM Light endpoint. @@ -427,10 +366,10 @@ The contents must also conform to the [Italian SIRI profile](https://github.com/ which requires SIRI 2.1. -

    headers

    +

    headers

    **Since version:** `2.6` ∙ **Type:** `map of string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[15] +**Path:** /updaters/[14] HTTP headers to add to the request. Any header key, value can be inserted. diff --git a/doc/user/sandbox/siri/SiriAzureUpdater.md b/doc/user/sandbox/siri/SiriAzureUpdater.md index 7b29e802f21..c8e7f4d9255 100644 --- a/doc/user/sandbox/siri/SiriAzureUpdater.md +++ b/doc/user/sandbox/siri/SiriAzureUpdater.md @@ -25,14 +25,14 @@ To enable the SIRI updater you need to add it to the updaters section of the `ro | Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | |------------------------------------------------------------|:----------:|------------------------------------------------------------------|:----------:|---------------------|:-----:| | type = "siri-azure-et-updater" | `enum` | The type of the updater. | *Required* | | 1.5 | -| [authenticationType](#u__12__authenticationType) | `enum` | Which authentication type to use | *Optional* | `"sharedaccesskey"` | 2.5 | +| [authenticationType](#u__11__authenticationType) | `enum` | Which authentication type to use | *Optional* | `"sharedaccesskey"` | 2.5 | | autoDeleteOnIdle | `duration` | The time after which an inactive subscription is removed. | *Optional* | `"PT1H"` | 2.5 | -| [customMidnight](#u__12__customMidnight) | `integer` | Time on which time breaks into new day. | *Optional* | `0` | 2.2 | +| [customMidnight](#u__11__customMidnight) | `integer` | Time on which time breaks into new day. | *Optional* | `0` | 2.2 | | feedId | `string` | The ID of the feed to apply the updates to. | *Optional* | | 2.2 | -| [fullyQualifiedNamespace](#u__12__fullyQualifiedNamespace) | `string` | Service Bus fully qualified namespace used for authentication. | *Optional* | | 2.5 | +| [fullyQualifiedNamespace](#u__11__fullyQualifiedNamespace) | `string` | Service Bus fully qualified namespace used for authentication. | *Optional* | | 2.5 | | fuzzyTripMatching | `boolean` | Whether to apply fuzzyTripMatching on the updates | *Optional* | `false` | 2.2 | | prefetchCount | `integer` | The number of messages to fetch from the subscription at a time. | *Optional* | `10` | 2.5 | -| [servicebus-url](#u__12__servicebus_url) | `string` | Service Bus connection used for authentication. | *Optional* | | 2.2 | +| [servicebus-url](#u__11__servicebus_url) | `string` | Service Bus connection used for authentication. | *Optional* | | 2.2 | | topic | `string` | Service Bus topic to connect to. | *Optional* | | 2.2 | | history | `object` | Configuration for fetching historical data on startup | *Optional* | | 2.2 | |    fromDateTime | `string` | Datetime boundary for historical data | *Optional* | `"-P1D"` | 2.2 | @@ -42,36 +42,36 @@ To enable the SIRI updater you need to add it to the updaters section of the `ro ##### Parameter details -

    authenticationType

    +

    authenticationType

    **Since version:** `2.5` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"sharedaccesskey"` -**Path:** /updaters/[12] +**Path:** /updaters/[11] **Enum values:** `sharedaccesskey` | `federatedidentity` Which authentication type to use -

    customMidnight

    +

    customMidnight

    **Since version:** `2.2` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0` -**Path:** /updaters/[12] +**Path:** /updaters/[11] Time on which time breaks into new day. It is common that operating day date breaks a little bit later than midnight so that the switch happens when traffic is at the lowest point. Parameter uses 24-hour format. If the switch happens on 4 am then set this field to 4. -

    fullyQualifiedNamespace

    +

    fullyQualifiedNamespace

    **Since version:** `2.5` ∙ **Type:** `string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[12] +**Path:** /updaters/[11] Service Bus fully qualified namespace used for authentication. Has to be present for authenticationMethod FederatedIdentity. -

    servicebus-url

    +

    servicebus-url

    **Since version:** `2.2` ∙ **Type:** `string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[12] +**Path:** /updaters/[11] Service Bus connection used for authentication. @@ -113,14 +113,14 @@ Has to be present for authenticationMethod SharedAccessKey. This should be Prima | Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | |------------------------------------------------------------|:----------:|------------------------------------------------------------------|:----------:|---------------------|:-----:| | type = "siri-azure-sx-updater" | `enum` | The type of the updater. | *Required* | | 1.5 | -| [authenticationType](#u__11__authenticationType) | `enum` | Which authentication type to use | *Optional* | `"sharedaccesskey"` | 2.5 | +| [authenticationType](#u__10__authenticationType) | `enum` | Which authentication type to use | *Optional* | `"sharedaccesskey"` | 2.5 | | autoDeleteOnIdle | `duration` | The time after which an inactive subscription is removed. | *Optional* | `"PT1H"` | 2.5 | -| [customMidnight](#u__11__customMidnight) | `integer` | Time on which time breaks into new day. | *Optional* | `0` | 2.2 | +| [customMidnight](#u__10__customMidnight) | `integer` | Time on which time breaks into new day. | *Optional* | `0` | 2.2 | | feedId | `string` | The ID of the feed to apply the updates to. | *Optional* | | 2.2 | -| [fullyQualifiedNamespace](#u__11__fullyQualifiedNamespace) | `string` | Service Bus fully qualified namespace used for authentication. | *Optional* | | 2.5 | +| [fullyQualifiedNamespace](#u__10__fullyQualifiedNamespace) | `string` | Service Bus fully qualified namespace used for authentication. | *Optional* | | 2.5 | | fuzzyTripMatching | `boolean` | Whether to apply fuzzyTripMatching on the updates | *Optional* | `false` | 2.2 | | prefetchCount | `integer` | The number of messages to fetch from the subscription at a time. | *Optional* | `10` | 2.5 | -| [servicebus-url](#u__11__servicebus_url) | `string` | Service Bus connection used for authentication. | *Optional* | | 2.2 | +| [servicebus-url](#u__10__servicebus_url) | `string` | Service Bus connection used for authentication. | *Optional* | | 2.2 | | topic | `string` | Service Bus topic to connect to. | *Optional* | | 2.2 | | history | `object` | Configuration for fetching historical data on startup | *Optional* | | 2.2 | |    fromDateTime | `string` | Datetime boundary for historical data. | *Optional* | `"-P1D"` | 2.2 | @@ -131,36 +131,36 @@ Has to be present for authenticationMethod SharedAccessKey. This should be Prima ##### Parameter details -

    authenticationType

    +

    authenticationType

    **Since version:** `2.5` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"sharedaccesskey"` -**Path:** /updaters/[11] +**Path:** /updaters/[10] **Enum values:** `sharedaccesskey` | `federatedidentity` Which authentication type to use -

    customMidnight

    +

    customMidnight

    **Since version:** `2.2` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0` -**Path:** /updaters/[11] +**Path:** /updaters/[10] Time on which time breaks into new day. It is common that operating day date breaks a little bit later than midnight so that the switch happens when traffic is at the lowest point. Parameter uses 24-hour format. If the switch happens on 4 am then set this field to 4. -

    fullyQualifiedNamespace

    +

    fullyQualifiedNamespace

    **Since version:** `2.5` ∙ **Type:** `string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[11] +**Path:** /updaters/[10] Service Bus fully qualified namespace used for authentication. Has to be present for authenticationMethod FederatedIdentity. -

    servicebus-url

    +

    servicebus-url

    **Since version:** `2.2` ∙ **Type:** `string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[11] +**Path:** /updaters/[10] Service Bus connection used for authentication. diff --git a/doc/user/sandbox/siri/SiriGooglePubSubUpdater.md b/doc/user/sandbox/siri/SiriGooglePubSubUpdater.md index 74dfc4a4238..5232696ad9b 100644 --- a/doc/user/sandbox/siri/SiriGooglePubSubUpdater.md +++ b/doc/user/sandbox/siri/SiriGooglePubSubUpdater.md @@ -31,22 +31,23 @@ of the `router-config.json`. | Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | |------------------------------------------------------------|:----------:|----------------------------------------------------------------------------------|:----------:|---------------|:-----:| | type = "siri-et-google-pubsub-updater" | `enum` | The type of the updater. | *Required* | | 1.5 | -| [dataInitializationUrl](#u__13__dataInitializationUrl) | `string` | URL used to download over HTTP the recent history of SIRI-ET messages. | *Optional* | | 2.1 | +| [dataInitializationUrl](#u__12__dataInitializationUrl) | `string` | URL used to download over HTTP the recent history of SIRI-ET messages. | *Optional* | | 2.1 | | feedId | `string` | The ID of the feed to apply the updates to. | *Optional* | | 2.1 | | fuzzyTripMatching | `boolean` | If the trips should be matched fuzzily. | *Optional* | `false` | 2.1 | -| [initialGetDataTimeout](#u__13__initialGetDataTimeout) | `duration` | Timeout for retrieving the recent history of SIRI-ET messages. | *Optional* | `"PT30S"` | 2.1 | -| [reconnectPeriod](#u__13__reconnectPeriod) | `duration` | Wait this amount of time before trying to reconnect to the PubSub subscription. | *Optional* | `"PT30S"` | 2.1 | -| [subscriptionProjectName](#u__13__subscriptionProjectName) | `string` | The Google Cloud project that hosts the PubSub subscription. | *Required* | | 2.1 | +| [initialGetDataTimeout](#u__12__initialGetDataTimeout) | `duration` | Timeout for retrieving the recent history of SIRI-ET messages. | *Optional* | `"PT30S"` | 2.1 | +| producerMetrics | `boolean` | If failure, success, and warning metrics should be collected per producer. | *Optional* | `false` | 2.7 | +| [reconnectPeriod](#u__12__reconnectPeriod) | `duration` | Wait this amount of time before trying to reconnect to the PubSub subscription. | *Optional* | `"PT30S"` | 2.1 | +| [subscriptionProjectName](#u__12__subscriptionProjectName) | `string` | The Google Cloud project that hosts the PubSub subscription. | *Required* | | 2.1 | | topicName | `string` | The name of the PubSub topic that publishes the updates. | *Required* | | 2.1 | | topicProjectName | `string` | The Google Cloud project that hosts the PubSub topic that publishes the updates. | *Required* | | 2.1 | ##### Parameter details -

    dataInitializationUrl

    +

    dataInitializationUrl

    **Since version:** `2.1` ∙ **Type:** `string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[13] +**Path:** /updaters/[12] URL used to download over HTTP the recent history of SIRI-ET messages. @@ -55,10 +56,10 @@ If this parameter is set, the updater will be marked as initialized (primed) onl the message history is fully downloaded and applied. -

    initialGetDataTimeout

    +

    initialGetDataTimeout

    **Since version:** `2.1` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT30S"` -**Path:** /updaters/[13] +**Path:** /updaters/[12] Timeout for retrieving the recent history of SIRI-ET messages. @@ -67,10 +68,10 @@ of time for the connection to be established. If the connection times out, the updater will retry indefinitely with exponential backoff. -

    reconnectPeriod

    +

    reconnectPeriod

    **Since version:** `2.1` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT30S"` -**Path:** /updaters/[13] +**Path:** /updaters/[12] Wait this amount of time before trying to reconnect to the PubSub subscription. @@ -78,10 +79,10 @@ In case of a network error, the updater will try periodically to reconnect to th Google PubSub subscription. -

    subscriptionProjectName

    +

    subscriptionProjectName

    **Since version:** `2.1` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /updaters/[13] +**Path:** /updaters/[12] The Google Cloud project that hosts the PubSub subscription. diff --git a/doc/user/sandbox/siri/SiriUpdater.md b/doc/user/sandbox/siri/SiriUpdater.md index 72ab45d0f39..28f2f9a85db 100644 --- a/doc/user/sandbox/siri/SiriUpdater.md +++ b/doc/user/sandbox/siri/SiriUpdater.md @@ -35,18 +35,19 @@ To enable the SIRI updater you need to add it to the updaters section of the `ro | frequency | `duration` | How often the updates should be retrieved. | *Optional* | `"PT1M"` | 2.0 | | fuzzyTripMatching | `boolean` | If the fuzzy trip matcher should be used to match trips. | *Optional* | `false` | 2.0 | | previewInterval | `duration` | TODO | *Optional* | | 2.0 | +| producerMetrics | `boolean` | If failure, success, and warning metrics should be collected per producer. | *Optional* | `false` | 2.7 | | requestorRef | `string` | The requester reference. | *Optional* | | 2.0 | | timeout | `duration` | The HTTP timeout to download the updates. | *Optional* | `"PT15S"` | 2.0 | -| [url](#u__9__url) | `string` | The URL to send the HTTP requests to. | *Required* | | 2.0 | -| [headers](#u__9__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | +| [url](#u__8__url) | `string` | The URL to send the HTTP requests to. | *Required* | | 2.0 | +| [headers](#u__8__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | ##### Parameter details -

    url

    +

    url

    **Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /updaters/[9] +**Path:** /updaters/[8] The URL to send the HTTP requests to. @@ -58,10 +59,10 @@ renamed by the loader when processed: -

    headers

    +

    headers

    **Since version:** `2.3` ∙ **Type:** `map of string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[9] +**Path:** /updaters/[8] HTTP headers to add to the request. Any header key, value can be inserted. @@ -93,25 +94,25 @@ HTTP headers to add to the request. Any header key, value can be inserted. -| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | -|----------------------------------|:---------------:|--------------------------------------------------------------------------------------------------------|:----------:|---------------|:-----:| -| type = "siri-sx-updater" | `enum` | The type of the updater. | *Required* | | 1.5 | -| blockReadinessUntilInitialized | `boolean` | Whether catching up with the updates should block the readiness check from returning a 'ready' result. | *Optional* | `false` | 2.0 | -| [earlyStart](#u__10__earlyStart) | `duration` | This value is subtracted from the actual validity defined in the message. | *Optional* | `"PT0S"` | 2.0 | -| feedId | `string` | The ID of the feed to apply the updates to. | *Required* | | 2.0 | -| frequency | `duration` | How often the updates should be retrieved. | *Optional* | `"PT1M"` | 2.0 | -| requestorRef | `string` | The requester reference. | *Optional* | | 2.0 | -| timeout | `duration` | The HTTP timeout to download the updates. | *Optional* | `"PT15S"` | 2.0 | -| [url](#u__10__url) | `string` | The URL to send the HTTP requests to. Supports http/https and file protocol. | *Required* | | 2.0 | -| [headers](#u__10__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | +| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | +|---------------------------------|:---------------:|--------------------------------------------------------------------------------------------------------|:----------:|---------------|:-----:| +| type = "siri-sx-updater" | `enum` | The type of the updater. | *Required* | | 1.5 | +| blockReadinessUntilInitialized | `boolean` | Whether catching up with the updates should block the readiness check from returning a 'ready' result. | *Optional* | `false` | 2.0 | +| [earlyStart](#u__9__earlyStart) | `duration` | This value is subtracted from the actual validity defined in the message. | *Optional* | `"PT0S"` | 2.0 | +| feedId | `string` | The ID of the feed to apply the updates to. | *Required* | | 2.0 | +| frequency | `duration` | How often the updates should be retrieved. | *Optional* | `"PT1M"` | 2.0 | +| requestorRef | `string` | The requester reference. | *Optional* | | 2.0 | +| timeout | `duration` | The HTTP timeout to download the updates. | *Optional* | `"PT15S"` | 2.0 | +| [url](#u__9__url) | `string` | The URL to send the HTTP requests to. Supports http/https and file protocol. | *Required* | | 2.0 | +| [headers](#u__9__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | ##### Parameter details -

    earlyStart

    +

    earlyStart

    **Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"` -**Path:** /updaters/[10] +**Path:** /updaters/[9] This value is subtracted from the actual validity defined in the message. @@ -119,10 +120,10 @@ Normally the planned departure time is used, so setting this to 10s will cause t SX-message to be included in trip-results 10 seconds before the the planned departure time. -

    url

    +

    url

    **Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /updaters/[10] +**Path:** /updaters/[9] The URL to send the HTTP requests to. Supports http/https and file protocol. @@ -135,10 +136,10 @@ renamed by the loader when processed: -

    headers

    +

    headers

    **Since version:** `2.3` ∙ **Type:** `map of string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[10] +**Path:** /updaters/[9] HTTP headers to add to the request. Any header key, value can be inserted. diff --git a/doc/user/sandbox/transferanalyzer.md b/doc/user/sandbox/transferanalyzer.md index edc1a2579ea..d1dfabe10b2 100644 --- a/doc/user/sandbox/transferanalyzer.md +++ b/doc/user/sandbox/transferanalyzer.md @@ -17,5 +17,5 @@ generates lists of both unusually long and unroutable transfers. These lists can to improve the quality of OSM data for transfer purposes. See javadoc in -[DirectTransferAnalyzer](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/ext/java/org/opentripplanner/ext/transferanalyzer/DirectTransferAnalyzer.java) +[DirectTransferAnalyzer](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/application/src/ext/java/org/opentripplanner/ext/transferanalyzer/DirectTransferAnalyzer.java) class \ No newline at end of file diff --git a/gtfs-realtime-protobuf/pom.xml b/gtfs-realtime-protobuf/pom.xml new file mode 100644 index 00000000000..e4465a4d366 --- /dev/null +++ b/gtfs-realtime-protobuf/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + org.opentripplanner + otp-root + 2.7.0-SNAPSHOT + + gtfs-realtime-protobuf + OpenTripPlanner - GTFS Realtime (protobuf) + + + + com.google.protobuf + protobuf-java + + + + + + + kr.motd.maven + os-maven-plugin + 1.7.1 + + + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + 0.6.1 + + + + compile + test-compile + + + + + com.google.protobuf:protoc:3.22.0:exe:${os.detected.classifier} + + + + + \ No newline at end of file diff --git a/src/main/proto/gtfs-realtime.proto b/gtfs-realtime-protobuf/src/main/proto/gtfs-realtime.proto similarity index 100% rename from src/main/proto/gtfs-realtime.proto rename to gtfs-realtime-protobuf/src/main/proto/gtfs-realtime.proto diff --git a/src/main/proto/mfdz-realtime-extensions.proto b/gtfs-realtime-protobuf/src/main/proto/mfdz-realtime-extensions.proto similarity index 100% rename from src/main/proto/mfdz-realtime-extensions.proto rename to gtfs-realtime-protobuf/src/main/proto/mfdz-realtime-extensions.proto diff --git a/magidoc.mjs b/magidoc.mjs index 595ba25c0c0..d43945f976c 100644 --- a/magidoc.mjs +++ b/magidoc.mjs @@ -1,7 +1,7 @@ export default { introspection: { type: 'sdl', - paths: ['src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls'], + paths: ['application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls'], }, website: { template: 'carbon-multi-page', @@ -9,6 +9,7 @@ export default { options: { siteRoot: '/api/dev-2.x/graphql-gtfs', appLogo: 'https://docs.opentripplanner.org/en/dev-2.x/images/otp-logo.svg', + customStyles: ['https://docs.opentripplanner.org/en/dev-2.x/css/magidoc-overrides.css'], pages: [{ title: 'Introduction', content: ` diff --git a/mkdocs.yml b/mkdocs.yml index 8b3748be2b0..51245f6c3b8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -56,12 +56,12 @@ nav: - Visual Identity: 'Visual-Identity.md' - 'Usage': - Basic Tutorial: 'Basic-Tutorial.md' - - Data Sources: 'Data-Sources.md' + - Netex and SIRI Tutorial: 'Netex-Tutorial.md' - Getting OTP: 'Getting-OTP.md' + - Data Sources: 'Data-Sources.md' - Container Image: 'Container-Image.md' - System Requirements and Suggestions: 'System-Requirements.md' - Preparing OSM Data: 'Preparing-OSM.md' - - Netex and SIRI: 'Netex-Norway.md' - Troubleshooting: 'Troubleshooting-Routing.md' - Comparing OTP2 to OTP1: 'Version-Comparison.md' - Frontends: 'Frontends.md' @@ -74,7 +74,7 @@ nav: - Introduction: 'Configuration.md' - Build: 'BuildConfiguration.md' - OSM Tag Mapping: - - Default: 'osm/Default.md' + - Default: 'osm/OsmTag.md' - Finland: 'osm/Finland.md' - Germany: 'osm/Germany.md' - Norway: 'osm/Norway.md' @@ -82,6 +82,7 @@ nav: - Router: 'RouterConfiguration.md' - "Route Request": 'RouteRequest.md' - "Realtime Updaters": 'UpdaterConfig.md' + - "Debug UI": 'DebugUiConfiguration.md' - "Migrating between versions/builds": 'Migrating-Configuration.md' - Features explained: - "Routing modes": 'RoutingModes.md' @@ -90,11 +91,11 @@ nav: - "Stop Area Relations": 'StopAreas.md' - "Street Graph Pruning": 'IslandPruning.md' - Accessibility: 'Accessibility.md' + - NeTex and Siri compatibility: 'features-explained/Netex-Siri-Compatibility.md' - "Travel Time Analysis": 'Analysis.md' - "Logging": "Logging.md" - Development: - "Developers' Guide": 'Developers-Guide.md' - - Localization: 'Localization.md' - Bibliography: 'Bibliography.md' - Sandbox Development: 'SandboxExtension.md' - Release Checklist: 'ReleaseChecklist.md' @@ -121,3 +122,4 @@ nav: - Ride Hailing: 'sandbox/RideHailing.md' - Emissions: 'sandbox/Emissions.md' - Stop Consolidation: 'sandbox/StopConsolidation.md' + - Sørlandsbanen: 'sandbox/Sorlandsbanen.md' diff --git a/pom.xml b/pom.xml index 8eb3e64d897..a502f3d57bc 100644 --- a/pom.xml +++ b/pom.xml @@ -1,14 +1,16 @@ - + 4.0.0 + org.opentripplanner + otp-root + 2.7.0-SNAPSHOT + pom - OpenTripPlanner + OpenTripPlanner - Root The OpenTripPlanner multimodal journey planning system https://opentripplanner.org - org.opentripplanner - otp - 2.6.0-SNAPSHOT - jar @@ -56,17 +58,17 @@ - 157 + 174 - 31.3 + 32.1 2.52 - 2.17.2 - 3.1.8 - 5.11.0 - 1.13.4 + 2.18.2 + 3.1.9 + 5.11.3 + 1.14.1 5.6.0 - 1.5.7 - 9.11.1 + 1.5.12 + 9.12.0 2.0.16 2.0.15 1.27 @@ -80,7 +82,7 @@ 0.22 write - + false @@ -91,53 +93,25 @@ + + utils + raptor + gtfs-realtime-protobuf + application + shaded-jar + + + - - - - src/main/resources - true - - - src/ext/resources - true - - - src/client - client - false - - - - - src/test/resources - - - src/ext-test/resources - - - - - - src/scripts - true - - ../.. - - - - - - kr.motd.maven - os-maven-plugin - 1.7.1 - - + + + + org.apache.maven.plugins + maven-shade-plugin + 3.6.0 + + + org.apache.maven.plugins @@ -174,10 +148,13 @@ package-javadoc package - jar + + jar + ${basedir}/doc/javadoc javadoc + true @@ -206,43 +183,10 @@ UTF-8 - - org.codehaus.mojo - build-helper-maven-plugin - 3.6.0 - - - build-helper-generate-sources - generate-sources - - add-source - - - - src/main/java - src/ext/java - - - - - build-helper-generate-test-sources - generate-test-sources - - add-test-source - - - - src/test/java - src/ext-test/java - - - - - org.apache.maven.plugins maven-surefire-plugin - 3.3.1 + 3.5.2 me.fabriciorby @@ -290,8 +234,6 @@ --add-opens java.base/sun.invoke.util=ALL-UNNAMED --add-opens java.xml/org.xml.sax.helpers=ALL-UNNAMED - - true plain true @@ -305,6 +247,7 @@ true true false + UNICODE @@ -344,91 +287,17 @@ - - - - org.apache.maven.plugins - maven-shade-plugin - 3.6.0 - - - package - - shade - - - - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - true - shaded - false - - - - - - - org.opentripplanner.standalone.OTPMain - - Java Advanced Imaging Image I/O - Tools - - 1.1 - Sun Microsystems, Inc. - com.sun.media.imageio - 1.1 - Sun Microsystems, Inc. - com.sun.media.imageio - - - - - - - com.hubspot.maven.plugins prettier-maven-plugin ${plugin.prettier.version} + ${plugin.prettier.skip} 2.0.0 src/main/java/**/*.java src/test/java/**/*.java - src/ext/java/**/*.java - src/ext-test/java/**/*.java + src/**/*.json src/test/resources/org/opentripplanner/apis/**/*.graphql @@ -440,12 +309,11 @@ - com.google.cloud.tools jib-maven-plugin - 3.4.3 + 3.4.4 org.opentripplanner.standalone.OTPMain @@ -494,27 +362,6 @@ - - - - org.xolstice.maven.plugins - protobuf-maven-plugin - 0.6.1 - - - - compile - test-compile - - - - - com.google.protobuf:protoc:3.22.0:exe:${os.detected.classifier} - - @@ -524,9 +371,9 @@ Maven tries to download from every other repository and fails before checking central. Do not change the id from central2 to central, otherwise the entry will be ignored. --> - central2 - Check central first to avoid a lot of not found warnings - https://repo.maven.apache.org/maven2 + central2 + Check central first to avoid a lot of not found warnings + https://repo.maven.apache.org/maven2 osgeo @@ -541,381 +388,102 @@ com.google.cloud libraries-bom - 26.45.0 + 26.48.0 pom import - - - - - - - org.slf4j - slf4j-api - ${slf4j.version} - - - - org.slf4j - jul-to-slf4j - ${slf4j.version} - - - - ch.qos.logback - logback-classic - ${logback.version} - - - - net.logstash.logback - logstash-logback-encoder - 8.0 - - - - - com.google.dagger - dagger - ${google.dagger.version} - - - - - - - org.geotools - gt-coverage - ${geotools.version} - - - org.geotools - gt-geotiff - ${geotools.version} - - - org.geotools - gt-api - ${geotools.version} - - - org.geotools - gt-geojson-core - ${geotools.version} - - - - - org.apache.lucene - lucene-core - ${lucene.version} - - - org.apache.lucene - lucene-queryparser - ${lucene.version} - - - org.apache.lucene - lucene-suggest - ${lucene.version} - - - - io.micrometer - micrometer-registry-prometheus - ${micrometer.version} - - - io.micrometer - micrometer-registry-influx - ${micrometer.version} - test - - - - - - edu.ucar - netcdf4 - ${netcdf4.version} - - - - org.entur - netex-java-model - ${netex-java-model.version} - - - - - org.entur - siri-java-model - ${siri-java-model.version} - - - - - org.entur - siri-protobuf-mapper - 1.0.3 - - - - org.mobilitydata - gbfs-java-model - 1.0.7 - - - - - org.junit.jupiter - junit-jupiter-api - ${junit.version} - test - - - org.junit.jupiter - junit-jupiter-params - ${junit.version} - test - - - com.google.truth - truth - 1.4.4 - test - - - com.tngtech.archunit - archunit - 1.3.0 - test - - - org.mockito - mockito-core - 5.12.0 - test - - - io.github.origin-energy - java-snapshot-testing-junit5 - 2.3.0 - test - - - - - com.conveyal - kryo-tools - 1.6.0 - - - - de.javakaffee - kryo-serializers - 0.45 - - - - com.google.guava - guava - 33.2.1-jre - - - - org.glassfish.jersey.core - jersey-server - ${jersey.version} - - - - org.glassfish.jersey.containers - jersey-container-grizzly2-http - ${jersey.version} - - - - org.glassfish.jersey.media - jersey-media-json-jackson - ${jersey.version} - - - - org.glassfish.jersey.inject - jersey-hk2 - ${jersey.version} - - - - - org.glassfish.jaxb - jaxb-runtime - ${jaxb-runtime.version} - - - - - com.fasterxml.jackson.core - jackson-core - ${jackson.version} - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - - - com.fasterxml.jackson.datatype - jackson-datatype-jdk8 - ${jackson.version} - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - ${jackson.version} - - - - com.fasterxml.jackson.core - jackson-annotations - ${jackson.version} - - - + + + org.slf4j + slf4j-api + ${slf4j.version} + - - - com.google.cloud - google-cloud-storage - + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + net.sf.trove4j + trove4j + 3.0.3 + + + com.google.guava + guava + 33.3.1-jre + - - - com.google.cloud - google-cloud-pubsub - + + + + org.geotools + gt-coverage + ${geotools.version} + + + org.geotools + gt-geotiff + ${geotools.version} + + + org.geotools + gt-api + ${geotools.version} + + + org.geotools + gt-geojson-core + ${geotools.version} + + + de.grundid.opendatalab + geojson-jackson + 1.14 + - - - com.google.protobuf - protobuf-java - + - - - org.onebusaway - onebusaway-gtfs - 3.2.3 - - - - org.processing - core - 2.2.1 - - - - net.java.dev.jets3t - jets3t - 0.9.4 - - - - org.openstreetmap.osmosis - osmosis-osm-binary - 0.48.3 - - - - com.beust - jcommander - 1.82 - - - com.graphql-java - graphql-java - 22.3 - - - com.graphql-java - graphql-java-extended-scalars - 22.0 - - - org.apache.httpcomponents.client5 - httpclient5 - 5.3.1 - - - commons-cli - commons-cli - 1.5.0 - test - - - net.sourceforge.javacsv - javacsv - 2.0 - - - org.eclipse.paho - org.eclipse.paho.client.mqttv3 - 1.2.5 - - - io.github.ci-cmg - mapbox-vector-tile - 4.0.6 - - - net.objecthunter - exp4j - 0.4.8 - - - com.azure - azure-core - 1.46.0 - - - com.azure - azure-messaging-servicebus - 7.15.0 - - - com.azure - azure-identity - 1.11.2 - compile - - - ch.poole - OpeningHoursParser - 0.28.2 - + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + + + org.junit.jupiter + junit-jupiter-params + ${junit.version} + + + com.google.truth + truth + 1.4.4 + + + com.tngtech.archunit + archunit + 1.3.0 + + + org.mockito + mockito-core + 5.14.2 + + + io.github.origin-energy + java-snapshot-testing-junit5 + 2.3.0 + - - - org.apache.commons - commons-compress - 1.27.0 - test - - + + @@ -938,18 +506,9 @@ - - - - com.hubspot.maven.plugins - prettier-maven-plugin - ${plugin.prettier.version} - - true - - - - + + true + clean-test-snapshots @@ -989,7 +548,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.2.5 + 3.2.7 sign-artifacts diff --git a/raptor/pom.xml b/raptor/pom.xml new file mode 100644 index 00000000000..faf38e5f6b3 --- /dev/null +++ b/raptor/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + org.opentripplanner + otp-root + 2.7.0-SNAPSHOT + + + raptor + OpenTripPlanner - Raptor + + + + + + ${project.groupId} + utils + ${project.version} + + + + + + + com.google.code.findbugs + jsr305 + + + net.sf.trove4j + trove4j + + + + org.slf4j + slf4j-api + + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-params + test + + + com.tngtech.archunit + archunit + test + + + diff --git a/src/main/java/org/opentripplanner/raptor/RaptorService.java b/raptor/src/main/java/org/opentripplanner/raptor/RaptorService.java similarity index 83% rename from src/main/java/org/opentripplanner/raptor/RaptorService.java rename to raptor/src/main/java/org/opentripplanner/raptor/RaptorService.java index d8e7fcd3dcd..599a4104414 100644 --- a/src/main/java/org/opentripplanner/raptor/RaptorService.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/RaptorService.java @@ -1,6 +1,7 @@ package org.opentripplanner.raptor; import java.util.stream.Collectors; +import javax.annotation.Nullable; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.request.RaptorRequest; import org.opentripplanner.raptor.api.response.RaptorResponse; @@ -8,6 +9,7 @@ import org.opentripplanner.raptor.service.DefaultStopArrivals; import org.opentripplanner.raptor.service.HeuristicSearchTask; import org.opentripplanner.raptor.service.RangeRaptorDynamicSearch; +import org.opentripplanner.raptor.spi.ExtraMcRouterSearch; import org.opentripplanner.raptor.spi.RaptorTransitDataProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,8 +25,16 @@ public class RaptorService { private final RaptorConfig config; - public RaptorService(RaptorConfig config) { + @Nullable + private final ExtraMcRouterSearch extraMcSearch; + + public RaptorService(RaptorConfig config, @Nullable ExtraMcRouterSearch extraMcSearch) { this.config = config; + this.extraMcSearch = extraMcSearch; + } + + public RaptorService(RaptorConfig config) { + this(config, null); } public RaptorResponse route( @@ -35,7 +45,8 @@ public RaptorResponse route( RaptorResponse response; if (request.isDynamicSearch()) { - response = new RangeRaptorDynamicSearch<>(config, transitData, request).route(); + response = + new RangeRaptorDynamicSearch<>(config, transitData, extraMcSearch, request).route(); } else { response = routeUsingStdWorker(transitData, request); } @@ -68,8 +79,8 @@ private RaptorResponse routeUsingStdWorker( RaptorTransitDataProvider transitData, RaptorRequest request ) { - var worker = config.createStdWorker(transitData, request); - var result = worker.route(); + var rangeRaptorRouter = config.createRangeRaptorWithStdWorker(transitData, request); + var result = rangeRaptorRouter.route(); var arrivals = new DefaultStopArrivals(result); return new RaptorResponse<>(result.extractPaths(), arrivals, request, false); } diff --git a/src/main/java/org/opentripplanner/raptor/RaptorTimeLine.svg b/raptor/src/main/java/org/opentripplanner/raptor/RaptorTimeLine.svg similarity index 100% rename from src/main/java/org/opentripplanner/raptor/RaptorTimeLine.svg rename to raptor/src/main/java/org/opentripplanner/raptor/RaptorTimeLine.svg diff --git a/src/main/java/org/opentripplanner/raptor/api/debug/DebugEvent.java b/raptor/src/main/java/org/opentripplanner/raptor/api/debug/DebugEvent.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/api/debug/DebugEvent.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/debug/DebugEvent.java index 7162a4a6641..a69e977efe3 100644 --- a/src/main/java/org/opentripplanner/raptor/api/debug/DebugEvent.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/debug/DebugEvent.java @@ -1,6 +1,6 @@ package org.opentripplanner.raptor.api.debug; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Debug events hold information about an internal event in the Raptor Algorithm. The element may be diff --git a/src/main/java/org/opentripplanner/raptor/api/debug/DebugLogger.java b/raptor/src/main/java/org/opentripplanner/raptor/api/debug/DebugLogger.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/debug/DebugLogger.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/debug/DebugLogger.java diff --git a/src/main/java/org/opentripplanner/raptor/api/debug/DebugTopic.java b/raptor/src/main/java/org/opentripplanner/raptor/api/debug/DebugTopic.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/debug/DebugTopic.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/debug/DebugTopic.java diff --git a/src/main/java/org/opentripplanner/raptor/api/debug/RaptorTimers.java b/raptor/src/main/java/org/opentripplanner/raptor/api/debug/RaptorTimers.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/debug/RaptorTimers.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/debug/RaptorTimers.java diff --git a/src/main/java/org/opentripplanner/raptor/api/model/AbstractAccessEgressDecorator.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/AbstractAccessEgressDecorator.java similarity index 89% rename from src/main/java/org/opentripplanner/raptor/api/model/AbstractAccessEgressDecorator.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/AbstractAccessEgressDecorator.java index ddb266e0884..eb1a388f91c 100644 --- a/src/main/java/org/opentripplanner/raptor/api/model/AbstractAccessEgressDecorator.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/model/AbstractAccessEgressDecorator.java @@ -16,6 +16,18 @@ public AbstractAccessEgressDecorator(RaptorAccessEgress delegate) { this.delegate = delegate; } + public static RaptorAccessEgress accessEgressWithExtraSlack( + RaptorAccessEgress delegate, + int slack + ) { + return new AbstractAccessEgressDecorator(delegate) { + @Override + public int durationInSeconds() { + return super.durationInSeconds() + slack; + } + }; + } + protected RaptorAccessEgress delegate() { return delegate; } diff --git a/src/main/java/org/opentripplanner/raptor/api/model/DominanceFunction.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/DominanceFunction.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/model/DominanceFunction.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/DominanceFunction.java diff --git a/src/main/java/org/opentripplanner/raptor/api/model/GeneralizedCostRelaxFunction.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/GeneralizedCostRelaxFunction.java similarity index 96% rename from src/main/java/org/opentripplanner/raptor/api/model/GeneralizedCostRelaxFunction.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/GeneralizedCostRelaxFunction.java index 0335e962d98..0038a8e2681 100644 --- a/src/main/java/org/opentripplanner/raptor/api/model/GeneralizedCostRelaxFunction.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/model/GeneralizedCostRelaxFunction.java @@ -3,8 +3,8 @@ import java.time.Duration; import java.util.Locale; import java.util.Objects; -import org.opentripplanner.framework.lang.IntUtils; -import org.opentripplanner.framework.lang.OtpNumberFormat; +import org.opentripplanner.utils.lang.IntUtils; +import org.opentripplanner.utils.lang.OtpNumberFormat; /** * This relax-function is used to relax increasing values by: diff --git a/src/main/java/org/opentripplanner/raptor/api/model/PathLegType.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/PathLegType.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/model/PathLegType.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/PathLegType.java diff --git a/src/main/java/org/opentripplanner/raptor/api/model/RaptorAccessEgress.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorAccessEgress.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/api/model/RaptorAccessEgress.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorAccessEgress.java index 3a7f48cf743..f970254dcc8 100644 --- a/src/main/java/org/opentripplanner/raptor/api/model/RaptorAccessEgress.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorAccessEgress.java @@ -4,8 +4,8 @@ import java.time.temporal.ChronoUnit; import javax.annotation.Nullable; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; /** * Encapsulate information about an access or egress path. We do not distinguish between diff --git a/src/main/java/org/opentripplanner/raptor/api/model/RaptorConstants.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorConstants.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/model/RaptorConstants.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorConstants.java diff --git a/src/main/java/org/opentripplanner/raptor/api/model/RaptorConstrainedTransfer.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorConstrainedTransfer.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/model/RaptorConstrainedTransfer.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorConstrainedTransfer.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostConverter.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorCostConverter.java similarity index 86% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostConverter.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorCostConverter.java index 210197f107b..3801c948e3e 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostConverter.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorCostConverter.java @@ -1,14 +1,14 @@ -package org.opentripplanner.routing.algorithm.raptoradapter.transit.cost; +package org.opentripplanner.raptor.api.model; import java.time.Duration; -import org.opentripplanner.raptor.api.model.RaptorValueFormatter; /** - * Convert Raptor internal cost to OTP domain model cost, and back. + * Convert Raptor internal cost to OTP domain model cost, and back. This is provided by the Raptor + * module as a utility, but not used in Raptor except in unit-tests. *

    - * Inside Raptor the a cost unit is 1/100 of a "transit second" using {@code int} as type. In the - * OTP internal domain the unit used for cost is one "transit second" with type {@code double}. Cost - * in raptor is calculated using ints to spped up the calculations and to save memory. + * Inside Raptor the cost unit is 1/100 of a "transit second" using {@code int} as type. In the + * OTP internal domain the unit used for cost is one "transit second" with type {@code double}. + * Cost in raptor is calculated using ints to speed up the calculations and to save memory. *

    * The reason for using 1/100 of a second resolution is that we want a cost factor of {@code 0.99} * to win over a cost factor of {@code 1.00}. diff --git a/src/main/java/org/opentripplanner/raptor/api/path/RaptorStopNameResolver.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorStopNameResolver.java similarity index 94% rename from src/main/java/org/opentripplanner/raptor/api/path/RaptorStopNameResolver.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorStopNameResolver.java index 1825c7965fe..a973e1732be 100644 --- a/src/main/java/org/opentripplanner/raptor/api/path/RaptorStopNameResolver.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorStopNameResolver.java @@ -1,4 +1,4 @@ -package org.opentripplanner.raptor.api.path; +package org.opentripplanner.raptor.api.model; import javax.annotation.Nullable; diff --git a/src/main/java/org/opentripplanner/raptor/api/model/RaptorTransfer.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorTransfer.java similarity index 84% rename from src/main/java/org/opentripplanner/raptor/api/model/RaptorTransfer.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorTransfer.java index bab4b9ab166..477c785eaa4 100644 --- a/src/main/java/org/opentripplanner/raptor/api/model/RaptorTransfer.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorTransfer.java @@ -1,6 +1,6 @@ package org.opentripplanner.raptor.api.model; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.utils.time.DurationUtils; /** * Encapsulate information about a transfer path. @@ -14,8 +14,7 @@ public interface RaptorTransfer { int stop(); /** - * The generalized cost of this transfer in centi-seconds. The value is used to compare with - * riding transit, and will be one component of a full itinerary. + * The generalized cost of this transfer in centi-seconds. *

    * This method is called many times, so care needs to be taken that the value is stored, not * calculated for each invocation. diff --git a/src/main/java/org/opentripplanner/raptor/api/model/RaptorTransferConstraint.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorTransferConstraint.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/model/RaptorTransferConstraint.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorTransferConstraint.java diff --git a/src/main/java/org/opentripplanner/raptor/api/model/RaptorTripPattern.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorTripPattern.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/model/RaptorTripPattern.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorTripPattern.java diff --git a/src/main/java/org/opentripplanner/raptor/api/model/RaptorTripSchedule.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorTripSchedule.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/model/RaptorTripSchedule.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorTripSchedule.java diff --git a/src/main/java/org/opentripplanner/raptor/api/model/RaptorValueFormatter.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorValueFormatter.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/model/RaptorValueFormatter.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorValueFormatter.java diff --git a/src/main/java/org/opentripplanner/raptor/api/model/RelaxFunction.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RelaxFunction.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/model/RelaxFunction.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/RelaxFunction.java diff --git a/src/main/java/org/opentripplanner/raptor/api/model/SearchDirection.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/SearchDirection.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/model/SearchDirection.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/SearchDirection.java diff --git a/src/main/java/org/opentripplanner/raptor/api/model/TransitArrival.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/TransitArrival.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/model/TransitArrival.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/model/TransitArrival.java diff --git a/src/main/java/org/opentripplanner/raptor/api/path/AccessPathLeg.java b/raptor/src/main/java/org/opentripplanner/raptor/api/path/AccessPathLeg.java similarity index 95% rename from src/main/java/org/opentripplanner/raptor/api/path/AccessPathLeg.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/path/AccessPathLeg.java index b76e0a1df4d..cb4a8030ff6 100644 --- a/src/main/java/org/opentripplanner/raptor/api/path/AccessPathLeg.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/path/AccessPathLeg.java @@ -1,7 +1,6 @@ package org.opentripplanner.raptor.api.path; import java.util.Objects; -import javax.annotation.Nonnull; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; @@ -20,11 +19,11 @@ public final class AccessPathLeg implements PathLe private final PathLeg next; public AccessPathLeg( - @Nonnull RaptorAccessEgress access, + RaptorAccessEgress access, int fromTime, int toTime, int c1, - @Nonnull PathLeg next + PathLeg next ) { this.access = access; this.fromTime = fromTime; diff --git a/src/main/java/org/opentripplanner/raptor/api/path/EgressPathLeg.java b/raptor/src/main/java/org/opentripplanner/raptor/api/path/EgressPathLeg.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/path/EgressPathLeg.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/path/EgressPathLeg.java diff --git a/src/main/java/org/opentripplanner/raptor/api/path/PathLeg.java b/raptor/src/main/java/org/opentripplanner/raptor/api/path/PathLeg.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/api/path/PathLeg.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/path/PathLeg.java index 35a351a4d77..20ffdbae34a 100644 --- a/src/main/java/org/opentripplanner/raptor/api/path/PathLeg.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/path/PathLeg.java @@ -4,9 +4,9 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; import javax.annotation.Nullable; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; /** * A leg in a Raptor path. The legs are linked together from the first leg {@link AccessPathLeg}, to diff --git a/src/main/java/org/opentripplanner/raptor/api/path/PathStringBuilder.java b/raptor/src/main/java/org/opentripplanner/raptor/api/path/PathStringBuilder.java similarity index 96% rename from src/main/java/org/opentripplanner/raptor/api/path/PathStringBuilder.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/path/PathStringBuilder.java index b96d1a96f14..cefba73f41f 100644 --- a/src/main/java/org/opentripplanner/raptor/api/path/PathStringBuilder.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/path/PathStringBuilder.java @@ -3,12 +3,13 @@ import java.time.ZonedDateTime; import java.util.function.Consumer; import javax.annotation.Nullable; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorValueFormatter; import org.opentripplanner.raptor.spi.RaptorCostCalculator; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; /** * Create a path like: {@code Walk 5m - 101 - Transit 10:07 10:35 - 2111 - Walk 4m } diff --git a/src/main/java/org/opentripplanner/raptor/api/path/RaptorPath.java b/raptor/src/main/java/org/opentripplanner/raptor/api/path/RaptorPath.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/api/path/RaptorPath.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/path/RaptorPath.java index b92d30643ec..78d90f1d9f4 100644 --- a/src/main/java/org/opentripplanner/raptor/api/path/RaptorPath.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/path/RaptorPath.java @@ -4,6 +4,7 @@ import java.util.stream.Stream; import javax.annotation.Nullable; import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.model.RelaxFunction; diff --git a/src/main/java/org/opentripplanner/raptor/api/path/TransferPathLeg.java b/raptor/src/main/java/org/opentripplanner/raptor/api/path/TransferPathLeg.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/path/TransferPathLeg.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/path/TransferPathLeg.java diff --git a/src/main/java/org/opentripplanner/raptor/api/path/TransitPathLeg.java b/raptor/src/main/java/org/opentripplanner/raptor/api/path/TransitPathLeg.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/path/TransitPathLeg.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/path/TransitPathLeg.java diff --git a/src/main/java/org/opentripplanner/raptor/api/request/DebugRequest.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/DebugRequest.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/api/request/DebugRequest.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/request/DebugRequest.java index 876175bae6e..91144d86917 100644 --- a/src/main/java/org/opentripplanner/raptor/api/request/DebugRequest.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/DebugRequest.java @@ -3,12 +3,12 @@ import java.util.List; import java.util.Objects; import java.util.function.Consumer; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.debug.DebugEvent; import org.opentripplanner.raptor.api.debug.DebugLogger; import org.opentripplanner.raptor.api.path.RaptorPath; import org.opentripplanner.raptor.api.view.ArrivalView; import org.opentripplanner.raptor.api.view.PatternRideView; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This class configure the amount of debugging you want for your request. Debugging is supported by diff --git a/src/main/java/org/opentripplanner/raptor/api/request/DebugRequestBuilder.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/DebugRequestBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/request/DebugRequestBuilder.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/request/DebugRequestBuilder.java diff --git a/src/main/java/org/opentripplanner/raptor/api/request/DynamicSearchWindowCoefficients.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/DynamicSearchWindowCoefficients.java similarity index 94% rename from src/main/java/org/opentripplanner/raptor/api/request/DynamicSearchWindowCoefficients.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/request/DynamicSearchWindowCoefficients.java index 27ebb62c870..4cc74c34c66 100644 --- a/src/main/java/org/opentripplanner/raptor/api/request/DynamicSearchWindowCoefficients.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/DynamicSearchWindowCoefficients.java @@ -60,11 +60,10 @@ default Duration minWindow() { /** * Set an upper limit to the calculation of the dynamic search window to prevent exceptionable - * cases to cause very long search windows. Long search windows consumes a lot of resources and + * cases to cause very long search windows. Long search windows consume a lot of resources and * may take a long time. Use this parameter to tune the desired maximum search time. *

    - * This is the parameter that affect the response time most, the downside is that a search is only - * guaranteed to be pareto-optimal within a search-window. + * This is the parameter that affects the response time the most. *

    * The default is 3 hours. The unit is minutes. */ diff --git a/src/main/java/org/opentripplanner/raptor/api/request/MultiCriteriaRequest.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/MultiCriteriaRequest.java similarity index 99% rename from src/main/java/org/opentripplanner/raptor/api/request/MultiCriteriaRequest.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/request/MultiCriteriaRequest.java index 683c9807af5..7f0da11b558 100644 --- a/src/main/java/org/opentripplanner/raptor/api/request/MultiCriteriaRequest.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/MultiCriteriaRequest.java @@ -4,9 +4,9 @@ import java.util.Objects; import java.util.Optional; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.model.RelaxFunction; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Parameters to configure the multi-criteria search. diff --git a/src/main/java/org/opentripplanner/raptor/api/request/Optimization.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/Optimization.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/request/Optimization.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/request/Optimization.java diff --git a/src/main/java/org/opentripplanner/raptor/api/request/PassThroughPoint.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/PassThroughPoint.java similarity index 95% rename from src/main/java/org/opentripplanner/raptor/api/request/PassThroughPoint.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/request/PassThroughPoint.java index b17fab84347..7c529343b32 100644 --- a/src/main/java/org/opentripplanner/raptor/api/request/PassThroughPoint.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/PassThroughPoint.java @@ -6,11 +6,14 @@ import java.util.function.IntFunction; import java.util.stream.IntStream; import javax.annotation.Nullable; -import org.opentripplanner.framework.lang.StringUtils; +import org.opentripplanner.utils.lang.StringUtils; /** * A collection of stop indexes used to define a pass through-point. + * + * @deprecated This will be replaced by ViaLocation */ +@Deprecated public class PassThroughPoint { private final String name; diff --git a/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorEnvironment.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorEnvironment.java new file mode 100644 index 00000000000..30e3abb5b27 --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorEnvironment.java @@ -0,0 +1,41 @@ +package org.opentripplanner.raptor.api.request; + +import java.util.concurrent.ExecutorService; +import javax.annotation.Nullable; + +/** + * The raptor environment provides a few hooks and integration points to the caller. The default + * implementation will work just fine, override to adjust Raptor to the calling application. + */ +public interface RaptorEnvironment { + Runnable NOOP = () -> {}; + + /** + * Use the timeout-hook to register a callback from Raptor. The hook is called periodically to + * check if a time-out is reached. The hook should then exit with an exception handled by the + * caller. Raptor does not have blocking method calls so just calling {@link Thread#interrupt()} + * will not terminate the Raptor search. + */ + default Runnable timeoutHook() { + return NOOP; + } + + /** + * Raptor has support for running a few things in parallel. If Raptor catches an + * {@link InterruptedException}, Raptor will convert the checked exception to an unchecked + * exception. The default is {@link RuntimeException}. Override this method to map + * {@link InterruptedException} to your prefered runtime exception. + */ + default RuntimeException mapInterruptedException(InterruptedException e) { + return new RuntimeException(e); + } + + /** + * Inject a thread pool into Raptor to run part of the raptor search in parallel. If no + * thread pool is provided, then Raptor runs everything in the caller thread. + */ + @Nullable + default ExecutorService threadPool() { + return null; + } +} diff --git a/src/main/java/org/opentripplanner/raptor/api/request/RaptorProfile.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorProfile.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/request/RaptorProfile.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorProfile.java diff --git a/src/main/java/org/opentripplanner/raptor/api/request/RaptorRequest.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorRequest.java similarity index 99% rename from src/main/java/org/opentripplanner/raptor/api/request/RaptorRequest.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorRequest.java index 010bff4bc08..3c27f5478c8 100644 --- a/src/main/java/org/opentripplanner/raptor/api/request/RaptorRequest.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorRequest.java @@ -4,10 +4,10 @@ import java.util.Collections; import java.util.Objects; import java.util.Set; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.debug.RaptorTimers; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.model.SearchDirection; +import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/raptor/api/request/RaptorRequestBuilder.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorRequestBuilder.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/request/RaptorRequestBuilder.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorRequestBuilder.java diff --git a/src/main/java/org/opentripplanner/raptor/api/request/RaptorTransitGroupPriorityCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorTransitGroupPriorityCalculator.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/request/RaptorTransitGroupPriorityCalculator.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorTransitGroupPriorityCalculator.java diff --git a/src/main/java/org/opentripplanner/raptor/api/request/RaptorTuningParameters.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorTuningParameters.java similarity index 86% rename from src/main/java/org/opentripplanner/raptor/api/request/RaptorTuningParameters.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorTuningParameters.java index d80c50ed7f5..a85fc3069f6 100644 --- a/src/main/java/org/opentripplanner/raptor/api/request/RaptorTuningParameters.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorTuningParameters.java @@ -20,11 +20,6 @@ default int iterationDepartureStepInSeconds() { return 60; } - /** see {@link org.opentripplanner.standalone.config.routerconfig.TransitRoutingConfig} **/ - default int searchThreadPoolSize() { - return 0; - } - /** * Coefficients used to calculate raptor-search-window parameters dynamically from heuristics. */ diff --git a/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorViaConnection.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorViaConnection.java new file mode 100644 index 00000000000..a8359e6c5fa --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorViaConnection.java @@ -0,0 +1,143 @@ +package org.opentripplanner.raptor.api.request; + +import java.util.Objects; +import javax.annotation.Nullable; +import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; +import org.opentripplanner.raptor.api.model.RaptorTransfer; +import org.opentripplanner.utils.time.DurationUtils; + +/** + * A via-connection is used to define one of the physical locations in a via location Raptor must + * visit. At least one connection in a {@link RaptorViaLocation} must be used. A connection can be + * a single stop or a stop and a transfer to another stop. The last is useful if you want to use + * the connection to visit something other than a stop, like a street location. + * This is not an alternative to transfers. Raptor supports several use-cases + * through via-connections: + * + *

    Route via a pass-through-stop

    + * Raptor will allow a path to go through a pass-through-stop. The stop can be visited on-board + * transit, or at the alight- or board-stop. The from-stop and to-stop must be the same, and the + * minimum-wait-time must be zero. + * + *

    Route via a single stop with a minimum-wait-time

    + * Raptor will allow a path to go through a single stop, if the from-stop and to-stop is the + * same. If the minimum-wait-time is greater than zero(0) the path will either alight or board + * transit at this stop, and the minimum-wait-time criteria is enforced. + * + *

    Route via a coordinate

    + * + * To route through a coordinate you need to find all nearby stops, then find all access and egress + * paths to and from the street location. Then combine all access and egress paths to form + * complete transfers. Raptor does not know/see the actual via street location, it only uses the + * connection from a stop to another, the total time it takes and the total cost. You must generate + * a transfer with two "legs" in it. One leg going from the 'from-stop' to the street location, and + * one leg going back to the 'to-stop'. If you have 10 stops around the via street location, then + * you must combine all ten access paths and egress paths. + * + * The min-wait-time in the {@link RaptorViaLocation} is added to the transfers + * {@code durationInSeconds}. The calculation of {@code c1} should include the walk time, but not + * the min-wait-time (assuming all connections have the same minimum wait time). + */ +public final class RaptorViaConnection { + + private final int fromStop; + private final int durationInSeconds; + + @Nullable + private final RaptorTransfer transfer; + + RaptorViaConnection(RaptorViaLocation parent, int fromStop, @Nullable RaptorTransfer transfer) { + this.fromStop = fromStop; + this.transfer = transfer; + this.durationInSeconds = + parent.minimumWaitTime() + + (transfer == null ? RaptorConstants.ZERO : transfer.durationInSeconds()); + } + + /** + * Stop index where the connection starts. + */ + public int fromStop() { + return fromStop; + } + + @Nullable + public RaptorTransfer transfer() { + return transfer; + } + + /** + * Stop index where the connection ends. This can be the same as the {@code fromStop}. + */ + public int toStop() { + return isSameStop() ? fromStop : transfer.stop(); + } + + /** + * The time duration to walk or travel from the {@code fromStop} to the {@code toStop}. + */ + public int durationInSeconds() { + return durationInSeconds; + } + + /** + * The generalized cost of this via-connection in centi-seconds. + *

    + * This method is called many times, so care needs to be taken that the value is stored, not + * calculated for each invocation. + */ + public int c1() { + return isSameStop() ? RaptorConstants.ZERO : transfer.c1(); + } + + public boolean isSameStop() { + return transfer == null; + } + + /** + * This method is used to check that all connections are unique/provide an optimal path. + * The method returns {@code true} if this instance is better or equals to the given other + * stop with respect to being pareto-optimal. + */ + boolean isBetterOrEqual(RaptorViaConnection other) { + if (fromStop != other.fromStop || toStop() != other.toStop()) { + return false; + } + return durationInSeconds() <= other.durationInSeconds() && c1() <= other.c1(); + } + + /** + * Only from and to stop is part of the equals/hashCode, duplicate connection between to stops + * are not allowed. + */ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + RaptorViaConnection that = (RaptorViaConnection) o; + return fromStop == that.fromStop && Objects.equals(transfer, that.transfer); + } + + @Override + public int hashCode() { + return Objects.hash(fromStop, transfer); + } + + @Override + public String toString() { + return toString(Integer::toString); + } + + public String toString(RaptorStopNameResolver stopNameResolver) { + var buf = new StringBuilder(stopNameResolver.apply(fromStop)); + if (transfer != null) { + buf.append("~").append(stopNameResolver.apply(toStop())); + } + int d = durationInSeconds(); + if (d > RaptorConstants.ZERO) { + buf.append(" ").append(DurationUtils.durationToStr(d)); + } + return buf.toString(); + } +} diff --git a/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorViaLocation.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorViaLocation.java new file mode 100644 index 00000000000..fbaae6dabdc --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/RaptorViaLocation.java @@ -0,0 +1,191 @@ +package org.opentripplanner.raptor.api.request; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import javax.annotation.Nullable; +import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; +import org.opentripplanner.raptor.api.model.RaptorTransfer; +import org.opentripplanner.utils.lang.IntUtils; +import org.opentripplanner.utils.time.DurationUtils; + +/** + * Defines a via location which Raptor will force the path through. The concrete location is + * called a connection. A location must have at least one connection, but can have more than + * on alternative. Raptor will force the path through one of the connections. So, if there + * are two connections, stop A and B, then Raptor will force the path through A or B. If the + * path goes through A, it may or may not go through B. + */ +public final class RaptorViaLocation { + + private static final int MAX_WAIT_TIME_LIMIT = (int) Duration.ofHours(24).toSeconds(); + + private final String label; + private final boolean allowPassThrough; + private final int minimumWaitTime; + private final List connections; + + private RaptorViaLocation( + String label, + boolean allowPassThrough, + Duration minimumWaitTime, + List connections + ) { + this.label = label; + this.allowPassThrough = allowPassThrough; + this.minimumWaitTime = + IntUtils.requireInRange( + (int) minimumWaitTime.toSeconds(), + RaptorConstants.ZERO, + MAX_WAIT_TIME_LIMIT, + "minimumWaitTime" + ); + this.connections = validateConnections(connections); + + if (allowPassThrough && this.minimumWaitTime > RaptorConstants.ZERO) { + throw new IllegalArgumentException("Pass-through and min-wait-time is not allowed."); + } + } + + /** + * Force the path through a set of stops, either on-board or as an alight or board stop. + */ + public static Builder allowPassThrough(@Nullable String label) { + return new Builder(label, true, Duration.ZERO); + } + + /** + * Force the path through one of the listed connections. To visit a stop, the path must board or + * alight transit at the given stop, on-board visits do not count, see + * {@link #allowPassThrough(String)}. + */ + public static Builder via(@Nullable String label) { + return new Builder(label, false, Duration.ZERO); + } + + /** + * Force the path through one of the listed connections, and wait the given minimum-wait-time + * before continuing. To visit a stop, the path must board or alight transit at the given stop, + * on-board visits do not count, see {@link #allowPassThrough(String)}. + */ + public static Builder via(@Nullable String label, Duration minimumWaitTime) { + return new Builder(label, false, minimumWaitTime); + } + + @Nullable + public String label() { + return label; + } + + public boolean allowPassThrough() { + return allowPassThrough; + } + + public int minimumWaitTime() { + return minimumWaitTime; + } + + public List connections() { + return connections; + } + + public String toString() { + return toString(Integer::toString); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + RaptorViaLocation that = (RaptorViaLocation) o; + return ( + allowPassThrough == that.allowPassThrough && + minimumWaitTime == that.minimumWaitTime && + Objects.equals(label, that.label) && + Objects.equals(connections, that.connections) + ); + } + + @Override + public int hashCode() { + return Objects.hash(label, allowPassThrough, minimumWaitTime, connections); + } + + public String toString(RaptorStopNameResolver stopNameResolver) { + var buf = new StringBuilder("Via{"); + if (label != null) { + buf.append("label: ").append(label).append(", "); + } + if (allowPassThrough) { + buf.append("allowPassThrough, "); + } + if (minimumWaitTime > RaptorConstants.ZERO) { + buf.append("minWaitTime: ").append(DurationUtils.durationToStr(minimumWaitTime)).append(", "); + } + buf + .append("connections: ") + .append(connections.stream().map(it -> it.toString(stopNameResolver)).toList()); + return buf.append("}").toString(); + } + + private List validateConnections(List connections) { + if (connections.isEmpty()) { + throw new IllegalArgumentException("At least one connection is required."); + } + var list = connections + .stream() + .map(it -> new RaptorViaConnection(this, it.fromStop, it.transfer)) + .toList(); + + // Compare all pairs to check for duplicates and non-optimal connections + for (int i = 0; i < list.size(); ++i) { + var a = list.get(i); + for (int j = i + 1; j < list.size(); ++j) { + var b = list.get(j); + if (a.isBetterOrEqual(b) || b.isBetterOrEqual(a)) { + throw new IllegalArgumentException( + "All connection need to be pareto-optimal: (" + a + ") <-> (" + b + ")" + ); + } + } + } + return list; + } + + public static final class Builder { + + private final String label; + private final boolean allowPassThrough; + private final Duration minimumWaitTime; + private final List connections = new ArrayList<>(); + + public Builder(String label, boolean allowPassThrough, Duration minimumWaitTime) { + this.label = label; + this.allowPassThrough = allowPassThrough; + this.minimumWaitTime = minimumWaitTime; + } + + public Builder addViaStop(int stop) { + this.connections.add(new StopAndTransfer(stop, null)); + return this; + } + + public Builder addViaTransfer(int fromStop, RaptorTransfer transfer) { + this.connections.add(new StopAndTransfer(fromStop, transfer)); + return this; + } + + public RaptorViaLocation build() { + return new RaptorViaLocation(label, allowPassThrough, minimumWaitTime, connections); + } + } + + /** + * Use internally to store connection data, before creating the connection objects. If is + * needed to create the bidirectional relationship between {@link RaptorViaLocation} and + * {@link RaptorViaConnection}. + */ + private record StopAndTransfer(int fromStop, @Nullable RaptorTransfer transfer) {} +} diff --git a/src/main/java/org/opentripplanner/raptor/api/request/SearchParams.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/SearchParams.java similarity index 90% rename from src/main/java/org/opentripplanner/raptor/api/request/SearchParams.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/request/SearchParams.java index 9bad7cf7222..d43d0f11ab6 100644 --- a/src/main/java/org/opentripplanner/raptor/api/request/SearchParams.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/SearchParams.java @@ -5,10 +5,10 @@ import java.util.Collection; import java.util.List; import java.util.Objects; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorTransfer; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * The responsibility of this class is to encapsulate a Range Raptor travel request search @@ -16,6 +16,12 @@ */ public class SearchParams { + /** + * The maximum number of via-locations is used as a check to avoid exploiting the + * search performance. Consider restricting this further in the upstream services. + */ + private static final int MAX_VIA_POINTS = 10; + private final int earliestDepartureTime; private final int latestArrivalTime; private final int searchWindowInSeconds; @@ -26,6 +32,7 @@ public class SearchParams { private final boolean constrainedTransfers; private final Collection accessPaths; private final Collection egressPaths; + private final List viaLocations; /** * Default values are defined in the default constructor. @@ -41,6 +48,7 @@ private SearchParams() { constrainedTransfers = false; accessPaths = List.of(); egressPaths = List.of(); + viaLocations = List.of(); } SearchParams(SearchParamsBuilder builder) { @@ -54,6 +62,7 @@ private SearchParams() { this.constrainedTransfers = builder.constrainedTransfers(); this.accessPaths = List.copyOf(builder.accessPaths()); this.egressPaths = List.copyOf(builder.egressPaths()); + this.viaLocations = List.copyOf(builder.viaLocations()); } /** @@ -195,6 +204,17 @@ public Collection egressPaths() { return egressPaths; } + /** + * List of all possible via locations. + */ + public List viaLocations() { + return viaLocations; + } + + public boolean hasViaLocations() { + return !viaLocations.isEmpty(); + } + /** * Get the maximum duration of any access or egress path in seconds. */ @@ -214,7 +234,8 @@ public int hashCode() { preferLateArrival, numberOfAdditionalTransfers, accessPaths, - egressPaths + egressPaths, + viaLocations ); } @@ -234,7 +255,8 @@ public boolean equals(Object o) { preferLateArrival == that.preferLateArrival && numberOfAdditionalTransfers == that.numberOfAdditionalTransfers && accessPaths.equals(that.accessPaths) && - egressPaths.equals(that.egressPaths) + egressPaths.equals(that.egressPaths) && + viaLocations.equals(viaLocations) ); } @@ -254,6 +276,7 @@ public String toString() { ) .addCollection("accessPaths", accessPaths, 5, RaptorAccessEgress::defaultToString) .addCollection("egressPaths", egressPaths, 5, RaptorAccessEgress::defaultToString) + .addCollection("via", viaLocations, 5) .toString(); } @@ -278,5 +301,9 @@ void verify() { !(preferLateArrival && timetable), "The 'departAsLateAsPossible' is not allowed together with 'timetableEnabled'." ); + assertProperty( + viaLocations.size() <= MAX_VIA_POINTS, + "The 'viaLocations' exceeds the maximum number of via-locations (" + MAX_VIA_POINTS + ")." + ); } } diff --git a/src/main/java/org/opentripplanner/raptor/api/request/SearchParamsBuilder.java b/raptor/src/main/java/org/opentripplanner/raptor/api/request/SearchParamsBuilder.java similarity index 89% rename from src/main/java/org/opentripplanner/raptor/api/request/SearchParamsBuilder.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/request/SearchParamsBuilder.java index 5774a92d6e1..cdb7146e814 100644 --- a/src/main/java/org/opentripplanner/raptor/api/request/SearchParamsBuilder.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/request/SearchParamsBuilder.java @@ -4,10 +4,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import org.opentripplanner.framework.tostring.ToStringBuilder; +import java.util.List; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * Mutable version of {@link SearchParams}. @@ -18,9 +19,7 @@ public class SearchParamsBuilder { private final RaptorRequestBuilder parent; - private final Collection accessPaths = new ArrayList<>(); - private final Collection egressPaths = new ArrayList<>(); - // Search + private int earliestDepartureTime; private int latestArrivalTime; private int searchWindowInSeconds; @@ -29,6 +28,9 @@ public class SearchParamsBuilder { private int maxNumberOfTransfers; private boolean timetable; private boolean constrainedTransfers; + private final Collection accessPaths = new ArrayList<>(); + private final Collection egressPaths = new ArrayList<>(); + private final List viaLocations = new ArrayList<>(); public SearchParamsBuilder(RaptorRequestBuilder parent, SearchParams defaults) { this.parent = parent; @@ -42,6 +44,7 @@ public SearchParamsBuilder(RaptorRequestBuilder parent, SearchParams defaults this.constrainedTransfers = defaults.constrainedTransfers(); this.accessPaths.addAll(defaults.accessPaths()); this.egressPaths.addAll(defaults.egressPaths()); + this.viaLocations.addAll(defaults.viaLocations()); } public int earliestDepartureTime() { @@ -72,9 +75,9 @@ public SearchParamsBuilder searchWindowInSeconds(int searchWindowInSeconds) { } public SearchParamsBuilder searchWindow(Duration searchWindow) { - this.searchWindowInSeconds = - searchWindow == null ? RaptorConstants.NOT_SET : (int) searchWindow.toSeconds(); - return this; + return searchWindowInSeconds( + searchWindow == null ? RaptorConstants.NOT_SET : (int) searchWindow.toSeconds() + ); } /** @@ -160,6 +163,20 @@ public SearchParamsBuilder addEgressPaths(RaptorAccessEgress... egressPaths) return addEgressPaths(Arrays.asList(egressPaths)); } + public Collection viaLocations() { + return viaLocations; + } + + public SearchParamsBuilder addViaLocation(RaptorViaLocation location) { + viaLocations.add(location); + return this; + } + + public SearchParamsBuilder addViaLocations(Collection locations) { + viaLocations.addAll(locations); + return this; + } + public RaptorRequest build() { return parent.build(); } @@ -180,6 +197,7 @@ public String toString() { .addNum("numberOfAdditionalTransfers", numberOfAdditionalTransfers) .addCollection("accessPaths", accessPaths, 5) .addCollection("egressPaths", egressPaths, 5) + .addCollection("via", viaLocations, 10) .toString(); } } diff --git a/src/main/java/org/opentripplanner/raptor/api/response/RaptorResponse.java b/raptor/src/main/java/org/opentripplanner/raptor/api/response/RaptorResponse.java similarity index 97% rename from src/main/java/org/opentripplanner/raptor/api/response/RaptorResponse.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/response/RaptorResponse.java index 82c0c06d0cd..5b0f1885a85 100644 --- a/src/main/java/org/opentripplanner/raptor/api/response/RaptorResponse.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/response/RaptorResponse.java @@ -1,11 +1,11 @@ package org.opentripplanner.raptor.api.response; import java.util.Collection; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.RaptorService; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.RaptorPath; import org.opentripplanner.raptor.api.request.RaptorRequest; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This is the result of a raptor search including the result paths, the original request diff --git a/src/main/java/org/opentripplanner/raptor/api/response/StopArrivals.java b/raptor/src/main/java/org/opentripplanner/raptor/api/response/StopArrivals.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/response/StopArrivals.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/response/StopArrivals.java diff --git a/src/main/java/org/opentripplanner/raptor/api/view/AccessPathView.java b/raptor/src/main/java/org/opentripplanner/raptor/api/view/AccessPathView.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/view/AccessPathView.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/view/AccessPathView.java diff --git a/src/main/java/org/opentripplanner/raptor/api/view/ArrivalView.java b/raptor/src/main/java/org/opentripplanner/raptor/api/view/ArrivalView.java similarity index 96% rename from src/main/java/org/opentripplanner/raptor/api/view/ArrivalView.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/view/ArrivalView.java index 862f7f17fb6..83e46f2d78f 100644 --- a/src/main/java/org/opentripplanner/raptor/api/view/ArrivalView.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/view/ArrivalView.java @@ -2,7 +2,6 @@ import java.util.function.IntFunction; import javax.annotation.Nullable; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor.api.model.PathLegType; import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorTransfer; @@ -10,7 +9,7 @@ import org.opentripplanner.raptor.api.model.RaptorValueFormatter; import org.opentripplanner.raptor.api.model.TransitArrival; import org.opentripplanner.raptor.spi.RaptorCostCalculator; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.DefaultCostCalculator; +import org.opentripplanner.utils.time.TimeUtils; /** * The purpose of the stop-arrival-view is to provide a common interface for stop-arrivals for @@ -157,7 +156,7 @@ default String asString() { String arrival = "[" + TimeUtils.timeToStrCompact(arrivalTime()) + - cost(c1(), DefaultCostCalculator.ZERO_COST, RaptorValueFormatter::formatC1) + + cost(c1(), RaptorCostCalculator.ZERO_COST, RaptorValueFormatter::formatC1) + cost(c2(), RaptorConstants.NOT_SET, RaptorValueFormatter::formatC2) + "]"; return switch (arrivedBy()) { diff --git a/src/main/java/org/opentripplanner/raptor/api/view/EgressPathView.java b/raptor/src/main/java/org/opentripplanner/raptor/api/view/EgressPathView.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/view/EgressPathView.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/view/EgressPathView.java diff --git a/src/main/java/org/opentripplanner/raptor/api/view/PatternRideView.java b/raptor/src/main/java/org/opentripplanner/raptor/api/view/PatternRideView.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/view/PatternRideView.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/view/PatternRideView.java diff --git a/src/main/java/org/opentripplanner/raptor/api/view/TransitPathView.java b/raptor/src/main/java/org/opentripplanner/raptor/api/view/TransitPathView.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/api/view/TransitPathView.java rename to raptor/src/main/java/org/opentripplanner/raptor/api/view/TransitPathView.java diff --git a/raptor/src/main/java/org/opentripplanner/raptor/configure/RaptorConfig.java b/raptor/src/main/java/org/opentripplanner/raptor/configure/RaptorConfig.java new file mode 100644 index 00000000000..66d72900889 --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/configure/RaptorConfig.java @@ -0,0 +1,200 @@ +package org.opentripplanner.raptor.configure; + +import java.util.concurrent.ExecutorService; +import javax.annotation.Nullable; +import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.raptor.api.request.RaptorEnvironment; +import org.opentripplanner.raptor.api.request.RaptorRequest; +import org.opentripplanner.raptor.api.request.RaptorTuningParameters; +import org.opentripplanner.raptor.rangeraptor.ConcurrentCompositeRaptorRouter; +import org.opentripplanner.raptor.rangeraptor.DefaultRangeRaptorWorker; +import org.opentripplanner.raptor.rangeraptor.RangeRaptor; +import org.opentripplanner.raptor.rangeraptor.RangeRaptorWorkerComposite; +import org.opentripplanner.raptor.rangeraptor.context.SearchContext; +import org.opentripplanner.raptor.rangeraptor.context.SearchContextViaLeg; +import org.opentripplanner.raptor.rangeraptor.internalapi.Heuristics; +import org.opentripplanner.raptor.rangeraptor.internalapi.PassThroughPointsService; +import org.opentripplanner.raptor.rangeraptor.internalapi.RangeRaptorWorker; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouter; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouterResult; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerState; +import org.opentripplanner.raptor.rangeraptor.internalapi.RoutingStrategy; +import org.opentripplanner.raptor.rangeraptor.multicriteria.McStopArrivals; +import org.opentripplanner.raptor.rangeraptor.multicriteria.configure.McRangeRaptorConfig; +import org.opentripplanner.raptor.rangeraptor.standard.configure.StdRangeRaptorConfig; +import org.opentripplanner.raptor.rangeraptor.transit.RaptorSearchWindowCalculator; +import org.opentripplanner.raptor.spi.ExtraMcRouterSearch; +import org.opentripplanner.raptor.spi.RaptorTransitDataProvider; + +/** + * This class is responsible for creating a new search and holding application scoped Raptor state. + *

    + * This class should have APPLICATION scope. It keeps a reference to the environment and the + * tuning parameters. The environment has a thread-pool, which should be APPLICATION scope. + * + * @param The TripSchedule type defined by the user of the raptor API. + */ +public class RaptorConfig { + + private final RaptorEnvironment environment; + private final RaptorTuningParameters tuningParameters; + + /** The service is not final, because it depends on the request. */ + private PassThroughPointsService passThroughPointsService = null; + + public RaptorConfig(RaptorTuningParameters tuningParameters, RaptorEnvironment environment) { + this.tuningParameters = tuningParameters; + this.environment = environment; + } + + public static RaptorConfig defaultConfigForTest() { + return new RaptorConfig<>(new RaptorTuningParameters() {}, new RaptorEnvironment() {}); + } + + public SearchContext context(RaptorTransitDataProvider transit, RaptorRequest request) { + // The passThroughPointsService is needed to create the context, so we initialize it here. + this.passThroughPointsService = createPassThroughPointsService(request); + var acceptC2AtDestination = passThroughPointsService.isNoop() + ? null + : passThroughPointsService.acceptC2AtDestination(); + return SearchContext.of(request, tuningParameters, transit, acceptC2AtDestination).build(); + } + + public RaptorRouter createRangeRaptorWithStdWorker( + RaptorTransitDataProvider transitData, + RaptorRequest request + ) { + var context = context(transitData, request); + var stdConfig = new StdRangeRaptorConfig<>(context); + var worker = createWorker(context.legs().getFirst(), stdConfig.state(), stdConfig.strategy()); + return createRangeRaptor(context, worker); + } + + public RaptorRouter createRangeRaptorWithMcWorker( + RaptorTransitDataProvider transitData, + RaptorRequest request, + Heuristics heuristics, + @Nullable ExtraMcRouterSearch extraMcSearch + ) { + var mainSearch = createRangeRaptorWithMcWorker(transitData, request, heuristics); + + if (extraMcSearch == null) { + return mainSearch; + } + var alternativeSearch = createRangeRaptorWithMcWorker( + extraMcSearch.createTransitDataAlternativeSearch(transitData), + request, + heuristics + ); + return new ConcurrentCompositeRaptorRouter<>( + mainSearch, + alternativeSearch, + extraMcSearch.merger(), + threadPool(), + environment::mapInterruptedException + ); + } + + private RaptorRouter createRangeRaptorWithMcWorker( + RaptorTransitDataProvider transitData, + RaptorRequest request, + Heuristics heuristics + ) { + var context = context(transitData, request); + RangeRaptorWorker worker = null; + McStopArrivals nextStopArrivals = null; + + if (request.searchParams().hasViaLocations()) { + for (SearchContextViaLeg cxLeg : context.legs().reversed()) { + var c = new McRangeRaptorConfig<>(cxLeg, passThroughPointsService) + .connectWithNextLegArrivals(nextStopArrivals); + var w = createWorker(cxLeg, c.state(), c.strategy()); + worker = RangeRaptorWorkerComposite.of(w, worker); + nextStopArrivals = c.stopArrivals(); + } + } else { + // The first leg is the only leg + var leg = context.legs().getFirst(); + var c = new McRangeRaptorConfig<>(leg, passThroughPointsService).withHeuristics(heuristics); + worker = createWorker(leg, c.state(), c.strategy()); + } + return createRangeRaptor(context, worker); + } + + public RaptorRouter createRangeRaptorWithHeuristicSearch( + RaptorTransitDataProvider transitData, + RaptorRequest request + ) { + return createRangeRaptorWithStdWorker(transitData, request); + } + + public Heuristics createHeuristic( + RaptorTransitDataProvider transitData, + RaptorRequest request, + RaptorRouterResult results + ) { + var context = context(transitData, request); + return new StdRangeRaptorConfig<>(context).createHeuristics(results); + } + + public boolean isMultiThreaded() { + return threadPool() != null; + } + + @Nullable + public ExecutorService threadPool() { + return environment.threadPool(); + } + + public void shutdown() { + if (threadPool() != null) { + threadPool().shutdown(); + } + } + + public RuntimeException mapInterruptedException(InterruptedException e) { + return environment.mapInterruptedException(e); + } + + public RaptorSearchWindowCalculator searchWindowCalculator() { + return new RaptorSearchWindowCalculator(tuningParameters.dynamicSearchWindowCoefficients()); + } + + /* private factory methods */ + + private static PassThroughPointsService createPassThroughPointsService(RaptorRequest request) { + return McRangeRaptorConfig.passThroughPointsService(request.multiCriteria()); + } + + private RangeRaptorWorker createWorker( + SearchContextViaLeg ctxLeg, + RaptorWorkerState workerState, + RoutingStrategy routingStrategy + ) { + var ctx = ctxLeg.parent(); + return new DefaultRangeRaptorWorker<>( + workerState, + routingStrategy, + ctx.transitData(), + ctx.slackProvider(), + ctxLeg.accessPaths(), + ctx.calculator(), + ctx.lifeCycle(), + ctx.performanceTimers(), + ctx.useConstrainedTransfers() + ); + } + + private RaptorRouter createRangeRaptor(SearchContext ctx, RangeRaptorWorker worker) { + return new RangeRaptor<>( + worker, + ctx.transitData(), + ctx.legs().getFirst().accessPaths(), + ctx.roundTracker(), + ctx.calculator(), + ctx.createLifeCyclePublisher(), + ctx.performanceTimers(), + environment.timeoutHook() + ); + } +} diff --git a/src/main/java/org/opentripplanner/raptor/package.md b/raptor/src/main/java/org/opentripplanner/raptor/package.md similarity index 100% rename from src/main/java/org/opentripplanner/raptor/package.md rename to raptor/src/main/java/org/opentripplanner/raptor/package.md diff --git a/src/main/java/org/opentripplanner/raptor/path/Path.java b/raptor/src/main/java/org/opentripplanner/raptor/path/Path.java similarity index 99% rename from src/main/java/org/opentripplanner/raptor/path/Path.java rename to raptor/src/main/java/org/opentripplanner/raptor/path/Path.java index ebade8b2690..99f226df0ef 100644 --- a/src/main/java/org/opentripplanner/raptor/path/Path.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/path/Path.java @@ -8,6 +8,7 @@ import java.util.stream.Stream; import javax.annotation.Nullable; import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.AccessPathLeg; @@ -15,7 +16,6 @@ import org.opentripplanner.raptor.api.path.PathLeg; import org.opentripplanner.raptor.api.path.PathStringBuilder; import org.opentripplanner.raptor.api.path.RaptorPath; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.api.path.TransitPathLeg; /** diff --git a/src/main/java/org/opentripplanner/raptor/path/PathBuilder.java b/raptor/src/main/java/org/opentripplanner/raptor/path/PathBuilder.java similarity index 99% rename from src/main/java/org/opentripplanner/raptor/path/PathBuilder.java rename to raptor/src/main/java/org/opentripplanner/raptor/path/PathBuilder.java index 7612cc0b3ba..3d0d5e706f6 100644 --- a/src/main/java/org/opentripplanner/raptor/path/PathBuilder.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/path/PathBuilder.java @@ -6,12 +6,12 @@ import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorConstrainedTransfer; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.AccessPathLeg; import org.opentripplanner.raptor.api.path.PathStringBuilder; import org.opentripplanner.raptor.api.path.RaptorPath; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.spi.BoardAndAlightTime; import org.opentripplanner.raptor.spi.RaptorCostCalculator; import org.opentripplanner.raptor.spi.RaptorPathConstrainedTransferSearch; diff --git a/src/main/java/org/opentripplanner/raptor/path/PathBuilderLeg.java b/raptor/src/main/java/org/opentripplanner/raptor/path/PathBuilderLeg.java similarity index 99% rename from src/main/java/org/opentripplanner/raptor/path/PathBuilderLeg.java rename to raptor/src/main/java/org/opentripplanner/raptor/path/PathBuilderLeg.java index 335d38203b1..eb80b36316b 100644 --- a/src/main/java/org/opentripplanner/raptor/path/PathBuilderLeg.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/path/PathBuilderLeg.java @@ -2,7 +2,6 @@ import java.util.function.Predicate; import javax.annotation.Nullable; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorConstrainedTransfer; @@ -22,6 +21,7 @@ import org.opentripplanner.raptor.spi.BoardAndAlightTime; import org.opentripplanner.raptor.spi.RaptorCostCalculator; import org.opentripplanner.raptor.spi.RaptorSlackProvider; +import org.opentripplanner.utils.time.TimeUtils; /** * This is the leg implementation for the {@link PathBuilder}. It helps to cache and calculate diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/CompositeResult.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/CompositeResult.java new file mode 100644 index 00000000000..e72c4731cc5 --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/CompositeResult.java @@ -0,0 +1,62 @@ +package org.opentripplanner.raptor.rangeraptor; + +import java.util.Collection; +import java.util.function.BiFunction; +import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.raptor.api.path.RaptorPath; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouterResult; +import org.opentripplanner.raptor.rangeraptor.internalapi.SingleCriteriaStopArrivals; + +/** + * Join two results together. + *

      + *
    • Everything from the first result is added
    • + *
    • The result is merged with the injected merge strategy.
    • + *
    • Some of the methods ONLY return the result of the main search!
    • + *
    + */ +class CompositeResult implements RaptorRouterResult { + + private static final String UNSUPPORTED_OPERATION = + "Merging all stop arrivals will be a complicated and memory intensive process, unless we need this this should not be done."; + private final Collection> result; + + CompositeResult( + RaptorRouterResult mainResult, + RaptorRouterResult alternativeResult, + BiFunction>, Collection>, Collection>> merger + ) { + this.result = merger.apply(mainResult.extractPaths(), alternativeResult.extractPaths()); + } + + /** + * Return the merged result. + */ + @Override + public Collection> extractPaths() { + return result; + } + + @Override + public SingleCriteriaStopArrivals extractBestOverallArrivals() { + throw new UnsupportedOperationException(UNSUPPORTED_OPERATION); + } + + @Override + public SingleCriteriaStopArrivals extractBestTransitArrivals() { + throw new UnsupportedOperationException(UNSUPPORTED_OPERATION); + } + + @Override + public SingleCriteriaStopArrivals extractBestNumberOfTransfers() { + throw new UnsupportedOperationException(UNSUPPORTED_OPERATION); + } + + /** + * Return true if either the main or the alternative search has reached the destination. + */ + @Override + public boolean isDestinationReached() { + return !result.isEmpty(); + } +} diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/ConcurrentCompositeRaptorRouter.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/ConcurrentCompositeRaptorRouter.java new file mode 100644 index 00000000000..1a16c6f0527 --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/ConcurrentCompositeRaptorRouter.java @@ -0,0 +1,72 @@ +package org.opentripplanner.raptor.rangeraptor; + +import java.util.Collection; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.function.BiFunction; +import java.util.function.Function; +import javax.annotation.Nullable; +import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.raptor.api.path.RaptorPath; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouter; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouterResult; + +/** + * Run two Raptor routers and join the result. The two searches are run concurrently if an + * {@link ExecutorService} is provided. + * @see CompositeResult for joining results. + */ +public class ConcurrentCompositeRaptorRouter + implements RaptorRouter { + + private final RaptorRouter mainWorker; + private final RaptorRouter alternativeWorker; + private final BiFunction>, Collection>, Collection>> merger; + + @Nullable + private final ExecutorService executorService; + + @Nullable + private final Function mapInterruptedException; + + public ConcurrentCompositeRaptorRouter( + RaptorRouter mainWorker, + RaptorRouter alternativeWorker, + BiFunction>, Collection>, Collection>> merger, + @Nullable ExecutorService executorService, + @Nullable Function mapInterruptedException + ) { + this.mainWorker = mainWorker; + this.alternativeWorker = alternativeWorker; + this.merger = merger; + this.executorService = executorService; + this.mapInterruptedException = mapInterruptedException; + } + + @Override + public RaptorRouterResult route() { + if (executorService == null) { + var mainResult = mainWorker.route(); + var alternativeResult = alternativeWorker.route(); + return new CompositeResult<>(mainResult, alternativeResult, merger); + } + + var mainResultFuture = executorService.submit(mainWorker::route); + var alternativeResultFuture = executorService.submit(alternativeWorker::route); + + try { + var mainResult = mainResultFuture.get(); + var alternativeResult = alternativeResultFuture.get(); + return new CompositeResult<>(mainResult, alternativeResult, merger); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + // propagate interruption to the running task. + + mainResultFuture.cancel(true); + alternativeResultFuture.cancel(true); + throw mapInterruptedException.apply(e); + } catch (ExecutionException e) { + throw (e.getCause() instanceof RuntimeException re) ? re : new RuntimeException(e); + } + } +} diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/DefaultRangeRaptorWorker.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/DefaultRangeRaptorWorker.java similarity index 64% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/DefaultRangeRaptorWorker.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/DefaultRangeRaptorWorker.java index 0f2ceb9d6e4..ca71c85af22 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/DefaultRangeRaptorWorker.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/DefaultRangeRaptorWorker.java @@ -1,21 +1,19 @@ package org.opentripplanner.raptor.rangeraptor; import java.util.Collection; -import org.opentripplanner.framework.application.OTPRequestTimeoutException; +import javax.annotation.Nullable; import org.opentripplanner.raptor.api.debug.RaptorTimers; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; -import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorker; -import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerResult; +import org.opentripplanner.raptor.rangeraptor.internalapi.RangeRaptorWorker; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouterResult; import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerState; -import org.opentripplanner.raptor.rangeraptor.internalapi.RoundProvider; import org.opentripplanner.raptor.rangeraptor.internalapi.RoutingStrategy; import org.opentripplanner.raptor.rangeraptor.internalapi.SlackProvider; -import org.opentripplanner.raptor.rangeraptor.lifecycle.LifeCycleEventPublisher; +import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; import org.opentripplanner.raptor.rangeraptor.transit.AccessPaths; import org.opentripplanner.raptor.rangeraptor.transit.RaptorTransitCalculator; -import org.opentripplanner.raptor.rangeraptor.transit.RoundTracker; import org.opentripplanner.raptor.spi.IntIterator; import org.opentripplanner.raptor.spi.RaptorTransitDataProvider; @@ -50,7 +48,7 @@ */ @SuppressWarnings("Duplicates") public final class DefaultRangeRaptorWorker - implements RaptorWorker { + implements RangeRaptorWorker { private final RoutingStrategy transitWorker; @@ -65,12 +63,6 @@ public final class DefaultRangeRaptorWorker */ private final RaptorWorkerState state; - /** - * The round tracker keep track for the current Raptor round, and abort the search if the round - * max limit is reached. - */ - private final RoundTracker roundTracker; - private final RaptorTransitDataProvider transitData; private final SlackProvider slackProvider; @@ -79,25 +71,27 @@ public final class DefaultRangeRaptorWorker private final RaptorTimers timers; + @Nullable private final AccessPaths accessPaths; - private final LifeCycleEventPublisher lifeCycle; - - private final int minNumberOfRounds; - private final boolean enableTransferConstraints; private int iterationDepartureTime; + private int round; + + /** + * @param accessPaths can be null in case the worker is chained - only the first worker has + * access. + */ public DefaultRangeRaptorWorker( RaptorWorkerState state, RoutingStrategy transitWorker, RaptorTransitDataProvider transitData, SlackProvider slackProvider, - AccessPaths accessPaths, - RoundProvider roundProvider, + @Nullable AccessPaths accessPaths, RaptorTransitCalculator calculator, - LifeCycleEventPublisher lifeCyclePublisher, + WorkerLifeCycle lifeCycle, RaptorTimers timers, boolean enableTransferConstraints ) { @@ -108,92 +102,30 @@ public DefaultRangeRaptorWorker( this.calculator = calculator; this.timers = timers; this.accessPaths = accessPaths; - this.minNumberOfRounds = accessPaths.calculateMaxNumberOfRides(); this.enableTransferConstraints = enableTransferConstraints; - // We do a cast here to avoid exposing the round tracker and the life cycle publisher to - // "everyone" by providing access to it in the context. - this.roundTracker = (RoundTracker) roundProvider; - this.lifeCycle = lifeCyclePublisher; + lifeCycle.onSetupIteration(time -> this.iterationDepartureTime = time); + lifeCycle.onPrepareForNextRound(round -> this.round = round); } - /** - * For each iteration (minute), calculate the minimum travel time to each transit stop in - * seconds. - *

    - * Run the scheduled search, round 0 is the street search. - */ @Override - public RaptorWorkerResult route() { - timers.route(() -> { - lifeCycle.notifyRouteSearchStart(calculator.searchForward()); - transitData.setup(); - - // The main outer loop iterates backward over all minutes in the departure times window. - // Ergo, we re-use the arrival times found in searches that have already occurred that - // depart later, because the arrival time given departure at time t is upper-bounded by - // the arrival time given departure at minute t + 1. - final IntIterator it = calculator.rangeRaptorMinutes(); - while (it.hasNext()) { - setupIteration(it.next()); - runRaptorForMinute(); - } - - // Iterate over virtual departure times - this is needed to allow access with a time-penalty - // which falls outside the search-window due to the added time-penalty. - if (!calculator.oneIterationOnly()) { - final IntIterator as = accessPaths.iterateOverPathsWithPenalty(iterationDepartureTime); - while (as.hasNext()) { - setupIteration(as.next()); - runRaptorForMinute(); - } - } - }); + public RaptorRouterResult result() { return state.results(); } - /** - * Perform one minute of a RAPTOR search. - */ - private void runRaptorForMinute() { - findAccessOnStreetForRound(); - - while (hasMoreRounds()) { - lifeCycle.prepareForNextRound(roundTracker.nextRound()); - - // NB since we have transfer limiting not bothering to cut off search when there are no - // more transfers as that will be rare and complicates the code - findTransitForRound(); - - findAccessOnBoardForRound(); - - findTransfersForRound(); - - lifeCycle.roundComplete(state.isDestinationReachedInCurrentRound()); - - findAccessOnStreetForRound(); - } - - // This state is repeatedly modified as the outer loop progresses over departure minutes. - // We have to be careful here, the next iteration will modify the state, so we need to make - // protective copies of any information we want to retain. - lifeCycle.iterationComplete(); - } - /** * Check if the RangeRaptor should continue with a new round. */ - private boolean hasMoreRounds() { - if (round() < minNumberOfRounds) { - return true; - } - return state.isNewRoundAvailable() && roundTracker.hasMoreRounds(); + @Override + public boolean hasMoreRounds() { + return state.isNewRoundAvailable(); } /** * Perform a scheduled search */ - private void findTransitForRound() { + @Override + public void findTransitForRound() { timers.findTransitForRound(() -> { IntIterator stops = state.stopsTouchedPreviousRound(); IntIterator routeIndexIterator = transitData.routeIndexIterator(stops); @@ -248,11 +180,11 @@ private void findTransitForRound() { } } } - lifeCycle.transitsForRoundComplete(); }); } - private void findTransfersForRound() { + @Override + public void findTransfersForRound() { timers.findTransfersForRound(() -> { IntIterator it = state.stopsTouchedByTransitCurrentRound(); @@ -262,30 +194,22 @@ private void findTransfersForRound() { // loop transfers are already included by virtue of those stops having been reached state.transferToStops(fromStop, calculator.getTransfers(transitData, fromStop)); } - - lifeCycle.transfersForRoundComplete(); }); } - private int round() { - return roundTracker.round(); - } - - private void findAccessOnStreetForRound() { - addAccessPaths(accessPaths.arrivedOnStreetByNumOfRides(round())); + @Override + public boolean isDestinationReachedInCurrentRound() { + return state.isDestinationReachedInCurrentRound(); } - private void findAccessOnBoardForRound() { - addAccessPaths(accessPaths.arrivedOnBoardByNumOfRides(round())); + @Override + public void findAccessOnStreetForRound() { + addAccessPaths(accessPaths.arrivedOnStreetByNumOfRides(round)); } - /** - * Run the raptor search for this particular iteration departure time - */ - private void setupIteration(int iterationDepartureTime) { - OTPRequestTimeoutException.checkForTimeout(); - this.iterationDepartureTime = iterationDepartureTime; - lifeCycle.setupIteration(this.iterationDepartureTime); + @Override + public void findAccessOnBoardForRound() { + addAccessPaths(accessPaths.arrivedOnBoardByNumOfRides(round)); } /** diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/RangeRaptor.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/RangeRaptor.java new file mode 100644 index 00000000000..02fb2a627e9 --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/RangeRaptor.java @@ -0,0 +1,176 @@ +package org.opentripplanner.raptor.rangeraptor; + +import static java.util.Objects.requireNonNull; + +import org.opentripplanner.raptor.api.debug.RaptorTimers; +import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.raptor.rangeraptor.internalapi.RangeRaptorWorker; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouter; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouterResult; +import org.opentripplanner.raptor.rangeraptor.lifecycle.LifeCycleEventPublisher; +import org.opentripplanner.raptor.rangeraptor.transit.AccessPaths; +import org.opentripplanner.raptor.rangeraptor.transit.RaptorTransitCalculator; +import org.opentripplanner.raptor.rangeraptor.transit.RoundTracker; +import org.opentripplanner.raptor.spi.IntIterator; +import org.opentripplanner.raptor.spi.RaptorTransitDataProvider; + +/** + * The algorithm used herein is described in + *

    + * Conway, Matthew Wigginton, Andrew Byrd, and Marco van der Linden. “Evidence-Based Transit and + * Land Use Sketch Planning Using Interactive Accessibility Methods on Combined Schedule and + * Headway-Based Networks.” Transportation Research Record 2653 (2017). doi:10.3141/2653-06. + *

    + * + * Delling, Daniel, Thomas Pajor, and Renato Werneck. “Round-Based Public Transit Routing”, + * January 1, 2012. + * . + *

    + * This version supports the following features: + *

      + *
    • Raptor (R) + *
    • Range Raptor (RR) + *
    • Multi-criteria pareto optimal Range Raptor (McRR) + *
    • Reverse search in combination with R and RR + *
    + * This version does NOT support the following features: + *
      + *
    • Frequency routes, supported by the original code using Monte Carlo methods + * (generating randomized schedules) + *
    + *

    + * This class originated as a rewrite of Conveyals RAPTOR code: https://github.com/conveyal/r5. + * + * @param The TripSchedule type defined by the user of the raptor API. + */ +@SuppressWarnings("Duplicates") +public final class RangeRaptor implements RaptorRouter { + + private final RangeRaptorWorker worker; + + /** + * The round tracker keep track for the current Raptor round, and abort the search if the round + * max limit is reached. + */ + private final RoundTracker roundTracker; + + private final RaptorTransitDataProvider transitData; + + private final RaptorTransitCalculator calculator; + + private final RaptorTimers timers; + + private final AccessPaths accessPaths; + + private final LifeCycleEventPublisher lifeCycle; + + private final Runnable timeoutHook; + + private final int minNumberOfRounds; + + public RangeRaptor( + RangeRaptorWorker worker, + RaptorTransitDataProvider transitData, + AccessPaths accessPaths, + RoundTracker roundTracker, + RaptorTransitCalculator calculator, + LifeCycleEventPublisher lifeCyclePublisher, + RaptorTimers timers, + Runnable timeoutHook + ) { + this.worker = requireNonNull(worker); + this.transitData = requireNonNull(transitData); + this.calculator = requireNonNull(calculator); + this.timers = requireNonNull(timers); + this.accessPaths = requireNonNull(accessPaths); + this.minNumberOfRounds = accessPaths.calculateMaxNumberOfRides(); + this.roundTracker = requireNonNull(roundTracker); + this.lifeCycle = requireNonNull(lifeCyclePublisher); + this.timeoutHook = requireNonNull(timeoutHook); + } + + public RaptorRouterResult route() { + timers.route(() -> { + int iterationDepartureTime = RaptorConstants.TIME_NOT_SET; + lifeCycle.notifyRouteSearchStart(calculator.searchForward()); + transitData.setup(); + + // The main outer loop iterates backward over all minutes in the departure times window. + // Ergo, we re-use the arrival times found in searches that have already occurred that + // depart later, because the arrival time given departure at time t is upper-bounded by + // the arrival time given departure at minute t + 1. + final IntIterator it = calculator.rangeRaptorMinutes(); + while (it.hasNext()) { + iterationDepartureTime = it.next(); + runRaptorForMinute(iterationDepartureTime); + } + + // Iterate over virtual departure times - this is needed to allow access with a time-penalty + // which falls outside the search-window due to the added time-penalty. + if (!calculator.oneIterationOnly()) { + final IntIterator as = accessPaths.iterateOverPathsWithPenalty(iterationDepartureTime); + while (as.hasNext()) { + iterationDepartureTime = as.next(); + runRaptorForMinute(iterationDepartureTime); + } + } + }); + return worker.result(); + } + + /** + * Perform one minute of a RAPTOR search. + */ + private void runRaptorForMinute(int iterationDepartureTime) { + setupIteration(iterationDepartureTime); + worker.findAccessOnStreetForRound(); + + while (hasMoreRounds()) { + lifeCycle.prepareForNextRound(roundTracker.nextRound()); + + // NB since we have transfer limiting not bothering to cut off search when there are no + // more transfers as that will be rare and complicates the code + worker.findTransitForRound(); + lifeCycle.transitsForRoundComplete(); + + worker.findAccessOnBoardForRound(); + + worker.findTransfersForRound(); + lifeCycle.transfersForRoundComplete(); + + lifeCycle.roundComplete(worker.isDestinationReachedInCurrentRound()); + + worker.findAccessOnStreetForRound(); + } + + // This state is repeatedly modified as the outer loop progresses over departure minutes. + // We have to be careful here, the next iteration will modify the state, so we need to make + // protective copies of any information we want to retain. + lifeCycle.iterationComplete(); + } + + /** + * Check if the RangeRaptor should continue with a new round. + */ + private boolean hasMoreRounds() { + if (round() < minNumberOfRounds) { + return true; + } + return worker.hasMoreRounds() && roundTracker.hasMoreRounds(); + } + + private int round() { + return roundTracker.round(); + } + + /** + * Run the raptor search for this particular iteration departure time + */ + private void setupIteration(int iterationDepartureTime) { + timeoutHook.run(); + roundTracker.setupIteration(); + lifeCycle.prepareForNextRound(round()); + lifeCycle.setupIteration(iterationDepartureTime); + } +} diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/RangeRaptorWorkerComposite.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/RangeRaptorWorkerComposite.java new file mode 100644 index 00000000000..2147101285d --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/RangeRaptorWorkerComposite.java @@ -0,0 +1,88 @@ +package org.opentripplanner.raptor.rangeraptor; + +import java.util.Collection; +import java.util.List; +import javax.annotation.Nullable; +import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.raptor.rangeraptor.internalapi.RangeRaptorWorker; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouterResult; +import org.opentripplanner.raptor.util.composite.CompositeUtil; + +/** + * Iterate over two RR workers. The head should process the access and the tail should produce the + * result. Paths from the head needs to propagate to the tail - this is NOT part of the + * responsibilities for this class. + */ +public class RangeRaptorWorkerComposite + implements RangeRaptorWorker { + + private final List> children; + + private RangeRaptorWorkerComposite(Collection> children) { + this.children = List.copyOf(children); + } + + /** + * Concatenate the two given workers, flattening any composite workers into a list. + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static RangeRaptorWorker of( + @Nullable RangeRaptorWorker a, + @Nullable RangeRaptorWorker b + ) { + return CompositeUtil.of( + RangeRaptorWorkerComposite::new, + it -> it instanceof RangeRaptorWorkerComposite, + it -> ((RangeRaptorWorkerComposite) it).children, + a, + b + ); + } + + @Override + public RaptorRouterResult result() { + return tail().result(); + } + + @Override + public boolean hasMoreRounds() { + return children.stream().anyMatch(RangeRaptorWorker::hasMoreRounds); + } + + @Override + public void findTransitForRound() { + for (RangeRaptorWorker child : children) { + child.findTransitForRound(); + } + } + + @Override + public void findTransfersForRound() { + for (RangeRaptorWorker child : children) { + child.findTransfersForRound(); + } + } + + @Override + public boolean isDestinationReachedInCurrentRound() { + return tail().isDestinationReachedInCurrentRound(); + } + + @Override + public void findAccessOnStreetForRound() { + head().findAccessOnStreetForRound(); + } + + @Override + public void findAccessOnBoardForRound() { + head().findAccessOnBoardForRound(); + } + + private RangeRaptorWorker head() { + return children.getFirst(); + } + + private RangeRaptorWorker tail() { + return children.getLast(); + } +} diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/SystemErrDebugLogger.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/SystemErrDebugLogger.java similarity index 93% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/SystemErrDebugLogger.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/SystemErrDebugLogger.java index 951721f81a7..c80d226afc7 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/SystemErrDebugLogger.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/SystemErrDebugLogger.java @@ -1,22 +1,17 @@ package org.opentripplanner.raptor.rangeraptor; -import static org.opentripplanner.framework.text.Table.Align.Center; -import static org.opentripplanner.framework.text.Table.Align.Left; -import static org.opentripplanner.framework.text.Table.Align.Right; -import static org.opentripplanner.framework.time.TimeUtils.timeToStrCompact; -import static org.opentripplanner.framework.time.TimeUtils.timeToStrLong; import static org.opentripplanner.raptor.api.model.PathLegType.ACCESS; import static org.opentripplanner.raptor.api.model.PathLegType.TRANSIT; +import static org.opentripplanner.utils.text.Table.Align.Center; +import static org.opentripplanner.utils.text.Table.Align.Left; +import static org.opentripplanner.utils.text.Table.Align.Right; +import static org.opentripplanner.utils.time.TimeUtils.timeToStrCompact; +import static org.opentripplanner.utils.time.TimeUtils.timeToStrLong; import java.text.NumberFormat; import java.util.Locale; import java.util.function.Consumer; import javax.annotation.Nullable; -import org.opentripplanner.framework.lang.IntUtils; -import org.opentripplanner.framework.lang.OtpNumberFormat; -import org.opentripplanner.framework.lang.StringUtils; -import org.opentripplanner.framework.text.Table; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.raptor.api.debug.DebugEvent; import org.opentripplanner.raptor.api.debug.DebugLogger; import org.opentripplanner.raptor.api.debug.DebugTopic; @@ -26,6 +21,11 @@ import org.opentripplanner.raptor.api.view.ArrivalView; import org.opentripplanner.raptor.api.view.PatternRideView; import org.opentripplanner.raptor.rangeraptor.transit.TripTimesSearch; +import org.opentripplanner.utils.lang.IntUtils; +import org.opentripplanner.utils.lang.OtpNumberFormat; +import org.opentripplanner.utils.lang.StringUtils; +import org.opentripplanner.utils.text.Table; +import org.opentripplanner.utils.time.DurationUtils; /** * A debug logger which can be plugged into Raptor to do debug logging to standard error. This is diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContext.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContext.java similarity index 83% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContext.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContext.java index 518d02ae3ad..e197bad8461 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContext.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContext.java @@ -4,6 +4,7 @@ import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime.USE_DEPARTURE_TIME; import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime.USE_TIMETABLE; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -13,10 +14,10 @@ import javax.annotation.Nullable; import org.opentripplanner.raptor.api.debug.RaptorTimers; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTripPattern; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.model.SearchDirection; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.api.request.DebugRequest; import org.opentripplanner.raptor.api.request.MultiCriteriaRequest; import org.opentripplanner.raptor.api.request.RaptorProfile; @@ -25,7 +26,6 @@ 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; import org.opentripplanner.raptor.rangeraptor.lifecycle.LifeCycleEventPublisher; @@ -38,13 +38,14 @@ import org.opentripplanner.raptor.rangeraptor.transit.ReverseRaptorTransitCalculator; import org.opentripplanner.raptor.rangeraptor.transit.RoundTracker; import org.opentripplanner.raptor.rangeraptor.transit.SlackProviderAdapter; +import org.opentripplanner.raptor.rangeraptor.transit.ViaConnections; import org.opentripplanner.raptor.spi.RaptorCostCalculator; import org.opentripplanner.raptor.spi.RaptorSlackProvider; import org.opentripplanner.raptor.spi.RaptorTransitDataProvider; /** - * The search context is used to hold search scoped instances and to pass these to who ever need - * them. + * The search context is used to hold search scoped instances and to pass these to whom ever needs + * them. It is one search-context pr RangeRaptor * * @param The TripSchedule type defined by the user of the raptor API. */ @@ -58,37 +59,35 @@ public class SearchContext { /** * the transit data role needed for routing */ - protected final RaptorTransitDataProvider transit; + protected final RaptorTransitDataProvider transitData; private final RaptorTransitCalculator calculator; private final RaptorTuningParameters tuningParameters; private final RoundTracker roundTracker; private final DebugHandlerFactory debugFactory; - private final EgressPaths egressPaths; - private final AccessPaths accessPaths; private final LifeCycleSubscriptions lifeCycleSubscriptions = new LifeCycleSubscriptions(); @Nullable private final IntPredicate acceptC2AtDestination; + private final List> legs; + /** Lazy initialized */ private RaptorCostCalculator costCalculator = null; - /** - * @param acceptC2AtDestination Currently only the pass-through has a constraint on the c2 value - * for accepting it at the destination, if not this is {@code null}. - */ - public SearchContext( + SearchContext( RaptorRequest request, RaptorTuningParameters tuningParameters, - RaptorTransitDataProvider transit, + RaptorTransitDataProvider transitData, + AccessPaths accessPaths, + List viaConnections, + EgressPaths egressPaths, @Nullable IntPredicate acceptC2AtDestination ) { this.request = request; this.tuningParameters = tuningParameters; - this.transit = transit; - this.accessPaths = accessPaths(tuningParameters.iterationDepartureStepInSeconds(), request); - this.egressPaths = egressPaths(request); + this.transitData = transitData; + this.calculator = createCalculator(request, tuningParameters); this.roundTracker = new RoundTracker( @@ -98,18 +97,24 @@ public SearchContext( ); this.debugFactory = new DebugHandlerFactory<>(debugRequest(request), lifeCycle()); this.acceptC2AtDestination = acceptC2AtDestination; + this.legs = initLegs(accessPaths, viaConnections, egressPaths); } - public AccessPaths accessPaths() { - return accessPaths; - } - - public EgressPaths egressPaths() { - return egressPaths; + /** + * @param acceptC2AtDestination Currently only the pass-through has a constraint on the c2 value + * for accepting it at the destination, if not this is {@code null}. + */ + public static SearchContextBuilder of( + RaptorRequest request, + RaptorTuningParameters tuningParameters, + RaptorTransitDataProvider transit, + @Nullable IntPredicate acceptC2AtDestination + ) { + return new SearchContextBuilder<>(request, tuningParameters, transit, acceptC2AtDestination); } - public int[] egressStops() { - return egressPaths().stops(); + public List> legs() { + return legs; } public SearchParams searchParams() { @@ -128,8 +133,8 @@ public MultiCriteriaRequest multiCriteria() { return request.multiCriteria(); } - public RaptorTransitDataProvider transit() { - return transit; + public RaptorTransitDataProvider transitData() { + return transitData; } public RaptorTransitCalculator calculator() { @@ -145,7 +150,7 @@ public SlackProvider slackProvider() { } public RaptorSlackProvider raptorSlackProvider() { - return transit.slackProvider(); + return transitData.slackProvider(); } /** @@ -162,7 +167,7 @@ public ToIntFunction boardSlackProvider() { @Nullable public RaptorCostCalculator costCalculator() { if (costCalculator == null) { - this.costCalculator = transit.multiCriteriaCostCalculator(); + this.costCalculator = transitData.multiCriteriaCostCalculator(); } return costCalculator; } @@ -182,7 +187,7 @@ public IntPredicate acceptC2AtDestination() { /** Number of stops in transit graph. */ public int nStops() { - return transit.numberOfStops(); + return transitData.numberOfStops(); } /** Calculate the maximum number of rounds to perform. */ @@ -193,7 +198,7 @@ public int nRounds() { return tuningParameters.maxNumberOfTransfers() + 1; } - public RoundProvider roundProvider() { + public RoundTracker roundTracker() { return roundTracker; } @@ -219,15 +224,14 @@ public boolean useConstrainedTransfers() { /* private methods */ public RaptorStopNameResolver stopNameResolver() { - return transit.stopNameResolver(); + return transitData.stopNameResolver(); } public TimeBasedBoardingSupport createTimeBasedBoardingSupport() { return new TimeBasedBoardingSupport<>( - accessPaths().hasTimeDependentAccess(), + legs.getFirst().accessPaths().hasTimeDependentAccess(), slackProvider(), calculator(), - roundProvider(), lifeCycle() ); } @@ -314,18 +318,29 @@ private static ToIntFunction createBoardSlackProvider( : p -> slackProvider.alightSlack(p.slackIndex()); } - private static AccessPaths accessPaths(int iterationStep, RaptorRequest request) { - boolean forward = request.searchDirection().isForward(); - var params = request.searchParams(); - var paths = forward ? params.accessPaths() : params.egressPaths(); - return AccessPaths.create(iterationStep, paths, request.profile(), request.searchDirection()); - } + private List> initLegs( + AccessPaths accessPaths, + List viaConnections, + EgressPaths egressPaths + ) { + if (viaConnections.isEmpty()) { + return List.of(new SearchContextViaLeg<>(this, accessPaths, null, egressPaths)); + } + var accessEmpty = accessPaths.copyEmpty(); + var list = new ArrayList>(); + for (ViaConnections c : viaConnections) { + list.add( + new SearchContextViaLeg<>( + this, + c == viaConnections.getFirst() ? accessPaths : accessEmpty, + c, + null + ) + ); + } + list.add(new SearchContextViaLeg<>(this, accessEmpty, null, egressPaths)); - private static EgressPaths egressPaths(RaptorRequest request) { - boolean forward = request.searchDirection().isForward(); - var params = request.searchParams(); - var paths = forward ? params.egressPaths() : params.accessPaths(); - return EgressPaths.create(paths, request.profile()); + return List.copyOf(list); } static ParetoSetTime paretoSetTimeConfig( diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContextBuilder.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContextBuilder.java new file mode 100644 index 00000000000..e0a6725c5c0 --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContextBuilder.java @@ -0,0 +1,82 @@ +package org.opentripplanner.raptor.rangeraptor.context; + +import java.util.List; +import java.util.function.IntPredicate; +import javax.annotation.Nullable; +import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.raptor.api.request.RaptorRequest; +import org.opentripplanner.raptor.api.request.RaptorTuningParameters; +import org.opentripplanner.raptor.api.request.RaptorViaLocation; +import org.opentripplanner.raptor.rangeraptor.transit.AccessPaths; +import org.opentripplanner.raptor.rangeraptor.transit.EgressPaths; +import org.opentripplanner.raptor.rangeraptor.transit.ViaConnections; +import org.opentripplanner.raptor.spi.RaptorTransitDataProvider; + +public class SearchContextBuilder { + + private final RaptorRequest request; + private final RaptorTuningParameters tuningParameters; + private final RaptorTransitDataProvider transit; + + @Nullable + private final IntPredicate acceptC2AtDestination; + + public SearchContextBuilder( + RaptorRequest request, + RaptorTuningParameters tuningParameters, + RaptorTransitDataProvider transit, + @Nullable IntPredicate acceptC2AtDestination + ) { + this.request = request; + this.tuningParameters = tuningParameters; + this.transit = transit; + this.acceptC2AtDestination = acceptC2AtDestination; + } + + public SearchContext build() { + return createContext(accessPaths(), viaConnections(), egressPaths()); + } + + private SearchContext createContext( + AccessPaths accessPaths, + List viaConnections, + EgressPaths egressPaths + ) { + return new SearchContext<>( + request, + tuningParameters, + transit, + accessPaths, + viaConnections, + egressPaths, + acceptC2AtDestination + ); + } + + private AccessPaths accessPaths() { + int iterationStep = tuningParameters.iterationDepartureStepInSeconds(); + boolean forward = request.searchDirection().isForward(); + var params = request.searchParams(); + var paths = forward ? params.accessPaths() : params.egressPaths(); + return AccessPaths.create(iterationStep, paths, request.profile(), request.searchDirection()); + } + + private List viaConnections() { + return request.searchParams().hasViaLocations() + ? request + .searchParams() + .viaLocations() + .stream() + .map(RaptorViaLocation::connections) + .map(ViaConnections::new) + .toList() + : List.of(); + } + + private EgressPaths egressPaths() { + boolean forward = request.searchDirection().isForward(); + var params = request.searchParams(); + var paths = forward ? params.egressPaths() : params.accessPaths(); + return EgressPaths.create(paths, request.profile()); + } +} diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContextViaLeg.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContextViaLeg.java new file mode 100644 index 00000000000..9472d3b1464 --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContextViaLeg.java @@ -0,0 +1,64 @@ +package org.opentripplanner.raptor.rangeraptor.context; + +import javax.annotation.Nullable; +import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.raptor.rangeraptor.transit.AccessPaths; +import org.opentripplanner.raptor.rangeraptor.transit.EgressPaths; +import org.opentripplanner.raptor.rangeraptor.transit.ViaConnections; + +/** + * A search can be split into one or more legs. The {@code parent} search context will have a list + * of legs. The first leg will have a list of {@code accessPaths} and the {@link ViaConnections} + * for transferring to the next leg. The last leg will have {@code egressPaths}. + */ +public class SearchContextViaLeg { + + private final SearchContext parent; + private final AccessPaths accessPaths; + private final ViaConnections viaConnections; + private final EgressPaths egressPaths; + + public SearchContextViaLeg( + SearchContext parent, + AccessPaths accessPaths, + ViaConnections viaConnections, + EgressPaths egressPaths + ) { + this.parent = parent; + this.accessPaths = accessPaths; + this.viaConnections = viaConnections; + this.egressPaths = egressPaths; + } + + /** + * The parent search context this leg is part of. + */ + public SearchContext parent() { + return parent; + } + + /** + * The set of access paths to be used to board this leg. This method returns an empty + * set of access-paths if the leg is not the first leg. Hence, it is null-safe. + */ + public AccessPaths accessPaths() { + return accessPaths; + } + + /** + * The via connections for the via-location this leg ends with. This is {@code null} if this + * leg is the last leg. + */ + @Nullable + public ViaConnections viaConnections() { + return viaConnections; + } + + /** + * The egress path for search. Non-null if and only if this is the last leg. + */ + @Nullable + public EgressPaths egressPaths() { + return egressPaths; + } +} diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/AbstractDebugHandlerAdapter.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/AbstractDebugHandlerAdapter.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/debug/AbstractDebugHandlerAdapter.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/AbstractDebugHandlerAdapter.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerFactory.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerFactory.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerFactory.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerPathAdapter.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerPathAdapter.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerPathAdapter.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerPathAdapter.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerPatternRideAdapter.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerPatternRideAdapter.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerPatternRideAdapter.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerPatternRideAdapter.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerStopArrivalAdapter.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerStopArrivalAdapter.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerStopArrivalAdapter.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/DebugHandlerStopArrivalAdapter.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/ParetoSetDebugHandlerAdapter.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/ParetoSetDebugHandlerAdapter.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/debug/ParetoSetDebugHandlerAdapter.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/debug/ParetoSetDebugHandlerAdapter.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/DebugHandler.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/DebugHandler.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/DebugHandler.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/DebugHandler.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/HeuristicAtStop.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/HeuristicAtStop.java similarity index 87% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/HeuristicAtStop.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/HeuristicAtStop.java index b58d773969c..da07c643fb6 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/HeuristicAtStop.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/HeuristicAtStop.java @@ -1,8 +1,8 @@ package org.opentripplanner.raptor.rangeraptor.internalapi; -import org.opentripplanner.framework.lang.OtpNumberFormat; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.utils.lang.OtpNumberFormat; +import org.opentripplanner.utils.time.DurationUtils; /** * Heuristic data for a given stop. diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/Heuristics.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/Heuristics.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/Heuristics.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/Heuristics.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/ParetoSetCost.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/ParetoSetCost.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/ParetoSetCost.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/ParetoSetCost.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/ParetoSetTime.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/ParetoSetTime.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/ParetoSetTime.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/ParetoSetTime.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/PassThroughPointsService.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/PassThroughPointsService.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/PassThroughPointsService.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/PassThroughPointsService.java diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RangeRaptorWorker.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RangeRaptorWorker.java new file mode 100644 index 00000000000..7e80ce96898 --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RangeRaptorWorker.java @@ -0,0 +1,47 @@ +package org.opentripplanner.raptor.rangeraptor.internalapi; + +import org.opentripplanner.raptor.api.model.RaptorTripSchedule; + +/** + * The worker performs the travel search. There are multiple implementations, even some that do not + * return paths. + * + * @param The TripSchedule type defined by the user of the raptor API. + */ +public interface RangeRaptorWorker { + /** + * Fetch the result after the search is performed. + */ + RaptorRouterResult result(); + + /** + * Check if the RangeRaptor should continue with a new round. + */ + boolean hasMoreRounds(); + + /** + * Perform a transit search for the current round. + */ + void findTransitForRound(); + + /** + * Apply transfers for the current round. + */ + void findTransfersForRound(); + + /** + * Return {@code true} if the destination is reached in the current round. + */ + boolean isDestinationReachedInCurrentRound(); + + /** + * Apply access for the current round, including round zero - before the first transit. + * This is applied in each round because the access may include transit (FLEX). + */ + void findAccessOnStreetForRound(); + + /** + * Apply access for the current round, when the access arrives to the stop on-board (FLEX). + */ + void findAccessOnBoardForRound(); +} diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorRouter.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorRouter.java new file mode 100644 index 00000000000..3b5fb711b06 --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorRouter.java @@ -0,0 +1,17 @@ +package org.opentripplanner.raptor.rangeraptor.internalapi; + +import org.opentripplanner.raptor.api.model.RaptorTripSchedule; + +/** + * Interface for Raptor Router. Allow instrumentation/wrapping the router. This is not + * currently used in the main branch of OTP, but it is used in Entur fork to extend the + * router functionality. + */ +public interface RaptorRouter { + /** + * Perform the routing request and return the result. A range-raptor request will + * iterate over the minutes in the search-window, while a plain raptor search will + * just do one iteration. + */ + RaptorRouterResult route(); +} diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorWorkerResult.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorRouterResult.java similarity index 87% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorWorkerResult.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorRouterResult.java index 59aeb48e6ab..df073b796ec 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorWorkerResult.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorRouterResult.java @@ -5,9 +5,9 @@ import org.opentripplanner.raptor.api.path.RaptorPath; /** - * This is the result of the {@link RaptorWorker#route()} call. + * This is the result of a RangeRaptor route call. */ -public interface RaptorWorkerResult { +public interface RaptorRouterResult { /** * Return all paths found. */ diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorWorkerState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorWorkerState.java similarity index 89% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorWorkerState.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorWorkerState.java index a71b8765adb..2add95f9a79 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorWorkerState.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorWorkerState.java @@ -3,11 +3,11 @@ import java.util.Iterator; import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; -import org.opentripplanner.raptor.rangeraptor.DefaultRangeRaptorWorker; +import org.opentripplanner.raptor.rangeraptor.RangeRaptor; import org.opentripplanner.raptor.spi.IntIterator; /** - * The contract the state must implement for the {@link DefaultRangeRaptorWorker} to do its job. This + * The contract the state must implement for the {@link RangeRaptor} to do its job. This * allows us to mix workers and states to implement different versions of the algorithm like * Standard, Standard-reversed and multi-criteria and use this with different states keeping only * the information needed by the use-case. Some example use-cases are calculating heuristics, @@ -45,5 +45,5 @@ public interface RaptorWorkerState { */ void transferToStops(int fromStop, Iterator transfers); - RaptorWorkerResult results(); + RaptorRouterResult results(); } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RoutingStrategy.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RoutingStrategy.java similarity index 96% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RoutingStrategy.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RoutingStrategy.java index 63be40e9e8a..df9577aaeff 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RoutingStrategy.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RoutingStrategy.java @@ -2,13 +2,13 @@ import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; -import org.opentripplanner.raptor.rangeraptor.DefaultRangeRaptorWorker; +import org.opentripplanner.raptor.rangeraptor.RangeRaptor; import org.opentripplanner.raptor.spi.RaptorConstrainedBoardingSearch; import org.opentripplanner.raptor.spi.RaptorRoute; import org.opentripplanner.raptor.spi.RaptorTimeTable; /** - * Provides alternative implementations of some logic within the {@link DefaultRangeRaptorWorker}. + * Provides alternative implementations of some logic within the {@link RangeRaptor}. * * @param The TripSchedule type defined by the user of the raptor API. */ diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/SingleCriteriaStopArrivals.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/SingleCriteriaStopArrivals.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/SingleCriteriaStopArrivals.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/SingleCriteriaStopArrivals.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/SlackProvider.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/SlackProvider.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/SlackProvider.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/SlackProvider.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/WorkerLifeCycle.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/WorkerLifeCycle.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/WorkerLifeCycle.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/WorkerLifeCycle.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/lifecycle/LifeCycleEventPublisher.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/lifecycle/LifeCycleEventPublisher.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/lifecycle/LifeCycleEventPublisher.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/lifecycle/LifeCycleEventPublisher.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/lifecycle/LifeCycleSubscriptions.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/lifecycle/LifeCycleSubscriptions.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/lifecycle/LifeCycleSubscriptions.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/lifecycle/LifeCycleSubscriptions.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/CalculateTransferToDestination.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/CalculateTransferToDestination.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/CalculateTransferToDestination.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/CalculateTransferToDestination.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/DebugStopArrivalsStatistics.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/DebugStopArrivalsStatistics.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/DebugStopArrivalsStatistics.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/DebugStopArrivalsStatistics.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRangeRaptorWorkerState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRangeRaptorWorkerState.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRangeRaptorWorkerState.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRangeRaptorWorkerState.java index eccb009aeaa..1dcada83419 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRangeRaptorWorkerState.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRangeRaptorWorkerState.java @@ -6,7 +6,7 @@ import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; -import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerResult; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouterResult; import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerState; import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrival; @@ -110,9 +110,9 @@ public void transferToStops(int fromStop, Iterator tra } @Override - public RaptorWorkerResult results() { + public RaptorRouterResult results() { arrivals.debugStateInfo(); - return new McRaptorWorkerResult(arrivals, paths); + return new McRaptorRouterResult(arrivals, paths); } Iterable> listStopArrivalsPreviousRound(int stop) { diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRaptorWorkerResult.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRaptorRouterResult.java similarity index 91% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRaptorWorkerResult.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRaptorRouterResult.java index a664c89e0bd..2339c2a8df6 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRaptorWorkerResult.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McRaptorRouterResult.java @@ -3,16 +3,16 @@ import java.util.Collection; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.RaptorPath; -import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerResult; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouterResult; import org.opentripplanner.raptor.rangeraptor.internalapi.SingleCriteriaStopArrivals; import org.opentripplanner.raptor.rangeraptor.path.DestinationArrivalPaths; -public class McRaptorWorkerResult implements RaptorWorkerResult { +public class McRaptorRouterResult implements RaptorRouterResult { private final McStopArrivals stopArrivals; private final DestinationArrivalPaths paths; - public McRaptorWorkerResult(McStopArrivals arrivals, DestinationArrivalPaths paths) { + public McRaptorRouterResult(McStopArrivals arrivals, DestinationArrivalPaths paths) { stopArrivals = arrivals; this.paths = paths; } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McStopArrivals.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McStopArrivals.java similarity index 59% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McStopArrivals.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McStopArrivals.java index 4090890cc82..f56e35d2f82 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McStopArrivals.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/McStopArrivals.java @@ -4,17 +4,21 @@ import java.util.BitSet; import java.util.Collections; +import java.util.Objects; import java.util.function.Function; import java.util.stream.Stream; +import javax.annotation.Nullable; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.rangeraptor.debug.DebugHandlerFactory; import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.ArrivalParetoSetComparatorFactory; import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrival; +import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrivalFactory; import org.opentripplanner.raptor.rangeraptor.path.DestinationArrivalPaths; -import org.opentripplanner.raptor.rangeraptor.transit.AccessPaths; import org.opentripplanner.raptor.rangeraptor.transit.EgressPaths; +import org.opentripplanner.raptor.rangeraptor.transit.ViaConnections; import org.opentripplanner.raptor.spi.IntIterator; import org.opentripplanner.raptor.util.BitSetIterator; +import org.opentripplanner.raptor.util.paretoset.ParetoComparator; /** * This class serve as a wrapper for all stop arrival pareto set, one set for each stop. It also @@ -28,43 +32,57 @@ public final class McStopArrivals { private final StopArrivalParetoSet[] arrivals; private final BitSet touchedStops; - private final ArrivalParetoSetComparatorFactory> comparatorFactory; private final DebugHandlerFactory debugHandlerFactory; private final DebugStopArrivalsStatistics debugStats; + private final ParetoComparator> comparator; /** - * Set the time at a transit index iff it is optimal. This sets both the best time and the - * transfer time + * Set the time at a transit index if it is optimal. This sets both the best time and the + * transfer time. + * + * @param nextLeg When chaining two Raptor searches together, the next-leg is the next + * search we are copying state into. */ public McStopArrivals( int nStops, - EgressPaths egressPaths, - AccessPaths accessPaths, + @Nullable EgressPaths egressPaths, + ViaConnections viaConnections, DestinationArrivalPaths paths, + McStopArrivals nextLeg, + McStopArrivalFactory stopArrivalFactory, ArrivalParetoSetComparatorFactory> comparatorFactory, DebugHandlerFactory debugHandlerFactory ) { - this.comparatorFactory = comparatorFactory; + // Assert only-one-of next or egressPaths is set + if (nextLeg == null) { + Objects.requireNonNull(egressPaths); + } else if (egressPaths != null) { + throw new IllegalArgumentException( + "Can not delegate to next-leg and at the same have egress paths." + ); + } + //noinspection unchecked this.arrivals = (StopArrivalParetoSet[]) new StopArrivalParetoSet[nStops]; this.touchedStops = new BitSet(nStops); + this.comparator = comparatorFactory.compareArrivalTimeRoundCostAndOnBoardArrival(); this.debugHandlerFactory = debugHandlerFactory; this.debugStats = new DebugStopArrivalsStatistics(debugHandlerFactory.debugLogger()); - initAccessArrivals(accessPaths); - glueTogetherEgressStopWithDestinationArrivals(egressPaths, paths); + initViaConnections(viaConnections, stopArrivalFactory, nextLeg); + initEgressStopAndGlueItToDestinationArrivals(egressPaths, paths); } - public boolean reached(int stopIndex) { + boolean reached(int stopIndex) { return arrivals[stopIndex] != null && !arrivals[stopIndex].isEmpty(); } /** Slow! do not use during routing! */ - public int bestArrivalTime(int stopIndex) { + int bestArrivalTime(int stopIndex) { return minInt(arrivals[stopIndex].stream(), McStopArrival::arrivalTime); } - public boolean reachedByTransit(int stopIndex) { + boolean reachedByTransit(int stopIndex) { return ( arrivals[stopIndex] != null && arrivals[stopIndex].stream().anyMatch(a -> a.arrivedBy(TRANSIT)) @@ -72,12 +90,12 @@ public boolean reachedByTransit(int stopIndex) { } /** Slow! do not use during routing! */ - public int bestTransitArrivalTime(int stopIndex) { + int bestTransitArrivalTime(int stopIndex) { return transitStopArrivalsMinInt(stopIndex, McStopArrival::arrivalTime); } /** Slow! do not use during routing! */ - public int smallestNumberOfTransfers(int stopIndex) { + int smallestNumberOfTransfers(int stopIndex) { return transitStopArrivalsMinInt(stopIndex, McStopArrival::numberOfTransfers); } @@ -91,6 +109,7 @@ IntIterator stopsTouchedIterator() { void addStopArrival(McStopArrival arrival) { boolean added = findOrCreateSet(arrival.stop()).add(arrival); + if (added) { touchedStops.set(arrival.stop()); } @@ -100,22 +119,16 @@ void debugStateInfo() { debugStats.debugStatInfo(arrivals); } - public boolean hasArrivalsAfterMarker(int stop) { - StopArrivalParetoSet it = arrivals[stop]; - if (it == null) { - return false; - } - return it.hasElementsAfterMarker(); + boolean hasArrivalsAfterMarker(int stop) { + var it = arrivals[stop]; + return it != null && it.hasElementsAfterMarker(); } /** List all transits arrived this round. */ Iterable> listArrivalsAfterMarker(final int stop) { - StopArrivalParetoSet it = arrivals[stop]; - if (it == null) { - // Avoid creating new objects in a tight loop - return Collections::emptyIterator; - } - return it.elementsAfterMarker(); + var it = arrivals[stop]; + // Avoid creating new objects in a tight loop + return it == null ? Collections::emptyIterator : it.elementsAfterMarker(); } void clearTouchedStopsAndSetStopMarkers() { @@ -131,47 +144,59 @@ void clearTouchedStopsAndSetStopMarkers() { private StopArrivalParetoSet findOrCreateSet(final int stop) { if (arrivals[stop] == null) { arrivals[stop] = - StopArrivalParetoSet.createStopArrivalSet( - comparatorFactory.compareArrivalTimeRoundAndCost(), - debugHandlerFactory.paretoSetStopArrivalListener(stop) - ); + StopArrivalParetoSet + .of(comparator) + .withDebugListener(debugHandlerFactory.paretoSetStopArrivalListener(stop)) + .build(); } return arrivals[stop]; } - private void initAccessArrivals(AccessPaths accessPaths) { - int maxNRides = accessPaths.calculateMaxNumberOfRides(); - for (int nRides = 0; nRides <= maxNRides; ++nRides) { - for (var access : accessPaths.arrivedOnBoardByNumOfRides(nRides)) { - int stop = access.stop(); - arrivals[stop] = - StopArrivalParetoSet.createStopArrivalSet( - comparatorFactory.compareArrivalTimeRoundCostAndOnBoardArrival(), - debugHandlerFactory.paretoSetStopArrivalListener(stop) - ); - } + private void initViaConnections( + @Nullable ViaConnections viaConnections, + McStopArrivalFactory stopArrivalFactory, + McStopArrivals nextLeg + ) { + if (viaConnections == null) { + return; } + viaConnections + .byFromStop() + .forEachEntry((stop, connections) -> { + this.arrivals[stop] = + StopArrivalParetoSet + .of(comparator) + .withDebugListener(debugHandlerFactory.paretoSetStopArrivalListener(stop)) + .withNextLegListener( + new ViaConnectionStopArrivalEventListener<>(stopArrivalFactory, connections, nextLeg) + ) + .build(); + return true; + }); } /** * This method creates a ParetoSet for the given egress stop. When arrivals are added to the stop, * the "glue" make sure new destination arrivals are added to the destination arrivals. */ - private void glueTogetherEgressStopWithDestinationArrivals( - EgressPaths egressPaths, + private void initEgressStopAndGlueItToDestinationArrivals( + @Nullable EgressPaths egressPaths, DestinationArrivalPaths paths ) { + if (egressPaths == null) { + return; + } + egressPaths .byStop() .forEachEntry((stop, list) -> { // The factory is creating the actual "glue" this.arrivals[stop] = - StopArrivalParetoSet.createEgressStopArrivalSet( - comparatorFactory.compareArrivalTimeRoundCostAndOnBoardArrival(), - list, - paths, - debugHandlerFactory.paretoSetStopArrivalListener(stop) - ); + StopArrivalParetoSet + .of(comparator) + .withDebugListener(debugHandlerFactory.paretoSetStopArrivalListener(stop)) + .withEgressListener(list, paths) + .build(); return true; }); } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/MultiCriteriaRoutingStrategy.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/MultiCriteriaRoutingStrategy.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/MultiCriteriaRoutingStrategy.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/MultiCriteriaRoutingStrategy.java diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/StopArrivalParetoSet.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/StopArrivalParetoSet.java new file mode 100644 index 00000000000..2d158c05cc1 --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/StopArrivalParetoSet.java @@ -0,0 +1,86 @@ +package org.opentripplanner.raptor.rangeraptor.multicriteria; + +import java.util.List; +import org.opentripplanner.raptor.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.raptor.api.view.ArrivalView; +import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrival; +import org.opentripplanner.raptor.rangeraptor.path.DestinationArrivalPaths; +import org.opentripplanner.raptor.util.paretoset.ParetoComparator; +import org.opentripplanner.raptor.util.paretoset.ParetoSetEventListener; +import org.opentripplanner.raptor.util.paretoset.ParetoSetEventListenerComposite; +import org.opentripplanner.raptor.util.paretoset.ParetoSetWithMarker; + +/** + * A pareto optimal set of stop arrivals for a given stop. + * + * @param The TripSchedule type defined by the user of the raptor API. + */ +class StopArrivalParetoSet + extends ParetoSetWithMarker> { + + /** + * Use the factory methods in this class to create a new instance. + */ + private StopArrivalParetoSet( + ParetoComparator> comparator, + ParetoSetEventListener> listener + ) { + super(comparator, listener); + } + + public static Builder of( + ParetoComparator> comparator + ) { + return new Builder<>(comparator); + } + + static class Builder { + + private ParetoSetEventListener> debugListener = null; + private ParetoSetEventListener> egressListener = null; + private ParetoSetEventListener> nextSearchListener = null; + private final ParetoComparator> comparator; + + Builder(ParetoComparator> comparator) { + this.comparator = comparator; + } + + /** + * Attach an optional debug handler. + */ + Builder withDebugListener(ParetoSetEventListener> debugListener) { + this.debugListener = debugListener; + return this; + } + + /** + * Attach a {@link CalculateTransferToDestination} listener which will create new destination + * arrivals for each accepted egress stop arrival. + */ + Builder withEgressListener( + List egressPaths, + DestinationArrivalPaths destinationArrivals + ) { + this.egressListener = new CalculateTransferToDestination<>(egressPaths, destinationArrivals); + return this; + } + + /** + * Attach an optional listener for copy state over to the next-leg Raptor search. + */ + Builder withNextLegListener(ParetoSetEventListener> nextSearchListener) { + this.nextSearchListener = nextSearchListener; + return this; + } + + StopArrivalParetoSet build() { + // The order of the listeners is important, we want the debug event for reaching a + // stop to appear before the path is logged (in case both debuggers are enabled). + return new StopArrivalParetoSet<>( + comparator, + ParetoSetEventListenerComposite.of(debugListener, nextSearchListener, egressListener) + ); + } + } +} diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ViaConnectionStopArrivalEventListener.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ViaConnectionStopArrivalEventListener.java new file mode 100644 index 00000000000..6b0128e12e2 --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ViaConnectionStopArrivalEventListener.java @@ -0,0 +1,68 @@ +package org.opentripplanner.raptor.rangeraptor.multicriteria; + +import java.util.List; +import javax.annotation.Nullable; +import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.raptor.api.request.RaptorViaConnection; +import org.opentripplanner.raptor.api.view.ArrivalView; +import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrival; +import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrivalFactory; +import org.opentripplanner.raptor.util.paretoset.ParetoSetEventListener; + +/** + * This class is used to listen for stop arrivals in one raptor state and then copy + * over the arrival event to another state. This is used to chain the Raptor searches + * together to force the paths through the given via connections. + */ +class ViaConnectionStopArrivalEventListener + implements ParetoSetEventListener> { + + private final McStopArrivalFactory stopArrivalFactory; + private final List connections; + private final McStopArrivals next; + + public ViaConnectionStopArrivalEventListener( + McStopArrivalFactory stopArrivalFactory, + List connections, + McStopArrivals next + ) { + this.stopArrivalFactory = stopArrivalFactory; + this.connections = connections; + this.next = next; + } + + @Override + public void notifyElementAccepted(ArrivalView newElement) { + for (RaptorViaConnection c : connections) { + var e = (McStopArrival) newElement; + var n = createViaStopArrival(e, c); + if (n != null) { + next.addStopArrival(n); + } + } + } + + @Nullable + private McStopArrival createViaStopArrival( + McStopArrival previous, + RaptorViaConnection viaConnection + ) { + if (viaConnection.isSameStop()) { + if (viaConnection.durationInSeconds() == 0) { + return previous; + } else { + return previous.addSlackToArrivalTime(viaConnection.durationInSeconds()); + } + } else { + if (previous.arrivedOnBoard()) { + return stopArrivalFactory.createTransferStopArrival( + previous, + viaConnection.transfer(), + previous.arrivalTime() + viaConnection.durationInSeconds() + ); + } else { + return null; + } + } + } +} diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/ArrivalParetoSetComparatorFactory.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/ArrivalParetoSetComparatorFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/ArrivalParetoSetComparatorFactory.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/ArrivalParetoSetComparatorFactory.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrival.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrival.java similarity index 94% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrival.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrival.java index 895e6aa17e0..e4775c61508 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrival.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrival.java @@ -107,6 +107,12 @@ public McStopArrival timeShiftNewArrivalTime(int newArrivalTime) { throw new UnsupportedOperationException("No accessEgress for transfer stop arrival"); } + /** + * Add the given amount of slack to the arrival-time. This is used to add extraordinary + * wait-time to an arrival - for example, in via-search where a minimum-wait-time can be set. + */ + public abstract McStopArrival addSlackToArrivalTime(int slack); + @Override public final int hashCode() { throw new IllegalStateException("Avoid using hashCode() and equals() for this class."); diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrivalFactory.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrivalFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrivalFactory.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrivalFactory.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/AccessStopArrival.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/AccessStopArrival.java similarity index 84% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/AccessStopArrival.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/AccessStopArrival.java index e3787d41f78..cab1cde3c73 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/AccessStopArrival.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/AccessStopArrival.java @@ -1,5 +1,6 @@ package org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.c1; +import static org.opentripplanner.raptor.api.model.AbstractAccessEgressDecorator.accessEgressWithExtraSlack; import static org.opentripplanner.raptor.api.model.PathLegType.ACCESS; import org.opentripplanner.raptor.api.model.PathLegType; @@ -16,6 +17,7 @@ */ final class AccessStopArrival extends McStopArrival { + private final int departureTime; private final RaptorAccessEgress access; AccessStopArrival(int departureTime, RaptorAccessEgress access) { @@ -26,6 +28,7 @@ final class AccessStopArrival extends McStopArriva access.c1(), access.numberOfRides() ); + this.departureTime = departureTime; this.access = access; } @@ -44,6 +47,11 @@ public AccessPathView accessPath() { return () -> access; } + @Override + public boolean arrivedOnBoard() { + return access.stopReachedOnBoard(); + } + @Override public McStopArrival timeShiftNewArrivalTime(int newRequestedArrivalTime) { int newArrivalTime = access.latestArrivalTime(newRequestedArrivalTime); @@ -62,7 +70,7 @@ public McStopArrival timeShiftNewArrivalTime(int newRequestedArrivalTime) { } @Override - public boolean arrivedOnBoard() { - return access.stopReachedOnBoard(); + public McStopArrival addSlackToArrivalTime(int slack) { + return new AccessStopArrival<>(departureTime, accessEgressWithExtraSlack(access, slack)); } } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/StopArrivalFactoryC1.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/StopArrivalFactoryC1.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/StopArrivalFactoryC1.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/StopArrivalFactoryC1.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransferStopArrival.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransferStopArrival.java similarity index 90% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransferStopArrival.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransferStopArrival.java index 05c165a158b..bca25dbf61c 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransferStopArrival.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransferStopArrival.java @@ -55,4 +55,9 @@ public RaptorTransfer transfer() { public boolean arrivedOnBoard() { return false; } + + @Override + public McStopArrival addSlackToArrivalTime(int slack) { + return new TransferStopArrival<>(previous(), transfer, arrivalTime() + slack); + } } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransitStopArrival.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransitStopArrival.java similarity index 90% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransitStopArrival.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransitStopArrival.java index a30581512a7..ee572175b81 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransitStopArrival.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransitStopArrival.java @@ -69,4 +69,9 @@ public TransitPathView transitPath() { public boolean arrivedOnBoard() { return true; } + + @Override + public McStopArrival addSlackToArrivalTime(int slack) { + return new TransitStopArrival<>(previous(), stop(), arrivalTime() + slack, c1(), trip); + } } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/AbstractStopArrivalC2.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/AbstractStopArrivalC2.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/AbstractStopArrivalC2.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/AbstractStopArrivalC2.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/AccessStopArrivalC2.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/AccessStopArrivalC2.java similarity index 81% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/AccessStopArrivalC2.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/AccessStopArrivalC2.java index ed4d9df1415..ecc54110feb 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/AccessStopArrivalC2.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/AccessStopArrivalC2.java @@ -1,5 +1,6 @@ package org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.c2; +import static org.opentripplanner.raptor.api.model.AbstractAccessEgressDecorator.accessEgressWithExtraSlack; import static org.opentripplanner.raptor.api.model.PathLegType.ACCESS; import org.opentripplanner.raptor.api.model.PathLegType; @@ -7,6 +8,7 @@ import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.view.AccessPathView; +import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrival; import org.opentripplanner.raptor.spi.RaptorCostCalculator; /** @@ -16,6 +18,7 @@ */ final class AccessStopArrivalC2 extends AbstractStopArrivalC2 { + private final int departureTime; private final RaptorAccessEgress access; AccessStopArrivalC2(int departureTime, RaptorAccessEgress access) { @@ -27,6 +30,7 @@ final class AccessStopArrivalC2 extends AbstractSt access.c1(), RaptorCostCalculator.ZERO_COST ); + this.departureTime = departureTime; this.access = access; } @@ -57,6 +61,11 @@ public AbstractStopArrivalC2 timeShiftNewArrivalTime(int newRequestedArrivalT return new AccessStopArrivalC2<>(newDepartureTime, access); } + @Override + public McStopArrival addSlackToArrivalTime(int slack) { + return new AccessStopArrivalC2<>(departureTime, accessEgressWithExtraSlack(access, slack)); + } + @Override public boolean arrivedOnBoard() { return access.stopReachedOnBoard(); diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/StopArrivalFactoryC2.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/StopArrivalFactoryC2.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/StopArrivalFactoryC2.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/StopArrivalFactoryC2.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransferStopArrivalC2.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransferStopArrivalC2.java similarity index 89% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransferStopArrivalC2.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransferStopArrivalC2.java index 42ee55ff784..888346b30fe 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransferStopArrivalC2.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransferStopArrivalC2.java @@ -46,4 +46,9 @@ public RaptorTransfer transfer() { public boolean arrivedOnBoard() { return false; } + + @Override + public McStopArrival addSlackToArrivalTime(int slack) { + return new TransferStopArrivalC2<>(previous(), transfer, arrivalTime() + slack); + } } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransitStopArrivalC2.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransitStopArrivalC2.java similarity index 88% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransitStopArrivalC2.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransitStopArrivalC2.java index c047f484609..e08dde5103a 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransitStopArrivalC2.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransitStopArrivalC2.java @@ -58,4 +58,9 @@ public TransitPathView transitPath() { public boolean arrivedOnBoard() { return true; } + + @Override + public McStopArrival addSlackToArrivalTime(int slack) { + return new TransitStopArrivalC2<>(previous(), stop(), arrivalTime() + slack, c1(), c2(), trip); + } } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/configure/McRangeRaptorConfig.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/configure/McRangeRaptorConfig.java similarity index 73% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/configure/McRangeRaptorConfig.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/configure/McRangeRaptorConfig.java index 3673e78ee47..f30b391b929 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/configure/McRangeRaptorConfig.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/configure/McRangeRaptorConfig.java @@ -1,17 +1,16 @@ package org.opentripplanner.raptor.rangeraptor.multicriteria.configure; import java.util.Objects; -import java.util.function.BiFunction; import javax.annotation.Nullable; import org.opentripplanner.raptor.api.model.DominanceFunction; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.request.MultiCriteriaRequest; import org.opentripplanner.raptor.api.request.RaptorTransitGroupPriorityCalculator; import org.opentripplanner.raptor.rangeraptor.context.SearchContext; +import org.opentripplanner.raptor.rangeraptor.context.SearchContextViaLeg; 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; import org.opentripplanner.raptor.rangeraptor.internalapi.RoutingStrategy; import org.opentripplanner.raptor.rangeraptor.multicriteria.McRangeRaptorWorkerState; @@ -42,18 +41,22 @@ */ public class McRangeRaptorConfig { - private final SearchContext context; + private final SearchContextViaLeg contextLeg; private final PathConfig pathConfig; + private final PassThroughPointsService passThroughPointsService; private DestinationArrivalPaths paths; - private PassThroughPointsService passThroughPointsService; + private McRangeRaptorWorkerState state; + private Heuristics heuristics; + private McStopArrivals arrivals; + private McStopArrivals nextLegArrivals = null; public McRangeRaptorConfig( - SearchContext context, + SearchContextViaLeg contextLeg, PassThroughPointsService passThroughPointsService ) { - this.context = Objects.requireNonNull(context); + this.contextLeg = Objects.requireNonNull(contextLeg); this.passThroughPointsService = Objects.requireNonNull(passThroughPointsService); - this.pathConfig = new PathConfig<>(context); + this.pathConfig = new PathConfig<>(this.contextLeg.parent()); } /** @@ -70,12 +73,51 @@ public static PassThroughPointsService passThroughPointsService( /** * Create new multi-criteria worker with optional heuristics. */ - public RaptorWorker createWorker( - Heuristics heuristics, - BiFunction, RoutingStrategy, RaptorWorker> createWorker + public McRangeRaptorConfig withHeuristics(Heuristics heuristics) { + this.heuristics = heuristics; + return this; + } + + /** + * Sets the next leg state. This is used to connect the state created by this config with the + * next leg. If this is the last leg, the next leg should be {@code null}. This is optional. + */ + public McRangeRaptorConfig connectWithNextLegArrivals( + @Nullable McStopArrivals nextLegArrivals ) { - McRangeRaptorWorkerState state = createState(heuristics); - return createWorker.apply(state, createTransitWorkerStrategy(state)); + this.nextLegArrivals = nextLegArrivals; + return this; + } + + /** + * Create new multi-criteria worker with optional heuristics. + */ + public RoutingStrategy strategy() { + return createTransitWorkerStrategy(createState(heuristics)); + } + + public RaptorWorkerState state() { + return createState(heuristics); + } + + /** + * This is used in the config to chain more than one search together. + */ + public McStopArrivals stopArrivals() { + if (arrivals == null) { + this.arrivals = + new McStopArrivals<>( + context().nStops(), + contextLeg.egressPaths(), + contextLeg.viaConnections(), + createDestinationArrivalPaths(), + nextLegArrivals, + createStopArrivalFactory(), + createFactoryParetoComparator(), + context().debugFactory() + ); + } + return arrivals; } /* private factory methods */ @@ -101,51 +143,49 @@ private > RoutingStrategy createTransitWorkerStrateg ) { return new MultiCriteriaRoutingStrategy<>( state, - context.createTimeBasedBoardingSupport(), + context().createTimeBasedBoardingSupport(), factory, passThroughPointsService, - context.costCalculator(), - context.slackProvider(), + context().costCalculator(), + context().slackProvider(), createPatternRideParetoSet(patternRideComparator) ); } private McRangeRaptorWorkerState createState(Heuristics heuristics) { - return new McRangeRaptorWorkerState<>( - createStopArrivals(), - createDestinationArrivalPaths(), - createHeuristicsProvider(heuristics), - createStopArrivalFactory(), - context.costCalculator(), - context.calculator(), - context.lifeCycle() - ); + if (state == null) { + state = + new McRangeRaptorWorkerState<>( + stopArrivals(), + createDestinationArrivalPaths(), + createHeuristicsProvider(heuristics), + createStopArrivalFactory(), + context().costCalculator(), + context().calculator(), + context().lifeCycle() + ); + } + return state; } private McStopArrivalFactory createStopArrivalFactory() { return includeC2() ? new StopArrivalFactoryC2<>() : new StopArrivalFactoryC1<>(); } - private McStopArrivals createStopArrivals() { - return new McStopArrivals<>( - context.nStops(), - context.egressPaths(), - context.accessPaths(), - createDestinationArrivalPaths(), - createFactoryParetoComparator(), - context.debugFactory() - ); + private SearchContext context() { + return contextLeg.parent(); } private HeuristicsProvider createHeuristicsProvider(Heuristics heuristics) { if (heuristics == null) { return new HeuristicsProvider<>(); } else { + var ctx = contextLeg.parent(); return new HeuristicsProvider<>( heuristics, - context.roundProvider(), createDestinationArrivalPaths(), - context.debugFactory() + ctx.lifeCycle(), + ctx.debugFactory() ); } } @@ -153,7 +193,7 @@ private HeuristicsProvider createHeuristicsProvider(Heuristics heuristics) { private > ParetoSet createPatternRideParetoSet( ParetoComparator comparator ) { - return new ParetoSet<>(comparator, context.debugFactory().paretoSetPatternRideListener()); + return new ParetoSet<>(comparator, context().debugFactory().paretoSetPatternRideListener()); } private DestinationArrivalPaths createDestinationArrivalPaths() { @@ -169,7 +209,7 @@ private ArrivalParetoSetComparatorFactory> createFactoryParetoC } private MultiCriteriaRequest mcRequest() { - return context.multiCriteria(); + return context().multiCriteria(); } /** @@ -220,7 +260,7 @@ private ParetoSetCost resolveCostConfig() { if (isPassThrough()) { return ParetoSetCost.USE_C1_AND_C2; } - if (context.multiCriteria().relaxCostAtDestination() != null) { + 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/multicriteria/heuristic/HeuristicsProvider.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/heuristic/HeuristicsProvider.java similarity index 82% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/heuristic/HeuristicsProvider.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/heuristic/HeuristicsProvider.java index c7b1c43c991..fc4d11c33a4 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/heuristic/HeuristicsProvider.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/heuristic/HeuristicsProvider.java @@ -1,11 +1,12 @@ package org.opentripplanner.raptor.rangeraptor.multicriteria.heuristic; +import java.util.Objects; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.request.Optimization; import org.opentripplanner.raptor.rangeraptor.debug.DebugHandlerFactory; import org.opentripplanner.raptor.rangeraptor.internalapi.HeuristicAtStop; import org.opentripplanner.raptor.rangeraptor.internalapi.Heuristics; -import org.opentripplanner.raptor.rangeraptor.internalapi.RoundProvider; +import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrival; import org.opentripplanner.raptor.rangeraptor.path.DestinationArrivalPaths; @@ -18,26 +19,32 @@ public final class HeuristicsProvider { private final Heuristics heuristics; - private final RoundProvider roundProvider; private final DestinationArrivalPaths paths; private final HeuristicAtStop[] stops; private final DebugHandlerFactory debugHandlerFactory; + private int round; + public HeuristicsProvider() { - this(null, null, null, null); + this.heuristics = null; + this.paths = null; + this.stops = null; + this.debugHandlerFactory = null; } public HeuristicsProvider( Heuristics heuristics, - RoundProvider roundProvider, DestinationArrivalPaths paths, + WorkerLifeCycle lifeCycle, DebugHandlerFactory debugHandlerFactory ) { - this.heuristics = heuristics; - this.roundProvider = roundProvider; - this.paths = paths; - this.stops = heuristics == null ? null : new HeuristicAtStop[heuristics.size()]; - this.debugHandlerFactory = debugHandlerFactory; + this.heuristics = Objects.requireNonNull(heuristics); + this.paths = Objects.requireNonNull(paths); + this.stops = new HeuristicAtStop[heuristics.size()]; + this.debugHandlerFactory = Objects.requireNonNull(debugHandlerFactory); + + // Use life-cycle events to inject the range-raptor round + lifeCycle.onPrepareForNextRound(r -> this.round = r); } /** @@ -89,7 +96,7 @@ private boolean qualify(int stop, int arrivalTime, int travelDuration, int cost) return false; } int minArrivalTime = arrivalTime + h.minTravelDuration(); - int minNumberOfTransfers = roundProvider.round() - 1 + h.minNumTransfers(); + int minNumberOfTransfers = round - 1 + h.minNumTransfers(); int minTravelDuration = travelDuration + h.minTravelDuration(); int minCost = cost + h.minCost(); int departureTime = minArrivalTime - minTravelDuration; diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/passthrough/BitSetPassThroughPointsService.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/passthrough/BitSetPassThroughPointsService.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/passthrough/BitSetPassThroughPointsService.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/passthrough/BitSetPassThroughPointsService.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/PatternRide.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/PatternRide.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/PatternRide.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/PatternRide.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/PatternRideFactory.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/PatternRideFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/PatternRideFactory.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/PatternRideFactory.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c1/PatternRideC1.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c1/PatternRideC1.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c1/PatternRideC1.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c1/PatternRideC1.java index cbb3fbfadf3..fd669e40ffc 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c1/PatternRideC1.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c1/PatternRideC1.java @@ -1,12 +1,12 @@ package org.opentripplanner.raptor.rangeraptor.multicriteria.ride.c1; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrival; import org.opentripplanner.raptor.rangeraptor.multicriteria.ride.PatternRide; import org.opentripplanner.raptor.rangeraptor.multicriteria.ride.PatternRideFactory; import org.opentripplanner.raptor.spi.RaptorCostCalculator; import org.opentripplanner.raptor.util.paretoset.ParetoComparator; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A {@link PatternRide} with support for c1 {@code generalized-cost}. diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PassThroughRideFactory.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PassThroughRideFactory.java similarity index 97% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PassThroughRideFactory.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PassThroughRideFactory.java index 6120ae9d698..734766666c5 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PassThroughRideFactory.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PassThroughRideFactory.java @@ -1,10 +1,10 @@ package org.opentripplanner.raptor.rangeraptor.multicriteria.ride.c2; -import org.opentripplanner.framework.lang.IntBox; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.rangeraptor.internalapi.PassThroughPointsService; import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrival; import org.opentripplanner.raptor.rangeraptor.multicriteria.ride.PatternRideFactory; +import org.opentripplanner.utils.lang.IntBox; public class PassThroughRideFactory implements PatternRideFactory> { diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PatternRideC2.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PatternRideC2.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PatternRideC2.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PatternRideC2.java index d02bef207c2..a23999f1813 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PatternRideC2.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PatternRideC2.java @@ -1,11 +1,11 @@ package org.opentripplanner.raptor.rangeraptor.multicriteria.ride.c2; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.DominanceFunction; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrival; import org.opentripplanner.raptor.rangeraptor.multicriteria.ride.PatternRide; import org.opentripplanner.raptor.util.paretoset.ParetoComparator; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * A {@link PatternRide} with support for c1 {@code generalized-cost} and c2 (custom-use-case-cost). diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/TransitGroupPriorityRideFactory.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/TransitGroupPriorityRideFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/TransitGroupPriorityRideFactory.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/TransitGroupPriorityRideFactory.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/BoardAndAlightTimeSearch.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/BoardAndAlightTimeSearch.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/path/BoardAndAlightTimeSearch.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/BoardAndAlightTimeSearch.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/DestinationArrival.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/DestinationArrival.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/path/DestinationArrival.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/DestinationArrival.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/DestinationArrivalPaths.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/DestinationArrivalPaths.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/path/DestinationArrivalPaths.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/DestinationArrivalPaths.java index f5e67d593ca..2f257e52645 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/DestinationArrivalPaths.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/DestinationArrivalPaths.java @@ -5,13 +5,11 @@ import java.util.Optional; import java.util.function.IntPredicate; import javax.annotation.Nullable; -import org.opentripplanner.framework.lang.OtpNumberFormat; -import org.opentripplanner.framework.logging.Throttle; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.RaptorPath; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.api.view.ArrivalView; import org.opentripplanner.raptor.path.Path; import org.opentripplanner.raptor.rangeraptor.debug.DebugHandlerFactory; @@ -22,6 +20,8 @@ import org.opentripplanner.raptor.spi.RaptorCostCalculator; import org.opentripplanner.raptor.util.paretoset.ParetoComparator; import org.opentripplanner.raptor.util.paretoset.ParetoSet; +import org.opentripplanner.utils.lang.OtpNumberFormat; +import org.opentripplanner.utils.logging.Throttle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/ForwardPathMapper.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/ForwardPathMapper.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/path/ForwardPathMapper.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/ForwardPathMapper.java index 8e9b77f9cb8..6f48aacf652 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/ForwardPathMapper.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/ForwardPathMapper.java @@ -1,8 +1,8 @@ package org.opentripplanner.raptor.rangeraptor.path; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.RaptorPath; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.api.view.ArrivalView; import org.opentripplanner.raptor.path.PathBuilder; import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/PathMapper.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/PathMapper.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/path/PathMapper.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/PathMapper.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparators.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparators.java similarity index 92% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparators.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparators.java index 192f957ae8f..22212517ce1 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparators.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparators.java @@ -8,7 +8,6 @@ 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; @@ -128,9 +127,7 @@ > ParetoComparator> comparatorTimetableAndC1() { private static < T extends RaptorTripSchedule - > ParetoComparator> comparatorTimetableAndRelaxedC1( - @Nonnull final RelaxFunction relaxCost - ) { + > ParetoComparator> comparatorTimetableAndRelaxedC1(final RelaxFunction relaxCost) { return (l, r) -> compareIterationDepartureTime(l, r) || compareArrivalTime(l, r) || @@ -161,9 +158,7 @@ > ParetoComparator> comparatorDepartureTimeAndC1() { private static < T extends RaptorTripSchedule - > ParetoComparator> comparatorArrivalTimeAndRelaxedC1( - @Nonnull RelaxFunction relaxCost - ) { + > ParetoComparator> comparatorArrivalTimeAndRelaxedC1(RelaxFunction relaxCost) { return (l, r) -> compareArrivalTime(l, r) || compareNumberOfTransfers(l, r) || @@ -173,9 +168,7 @@ > ParetoComparator> comparatorArrivalTimeAndRelaxedC1( private static < T extends RaptorTripSchedule - > ParetoComparator> comparatorDepartureTimeAndRelaxedC1( - @Nonnull RelaxFunction relaxCost - ) { + > ParetoComparator> comparatorDepartureTimeAndRelaxedC1(RelaxFunction relaxCost) { return (l, r) -> compareDepartureTime(l, r) || compareNumberOfTransfers(l, r) || @@ -185,9 +178,7 @@ > ParetoComparator> comparatorDepartureTimeAndRelaxedC1( private static < T extends RaptorTripSchedule - > ParetoComparator> comparatorTimetableAndC1AndC2( - @Nonnull DominanceFunction c2Comp - ) { + > ParetoComparator> comparatorTimetableAndC1AndC2(DominanceFunction c2Comp) { return (l, r) -> compareIterationDepartureTime(l, r) || compareArrivalTime(l, r) || @@ -200,8 +191,8 @@ > ParetoComparator> comparatorTimetableAndC1AndC2( private static < T extends RaptorTripSchedule > ParetoComparator> comparatorTimetableAndRelaxedC1IfC2IsOptimal( - @Nonnull RelaxFunction relaxCost, - @Nonnull DominanceFunction c2Comp + RelaxFunction relaxCost, + DominanceFunction c2Comp ) { return (l, r) -> compareIterationDepartureTime(l, r) || @@ -213,7 +204,7 @@ > ParetoComparator> comparatorTimetableAndRelaxedC1IfC2IsOptimal( private static < T extends RaptorTripSchedule - > ParetoComparator> comparatorWithC1AndC2(@Nonnull DominanceFunction c2Comp) { + > ParetoComparator> comparatorWithC1AndC2(DominanceFunction c2Comp) { return (l, r) -> compareArrivalTime(l, r) || compareNumberOfTransfers(l, r) || @@ -224,9 +215,7 @@ > ParetoComparator> comparatorWithC1AndC2(@Nonnull DominanceFuncti private static < T extends RaptorTripSchedule - > ParetoComparator> comparatorDepartureTimeAndC1AndC2( - @Nonnull DominanceFunction c2Comp - ) { + > ParetoComparator> comparatorDepartureTimeAndC1AndC2(DominanceFunction c2Comp) { return (l, r) -> compareDepartureTime(l, r) || compareNumberOfTransfers(l, r) || @@ -238,8 +227,8 @@ > ParetoComparator> comparatorDepartureTimeAndC1AndC2( private static < T extends RaptorTripSchedule > ParetoComparator> comparatorArrivalTimeAndRelaxedC1IfC2IsOptimal( - @Nonnull RelaxFunction relaxCost, - @Nonnull DominanceFunction c2Comp + RelaxFunction relaxCost, + DominanceFunction c2Comp ) { return (l, r) -> compareArrivalTime(l, r) || @@ -251,8 +240,8 @@ > ParetoComparator> comparatorArrivalTimeAndRelaxedC1IfC2IsOptimal private static < T extends RaptorTripSchedule > ParetoComparator> comparatorDepartureTimeAndRelaxedC1IfC2IsOptimal( - @Nonnull RelaxFunction relaxCost, - @Nonnull DominanceFunction c2Comp + RelaxFunction relaxCost, + DominanceFunction c2Comp ) { return (l, r) -> compareDepartureTime(l, r) || @@ -262,10 +251,10 @@ > ParetoComparator> comparatorDepartureTimeAndRelaxedC1IfC2IsOptim } private static boolean compareC1RelaxedIfC2IsOptimal( - @Nonnull RaptorPath l, - @Nonnull RaptorPath r, - @Nonnull RelaxFunction relaxCost, - @Nonnull DominanceFunction c2Comp + RaptorPath l, + RaptorPath r, + RelaxFunction relaxCost, + 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/ReversePathMapper.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/ReversePathMapper.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/path/ReversePathMapper.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/ReversePathMapper.java index fde483b4cd8..94b68e10985 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/ReversePathMapper.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/ReversePathMapper.java @@ -1,8 +1,8 @@ package org.opentripplanner.raptor.rangeraptor.path; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.RaptorPath; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.path.PathBuilder; import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; import org.opentripplanner.raptor.rangeraptor.transit.TripTimesSearch; diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/configure/PathConfig.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/configure/PathConfig.java similarity index 97% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/path/configure/PathConfig.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/configure/PathConfig.java index 673c83e6b78..24c4d8a3bed 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/configure/PathConfig.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/path/configure/PathConfig.java @@ -4,11 +4,11 @@ import org.opentripplanner.raptor.api.model.DominanceFunction; import org.opentripplanner.raptor.api.model.GeneralizedCostRelaxFunction; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; 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; @@ -102,7 +102,7 @@ private PathMapper createPathMapper(boolean includeCost) { ctx.raptorSlackProvider(), includeCost ? ctx.costCalculator() : null, ctx.stopNameResolver(), - ctx.transit().transferConstraintsSearch(), + ctx.transitData().transferConstraintsSearch(), ctx.lifeCycle() ); } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/ArrivalTimeRoutingStrategy.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/ArrivalTimeRoutingStrategy.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/ArrivalTimeRoutingStrategy.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/ArrivalTimeRoutingStrategy.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/MinTravelDurationRoutingStrategy.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/MinTravelDurationRoutingStrategy.java similarity index 99% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/MinTravelDurationRoutingStrategy.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/MinTravelDurationRoutingStrategy.java index 0e18729b97e..f68299a0a13 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/MinTravelDurationRoutingStrategy.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/MinTravelDurationRoutingStrategy.java @@ -2,7 +2,6 @@ import static org.opentripplanner.raptor.spi.RaptorTripScheduleSearch.UNBOUNDED_TRIP_INDEX; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.rangeraptor.internalapi.RoutingStrategy; @@ -12,6 +11,7 @@ import org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent; import org.opentripplanner.raptor.spi.RaptorConstrainedBoardingSearch; import org.opentripplanner.raptor.spi.RaptorRoute; +import org.opentripplanner.utils.time.TimeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRangeRaptorWorkerState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRangeRaptorWorkerState.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRangeRaptorWorkerState.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRangeRaptorWorkerState.java index e3aba5c36f9..bcb2ca0f798 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRangeRaptorWorkerState.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRangeRaptorWorkerState.java @@ -5,7 +5,7 @@ import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.model.TransitArrival; -import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerResult; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouterResult; import org.opentripplanner.raptor.rangeraptor.standard.besttimes.BestTimes; import org.opentripplanner.raptor.rangeraptor.standard.internalapi.ArrivedAtDestinationCheck; import org.opentripplanner.raptor.rangeraptor.standard.internalapi.BestNumberOfTransfers; @@ -209,8 +209,8 @@ private void transferToStop(int arrivalTimeTransit, int fromStop, RaptorTransfer } @Override - public RaptorWorkerResult results() { - return new StdRaptorWorkerResult<>( + public RaptorRouterResult results() { + return new StdRaptorRouterResult<>( bestTimes, stopArrivalsState::extractPaths, bestNumberOfTransfers::extractBestNumberOfTransfers diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRaptorWorkerResult.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRaptorRouterResult.java similarity index 92% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRaptorWorkerResult.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRaptorRouterResult.java index 7a6812c9c95..1612234b185 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRaptorWorkerResult.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdRaptorRouterResult.java @@ -4,14 +4,14 @@ import java.util.function.Supplier; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.RaptorPath; -import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerResult; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouterResult; import org.opentripplanner.raptor.rangeraptor.internalapi.SingleCriteriaStopArrivals; import org.opentripplanner.raptor.rangeraptor.standard.besttimes.BestTimes; /** * Result for Standard Range Raptor route call. */ -public class StdRaptorWorkerResult implements RaptorWorkerResult { +public class StdRaptorRouterResult implements RaptorRouterResult { private final BestTimes bestTimes; private final Supplier>> pathSupplier; @@ -23,7 +23,7 @@ public class StdRaptorWorkerResult implements Rapt */ private Collection> paths = null; - public StdRaptorWorkerResult( + public StdRaptorRouterResult( BestTimes bestTimes, Supplier>> pathSupplier, Supplier bestNumberOfTransfersSupplier diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdWorkerState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdWorkerState.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdWorkerState.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/StdWorkerState.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/BestTimes.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/BestTimes.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/BestTimes.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/BestTimes.java index 3807b26b6c6..296325e9022 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/BestTimes.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/BestTimes.java @@ -1,14 +1,14 @@ package org.opentripplanner.raptor.rangeraptor.standard.besttimes; -import static org.opentripplanner.framework.lang.IntUtils.intArray; +import static org.opentripplanner.utils.lang.IntUtils.intArray; import java.util.BitSet; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.rangeraptor.internalapi.SingleCriteriaStopArrivals; import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; import org.opentripplanner.raptor.rangeraptor.support.IntArraySingleCriteriaArrivals; import org.opentripplanner.raptor.rangeraptor.transit.TransitCalculator; import org.opentripplanner.raptor.util.BitSetIterator; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This class is responsible for keeping track of the overall best times and the best "on-board" diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/BestTimesOnlyStopArrivalsState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/BestTimesOnlyStopArrivalsState.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/BestTimesOnlyStopArrivalsState.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/BestTimesOnlyStopArrivalsState.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/SimpleArrivedAtDestinationCheck.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/SimpleArrivedAtDestinationCheck.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/SimpleArrivedAtDestinationCheck.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/SimpleArrivedAtDestinationCheck.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/SimpleBestNumberOfTransfers.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/SimpleBestNumberOfTransfers.java similarity index 77% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/SimpleBestNumberOfTransfers.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/SimpleBestNumberOfTransfers.java index 1fb703565f6..f529ce31e20 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/SimpleBestNumberOfTransfers.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/SimpleBestNumberOfTransfers.java @@ -1,10 +1,10 @@ package org.opentripplanner.raptor.rangeraptor.standard.besttimes; -import org.opentripplanner.framework.lang.IntUtils; -import org.opentripplanner.raptor.rangeraptor.internalapi.RoundProvider; import org.opentripplanner.raptor.rangeraptor.internalapi.SingleCriteriaStopArrivals; +import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; import org.opentripplanner.raptor.rangeraptor.standard.internalapi.BestNumberOfTransfers; import org.opentripplanner.raptor.rangeraptor.support.IntArraySingleCriteriaArrivals; +import org.opentripplanner.utils.lang.IntUtils; /** * The responsibility for this class is to keep track of the best (minimun) number of transfers for @@ -13,11 +13,12 @@ public class SimpleBestNumberOfTransfers implements BestNumberOfTransfers { private final int[] bestNumOfTransfers; - private final RoundProvider roundProvider; + private int round; - public SimpleBestNumberOfTransfers(int nStops, RoundProvider roundProvider) { + public SimpleBestNumberOfTransfers(int nStops, WorkerLifeCycle lifeCycle) { this.bestNumOfTransfers = IntUtils.intArray(nStops, unreachedMinNumberOfTransfers()); - this.roundProvider = roundProvider; + + lifeCycle.onPrepareForNextRound(r -> this.round = r); } @Override @@ -29,7 +30,7 @@ public int calculateMinNumberOfTransfers(int stop) { * Call this method to notify that the given stop is reached in the current round of Raptor. */ void arriveAtStop(int stop) { - final int numOfTransfers = roundProvider.round() - 1; + final int numOfTransfers = round - 1; if (numOfTransfers < bestNumOfTransfers[stop]) { bestNumOfTransfers[stop] = numOfTransfers; } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/UnknownPathFactory.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/UnknownPathFactory.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/UnknownPathFactory.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/UnknownPathFactory.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/configure/StdRangeRaptorConfig.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/configure/StdRangeRaptorConfig.java similarity index 93% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/configure/StdRangeRaptorConfig.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/configure/StdRangeRaptorConfig.java index 6e0c3ee5afd..f5f689c68c4 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/configure/StdRangeRaptorConfig.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/configure/StdRangeRaptorConfig.java @@ -4,12 +4,13 @@ import static org.opentripplanner.raptor.rangeraptor.path.PathParetoSetComparators.paretoComparator; import java.util.HashSet; +import java.util.Objects; import java.util.Set; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; 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.RaptorRouterResult; import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerState; import org.opentripplanner.raptor.rangeraptor.internalapi.RoutingStrategy; import org.opentripplanner.raptor.rangeraptor.path.DestinationArrivalPaths; @@ -32,6 +33,7 @@ import org.opentripplanner.raptor.rangeraptor.standard.stoparrivals.StdStopArrivalsState; import org.opentripplanner.raptor.rangeraptor.standard.stoparrivals.path.EgressArrivalToPathAdapter; import org.opentripplanner.raptor.rangeraptor.standard.stoparrivals.view.StopsCursor; +import org.opentripplanner.raptor.rangeraptor.transit.EgressPaths; /** * The responsibility of this class is to wire different standard range raptor worker configurations @@ -68,11 +70,11 @@ public RoutingStrategy strategy() { return strategy; } - public Heuristics createHeuristics(RaptorWorkerResult results) { + public Heuristics createHeuristics(RaptorRouterResult results) { return oneOf( new HeuristicsAdapter( ctx.nStops(), - ctx.egressPaths(), + egressPaths(), ctx.calculator(), ctx.costCalculator(), results.extractBestOverallArrivals(), @@ -163,7 +165,7 @@ private StopArrivalsState stdStopArrivalsState() { private StopArrivalsState wrapStopArrivalsStateWithDebugger(StopArrivalsState state) { if (ctx.debugFactory().isDebugStopArrival()) { return new DebugStopArrivalsState<>( - ctx.roundProvider(), + ctx.lifeCycle(), ctx.debugFactory(), stopsCursor(), state @@ -180,7 +182,7 @@ private DestinationArrivalPaths destinationArrivalPaths() { // adapter notify the destination on each new egress stop arrival. var pathsAdapter = createEgressArrivalToPathAdapter(destinationArrivalPaths); - resolveStopArrivals().setupEgressStopStates(ctx.egressPaths(), pathsAdapter); + resolveStopArrivals().setupEgressStopStates(egressPaths(), pathsAdapter); return destinationArrivalPaths; } @@ -219,7 +221,7 @@ private StdStopArrivals resolveStopArrivals() { this.stopArrivals = withBestNumberOfTransfers( oneOf( - new StdStopArrivals(ctx.nRounds(), ctx.nStops(), ctx.roundProvider()), + new StdStopArrivals(ctx.nRounds(), ctx.nStops(), ctx.lifeCycle()), StdStopArrivals.class ) ); @@ -232,7 +234,7 @@ private StdStopArrivals resolveStopArrivals() { */ private SimpleBestNumberOfTransfers createSimpleBestNumberOfTransfers() { return withBestNumberOfTransfers( - new SimpleBestNumberOfTransfers(ctx.nStops(), ctx.roundProvider()) + new SimpleBestNumberOfTransfers(ctx.nStops(), ctx.lifeCycle()) ); } @@ -249,7 +251,7 @@ private UnknownPathFactory unknownPathFactory() { resolveBestNumberOfTransfers(), ctx.calculator(), ctx.slackProvider().transferSlack(), - ctx.egressPaths(), + egressPaths(), MIN_TRAVEL_DURATION.is(ctx.profile()), paretoComparator(ctx.paretoSetTimeConfig(), ParetoSetCost.NONE, null, null), ctx.lifeCycle() @@ -259,8 +261,15 @@ private UnknownPathFactory unknownPathFactory() { private SimpleArrivedAtDestinationCheck createSimpleArrivedAtDestinationCheck() { return new SimpleArrivedAtDestinationCheck( resolveBestTimes(), - ctx.egressPaths().egressesWitchStartByWalking(), - ctx.egressPaths().egressesWitchStartByARide() + egressPaths().egressesWitchStartByWalking(), + egressPaths().egressesWitchStartByARide() + ); + } + + private EgressPaths egressPaths() { + return Objects.requireNonNull( + ctx.legs().getLast().egressPaths(), + "Last leg must have non-null egressPaths" ); } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/configure/VerifyRequestIsValid.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/configure/VerifyRequestIsValid.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/configure/VerifyRequestIsValid.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/configure/VerifyRequestIsValid.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/DebugStopArrivalsState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/DebugStopArrivalsState.java similarity index 94% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/DebugStopArrivalsState.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/DebugStopArrivalsState.java index 6249764340f..2e0f3277a2a 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/DebugStopArrivalsState.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/DebugStopArrivalsState.java @@ -7,7 +7,7 @@ import org.opentripplanner.raptor.api.model.TransitArrival; import org.opentripplanner.raptor.api.path.RaptorPath; import org.opentripplanner.raptor.rangeraptor.debug.DebugHandlerFactory; -import org.opentripplanner.raptor.rangeraptor.internalapi.RoundProvider; +import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; import org.opentripplanner.raptor.rangeraptor.standard.internalapi.StopArrivalsState; import org.opentripplanner.raptor.rangeraptor.standard.stoparrivals.view.StopsCursor; @@ -28,12 +28,12 @@ public final class DebugStopArrivalsState * Create a Standard range raptor state for the given context */ public DebugStopArrivalsState( - RoundProvider roundProvider, + WorkerLifeCycle lifeCycle, DebugHandlerFactory dFactory, StopsCursor stopsCursor, StopArrivalsState delegate ) { - this.debug = new StateDebugger<>(stopsCursor, roundProvider, dFactory); + this.debug = new StateDebugger<>(stopsCursor, lifeCycle, dFactory); this.delegate = delegate; } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/StateDebugger.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/StateDebugger.java similarity index 81% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/StateDebugger.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/StateDebugger.java index 374b4aaf17e..1aee775b920 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/StateDebugger.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/debug/StateDebugger.java @@ -6,7 +6,7 @@ import org.opentripplanner.raptor.api.view.ArrivalView; import org.opentripplanner.raptor.rangeraptor.debug.DebugHandlerFactory; import org.opentripplanner.raptor.rangeraptor.internalapi.DebugHandler; -import org.opentripplanner.raptor.rangeraptor.internalapi.RoundProvider; +import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; import org.opentripplanner.raptor.rangeraptor.standard.stoparrivals.view.StopsCursor; /** @@ -17,28 +17,25 @@ class StateDebugger { private final StopsCursor cursor; - private final RoundProvider roundProvider; private final DebugHandler> debugHandlerStopArrivals; + private int round; - StateDebugger( - StopsCursor cursor, - RoundProvider roundProvider, - DebugHandlerFactory dFactory - ) { + StateDebugger(StopsCursor cursor, WorkerLifeCycle lifeCycle, DebugHandlerFactory dFactory) { this.cursor = cursor; - this.roundProvider = roundProvider; this.debugHandlerStopArrivals = dFactory.debugStopArrival(); + + lifeCycle.onPrepareForNextRound(r -> this.round = r); } void acceptAccessPath(int stop, RaptorAccessEgress access) { if (isDebug(stop)) { - debugHandlerStopArrivals.accept(cursor.access(round(), stop, access)); + debugHandlerStopArrivals.accept(cursor.access(round, stop, access)); } } void rejectAccessPath(RaptorAccessEgress accessPath, int arrivalTime) { if (isDebug(accessPath.stop())) { - reject(cursor.fictiveAccess(round(), accessPath, arrivalTime)); + reject(cursor.fictiveAccess(round, accessPath, arrivalTime)); } } @@ -64,13 +61,13 @@ void dropOldStateAndAcceptNewOnStreetArrival(int stop, Runnable body) { void rejectTransit(int alightStop, int alightTime, T trip, int boardStop, int boardTime) { if (isDebug(alightStop)) { - reject(cursor.fictiveTransit(round(), alightStop, alightTime, trip, boardStop, boardTime)); + reject(cursor.fictiveTransit(round, alightStop, alightTime, trip, boardStop, boardTime)); } } void rejectTransfer(int fromStop, RaptorTransfer transfer, int toStop, int arrivalTime) { if (isDebug(transfer.stop())) { - reject(cursor.fictiveTransfer(round(), fromStop, transfer, toStop, arrivalTime)); + reject(cursor.fictiveTransfer(round, fromStop, transfer, toStop, arrivalTime)); } } @@ -81,7 +78,7 @@ private boolean isDebug(int stop) { } private void accept(int stop, boolean stopReachedOnBoard) { - debugHandlerStopArrivals.accept(cursor.stop(round(), stop, stopReachedOnBoard)); + debugHandlerStopArrivals.accept(cursor.stop(round, stop, stopReachedOnBoard)); } /** @@ -94,8 +91,6 @@ private void accept(int stop, boolean stopReachedOnBoard) { * handler about arrivals that are about to be dropped. */ private void drop(int stop, boolean onBoard, boolean newBestOverall) { - final int round = round(); - // if new arrival arrived on-board, if (onBoard) { // and an existing on-board arrival exist @@ -122,8 +117,4 @@ private void reject(ArrivalView arrival) { private void dropExistingArrival(int round, int stop, boolean onBoard) { debugHandlerStopArrivals.drop(cursor.stop(round, stop, onBoard), null, null); } - - private int round() { - return roundProvider.round(); - } } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/heuristics/HeuristicsAdapter.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/heuristics/HeuristicsAdapter.java similarity index 97% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/heuristics/HeuristicsAdapter.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/heuristics/HeuristicsAdapter.java index 3dbff516347..00cce39622d 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/heuristics/HeuristicsAdapter.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/heuristics/HeuristicsAdapter.java @@ -4,9 +4,6 @@ import java.util.Arrays; import java.util.List; import java.util.function.IntUnaryOperator; -import org.opentripplanner.framework.lang.IntUtils; -import org.opentripplanner.framework.time.TimeUtils; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.rangeraptor.internalapi.HeuristicAtStop; import org.opentripplanner.raptor.rangeraptor.internalapi.Heuristics; @@ -15,6 +12,9 @@ import org.opentripplanner.raptor.rangeraptor.transit.RaptorTransitCalculator; import org.opentripplanner.raptor.rangeraptor.transit.TransitCalculator; import org.opentripplanner.raptor.spi.RaptorCostCalculator; +import org.opentripplanner.utils.lang.IntUtils; +import org.opentripplanner.utils.time.TimeUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * The responsibility of this class is to play the {@link Heuristics} role. It wrap the internal diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/ArrivedAtDestinationCheck.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/ArrivedAtDestinationCheck.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/ArrivedAtDestinationCheck.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/ArrivedAtDestinationCheck.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/BestNumberOfTransfers.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/BestNumberOfTransfers.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/BestNumberOfTransfers.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/BestNumberOfTransfers.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/DestinationArrivalListener.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/DestinationArrivalListener.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/DestinationArrivalListener.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/DestinationArrivalListener.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/StopArrivalsState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/StopArrivalsState.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/StopArrivalsState.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/internalapi/StopArrivalsState.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/AccessStopArrivalState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/AccessStopArrivalState.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/AccessStopArrivalState.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/AccessStopArrivalState.java index 867707be215..62f708d1899 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/AccessStopArrivalState.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/AccessStopArrivalState.java @@ -1,9 +1,9 @@ package org.opentripplanner.raptor.rangeraptor.standard.stoparrivals; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This class is responsible for adding access functionality, which the {@link diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/DefaultStopArrivalState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/DefaultStopArrivalState.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/DefaultStopArrivalState.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/DefaultStopArrivalState.java index 6df63b37d16..b76b0560791 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/DefaultStopArrivalState.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/DefaultStopArrivalState.java @@ -1,9 +1,9 @@ package org.opentripplanner.raptor.rangeraptor.standard.stoparrivals; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * The main purpose of this class is to hold data for a given arrival at a stop and raptor round. It diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/EgressStopArrivalState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/EgressStopArrivalState.java similarity index 97% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/EgressStopArrivalState.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/EgressStopArrivalState.java index f546e358ad8..c002f57dcba 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/EgressStopArrivalState.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/EgressStopArrivalState.java @@ -2,11 +2,11 @@ import java.util.Collection; import java.util.List; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.rangeraptor.standard.internalapi.DestinationArrivalListener; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * The egress stop arrival state is responsible for sending arrival notifications. This is used to diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivals.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivals.java similarity index 87% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivals.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivals.java index b3b32890ec7..a6dee126211 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivals.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivals.java @@ -4,8 +4,8 @@ import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.model.TransitArrival; -import org.opentripplanner.raptor.rangeraptor.internalapi.RoundProvider; import org.opentripplanner.raptor.rangeraptor.internalapi.SingleCriteriaStopArrivals; +import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; import org.opentripplanner.raptor.rangeraptor.standard.internalapi.BestNumberOfTransfers; import org.opentripplanner.raptor.rangeraptor.standard.internalapi.DestinationArrivalListener; import org.opentripplanner.raptor.rangeraptor.support.IntArraySingleCriteriaArrivals; @@ -18,12 +18,12 @@ public final class StdStopArrivals implements Best /** Arrivals by round and stop - [round][stop] */ private final StopArrivalState[][] arrivals; - private final RoundProvider roundProvider; + private int round; - public StdStopArrivals(int nRounds, int nStops, RoundProvider roundProvider) { - this.roundProvider = roundProvider; + public StdStopArrivals(int nRounds, int nStops, WorkerLifeCycle lifeCycle) { //noinspection unchecked this.arrivals = (StopArrivalState[][]) new StopArrivalState[nRounds][nStops]; + lifeCycle.onPrepareForNextRound(r -> this.round = r); } /** @@ -71,12 +71,12 @@ public SingleCriteriaStopArrivals extractBestNumberOfTransfers() { void setAccessTime(int time, RaptorAccessEgress access, boolean bestTime) { final int stop = access.stop(); - var existingArrival = getOrCreateStopIndex(round(), stop); + var existingArrival = getOrCreateStopIndex(round, stop); if (existingArrival instanceof AccessStopArrivalState) { ((AccessStopArrivalState) existingArrival).setAccessTime(time, access, bestTime); } else { - arrivals[round()][stop] = + arrivals[round][stop] = new AccessStopArrivalState<>( time, access, @@ -92,13 +92,13 @@ void setAccessTime(int time, RaptorAccessEgress access, boolean bestTime) { */ void transferToStop(int fromStop, RaptorTransfer transfer, int arrivalTime) { int stop = transfer.stop(); - var state = getOrCreateStopIndex(round(), stop); + var state = getOrCreateStopIndex(round, stop); state.transferToStop(fromStop, arrivalTime, transfer); } void transitToStop(int stop, int time, int boardStop, int boardTime, T trip, boolean bestTime) { - var state = getOrCreateStopIndex(round(), stop); + var state = getOrCreateStopIndex(round, stop); state.arriveByTransit(time, boardStop, boardTime, trip); @@ -108,13 +108,13 @@ void transitToStop(int stop, int time, int boardStop, int boardTime, T trip, boo } int bestTimePreviousRound(int stop) { - return get(round() - 1, stop).time(); + return get(round - 1, stop).time(); } /* private methods */ TransitArrival previousTransit(int boardStopIndex) { - final int prevRound = round() - 1; + final int prevRound = round - 1; int stopIndex = boardStopIndex; StopArrivalState state = get(prevRound, boardStopIndex); @@ -129,10 +129,6 @@ TransitArrival previousTransit(int boardStopIndex) { : null; } - private int round() { - return roundProvider.round(); - } - private StopArrivalState getOrCreateStopIndex(final int round, final int stop) { if (arrivals[round][stop] == null) { arrivals[round][stop] = StopArrivalState.create(); diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivalsState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivalsState.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivalsState.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StdStopArrivalsState.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StopArrivalState.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StopArrivalState.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StopArrivalState.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/StopArrivalState.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/path/EgressArrivalToPathAdapter.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/path/EgressArrivalToPathAdapter.java similarity index 97% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/path/EgressArrivalToPathAdapter.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/path/EgressArrivalToPathAdapter.java index b52e0d854da..a5d39d2eca9 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/path/EgressArrivalToPathAdapter.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/path/EgressArrivalToPathAdapter.java @@ -4,8 +4,6 @@ import java.util.ArrayList; import java.util.List; -import org.opentripplanner.framework.time.TimeUtils; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.view.ArrivalView; @@ -16,6 +14,8 @@ import org.opentripplanner.raptor.rangeraptor.standard.internalapi.DestinationArrivalListener; import org.opentripplanner.raptor.rangeraptor.standard.stoparrivals.view.StopsCursor; import org.opentripplanner.raptor.rangeraptor.transit.TransitCalculator; +import org.opentripplanner.utils.time.TimeUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * The responsibility of this class is to listen for egress stop arrivals and forward these as diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Access.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Access.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Access.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Access.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/StopArrivalViewAdapter.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/StopArrivalViewAdapter.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/StopArrivalViewAdapter.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/StopArrivalViewAdapter.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/StopsCursor.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/StopsCursor.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/StopsCursor.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/StopsCursor.java index f72047597a7..32406951eda 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/StopsCursor.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/StopsCursor.java @@ -1,7 +1,6 @@ package org.opentripplanner.raptor.rangeraptor.standard.stoparrivals.view; import java.util.function.ToIntFunction; -import javax.annotation.Nonnull; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorTransfer; @@ -139,7 +138,7 @@ public ArrivalView stop(int round, int stop, boolean stopReachedOnBoard) { * Set cursor to stop followed by the give transit leg - this allows access to be time-shifted * according to the next transit boarding/departure time. */ - public ArrivalView stop(int round, int stop, @Nonnull Transit nextTransitLeg) { + public ArrivalView stop(int round, int stop, Transit nextTransitLeg) { var arrival = arrivals.get(round, stop); if (arrival.arrivedByAccessOnStreet()) { diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Transfer.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Transfer.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Transfer.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Transfer.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Transit.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Transit.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Transit.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/stoparrivals/view/Transit.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/support/IntArraySingleCriteriaArrivals.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/support/IntArraySingleCriteriaArrivals.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/support/IntArraySingleCriteriaArrivals.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/support/IntArraySingleCriteriaArrivals.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/support/TimeBasedBoardingSupport.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/support/TimeBasedBoardingSupport.java similarity index 92% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/support/TimeBasedBoardingSupport.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/support/TimeBasedBoardingSupport.java index 40df7000461..2b5c4694409 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/support/TimeBasedBoardingSupport.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/support/TimeBasedBoardingSupport.java @@ -1,10 +1,10 @@ package org.opentripplanner.raptor.rangeraptor.support; +import static org.opentripplanner.raptor.rangeraptor.transit.RoundTracker.isFirstRound; import static org.opentripplanner.raptor.spi.RaptorTripScheduleSearch.UNBOUNDED_TRIP_INDEX; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.model.TransitArrival; -import org.opentripplanner.raptor.rangeraptor.internalapi.RoundProvider; import org.opentripplanner.raptor.rangeraptor.internalapi.RoutingStrategy; import org.opentripplanner.raptor.rangeraptor.internalapi.SlackProvider; import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; @@ -13,7 +13,6 @@ import org.opentripplanner.raptor.spi.RaptorConstrainedBoardingSearch; import org.opentripplanner.raptor.spi.RaptorTimeTable; import org.opentripplanner.raptor.spi.RaptorTripScheduleSearch; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.request.TripScheduleBoardSearch; /** * This class contains code which is shared by all time-dependent {@link RoutingStrategy}s. @@ -23,25 +22,24 @@ public final class TimeBasedBoardingSupport { private final SlackProvider slackProvider; private final RaptorTransitCalculator calculator; - private final RoundProvider roundProvider; private final boolean hasTimeDependentAccess; private boolean inFirstIteration = true; private RaptorTimeTable timeTable; private RaptorTripScheduleSearch tripSearch; + private int round; public TimeBasedBoardingSupport( boolean hasTimeDependentAccess, SlackProvider slackProvider, RaptorTransitCalculator calculator, - RoundProvider roundProvider, WorkerLifeCycle subscriptions ) { this.hasTimeDependentAccess = hasTimeDependentAccess; this.slackProvider = slackProvider; this.calculator = calculator; - this.roundProvider = roundProvider; subscriptions.onIterationComplete(() -> inFirstIteration = false); + subscriptions.onPrepareForNextRound(r -> this.round = r); } public void prepareForTransitWith(RaptorTimeTable timeTable) { @@ -120,11 +118,8 @@ private int earliestBoardTime(int prevArrivalTime, int boardSlack) { return calculator.plusDuration(prevArrivalTime, boardSlack); } - /** - * Create a trip search using {@link TripScheduleBoardSearch}. - */ private RaptorTripScheduleSearch createTripSearch(RaptorTimeTable timeTable) { - if (!inFirstIteration && roundProvider.isFirstRound() && !hasTimeDependentAccess) { + if (!inFirstIteration && isFirstRound(round) && !hasTimeDependentAccess) { // For the first round of every iteration(except the first) we restrict the first // departure to happen within the time-window of the iteration. Another way to put this, // is to say that we allow for the access path to be time-shifted to a later departure, diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPaths.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPaths.java similarity index 92% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPaths.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPaths.java index 66b7227584d..7b4c3b76321 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPaths.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPaths.java @@ -5,6 +5,7 @@ import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNonOptimalPathsForStandardRaptor; import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.TIntObjectHashMap; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -38,17 +39,14 @@ private AccessPaths( int iterationStep, IntUnaryOperator iterationOp, TIntObjectMap> arrivedOnStreetByNumOfRides, - TIntObjectMap> arrivedOnBoardByNumOfRides + TIntObjectMap> arrivedOnBoardByNumOfRides, + int maxTimePenalty ) { this.iterationStep = iterationStep; this.iterationOp = iterationOp; this.arrivedOnStreetByNumOfRides = arrivedOnStreetByNumOfRides; this.arrivedOnBoardByNumOfRides = arrivedOnBoardByNumOfRides; - this.maxTimePenalty = - Math.max( - maxTimePenalty(arrivedOnBoardByNumOfRides), - maxTimePenalty(arrivedOnStreetByNumOfRides) - ); + this.maxTimePenalty = maxTimePenalty; } /** @@ -74,12 +72,28 @@ public static AccessPaths create( } paths = decorateWithTimePenaltyLogic(paths); + var arrivedOnBoardByNumOfRides = groupByRound(paths, RaptorAccessEgress::stopReachedByWalking); + var arrivedOnStreetByNumOfRides = groupByRound(paths, RaptorAccessEgress::stopReachedOnBoard); return new AccessPaths( iterationStep, iterationOp(searchDirection), - groupByRound(paths, RaptorAccessEgress::stopReachedByWalking), - groupByRound(paths, RaptorAccessEgress::stopReachedOnBoard) + arrivedOnBoardByNumOfRides, + arrivedOnStreetByNumOfRides, + Math.max( + maxTimePenalty(arrivedOnBoardByNumOfRides), + maxTimePenalty(arrivedOnStreetByNumOfRides) + ) + ); + } + + public AccessPaths copyEmpty() { + return new AccessPaths( + iterationStep, + iterationOp, + new TIntObjectHashMap<>(), + new TIntObjectHashMap<>(), + maxTimePenalty ); } @@ -141,7 +155,17 @@ public int next() { }; } - private int maxTimePenalty(TIntObjectMap> col) { + /** Raptor uses this information to optimize boarding of the first trip */ + public boolean hasTimeDependentAccess() { + return ( + hasTimeDependentAccess(arrivedOnBoardByNumOfRides) || + hasTimeDependentAccess(arrivedOnStreetByNumOfRides) + ); + } + + /* private methods */ + + private static int maxTimePenalty(TIntObjectMap> col) { return col .valueCollection() .stream() @@ -161,14 +185,6 @@ private static List decorateWithTimePenaltyLogic( return paths.stream().map(it -> it.hasTimePenalty() ? new AccessWithPenalty(it) : it).toList(); } - /** Raptor uses this information to optimize boarding of the first trip */ - public boolean hasTimeDependentAccess() { - return ( - hasTimeDependentAccess(arrivedOnBoardByNumOfRides) || - hasTimeDependentAccess(arrivedOnStreetByNumOfRides) - ); - } - private boolean hasTimePenalty() { return maxTimePenalty != RaptorConstants.TIME_NOT_SET; } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessWithPenalty.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessWithPenalty.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessWithPenalty.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessWithPenalty.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPaths.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPaths.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPaths.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPaths.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressWithPenalty.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressWithPenalty.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressWithPenalty.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressWithPenalty.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculator.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculator.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculator.java index 5c50aa030f5..20dda7a3b37 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculator.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculator.java @@ -1,7 +1,6 @@ package org.opentripplanner.raptor.rangeraptor.transit; import java.util.Iterator; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; @@ -14,6 +13,7 @@ import org.opentripplanner.raptor.spi.RaptorTransitDataProvider; import org.opentripplanner.raptor.spi.RaptorTripScheduleSearch; import org.opentripplanner.raptor.util.IntIterators; +import org.opentripplanner.utils.time.TimeUtils; public final class ForwardRaptorTransitCalculator extends ForwardTransitCalculator diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTimeCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTimeCalculator.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTimeCalculator.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTimeCalculator.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTransitCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTransitCalculator.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTransitCalculator.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTransitCalculator.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorSearchWindowCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorSearchWindowCalculator.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorSearchWindowCalculator.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorSearchWindowCalculator.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorTransitCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorTransitCalculator.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorTransitCalculator.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorTransitCalculator.java index af9cff110d0..141c71ee86c 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorTransitCalculator.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorTransitCalculator.java @@ -1,7 +1,7 @@ package org.opentripplanner.raptor.rangeraptor.transit; -import static org.opentripplanner.framework.time.TimeUtils.hm2time; import static org.opentripplanner.raptor.api.model.RaptorConstants.TIME_NOT_SET; +import static org.opentripplanner.utils.time.TimeUtils.hm2time; import java.util.Iterator; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculator.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculator.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculator.java index 09ded9fb4b7..1229c8d85ff 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculator.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculator.java @@ -1,7 +1,6 @@ package org.opentripplanner.raptor.rangeraptor.transit; import java.util.Iterator; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; @@ -14,6 +13,7 @@ import org.opentripplanner.raptor.spi.RaptorTransitDataProvider; import org.opentripplanner.raptor.spi.RaptorTripScheduleSearch; import org.opentripplanner.raptor.util.IntIterators; +import org.opentripplanner.utils.time.TimeUtils; public final class ReverseRaptorTransitCalculator extends ReverseTransitCalculator diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTimeCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTimeCalculator.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTimeCalculator.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTimeCalculator.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTransitCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTransitCalculator.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTransitCalculator.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTransitCalculator.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RoundTracker.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RoundTracker.java similarity index 82% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RoundTracker.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RoundTracker.java index 05159a19a1e..f65fb5bca5e 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RoundTracker.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/RoundTracker.java @@ -1,15 +1,17 @@ package org.opentripplanner.raptor.rangeraptor.transit; -import org.opentripplanner.raptor.rangeraptor.internalapi.RoundProvider; import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; /** * Round tracker to keep track of round index and when to stop exploring new rounds. *

    - * In round 0 the access paths with one leg are added. In round 1 the first transit and transfers is - * added, ... + * In round zero(0), the access paths with one leg are added. In round one(1) the first transit and + * transfers is added, ... */ -public class RoundTracker implements RoundProvider { +public class RoundTracker { + + private static final int ROUND_ZERO = 0; + private static final int FIRST_ROUND = 1; /** * The extra number of rounds/transfers we accept compared to the trip with the fewest number of @@ -20,7 +22,7 @@ public class RoundTracker implements RoundProvider { /** * The current round in progress (round index). */ - private int round = 0; + private int round = ROUND_ZERO; /** * The round upper limit for when to abort the search. @@ -28,7 +30,7 @@ public class RoundTracker implements RoundProvider { * This is default set to the maximum number of rounds limit, but as soon as the destination is * reach the {@link #numberOfAdditionalTransfers} is used to update the limit. *

    - * The limit is inclusive, indicating the the last round to process. + * The limit is inclusive, indicating the last round to process. */ private int roundMaxLimit; @@ -61,15 +63,15 @@ public int round() { * Return true if this round is the fist round, calculating the first transit path. Access is * calculated in round zero (0). */ - public boolean isFirstRound() { - return round == 1; + public static boolean isFirstRound(int round) { + return round == FIRST_ROUND; } /** * Before each iteration, initialize the round to 0. */ - private void setupIteration() { - round = 0; + public void setupIteration() { + round = ROUND_ZERO; } /** diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/SlackProviderAdapter.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/SlackProviderAdapter.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/SlackProviderAdapter.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/SlackProviderAdapter.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TimeCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TimeCalculator.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TimeCalculator.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TimeCalculator.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TransitCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TransitCalculator.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TransitCalculator.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TransitCalculator.java diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripScheduleExactMatchSearch.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripScheduleExactMatchSearch.java similarity index 97% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripScheduleExactMatchSearch.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripScheduleExactMatchSearch.java index 666cf95f31e..1db6b2de055 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripScheduleExactMatchSearch.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripScheduleExactMatchSearch.java @@ -1,9 +1,9 @@ package org.opentripplanner.raptor.rangeraptor.transit; -import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent; import org.opentripplanner.raptor.spi.RaptorTripScheduleSearch; +import org.opentripplanner.utils.tostring.ToStringBuilder; /** * This trip search will only match trips that is within the given slack of the timeLimit. diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripTimesSearch.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripTimesSearch.java similarity index 99% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripTimesSearch.java rename to raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripTimesSearch.java index 83bfbe16481..94dfa83ad80 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripTimesSearch.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/TripTimesSearch.java @@ -1,10 +1,10 @@ package org.opentripplanner.raptor.rangeraptor.transit; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor.api.model.RaptorTripPattern; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.view.ArrivalView; import org.opentripplanner.raptor.spi.BoardAndAlightTime; +import org.opentripplanner.utils.time.TimeUtils; /** * This class is used to find the board and alight time for a known trip, where you now the diff --git a/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ViaConnections.java b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ViaConnections.java new file mode 100644 index 00000000000..053c1da4354 --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/ViaConnections.java @@ -0,0 +1,26 @@ +package org.opentripplanner.raptor.rangeraptor.transit; + +import static java.util.stream.Collectors.groupingBy; + +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import java.util.Collection; +import java.util.List; +import org.opentripplanner.raptor.api.request.RaptorViaConnection; + +public class ViaConnections { + + private final TIntObjectMap> byFromStop; + + public ViaConnections(Collection viaConnections) { + this.byFromStop = new TIntObjectHashMap<>(); + viaConnections + .stream() + .collect(groupingBy(RaptorViaConnection::fromStop)) + .forEach(byFromStop::put); + } + + public TIntObjectMap> byFromStop() { + return byFromStop; + } +} diff --git a/src/main/java/org/opentripplanner/raptor/service/DebugHeuristics.java b/raptor/src/main/java/org/opentripplanner/raptor/service/DebugHeuristics.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/service/DebugHeuristics.java rename to raptor/src/main/java/org/opentripplanner/raptor/service/DebugHeuristics.java index bb4241bb2ae..f4c2c141f04 100644 --- a/src/main/java/org/opentripplanner/raptor/service/DebugHeuristics.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/service/DebugHeuristics.java @@ -5,13 +5,13 @@ import static org.opentripplanner.raptor.api.model.RaptorConstants.N_TRANSFERS_UNREACHED; import static org.opentripplanner.raptor.api.model.RaptorConstants.UNREACHED_HIGH; -import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.raptor.api.debug.DebugLogger; import org.opentripplanner.raptor.api.model.SearchDirection; import org.opentripplanner.raptor.api.request.DebugRequest; import org.opentripplanner.raptor.api.request.RaptorRequest; import org.opentripplanner.raptor.rangeraptor.internalapi.Heuristics; import org.opentripplanner.raptor.util.CompareIntArrays; +import org.opentripplanner.utils.lang.IntUtils; /** * Utility class to log computed heuristic data. diff --git a/src/main/java/org/opentripplanner/raptor/service/DefaultStopArrivals.java b/raptor/src/main/java/org/opentripplanner/raptor/service/DefaultStopArrivals.java similarity index 93% rename from src/main/java/org/opentripplanner/raptor/service/DefaultStopArrivals.java rename to raptor/src/main/java/org/opentripplanner/raptor/service/DefaultStopArrivals.java index 2d3e3795cd9..244dca1c81c 100644 --- a/src/main/java/org/opentripplanner/raptor/service/DefaultStopArrivals.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/service/DefaultStopArrivals.java @@ -1,7 +1,7 @@ package org.opentripplanner.raptor.service; import org.opentripplanner.raptor.api.response.StopArrivals; -import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerResult; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouterResult; import org.opentripplanner.raptor.rangeraptor.internalapi.SingleCriteriaStopArrivals; /** @@ -13,9 +13,9 @@ public class DefaultStopArrivals implements StopArrivals { private SingleCriteriaStopArrivals bestTransitArrivalTime = null; private SingleCriteriaStopArrivals bestNumberOfTransfers = null; - private final RaptorWorkerResult results; + private final RaptorRouterResult results; - public DefaultStopArrivals(RaptorWorkerResult results) { + public DefaultStopArrivals(RaptorRouterResult results) { this.results = results; } diff --git a/src/main/java/org/opentripplanner/raptor/service/DestinationNotReachedException.java b/raptor/src/main/java/org/opentripplanner/raptor/service/DestinationNotReachedException.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/service/DestinationNotReachedException.java rename to raptor/src/main/java/org/opentripplanner/raptor/service/DestinationNotReachedException.java diff --git a/src/main/java/org/opentripplanner/raptor/service/HeuristicSearchTask.java b/raptor/src/main/java/org/opentripplanner/raptor/service/HeuristicSearchTask.java similarity index 87% rename from src/main/java/org/opentripplanner/raptor/service/HeuristicSearchTask.java rename to raptor/src/main/java/org/opentripplanner/raptor/service/HeuristicSearchTask.java index 6a8bc003dd5..8d4f1218aaf 100644 --- a/src/main/java/org/opentripplanner/raptor/service/HeuristicSearchTask.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/service/HeuristicSearchTask.java @@ -3,22 +3,23 @@ import static org.opentripplanner.raptor.api.request.RaptorProfile.MIN_TRAVEL_DURATION; import javax.annotation.Nullable; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.model.SearchDirection; import org.opentripplanner.raptor.api.request.RaptorRequest; import org.opentripplanner.raptor.configure.RaptorConfig; +import org.opentripplanner.raptor.rangeraptor.RangeRaptor; import org.opentripplanner.raptor.rangeraptor.internalapi.Heuristics; -import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorker; -import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerResult; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouter; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouterResult; import org.opentripplanner.raptor.spi.RaptorTransitDataProvider; +import org.opentripplanner.utils.time.DurationUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Thin wrapper around a {@link RaptorWorker} to allow for some small additional features. This - * is mostly to extracted some "glue" out of the {@link RangeRaptorDynamicSearch} to make that - * simpler and let it focus on the main bossiness logic. + * This is a thin wrapper around the {@link RangeRaptor} to allow for some small additional + * features. This is mostly to extract some "glue" out of the {@link RangeRaptorDynamicSearch} to + * make that simpler and let it focus on the main business logic. *

    * This class is not meant for reuse, create one task for each potential heuristic search. The task * must be {@link #enable()}d before it is {@link #run()}. @@ -33,10 +34,10 @@ public class HeuristicSearchTask { private final RaptorTransitDataProvider transitData; private boolean run = false; - private RaptorWorker search = null; + private RaptorRouter search = null; private RaptorRequest originalRequest; private RaptorRequest heuristicRequest; - private RaptorWorkerResult result = null; + private RaptorRouterResult result = null; public HeuristicSearchTask( RaptorRequest request, @@ -144,7 +145,7 @@ private void createHeuristicSearchIfNotExist(RaptorRequest request) { ); heuristicRequest = builder.build(); - search = config.createHeuristicSearch(transitData, heuristicRequest); + search = config.createRangeRaptorWithHeuristicSearch(transitData, heuristicRequest); } } } diff --git a/src/main/java/org/opentripplanner/raptor/service/HeuristicToRunResolver.java b/raptor/src/main/java/org/opentripplanner/raptor/service/HeuristicToRunResolver.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/service/HeuristicToRunResolver.java rename to raptor/src/main/java/org/opentripplanner/raptor/service/HeuristicToRunResolver.java diff --git a/src/main/java/org/opentripplanner/raptor/service/RangeRaptorDynamicSearch.java b/raptor/src/main/java/org/opentripplanner/raptor/service/RangeRaptorDynamicSearch.java similarity index 89% rename from src/main/java/org/opentripplanner/raptor/service/RangeRaptorDynamicSearch.java rename to raptor/src/main/java/org/opentripplanner/raptor/service/RangeRaptorDynamicSearch.java index fb96b7a8724..50b485ab4cf 100644 --- a/src/main/java/org/opentripplanner/raptor/service/RangeRaptorDynamicSearch.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/service/RangeRaptorDynamicSearch.java @@ -11,7 +11,6 @@ import java.util.concurrent.Future; import java.util.stream.Collectors; import javax.annotation.Nullable; -import org.opentripplanner.framework.application.OTPRequestTimeoutException; import org.opentripplanner.raptor.RaptorService; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.request.RaptorRequest; @@ -20,8 +19,9 @@ import org.opentripplanner.raptor.api.response.RaptorResponse; import org.opentripplanner.raptor.configure.RaptorConfig; import org.opentripplanner.raptor.rangeraptor.internalapi.Heuristics; -import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorker; +import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorRouter; import org.opentripplanner.raptor.rangeraptor.transit.RaptorSearchWindowCalculator; +import org.opentripplanner.raptor.spi.ExtraMcRouterSearch; import org.opentripplanner.raptor.spi.RaptorTransitDataProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,7 +43,10 @@ public class RangeRaptorDynamicSearch { private final RaptorConfig config; private final RaptorTransitDataProvider transitData; private final RaptorRequest originalRequest; - private final RaptorSearchWindowCalculator dynamicSearchParamsCalculator; + private final RaptorSearchWindowCalculator dynamicSearchWindowCalculator; + + @Nullable + private final ExtraMcRouterSearch extraMcSearch; private final HeuristicSearchTask fwdHeuristics; private final HeuristicSearchTask revHeuristics; @@ -51,13 +54,15 @@ public class RangeRaptorDynamicSearch { public RangeRaptorDynamicSearch( RaptorConfig config, RaptorTransitDataProvider transitData, + @Nullable ExtraMcRouterSearch extraMcSearch, RaptorRequest originalRequest ) { this.config = config; this.transitData = transitData; this.originalRequest = originalRequest; - this.dynamicSearchParamsCalculator = + this.dynamicSearchWindowCalculator = config.searchWindowCalculator().withSearchParams(originalRequest.searchParams()); + this.extraMcSearch = extraMcSearch; this.fwdHeuristics = new HeuristicSearchTask<>(FORWARD, "Forward", config, transitData); this.revHeuristics = new HeuristicSearchTask<>(REVERSE, "Reverse", config, transitData); @@ -67,19 +72,18 @@ public RaptorResponse route() { try { enableHeuristicSearchBasedOnOptimizationsAndSearchParameters(); - // Run heuristics, if no destination is reached + // Run the heuristics if no destination is reached runHeuristics(); // Set search-window and other dynamic calculated parameters - RaptorRequest dynamicRequest = originalRequest; - dynamicRequest = requestWithDynamicSearchParams(dynamicRequest); + var dynamicRequest = requestWithDynamicSearchParams(originalRequest); return createAndRunDynamicRRWorker(dynamicRequest); } catch (DestinationNotReachedException e) { return new RaptorResponse<>( Collections.emptyList(), null, - // If a trip exist(forward heuristics succeed), but is outside the calculated + // If a trip exists(forward heuristics succeed), but is outside the calculated // search-window, then set the search-window params as if the request was // performed. This enables the client to page to the next window requestWithDynamicSearchParams(originalRequest), @@ -130,17 +134,23 @@ private void runHeuristics() { private RaptorResponse createAndRunDynamicRRWorker(RaptorRequest request) { LOG.debug("Main request: {}", request); - RaptorWorker raptorWorker; + RaptorRouter raptorRouter; // Create worker if (request.profile().is(MULTI_CRITERIA)) { - raptorWorker = config.createMcWorker(transitData, request, getDestinationHeuristics()); + raptorRouter = + config.createRangeRaptorWithMcWorker( + transitData, + request, + getDestinationHeuristics(), + extraMcSearch + ); } else { - raptorWorker = config.createStdWorker(transitData, request); + raptorRouter = config.createRangeRaptorWithStdWorker(transitData, request); } // Route - var result = raptorWorker.route(); + var result = raptorRouter.route(); // create and return response return new RaptorResponse<>( @@ -182,10 +192,10 @@ private void runHeuristicsInParallel() { Thread.currentThread().interrupt(); // propagate interruption to the running task. asyncResult.cancel(true); - throw new OTPRequestTimeoutException(); + throw config.mapInterruptedException(e); } catch (ExecutionException e) { - if (e.getCause() instanceof DestinationNotReachedException) { - throw new DestinationNotReachedException(); + if (e.getCause() instanceof DestinationNotReachedException dnr) { + throw dnr; } LOG.error(e.getMessage() + ". Request: " + originalRequest, e); throw new IllegalStateException( @@ -274,10 +284,10 @@ private RaptorRequest requestWithDynamicSearchParams(RaptorRequest request SearchParamsBuilder builder = request.mutate().searchParams(); if (!request.searchParams().isEarliestDepartureTimeSet()) { - builder.earliestDepartureTime(dynamicSearchParamsCalculator.getEarliestDepartureTime()); + builder.earliestDepartureTime(dynamicSearchWindowCalculator.getEarliestDepartureTime()); } if (!request.searchParams().isSearchWindowSet()) { - builder.searchWindowInSeconds(dynamicSearchParamsCalculator.getSearchWindowSeconds()); + builder.searchWindowInSeconds(dynamicSearchWindowCalculator.getSearchWindowSeconds()); } // We do not set the latest-arrival-time, because we do not want to limit the forward // multi-criteria search, it does not have much effect on the performance - we only risk @@ -287,7 +297,7 @@ private RaptorRequest requestWithDynamicSearchParams(RaptorRequest request private void calculateDynamicSearchParametersFromHeuristics(@Nullable Heuristics heuristics) { if (heuristics != null) { - dynamicSearchParamsCalculator + dynamicSearchWindowCalculator .withHeuristics( heuristics.bestOverallJourneyTravelDuration(), heuristics.minWaitTimeForJourneysReachingDestination() diff --git a/src/main/java/org/opentripplanner/raptor/spi/BoardAndAlightTime.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/BoardAndAlightTime.java similarity index 76% rename from src/main/java/org/opentripplanner/raptor/spi/BoardAndAlightTime.java rename to raptor/src/main/java/org/opentripplanner/raptor/spi/BoardAndAlightTime.java index 94744f4bd61..c90e67934a8 100644 --- a/src/main/java/org/opentripplanner/raptor/spi/BoardAndAlightTime.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/spi/BoardAndAlightTime.java @@ -1,8 +1,9 @@ package org.opentripplanner.raptor.spi; import java.util.Objects; -import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; /** * Board and alight time tuple value object. @@ -68,19 +69,18 @@ public boolean equals(Object o) { @Override public String toString() { - return ValueObjectToStringBuilder - .of() - .addText("[") - .addObj(trip.pattern().stopIndex(boardStopPos)) - .addText(" ~ ") - .addServiceTime(boardTime()) - .addText(" ") - .addServiceTime(alightTime()) - .addText("(") - .addDurationSec(alightTime() - boardTime()) - .addText(") ~ ") - .addObj(trip.pattern().stopIndex(alightStopPos)) - .addText("]") - .toString(); + return ( + "[" + + trip.pattern().stopIndex(boardStopPos) + + " ~ " + + TimeUtils.timeToStrCompact(boardTime()) + + " " + + TimeUtils.timeToStrCompact(alightTime()) + + "(" + + DurationUtils.durationToStr(alightTime() - boardTime()) + + ") ~ " + + trip.pattern().stopIndex(alightStopPos) + + "]" + ); } } diff --git a/src/main/java/org/opentripplanner/raptor/spi/DefaultSlackProvider.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/DefaultSlackProvider.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/spi/DefaultSlackProvider.java rename to raptor/src/main/java/org/opentripplanner/raptor/spi/DefaultSlackProvider.java diff --git a/src/main/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEvent.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEvent.java similarity index 86% rename from src/main/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEvent.java rename to raptor/src/main/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEvent.java index 9d29fc50d38..4c0b76d99f9 100644 --- a/src/main/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEvent.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEvent.java @@ -1,10 +1,10 @@ package org.opentripplanner.raptor.spi; import java.util.function.Consumer; -import javax.annotation.Nonnull; import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.utils.time.TimeUtils; record EmptyBoardOrAlightEvent(int earliestBoardTime) implements RaptorBoardOrAlightEvent { @@ -28,7 +28,6 @@ public int time() { throw new UnsupportedOperationException(); } - @Nonnull @Override public RaptorTransferConstraint transferConstraint() { return RaptorTransferConstraint.REGULAR_TRANSFER; @@ -46,4 +45,9 @@ public void boardWithFallback( ) { alternativeBoardingFallback.accept(this); } + + @Override + public String toString() { + return "EmptyBoardOrAlightEvent(" + TimeUtils.timeToStrLong(earliestBoardTime) + ")"; + } } diff --git a/raptor/src/main/java/org/opentripplanner/raptor/spi/ExtraMcRouterSearch.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/ExtraMcRouterSearch.java new file mode 100644 index 00000000000..e6fdc4fd0d0 --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/spi/ExtraMcRouterSearch.java @@ -0,0 +1,39 @@ +package org.opentripplanner.raptor.spi; + +import java.util.Collection; +import java.util.function.BiFunction; +import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.raptor.api.path.RaptorPath; + +/** + * This interface is used to run two multi-criteria searches and merging the result. Raptor will + * run the heuristics as normal. Then create two multi-criteria searches, the main search and the + * alternative search. The caller must provide a {@code merger} and + * {@link RaptorTransitDataProvider}. The transit data is used for the alternative search. This + * allows the caller to filter the transit data or change the cost-calculator. + *

    + * When changing the transit data, you may also invalidate the heuristics created by Raptor. If this + * is the case, you need to turn off the {@link org.opentripplanner.raptor.api.request.Optimization#PARETO_CHECK_AGAINST_DESTINATION}. + * For the heuristics to work, you may add extra cost or filter away data. But you cannot decrease + * the cost, add transfer or add new trips. + *

    + * This will alter the multi-criteria search, if only a standard search is requested any extra + * multi-criteria search is ignored. + *

    + * @param The TripSchedule type defined by the user of the raptor API. + */ +public interface ExtraMcRouterSearch { + /** + * The returned transit-data is used in the ALTERNATIVE search. The given transit data is used in + * the main search. It is the same data passed into Raptor. + */ + RaptorTransitDataProvider createTransitDataAlternativeSearch( + RaptorTransitDataProvider transitDataMainSearch + ); + + /** + * You must provide a merge strategy to merge the main result (first argument) with the + * alternative result(second argument). Make sure the end result does not have any duplicates. + */ + BiFunction>, Collection>, Collection>> merger(); +} diff --git a/src/main/java/org/opentripplanner/raptor/spi/Flyweight.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/Flyweight.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/spi/Flyweight.java rename to raptor/src/main/java/org/opentripplanner/raptor/spi/Flyweight.java diff --git a/src/main/java/org/opentripplanner/raptor/spi/IntIterator.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/IntIterator.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/spi/IntIterator.java rename to raptor/src/main/java/org/opentripplanner/raptor/spi/IntIterator.java diff --git a/src/main/java/org/opentripplanner/raptor/spi/RaptorBoardOrAlightEvent.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorBoardOrAlightEvent.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/spi/RaptorBoardOrAlightEvent.java rename to raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorBoardOrAlightEvent.java index 5913f950969..bf71011a330 100644 --- a/src/main/java/org/opentripplanner/raptor/spi/RaptorBoardOrAlightEvent.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorBoardOrAlightEvent.java @@ -1,7 +1,6 @@ package org.opentripplanner.raptor.spi; import java.util.function.Consumer; -import javax.annotation.Nonnull; import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; @@ -65,7 +64,6 @@ default int boardStopIndex() { * constraints assisiated with the boarding the {@link RaptorTransferConstraint#isRegularTransfer()} * is {@code true}. */ - @Nonnull RaptorTransferConstraint transferConstraint(); /** diff --git a/src/main/java/org/opentripplanner/raptor/spi/RaptorConstrainedBoardingSearch.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorConstrainedBoardingSearch.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/spi/RaptorConstrainedBoardingSearch.java rename to raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorConstrainedBoardingSearch.java diff --git a/src/main/java/org/opentripplanner/raptor/spi/RaptorCostCalculator.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorCostCalculator.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/spi/RaptorCostCalculator.java rename to raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorCostCalculator.java diff --git a/src/main/java/org/opentripplanner/raptor/spi/RaptorPathConstrainedTransferSearch.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorPathConstrainedTransferSearch.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/spi/RaptorPathConstrainedTransferSearch.java rename to raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorPathConstrainedTransferSearch.java diff --git a/src/main/java/org/opentripplanner/raptor/spi/RaptorRoute.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorRoute.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/spi/RaptorRoute.java rename to raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorRoute.java diff --git a/src/main/java/org/opentripplanner/raptor/spi/RaptorSlackProvider.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorSlackProvider.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/spi/RaptorSlackProvider.java rename to raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorSlackProvider.java diff --git a/src/main/java/org/opentripplanner/raptor/spi/RaptorTimeTable.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorTimeTable.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/spi/RaptorTimeTable.java rename to raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorTimeTable.java diff --git a/src/main/java/org/opentripplanner/raptor/spi/RaptorTransitDataProvider.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorTransitDataProvider.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/spi/RaptorTransitDataProvider.java rename to raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorTransitDataProvider.java index b4accdbcc2b..a442f0a3216 100644 --- a/src/main/java/org/opentripplanner/raptor/spi/RaptorTransitDataProvider.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorTransitDataProvider.java @@ -2,11 +2,11 @@ import java.util.Iterator; import javax.annotation.Nonnull; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; import org.opentripplanner.raptor.api.model.RaptorTripPattern; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.api.request.RaptorRequest; /** @@ -120,7 +120,6 @@ default void setup() {} * method is used by Raptor to translate from the stop index to a string which should be short and * identify the stop given the related pattern, for example the stop name would be great. */ - @Nonnull RaptorStopNameResolver stopNameResolver(); /** diff --git a/src/main/java/org/opentripplanner/raptor/spi/RaptorTripScheduleSearch.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorTripScheduleSearch.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/spi/RaptorTripScheduleSearch.java rename to raptor/src/main/java/org/opentripplanner/raptor/spi/RaptorTripScheduleSearch.java diff --git a/src/main/java/org/opentripplanner/raptor/spi/UnknownPath.java b/raptor/src/main/java/org/opentripplanner/raptor/spi/UnknownPath.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/spi/UnknownPath.java rename to raptor/src/main/java/org/opentripplanner/raptor/spi/UnknownPath.java index 24eae14f997..91de7373650 100644 --- a/src/main/java/org/opentripplanner/raptor/spi/UnknownPath.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/spi/UnknownPath.java @@ -3,13 +3,13 @@ import java.util.List; import java.util.stream.Stream; import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.AccessPathLeg; import org.opentripplanner.raptor.api.path.EgressPathLeg; import org.opentripplanner.raptor.api.path.PathLeg; import org.opentripplanner.raptor.api.path.PathStringBuilder; import org.opentripplanner.raptor.api.path.RaptorPath; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.api.path.TransitPathLeg; /** diff --git a/src/main/java/org/opentripplanner/raptor/util/BitSetIterator.java b/raptor/src/main/java/org/opentripplanner/raptor/util/BitSetIterator.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/util/BitSetIterator.java rename to raptor/src/main/java/org/opentripplanner/raptor/util/BitSetIterator.java diff --git a/src/main/java/org/opentripplanner/raptor/util/CompareIntArrays.java b/raptor/src/main/java/org/opentripplanner/raptor/util/CompareIntArrays.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/util/CompareIntArrays.java rename to raptor/src/main/java/org/opentripplanner/raptor/util/CompareIntArrays.java index 9bff831a670..1f446fe036c 100644 --- a/src/main/java/org/opentripplanner/raptor/util/CompareIntArrays.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/util/CompareIntArrays.java @@ -2,7 +2,7 @@ import java.util.Comparator; import java.util.function.IntFunction; -import org.opentripplanner.framework.time.TimeUtils; +import org.opentripplanner.utils.time.TimeUtils; /** * The responsibility of this class is to compare two int arrays and list all elements that differ. diff --git a/src/main/java/org/opentripplanner/raptor/util/IntIterators.java b/raptor/src/main/java/org/opentripplanner/raptor/util/IntIterators.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/util/IntIterators.java rename to raptor/src/main/java/org/opentripplanner/raptor/util/IntIterators.java diff --git a/raptor/src/main/java/org/opentripplanner/raptor/util/composite/CompositeUtil.java b/raptor/src/main/java/org/opentripplanner/raptor/util/composite/CompositeUtil.java new file mode 100644 index 00000000000..057e30cf7e7 --- /dev/null +++ b/raptor/src/main/java/org/opentripplanner/raptor/util/composite/CompositeUtil.java @@ -0,0 +1,54 @@ +package org.opentripplanner.raptor.util.composite; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Stream; +import javax.annotation.Nullable; + +public class CompositeUtil { + + /** + * Take a list of children and return a composite instance. {@code null} values are skipped. If + * the result is empty {@code null} is returned. If just one listener is passed in the listener + * it-self is returned (without any composite wrapper). + * + * @param The base type which the composite inherit from. + * @param compositeFactory Factory method to create a new composite. + * @param isComposite used to test if an instance is of a composite type. + * @param listCompositeChildren is a function used to extract all children out of a composite + * instance. + * @return {@code null} if the list of children is empty - ignoring {@code null} elements. + * Returning THE element if just one element exists. And returning a composite with a + * list of children if more than one element exists. The order is kept "as is". Any + * composite children flattened, the children are inserted in it place. + */ + @Nullable + @SafeVarargs + public static T of( + Function, T> compositeFactory, + Predicate isComposite, + Function> listCompositeChildren, + T... children + ) { + Objects.requireNonNull(children); + + var list = Arrays + .stream(children) + .filter(Objects::nonNull) + .flatMap(it -> isComposite.test(it) ? listCompositeChildren.apply(it).stream() : Stream.of(it) + ) + .toList(); + + if (list.isEmpty()) { + return null; + } + if (list.size() == 1) { + return list.getFirst(); + } + return compositeFactory.apply(list); + } +} diff --git a/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoComparator.java b/raptor/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoComparator.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoComparator.java rename to raptor/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoComparator.java diff --git a/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSet.java b/raptor/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSet.java similarity index 98% rename from src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSet.java rename to raptor/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSet.java index 39656d433e9..536378e3722 100644 --- a/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSet.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSet.java @@ -211,6 +211,14 @@ protected void notifyElementMoved(int fromIndex, int toIndex) { // Noop } + protected ParetoComparator getComparator() { + return comparator; + } + + protected ParetoSetEventListener getEventListener() { + return eventListener; + } + /** * Return an iterable instance. This is made to be as FAST AS POSSIBLE, sacrificing thread-safety * and modifiable protection. diff --git a/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListener.java b/raptor/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListener.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListener.java rename to raptor/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListener.java diff --git a/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerComposite.java b/raptor/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerComposite.java similarity index 52% rename from src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerComposite.java rename to raptor/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerComposite.java index 01d68af4392..a8a74f8c80e 100644 --- a/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerComposite.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerComposite.java @@ -1,9 +1,9 @@ package org.opentripplanner.raptor.util.paretoset; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.List; +import javax.annotation.Nullable; +import org.opentripplanner.raptor.util.composite.CompositeUtil; /** * The {@link ParetoSet} do only support ONE listener, this class uses the composite pattern to @@ -14,17 +14,29 @@ */ public class ParetoSetEventListenerComposite implements ParetoSetEventListener { - private final List> listeners = new ArrayList<>(); + private final List> listeners; + /** + * Take a list of listeners and return a composite listener. Input listeners, which are {@code null}, + * are skipped. If no listeners are provided or all listeners are {@code null}, then + * {@code null} is returned. If just one listener is passed in the listener it-self is returned + * (without any wrapper). If more than one listener exists, a composite instance is returned. + */ + @Nullable @SafeVarargs - public ParetoSetEventListenerComposite(ParetoSetEventListener... listeners) { - this(Arrays.asList(listeners)); + public static ParetoSetEventListener of(ParetoSetEventListener... listeners) { + return CompositeUtil.of( + ParetoSetEventListenerComposite::new, + it -> it instanceof ParetoSetEventListenerComposite, + it -> ((ParetoSetEventListenerComposite) it).listeners, + listeners + ); } private ParetoSetEventListenerComposite( Collection> listeners ) { - this.listeners.addAll(listeners); + this.listeners = List.copyOf(listeners); } @Override @@ -47,4 +59,9 @@ public void notifyElementRejected(T element, T rejectedByElement) { it.notifyElementRejected(element, rejectedByElement); } } + + @Override + public String toString() { + return "ParetoSetEventListenerComposite{" + "listeners=" + listeners + '}'; + } } diff --git a/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSetWithMarker.java b/raptor/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSetWithMarker.java similarity index 100% rename from src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSetWithMarker.java rename to raptor/src/main/java/org/opentripplanner/raptor/util/paretoset/ParetoSetWithMarker.java diff --git a/src/test/java/org/opentripplanner/raptor/RaptorArchitectureTest.java b/raptor/src/test/java/org/opentripplanner/raptor/RaptorArchitectureTest.java similarity index 80% rename from src/test/java/org/opentripplanner/raptor/RaptorArchitectureTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/RaptorArchitectureTest.java index 39022da42ca..3ada07c090b 100644 --- a/src/test/java/org/opentripplanner/raptor/RaptorArchitectureTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/RaptorArchitectureTest.java @@ -1,27 +1,33 @@ package org.opentripplanner.raptor; import static com.tngtech.archunit.library.dependencies.SlicesRuleDefinition.slices; -import static org.opentripplanner.OtpArchitectureModules.FRAMEWORK_UTILS; -import static org.opentripplanner.OtpArchitectureModules.GNU_TROVE; -import static org.opentripplanner.OtpArchitectureModules.OTP_ROOT; -import static org.opentripplanner.OtpArchitectureModules.RAPTOR_API; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.opentripplanner._support.arch.ArchComponent; -import org.opentripplanner._support.arch.Module; -import org.opentripplanner._support.arch.Package; +import org.opentripplanner.raptor._support.arch.ArchComponent; +import org.opentripplanner.raptor._support.arch.Module; +import org.opentripplanner.raptor._support.arch.Package; public class RaptorArchitectureTest { + private static final Package OTP_ROOT = Package.of("org.opentripplanner"); + private static final Package GNU_TROVE = Package.of("gnu.trove.."); + private static final Package OTP_UTILS = OTP_ROOT.subPackage("utils.."); + /* The Raptor module, all packages that other paths of OTP may use. */ private static final Package RAPTOR = OTP_ROOT.subPackage("raptor"); + private static final Package RAPTOR_API = RAPTOR.subPackage("api.."); private static final Package API = RAPTOR.subPackage("api"); private static final Package API_MODEL = API.subPackage("model"); private static final Package API_PATH = API.subPackage("path"); private static final Package RAPTOR_UTIL = RAPTOR.subPackage("util"); private static final Package RAPTOR_UTIL_PARETO_SET = RAPTOR_UTIL.subPackage("paretoset"); - private static final Module RAPTOR_UTILS = Module.of(RAPTOR_UTIL, RAPTOR_UTIL_PARETO_SET); + private static final Package RAPTOR_UTIL_COMPOSITE = RAPTOR_UTIL.subPackage("composite"); + private static final Module RAPTOR_UTILS = Module.of( + RAPTOR_UTIL, + RAPTOR_UTIL_PARETO_SET, + RAPTOR_UTIL_COMPOSITE + ); private static final Package RAPTOR_SPI = RAPTOR.subPackage("spi"); private static final Package RAPTOR_PATH = RAPTOR.subPackage("path"); private static final Package CONFIGURE = RAPTOR.subPackage("configure"); @@ -44,7 +50,7 @@ public class RaptorArchitectureTest { * Packages used by standard-range-raptor and multi-criteria-range-raptor. */ private static final Module RR_SHARED_PACKAGES = Module.of( - FRAMEWORK_UTILS, + OTP_UTILS, GNU_TROVE, RAPTOR_API, RAPTOR_SPI, @@ -59,36 +65,37 @@ public class RaptorArchitectureTest { @Test void enforcePackageDependenciesRaptorAPI() { - API_MODEL.dependsOn(FRAMEWORK_UTILS).verify(); - API_PATH.dependsOn(FRAMEWORK_UTILS, API_MODEL).verify(); - var debug = API.subPackage("debug").dependsOn(FRAMEWORK_UTILS).verify(); - var view = API.subPackage("view").dependsOn(FRAMEWORK_UTILS, API_MODEL).verify(); + API_MODEL.dependsOn(OTP_UTILS).verify(); + API_PATH.dependsOn(OTP_UTILS, API_MODEL).verify(); + var debug = API.subPackage("debug").dependsOn(OTP_UTILS).verify(); + var view = API.subPackage("view").dependsOn(OTP_UTILS, API_MODEL).verify(); var request = API .subPackage("request") - .dependsOn(FRAMEWORK_UTILS, debug, API_MODEL, API_PATH, view) + .dependsOn(OTP_UTILS, debug, API_MODEL, API_PATH, view) .verify(); - API.subPackage("response").dependsOn(FRAMEWORK_UTILS, API_MODEL, API_PATH, request).verify(); + API.subPackage("response").dependsOn(OTP_UTILS, API_MODEL, API_PATH, request).verify(); } @Test void enforcePackageDependenciesRaptorSPI() { - RAPTOR.subPackage("spi").dependsOn(FRAMEWORK_UTILS, API_MODEL, API_PATH).verify(); + RAPTOR_SPI.dependsOn(OTP_UTILS, API_MODEL, API_PATH).verify(); } @Test void enforcePackageDependenciesUtil() { - RAPTOR_UTIL.dependsOn(FRAMEWORK_UTILS, RAPTOR_SPI).verify(); - RAPTOR_UTIL_PARETO_SET.verify(); + RAPTOR_UTIL.dependsOn(OTP_UTILS, RAPTOR_SPI).verify(); + RAPTOR_UTIL_PARETO_SET.dependsOn(RAPTOR_UTIL_COMPOSITE).verify(); + RAPTOR_UTIL_COMPOSITE.verify(); } @Test void enforcePackageDependenciesRaptorPath() { - RAPTOR_PATH.dependsOn(FRAMEWORK_UTILS, API_PATH, API_MODEL, RAPTOR_SPI, RR_TRANSIT).verify(); + RAPTOR_PATH.dependsOn(OTP_UTILS, API_PATH, API_MODEL, RAPTOR_SPI, RR_TRANSIT).verify(); } @Test void enforcePackageDependenciesInRangeRaptorSharedPackages() { - RR_INTERNAL_API.dependsOn(FRAMEWORK_UTILS, RAPTOR_API, RAPTOR_SPI).verify(); + RR_INTERNAL_API.dependsOn(OTP_UTILS, RAPTOR_API, RAPTOR_SPI).verify(); RR_DEBUG.dependsOn(RR_SHARED_PACKAGES).verify(); RR_LIFECYCLE.dependsOn(RR_SHARED_PACKAGES).verify(); RR_TRANSIT.dependsOn(RR_SHARED_PACKAGES, RR_DEBUG, RR_LIFECYCLE).verify(); @@ -194,13 +201,14 @@ void enforcePackageDependenciesInMultiCriteriaImplementation() { void enforcePackageDependenciesInRaptorService() { SERVICE .dependsOn( - FRAMEWORK_UTILS, + OTP_UTILS, RAPTOR_API, RAPTOR_SPI, RAPTOR_UTIL, CONFIGURE, RR_INTERNAL_API, - RR_TRANSIT + RR_TRANSIT, + RANGE_RAPTOR ) .verify(); } @@ -209,6 +217,7 @@ void enforcePackageDependenciesInRaptorService() { void enforcePackageDependenciesInConfigure() { CONFIGURE .dependsOn( + OTP_UTILS, RAPTOR_API, RAPTOR_SPI, RANGE_RAPTOR, @@ -216,8 +225,7 @@ void enforcePackageDependenciesInConfigure() { RR_TRANSIT, RR_CONTEXT, RR_STD_CONFIGURE, - RR_MC_CONFIGURE, - FRAMEWORK_UTILS + RR_MC_CONFIGURE ) .verify(); } diff --git a/src/test/java/org/opentripplanner/raptor/_data/RaptorTestConstants.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/RaptorTestConstants.java similarity index 93% rename from src/test/java/org/opentripplanner/raptor/_data/RaptorTestConstants.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/RaptorTestConstants.java index 78489508dc4..0b5e47c977a 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/RaptorTestConstants.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/RaptorTestConstants.java @@ -1,7 +1,7 @@ package org.opentripplanner.raptor._data; -import static org.opentripplanner.framework.time.DurationUtils.durationInSeconds; -import static org.opentripplanner.framework.time.TimeUtils.hm2time; +import static org.opentripplanner.utils.time.DurationUtils.durationInSeconds; +import static org.opentripplanner.utils.time.TimeUtils.hm2time; import org.opentripplanner.raptor.spi.DefaultSlackProvider; import org.opentripplanner.raptor.spi.RaptorSlackProvider; diff --git a/src/test/java/org/opentripplanner/raptor/_data/api/PathUtils.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/api/PathUtils.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/_data/api/PathUtils.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/api/PathUtils.java diff --git a/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilder.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilder.java similarity index 98% rename from src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilder.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilder.java index 007018ca6c4..3c59c8543dd 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilder.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilder.java @@ -9,8 +9,8 @@ import org.opentripplanner.raptor._data.transit.TestTripPattern; import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.path.RaptorPath; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.path.PathBuilder; import org.opentripplanner.raptor.spi.DefaultSlackProvider; import org.opentripplanner.raptor.spi.RaptorCostCalculator; diff --git a/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilderTestRaptor.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilderTestRaptor.java similarity index 91% rename from src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilderTestRaptor.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilderTestRaptor.java index de40c29d583..e5a48ecd289 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilderTestRaptor.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilderTestRaptor.java @@ -2,13 +2,12 @@ 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; import static org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase.C1_CALCULATOR; import static org.opentripplanner.raptor._data.transit.TestAccessEgress.walk; +import static org.opentripplanner.raptor.api.model.RaptorTransferConstraint.REGULAR_TRANSFER; +import static org.opentripplanner.utils.time.DurationUtils.durationInSeconds; +import static org.opentripplanner.utils.time.TimeUtils.time; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.opentripplanner.raptor._data.RaptorTestConstants; import org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase; diff --git a/src/test/java/org/opentripplanner/raptor/_data/api/TestRaptorPath.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/api/TestRaptorPath.java similarity index 97% rename from src/test/java/org/opentripplanner/raptor/_data/api/TestRaptorPath.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/api/TestRaptorPath.java index dab47a6d18b..b1cd2c4d411 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/api/TestRaptorPath.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/api/TestRaptorPath.java @@ -4,12 +4,12 @@ import java.util.stream.Stream; import javax.annotation.Nullable; import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.AccessPathLeg; import org.opentripplanner.raptor.api.path.EgressPathLeg; import org.opentripplanner.raptor.api.path.PathLeg; import org.opentripplanner.raptor.api.path.RaptorPath; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.api.path.TransitPathLeg; /** diff --git a/src/test/java/org/opentripplanner/raptor/_data/multicriteria/ride/TestPatterRideBuilder.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/multicriteria/ride/TestPatterRideBuilder.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/_data/multicriteria/ride/TestPatterRideBuilder.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/multicriteria/ride/TestPatterRideBuilder.java diff --git a/src/test/java/org/opentripplanner/raptor/_data/stoparrival/AbstractStopArrival.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/AbstractStopArrival.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/_data/stoparrival/AbstractStopArrival.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/AbstractStopArrival.java diff --git a/src/test/java/org/opentripplanner/raptor/_data/stoparrival/Access.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/Access.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/_data/stoparrival/Access.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/Access.java diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/AccessAndEgressWithOpeningHoursPathTestCase.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/AccessAndEgressWithOpeningHoursPathTestCase.java new file mode 100644 index 00000000000..89e13aa58ec --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/AccessAndEgressWithOpeningHoursPathTestCase.java @@ -0,0 +1,381 @@ +package org.opentripplanner.raptor._data.stoparrival; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.raptor._data.stoparrival.TestArrivals.access; +import static org.opentripplanner.raptor._data.stoparrival.TestArrivals.bus; +import static org.opentripplanner.raptor.api.model.RaptorCostConverter.toRaptorCost; +import static org.opentripplanner.raptor.api.model.RaptorValueFormatter.formatC1; +import static org.opentripplanner.utils.time.DurationUtils.durationInSeconds; +import static org.opentripplanner.utils.time.TimeUtils.time; + +import org.junit.jupiter.api.Test; +import org.opentripplanner.raptor._data.RaptorTestConstants; +import org.opentripplanner.raptor._data.transit.TestAccessEgress; +import org.opentripplanner.raptor._data.transit.TestCostCalculator; +import org.opentripplanner.raptor._data.transit.TestTransfer; +import org.opentripplanner.raptor._data.transit.TestTripPattern; +import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.raptor.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; +import org.opentripplanner.raptor.api.model.RaptorTransfer; +import org.opentripplanner.raptor.api.view.ArrivalView; +import org.opentripplanner.raptor.rangeraptor.path.DestinationArrival; +import org.opentripplanner.raptor.spi.DefaultSlackProvider; +import org.opentripplanner.raptor.spi.RaptorSlackProvider; +import org.opentripplanner.utils.time.TimeUtils; + +/** + * This test case construct two Raptor paths for forward and reverse search, with and without + * opening hours for the flex access and egress. + *

    + * Case A with flex access and egress and one transit: + *

      + *
    1. Flex access
    2. + *
    3. Transit, BUS A
    4. + *
    5. Flex egress
    6. + *
    + *

    + * Case B with walking between transit and flex: + *

      + *
    1. Flex access
    2. + *
    3. Walk transfer
    4. + *
    5. Transit. BUS B
    6. + *
    7. Walk transfer
    8. + *
    9. Flex egress
    10. + *
    + */ +public class AccessAndEgressWithOpeningHoursPathTestCase implements RaptorTestConstants { + + private static final int ZERO = 0; + // The transit reluctance is ignored, any value should work + private static final int TRANSIT_RELUCTANCE_INDEX = -1; + public static final double WAIT_RELUCTANCE = 0.8; + public static final int BOARD_C1_SEC = 60; + public static final int TRANSFER_C1_SEC = 120; + // The C1_CALCULATOR is not under test, so we use it to calculate correct cost values. + public static final TestCostCalculator C1_CALCULATOR = new TestCostCalculator( + BOARD_C1_SEC, + TRANSFER_C1_SEC, + WAIT_RELUCTANCE, + null + ); + + public static final RaptorSlackProvider SLACK_PROVIDER = new DefaultSlackProvider( + TRANSFER_SLACK, + BOARD_SLACK, + ALIGHT_SLACK + ); + + // FLEX Access 5m tx 1 ~ A. Note! The actual times might get time-shifted. + public static final int ACCESS_DURATION = durationInSeconds("5m15s"); + public static final int ACCESS_C1 = toRaptorCost(600); + // Using transfer reluctance is incorrect, we should use the cost from the access path + public static final TestAccessEgress ACCESS = TestAccessEgress.flex( + STOP_A, + ACCESS_DURATION, + ONE_RIDE, + ACCESS_C1 + ); + // Alternative Flex access with restricted opening hours: 09:00 - 09:50 + public static final int ACCESS_OPEN = time("09:00"); + public static final int ACCESS_CLOSE = time("09:50"); + public static final TestAccessEgress ACCESS_W_OPENING_HOURS = ACCESS.openingHours( + ACCESS_OPEN, + ACCESS_CLOSE + ); + + // Transfers (A ~ Walk 1m ~ B) (Used in Case B only) + public static final int TX1_START = time("10:05:15"); + public static final int TX1_END = time("10:06:15"); + public static final int TX1_DURATION = TX1_END - TX1_START; + public static final RaptorTransfer TX1_TRANSFER = TestTransfer.transfer(STOP_B, TX1_DURATION); + public static final RaptorTransfer TX1_TRANSFER_REV = TestTransfer.transfer(STOP_A, TX1_DURATION); + public static final int TX1_C1 = TX1_TRANSFER.c1(); + + // Trip A (B ~ BUS L11 10:08 10:20 ~ C) + public static final int L1_START = time("10:08"); + public static final int L1_END = time("10:20"); + // The departure time with transfer_slack excluded + public static final int L1_STOP_ARR_TIME = L1_END + ALIGHT_SLACK; + public static final int L1_STOP_ARR_TIME_REV = L1_START - BOARD_SLACK; + + // Wait at least 1m45s (45s BOARD_SLACK and 60s TRANSFER_SLACK) + public static final int L1_TRANSIT_DURATION = L1_END - L1_START; + + // Transfers (C ~ Walk 2m ~ D) (Used in Case B only) + public static final int TX2_START = time("10:20:15"); + public static final int TX2_END = time("10:22:15"); + public static final int TX2_DURATION = TX2_END - TX2_START; + public static final RaptorTransfer TX2_TRANSFER = TestTransfer.transfer(STOP_D, TX2_DURATION); + public static final RaptorTransfer TX2_TRANSFER_REV = TestTransfer.transfer(STOP_C, TX2_DURATION); + public static final int TX2_C1 = TX2_TRANSFER.c1(); + + // Wait 15s (ALIGHT_SLACK) + // D ~ FLEX Egress 6m tx 1 . Note! The actual times might get time-shifted. + public static final int EGRESS_DURATION = durationInSeconds("6m"); + public static final int EGRESS_C1 = toRaptorCost(800); + // Using transfer reluctance is incorrect, we should use the cost from the egress path + public static final TestAccessEgress EGRESS = TestAccessEgress.flex( + STOP_D, + EGRESS_DURATION, + ONE_RIDE, + EGRESS_C1 + ); + public static final int EGRESS_OPENING = TimeUtils.time("10:30"); + public static final int EGRESS_CLOSING = TimeUtils.time("11:00"); + public static final TestAccessEgress EGRESS_W_OPENING_HOURS = EGRESS.openingHours( + EGRESS_OPENING, + EGRESS_CLOSING + ); + + public static final int EGRESS_C1_W_1M_SLACK = + EGRESS_C1 + toRaptorCost(TRANSFER_C1_SEC) + C1_CALCULATOR.waitCost(TRANSFER_SLACK); + public static final int EGRESS_C1_W_7M45S_SLACK = + EGRESS_C1_W_1M_SLACK + C1_CALCULATOR.waitCost(durationInSeconds("6m45s")); + public static final int EGRESS_C1_W_9M45S_SLACK = + EGRESS_C1_W_1M_SLACK + C1_CALCULATOR.waitCost(durationInSeconds("8m45s")); + + public static final String LINE_A = "A"; + public static final String LINE_B = "B"; + + public static final TestTripSchedule TRIP_A = TestTripSchedule + .schedule(TestTripPattern.pattern(LINE_A, STOP_A, STOP_D)) + .times(L1_START, L1_END) + .build(); + + public static final TestTripSchedule TRIP_B = TestTripSchedule + .schedule(TestTripPattern.pattern(LINE_B, STOP_B, STOP_C)) + .times(L1_START, L1_END) + .build(); + + public static final int L1_C1_EX_WAIT = C1_CALCULATOR.transitArrivalCost( + C1_CALCULATOR.boardingCostRegularTransfer(false, L1_START, STOP_B, L1_START), + ZERO, + L1_TRANSIT_DURATION, + TRIP_A, + STOP_C + ); + + private static final int TOT_C1_A = toRaptorCost(2564); + private static final int TOT_C1_W_OPENING_HOURS_A = toRaptorCost(3512); + private static final int TOT_C1_B = toRaptorCost(2924); + private static final int TOT_C1_W_OPENING_HOURS_B = toRaptorCost(3728); + // Wait before 12m45s + ALIGHT SLACK 15s + private static final int L1_C1_INC_WAIT_W_OPENING_HOURS_A = + L1_C1_EX_WAIT + C1_CALCULATOR.waitCost(durationInSeconds("13m")); + private static final int L1_C1_INC_WAIT_W_OPENING_HOURS_B = + L1_C1_EX_WAIT + C1_CALCULATOR.waitCost(durationInSeconds("12m")); + + /* TEST CASES WITH EXPECTED TO-STRING TEXTS */ + + public static DestinationArrival flexCaseAForwardSearch() { + return flexForwardSearch(ACCESS, EGRESS, LINE_A); + } + + public static String flexCaseAText() { + return String.format( + "Flex 5m15s 1x 10:01 10:06:15 %s ~ A 1m45s ~ " + + "BUS A 10:08 10:20 12m C₁996 ~ D 1m15s ~ " + + "Flex 6m 1x 10:21:15 10:27:15 %s " + + "[10:01 10:27:15 26m15s Tₓ2 %s]", + RaptorCostConverter.toString(ACCESS_C1), + RaptorCostConverter.toString(EGRESS_C1_W_1M_SLACK), + RaptorCostConverter.toString(TOT_C1_A) + ); + } + + public static DestinationArrival flexCaseBForwardSearch() { + return flexForwardSearch(ACCESS, EGRESS, LINE_B); + } + + public static String flexCaseBText() { + return String.format( + "Flex 5m15s 1x 10:00 10:05:15 %s ~ A 0s ~ " + + "Walk 1m 10:05:15 10:06:15 C₁120 ~ B 1m45s ~ " + + "BUS B 10:08 10:20 12m C₁996 ~ C 15s ~ " + + "Walk 2m 10:20:15 10:22:15 C₁240 ~ D 1m ~ " + + "Flex 6m 1x 10:23:15 10:29:15 %s" + + " [10:00 10:29:15 29m15s Tₓ2 %s]", + RaptorCostConverter.toString(ACCESS_C1), + RaptorCostConverter.toString(EGRESS_C1_W_1M_SLACK), + RaptorCostConverter.toString(TOT_C1_B) + ); + } + + public static DestinationArrival flexCaseAWithOpeningHoursForwardSearch() { + return flexForwardSearch(ACCESS_W_OPENING_HOURS, EGRESS_W_OPENING_HOURS, LINE_A); + } + + public static String flexCaseAWithOpeningHoursText() { + return String.format( + "Flex 5m15s 1x Open(9:00 9:50) 9:50 9:55:15 %s ~ A 12m45s ~ " + + "BUS A 10:08 10:20 12m %s ~ D 10m ~ " + + "Flex 6m 1x Open(10:30 11:00) 10:30 10:36 %s " + + "[9:50 10:36 46m Tₓ2 %s]", + formatC1(ACCESS_C1), + formatC1(L1_C1_INC_WAIT_W_OPENING_HOURS_A), + formatC1(EGRESS_C1_W_9M45S_SLACK), + formatC1(TOT_C1_W_OPENING_HOURS_A) + ); + } + + public static DestinationArrival flexCaseBWithOpeningHoursForwardSearch() { + return flexForwardSearch(ACCESS_W_OPENING_HOURS, EGRESS_W_OPENING_HOURS, LINE_B); + } + + public static String flexCaseBWithOpeningHoursText() { + return String.format( + "Flex 5m15s 1x Open(9:00 9:50) 9:50 9:55:15 %s ~ A 0s ~ " + + "Walk 1m 9:55:15 9:56:15 C₁120 ~ B 11m45s ~ " + + "BUS B 10:08 10:20 12m %s ~ C 15s ~ " + + "Walk 2m 10:20:15 10:22:15 C₁240 ~ D 7m45s ~ " + + "Flex 6m 1x Open(10:30 11:00) 10:30 10:36 %s" + + " [9:50 10:36 46m Tₓ2 %s]", + formatC1(ACCESS_C1), + formatC1(L1_C1_INC_WAIT_W_OPENING_HOURS_B), + formatC1(EGRESS_C1_W_7M45S_SLACK), + formatC1(TOT_C1_W_OPENING_HOURS_B) + ); + } + + public static DestinationArrival flexCaseAReverseSearch() { + return flexReverseSearch(ACCESS, EGRESS, LINE_A); + } + + public static DestinationArrival flexCaseBReverseSearch() { + return flexReverseSearch(ACCESS, EGRESS, LINE_B); + } + + public static DestinationArrival flexCaseAWithOpeningHoursReverseSearch() { + return flexReverseSearch(ACCESS_W_OPENING_HOURS, EGRESS_W_OPENING_HOURS, LINE_A); + } + + public static DestinationArrival flexCaseBWithOpeningHoursReverseSearch() { + return flexReverseSearch(ACCESS_W_OPENING_HOURS, EGRESS_W_OPENING_HOURS, LINE_B); + } + + @Test + public void testSetup() { + // Assert test data is configured correct + + // Assert all durations + assertEquals(TX1_END - TX1_START, TX1_DURATION); + assertEquals(L1_END - L1_START, L1_TRANSIT_DURATION); + assertEquals(TX2_END - TX2_START, TX2_DURATION); + + // Asset proper wait times + int txBoardSlack = TRANSFER_SLACK + BOARD_SLACK; + assertEquals(TX1_END + txBoardSlack, L1_START); + assertEquals(L1_END + ALIGHT_SLACK, TX2_START); + + // Assert cost + // The calculator is not under test here, so we assert everything is as expected + assertEquals(12000, TX1_C1); + assertEquals(90000, L1_C1_EX_WAIT); + assertEquals(24000, TX2_C1); + } + + /* PRIVATE METHODS */ + + private static DestinationArrival flexForwardSearch( + RaptorAccessEgress accessPath, + RaptorAccessEgress egressPath, + String line + ) { + int departureTime, arrivalTime, waitTime; + ArrivalView prevArrival; + + if (LINE_A.equals(line)) { + // The latest time the access can arrive is the same as the TX1 arrival time in case B + arrivalTime = accessPath.latestArrivalTime(TX1_END); + prevArrival = access(accessPath.stop(), arrivalTime, accessPath); + + int waitCost = costL1ForwardIncWait(prevArrival.arrivalTime()); + prevArrival = bus(2, STOP_D, L1_STOP_ARR_TIME, waitCost, 0, TRIP_A, prevArrival); + } else { + arrivalTime = accessPath.latestArrivalTime(TX1_START); + prevArrival = access(accessPath.stop(), arrivalTime, accessPath); + int timeShift = TX1_START - prevArrival.arrivalTime(); + + prevArrival = new Transfer(1, TX1_END - timeShift, TX1_TRANSFER, prevArrival); + + int waitCost = costL1ForwardIncWait(prevArrival.arrivalTime()); + prevArrival = bus(2, STOP_C, L1_STOP_ARR_TIME, waitCost, 0, TRIP_B, prevArrival); + + prevArrival = new Transfer(2, TX2_END, TX2_TRANSFER, prevArrival); + } + + // Egress + departureTime = prevArrival.arrivalTime() + TRANSFER_SLACK; + // Time-shift departure time + departureTime = egressPath.earliestDepartureTime(departureTime); + arrivalTime = departureTime + egressPath.durationInSeconds(); + waitTime = departureTime - prevArrival.arrivalTime(); + int additionalCost = + egressPath.c1() + toRaptorCost(waitTime * WAIT_RELUCTANCE + TRANSFER_C1_SEC); + + return new DestinationArrival<>( + egressPath, + prevArrival, + arrivalTime, + additionalCost, + RaptorConstants.NOT_SET + ); + } + + private static DestinationArrival flexReverseSearch( + RaptorAccessEgress accessPath, + RaptorAccessEgress egressPath, + String line + ) { + int departureTime, arrivalTime, cost; + ArrivalView prevArrival; + + if (LINE_A.equals(line)) { + arrivalTime = L1_END + ALIGHT_SLACK + TRANSFER_SLACK; + arrivalTime = egressPath.earliestDepartureTime(arrivalTime); + prevArrival = access(egressPath.stop(), arrivalTime, egressPath); + + cost = costL1ReverseIncWait(prevArrival.arrivalTime()); + prevArrival = bus(2, STOP_A, L1_STOP_ARR_TIME_REV, cost, 0, TRIP_A, prevArrival); + } else { + arrivalTime = L1_END + ALIGHT_SLACK + TX2_DURATION + TRANSFER_SLACK; + arrivalTime = egressPath.earliestDepartureTime(arrivalTime); + prevArrival = access(egressPath.stop(), arrivalTime, egressPath); + arrivalTime = prevArrival.arrivalTime() - TX2_DURATION; + prevArrival = new Transfer(1, arrivalTime, TX2_TRANSFER_REV, prevArrival); + cost = costL1ReverseIncWait(prevArrival.arrivalTime()); + prevArrival = bus(2, STOP_B, L1_STOP_ARR_TIME_REV, cost, 0, TRIP_B, prevArrival); + arrivalTime = prevArrival.arrivalTime() - TX1_DURATION; + prevArrival = new Transfer(2, arrivalTime, TX1_TRANSFER_REV, prevArrival); + } + + // Access + departureTime = prevArrival.arrivalTime() - TRANSFER_SLACK; + // Time-shift departure time + departureTime = accessPath.latestArrivalTime(departureTime); + arrivalTime = departureTime - accessPath.durationInSeconds(); + int waitTime = prevArrival.arrivalTime() - departureTime; + int additionalCost = + accessPath.c1() + toRaptorCost(waitTime * WAIT_RELUCTANCE + TRANSFER_C1_SEC); + + return new DestinationArrival<>( + accessPath, + prevArrival, + arrivalTime, + additionalCost, + RaptorConstants.NOT_SET + ); + } + + private static int costL1ForwardIncWait(int prevArrivalTime) { + int waitTime = L1_START - prevArrivalTime + ALIGHT_SLACK; + return toRaptorCost(waitTime * WAIT_RELUCTANCE) + L1_C1_EX_WAIT; + } + + private static int costL1ReverseIncWait(int prevArrivalTime) { + int waitTime = (prevArrivalTime - L1_END) + BOARD_SLACK; + return toRaptorCost(waitTime * WAIT_RELUCTANCE) + L1_C1_EX_WAIT; + } +} diff --git a/src/test/java/org/opentripplanner/raptor/_data/stoparrival/BasicPathTestCase.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/BasicPathTestCase.java similarity index 95% rename from src/test/java/org/opentripplanner/raptor/_data/stoparrival/BasicPathTestCase.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/BasicPathTestCase.java index 4a92264e87c..5163140e40f 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/stoparrival/BasicPathTestCase.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/BasicPathTestCase.java @@ -1,22 +1,23 @@ package org.opentripplanner.raptor._data.stoparrival; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.time.DurationUtils.durationToStr; -import static org.opentripplanner.framework.time.TimeUtils.time; -import static org.opentripplanner.model.transfer.TransferConstraint.REGULAR_TRANSFER; import static org.opentripplanner.raptor._data.stoparrival.TestArrivals.access; import static org.opentripplanner.raptor._data.stoparrival.TestArrivals.bus; import static org.opentripplanner.raptor._data.stoparrival.TestArrivals.egress; import static org.opentripplanner.raptor._data.stoparrival.TestArrivals.transfer; import static org.opentripplanner.raptor._data.transit.TestAccessEgress.flexWithOnBoard; import static org.opentripplanner.raptor._data.transit.TestTripPattern.pattern; -import static org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter.toRaptorCost; +import static org.opentripplanner.raptor.api.model.RaptorCostConverter.toRaptorCost; +import static org.opentripplanner.raptor.api.model.RaptorTransferConstraint.REGULAR_TRANSFER; +import static org.opentripplanner.utils.time.DurationUtils.durationToStr; +import static org.opentripplanner.utils.time.TimeUtils.time; import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner.raptor._data.RaptorTestConstants; import org.opentripplanner.raptor._data.transit.TestAccessEgress; +import org.opentripplanner.raptor._data.transit.TestCostCalculator; import org.opentripplanner.raptor._data.transit.TestTransfer; import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; @@ -34,7 +35,6 @@ import org.opentripplanner.raptor.rangeraptor.lifecycle.LifeCycleSubscriptions; import org.opentripplanner.raptor.rangeraptor.path.DestinationArrival; import org.opentripplanner.raptor.spi.RaptorCostCalculator; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.DefaultCostCalculator; /** * This class is used to create a journeys with stop arrivals. @@ -96,7 +96,7 @@ public class BasicPathTestCase implements RaptorTestConstants { /** Stop cost for stop NA, A, C, E .. H is zero(0), B: 30s, and D: 60s. ?=0, A=1 .. H=8 */ private static final int[] STOP_C1S = { 0, 0, 3_000, 0, 6_000, 0, 0, 0, 0, 0 }; - // Some times which should not have eny effect on tests + // These times should not have eny effect on tests private static final int VERY_EARLY = time("00:00"); private static final int VERY_LATE = time("23:59"); @@ -195,13 +195,11 @@ public class BasicPathTestCase implements RaptorTestConstants { public static final TestTripSchedule TRIP_1 = TestTripSchedule .schedule(pattern(LINE_11, STOP_A, STOP_B)) .times(L11_START, L11_END) - .transitReluctanceIndex(TRANSIT_RELUCTANCE_INDEX) .build(); public static final TestTripSchedule TRIP_2 = TestTripSchedule .schedule(pattern(LINE_21, STOP_C, STOP_D)) .times(L21_START, L21_END) - .transitReluctanceIndex(TRANSIT_RELUCTANCE_INDEX) .build(); public static final TestTripSchedule TRIP_3 = TestTripSchedule @@ -209,14 +207,12 @@ public class BasicPathTestCase implements RaptorTestConstants { // The early arrival and late departure should not have any effect on tests .arrivals(VERY_EARLY, L31_END) .departures(L31_START, VERY_LATE) - .transitReluctanceIndex(TRANSIT_RELUCTANCE_INDEX) .build(); - public static final RaptorCostCalculator C1_CALCULATOR = new DefaultCostCalculator<>( + public static final RaptorCostCalculator C1_CALCULATOR = new TestCostCalculator( BOARD_C1_SEC, TRANSFER_C1_SEC, WAIT_RELUCTANCE, - TRANSIT_RELUCTANCE, STOP_C1S ); diff --git a/src/test/java/org/opentripplanner/raptor/_data/stoparrival/Egress.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/Egress.java similarity index 95% rename from src/test/java/org/opentripplanner/raptor/_data/stoparrival/Egress.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/Egress.java index a244acdf720..302de528d9f 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/stoparrival/Egress.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/Egress.java @@ -1,11 +1,11 @@ package org.opentripplanner.raptor._data.stoparrival; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.model.PathLegType; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.view.ArrivalView; import org.opentripplanner.raptor.api.view.EgressPathView; +import org.opentripplanner.utils.time.TimeUtils; public class Egress extends AbstractStopArrival { diff --git a/src/test/java/org/opentripplanner/raptor/_data/stoparrival/TestArrivals.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/TestArrivals.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/_data/stoparrival/TestArrivals.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/TestArrivals.java diff --git a/src/test/java/org/opentripplanner/raptor/_data/stoparrival/Transfer.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/Transfer.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/_data/stoparrival/Transfer.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/Transfer.java diff --git a/src/test/java/org/opentripplanner/raptor/_data/stoparrival/Transit.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/Transit.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/_data/stoparrival/Transit.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/stoparrival/Transit.java diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/BoardAlightRestrictions.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/BoardAlightRestrictions.java new file mode 100644 index 00000000000..b18082f71ca --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/BoardAlightRestrictions.java @@ -0,0 +1,98 @@ +package org.opentripplanner.raptor._data.transit; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + +public class BoardAlightRestrictions { + + private static final EnumSet BOARDING_ONLY = EnumSet.of( + BoardAlightRestriction.BOARDING + ); + private static final EnumSet ALIGHTING_ONLY = EnumSet.of( + BoardAlightRestriction.ALIGHTING + ); + private static final EnumSet ALL_ALLOWED = EnumSet.allOf( + BoardAlightRestriction.class + ); + private static final EnumSet NONE_ALLOWED = EnumSet.noneOf( + BoardAlightRestriction.class + ); + + private final List> restrictions; + + private BoardAlightRestrictions(List> restrictions) { + if (restrictions.isEmpty()) { + throw new IllegalArgumentException("At least one stop is required."); + } + this.restrictions = restrictions; + } + + public static BoardAlightRestrictions noRestriction(int size) { + var list = new ArrayList>(size); + for (int i = 0; i < size; i++) { + list.add(ALL_ALLOWED); + } + return new BoardAlightRestrictions(List.copyOf(list)); + } + + /** + * Set alight and board restriction using a "coded" string, use space as a separator + * between stops. + *
    +   * Codes:
    +   *   b : Board
    +   *   a : Alight
    +   *   * : Board & Alight
    +   *   - : Boarding & Alighting is not allowed
    +   *
    +   * Example:   B BA * A
    +   * 
    + */ + public static BoardAlightRestrictions restrictions(String restrictions) { + var codes = restrictions.toLowerCase().trim().split("\\s"); + var list = new ArrayList>(); + for (String code : codes) { + if ("a".equals(code)) { + list.add(ALIGHTING_ONLY); + } else if ("b".equals(code)) { + list.add(BOARDING_ONLY); + } else if (code.matches("ab|ba|\\*")) { + list.add(ALL_ALLOWED); + } else if ("-".equals(code)) { + list.add(NONE_ALLOWED); + } + } + return new BoardAlightRestrictions(list); + } + + public boolean isBoardingPossibleAt(int stopPositionInPattern) { + return restrictions.get(stopPositionInPattern).contains(BoardAlightRestriction.BOARDING); + } + + public boolean isAlightingPossibleAt(int stopPositionInPattern) { + return restrictions.get(stopPositionInPattern).contains(BoardAlightRestriction.ALIGHTING); + } + + @Override + public String toString() { + var buf = new StringBuilder(); + for (int i = 0; i < restrictions.size(); ++i) { + if (isAlightingPossibleAt(i) && isBoardingPossibleAt(i)) { + buf.append(" *"); + } else if (isAlightingPossibleAt(i)) { + buf.append(" A"); + } else if (isBoardingPossibleAt(i)) { + buf.append(" B"); + } else { + buf.append(" Ø"); + } + } + return buf.substring(1); + } + + private enum BoardAlightRestriction { + BOARDING, + ALIGHTING, + } +} diff --git a/src/test/java/org/opentripplanner/raptor/_data/transit/TestAccessEgress.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestAccessEgress.java similarity index 98% rename from src/test/java/org/opentripplanner/raptor/_data/transit/TestAccessEgress.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestAccessEgress.java index 8047ec0d4cb..4714c92939c 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/transit/TestAccessEgress.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestAccessEgress.java @@ -4,14 +4,14 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.raptor._data.RaptorTestConstants.SECONDS_IN_A_DAY; -import static org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter.toRaptorCost; +import static org.opentripplanner.raptor.api.model.RaptorCostConverter.toRaptorCost; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.utils.time.TimeUtils; /** * Simple implementation for {@link RaptorAccessEgress} for use in unit-tests. diff --git a/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedBoardingSearch.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedBoardingSearch.java similarity index 93% rename from src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedBoardingSearch.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedBoardingSearch.java index 7812b9d2fce..2b0e09bd397 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedBoardingSearch.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedBoardingSearch.java @@ -9,11 +9,10 @@ import java.util.function.BiPredicate; import java.util.stream.Collectors; import javax.annotation.Nullable; -import org.opentripplanner.framework.tostring.ToStringBuilder; -import org.opentripplanner.model.transfer.TransferConstraint; import org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent; import org.opentripplanner.raptor.spi.RaptorConstrainedBoardingSearch; import org.opentripplanner.raptor.spi.RaptorTimeTable; +import org.opentripplanner.utils.tostring.ToStringBuilder; public class TestConstrainedBoardingSearch implements RaptorConstrainedBoardingSearch { @@ -55,7 +54,7 @@ public RaptorBoardOrAlightEvent find( var trip = tx.getSourceTrip(); if (trip == sourceTrip) { int stopPos = trip.findDepartureStopPosition(prevTransitArrivalTime, sourceStopIndex); - boolean boardAlightPossible = timeAfterOrEqual.test(tx.getTime(), prevTransitArrivalTime); + boolean boardAlightPossible = timeAfterOrEqual.test(tx.time(), prevTransitArrivalTime); if (tx.getSourceStopPos() == stopPos && boardAlightPossible) { return tx.boardingEvent(tx.isFacilitated() ? prevTransitArrivalTime : earliestBoardTime); } @@ -95,7 +94,7 @@ void addConstraintTransfers( int targetTripIndex, int targetStopPos, int targetTime, - TransferConstraint constraint + TestTransferConstraint constraint ) { List list = transfersByFromStopPos.get(targetStopPos); if (list == null) { diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedTransfer.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedTransfer.java new file mode 100644 index 00000000000..132d20465ac --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestConstrainedTransfer.java @@ -0,0 +1,139 @@ +package org.opentripplanner.raptor._data.transit; + +import static org.opentripplanner.raptor.api.model.RaptorConstants.NOT_SET; + +import java.util.function.Consumer; +import javax.annotation.Nullable; +import org.opentripplanner.raptor.api.model.RaptorConstrainedTransfer; +import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; +import org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent; +import org.opentripplanner.utils.tostring.ToStringBuilder; + +class TestConstrainedTransfer + implements RaptorConstrainedTransfer, RaptorBoardOrAlightEvent { + + private final TestTransferConstraint transferConstraint; + private final TestTripSchedule sourceTrip; + private final int sourceStopPos; + private final TestTripSchedule targetTrip; + private final int targetStopPos; + private final int targetTripIndex; + private final int targetTime; + + private int earliestBoardTime = NOT_SET; + + TestConstrainedTransfer( + TestTransferConstraint transferConstraint, + TestTripSchedule sourceTrip, + int sourceStopPos, + TestTripSchedule targetTrip, + int targetStopPos, + int targetTripIndex, + int targetTime + ) { + this.transferConstraint = transferConstraint; + this.sourceTrip = sourceTrip; + this.sourceStopPos = sourceStopPos; + this.targetTrip = targetTrip; + this.targetTripIndex = targetTripIndex; + this.targetStopPos = targetStopPos; + this.targetTime = targetTime; + } + + @Override + public int tripIndex() { + return targetTripIndex; + } + + @Override + public TestTripSchedule trip() { + return targetTrip; + } + + @Override + public int stopPositionInPattern() { + return targetStopPos; + } + + @Override + public int time() { + return targetTime; + } + + @Override + public int earliestBoardTime() { + return earliestBoardTime; + } + + @Override + public RaptorTransferConstraint transferConstraint() { + return transferConstraint; + } + + @Override + public boolean empty() { + return false; + } + + @Override + public void boardWithFallback( + Consumer> boardCallback, + Consumer> alternativeBoardingFallback + ) { + if (empty()) { + alternativeBoardingFallback.accept(this); + } else if (!transferConstraint.isNotAllowed()) { + boardCallback.accept(this); + } + } + + public boolean isFacilitated() { + return transferConstraint.isStaySeated() || transferConstraint.isGuaranteed(); + } + + @Nullable + @Override + public RaptorTransferConstraint getTransferConstraint() { + return transferConstraint; + } + + TestTripSchedule getSourceTrip() { + return sourceTrip; + } + + int getSourceStopPos() { + return sourceStopPos; + } + + RaptorBoardOrAlightEvent boardingEvent(int earliestBoardingTime) { + this.earliestBoardTime = earliestBoardingTime; + return this; + } + + public boolean match( + TestTripSchedule sourceTrip, + int sourceStopPos, + TestTripSchedule targetTrip, + int targetStopPos + ) { + return ( + this.sourceTrip.equals(sourceTrip) && + this.sourceStopPos == sourceStopPos && + this.targetTrip.equals(targetTrip) && + this.targetStopPos == targetStopPos + ); + } + + @Override + public String toString() { + return ToStringBuilder + .of(TestConstrainedTransfer.class) + .addObj("sourceTrip", sourceTrip) + .addNum("sourceStopPos", sourceStopPos) + .addObj("targetTrip", targetTrip) + .addNum("targetTripIndex", targetTripIndex) + .addNum("targetStopPos", targetStopPos) + .addServiceTime("targetTime", targetTime) + .toString(); + } +} diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestCostCalculator.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestCostCalculator.java new file mode 100644 index 00000000000..ab2d4ae3476 --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestCostCalculator.java @@ -0,0 +1,199 @@ +package org.opentripplanner.raptor._data.transit; + +import javax.annotation.Nullable; +import org.opentripplanner.raptor.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; +import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; +import org.opentripplanner.raptor.spi.RaptorCostCalculator; + +/** + * The responsibility for the cost calculator is to calculate the default multi-criteria cost. + *

    + * This class is immutable and thread safe. + */ +public final class TestCostCalculator implements RaptorCostCalculator { + + private static final int TRANSIT_RELUCTANCE = RaptorCostConverter.toRaptorCost(1); + + private final int boardCost; + private final int transferCost; + private final int waitFactor; + + /** + * Costs for boarding and alighting at a given stop during transfer. + * See TransitLayer.getStopBoardAlightTransferCosts() + */ + @Nullable + private final int[] stopBoardAlightTransferCosts; + + /** + * Cost unit: SECONDS - The unit for all input parameters are in the OTP TRANSIT model cost unit + * (in Raptor the unit for cost is centi-seconds). + * + * @param stopBoardAlightTransferCosts Unit centi-seconds. This parameter is used "as-is" and not + * transformed into the Raptor cast unit to avoid the transformation for each + * request. Use {@code null} to ignore stop cost. + */ + public TestCostCalculator( + int boardCost, + int transferCost, + double waitReluctanceFactor, + @Nullable int[] stopBoardAlightTransferCosts + ) { + this.boardCost = RaptorCostConverter.toRaptorCost(boardCost); + this.transferCost = RaptorCostConverter.toRaptorCost(transferCost); + this.waitFactor = RaptorCostConverter.toRaptorCost(waitReluctanceFactor); + this.stopBoardAlightTransferCosts = stopBoardAlightTransferCosts; + } + + @Override + public int boardingCost( + boolean firstBoarding, + int prevArrivalTime, + int boardStop, + int boardTime, + TestTripSchedule trip, + RaptorTransferConstraint transferConstraints + ) { + if (transferConstraints.isRegularTransfer()) { + return boardingCostRegularTransfer(firstBoarding, prevArrivalTime, boardStop, boardTime); + } else { + return boardingCostConstrainedTransfer( + prevArrivalTime, + boardStop, + boardTime, + firstBoarding, + transferConstraints + ); + } + } + + @Override + public int onTripRelativeRidingCost(int boardTime, TestTripSchedule tripScheduledBoarded) { + // The relative-transit-time is time spent on transit. We do not know the alight-stop, so + // it is impossible to calculate the "correct" time. But the only thing that maters is that + // the relative difference between to boardings are correct, assuming riding the same trip. + // So, we can use the negative board time as relative-transit-time. + return -boardTime * TRANSIT_RELUCTANCE; + } + + @Override + public int transitArrivalCost( + int boardCost, + int alightSlack, + int transitTime, + TestTripSchedule trip, + int toStop + ) { + int cost = boardCost + TRANSIT_RELUCTANCE * transitTime + waitFactor * alightSlack; + + // Add transfer cost on all alighting events. + // If it turns out to be the last one this cost will be removed during costEgress phase. + if (stopBoardAlightTransferCosts != null) { + cost += stopBoardAlightTransferCosts[toStop]; + } + + return cost; + } + + @Override + public int waitCost(int waitTimeInSeconds) { + return waitFactor * waitTimeInSeconds; + } + + @Override + public int calculateRemainingMinCost(int minTravelTime, int minNumTransfers, int fromStop) { + if (minNumTransfers > -1) { + return ( + boardCost + + ((boardCost + transferCost) * minNumTransfers) + + (TRANSIT_RELUCTANCE * minTravelTime) + ); + } else { + // Remove cost that was added during alighting similar as we do in the costEgress() method + return stopBoardAlightTransferCosts == null + ? (TRANSIT_RELUCTANCE * minTravelTime) + : (TRANSIT_RELUCTANCE * minTravelTime) - stopBoardAlightTransferCosts[fromStop]; + } + } + + @Override + public int costEgress(RaptorAccessEgress egress) { + if (egress.hasRides()) { + return egress.c1() + transferCost; + } else if (stopBoardAlightTransferCosts != null) { + // Remove cost that was added during alighting. + // We do not want to add this cost on last alighting since it should only be applied on transfers + // It has to be done here because during alighting we do not know yet if it will be + // a transfer or not. + return egress.c1() - stopBoardAlightTransferCosts[egress.stop()]; + } else { + return egress.c1(); + } + } + + /** This is public for test purposes only */ + public int boardingCostRegularTransfer( + boolean firstBoarding, + int prevArrivalTime, + int boardStop, + int boardTime + ) { + // Calculate the wait-time before the boarding which should be accounted for in the cost + // calculation. Any slack at the end of the last leg is not part of this, because it is + // already accounted for. If the previous leg is an access leg, then it is already + // time-shifted, which is important for this calculation to be correct. + final int boardWaitTime = boardTime - prevArrivalTime; + + int cost = waitFactor * boardWaitTime; + + cost += firstBoarding ? boardCost : (boardCost + transferCost); + + // If it's first boarding event then it is not a transfer + if (stopBoardAlightTransferCosts != null && !firstBoarding) { + cost += stopBoardAlightTransferCosts[boardStop]; + } + return cost; + } + + /* private methods */ + + private int boardingCostConstrainedTransfer( + int prevArrivalTime, + int boardStop, + int boardTime, + boolean firstBoarding, + RaptorTransferConstraint txConstraints + ) { + // This cast could be avoided, if we added another generic type to the Raptor component, + // but it would be rather messy, just to avoid a single cast. + var tx = (TestTransferConstraint) txConstraints; + + if (tx.isStaySeated()) { + final int boardWaitTime = boardTime - prevArrivalTime; + // For a stay-seated transfer the wait-time is spent on-board and we should use the + // transitReluctance, not the waitReluctance, to find the cost of the time since + // the stop arrival. So we take the time and multiply it with the transit reluctance. + // + // Note! if the boarding happens BEFORE the previous stop arrival, we will get a + // negative time - this is ok, so we allow it in this calculation. + // + // The previous stop arrival might have a small alight-slack, this should be replaced + // with "on-board" time, but the slack should be short and the differance between + // transit reluctance and wait reluctance is also small, so we ignore this. + // + return TRANSIT_RELUCTANCE * boardWaitTime; + } else if (tx.isGuaranteed()) { + // For a guaranteed transfer we skip board- and transfer-cost + final int boardWaitTime = boardTime - prevArrivalTime; + + // StopBoardAlightTransferCost is NOT added to the cost here. This is because a trip-to-trip + // constrained transfer take precedence over stop-to-stop transfer priority (NeTEx station + // transfer priority). + return waitFactor * boardWaitTime; + } + + // fallback to regular transfer + return boardingCostRegularTransfer(firstBoarding, prevArrivalTime, boardStop, boardTime); + } +} diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestRoute.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestRoute.java new file mode 100644 index 00000000000..2cd87a065ea --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestRoute.java @@ -0,0 +1,144 @@ +package org.opentripplanner.raptor._data.transit; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.opentripplanner.raptor.api.model.SearchDirection; +import org.opentripplanner.raptor.spi.RaptorConstrainedBoardingSearch; +import org.opentripplanner.raptor.spi.RaptorRoute; +import org.opentripplanner.raptor.spi.RaptorTimeTable; +import org.opentripplanner.raptor.spi.RaptorTripScheduleSearch; +import org.opentripplanner.utils.tostring.ToStringBuilder; + +public class TestRoute implements RaptorRoute, RaptorTimeTable { + + private final TestTripPattern pattern; + private final List schedules = new ArrayList<>(); + private final TestConstrainedBoardingSearch transferConstraintsForwardSearch = new TestConstrainedBoardingSearch( + true + ); + private final TestConstrainedBoardingSearch transferConstraintsReverseSearch = new TestConstrainedBoardingSearch( + false + ); + + private TestRoute(TestTripPattern pattern) { + this.pattern = pattern; + } + + public static TestRoute route(TestTripPattern pattern) { + return new TestRoute(pattern); + } + + public static TestRoute route(String name, int... stopIndexes) { + return route(TestTripPattern.pattern(name, stopIndexes)); + } + + /* RaptorRoute */ + + @Override + public RaptorTimeTable timetable() { + return this; + } + + @Override + public TestTripPattern pattern() { + return pattern; + } + + public RaptorConstrainedBoardingSearch transferConstraintsForwardSearch() { + return transferConstraintsForwardSearch; + } + + public RaptorConstrainedBoardingSearch transferConstraintsReverseSearch() { + return transferConstraintsReverseSearch; + } + + /* RaptorTimeTable */ + + @Override + public TestTripSchedule getTripSchedule(int index) { + return schedules.get(index); + } + + @Override + public int numberOfTripSchedules() { + return schedules.size(); + } + + @Override + public RaptorTripScheduleSearch tripSearch(SearchDirection direction) { + return new TestTripScheduleSearch(direction, schedules); + } + + public List listTransferConstraintsForwardSearch() { + return transferConstraintsForwardSearch.constrainedBoardings(); + } + + public TestRoute withTimetable(TestTripSchedule... trips) { + Collections.addAll(schedules, trips); + return this; + } + + public TestRoute withTimetable(TestTripSchedule.Builder... scheduleBuilders) { + for (TestTripSchedule.Builder builder : scheduleBuilders) { + var tripSchedule = builder.pattern(pattern).build(); + schedules.add(tripSchedule); + } + return this; + } + + @Override + public String toString() { + return ToStringBuilder + .of(TestRoute.class) + .addObj("pattern", pattern) + .addObj("schedules", schedules) + .toString(); + } + + void clearTransferConstraints() { + transferConstraintsForwardSearch.clear(); + transferConstraintsReverseSearch.clear(); + } + + /** + * Add a transfer constraint to the route by iterating over all trips and matching the provided + * {@code toTrip}(added to forward search) {@code fromTrip}(added to reverse search) with the rips + * in the route timetable. + */ + void addTransferConstraint( + TestTripSchedule fromTrip, + int fromStopPos, + TestTripSchedule toTrip, + int toStopPos, + TestTransferConstraint constraint + ) { + for (int i = 0; i < timetable().numberOfTripSchedules(); i++) { + var trip = timetable().getTripSchedule(i); + if (toTrip == trip) { + this.transferConstraintsForwardSearch.addConstraintTransfers( + fromTrip, + fromStopPos, + trip, + i, + toStopPos, + trip.arrival(toStopPos), + constraint + ); + } + // Reverse search transfer, the {@code source/target} is the trips in order of the + // reverse search, which is opposite from {@code from/to} in the result path. + if (fromTrip == trip) { + this.transferConstraintsReverseSearch.addConstraintTransfers( + toTrip, + toStopPos, + trip, + i, + fromStopPos, + trip.departure(fromStopPos), + constraint + ); + } + } + } +} diff --git a/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransfer.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransfer.java similarity index 86% rename from src/test/java/org/opentripplanner/raptor/_data/transit/TestTransfer.java rename to raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransfer.java index 5645f6342d6..b90fd5f7c46 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransfer.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransfer.java @@ -1,6 +1,6 @@ package org.opentripplanner.raptor._data.transit; -import static org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter.toRaptorCost; +import static org.opentripplanner.raptor.api.model.RaptorCostConverter.toRaptorCost; import org.opentripplanner.raptor.api.model.RaptorTransfer; @@ -18,6 +18,10 @@ public static TestTransfer transfer(int stop, int durationInSeconds, int cost) { return new TestTransfer(stop, durationInSeconds, cost); } + public TestTransfer reverse(int stop) { + return new TestTransfer(stop, durationInSeconds, cost); + } + public static int walkCost(int durationInSeconds) { return walkCost(durationInSeconds, DEFAULT_WALK_RELUCTANCE); } diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransferConstraint.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransferConstraint.java new file mode 100644 index 00000000000..c630c6a8bbb --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransferConstraint.java @@ -0,0 +1,84 @@ +package org.opentripplanner.raptor._data.transit; + +import java.io.Serializable; +import java.util.Objects; +import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; + +/** + * This class holds transfer constraint information. + *

    + * The class is immutable. + */ +public class TestTransferConstraint implements Serializable, RaptorTransferConstraint { + + private enum Type { + NOT_ALLOWED, + STAY_SEATED, + GUARANTEED; + + boolean is(Type type) { + return this == type; + } + } + + private final Type type; + + public TestTransferConstraint(Type type) { + this.type = type; + } + + public static TestTransferConstraint notAllowed() { + return new TestTransferConstraint(Type.NOT_ALLOWED); + } + + public static TestTransferConstraint staySeated() { + return new TestTransferConstraint(Type.STAY_SEATED); + } + + public static TestTransferConstraint guaranteed() { + return new TestTransferConstraint(Type.GUARANTEED); + } + + public static RaptorTransferConstraint regular() { + return RaptorTransferConstraint.REGULAR_TRANSFER; + } + + public boolean isGuaranteed() { + return type.is(Type.GUARANTEED); + } + + @Override + public boolean isNotAllowed() { + return type.is(Type.NOT_ALLOWED); + } + + @Override + public boolean isRegularTransfer() { + return false; + } + + @Override + public boolean isStaySeated() { + return type.is(Type.STAY_SEATED); + } + + @Override + public int hashCode() { + return Objects.hash(type); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof final TestTransferConstraint that)) { + return false; + } + return type == that.type; + } + + public String toString() { + return "{" + type + "}"; + } +} diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransitData.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransitData.java new file mode 100644 index 00000000000..edd87c16b48 --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTransitData.java @@ -0,0 +1,347 @@ +package org.opentripplanner.raptor._data.transit; + +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.util.ArrayList; +import java.util.BitSet; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import javax.annotation.Nullable; +import org.opentripplanner.raptor._data.RaptorTestConstants; +import org.opentripplanner.raptor.api.model.RaptorConstrainedTransfer; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; +import org.opentripplanner.raptor.api.model.RaptorTransfer; +import org.opentripplanner.raptor.api.model.RaptorTripPattern; +import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; +import org.opentripplanner.raptor.rangeraptor.SystemErrDebugLogger; +import org.opentripplanner.raptor.spi.DefaultSlackProvider; +import org.opentripplanner.raptor.spi.IntIterator; +import org.opentripplanner.raptor.spi.RaptorConstrainedBoardingSearch; +import org.opentripplanner.raptor.spi.RaptorCostCalculator; +import org.opentripplanner.raptor.spi.RaptorPathConstrainedTransferSearch; +import org.opentripplanner.raptor.spi.RaptorRoute; +import org.opentripplanner.raptor.spi.RaptorSlackProvider; +import org.opentripplanner.raptor.spi.RaptorTimeTable; +import org.opentripplanner.raptor.spi.RaptorTransitDataProvider; +import org.opentripplanner.raptor.util.BitSetIterator; + +@SuppressWarnings("UnusedReturnValue") +public class TestTransitData + implements RaptorTransitDataProvider, RaptorTestConstants { + + public static final TestTransferConstraint TX_GUARANTEED = TestTransferConstraint.guaranteed(); + public static final TestTransferConstraint TX_NOT_ALLOWED = TestTransferConstraint.notAllowed(); + + // Slack defaults: 1 minute for transfer-slack, 0 minutes for board- and alight-slack. + public static final RaptorSlackProvider SLACK_PROVIDER = new DefaultSlackProvider(60, 0, 0); + + private final List> transfersFromStop = new ArrayList<>(); + private final List> transfersToStop = new ArrayList<>(); + private final List> routeIndexesByStopIndex = new ArrayList<>(); + private final List routes = new ArrayList<>(); + private final List constrainedTransfers = new ArrayList<>(); + private int boardCostSec = 600; + private int transferCostSec = 0; + private double waitReluctance = 1.0; + + private final int[] stopBoardAlightTransferCosts = new int[NUM_STOPS]; + + private RaptorSlackProvider slackProvider = SLACK_PROVIDER; + + @Override + public Iterator getTransfersFromStop(int fromStop) { + return transfersFromStop.get(fromStop).iterator(); + } + + @Override + public Iterator getTransfersToStop(int toStop) { + return transfersToStop.get(toStop).iterator(); + } + + @Override + public IntIterator routeIndexIterator(IntIterator stops) { + BitSet routes = new BitSet(); + while (stops.hasNext()) { + int stop = stops.next(); + for (int i : routeIndexesByStopIndex.get(stop)) { + routes.set(i); + } + } + return new BitSetIterator(routes); + } + + @Override + public RaptorRoute getRouteForIndex(int routeIndex) { + return this.routes.get(routeIndex); + } + + @Override + public int numberOfStops() { + return routeIndexesByStopIndex.size(); + } + + @Override + public RaptorCostCalculator multiCriteriaCostCalculator() { + return new TestCostCalculator( + boardCostSec, + transferCostSec, + waitReluctance, + stopBoardAlightTransferCosts() + ); + } + + @Override + public RaptorSlackProvider slackProvider() { + return slackProvider; + } + + public TestTransitData withSlackProvider(RaptorSlackProvider slackProvider) { + this.slackProvider = slackProvider; + return this; + } + + @Override + public RaptorPathConstrainedTransferSearch transferConstraintsSearch() { + return new RaptorPathConstrainedTransferSearch<>() { + @Nullable + @Override + public RaptorConstrainedTransfer findConstrainedTransfer( + TestTripSchedule fromTrip, + int fromStopPosition, + TestTripSchedule toTrip, + int toStopPosition + ) { + var list = routes + .stream() + .flatMap(r -> r.listTransferConstraintsForwardSearch().stream()) + .filter(tx -> tx.match(fromTrip, fromStopPosition, toTrip, toStopPosition)) + .toList(); + + if (list.isEmpty()) { + return null; + } + if (list.size() == 1) { + return list.get(0); + } + throw new IllegalStateException("More than on transfers found: " + list); + } + }; + } + + @Override + public RaptorStopNameResolver stopNameResolver() { + // Index is translated: 1->'A', 2->'B', 3->'C' ... + return this::stopIndexToName; + } + + @Override + public int getValidTransitDataStartTime() { + return this.routes.stream() + .mapToInt(route -> route.timetable().getTripSchedule(0).departure(0)) + .min() + .orElseThrow(); + } + + @Override + public int getValidTransitDataEndTime() { + return this.routes.stream() + .mapToInt(route -> { + RaptorTimeTable timetable = route.timetable(); + RaptorTripPattern pattern = route.pattern(); + return timetable + .getTripSchedule(timetable.numberOfTripSchedules() - 1) + .departure(pattern.numberOfStopsInPattern() - 1); + }) + .max() + .orElseThrow(); + } + + @Override + public RaptorConstrainedBoardingSearch transferConstraintsForwardSearch( + int routeIndex + ) { + return getRoute(routeIndex).transferConstraintsForwardSearch(); + } + + @Override + public RaptorConstrainedBoardingSearch transferConstraintsReverseSearch( + int routeIndex + ) { + return getRoute(routeIndex).transferConstraintsReverseSearch(); + } + + public TestRoute getRoute(int index) { + return routes.get(index); + } + + public void debugToStdErr(RaptorRequestBuilder request, boolean dryRun) { + var debug = request.debug(); + + if (debug.stops().isEmpty()) { + debug.addStops(stopsVisited()); + } + var logger = new SystemErrDebugLogger(true, dryRun); + + debug + .stopArrivalListener(logger::stopArrivalLister) + .patternRideDebugListener(logger::patternRideLister) + .pathFilteringListener(logger::pathFilteringListener) + .logger(logger); + } + + public TestTransitData withRoute(TestRoute route) { + this.routes.add(route); + int routeIndex = this.routes.indexOf(route); + var pattern = route.pattern(); + for (int i = 0; i < pattern.numberOfStopsInPattern(); ++i) { + int stopIndex = pattern.stopIndex(i); + expandNumOfStops(stopIndex); + routeIndexesByStopIndex.get(stopIndex).add(routeIndex); + } + return this; + } + + /** + * Same as: + *

    +   * withRoute(
    +   *   route(pattern(routeName, stopIndexes))
    +   *     .withTimetable(schedule().times(times))
    +   * )
    +   * 
    + */ + public TestTransitData withTransit(String routeName, String times, int... stopIndexes) { + return withRoute(route(pattern(routeName, stopIndexes)).withTimetable(schedule().times(times))); + } + + public TestTransitData withRoutes(TestRoute... routes) { + for (TestRoute route : routes) { + withRoute(route); + } + return this; + } + + public TestTransitData withTransfer(int fromStop, TestTransfer transfer) { + expandNumOfStops(Math.max(fromStop, transfer.stop())); + transfersFromStop.get(fromStop).add(transfer); + transfersToStop.get(transfer.stop()).add(transfer.reverse(fromStop)); + return this; + } + + public TestTransitData withTransferCost(int transferCostSec) { + this.transferCostSec = transferCostSec; + return this; + } + + public TestTransitData withGuaranteedTransfer( + TestTripSchedule fromTrip, + int fromStop, + TestTripSchedule toTrip, + int toStop + ) { + return withConstrainedTransfer(fromTrip, fromStop, toTrip, toStop, TX_GUARANTEED); + } + + public void clearConstrainedTransfers() { + constrainedTransfers.clear(); + for (TestRoute route : routes) { + route.clearTransferConstraints(); + } + } + + /** + * Create constraint for a given transfer. If trip passes through the stop more than once + * constraint will be placed on stop position for the first visit. + * @param fromTrip initial trip + * @param fromStop initial stop index + * @param toTrip destination trip + * @param toStop destination trip index + * @param constraint constraint to set + */ + public TestTransitData withConstrainedTransfer( + TestTripSchedule fromTrip, + int fromStop, + TestTripSchedule toTrip, + int toStop, + TestTransferConstraint constraint + ) { + int fromStopPos = fromTrip.pattern().findStopPositionAfter(0, fromStop); + int toStopPos = toTrip.pattern().findStopPositionAfter(0, toStop); + + for (TestRoute route : routes) { + route.addTransferConstraint(fromTrip, fromStopPos, toTrip, toStopPos, constraint); + } + constrainedTransfers.add( + new TestConstrainedTransfer( + constraint, + fromTrip, + fromStopPos, + toTrip, + toStopPos, + toTrip.tripSortIndex(), + toTrip.departure(toStopPos) + ) + ); + return this; + } + + public TestTransitData withStopBoardAlightTransferCost(int stop, int boardAlightTransferCost) { + stopBoardAlightTransferCosts[stop] = boardAlightTransferCost; + return this; + } + + public TestConstrainedTransfer findConstrainedTransfer( + TestTripSchedule fromTrip, + int fromStop, + int fromStopPosition, + TestTripSchedule toTrip, + int toStop, + int toStopPosition + ) { + for (var tx : constrainedTransfers) { + if (tx.match(fromTrip, fromStopPosition, toTrip, toStopPosition)) { + return tx; + } + } + return null; + } + + public TestTransitData withBoardCost(int boardCostSec) { + this.boardCostSec = boardCostSec; + return this; + } + + public TestTransitData withWaitReluctance(double waitReluctance) { + this.waitReluctance = waitReluctance; + return this; + } + + /* private methods */ + + private int[] stopBoardAlightTransferCosts() { + // Not implemented, no test for this yet. + return stopBoardAlightTransferCosts; + } + + private void expandNumOfStops(int stopIndex) { + for (int i = numberOfStops(); i <= stopIndex; ++i) { + transfersFromStop.add(new ArrayList<>()); + transfersToStop.add(new ArrayList<>()); + routeIndexesByStopIndex.add(new HashSet<>()); + } + } + + private List stopsVisited() { + final List stops = new ArrayList<>(); + for (int i = 0; i < routeIndexesByStopIndex.size(); i++) { + if (!routeIndexesByStopIndex.get(i).isEmpty()) { + stops.add(i); + } + } + return stops; + } +} diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripPattern.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripPattern.java new file mode 100644 index 00000000000..e9b6613500b --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripPattern.java @@ -0,0 +1,160 @@ +package org.opentripplanner.raptor._data.transit; + +import java.util.Objects; +import org.opentripplanner.raptor.api.model.RaptorTripPattern; +import org.opentripplanner.utils.tostring.ToStringBuilder; + +public class TestTripPattern implements RaptorTripPattern { + + private final String name; + private final int[] stopIndexes; + private final BoardAlightRestrictions restrictions; + private final int slackIndex; + private final int patternIndex; + private final int priorityGroupId; + + private TestTripPattern( + String name, + int[] stopIndexes, + BoardAlightRestrictions restrictions, + int slackIndex, + int patternIndex, + int priorityGroupId + ) { + this.name = Objects.requireNonNull(name); + this.stopIndexes = Objects.requireNonNull(stopIndexes); + this.restrictions = Objects.requireNonNull(restrictions); + this.slackIndex = slackIndex; + this.patternIndex = patternIndex; + this.priorityGroupId = priorityGroupId; + } + + public static TestTripPattern.Builder of(String name, int... stopIndexes) { + return new TestTripPattern.Builder(name, stopIndexes); + } + + public static TestTripPattern pattern(String name, int... stopIndexes) { + return of(name, stopIndexes).build(); + } + + /** Create a pattern with name 'R1' and given stop indexes */ + public static TestTripPattern pattern(int... stopIndexes) { + return pattern("R1", stopIndexes); + } + + @Override + public int stopIndex(int stopPositionInPattern) { + return stopIndexes[stopPositionInPattern]; + } + + @Override + public boolean boardingPossibleAt(int stopPositionInPattern) { + return restrictions.isBoardingPossibleAt(stopPositionInPattern); + } + + @Override + public boolean alightingPossibleAt(int stopPositionInPattern) { + return restrictions.isAlightingPossibleAt(stopPositionInPattern); + } + + @Override + public int slackIndex() { + return slackIndex; + } + + @Override + public int priorityGroupId() { + return priorityGroupId; + } + + @Override + public int patternIndex() { + return patternIndex; + } + + @Override + public int numberOfStopsInPattern() { + return stopIndexes.length; + } + + @Override + public String debugInfo() { + return "BUS " + name; + } + + @Override + public String toString() { + return ToStringBuilder + .of(TestTripPattern.class) + .addStr("name", name) + .addInts("stops", stopIndexes) + .addObj("restrictions", restrictions) + .toString(); + } + + public static class Builder { + + private final String name; + private int[] stopIndexes; + private String restrictions; + private int slackIndex = 0; + private int patternIndex = 0; + private int priorityGroupId = 0; + + public Builder(String name, int... stopIndexes) { + this.name = name; + this.stopIndexes = stopIndexes; + } + + public Builder pattern(int... stopIndexes) { + this.stopIndexes = stopIndexes; + return this; + } + + /** + * Set alight and board restriction using a "coded" string, use space as a separator + * between stops. + *
    +     * Codes:
    +     *   b : Board
    +     *   a : Alight
    +     *   * : Board & Alight
    +     *   - : Boarding & Alighting is not allowed
    +     *
    +     * Example:   B BA * A
    +     * 
    + */ + public Builder restrictions(String restrictions) { + this.restrictions = restrictions; + return this; + } + + public Builder slackIndex(int index) { + this.slackIndex = index; + return this; + } + + public Builder patternIndex(int index) { + this.patternIndex = index; + return this; + } + + public Builder priorityGroup(int priorityGroupId) { + this.priorityGroupId = priorityGroupId; + return this; + } + + public TestTripPattern build() { + return new TestTripPattern( + name, + stopIndexes, + restrictions == null + ? BoardAlightRestrictions.noRestriction(stopIndexes.length) + : BoardAlightRestrictions.restrictions(restrictions), + slackIndex, + patternIndex, + priorityGroupId + ); + } + } +} diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripSchedule.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripSchedule.java new file mode 100644 index 00000000000..cbce4a642e0 --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripSchedule.java @@ -0,0 +1,216 @@ +package org.opentripplanner.raptor._data.transit; + +import java.util.Arrays; +import java.util.stream.IntStream; +import org.opentripplanner.raptor.api.model.RaptorTripPattern; +import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.utils.lang.IntUtils; +import org.opentripplanner.utils.time.TimeUtils; +import org.opentripplanner.utils.tostring.ToStringBuilder; + +/** + * An implementation of the {@link RaptorTripSchedule} for unit-testing. + */ +public class TestTripSchedule implements RaptorTripSchedule { + + private static final int DEFAULT_DEPARTURE_DELAY = 10; + private final int[] arrivalTimes; + private final int[] departureTimes; + private final RaptorTripPattern pattern; + + protected TestTripSchedule(TestTripPattern pattern, int[] arrivalTimes, int[] departureTimes) { + this.pattern = pattern; + this.arrivalTimes = arrivalTimes; + this.departureTimes = departureTimes; + } + + public static TestTripSchedule.Builder schedule() { + return new TestTripSchedule.Builder(); + } + + public static TestTripSchedule.Builder schedule(TestTripPattern pattern) { + return schedule().pattern(pattern); + } + + public static TestTripSchedule.Builder schedule(String times) { + return new TestTripSchedule.Builder().times(times); + } + + @Override + public int tripSortIndex() { + // We sort trips based on the departure from the first stop + return arrival(0); + } + + @Override + public int arrival(int stopPosInPattern) { + return arrivalTimes[stopPosInPattern]; + } + + @Override + public int departure(int stopPosInPattern) { + return departureTimes[stopPosInPattern]; + } + + @Override + public RaptorTripPattern pattern() { + return pattern; + } + + public int size() { + return arrivalTimes.length; + } + + @Override + public String toString() { + if (Arrays.equals(arrivalTimes, departureTimes)) { + return ToStringBuilder + .of(TestTripSchedule.class) + .addServiceTimeSchedule("times", arrivalTimes) + .toString(); + } + return ToStringBuilder + .of(TestTripSchedule.class) + .addServiceTimeSchedule("arrivals", arrivalTimes) + .addServiceTimeSchedule("departures", departureTimes) + .toString(); + } + + @SuppressWarnings("UnusedReturnValue") + public static class Builder { + + private TestTripPattern pattern; + private int[] arrivalTimes; + private int[] departureTimes; + private int arrivalDepartureOffset = DEFAULT_DEPARTURE_DELAY; + + public TestTripSchedule.Builder pattern(TestTripPattern pattern) { + this.pattern = pattern; + return this; + } + + public TestTripSchedule.Builder copy() { + var b = new TestTripSchedule.Builder(); + b.pattern = pattern; + b.arrivalTimes = arrivalTimes; + b.departureTimes = departureTimes; + b.arrivalDepartureOffset = arrivalDepartureOffset; + return b; + } + + public TestTripSchedule.Builder pattern(String name, int... stops) { + return pattern(TestTripPattern.pattern(name, stops)); + } + + /** @param times departure and arrival times per stop. Example: "0:10, 0:20, 0:45 .." */ + public TestTripSchedule.Builder times(String times) { + return times(TimeUtils.times(times)); + } + + /** @param times departure and arrival times per stop in seconds past midnight. */ + public TestTripSchedule.Builder times(int... times) { + arrivals(times); + departures(times); + return this; + } + + /** @param arrivalTimes arrival times per stop. Example: "0:10, 0:20, 0:45 .. */ + public TestTripSchedule.Builder arrivals(String arrivalTimes) { + return this.arrivals(TimeUtils.times(arrivalTimes)); + } + + /** @param arrivalTimes arrival times per stop in seconds past midnight. */ + public TestTripSchedule.Builder arrivals(int... arrivalTimes) { + this.arrivalTimes = arrivalTimes; + return this; + } + + /** @param departureTimes departure times per stop. Example: "0:10, 0:20, 0:45 .. */ + public TestTripSchedule.Builder departures(String departureTimes) { + return this.departures(TimeUtils.times(departureTimes)); + } + + /** @param departureTimes departure times per stop in seconds past midnight. */ + public TestTripSchedule.Builder departures(int... departureTimes) { + this.departureTimes = departureTimes; + return this; + } + + /** + * The time between arrival and departure for each stop in the pattern. If not both arrival and + * departure times are set, this parameter is used to calculate the unset values. + *

    + * Unit: seconds. The default is 10 seconds. + */ + public TestTripSchedule.Builder arrDepOffset(int arrivalDepartureOffset) { + this.arrivalDepartureOffset = arrivalDepartureOffset; + return this; + } + + /** + * Shift all arrival/departure times by the given {@code offset}. Be careful, this + * method change the builder instance, use {@link #copy()} if you need the original. + *

    + * Offset unit is seconds. + */ + public TestTripSchedule.Builder shiftTimes(int offset) { + if (arrivalTimes == departureTimes) { + arrivalTimes = departureTimes = IntUtils.shiftArray(offset, arrivalTimes); + } else { + if (arrivalTimes != null) { + arrivalTimes = IntUtils.shiftArray(offset, arrivalTimes); + } + if (departureTimes != null) { + departureTimes = IntUtils.shiftArray(offset, departureTimes); + } + } + return this; + } + + public TestTripSchedule.Builder[] repeat(int nTimes, int everySeconds) { + return IntStream + .range(0, nTimes) + .mapToObj(i -> copy().shiftTimes(i * everySeconds)) + .toArray(Builder[]::new); + } + + public TestTripSchedule build() { + if (arrivalTimes == null) { + arrivalTimes = copyWithOffset(departureTimes, -arrivalDepartureOffset); + } else if (departureTimes == null) { + departureTimes = copyWithOffset(arrivalTimes, arrivalDepartureOffset); + } + if (arrivalTimes.length != departureTimes.length) { + throw new IllegalStateException( + "Number of arrival and departure times do not match." + + " Arrivals: " + + arrivalTimes.length + + ", departures: " + + arrivalTimes.length + ); + } + if (pattern == null) { + pattern = TestTripPattern.pattern("DummyPattern", new int[arrivalTimes.length]); + } + if (arrivalTimes.length != pattern.numberOfStopsInPattern()) { + throw new IllegalStateException( + "Number of arrival and departure times do not match stops in pattern." + + " Arrivals/departures: " + + arrivalTimes.length + + ", stops: " + + pattern.numberOfStopsInPattern() + ); + } + + return new TestTripSchedule(pattern, arrivalTimes, departureTimes); + } + + private static int[] copyWithOffset(int[] source, int offset) { + int[] target = new int[source.length]; + for (int i = 0; i < source.length; i++) { + target[i] = source[i] + offset; + } + return target; + } + } +} diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripScheduleSearch.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripScheduleSearch.java new file mode 100644 index 00000000000..7e9a73e162e --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripScheduleSearch.java @@ -0,0 +1,122 @@ +package org.opentripplanner.raptor._data.transit; + +import static org.opentripplanner.raptor.api.model.RaptorConstants.NOT_FOUND; +import static org.opentripplanner.raptor.api.model.RaptorConstants.TIME_NOT_SET; + +import java.util.List; +import org.opentripplanner.raptor.api.model.RaptorTransferConstraint; +import org.opentripplanner.raptor.api.model.SearchDirection; +import org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent; +import org.opentripplanner.raptor.spi.RaptorTripScheduleSearch; +import org.opentripplanner.utils.tostring.ToStringBuilder; + +class TestTripScheduleSearch + implements + RaptorTripScheduleSearch, RaptorBoardOrAlightEvent { + + private final List trips; + private final SearchDirection direction; + + private int tripIndex; + private int stopPositionInPattern; + /** + * earliest-board-time in forward search, and latest-arrival-time for reverse search + */ + private int timeLimit; + private int time; + + public TestTripScheduleSearch(SearchDirection direction, List trips) { + this.trips = trips; + this.direction = direction; + this.tripIndex = NOT_FOUND; + this.time = TIME_NOT_SET; + } + + @Override + public RaptorBoardOrAlightEvent search( + int earliestBoardTime, + int stopPositionInPattern, + int tripIndexLimit + ) { + this.tripIndex = NOT_FOUND; + this.stopPositionInPattern = stopPositionInPattern; + this.timeLimit = earliestBoardTime; + + return direction.isForward() ? searchForward(tripIndexLimit) : searchInReverse(tripIndexLimit); + } + + private RaptorBoardOrAlightEvent searchForward(int tripIndexLimit) { + final int end = tripIndexLimit == UNBOUNDED_TRIP_INDEX ? trips.size() - 1 : tripIndexLimit - 1; + + for (int i = 0; i <= end; ++i) { + int departureTime = trips.get(i).departure(stopPositionInPattern); + if (timeLimit <= departureTime) { + this.time = departureTime; + this.tripIndex = i; + return this; + } + } + return RaptorBoardOrAlightEvent.empty(timeLimit); + } + + private RaptorBoardOrAlightEvent searchInReverse(int tripIndexLimit) { + final int end = tripIndexLimit == UNBOUNDED_TRIP_INDEX ? 0 : tripIndexLimit + 1; + + for (int i = trips.size() - 1; i >= end; --i) { + int arrivalTime = trips.get(i).arrival(stopPositionInPattern); + if (timeLimit >= arrivalTime) { + this.time = arrivalTime; + this.tripIndex = i; + return this; + } + } + return RaptorBoardOrAlightEvent.empty(timeLimit); + } + + @Override + public int tripIndex() { + return tripIndex; + } + + @Override + public TestTripSchedule trip() { + return trips.get(tripIndex); + } + + @Override + public int stopPositionInPattern() { + return stopPositionInPattern; + } + + @Override + public int time() { + return time; + } + + @Override + public int earliestBoardTime() { + return timeLimit; + } + + @Override + public RaptorTransferConstraint transferConstraint() { + return RaptorTransferConstraint.REGULAR_TRANSFER; + } + + @Override + public boolean empty() { + return tripIndex == NOT_FOUND; + } + + @Override + public String toString() { + return ToStringBuilder + .of(TestTripScheduleSearch.class) + .addBoolIfTrue("REVERSE", direction.isInReverse()) + .addNum("tripIndex", tripIndex, NOT_FOUND) + .addNum("stopPos", stopPositionInPattern) + .addServiceTime("timeLimit", timeLimit) + .addServiceTime("time", time, TIME_NOT_SET) + .toString(); + } +} diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripScheduleSearchTest.java b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripScheduleSearchTest.java new file mode 100644 index 00000000000..db4ff4610ba --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/_data/transit/TestTripScheduleSearchTest.java @@ -0,0 +1,175 @@ +package org.opentripplanner.raptor._data.transit; + +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.api.model.RaptorConstants.NOT_FOUND; +import static org.opentripplanner.raptor.api.model.SearchDirection.FORWARD; +import static org.opentripplanner.raptor.api.model.SearchDirection.REVERSE; + +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.RaptorTestConstants; +import org.opentripplanner.raptor.api.model.SearchDirection; +import org.opentripplanner.utils.time.TimeUtils; + +/** + * This tests another test class - we do it to make sure the + * {@link TestTripScheduleSearch} is following the Raptor SPI contract. + */ +class TestTripScheduleSearchTest implements RaptorTestConstants { + + private static final int NOT_DEFINED = -999_999; + private static final int T09_59_59 = TimeUtils.time("09:59:59"); + private static final int T10_00_00 = TimeUtils.time("10:00:00"); + private static final int T10_00_01 = TimeUtils.time("10:00:01"); + private static final int T10_09_59 = TimeUtils.time("10:09:59"); + private static final int T10_10_00 = TimeUtils.time("10:10:00"); + private static final int T10_10_01 = TimeUtils.time("10:10:01"); + private static final int T10_19_59 = TimeUtils.time("10:19:59"); + private static final int T10_20_00 = TimeUtils.time("10:20:00"); + private static final int T10_20_01 = TimeUtils.time("10:20:01"); + + private static final int TRIP_ONE = 0; + private static final int TRIP_TWO = 1; + + private static final TestTripPattern PATTERN = TestTripPattern.pattern("R1", STOP_A, STOP_B); + + private static final List ONE_TRIP = List.of( + TestTripSchedule.schedule(PATTERN).times("10:00 10:10").build() + ); + + private static final List TWO_TRIPS = List.of( + TestTripSchedule.schedule(PATTERN).times("10:00 10:10").build(), + TestTripSchedule.schedule(PATTERN).times("10:10 10:20").build() + ); + + static List tripSearchWithOneTripTestCases() { + return List.of( + Arguments.of(FORWARD, STOP_POS_0, T09_59_59, T10_00_00, Status.OK), + Arguments.of(FORWARD, STOP_POS_0, T10_00_00, T10_00_00, Status.OK), + Arguments.of(FORWARD, STOP_POS_0, T10_00_01, NOT_DEFINED, Status.EMPTY), + Arguments.of(FORWARD, STOP_POS_1, T10_09_59, T10_10_00, Status.OK), + Arguments.of(FORWARD, STOP_POS_1, T10_10_00, T10_10_00, Status.OK), + Arguments.of(FORWARD, STOP_POS_1, T10_10_01, NOT_DEFINED, Status.EMPTY), + Arguments.of(REVERSE, STOP_POS_0, T09_59_59, NOT_DEFINED, Status.EMPTY), + Arguments.of(REVERSE, STOP_POS_0, T10_00_00, T10_00_00, Status.OK), + Arguments.of(REVERSE, STOP_POS_0, T10_00_01, T10_00_00, Status.OK), + Arguments.of(REVERSE, STOP_POS_1, T10_09_59, NOT_DEFINED, Status.EMPTY), + Arguments.of(REVERSE, STOP_POS_1, T10_10_00, T10_10_00, Status.OK), + Arguments.of(REVERSE, STOP_POS_1, T10_10_01, T10_10_00, Status.OK) + ); + } + + @ParameterizedTest + @MethodSource("tripSearchWithOneTripTestCases") + void tripSearchWithOneTrip( + SearchDirection direction, + int stopPos, + int searchTime, + int expTime, + Status expStatus + ) { + var search = new TestTripScheduleSearch(direction, ONE_TRIP); + var result = search.search(searchTime, stopPos); + + if (expStatus == Status.EMPTY) { + assertTrue(result.empty()); + assertTime(searchTime, result.earliestBoardTime()); + assertEquals(NOT_FOUND, result.tripIndex()); + } else if (expStatus == Status.OK) { + assertFalse(result.empty()); + assertEquals(stopPos, result.stopPositionInPattern()); + assertTime(expTime, result.time()); + assertTime(searchTime, result.earliestBoardTime()); + assertEquals(0, result.tripIndex()); + } + + if (!result.empty()) { + // A second search fails if the first search succeeded + int tripIndex = result.tripIndex(); + var e = search.search(direction.isForward() ? T09_59_59 : T10_20_01, stopPos, tripIndex); + assertTrue(e.empty()); + } + } + + static List tripSearchWithTwoTripsTestCases() { + return List.of( + Arguments.of(FORWARD, STOP_POS_0, T09_59_59, T10_00_00, TRIP_ONE), + Arguments.of(FORWARD, STOP_POS_0, T10_00_00, T10_00_00, TRIP_ONE), + Arguments.of(FORWARD, STOP_POS_0, T10_00_01, T10_10_00, TRIP_TWO), + Arguments.of(FORWARD, STOP_POS_0, T10_09_59, T10_10_00, TRIP_TWO), + Arguments.of(FORWARD, STOP_POS_0, T10_10_00, T10_10_00, TRIP_TWO), + Arguments.of(FORWARD, STOP_POS_0, T10_10_01, NOT_DEFINED, NOT_FOUND), + Arguments.of(FORWARD, STOP_POS_1, T10_09_59, T10_10_00, TRIP_ONE), + Arguments.of(FORWARD, STOP_POS_1, T10_10_00, T10_10_00, TRIP_ONE), + Arguments.of(FORWARD, STOP_POS_1, T10_10_01, T10_20_00, TRIP_TWO), + Arguments.of(FORWARD, STOP_POS_1, T10_19_59, T10_20_00, TRIP_TWO), + Arguments.of(FORWARD, STOP_POS_1, T10_20_00, T10_20_00, TRIP_TWO), + Arguments.of(FORWARD, STOP_POS_1, T10_20_01, NOT_DEFINED, NOT_FOUND), + Arguments.of(REVERSE, STOP_POS_0, T09_59_59, NOT_DEFINED, NOT_FOUND), + Arguments.of(REVERSE, STOP_POS_0, T10_00_00, T10_00_00, TRIP_ONE), + Arguments.of(REVERSE, STOP_POS_0, T10_00_01, T10_00_00, TRIP_ONE), + Arguments.of(REVERSE, STOP_POS_0, T10_09_59, T10_00_00, TRIP_ONE), + Arguments.of(REVERSE, STOP_POS_0, T10_10_00, T10_10_00, TRIP_TWO), + Arguments.of(REVERSE, STOP_POS_0, T10_10_01, T10_10_00, TRIP_TWO), + Arguments.of(REVERSE, STOP_POS_1, T10_09_59, NOT_DEFINED, NOT_FOUND), + Arguments.of(REVERSE, STOP_POS_1, T10_10_00, T10_10_00, TRIP_ONE), + Arguments.of(REVERSE, STOP_POS_1, T10_10_01, T10_10_00, TRIP_ONE), + Arguments.of(REVERSE, STOP_POS_1, T10_19_59, T10_10_00, TRIP_ONE), + Arguments.of(REVERSE, STOP_POS_1, T10_20_00, T10_20_00, TRIP_TWO), + Arguments.of(REVERSE, STOP_POS_1, T10_20_01, T10_20_00, TRIP_TWO) + ); + } + + @ParameterizedTest + @MethodSource("tripSearchWithTwoTripsTestCases") + void tripSearchWithTwoTrips( + SearchDirection direction, + int stopPos, + int searchTime, + int expTime, + int expTripIndex + ) { + var search = new TestTripScheduleSearch(direction, TWO_TRIPS); + var result = search.search(searchTime, stopPos); + + if (expTripIndex == NOT_FOUND) { + assertTrue(result.empty()); + assertTime(searchTime, result.earliestBoardTime()); + assertEquals(NOT_FOUND, result.tripIndex()); + } else { + assertFalse(result.empty()); + assertEquals(stopPos, result.stopPositionInPattern()); + assertTime(expTime, result.time()); + assertTime(searchTime, result.earliestBoardTime()); + assertEquals(expTripIndex, result.tripIndex()); + } + + if (!result.empty()) { + int secondTrip = direction.isForward() ? TRIP_TWO : TRIP_ONE; + int firstTrip = direction.isForward() ? TRIP_ONE : TRIP_TWO; + int tripIndex = result.tripIndex(); + var e = search.search(direction.isForward() ? T09_59_59 : T10_20_01, stopPos, tripIndex); + + if (tripIndex == secondTrip) { + assertFalse(e.empty()); + assertEquals(firstTrip, result.tripIndex()); + } else { + assertTrue(e.empty()); + assertEquals(NOT_FOUND, result.tripIndex()); + } + } + } + + private static void assertTime(int expected, int actual) { + assertEquals(TimeUtils.timeToStrLong(expected), TimeUtils.timeToStrLong(actual)); + } + + private enum Status { + OK, + EMPTY, + } +} diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_support/arch/ArchComponent.java b/raptor/src/test/java/org/opentripplanner/raptor/_support/arch/ArchComponent.java new file mode 100644 index 00000000000..eb95bfaf708 --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/_support/arch/ArchComponent.java @@ -0,0 +1,35 @@ +package org.opentripplanner.raptor._support.arch; + +import com.tngtech.archunit.core.domain.JavaClasses; +import com.tngtech.archunit.core.importer.ClassFileImporter; +import com.tngtech.archunit.core.importer.ImportOption; +import java.util.Collection; + +public interface ArchComponent { + /** + * ArchUnit cached set of classes in OTP. It takes a bit of time to build the set of + * classes, so it is nice to avoid this for every test. ArchUnit also support JUnit5 + * with a @ArchTest annotation which cache and inject the classes, but the test become + * slightly more complex by using it and chasing it here works fine. + */ + JavaClasses OTP_CLASSES = new ClassFileImporter() + .withImportOption(new ImportOption.DoNotIncludeTests()) + .importPackages("org.opentripplanner"); + + /** + * All Java packages in {@code java.*} and {@code javax.*} + */ + Module JAVA_PACKAGES = Module.of( + Package.of("java.."), + Package.of("javax.(*).."), + Package.of("jakarta.(*)..") + ); + + Module LOG_FRAMEWORK = Module.of(Package.of("org.slf4j")); + + Collection packages(); + + default Collection packageIdentifiers() { + return packages().stream().map(Package::packageIdentifier).toList(); + } +} diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_support/arch/Module.java b/raptor/src/test/java/org/opentripplanner/raptor/_support/arch/Module.java new file mode 100644 index 00000000000..c6b16a8faf5 --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/_support/arch/Module.java @@ -0,0 +1,23 @@ +package org.opentripplanner.raptor._support.arch; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +public class Module implements ArchComponent { + + private final List packages; + + private Module(List packages) { + this.packages = packages; + } + + public static Module of(ArchComponent... components) { + return new Module(Arrays.stream(components).flatMap(c -> c.packages().stream()).toList()); + } + + @Override + public Collection packages() { + return packages; + } +} diff --git a/raptor/src/test/java/org/opentripplanner/raptor/_support/arch/Package.java b/raptor/src/test/java/org/opentripplanner/raptor/_support/arch/Package.java new file mode 100644 index 00000000000..d87daf06448 --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/_support/arch/Package.java @@ -0,0 +1,91 @@ +package org.opentripplanner.raptor._support.arch; + +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes; + +import com.tngtech.archunit.lang.ArchRule; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@SuppressWarnings("UnusedReturnValue") +public class Package implements ArchComponent { + + private final String packageIdentifier; + private final Set allowedPackages = new HashSet<>(); + + private Package(String packageIdentifier) { + this.packageIdentifier = packageIdentifier; + } + + public static Package of(String packageIdentifier) { + return new Package(packageIdentifier); + } + + public Package subPackage(String packageIdentifier) { + return new Package(this.packageIdentifier + "." + packageIdentifier); + } + + public String packageIdentifier() { + return packageIdentifier; + } + + public String packageIdentifierAllSubPackages() { + return packageIdentifier + ".(**)"; + } + + public Package dependsOn(ArchComponent... allowedDependencies) { + for (ArchComponent it : allowedDependencies) { + this.allowedPackages.addAll(it.packages()); + } + return this; + } + + @Override + public Set packages() { + return Set.of(this); + } + + public Package verify() { + ArchRule rule = classes() + .that() + .resideInAPackage(packageIdentifier) + .should() + .onlyDependOnClassesThat() + .resideInAnyPackage(allAllowedPackages()); + + rule.check(OTP_CLASSES); + return this; + } + + /** + * This includes the allowed packages plus all globally allowed packages like: + *

      + *
    • Java framework
    • + *
    • Log framework
    • + *
    • Arrays (in package "")
    • + *
    + */ + private String[] allAllowedPackages() { + List all = new ArrayList<>(); + + for (Package p : allowedPackages) { + all.add(p.packageIdentifier()); + } + // Allow all packages to depend on Java + for (Package p : JAVA_PACKAGES.packages()) { + all.add(p.packageIdentifier()); + } + // Allow all packages to depend on the log framework + for (Package p : LOG_FRAMEWORK.packages()) { + all.add(p.packageIdentifier()); + } + // Allow all packages to depend on itself + all.add(packageIdentifier); + + // Allow all packages to depend on array types in package "" (empty) + all.add(""); + + return all.toArray(String[]::new); + } +} diff --git a/src/test/java/org/opentripplanner/raptor/api/model/GeneralizedCostRelaxFunctionTest.java b/raptor/src/test/java/org/opentripplanner/raptor/api/model/GeneralizedCostRelaxFunctionTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/api/model/GeneralizedCostRelaxFunctionTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/api/model/GeneralizedCostRelaxFunctionTest.java diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostConverterTest.java b/raptor/src/test/java/org/opentripplanner/raptor/api/model/RaptorCostConverterTest.java similarity index 95% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostConverterTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/api/model/RaptorCostConverterTest.java index 3827bdd31b6..036ab4d4346 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/RaptorCostConverterTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/api/model/RaptorCostConverterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.raptoradapter.transit.cost; +package org.opentripplanner.raptor.api.model; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/org/opentripplanner/raptor/api/path/PathTest.java b/raptor/src/test/java/org/opentripplanner/raptor/api/path/PathTest.java similarity index 96% rename from src/test/java/org/opentripplanner/raptor/api/path/PathTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/api/path/PathTest.java index de71574a952..e0819717e10 100644 --- a/src/test/java/org/opentripplanner/raptor/api/path/PathTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/api/path/PathTest.java @@ -3,8 +3,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.opentripplanner.framework.time.TimeUtils.time; -import static org.opentripplanner.framework.time.TimeUtils.timeToStrCompact; import static org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase.ACCESS_START; import static org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase.BASIC_PATH_AS_DETAILED_STRING; import static org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase.BASIC_PATH_AS_STRING; @@ -13,15 +11,17 @@ import static org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase.TOTAL_C1; import static org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase.basicTripStops; import static org.opentripplanner.raptor._data.transit.TestTripPattern.pattern; +import static org.opentripplanner.utils.time.TimeUtils.time; +import static org.opentripplanner.utils.time.TimeUtils.timeToStrCompact; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; import org.junit.jupiter.api.Test; -import org.opentripplanner.model.transfer.TransferConstraint; import org.opentripplanner.raptor._data.RaptorTestConstants; import org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase; import org.opentripplanner.raptor._data.transit.TestAccessEgress; +import org.opentripplanner.raptor._data.transit.TestTransferConstraint; import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.path.Path; @@ -176,7 +176,7 @@ public void testCountTransfersWithStaySeated() { .times(time("09:10"), time("09:20")) .build(); - var tx = TransferConstraint.of().staySeated().build(); + var tx = TestTransferConstraint.staySeated(); TransitPathLeg leg2 = new TransitPathLeg<>( trip2, trip2.departure(0), diff --git a/src/test/java/org/opentripplanner/raptor/api/path/RaptorPathTest.java b/raptor/src/test/java/org/opentripplanner/raptor/api/path/RaptorPathTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/api/path/RaptorPathTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/api/path/RaptorPathTest.java diff --git a/src/test/java/org/opentripplanner/raptor/api/request/MultiCriteriaRequestTest.java b/raptor/src/test/java/org/opentripplanner/raptor/api/request/MultiCriteriaRequestTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/api/request/MultiCriteriaRequestTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/api/request/MultiCriteriaRequestTest.java diff --git a/src/test/java/org/opentripplanner/raptor/api/request/PassThroughPointTest.java b/raptor/src/test/java/org/opentripplanner/raptor/api/request/PassThroughPointTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/api/request/PassThroughPointTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/api/request/PassThroughPointTest.java diff --git a/src/test/java/org/opentripplanner/raptor/api/request/RaptorRequestTest.java b/raptor/src/test/java/org/opentripplanner/raptor/api/request/RaptorRequestTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/api/request/RaptorRequestTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/api/request/RaptorRequestTest.java diff --git a/src/test/java/org/opentripplanner/raptor/api/request/SearchParamsTest.java b/raptor/src/test/java/org/opentripplanner/raptor/api/request/SearchParamsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/api/request/SearchParamsTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/api/request/SearchParamsTest.java diff --git a/raptor/src/test/java/org/opentripplanner/raptor/api/request/ViaLocationTest.java b/raptor/src/test/java/org/opentripplanner/raptor/api/request/ViaLocationTest.java new file mode 100644 index 00000000000..2aca0845ff8 --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/api/request/ViaLocationTest.java @@ -0,0 +1,251 @@ +package org.opentripplanner.raptor.api.request; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.time.Duration; +import java.util.List; +import org.junit.jupiter.api.Assertions; +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.transit.TestTransfer; +import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorTransfer; + +class ViaLocationTest { + + private static final int STOP_A = 12; + private static final int STOP_B = 13; + private static final int STOP_C = 14; + private static final Duration WAIT_TIME = Duration.ofMinutes(3); + private static final int WAIT_TIME_SEC = (int) WAIT_TIME.toSeconds(); + private static final int C1 = 200; + private static final int TX_DURATION = 35; + private static final RaptorTransfer TX = new TestTransfer(STOP_B, TX_DURATION, C1); + + @Test + void passThroughStop() { + var subject = RaptorViaLocation.allowPassThrough("PassThrough A").addViaStop(STOP_C).build(); + + assertEquals("PassThrough A", subject.label()); + assertTrue(subject.allowPassThrough()); + assertEquals(RaptorConstants.ZERO, subject.minimumWaitTime()); + assertEquals( + "Via{label: PassThrough A, allowPassThrough, connections: [C]}", + subject.toString(ViaLocationTest::stopName) + ); + assertEquals( + "Via{label: PassThrough A, allowPassThrough, connections: [14]}", + subject.toString() + ); + + assertEquals(1, subject.connections().size()); + + var c = subject.connections().getFirst(); + assertEquals(STOP_C, c.fromStop()); + assertEquals(STOP_C, c.toStop()); + assertTrue(c.isSameStop()); + Assertions.assertEquals(RaptorConstants.ZERO, c.durationInSeconds()); + assertEquals(RaptorConstants.ZERO, c.c1()); + } + + @Test + void viaSingleStop() { + var subject = RaptorViaLocation.via("Tx A").addViaStop(STOP_B).build(); + + assertEquals("Tx A", subject.label()); + assertFalse(subject.allowPassThrough()); + assertEquals(RaptorConstants.ZERO, subject.minimumWaitTime()); + assertEquals("Via{label: Tx A, connections: [B]}", subject.toString(ViaLocationTest::stopName)); + assertEquals("Via{label: Tx A, connections: [13]}", subject.toString()); + assertEquals(1, subject.connections().size()); + + var connection = subject.connections().getFirst(); + assertEquals(STOP_B, connection.fromStop()); + assertEquals(STOP_B, connection.toStop()); + assertTrue(connection.isSameStop()); + Assertions.assertEquals(RaptorConstants.ZERO, connection.durationInSeconds()); + assertEquals(RaptorConstants.ZERO, connection.c1()); + } + + @Test + void testCombinationOfPassThroughAndTransfer() { + var subject = RaptorViaLocation + .allowPassThrough("PassThrough A") + .addViaStop(STOP_C) + .addViaTransfer(STOP_A, TX) + .build(); + + assertEquals("PassThrough A", subject.label()); + assertTrue(subject.allowPassThrough()); + assertEquals(RaptorConstants.ZERO, subject.minimumWaitTime()); + assertEquals( + "Via{label: PassThrough A, allowPassThrough, connections: [C, A~B 35s]}", + subject.toString(ViaLocationTest::stopName) + ); + assertEquals(2, subject.connections().size()); + + var c = subject.connections().getFirst(); + assertEquals(STOP_C, c.fromStop()); + assertEquals(STOP_C, c.toStop()); + assertTrue(c.isSameStop()); + Assertions.assertEquals(RaptorConstants.ZERO, c.durationInSeconds()); + assertEquals(RaptorConstants.ZERO, c.c1()); + + c = subject.connections().getLast(); + assertEquals(STOP_A, c.fromStop()); + assertEquals(STOP_B, c.toStop()); + assertFalse(c.isSameStop()); + Assertions.assertEquals(TX_DURATION, c.durationInSeconds()); + assertEquals(C1, c.c1()); + } + + @Test + void viaStopAorCWithWaitTime() { + var subject = RaptorViaLocation + .via("Plaza", WAIT_TIME) + .addViaStop(STOP_C) + .addViaTransfer(STOP_A, TX) + .build(); + + assertEquals("Plaza", subject.label()); + assertFalse(subject.allowPassThrough()); + assertEquals(WAIT_TIME_SEC, subject.minimumWaitTime()); + assertEquals( + "Via{label: Plaza, minWaitTime: 3m, connections: [C 3m, A~B 3m35s]}", + subject.toString(ViaLocationTest::stopName) + ); + assertEquals(2, subject.connections().size()); + + var connection = subject.connections().getFirst(); + assertEquals(STOP_C, connection.fromStop()); + assertEquals(STOP_C, connection.toStop()); + assertTrue(connection.isSameStop()); + Assertions.assertEquals(WAIT_TIME_SEC, connection.durationInSeconds()); + assertEquals(RaptorConstants.ZERO, connection.c1()); + + connection = subject.connections().getLast(); + assertEquals(STOP_A, connection.fromStop()); + assertEquals(STOP_B, connection.toStop()); + assertFalse(connection.isSameStop()); + Assertions.assertEquals(WAIT_TIME_SEC + TX.durationInSeconds(), connection.durationInSeconds()); + assertEquals(C1, connection.c1()); + } + + static List isBetterThanTestCases() { + // Subject is: STOP_A, STOP_B, MIN_DURATION, C1 + return List.of( + Arguments.of(STOP_A, STOP_B, TX_DURATION, C1, true, "Same"), + Arguments.of(STOP_C, STOP_B, TX_DURATION, C1, false, "toStop differ"), + Arguments.of(STOP_A, STOP_C, TX_DURATION, C1, false, "fromStop differ"), + Arguments.of(STOP_A, STOP_B, TX_DURATION + 1, C1, true, "Wait time is better"), + Arguments.of(STOP_A, STOP_B, TX_DURATION - 1, C1, false, "Wait time is worse"), + Arguments.of(STOP_A, STOP_B, TX_DURATION, C1 + 1, true, "C1 is better"), + Arguments.of(STOP_A, STOP_B, TX_DURATION, C1 - 1, false, "C1 is worse") + ); + } + + @ParameterizedTest + @MethodSource("isBetterThanTestCases") + void isBetterThan( + int fromStop, + int toStop, + int minWaitTime, + int c1, + boolean expected, + String description + ) { + var subject = RaptorViaLocation + .via("Subject") + .addViaTransfer(STOP_A, new TestTransfer(STOP_B, TX_DURATION, C1)) + .build() + .connections() + .getFirst(); + + var candidate = RaptorViaLocation + .via("Candidate") + .addViaTransfer(fromStop, new TestTransfer(toStop, minWaitTime, c1)) + .build() + .connections() + .getFirst(); + + assertEquals(subject.isBetterOrEqual(candidate), expected, description); + } + + @Test + void throwsExceptionIfConnectionsIsNotParetoOptimal() { + var e = assertThrows( + IllegalArgumentException.class, + () -> + RaptorViaLocation + .via("S") + .addViaTransfer(STOP_A, new TestTransfer(STOP_B, TX_DURATION, C1)) + .addViaTransfer(STOP_A, new TestTransfer(STOP_B, TX_DURATION, C1)) + .build() + ); + assertEquals( + "All connection need to be pareto-optimal: (12~13 35s) <-> (12~13 35s)", + e.getMessage() + ); + } + + @Test + void testEqualsAndHashCode() { + var subject = RaptorViaLocation.via(null).addViaTransfer(STOP_A, TX).build(); + var same = RaptorViaLocation.via(null).addViaTransfer(STOP_A, TX).build(); + // Slightly less wait-time and slightly larger cost(c1) + var other = RaptorViaLocation + .via(null, Duration.ofSeconds(1)) + .addViaTransfer(STOP_A, TX) + .build(); + + assertEquals(subject, same); + assertNotEquals(subject, other); + assertNotEquals(subject, "Does not match another type"); + + assertEquals(subject.hashCode(), same.hashCode()); + assertNotEquals(subject.hashCode(), other.hashCode()); + } + + @Test + void testToString() { + var subject = RaptorViaLocation.via("A|B").addViaStop(STOP_A).addViaStop(STOP_B).build(); + assertEquals("Via{label: A|B, connections: [12, 13]}", subject.toString()); + assertEquals( + "Via{label: A|B, connections: [A, B]}", + subject.toString(ViaLocationTest::stopName) + ); + + subject = RaptorViaLocation.via(null, WAIT_TIME).addViaStop(STOP_B).build(); + assertEquals("Via{minWaitTime: 3m, connections: [13 3m]}", subject.toString()); + assertEquals( + "Via{minWaitTime: 3m, connections: [B 3m]}", + subject.toString(ViaLocationTest::stopName) + ); + + subject = RaptorViaLocation.via(null).addViaTransfer(STOP_A, TX).build(); + assertEquals("Via{connections: [12~13 35s]}", subject.toString()); + assertEquals("Via{connections: [A~B 35s]}", subject.toString(ViaLocationTest::stopName)); + + subject = RaptorViaLocation.allowPassThrough(null).addViaStop(STOP_C).build(); + assertEquals("Via{allowPassThrough, connections: [14]}", subject.toString()); + assertEquals( + "Via{allowPassThrough, connections: [C]}", + subject.toString(ViaLocationTest::stopName) + ); + } + + private static String stopName(int i) { + return switch (i) { + case 12 -> "A"; + case 13 -> "B"; + case 14 -> "C"; + default -> throw new IllegalArgumentException("Unknown stop: " + i); + }; + } +} diff --git a/src/test/java/org/opentripplanner/raptor/api/view/BoardAndAlightTimeTest.java b/raptor/src/test/java/org/opentripplanner/raptor/api/view/BoardAndAlightTimeTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/api/view/BoardAndAlightTimeTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/api/view/BoardAndAlightTimeTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/A01_SingleRouteTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/A01_SingleRouteTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/A01_SingleRouteTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/A01_SingleRouteTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/A04_BoardingTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/A04_BoardingTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/A04_BoardingTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/A04_BoardingTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/B01_AccessTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/B01_AccessTest.java similarity index 98% rename from src/test/java/org/opentripplanner/raptor/moduletests/B01_AccessTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/B01_AccessTest.java index 37814d6c6dc..76583a38649 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/B01_AccessTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/B01_AccessTest.java @@ -12,7 +12,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.raptor.RaptorService; import org.opentripplanner.raptor._data.RaptorTestConstants; import org.opentripplanner.raptor._data.transit.TestAccessEgress; @@ -22,6 +21,7 @@ import org.opentripplanner.raptor.configure.RaptorConfig; import org.opentripplanner.raptor.moduletests.support.ModuleTestDebugLogging; import org.opentripplanner.raptor.moduletests.support.RaptorModuleTestCase; +import org.opentripplanner.utils.time.DurationUtils; /** * FEATURE UNDER TEST diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/B02_EgressTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/B02_EgressTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/B02_EgressTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/B02_EgressTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/B03_AccessEgressTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/B03_AccessEgressTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/B03_AccessEgressTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/B03_AccessEgressTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/B04_AccessEgressBoardingTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/B04_AccessEgressBoardingTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/B04_AccessEgressBoardingTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/B04_AccessEgressBoardingTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/B05_EgressStopBoardAlightTransferCostTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/B05_EgressStopBoardAlightTransferCostTest.java similarity index 98% rename from src/test/java/org/opentripplanner/raptor/moduletests/B05_EgressStopBoardAlightTransferCostTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/B05_EgressStopBoardAlightTransferCostTest.java index df38aabc483..7f2dd2f0072 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/B05_EgressStopBoardAlightTransferCostTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/B05_EgressStopBoardAlightTransferCostTest.java @@ -39,7 +39,7 @@ void setup() { .withRoute(route("R1", STOP_B, STOP_C).withTimetable(schedule("0:10, 0:14"))) .withRoute(route("R2", STOP_C, STOP_D).withTimetable(schedule("0:18, 0:20"))); - data.mcCostParamsBuilder().transferCost(0).boardCost(0); + data.withTransferCost(0).withBoardCost(0); data.withStopBoardAlightTransferCost(STOP_D, 60000); requestBuilder diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/C01_TransferBoardAndAlightSlackTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/C01_TransferBoardAndAlightSlackTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/C01_TransferBoardAndAlightSlackTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/C01_TransferBoardAndAlightSlackTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/C02_OnStreetTransfersTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/C02_OnStreetTransfersTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/C02_OnStreetTransfersTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/C02_OnStreetTransfersTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/C03_OnBoardArrivalDominateTransfersTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/C03_OnBoardArrivalDominateTransfersTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/C03_OnBoardArrivalDominateTransfersTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/C03_OnBoardArrivalDominateTransfersTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/D01_SingeRouteBoardAlightRestrictionsTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/D01_SingeRouteBoardAlightRestrictionsTest.java similarity index 94% rename from src/test/java/org/opentripplanner/raptor/moduletests/D01_SingeRouteBoardAlightRestrictionsTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/D01_SingeRouteBoardAlightRestrictionsTest.java index a63c208cae3..cde91ab61f8 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/D01_SingeRouteBoardAlightRestrictionsTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/D01_SingeRouteBoardAlightRestrictionsTest.java @@ -2,7 +2,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; 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 static org.opentripplanner.raptor.moduletests.support.RaptorModuleTestConfig.multiCriteria; import static org.opentripplanner.raptor.moduletests.support.RaptorModuleTestConfig.standard; @@ -57,8 +56,10 @@ public class D01_SingeRouteBoardAlightRestrictionsTest implements RaptorTestCons */ @BeforeEach void setup() { - TestTripPattern pattern = pattern("R1", STOP_B, STOP_C, STOP_D); - pattern.restrictions("BW BA AW"); + TestTripPattern pattern = TestTripPattern + .of("R1", STOP_B, STOP_C, STOP_D) + .restrictions("B BA A") + .build(); data.withRoute(route(pattern).withTimetable(schedule("00:01, 00:03, 00:05"))); requestBuilder .searchParams() diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/E01_StaySeatedTransferTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/E01_StaySeatedTransferTest.java similarity index 93% rename from src/test/java/org/opentripplanner/raptor/moduletests/E01_StaySeatedTransferTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/E01_StaySeatedTransferTest.java index d1d1f2191f5..16d0ea745fe 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/E01_StaySeatedTransferTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/E01_StaySeatedTransferTest.java @@ -10,11 +10,11 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.model.transfer.TransferConstraint; import org.opentripplanner.raptor.RaptorService; import org.opentripplanner.raptor._data.RaptorTestConstants; import org.opentripplanner.raptor._data.api.PathUtils; import org.opentripplanner.raptor._data.transit.TestAccessEgress; +import org.opentripplanner.raptor._data.transit.TestTransferConstraint; import org.opentripplanner.raptor._data.transit.TestTransitData; import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; @@ -57,14 +57,8 @@ public void setup() { var tripB = r2.timetable().getTripSchedule(0); data.withRoutes(r1, r2); - data.withConstrainedTransfer( - tripA, - STOP_B, - tripB, - STOP_B, - TransferConstraint.of().staySeated().build() - ); - data.mcCostParamsBuilder().transferCost(100); + data.withConstrainedTransfer(tripA, STOP_B, tripB, STOP_B, TestTransferConstraint.staySeated()); + data.withTransferCost(100); // NOTE! No search-window is set. requestBuilder diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/E02_GuaranteedWalkTransferTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/E02_GuaranteedWalkTransferTest.java similarity index 98% rename from src/test/java/org/opentripplanner/raptor/moduletests/E02_GuaranteedWalkTransferTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/E02_GuaranteedWalkTransferTest.java index c448560c7fb..cd2b1f3c25e 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/E02_GuaranteedWalkTransferTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/E02_GuaranteedWalkTransferTest.java @@ -61,7 +61,7 @@ public void setup() { data.withRoutes(r1, r2); data.withGuaranteedTransfer(tripA, STOP_B, tripB, STOP_C); data.withTransfer(STOP_B, TestTransfer.transfer(STOP_C, 30)); - data.mcCostParamsBuilder().transferCost(100); + data.withTransferCost(100); // NOTE! No search-window is set. requestBuilder diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/E03_NotAllowedConstrainedTransferTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/E03_NotAllowedConstrainedTransferTest.java similarity index 98% rename from src/test/java/org/opentripplanner/raptor/moduletests/E03_NotAllowedConstrainedTransferTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/E03_NotAllowedConstrainedTransferTest.java index 0866042548d..1a324796784 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/E03_NotAllowedConstrainedTransferTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/E03_NotAllowedConstrainedTransferTest.java @@ -64,7 +64,7 @@ public void setup() { // transit model, a not-allowed transfer should apply to ALL trips if constraint is passed // to raptor. data.withConstrainedTransfer(tripR1a, STOP_B, tripR2a, STOP_B, TestTransitData.TX_NOT_ALLOWED); - data.mcCostParamsBuilder().transferCost(100); + data.withTransferCost(100); // NOTE! No search-window set requestBuilder diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/F01_AccessWithRidesTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F01_AccessWithRidesTest.java similarity index 98% rename from src/test/java/org/opentripplanner/raptor/moduletests/F01_AccessWithRidesTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/F01_AccessWithRidesTest.java index e93f464826c..96a5a04d7fd 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/F01_AccessWithRidesTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F01_AccessWithRidesTest.java @@ -20,12 +20,12 @@ import org.opentripplanner.raptor._data.RaptorTestConstants; import org.opentripplanner.raptor._data.transit.TestTransitData; import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; import org.opentripplanner.raptor.configure.RaptorConfig; import org.opentripplanner.raptor.moduletests.support.ModuleTestDebugLogging; import org.opentripplanner.raptor.moduletests.support.RaptorModuleTestCase; import org.opentripplanner.raptor.spi.DefaultSlackProvider; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; /** * FEATURE UNDER TEST diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/F02_EgressWithRidesTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F02_EgressWithRidesTest.java similarity index 98% rename from src/test/java/org/opentripplanner/raptor/moduletests/F02_EgressWithRidesTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/F02_EgressWithRidesTest.java index 87b2237fac8..1b5164c79a4 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/F02_EgressWithRidesTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F02_EgressWithRidesTest.java @@ -17,7 +17,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.raptor.RaptorService; import org.opentripplanner.raptor._data.RaptorTestConstants; import org.opentripplanner.raptor._data.transit.TestTransitData; @@ -27,6 +26,7 @@ import org.opentripplanner.raptor.moduletests.support.ModuleTestDebugLogging; import org.opentripplanner.raptor.moduletests.support.RaptorModuleTestCase; import org.opentripplanner.raptor.spi.DefaultSlackProvider; +import org.opentripplanner.utils.time.DurationUtils; /** * FEATURE UNDER TEST diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/F03_AccessEgressWithRidesBoardAndAlightSlackTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F03_AccessEgressWithRidesBoardAndAlightSlackTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/F03_AccessEgressWithRidesBoardAndAlightSlackTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/F03_AccessEgressWithRidesBoardAndAlightSlackTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/F04_AccessEgressWithRidesNoTransitTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F04_AccessEgressWithRidesNoTransitTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/F04_AccessEgressWithRidesNoTransitTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/F04_AccessEgressWithRidesNoTransitTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/F05_OnBoardAccessEgressAndTransfersTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F05_OnBoardAccessEgressAndTransfersTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/F05_OnBoardAccessEgressAndTransfersTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/F05_OnBoardAccessEgressAndTransfersTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/F11_AccessWithRidesMultipleOptimalPathsTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F11_AccessWithRidesMultipleOptimalPathsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/F11_AccessWithRidesMultipleOptimalPathsTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/F11_AccessWithRidesMultipleOptimalPathsTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/F12_EgressWithRidesMultipleOptimalPathsTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F12_EgressWithRidesMultipleOptimalPathsTest.java similarity index 98% rename from src/test/java/org/opentripplanner/raptor/moduletests/F12_EgressWithRidesMultipleOptimalPathsTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/F12_EgressWithRidesMultipleOptimalPathsTest.java index 1ec5399a668..40e4ffd567d 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/F12_EgressWithRidesMultipleOptimalPathsTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/F12_EgressWithRidesMultipleOptimalPathsTest.java @@ -25,12 +25,12 @@ import org.opentripplanner.raptor._data.transit.TestTransfer; import org.opentripplanner.raptor._data.transit.TestTransitData; import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; import org.opentripplanner.raptor.configure.RaptorConfig; import org.opentripplanner.raptor.moduletests.support.ModuleTestDebugLogging; import org.opentripplanner.raptor.moduletests.support.RaptorModuleTestCase; import org.opentripplanner.raptor.spi.DefaultSlackProvider; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; /** * FEATURE UNDER TEST diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/G01_AccessWithOpeningHoursTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G01_AccessWithOpeningHoursTest.java similarity index 99% rename from src/test/java/org/opentripplanner/raptor/moduletests/G01_AccessWithOpeningHoursTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/G01_AccessWithOpeningHoursTest.java index 7f5e5421e79..bf3bf359001 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/G01_AccessWithOpeningHoursTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G01_AccessWithOpeningHoursTest.java @@ -19,7 +19,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor.RaptorService; import org.opentripplanner.raptor._data.RaptorTestConstants; import org.opentripplanner.raptor._data.transit.TestTransitData; @@ -30,6 +29,7 @@ import org.opentripplanner.raptor.moduletests.support.ModuleTestDebugLogging; import org.opentripplanner.raptor.moduletests.support.RaptorModuleTestCase; import org.opentripplanner.raptor.moduletests.support.RaptorModuleTestCaseFactory; +import org.opentripplanner.utils.time.TimeUtils; /* * FEATURE UNDER TEST diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/G02_EgressWithOpeningHoursTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G02_EgressWithOpeningHoursTest.java similarity index 99% rename from src/test/java/org/opentripplanner/raptor/moduletests/G02_EgressWithOpeningHoursTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/G02_EgressWithOpeningHoursTest.java index 9498f0b0080..994305cb0d5 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/G02_EgressWithOpeningHoursTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G02_EgressWithOpeningHoursTest.java @@ -1,7 +1,6 @@ package org.opentripplanner.raptor.moduletests; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.time.TimeUtils.hm2time; import static org.opentripplanner.raptor._data.api.PathUtils.withoutCost; import static org.opentripplanner.raptor._data.transit.TestAccessEgress.walk; import static org.opentripplanner.raptor._data.transit.TestRoute.route; @@ -13,6 +12,7 @@ import static org.opentripplanner.raptor.moduletests.support.RaptorModuleTestConfig.minDuration; import static org.opentripplanner.raptor.moduletests.support.RaptorModuleTestConfig.multiCriteria; import static org.opentripplanner.raptor.moduletests.support.RaptorModuleTestConfig.standard; +import static org.opentripplanner.utils.time.TimeUtils.hm2time; import java.time.Duration; import java.util.List; diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/G03_AccessWithOpeningHoursMultipleOptionsTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G03_AccessWithOpeningHoursMultipleOptionsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/G03_AccessWithOpeningHoursMultipleOptionsTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/G03_AccessWithOpeningHoursMultipleOptionsTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/G04_EgressWithOpeningHoursMultipleOptionsTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G04_EgressWithOpeningHoursMultipleOptionsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/G04_EgressWithOpeningHoursMultipleOptionsTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/G04_EgressWithOpeningHoursMultipleOptionsTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/G05_ClosedAccessOpeningHoursTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G05_ClosedAccessOpeningHoursTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/G05_ClosedAccessOpeningHoursTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/G05_ClosedAccessOpeningHoursTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/G06_ClosedEgressOpeningHoursTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/G06_ClosedEgressOpeningHoursTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/G06_ClosedEgressOpeningHoursTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/G06_ClosedEgressOpeningHoursTest.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/H11_GuaranteedTransferWithFlexAccessTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/H11_GuaranteedTransferWithFlexAccessTest.java similarity index 96% rename from src/test/java/org/opentripplanner/raptor/moduletests/H11_GuaranteedTransferWithFlexAccessTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/H11_GuaranteedTransferWithFlexAccessTest.java index 9cf2aaf7b82..64e4f728d09 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/H11_GuaranteedTransferWithFlexAccessTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/H11_GuaranteedTransferWithFlexAccessTest.java @@ -20,11 +20,11 @@ import org.opentripplanner.raptor._data.transit.TestTransfer; import org.opentripplanner.raptor._data.transit.TestTransitData; import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; import org.opentripplanner.raptor.configure.RaptorConfig; import org.opentripplanner.raptor.moduletests.support.ModuleTestDebugLogging; import org.opentripplanner.raptor.moduletests.support.RaptorModuleTestCase; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; /** * FEATURE UNDER TEST @@ -54,7 +54,7 @@ public void setup() { data.withRoutes(r1, r2); data.withGuaranteedTransfer(tripA, STOP_C, tripB, STOP_C); data.withTransfer(STOP_A, TestTransfer.transfer(STOP_B, D10m)); - data.mcCostParamsBuilder().transferCost(100); + data.withTransferCost(100); requestBuilder .searchParams() diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/I01_HeuristicTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/I01_HeuristicTest.java similarity index 96% rename from src/test/java/org/opentripplanner/raptor/moduletests/I01_HeuristicTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/I01_HeuristicTest.java index 7fe9cfa2c15..1e2f79cce44 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/I01_HeuristicTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/I01_HeuristicTest.java @@ -90,7 +90,7 @@ public void setup() { public void regular() { var request = requestBuilder.build(); - var search = new RangeRaptorDynamicSearch<>(config, data, request); + var search = new RangeRaptorDynamicSearch<>(config, data, null, request); search.route(); @@ -105,7 +105,7 @@ public void withConstrainedTransfers() { var request = requestBuilder.build(); - var search = new RangeRaptorDynamicSearch<>(config, data, request); + var search = new RangeRaptorDynamicSearch<>(config, data, null, request); search.route(); diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/J01_PassThroughTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/J01_PassThroughTest.java similarity index 98% rename from src/test/java/org/opentripplanner/raptor/moduletests/J01_PassThroughTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/J01_PassThroughTest.java index d37a1adf61f..6047280488a 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/J01_PassThroughTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/J01_PassThroughTest.java @@ -1,7 +1,7 @@ package org.opentripplanner.raptor.moduletests; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.model.plan.PlanTestConstants.D2m; +import static org.opentripplanner.raptor._data.RaptorTestConstants.D2m; import static org.opentripplanner.raptor._data.RaptorTestConstants.D30s; import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_A; import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_B; @@ -163,7 +163,7 @@ void passThroughPointInTheMiddle() { var r2 = route("R2", STOP_A, STOP_C, STOP_D).withTimetable(schedule("0:02 0:10 0:50")); data.withRoutes(r1, r2); - data.mcCostParamsBuilder().transferCost(100); + data.withTransferCost(100); var requestBuilder = prepareRequest(); @@ -195,7 +195,7 @@ void multiplePassThroughPoints() { .withTimetable(schedule("0:15 0:20 0:30 0:50")); data.withRoutes(r1, r2); - data.mcCostParamsBuilder().transferCost(100); + data.withTransferCost(100); var requestBuilder = prepareRequest(); diff --git a/raptor/src/test/java/org/opentripplanner/raptor/moduletests/J02_ViaSearchTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/J02_ViaSearchTest.java new file mode 100644 index 00000000000..fd872a3d138 --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/J02_ViaSearchTest.java @@ -0,0 +1,376 @@ +package org.opentripplanner.raptor.moduletests; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.raptor._data.RaptorTestConstants.D1m; +import static org.opentripplanner.raptor._data.RaptorTestConstants.D2m; +import static org.opentripplanner.raptor._data.RaptorTestConstants.D30s; +import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_A; +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.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.TestTransfer.transfer; +import static org.opentripplanner.raptor._data.transit.TestTripSchedule.schedule; +import static org.opentripplanner.raptor.api.request.RaptorViaLocation.via; + +import java.time.Duration; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.opentripplanner.raptor.RaptorService; +import org.opentripplanner.raptor._data.api.PathUtils; +import org.opentripplanner.raptor._data.transit.TestTransitData; +import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.raptor.api.request.RaptorProfile; +import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; +import org.opentripplanner.raptor.api.request.RaptorViaLocation; +import org.opentripplanner.raptor.configure.RaptorConfig; + +/** + * FEATURE UNDER TEST + * + * Raptor should be able to handle route request with one or more via locations. + * If a stop is specified as via location in the request, then all the results returned + * from raptor should include the stop. The stop should be a alight, board or intermediate + * stop of one of the trips in the path. + * + * It should be possible to specify more than one connection. The result should include the + * via locations in the order as they were specified in the request. Only alternatives that pass + * through all via locations should be included in the result. + * + * To support stations and other collections of stops, Raptor should also support multiple via + * connections in one via location. + */ +class J02_ViaSearchTest { + + static final List VIA_LOCATION_STOP_B = List.of(viaLocation("B", STOP_B)); + static final List VIA_LOCATION_STOP_C = List.of(viaLocation("C", STOP_C)); + static final List VIA_LOCATION_STOP_A_OR_B = List.of( + viaLocation("B&C", STOP_A, STOP_B) + ); + + static final List VIA_LOCATION_STOP_B_THEN_D = List.of( + viaLocation("B", STOP_B), + viaLocation("D", STOP_D) + ); + static final List VIA_LOCATION_STOP_C_THEN_B = List.of( + viaLocation("B", STOP_C), + viaLocation("D", STOP_B) + ); + + private final RaptorService raptorService = new RaptorService<>( + RaptorConfig.defaultConfigForTest() + ); + + private RaptorRequestBuilder prepareRequest() { + var builder = new RaptorRequestBuilder(); + + builder + .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(); + + builder + .searchParams() + .earliestDepartureTime(T00_00) + .latestArrivalTime(T01_00) + .searchWindow(Duration.ofMinutes(10)) + .timetable(true); + + return builder; + } + + @Test + @DisplayName( + "Basic via search with just one route. You should be forced to get off the " + + "first trip and wait for the next one at the specified via stop." + ) + void viaSearchAlightingAtViaStop() { + var data = new TestTransitData(); + + data.withRoutes( + route("R1", STOP_A, STOP_B, STOP_C, STOP_D) + .withTimetable(schedule("0:02 0:10 0:20 0:30"), schedule("0:12 0:20 0:30 0:40")) + ); + + var requestBuilder = prepareRequest(); + + requestBuilder + .searchParams() + .addAccessPaths(walk(STOP_A, D30s)) + .addViaLocation(via("C").addViaStop(STOP_C).build()) + .addEgressPaths(walk(STOP_D, D30s)); + + var result = raptorService.route(requestBuilder.build(), data); + + // Verify that we alight the first trip at stop C and board the second trip + assertEquals( + "Walk 30s ~ A ~ BUS R1 0:02 0:20 ~ C ~ BUS R1 0:30 0:40 ~ D ~ Walk 30s [0:01:30 0:40:30 39m Tₓ1 C₁3_600]", + pathsToString(result) + ); + } + + @Test + @DisplayName( + "Basic via search with just two routes. You should be forced to get off the first route, " + + "then transfer and BOARD the second trip at the specified via stop. This test that via works " + + "at the boarding stop. We will add better options for the transfer to see that the given via " + + "stop is used over the alternatives." + ) + void viaSearchArrivingByTransferAtViaStop() { + var data = new TestTransitData(); + + data + .withRoutes( + route("R1", STOP_A, STOP_B, STOP_D, STOP_E).withTimetable(schedule("0:02 0:10 0:20 0:30")), + route("R2", STOP_C, STOP_D, STOP_E).withTimetable(schedule("0:25 0:30 0:40")) + ) + // Walk 1 minute to transfer from D to C - this is the only way to visit stop C + .withTransfer(STOP_D, transfer(STOP_C, D1m)); + + var requestBuilder = prepareRequest(); + + requestBuilder + .searchParams() + .addAccessPaths(walk(STOP_A, D30s)) + .addViaLocation(via("C").addViaStop(STOP_C).build()) + .addEgressPaths(walk(STOP_E, D30s)); + + var result = raptorService.route(requestBuilder.build(), data); + + // Verify that we alight the first trip at stop C and board the second trip + assertEquals( + "Walk 30s ~ A ~ BUS R1 0:02 0:20 ~ D ~ Walk 1m ~ C ~ BUS R2 0:25 0:40 ~ E ~ Walk 30s " + + "[0:01:30 0:40:30 39m Tₓ1 C₁3_660]", + pathsToString(result) + ); + } + + @Test + @DisplayName( + "Via stop as the first stop in the journey - only the access will be used for the first " + + "part, no transit. Access arrival should be copied over to 'next' worker." + ) + void accessWalkToViaStopWithoutTransit() { + var data = new TestTransitData(); + + data.withRoutes( + route("R1", STOP_A, STOP_B, STOP_C, STOP_D) + .withTimetable( + schedule("0:02 0:05 0:10 0:15"), + // We add another trip to allow riding trip one - via B - then ride trip two, this + // is not a pareto-optimal solution and should only appear if there is something wrong. + schedule("0:12 0:15 0:20 0:25") + ) + ); + + var requestBuilder = prepareRequest(); + + // We will add access to A, B, and C, but since the B stop is the via point we expect that to + // be used + requestBuilder + .searchParams() + .addViaLocations(VIA_LOCATION_STOP_B) + // We allow access to A, B, and C - if the via search works as expected, only access to B + // should be used - access to A would require an extra transfer; C has no valid paths. + .addAccessPaths(walk(STOP_A, D30s)) + .addAccessPaths(walk(STOP_B, D30s)) + .addAccessPaths(walk(STOP_C, D30s)) + .addEgressPaths(walk(STOP_D, D30s)); + + // Verify that the journey start by walking to the via stop, the uses one trip to the destination. + // A combination of trip one and two with a transfer is not expected. + assertEquals( + PathUtils.join( + "Walk 30s ~ B ~ BUS R1 0:05 0:15 ~ D ~ Walk 30s [0:04:30 0:15:30 11m Tₓ0 C₁1_320]", + "Walk 30s ~ B ~ BUS R1 0:15 0:25 ~ D ~ Walk 30s [0:14:30 0:25:30 11m Tₓ0 C₁1_320]" + ), + pathsToString(raptorService.route(requestBuilder.build(), data)) + ); + } + + @Test + @DisplayName( + "Via stop as the last stop in the journey - only the egress will be used for the last " + + "part, no transit. The transit arrival at the via stop should be copied over to the " + + "next worker and then this should be used to add the egress - without any transfers or" + + "more transit." + ) + void transitToViaStopThenTakeEgressWalkToDestination() { + var data = new TestTransitData(); + + data.withRoutes( + route("R1", STOP_A, STOP_B, STOP_C, STOP_D) + .withTimetable( + schedule("0:02 0:05 0:10 0:20"), + // We add another trip to check that we do not transfer to the other trip at some point. + schedule("0:12 0:15 0:20 0:25") + ) + ); + + var requestBuilder = prepareRequest(); + + // We will add access to A, B, and C, but since the B stop is the via point we expect that to + // be used + requestBuilder + .searchParams() + .addAccessPaths(walk(STOP_A, D30s)) + .addViaLocations(VIA_LOCATION_STOP_C) + // We allow egress from B, C, and D - if the via search works as expected, only egress from C + // should be used - egress from B has not visited via stop C, and egress from stop D would + // require a transfer at stop C to visit the via stop - this is not an optimal path. + .addEgressPaths(walk(STOP_B, D30s)) + .addEgressPaths(walk(STOP_C, D30s)) + .addEgressPaths(walk(STOP_D, D30s)); + + assertEquals( + PathUtils.join( + "Walk 30s ~ A ~ BUS R1 0:02 0:10 ~ C ~ Walk 30s [0:01:30 0:10:30 9m Tₓ0 C₁1_200]", + "Walk 30s ~ A ~ BUS R1 0:12 0:20 ~ C ~ Walk 30s [0:11:30 0:20:30 9m Tₓ0 C₁1_200]" + ), + pathsToString(raptorService.route(requestBuilder.build(), data)) + ); + } + + @Test + @DisplayName("Multiple via points") + void multipleViaPoints() { + var data = new TestTransitData(); + + // Create two routes. + // The first one includes one via stop point. + // The second one includes the second via point. + // Both arrive at the desired destination, so normally there should not be any transfers. + data.withRoutes( + route("R2", STOP_A, STOP_B, STOP_C, STOP_D, STOP_E, STOP_F) + .withTimetable( + schedule("0:02 0:05 0:10 0:15 0:20 0:25"), + schedule("0:12 0:15 0:20 0:25 0:30 0:35"), + schedule("0:22 0:25 0:30 0:35 0:40 0:45") + ) + ); + + data.withTransferCost(100); + + var requestBuilder = prepareRequest(); + + requestBuilder + .searchParams() + .addAccessPaths(walk(STOP_A, D30s)) + .addViaLocations(VIA_LOCATION_STOP_B_THEN_D) + .addEgressPaths(walk(STOP_F, D30s)); + + // Verify that both via points are included + assertEquals( + "Walk 30s ~ A " + + "~ BUS R2 0:02 0:05 ~ B " + + "~ BUS R2 0:15 0:25 ~ D " + + "~ BUS R2 0:35 0:45 ~ F " + + "~ Walk 30s " + + "[0:01:30 0:45:30 44m Tₓ2 C₁4_700]", + pathsToString(raptorService.route(requestBuilder.build(), data)) + ); + } + + @Test + @DisplayName("Multiple via points works with circular lines, visit stop C than stop B") + void viaSearchWithCircularLine() { + var data = new TestTransitData(); + + data.withRoute( + route("R1", STOP_A, STOP_B, STOP_C, STOP_B, STOP_C, STOP_B, STOP_C, STOP_B, STOP_D) + .withTimetable(schedule("0:05 0:10 0:15 0:20 0:25 0:30 0:35 0:40 0:45")) + ); + + var requestBuilder = prepareRequest(); + + requestBuilder + .searchParams() + .addAccessPaths(walk(STOP_A, D30s)) + .addViaLocations(VIA_LOCATION_STOP_C_THEN_B) + .addEgressPaths(walk(STOP_D, D30s)); + + assertEquals( + "Walk 30s ~ A " + + "~ BUS R1 0:05 0:15 ~ C " + + "~ BUS R1 0:25 0:30 ~ B " + + "~ BUS R1 0:40 0:45 ~ D " + + "~ Walk 30s " + + "[0:04:30 0:45:30 41m Tₓ2 C₁4_320]", + pathsToString(raptorService.route(requestBuilder.build(), data)) + ); + } + + @Test + @DisplayName("Multiple stops in the same via location") + void testViaSearchWithManyStopsInTheViaLocation() { + var data = new TestTransitData(); + + data.withRoutes( + route("R1", STOP_A, STOP_C).withTimetable(schedule("0:04 0:15")), + route("R2", STOP_B, STOP_C).withTimetable(schedule("0:05 0:14")) + ); + + var requestBuilder = prepareRequest(); + + requestBuilder + .searchParams() + .addAccessPaths(walk(STOP_A, D30s)) + .addAccessPaths(walk(STOP_B, D2m)) + .addViaLocations(VIA_LOCATION_STOP_A_OR_B) + .addEgressPaths(walk(STOP_C, D30s)); + + // Both routes are pareto optimal. + // Route 2 is faster, but it contains more walking + // Verify that both routes are included as a valid result + assertEquals( + PathUtils.join( + "Walk 2m ~ B ~ BUS R2 0:05 0:14 ~ C ~ Walk 30s [0:03 0:14:30 11m30s Tₓ0 C₁1_440]", + "Walk 30s ~ A ~ BUS R1 0:04 0:15 ~ C ~ Walk 30s [0:03:30 0:15:30 12m Tₓ0 C₁1_380]" + ), + pathsToString(raptorService.route(requestBuilder.build(), data)) + ); + } + + @Test + @DisplayName("Test minimum wait time") + void testMinWaitTime() { + var data = new TestTransitData(); + data.withRoutes( + route("R1", STOP_A, STOP_B).withTimetable(schedule("0:02:00 0:04:00")), + route("R2", STOP_B, STOP_C) + .withTimetable(schedule("0:05:44 0:10"), schedule("0:05:45 0:11"), schedule("0:05:46 0:12")) + ); + + var requestBuilder = prepareRequest(); + var minWaitTime = Duration.ofSeconds(45); + + requestBuilder + .searchParams() + .addAccessPaths(walk(STOP_A, D30s)) + .addViaLocations(List.of(RaptorViaLocation.via("B", minWaitTime).addViaStop(STOP_B).build())) + .addEgressPaths(walk(STOP_C, D30s)); + + // We expect to bard the second trip at 0:05:45, since the minWaitTime is 45s and the + // transfer slack is 60s. + assertEquals( + "Walk 30s ~ A ~ BUS R1 0:02 0:04 ~ B ~ BUS R2 0:05:45 0:11 ~ C ~ Walk 30s " + + "[0:01:30 0:11:30 10m Tₓ1 C₁1_860]", + pathsToString(raptorService.route(requestBuilder.build(), data)) + ); + } + + private static RaptorViaLocation viaLocation(String label, int... stops) { + var builder = RaptorViaLocation.via(label); + Arrays.stream(stops).forEach(builder::addViaStop); + return builder.build(); + } +} diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java similarity index 90% rename from src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java index f03eb5335a0..4a08634db93 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java @@ -8,7 +8,6 @@ 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 static org.opentripplanner.raptor.moduletests.support.TestGroupPriorityCalculator.GROUP_A; import static org.opentripplanner.raptor.moduletests.support.TestGroupPriorityCalculator.GROUP_B; @@ -19,13 +18,14 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.raptor.RaptorService; import org.opentripplanner.raptor._data.transit.TestTransitData; +import org.opentripplanner.raptor._data.transit.TestTripPattern; import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.raptor.api.request.RaptorProfile; import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; import org.opentripplanner.raptor.api.request.RaptorTransitGroupPriorityCalculator; import org.opentripplanner.raptor.configure.RaptorConfig; import org.opentripplanner.raptor.moduletests.support.TestGroupPriorityCalculator; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; /** * FEATURE UNDER TEST @@ -54,13 +54,13 @@ public class K01_TransitPriorityTest { @BeforeEach private void prepareRequest() { data.withRoutes( - route(pattern("L1", STOP_B, STOP_C).withPriorityGroup(GROUP_A)) + route(TestTripPattern.of("L1", STOP_B, STOP_C).priorityGroup(GROUP_A).build()) .withTimetable(schedule("00:02 00:12")), - route(pattern("U1", STOP_B, STOP_C).withPriorityGroup(GROUP_A)) + route(TestTripPattern.of("U1", STOP_B, STOP_C).priorityGroup(GROUP_A).build()) .withTimetable(schedule("00:02 00:12:01")), - route(pattern("L2", STOP_B, STOP_C).withPriorityGroup(GROUP_B)) + route(TestTripPattern.of("L2", STOP_B, STOP_C).priorityGroup(GROUP_B).build()) .withTimetable(schedule("00:02 00:13")), - route(pattern("L3", STOP_B, STOP_C).withPriorityGroup(GROUP_C)) + route(TestTripPattern.of("L3", STOP_B, STOP_C).priorityGroup(GROUP_C).build()) .withTimetable(schedule("00:02 00:14")) ); diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java similarity index 90% rename from src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java index fb21128728c..e6d1fc38d12 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java @@ -11,7 +11,6 @@ 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 static org.opentripplanner.raptor.moduletests.support.TestGroupPriorityCalculator.GROUP_A; import static org.opentripplanner.raptor.moduletests.support.TestGroupPriorityCalculator.GROUP_B; @@ -22,13 +21,14 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.raptor.RaptorService; import org.opentripplanner.raptor._data.transit.TestTransitData; +import org.opentripplanner.raptor._data.transit.TestTripPattern; import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.raptor.api.request.RaptorProfile; import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; import org.opentripplanner.raptor.api.request.RaptorTransitGroupPriorityCalculator; import org.opentripplanner.raptor.configure.RaptorConfig; import org.opentripplanner.raptor.moduletests.support.TestGroupPriorityCalculator; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; /** * FEATURE UNDER TEST @@ -56,13 +56,13 @@ private void prepareRequest() { // 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)) + route(TestTripPattern.of("L1", STOP_B, STOP_C).priorityGroup(GROUP_A).build()) .withTimetable(schedule("00:02 00:12")), - route(pattern("U1", STOP_B, STOP_D).withPriorityGroup(GROUP_A)) + route(TestTripPattern.of("U1", STOP_B, STOP_D).priorityGroup(GROUP_A).build()) .withTimetable(schedule("00:02 00:12:01")), - route(pattern("L2", STOP_B, STOP_E).withPriorityGroup(GROUP_B)) + route(TestTripPattern.of("L2", STOP_B, STOP_E).priorityGroup(GROUP_B).build()) .withTimetable(schedule("00:02 00:13")), - route(pattern("L3", STOP_B, STOP_F).withPriorityGroup(GROUP_C)) + route(TestTripPattern.of("L3", STOP_B, STOP_F).priorityGroup(GROUP_C).build()) .withTimetable(schedule("00:02 00:14")) ); diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/L01_TimePenaltyAccessTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/L01_TimePenaltyAccessTest.java similarity index 99% rename from src/test/java/org/opentripplanner/raptor/moduletests/L01_TimePenaltyAccessTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/L01_TimePenaltyAccessTest.java index 778dd36a227..a4753cc2c17 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/L01_TimePenaltyAccessTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/L01_TimePenaltyAccessTest.java @@ -1,7 +1,6 @@ package org.opentripplanner.raptor.moduletests; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.time.TimeUtils.time; import static org.opentripplanner.raptor._data.api.PathUtils.withoutCost; import static org.opentripplanner.raptor._data.transit.TestAccessEgress.walk; import static org.opentripplanner.raptor._data.transit.TestRoute.route; @@ -11,6 +10,7 @@ import static org.opentripplanner.raptor.moduletests.support.RaptorModuleTestConfig.TC_STANDARD_REV; import static org.opentripplanner.raptor.moduletests.support.RaptorModuleTestConfig.TC_STANDARD_REV_ONE; import static org.opentripplanner.raptor.moduletests.support.RaptorModuleTestConfig.multiCriteria; +import static org.opentripplanner.utils.time.TimeUtils.time; import java.time.Duration; import java.util.List; diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/L01_TimePenaltyEgressTest.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/L01_TimePenaltyEgressTest.java similarity index 99% rename from src/test/java/org/opentripplanner/raptor/moduletests/L01_TimePenaltyEgressTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/L01_TimePenaltyEgressTest.java index 1e6897475f4..d75b91c7aee 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/L01_TimePenaltyEgressTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/L01_TimePenaltyEgressTest.java @@ -1,7 +1,6 @@ package org.opentripplanner.raptor.moduletests; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.time.TimeUtils.time; import static org.opentripplanner.raptor._data.api.PathUtils.withoutCost; import static org.opentripplanner.raptor._data.transit.TestAccessEgress.walk; import static org.opentripplanner.raptor._data.transit.TestRoute.route; @@ -11,6 +10,7 @@ import static org.opentripplanner.raptor.moduletests.support.RaptorModuleTestConfig.TC_STANDARD_REV; import static org.opentripplanner.raptor.moduletests.support.RaptorModuleTestConfig.TC_STANDARD_REV_ONE; import static org.opentripplanner.raptor.moduletests.support.RaptorModuleTestConfig.multiCriteria; +import static org.opentripplanner.utils.time.TimeUtils.time; import java.time.Duration; import java.util.List; diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/images/F11.svg b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/images/F11.svg similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/images/F11.svg rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/images/F11.svg diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/images/F12.svg b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/images/F12.svg similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/images/F12.svg rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/images/F12.svg diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/images/Samples.excalidraw b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/images/Samples.excalidraw similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/images/Samples.excalidraw rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/images/Samples.excalidraw diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/package-info.md b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/package-info.md similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/package-info.md rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/package-info.md diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/support/ExpectedList.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/ExpectedList.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/support/ExpectedList.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/ExpectedList.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/support/ModuleTestDebugLogging.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/ModuleTestDebugLogging.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/support/ModuleTestDebugLogging.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/ModuleTestDebugLogging.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestCase.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestCase.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestCase.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestCase.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestCaseFactory.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestCaseFactory.java similarity index 97% rename from src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestCaseFactory.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestCaseFactory.java index 0f7554dccab..937acd7fcc4 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestCaseFactory.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestCaseFactory.java @@ -7,10 +7,10 @@ import java.util.Arrays; import java.util.List; import java.util.function.Consumer; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; import org.opentripplanner.raptor.spi.UnknownPath; +import org.opentripplanner.utils.time.DurationUtils; /** * Factory for {@link RaptorModuleTestConfig}, create a list of test-cases. diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestConfig.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestConfig.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestConfig.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestConfig.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestConfigSetBuilder.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestConfigSetBuilder.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestConfigSetBuilder.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/RaptorModuleTestConfigSetBuilder.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/support/TestGroupPriorityCalculator.java b/raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/TestGroupPriorityCalculator.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/moduletests/support/TestGroupPriorityCalculator.java rename to raptor/src/test/java/org/opentripplanner/raptor/moduletests/support/TestGroupPriorityCalculator.java diff --git a/src/test/java/org/opentripplanner/raptor/package-info.md b/raptor/src/test/java/org/opentripplanner/raptor/package-info.md similarity index 100% rename from src/test/java/org/opentripplanner/raptor/package-info.md rename to raptor/src/test/java/org/opentripplanner/raptor/package-info.md diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/context/SearchContextTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/context/SearchContextTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/context/SearchContextTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/context/SearchContextTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/internalapi/NoopPassThroughPointsServiceTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/internalapi/NoopPassThroughPointsServiceTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/internalapi/NoopPassThroughPointsServiceTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/internalapi/NoopPassThroughPointsServiceTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/StopArrivalStateParetoSetTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/StopArrivalStateParetoSetTest.java similarity index 88% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/StopArrivalStateParetoSetTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/StopArrivalStateParetoSetTest.java index e9c39ba6bbf..60fa14e9385 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/StopArrivalStateParetoSetTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/StopArrivalStateParetoSetTest.java @@ -1,8 +1,6 @@ package org.opentripplanner.raptor.rangeraptor.multicriteria; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.raptor.rangeraptor.multicriteria.StopArrivalParetoSet.createEgressStopArrivalSet; -import static org.opentripplanner.raptor.rangeraptor.multicriteria.StopArrivalParetoSet.createStopArrivalSet; import java.util.Arrays; import java.util.List; @@ -20,6 +18,7 @@ import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrival; import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.c1.StopArrivalFactoryC1; import org.opentripplanner.raptor.rangeraptor.multicriteria.ride.c1.PatternRideC1; +import org.opentripplanner.raptor.util.paretoset.ParetoComparator; public class StopArrivalStateParetoSetTest { @@ -33,9 +32,9 @@ public class StopArrivalStateParetoSetTest { .schedule("10:00 10:30") .build(); - // In this test each stop is used to identify the pareto vector - it is just one - // ParetoSet "subject" with multiple "stops" in it. The stop have no effect on - // the Pareto functionality. + // In this test, each stop is used to identify the pareto vector - it is just one + // ParetoSet "subject" with multiple "stops" in it. The stop has no effect on + // the Pareto functionality - the stop is not a criteria in the pareto-function. private static final int STOP_1 = 1; private static final int STOP_2 = 2; private static final int STOP_3 = 3; @@ -72,19 +71,12 @@ public class StopArrivalStateParetoSetTest { ); private static Stream testCases() { + ParetoComparator> comparator = COMPARATOR_FACTORY.compareArrivalTimeRoundAndCost(); return Stream.of( - Arguments.of( - "Stop Arrival - regular", - createStopArrivalSet(COMPARATOR_FACTORY.compareArrivalTimeRoundAndCost(), null) - ), + Arguments.of("Stop Arrival - regular", StopArrivalParetoSet.of(comparator).build()), Arguments.of( "Stop Arrival - w/egress", - createEgressStopArrivalSet( - COMPARATOR_FACTORY.compareArrivalTimeRoundCostAndOnBoardArrival(), - List.of(), - null, - null - ) + StopArrivalParetoSet.of(comparator).withEgressListener(List.of(), null).build() ) ); } @@ -169,7 +161,8 @@ public void testRoundAndTimeDominance( */ @Test public void testTransitAndTransferDoesNotAffectDominance() { - var subject = createStopArrivalSet(COMPARATOR_FACTORY.compareArrivalTimeRoundAndCost(), null); + ParetoComparator> comparator = COMPARATOR_FACTORY.compareArrivalTimeRoundAndCost(); + var subject = StopArrivalParetoSet.of(comparator).build(); subject.add(newAccessStopState(STOP_1, 20, ANY)); subject.add(newTransitStopState(ROUND_1, STOP_2, 10, ANY)); subject.add(newTransferStopState(ROUND_1, STOP_4, 8, ANY)); @@ -184,12 +177,10 @@ public void testTransitAndTransferDoesNotAffectDominance() { */ @Test public void testTransitAndTransferDoesAffectDominanceForStopArrivalsWithEgress() { - var subject = createEgressStopArrivalSet( - COMPARATOR_FACTORY.compareArrivalTimeRoundCostAndOnBoardArrival(), - List.of(), - null, - null - ); + var subject = StopArrivalParetoSet + .of(COMPARATOR_FACTORY.compareArrivalTimeRoundCostAndOnBoardArrival()) + .withEgressListener(List.of(), null) + .build(); subject.add(newAccessStopState(STOP_1, 20, ANY)); subject.add(newTransitStopState(ROUND_1, STOP_2, 10, ANY)); subject.add(newTransferStopState(ROUND_1, STOP_4, 8, ANY)); diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/ArrivalParetoSetComparatorFactoryTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/ArrivalParetoSetComparatorFactoryTest.java similarity index 98% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/ArrivalParetoSetComparatorFactoryTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/ArrivalParetoSetComparatorFactoryTest.java index 9b6311b58bc..5fd19fc07f5 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/ArrivalParetoSetComparatorFactoryTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/ArrivalParetoSetComparatorFactoryTest.java @@ -305,5 +305,10 @@ public PathLegType arrivedBy() { public boolean arrivedOnBoard() { return arrivedOnBoard; } + + @Override + public McStopArrival addSlackToArrivalTime(int slack) { + throw new UnsupportedOperationException(); + } } } diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrivalTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrivalTest.java similarity index 97% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrivalTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrivalTest.java index 64593a91b2a..9cbb35ca0a6 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrivalTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/McStopArrivalTest.java @@ -149,5 +149,10 @@ public PathLegType arrivedBy() { public boolean arrivedOnBoard() { return arrivedOnBoard; } + + @Override + public McStopArrival addSlackToArrivalTime(int slack) { + throw new UnsupportedOperationException(); + } } } diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/AccessStopArrivalTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/AccessStopArrivalTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/AccessStopArrivalTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/AccessStopArrivalTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/StopArrivalFactoryC1Test.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/StopArrivalFactoryC1Test.java similarity index 97% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/StopArrivalFactoryC1Test.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/StopArrivalFactoryC1Test.java index d47edf1c58f..4d18cde5232 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/StopArrivalFactoryC1Test.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/StopArrivalFactoryC1Test.java @@ -3,8 +3,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor._data.transit.TestAccessEgress; import org.opentripplanner.raptor._data.transit.TestTransfer; import org.opentripplanner.raptor._data.transit.TestTripPattern; @@ -13,6 +11,8 @@ import org.opentripplanner.raptor.api.view.PatternRideView; import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrival; import org.opentripplanner.raptor.rangeraptor.multicriteria.ride.c1.PatternRideC1; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; public class StopArrivalFactoryC1Test { diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransferStopArrivalTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransferStopArrivalTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransferStopArrivalTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransferStopArrivalTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransitStopArrivalTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransitStopArrivalTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransitStopArrivalTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c1/TransitStopArrivalTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/AccessStopArrivalC2Test.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/AccessStopArrivalC2Test.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/AccessStopArrivalC2Test.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/AccessStopArrivalC2Test.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/StopArrivalFactoryC2Test.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/StopArrivalFactoryC2Test.java similarity index 97% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/StopArrivalFactoryC2Test.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/StopArrivalFactoryC2Test.java index 4c78461b016..c71ca7fee11 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/StopArrivalFactoryC2Test.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/StopArrivalFactoryC2Test.java @@ -3,8 +3,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor._data.transit.TestAccessEgress; import org.opentripplanner.raptor._data.transit.TestTransfer; import org.opentripplanner.raptor._data.transit.TestTripPattern; @@ -13,6 +11,8 @@ import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrival; import org.opentripplanner.raptor.rangeraptor.multicriteria.ride.c2.PatternRideC2; import org.opentripplanner.raptor.spi.RaptorCostCalculator; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; public class StopArrivalFactoryC2Test { diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransferStopArrivalC2Test.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransferStopArrivalC2Test.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransferStopArrivalC2Test.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransferStopArrivalC2Test.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransitStopArrivalC2Test.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransitStopArrivalC2Test.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransitStopArrivalC2Test.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/arrivals/c2/TransitStopArrivalC2Test.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/passthrough/BitSetPassThroughPointsServiceTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/passthrough/BitSetPassThroughPointsServiceTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/passthrough/BitSetPassThroughPointsServiceTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/passthrough/BitSetPassThroughPointsServiceTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c1/PatternRideC1Test.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c1/PatternRideC1Test.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c1/PatternRideC1Test.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c1/PatternRideC1Test.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PatternRideC2Test.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PatternRideC2Test.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PatternRideC2Test.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/PatternRideC2Test.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/path/DestinationArrivalTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/path/DestinationArrivalTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/path/DestinationArrivalTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/path/DestinationArrivalTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathMapperTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathMapperTest.java similarity index 69% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathMapperTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathMapperTest.java index bac2c1b0431..027d3d5852a 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathMapperTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathMapperTest.java @@ -1,38 +1,38 @@ package org.opentripplanner.raptor.rangeraptor.path; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.raptor._data.stoparrival.AccessAndEgressWithOpeningHoursPathTestCase.flexCaseAForwardSearch; +import static org.opentripplanner.raptor._data.stoparrival.AccessAndEgressWithOpeningHoursPathTestCase.flexCaseAReverseSearch; +import static org.opentripplanner.raptor._data.stoparrival.AccessAndEgressWithOpeningHoursPathTestCase.flexCaseAText; +import static org.opentripplanner.raptor._data.stoparrival.AccessAndEgressWithOpeningHoursPathTestCase.flexCaseAWithOpeningHoursForwardSearch; +import static org.opentripplanner.raptor._data.stoparrival.AccessAndEgressWithOpeningHoursPathTestCase.flexCaseAWithOpeningHoursReverseSearch; +import static org.opentripplanner.raptor._data.stoparrival.AccessAndEgressWithOpeningHoursPathTestCase.flexCaseAWithOpeningHoursText; +import static org.opentripplanner.raptor._data.stoparrival.AccessAndEgressWithOpeningHoursPathTestCase.flexCaseBForwardSearch; +import static org.opentripplanner.raptor._data.stoparrival.AccessAndEgressWithOpeningHoursPathTestCase.flexCaseBReverseSearch; +import static org.opentripplanner.raptor._data.stoparrival.AccessAndEgressWithOpeningHoursPathTestCase.flexCaseBText; +import static org.opentripplanner.raptor._data.stoparrival.AccessAndEgressWithOpeningHoursPathTestCase.flexCaseBWithOpeningHoursForwardSearch; +import static org.opentripplanner.raptor._data.stoparrival.AccessAndEgressWithOpeningHoursPathTestCase.flexCaseBWithOpeningHoursReverseSearch; +import static org.opentripplanner.raptor._data.stoparrival.AccessAndEgressWithOpeningHoursPathTestCase.flexCaseBWithOpeningHoursText; import static org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase.BASIC_PATH_AS_DETAILED_STRING; import static org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase.C1_CALCULATOR; import static org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase.basicTripByForwardSearch; import static org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase.basicTripByReverseSearch; import static org.opentripplanner.raptor._data.stoparrival.BasicPathTestCase.lifeCycle; -import static org.opentripplanner.raptor._data.stoparrival.FlexAccessAndEgressPathTestCase.flexCaseAForwardSearch; -import static org.opentripplanner.raptor._data.stoparrival.FlexAccessAndEgressPathTestCase.flexCaseAReverseSearch; -import static org.opentripplanner.raptor._data.stoparrival.FlexAccessAndEgressPathTestCase.flexCaseAText; -import static org.opentripplanner.raptor._data.stoparrival.FlexAccessAndEgressPathTestCase.flexCaseAWithOpeningHoursForwardSearch; -import static org.opentripplanner.raptor._data.stoparrival.FlexAccessAndEgressPathTestCase.flexCaseAWithOpeningHoursReverseSearch; -import static org.opentripplanner.raptor._data.stoparrival.FlexAccessAndEgressPathTestCase.flexCaseAWithOpeningHoursText; -import static org.opentripplanner.raptor._data.stoparrival.FlexAccessAndEgressPathTestCase.flexCaseBForwardSearch; -import static org.opentripplanner.raptor._data.stoparrival.FlexAccessAndEgressPathTestCase.flexCaseBReverseSearch; -import static org.opentripplanner.raptor._data.stoparrival.FlexAccessAndEgressPathTestCase.flexCaseBText; -import static org.opentripplanner.raptor._data.stoparrival.FlexAccessAndEgressPathTestCase.flexCaseBWithOpeningHoursForwardSearch; -import static org.opentripplanner.raptor._data.stoparrival.FlexAccessAndEgressPathTestCase.flexCaseBWithOpeningHoursReverseSearch; -import static org.opentripplanner.raptor._data.stoparrival.FlexAccessAndEgressPathTestCase.flexCaseBWithOpeningHoursText; import org.junit.jupiter.api.Test; import org.opentripplanner.raptor._data.RaptorTestConstants; -import org.opentripplanner.raptor._data.stoparrival.FlexAccessAndEgressPathTestCase; +import org.opentripplanner.raptor._data.stoparrival.AccessAndEgressWithOpeningHoursPathTestCase; +import org.opentripplanner.raptor._data.transit.TestCostCalculator; import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.path.RaptorPath; import org.opentripplanner.raptor.spi.RaptorSlackProvider; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.DefaultCostCalculator; public class PathMapperTest implements RaptorTestConstants { private static final RaptorSlackProvider FLEX_SLACK_PROVIDER = - FlexAccessAndEgressPathTestCase.SLACK_PROVIDER; - private static final DefaultCostCalculator FLEX_COST_CALCULATOR = - FlexAccessAndEgressPathTestCase.C1_CALCULATOR; + AccessAndEgressWithOpeningHoursPathTestCase.SLACK_PROVIDER; + private static final TestCostCalculator FLEX_COST_CALCULATOR = + AccessAndEgressWithOpeningHoursPathTestCase.C1_CALCULATOR; /* BASIC CASES */ diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparatorsTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparatorsTest.java similarity index 99% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparatorsTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparatorsTest.java index 296103499a1..00558b6f63d 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparatorsTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparatorsTest.java @@ -21,7 +21,6 @@ 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.rangeraptor.internalapi.ParetoSetCost; import org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime; diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/SimpleArrivedAtDestinationCheckTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/SimpleArrivedAtDestinationCheckTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/SimpleArrivedAtDestinationCheckTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/standard/besttimes/SimpleArrivedAtDestinationCheckTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/support/IntArraySingleCriteriaArrivalsTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/support/IntArraySingleCriteriaArrivalsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/support/IntArraySingleCriteriaArrivalsTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/support/IntArraySingleCriteriaArrivalsTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctionsTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctionsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctionsTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctionsTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPathsTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPathsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPathsTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPathsTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessWithPenaltyTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessWithPenaltyTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessWithPenaltyTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessWithPenaltyTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPathsTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPathsTest.java similarity index 98% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPathsTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPathsTest.java index 144904fa3e6..3939bbb865f 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPathsTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPathsTest.java @@ -10,9 +10,9 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.request.RaptorProfile; +import org.opentripplanner.utils.time.DurationUtils; class EgressPathsTest { diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/EgressWithPenaltyTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/EgressWithPenaltyTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/EgressWithPenaltyTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/EgressWithPenaltyTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculatorTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculatorTest.java similarity index 98% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculatorTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculatorTest.java index ad7a269b856..bf1999d88fc 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculatorTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardRaptorTransitCalculatorTest.java @@ -3,10 +3,10 @@ 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.framework.time.TimeUtils.hm2time; import static org.opentripplanner.raptor._data.RaptorTestConstants.D1m; import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_A; import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_B; +import static org.opentripplanner.utils.time.TimeUtils.hm2time; import org.junit.jupiter.api.Test; import org.opentripplanner.raptor._data.transit.TestAccessEgress; diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTimeCalculatorTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTimeCalculatorTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTimeCalculatorTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTimeCalculatorTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTransitCalculatorTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTransitCalculatorTest.java similarity index 98% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTransitCalculatorTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTransitCalculatorTest.java index 10f5e18875b..5fb1cb5fade 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTransitCalculatorTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ForwardTransitCalculatorTest.java @@ -1,11 +1,11 @@ package org.opentripplanner.raptor.rangeraptor.transit; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.time.TimeUtils.hm2time; import static org.opentripplanner.raptor._data.transit.TestAccessEgress.flex; import static org.opentripplanner.raptor._data.transit.TestAccessEgress.flexAndWalk; import static org.opentripplanner.raptor._data.transit.TestAccessEgress.free; import static org.opentripplanner.raptor._data.transit.TestAccessEgress.walk; +import static org.opentripplanner.utils.time.TimeUtils.hm2time; import org.junit.jupiter.api.Test; import org.opentripplanner.raptor._data.RaptorTestConstants; diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorSearchWindowCalculatorTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorSearchWindowCalculatorTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorSearchWindowCalculatorTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/RaptorSearchWindowCalculatorTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculatorTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculatorTest.java similarity index 97% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculatorTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculatorTest.java index 3afecaf3e81..981fb058f9b 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculatorTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseRaptorTransitCalculatorTest.java @@ -3,10 +3,10 @@ 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.framework.time.TimeUtils.hm2time; import static org.opentripplanner.raptor._data.RaptorTestConstants.D1m; import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_A; import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_B; +import static org.opentripplanner.utils.time.TimeUtils.hm2time; import org.junit.jupiter.api.Test; import org.opentripplanner.raptor._data.transit.TestTransfer; diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTimeCalculatorTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTimeCalculatorTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTimeCalculatorTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTimeCalculatorTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTransitCalculatorTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTransitCalculatorTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTransitCalculatorTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/ReverseTransitCalculatorTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/RoundTrackerTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/RoundTrackerTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/RoundTrackerTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/RoundTrackerTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/SlackProviderAdapterTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/SlackProviderAdapterTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/SlackProviderAdapterTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/SlackProviderAdapterTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/TripScheduleExactMatchSearchTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/TripScheduleExactMatchSearchTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/TripScheduleExactMatchSearchTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/TripScheduleExactMatchSearchTest.java diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/TripTimesSearchTest.java b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/TripTimesSearchTest.java similarity index 98% rename from src/test/java/org/opentripplanner/raptor/rangeraptor/transit/TripTimesSearchTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/TripTimesSearchTest.java index 50295b0341e..d70f58fd1c5 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/TripTimesSearchTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/TripTimesSearchTest.java @@ -2,7 +2,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.opentripplanner.framework.time.TimeUtils.timeToStrLong; import static org.opentripplanner.raptor._data.stoparrival.TestArrivals.access; import static org.opentripplanner.raptor._data.stoparrival.TestArrivals.bus; import static org.opentripplanner.raptor._data.transit.TestAccessEgress.free; @@ -11,13 +10,14 @@ import static org.opentripplanner.raptor.rangeraptor.transit.TripTimesSearch.findTripForwardSearchApproximateTime; import static org.opentripplanner.raptor.rangeraptor.transit.TripTimesSearch.findTripReverseSearch; import static org.opentripplanner.raptor.rangeraptor.transit.TripTimesSearch.findTripReverseSearchApproximateTime; +import static org.opentripplanner.utils.time.TimeUtils.timeToStrLong; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor._data.RaptorTestConstants; import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.view.ArrivalView; import org.opentripplanner.raptor.spi.BoardAndAlightTime; +import org.opentripplanner.utils.time.TimeUtils; public class TripTimesSearchTest implements RaptorTestConstants { diff --git a/src/test/java/org/opentripplanner/raptor/service/HeuristicToRunResolverTest.java b/raptor/src/test/java/org/opentripplanner/raptor/service/HeuristicToRunResolverTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/service/HeuristicToRunResolverTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/service/HeuristicToRunResolverTest.java diff --git a/src/test/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEventTest.java b/raptor/src/test/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEventTest.java similarity index 87% rename from src/test/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEventTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEventTest.java index 0ae5a09aa18..76c05386f18 100644 --- a/src/test/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEventTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/spi/EmptyBoardOrAlightEventTest.java @@ -15,6 +15,6 @@ void testEmptyBoardOrAlightEvent() { assertTrue(subject.empty()); assertEquals(300, subject.earliestBoardTime()); assertEquals(RaptorTransferConstraint.REGULAR_TRANSFER, subject.transferConstraint()); - assertEquals("EmptyBoardOrAlightEvent[earliestBoardTime=300]", subject.toString()); + assertEquals("EmptyBoardOrAlightEvent(00:05:00)", subject.toString()); } } diff --git a/src/test/java/org/opentripplanner/raptor/spi/RaptorSlackProviderTest.java b/raptor/src/test/java/org/opentripplanner/raptor/spi/RaptorSlackProviderTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/spi/RaptorSlackProviderTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/spi/RaptorSlackProviderTest.java diff --git a/src/test/java/org/opentripplanner/raptor/spi/RaptorTripPatternTest.java b/raptor/src/test/java/org/opentripplanner/raptor/spi/RaptorTripPatternTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/spi/RaptorTripPatternTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/spi/RaptorTripPatternTest.java diff --git a/src/test/java/org/opentripplanner/raptor/spi/RaptorTripScheduleTest.java b/raptor/src/test/java/org/opentripplanner/raptor/spi/RaptorTripScheduleTest.java similarity index 95% rename from src/test/java/org/opentripplanner/raptor/spi/RaptorTripScheduleTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/spi/RaptorTripScheduleTest.java index 6b4392a13a9..9188617016a 100644 --- a/src/test/java/org/opentripplanner/raptor/spi/RaptorTripScheduleTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/spi/RaptorTripScheduleTest.java @@ -1,7 +1,7 @@ package org.opentripplanner.raptor.spi; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.time.TimeUtils.timeToStrLong; +import static org.opentripplanner.utils.time.TimeUtils.timeToStrLong; import org.junit.jupiter.api.Test; import org.opentripplanner.raptor._data.transit.TestTripPattern; diff --git a/src/test/java/org/opentripplanner/raptor/spi/UnknownPathTest.java b/raptor/src/test/java/org/opentripplanner/raptor/spi/UnknownPathTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/spi/UnknownPathTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/spi/UnknownPathTest.java diff --git a/src/test/java/org/opentripplanner/raptor/util/BitSetIteratorTest.java b/raptor/src/test/java/org/opentripplanner/raptor/util/BitSetIteratorTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/util/BitSetIteratorTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/util/BitSetIteratorTest.java diff --git a/src/test/java/org/opentripplanner/raptor/util/IntIteratorsTest.java b/raptor/src/test/java/org/opentripplanner/raptor/util/IntIteratorsTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/util/IntIteratorsTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/util/IntIteratorsTest.java diff --git a/src/test/java/org/opentripplanner/raptor/util/PathStringBuilderTest.java b/raptor/src/test/java/org/opentripplanner/raptor/util/PathStringBuilderTest.java similarity index 97% rename from src/test/java/org/opentripplanner/raptor/util/PathStringBuilderTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/util/PathStringBuilderTest.java index 771efe6ab03..1179712e2fd 100644 --- a/src/test/java/org/opentripplanner/raptor/util/PathStringBuilderTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/util/PathStringBuilderTest.java @@ -5,8 +5,8 @@ import static org.opentripplanner.raptor._data.transit.TestAccessEgress.free; import org.junit.jupiter.api.Test; +import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.path.PathStringBuilder; -import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; public class PathStringBuilderTest { diff --git a/raptor/src/test/java/org/opentripplanner/raptor/util/composite/CompositeUtilTest.java b/raptor/src/test/java/org/opentripplanner/raptor/util/composite/CompositeUtilTest.java new file mode 100644 index 00000000000..6de1f8b842d --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/util/composite/CompositeUtilTest.java @@ -0,0 +1,76 @@ +package org.opentripplanner.raptor.util.composite; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.util.List; +import java.util.stream.Collectors; +import org.junit.jupiter.api.Test; + +class CompositeUtilTest { + + @Test + void testOf() { + TNamed EMPTY = null; + assertNull(composite(EMPTY)); + assertNull(composite(EMPTY, EMPTY)); + + assertEquals("A", composite(tnamed("A")).name()); + assertEquals("A", composite(EMPTY, tnamed("A"), EMPTY).name()); + assertEquals("(A:B)", composite(tnamed("A"), tnamed("B")).name()); + // Nested composites are flattened into one composite + assertEquals( + "(A:B:C)", + composite(composite(tnamed("A")), composite(tnamed("B")), composite(tnamed("C"))).name() + ); + } + + TNamed composite(TNamed... children) { + return TNamedComposite.of(children); + } + + TNamed tnamed(String name) { + return new DefaultTNamed(name); + } + + interface TNamed { + String name(); + } + + static final class DefaultTNamed implements TNamed { + + private final String name; + + public DefaultTNamed(String name) { + this.name = name; + } + + @Override + public String name() { + return name; + } + } + + static final class TNamedComposite implements TNamed { + + private final List children; + + private TNamedComposite(List children) { + this.children = children; + } + + static TNamed of(TNamed... children) { + return CompositeUtil.of( + TNamedComposite::new, + TNamedComposite.class::isInstance, + it -> ((TNamedComposite) it).children, + children + ); + } + + @Override + public String name() { + return "(" + children.stream().map(TNamed::name).collect(Collectors.joining(":")) + ")"; + } + } +} diff --git a/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerCompositeTest.java b/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerCompositeTest.java new file mode 100644 index 00000000000..3fe05f80afd --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerCompositeTest.java @@ -0,0 +1,63 @@ +package org.opentripplanner.raptor.util.paretoset; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.Test; + +class ParetoSetEventListenerCompositeTest { + + public static final String EMPTY = ""; + private final TestParetoSetEventListener l1 = new TestParetoSetEventListener<>(); + private final TestParetoSetEventListener l2 = new TestParetoSetEventListener<>(); + private final ParetoSetEventListener subject = ParetoSetEventListenerComposite.of(l1, l2); + + @Test + void notifyElementAccepted() { + assertNotNull(subject); + subject.notifyElementAccepted("A"); + assertState("A", EMPTY, EMPTY); + subject.notifyElementAccepted("B"); + assertState("A B", EMPTY, EMPTY); + } + + @Test + void notifyElementDropped() { + assertNotNull(subject); + subject.notifyElementDropped("A", "x"); + assertState(EMPTY, "A", EMPTY); + subject.notifyElementDropped("C", "y"); + assertState(EMPTY, "A C", EMPTY); + } + + @Test + void notifyElementRejected() { + assertNotNull(subject); + subject.notifyElementRejected("A", "x"); + assertState(EMPTY, EMPTY, "A"); + subject.notifyElementRejected("C", "y"); + assertState(EMPTY, EMPTY, "A C"); + } + + @Test + void verifyTheListenerStructureIsFlattenOut() { + assertNotNull(subject); + assertEquals( + subject.toString(), + "ParetoSetEventListenerComposite{listeners=[" + + "TestParetoSetEventListener, TestParetoSetEventListener" + + "]}" + ); + } + + private void assertState(String accepted, String dropped, String rejected) { + assertEquals(l1.acceptedAsString(), accepted); + assertEquals(l2.acceptedAsString(), accepted); + + assertEquals(l1.droppedAsString(), dropped); + assertEquals(l2.droppedAsString(), dropped); + + assertEquals(l1.rejectedAsString(), rejected); + assertEquals(l2.rejectedAsString(), rejected); + } +} diff --git a/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerTest.java b/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerTest.java similarity index 54% rename from src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerTest.java index 1843d2c18ba..0f23144efc6 100644 --- a/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetEventListenerTest.java @@ -2,7 +2,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import org.junit.jupiter.api.BeforeEach; @@ -10,22 +9,20 @@ public class ParetoSetEventListenerTest { - private final List accepted = new ArrayList<>(); - private final List rejected = new ArrayList<>(); - private final List dropped = new ArrayList<>(); - // Given a set and function + private final TestParetoSetEventListener listener = new TestParetoSetEventListener(); + @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") - private final ParetoSet subject = new ParetoSet<>( + private final ParetoSet subject = new ParetoSet<>( (l, r) -> l.v1 < r.v1 || l.v2 < r.v2, - eventListener() + listener ); @BeforeEach public void setup() { subject.clear(); - clearResult(); + listener.clear(); } @Test @@ -43,7 +40,7 @@ public void testAccept() { public void testReject() { // Add a initial value subject.add(vector(5, 1)); - clearResult(); + listener.clear(); // Add another value -> expect rejected subject.add(vector(6, 2)); @@ -56,7 +53,7 @@ public void testDropped() { subject.add(vector(2, 5)); subject.add(vector(4, 4)); subject.add(vector(5, 3)); - clearResult(); + listener.clear(); // Add another value -> expect rejected subject.add(vector(1, 5)); @@ -66,14 +63,8 @@ public void testDropped() { assertAcceptedRejectedAndDropped("[1, 0]", "", "[4, 4] [5, 3] [1, 5]"); } - private Vector vector(int u, int v) { - return new Vector("", u, v); - } - - private void clearResult() { - accepted.clear(); - rejected.clear(); - dropped.clear(); + private TestVector vector(int u, int v) { + return new TestVector("", u, v); } private void assertAcceptedRejectedAndDropped( @@ -81,32 +72,17 @@ private void assertAcceptedRejectedAndDropped( String expRejected, String expDropped ) { - assertEquals(expAccepted, toString(accepted)); - assertEquals(expRejected, toString(rejected)); - assertEquals(expDropped, toString(dropped)); - clearResult(); + assertEquals(expAccepted, listener.acceptedAsString()); + assertEquals(expRejected, listener.rejectedAsString()); + assertEquals(expDropped, listener.droppedAsString()); + listener.clear(); } - private String toString(List list) { - return list.stream().map(Vector::toString).collect(Collectors.joining(" ")); + private String toString(List list) { + return list.stream().map(TestVector::toString).collect(Collectors.joining(" ")); } - private ParetoSetEventListener eventListener() { - return new ParetoSetEventListener<>() { - @Override - public void notifyElementAccepted(Vector newElement) { - accepted.add(newElement); - } - - @Override - public void notifyElementDropped(Vector element, Vector droppedByElement) { - dropped.add(element); - } - - @Override - public void notifyElementRejected(Vector element, Vector rejectedByElement) { - rejected.add(element); - } - }; + private TestParetoSetEventListener eventListener() { + return new TestParetoSetEventListener<>(); } } diff --git a/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetTest.java b/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetTest.java similarity index 72% rename from src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetTest.java index 21f998b4757..5f2d56cfcdd 100644 --- a/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetTest.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetTest.java @@ -12,33 +12,33 @@ import java.util.stream.Collectors; import java.util.stream.StreamSupport; import org.junit.jupiter.api.Test; -import org.opentripplanner.framework.lang.IntUtils; +import org.opentripplanner.utils.lang.IntUtils; public class ParetoSetTest { - private static final ParetoComparator DIFFERENT = (l, r) -> l.v1 != r.v1; - private static final ParetoComparator LESS_THEN = (l, r) -> l.v1 < r.v1; - private static final ParetoComparator LESS_LESS_THEN = (l, r) -> + private static final ParetoComparator DIFFERENT = (l, r) -> l.v1 != r.v1; + private static final ParetoComparator LESS_THEN = (l, r) -> l.v1 < r.v1; + private static final ParetoComparator LESS_LESS_THEN = (l, r) -> l.v1 < r.v1 || l.v2 < r.v2; - private static final ParetoComparator LESS_DIFFERENT_THEN = (l, r) -> + private static final ParetoComparator LESS_DIFFERENT_THEN = (l, r) -> l.v1 < r.v1 || l.v2 != r.v2; // Used to stored dropped vectors (callback from set) - private final List dropped = new ArrayList<>(); + private final List dropped = new ArrayList<>(); - private final ParetoSetEventListener listener = new ParetoSetEventListener<>() { + private final ParetoSetEventListener listener = new ParetoSetEventListener<>() { @Override - public void notifyElementAccepted(Vector newElement) { + public void notifyElementAccepted(TestVector newElement) { /* NOOP */ } @Override - public void notifyElementDropped(Vector element, Vector droppedByElement) { + public void notifyElementDropped(TestVector element, TestVector droppedByElement) { dropped.add(element); } @Override - public void notifyElementRejected(Vector element, Vector rejectedByElement) { + public void notifyElementRejected(TestVector element, TestVector rejectedByElement) { /* NOOP */ } }; @@ -46,7 +46,7 @@ public void notifyElementRejected(Vector element, Vector rejectedByElement) { @Test public void initiallyEmpty() { // Given a empty set - ParetoSet set = new ParetoSet<>(LESS_THEN); + ParetoSet set = new ParetoSet<>(LESS_THEN); assertEquals("{}", set.toString(), "The initial set should be empty."); assertTrue(set.isEmpty(), "The initial set should be empty."); @@ -54,14 +54,14 @@ public void initiallyEmpty() { @Test public void addVector() { - ParetoSet set = new ParetoSet<>((l, r) -> + ParetoSet set = new ParetoSet<>((l, r) -> l.v1 < r.v1 || // less than l.v2 != r.v2 || // different dominates l.v3 + 2 < r.v3 // at least 2 less than ); // When one element is added - addOk(set, new Vector("V0", 5, 5, 5)); + addOk(set, new TestVector("V0", 5, 5, 5)); // Then the element should be the only element in the set assertEquals("{V0[5, 5, 5]}", set.toString()); @@ -73,8 +73,8 @@ public void addVector() { @Test public void removeAVectorIsNotAllowed() { // Given a set with a vector - ParetoSet set = new ParetoSet<>(LESS_THEN); - Vector vector = new Vector("V0", 5); + ParetoSet set = new ParetoSet<>(LESS_THEN); + TestVector vector = new TestVector("V0", 5); addOk(set, vector); // When vector is removed, expect an exception @@ -84,23 +84,23 @@ public void removeAVectorIsNotAllowed() { @Test public void testLessThen() { // Given a set with one element: [5] - ParetoSet set = new ParetoSet<>(LESS_THEN); - set.add(new Vector("V0", 5)); + ParetoSet set = new ParetoSet<>(LESS_THEN); + set.add(new TestVector("V0", 5)); // When adding the same value - addRejected(set, new Vector("Not", 5)); + addRejected(set, new TestVector("Not", 5)); // Then expect no change in the set assertEquals("{V0[5]}", set.toString()); // When adding a greater value - addRejected(set, new Vector("Not", 6)); + addRejected(set, new TestVector("Not", 6)); // Then expect no change in the set assertEquals("{V0[5]}", set.toString()); // When adding the a lesser value - addOk(set, new Vector("V1", 4)); + addOk(set, new TestVector("V1", 4)); // Then the lesser value should replace the bigger one assertEquals("{V1[4]}", set.toString()); @@ -109,23 +109,23 @@ public void testLessThen() { @Test public void testDifferent() { // Given a set with one element: [5] - ParetoSet set = new ParetoSet<>(DIFFERENT); - set.add(new Vector("V0", 5)); + ParetoSet set = new ParetoSet<>(DIFFERENT); + set.add(new TestVector("V0", 5)); // When adding the same value - addRejected(set, new Vector("NOT ADDED", 5)); + addRejected(set, new TestVector("NOT ADDED", 5)); // Then expect no change in the set assertEquals("{V0[5]}", set.toString()); // When adding the a different value - addOk(set, new Vector("D1", 6)); + addOk(set, new TestVector("D1", 6)); // Then both values should be included assertEquals("{V0[5], D1[6]}", set.toString()); // When adding the several more different values - addOk(set, new Vector("D2", 3)); - addOk(set, new Vector("D3", 4)); - addOk(set, new Vector("D4", 8)); + addOk(set, new TestVector("D2", 3)); + addOk(set, new TestVector("D3", 4)); + addOk(set, new TestVector("D4", 8)); // Then all values should be included assertEquals("{V0[5], D1[6], D2[3], D3[4], D4[8]}", set.toString()); } @@ -134,8 +134,8 @@ public void testDifferent() { public void testTwoCriteriaWithLessThen() { // Given a set with one element with 2 criteria: [5, 5] // and a function where at least one value is less then to make it into the set - ParetoSet set = new ParetoSet<>(LESS_LESS_THEN); - Vector v0 = new Vector("V0", 5, 5); + ParetoSet set = new ParetoSet<>(LESS_LESS_THEN); + TestVector v0 = new TestVector("V0", 5, 5); // Cases that does NOT make it into the set testNotAdded(set, v0, vector(6, 5), "Add a new vector where 1st value disqualifies it"); @@ -154,8 +154,8 @@ public void testTwoCriteriaWithLessThen() { @Test public void testTwoCriteria_lessThen_and_different() { // Given a set with one element with 2 criteria: [5, 5] - ParetoSet set = new ParetoSet<>(LESS_DIFFERENT_THEN); - Vector v0 = new Vector("V0", 5, 5); + ParetoSet set = new ParetoSet<>(LESS_DIFFERENT_THEN); + TestVector v0 = new TestVector("V0", 5, 5); // Cases that does NOT make it into the set testNotAdded(set, v0, vector(6, 5), "1st value disqualifies it"); @@ -173,8 +173,8 @@ public void testTwoCriteria_lessThen_and_different() { @Test public void testTwoCriteria_lessThen_and_lessThenValue() { // Given a set with one element with 2 criteria: [5, 5] - ParetoSet set = new ParetoSet<>((l, r) -> l.v1 < r.v1 || l.v2 < r.v2 + 1); - Vector v0 = new Vector("V0", 5, 5); + ParetoSet set = new ParetoSet<>((l, r) -> l.v1 < r.v1 || l.v2 < r.v2 + 1); + TestVector v0 = new TestVector("V0", 5, 5); // Cases that does NOT make it into the set testNotAdded(set, v0, vector(6, 6), "1st value is to big"); @@ -194,25 +194,25 @@ public void testTwoCriteria_lessThen_and_lessThenValue() { @Test public void testOneVectorDominatesMany() { // Given a set and function - ParetoSet set = new ParetoSet<>(LESS_LESS_THEN); + ParetoSet set = new ParetoSet<>(LESS_LESS_THEN); // Add some values - all pareto optimal - set.add(new Vector("V0", 5, 1)); - set.add(new Vector("V1", 3, 3)); - set.add(new Vector("V2", 0, 7)); - set.add(new Vector("V3", 1, 5)); + set.add(new TestVector("V0", 5, 1)); + set.add(new TestVector("V1", 3, 3)); + set.add(new TestVector("V2", 0, 7)); + set.add(new TestVector("V3", 1, 5)); // Assert all vectors is there assertEquals("{V0[5, 1], V1[3, 3], V2[0, 7], V3[1, 5]}", set.toString()); // Add a vector which dominates all vectors in set, except [0, 7] - set.add(new Vector("V", 1, 1)); + set.add(new TestVector("V", 1, 1)); // Expect just 2 vectors assertEquals("{V2[0, 7], V[1, 1]}", set.toString()); // Add a vector which dominates all vectors in set - set.add(new Vector("X", 0, 1)); + set.add(new TestVector("X", 0, 1)); // Expect just 1 vector - the last assertEquals("{X[0, 1]}", set.toString()); @@ -221,19 +221,19 @@ public void testOneVectorDominatesMany() { @Test public void testRelaxedCriteriaAcceptingTheTwoSmallestValues() { // Given a set and function - ParetoSet set = new ParetoSet<>((l, r) -> l.v1 < r.v1 || l.v2 < r.v2 + 2); + ParetoSet set = new ParetoSet<>((l, r) -> l.v1 < r.v1 || l.v2 < r.v2 + 2); // Add some values - set.add(new Vector("V0", 5, 5)); - set.add(new Vector("V1", 4, 4)); - set.add(new Vector("V2", 5, 4)); - set.add(new Vector("V3", 5, 3)); - set.add(new Vector("V4", 5, 2)); - set.add(new Vector("V5", 5, 1)); - set.add(new Vector("V6", 5, 2)); - set.add(new Vector("V7", 5, 3)); - set.add(new Vector("V8", 5, 4)); - set.add(new Vector("V9", 5, 5)); + set.add(new TestVector("V0", 5, 5)); + set.add(new TestVector("V1", 4, 4)); + set.add(new TestVector("V2", 5, 4)); + set.add(new TestVector("V3", 5, 3)); + set.add(new TestVector("V4", 5, 2)); + set.add(new TestVector("V5", 5, 1)); + set.add(new TestVector("V6", 5, 2)); + set.add(new TestVector("V7", 5, 3)); + set.add(new TestVector("V8", 5, 4)); + set.add(new TestVector("V9", 5, 5)); // Expect all vectors with v1=4 or v2 in [1,2] assertEquals("{V1[4, 4], V4[5, 2], V5[5, 1], V6[5, 2]}", set.toString()); @@ -242,16 +242,16 @@ public void testRelaxedCriteriaAcceptingTheTwoSmallestValues() { @Test public void testRelaxedCriteriaAcceptingTenPercentExtra() { // Given a set and function - ParetoSet set = new ParetoSet<>((l, r) -> + ParetoSet set = new ParetoSet<>((l, r) -> l.v1 < r.v1 || l.v2 <= IntUtils.round(r.v2 * 1.1) ); // Add some values - set.add(new Vector("a", 1, 110)); - set.add(new Vector("a", 1, 111)); - set.add(new Vector("d", 1, 100)); - set.add(new Vector("g", 1, 111)); - set.add(new Vector("g", 1, 110)); + set.add(new TestVector("a", 1, 110)); + set.add(new TestVector("a", 1, 111)); + set.add(new TestVector("d", 1, 100)); + set.add(new TestVector("g", 1, 111)); + set.add(new TestVector("g", 1, 110)); assertEquals("{a[1, 110], d[1, 100], g[1, 110]}", set.toString()); } @@ -260,10 +260,10 @@ public void testRelaxedCriteriaAcceptingTenPercentExtra() { public void testFourCriteria() { // Given a set with one element with 2 criteria: [5, 5] // and the pareto function is: <, !=, >, <+2 - ParetoSet set = new ParetoSet<>((l, r) -> + ParetoSet set = new ParetoSet<>((l, r) -> l.v1 < r.v1 || l.v2 != r.v2 || l.v3 > r.v3 || l.v4 < r.v4 + 2 ); - Vector v0 = new Vector("V0", 5, 5, 5, 5); + TestVector v0 = new TestVector("V0", 5, 5, 5, 5); // Cases that does NOT make it into the set testNotAdded(set, v0, vector(5, 5, 5, 7), "same as v0"); @@ -299,7 +299,7 @@ public void testFourCriteria() { @Test public void testAutoScalingOfParetoSet() { // Given a set with 2 criteria - ParetoSet set = new ParetoSet<>(LESS_LESS_THEN); + ParetoSet set = new ParetoSet<>(LESS_LESS_THEN); // The initial size is set to 16. // Add 100 mutually dominant values @@ -319,13 +319,13 @@ public void testAutoScalingOfParetoSet() { @Test public void testAddingMultipleElements() { // Given a set with 2 criteria: LT and LT - ParetoSet set = new ParetoSet<>(LESS_LESS_THEN); - Vector v55 = new Vector("v55", 5, 5); - Vector v53 = new Vector("v53", 5, 3); - Vector v44 = new Vector("v44", 4, 4); - Vector v35 = new Vector("v35", 3, 5); - Vector v25 = new Vector("v25", 2, 5); - Vector v22 = new Vector("v22", 2, 2); + ParetoSet set = new ParetoSet<>(LESS_LESS_THEN); + TestVector v55 = new TestVector("v55", 5, 5); + TestVector v53 = new TestVector("v53", 5, 3); + TestVector v44 = new TestVector("v44", 4, 4); + TestVector v35 = new TestVector("v35", 3, 5); + TestVector v25 = new TestVector("v25", 2, 5); + TestVector v22 = new TestVector("v22", 2, 2); // A dominant vector should replace more than one other vector test(set, "v25", v25, v35); @@ -355,7 +355,7 @@ public void testAddingMultipleElements() { @Test public void elementsAreNotDroppedWhenParetoOptimalElementsAreAdded() { // Given a set with 2 criteria: LT and LT - ParetoSet set = new ParetoSet<>(LESS_LESS_THEN, listener); + ParetoSet set = new ParetoSet<>(LESS_LESS_THEN, listener); // Before any elements are added the list of dropped elements should be empty assertTrue(dropped.isEmpty()); @@ -372,7 +372,7 @@ public void elementsAreNotDroppedWhenParetoOptimalElementsAreAdded() { @Test public void firstElementIsDroppedWhenANewDominatingElementIsAdded() { // Given a set with 2 criteria: LT and LT and a vector [7, 3] - ParetoSet set = new ParetoSet<>(LESS_LESS_THEN, listener); + ParetoSet set = new ParetoSet<>(LESS_LESS_THEN, listener); set.add(vector(7, 3)); assertTrue(dropped.isEmpty()); @@ -397,7 +397,7 @@ public void firstElementIsDroppedWhenANewDominatingElementIsAdded() { @Test public void lastElementIsDroppedWhenANewDominatingElementIsAdded() { // Given a set with 2 criteria: LT and LT and a vector [7, 3] - ParetoSet set = new ParetoSet<>(LESS_LESS_THEN, listener); + ParetoSet set = new ParetoSet<>(LESS_LESS_THEN, listener); set.add(vector(5, 5)); set.add(vector(7, 3)); assertTrue(dropped.isEmpty()); @@ -411,7 +411,7 @@ public void lastElementIsDroppedWhenANewDominatingElementIsAdded() { * Test that both #add and #qualify return the same value - true. The set should contain the * vector, but that is left to the caller to verify. */ - private static void addOk(ParetoSet set, Vector v) { + private static void addOk(ParetoSet set, TestVector v) { assertTrue(set.qualify(v)); assertTrue(set.add(v)); } @@ -420,58 +420,68 @@ private static void addOk(ParetoSet set, Vector v) { * Test that both #add and #qualify return the same value - false. The set should not contain the * vector, but that is left to the caller to verify. */ - private static void addRejected(ParetoSet set, Vector v) { + private static void addRejected(ParetoSet set, TestVector v) { assertFalse(set.qualify(v)); assertFalse(set.add(v)); } - private static String names(Iterable set) { + private static String names(Iterable set) { return StreamSupport .stream(set.spliterator(), false) .map(it -> it == null ? "null" : it.name) .collect(Collectors.joining(" ")); } - private static Vector vector(int a, int b) { - return new Vector("Test", a, b); + private static TestVector vector(int a, int b) { + return new TestVector("Test", a, b); } - private static Vector vector(int a, int b, int c, int d) { - return new Vector("Test", a, b, c, d); + private static TestVector vector(int a, int b, int c, int d) { + return new TestVector("Test", a, b, c, d); } private static void testNotAdded( - ParetoSet set, - Vector v0, - Vector v1, + ParetoSet set, + TestVector v0, + TestVector v1, String description ) { test(set, v0, v1, description, v0); } - private static void testReplace(ParetoSet set, Vector v0, Vector v1, String description) { + private static void testReplace( + ParetoSet set, + TestVector v0, + TestVector v1, + String description + ) { test(set, v0, v1, description, v1); } - private static void keepBoth(ParetoSet set, Vector v0, Vector v1, String description) { + private static void keepBoth( + ParetoSet set, + TestVector v0, + TestVector v1, + String description + ) { test(set, v0, v1, description, v0, v1); } private static void test( - ParetoSet set, - Vector v0, - Vector v1, + ParetoSet set, + TestVector v0, + TestVector v1, String description, - Vector... expected + TestVector... expected ) { new TestCase(v0, v1, description, expected).run(set); } - private void test(ParetoSet set, String expected, Vector... vectorsToAdd) { + private void test(ParetoSet set, String expected, TestVector... vectorsToAdd) { set.clear(); - for (Vector v : vectorsToAdd) { + for (TestVector v : vectorsToAdd) { // Copy vector to avoid any identity pitfalls - Vector vector = new Vector(v); + TestVector vector = new TestVector(v); boolean qualify = set.qualify(vector); assertEquals(qualify, set.add(vector), "Qualify and add should return the same value."); } @@ -480,12 +490,12 @@ private void test(ParetoSet set, String expected, Vector... vectorsToAdd static class TestCase { - final Vector v0; - final Vector v1; + final TestVector v0; + final TestVector v1; final String expected; final String description; - TestCase(Vector v0, Vector v1, String description, Vector... expected) { + TestCase(TestVector v0, TestVector v1, String description, TestVector... expected) { this.v0 = v0; this.v1 = v1; this.expected = @@ -495,7 +505,7 @@ static class TestCase { this.description = description; } - void run(ParetoSet set) { + void run(ParetoSet set) { set.clear(); set.add(v0); diff --git a/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetWithMarkerTest.java b/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetWithMarkerTest.java similarity index 100% rename from src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetWithMarkerTest.java rename to raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/ParetoSetWithMarkerTest.java diff --git a/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/TestParetoSetEventListener.java b/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/TestParetoSetEventListener.java new file mode 100644 index 00000000000..7e4bb539dc5 --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/TestParetoSetEventListener.java @@ -0,0 +1,58 @@ +package org.opentripplanner.raptor.util.paretoset; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * An event listener witch keeps the result for each event type. Used in tests in this package + * only! + */ +class TestParetoSetEventListener implements ParetoSetEventListener { + + private final List accepted = new ArrayList<>(); + private final List rejected = new ArrayList<>(); + private final List dropped = new ArrayList<>(); + + @Override + public void notifyElementAccepted(T newElement) { + accepted.add(newElement); + } + + @Override + public void notifyElementDropped(T element, T droppedByElement) { + dropped.add(element); + } + + @Override + public void notifyElementRejected(T element, T rejectedByElement) { + rejected.add(element); + } + + @Override + public String toString() { + return "TestParetoSetEventListener"; + } + + public String acceptedAsString() { + return toString(accepted); + } + + public String rejectedAsString() { + return toString(rejected); + } + + public String droppedAsString() { + return toString(dropped); + } + + void clear() { + accepted.clear(); + rejected.clear(); + dropped.clear(); + } + + private String toString(List list) { + return list.stream().map(Object::toString).collect(Collectors.joining(" ")); + } +} diff --git a/src/test/java/org/opentripplanner/raptor/util/paretoset/Vector.java b/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/TestVector.java similarity index 71% rename from src/test/java/org/opentripplanner/raptor/util/paretoset/Vector.java rename to raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/TestVector.java index fa696b9af17..7f9998f5485 100644 --- a/src/test/java/org/opentripplanner/raptor/util/paretoset/Vector.java +++ b/raptor/src/test/java/org/opentripplanner/raptor/util/paretoset/TestVector.java @@ -2,29 +2,33 @@ import java.util.Objects; -class Vector { +/** + * Create a value object type to test the ParetoSet "generic" type criteria. We create a new type + * to isolate the tests in this package from any other randomly chosen type. + */ +class TestVector { private static final int NOT_SET = -999; final String name; final int v1, v2, v3, v4; - Vector(Vector o) { + TestVector(TestVector o) { this(o.name, o.v1, o.v2, o.v3, o.v4); } - Vector(String name, int v1) { + TestVector(String name, int v1) { this(name, v1, NOT_SET, NOT_SET, NOT_SET); } - Vector(String name, int v1, int v2) { + TestVector(String name, int v1, int v2) { this(name, v1, v2, NOT_SET, NOT_SET); } - Vector(String name, int v1, int v2, int v3) { + TestVector(String name, int v1, int v2, int v3) { this(name, v1, v2, v3, NOT_SET); } - Vector(String name, int v1, int v2, int v3, int v4) { + TestVector(String name, int v1, int v2, int v3, int v4) { this.name = name; this.v1 = v1; this.v2 = v2; @@ -45,7 +49,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } - Vector v = (Vector) o; + TestVector v = (TestVector) o; return v1 == v.v1 && v2 == v.v2 && v3 == v.v3 && v4 == v.v4 && name.equals(v.name); } diff --git a/renovate.json5 b/renovate.json5 index b672797d48f..a5838fb3ff0 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -54,10 +54,8 @@ "me.fabriciorby:maven-surefire-junit5-tree-reporter", "com.google.truth:truth", "org.jacoco:jacoco-maven-plugin", // coverage plugin - "org.apache.commons:commons-compress" // only used by tests - ], - "matchPackagePrefixes": [ - "org.junit.jupiter:", + "org.apache.commons:commons-compress", // only used by tests + "org.junit.jupiter:{/,}**" ], "automerge": true, "schedule": "on the 17th day of the month" @@ -91,8 +89,8 @@ { // https://github.com/graphql-java-kickstart/renovate-config/blob/main/default.json "description": "GraphQL Java (ignoring snapshot builds)", - "matchPackagePrefixes": [ - "com.graphql-java:" + "matchPackageNames": [ + "com.graphql-java:{/,}**" ], "allowedVersions": "/^[0-9]+\\.[0-9]+(\\.[0-9]+)?$/" }, @@ -115,8 +113,8 @@ }, { "description": "in order to keep review burden low, don't update these quite so frequently", - "matchPackagePrefixes": [ - "org.apache.lucene:", + "matchPackageNames": [ + "org.apache.lucene:{/,}**", ], "extends": [ "schedule:quarterly" @@ -137,19 +135,29 @@ { "description": "Automerge logging dependencies in a single PR", "groupName": "logging dependencies", - "matchPackagePrefixes": [ - "org.slf4j:", - "ch.qos.logback:" + "matchPackageNames": [ + "org.slf4j:{/,}**", + "ch.qos.logback:{/,}**" ], "automerge": true, "schedule": "on the 4th day of the month" }, { "description": "give some projects time to publish a changelog before opening the PR", - "matchPackagePrefixes": [ - "com.google.dagger:" + "matchPackageNames": [ + "com.google.dagger:{/,}**", + "com.fasterxml.jackson:{/,}**", + "com.fasterxml.jackson.datatype::{/,}**" ], "minimumReleaseAge": "1 week" + }, + { + "description": "Geotools takes a while to publish a changelog and since it pulls in JTS it can change the serialization of the graph", + "matchPackageNames": [ + "org.geotools:{/,}**" + ], + "minimumReleaseAge": "1 week", + "labels": ["skip changelog", "bump serialization id"] } ], "timezone": "Europe/Berlin" diff --git a/src/scripts/otp b/script/otp similarity index 100% rename from src/scripts/otp rename to script/otp diff --git a/src/scripts/otp-ui b/script/otp-ui similarity index 100% rename from src/scripts/otp-ui rename to script/otp-ui diff --git a/shaded-jar/pom.xml b/shaded-jar/pom.xml new file mode 100644 index 00000000000..5709ef8245f --- /dev/null +++ b/shaded-jar/pom.xml @@ -0,0 +1,120 @@ + + + 4.0.0 + + org.opentripplanner + otp-root + 2.7.0-SNAPSHOT + + shaded-jar + pom + OpenTripPlanner - Shaded Jar + + + skip + false + + + + + + ${project.groupId} + application + ${project.version} + + + + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + ${project.build.directory}/otp-${project.version}-shaded.jar + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + ${skipShadeJar} + + true + + false + + + + + + + org.opentripplanner.standalone.OTPMain + + Java Advanced Imaging Image I/O + Tools + + 1.1 + Sun Microsystems, Inc. + com.sun.media.imageio + 1.1 + Sun Microsystems, Inc. + + com.sun.media.imageio + + + + + + + build-shaded-jar + shade + + + + + + diff --git a/src/client/classic-debug/js/otp/locale/ca_ES.json b/src/client/classic-debug/js/otp/locale/ca_ES.json deleted file mode 100644 index e0bc0c5e3ba..00000000000 --- a/src/client/classic-debug/js/otp/locale/ca_ES.json +++ /dev/null @@ -1,238 +0,0 @@ -{ - "Transit": "Transport públic", - "Bus Only": "Només bus", - "Rail Only": "Només tren", - "Airplane Only": "", - "Transit, No Airplane": "", - "Bicycle Only": "Bicicleta", - "Bicycle & Transit": "Transport públic i bicicleta", - "Walk Only": "Només a peu", - "Car Only": "", - "Taxi": "", - "Park and Ride": "", - "Ride and Kiss (Car Pickup)": "", - "Kiss and Ride (Car Dropoff)": "", - "Bike and Ride": "", - "Rented Bicycle": "", - "Transit & Rented Bicycle": "", - "Rented Scooter": "", - "Transit & Rented Scooter": "", - "Transit with flex access": "", - "Transit with flex egress": "", - "Transit with flex access and egress": "", - "Direct flex search": "", - "Recenter Map Here": "Centrar mapa aquí", - "Zoom In": "Apropar", - "Zoom Out": "Allunyar", - "Minimize all": "", - "Unminimize all": "", - "Stop Viewer": "", - "Plan Trip": "", - "From Stop": "", - "To Stop": "", - "Routes Serving Stop": "", - "Bike Share Planner": "", - "Trip Options": "", - "PICK UP BIKE": "", - "ALTERNATE PICKUP": "", - "DROP OFF BIKE": "", - "ALTERNATE DROP OFF": "", - "BIKE STATION": "", - "Station:": "", - "%d bike available": "", - "%d bike available_plural": "", - "%d dock available": "", - "%d dock available_plural": "", - "Recommended Pick Up:": "", - "Bicycle rental": "", - "Recommended Drop Off:": "", - "Multimodal Trip Planner": "", - "Itineraries": "", - "This itinerary departs on a different day from the previous one": "", - "%d Itinerary Returned": "", - "%d Itinerary Returned_plural": "", - "Link to search": "", - "Previous Page": "", - "Next Page": "", - "CONTINUES AS": "", - "%d min late": "", - "%d min late_plural": "", - "%d min early": "", - "%d min early_plural": "", - "on time": "", - "This itinerary departs on a different day than the one searched for": "", - "Arrived at destination with a rented bicycle!": "", - "End": "", - "Trip Summary": "", - "Travel": "Hora de sortida", - "Time": "Temps", - "GenCost": "", - "Total Walk": "", - "Total Bike": "", - "Total drive": "", - "Elevation Gained": "", - "Elevation Lost": "", - "Transfers": "transbords", - "Fare": "Tarifa", - "Valid": "Hora actual", - "Link to Itinerary": "", - "Print": "Imprimir", - "Your Trip": "", - "Email": "", - "every %d min": "", - "every %d min_plural": "", - "Board at ": "", - "Stop": "", - "Time in transit": "", - "Route ID": "", - "Trip ID": "", - "Service Date": "", - "Trip Viewer": "", - "late as": "", - "Stay on board": "stay on board", - "Alight": "", - "at": "a", - "%(currency)s %(price)s": "", - "Start: %(location)s at %(time_date)s": "", - "Board": "", - "(%(agency_id)s Stop ID #%(stop_id)s),": "", - "End: %(location)s at %(time_date)s": "", - "(%(agencyId)s Stop ID #%(id)s),": "", - "\nView itinerary online:\n%(itinerary_link)s\n": "", - "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "", - "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", - "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", - "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "", - "The trip planner is taking way too long to process your request. Please try again later.": "", - "The request has errors that the server is not willing or able to process.": "", - "Origin is unknown. Can you be a bit more descriptive?": "", - "Destination is unknown. Can you be a bit more descriptive?": "", - "Both origin and destination are unknown. Can you be a bit more descriptive?": "", - "Both origin and destination are not wheelchair accessible": "", - "Origin is within a trivial distance of the destination.": "", - "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "", - "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "", - "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "", - "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "", - "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "", - "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "", - "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "", - "Set as Start Location": "", - "Set as End Location": "", - "Destination": "", - "Error %(error_id)d": "", - "No Trip Found": "", - "Your %(bike_share_name)s route": "", - "Your bike route": "", - "Walk to the %(bike_share_name)s dock.": "", - "Walk from the %(bike_share_name)s dock to your destination.": "", - "Your walk route": "", - "Your route using the scooter": "", - "Your driving route": "", - "north": "nord", - "northeast": "nord-est", - "east": "est", - "southeast": "sud-est", - "south": "sud", - "southwest": "sud-oest", - "west": "oest", - "northwest": "nord-oest", - "hard left": "gira completament a la esquerra", - "left": "gira a la esquerra", - "slight left": "gira lleugerament a la esquerra", - "continue": "", - "slight right": "gira lleugerament a la dreta", - "right": "gira a la dreta", - "hard right": "gira completament a la dreta", - "elevator": "", - "U-turn left": "", - "U-turn right": "", - "Walk": "A peu", - "Cycle": "Bicicleta", - "Car": "Cotxe", - "Bus": "AUTOBÚS", - "Subway": "METRO", - "Train": "Tren", - "Ferry": "BOT", - "Light Rail": "", - "Cable Car": "PONT PENJANT", - "Funicular": "FUNICULAR", - "Aerial Tram": "", - "Airplane": "", - "Bicycle rental station": "", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", - "Start on": "", - " heading ": "", - "to continue on": "per a continuar a", - "on to": "", - "first": "", - "second": "", - "third": "", - "fourth": "", - "fifth": "", - "sixth": "", - "seventh": "", - "eight": "", - "ninth": "", - "tenth": "", - "%d hr": "", - "%d hr_plural": "", - "%d min": "", - "%d min_plural": "", - "%d sec": "", - "%d sec_plural": "", - "OK": "OK", - "Minimize": "", - "Bring to front": "", - "Send to back": "", - "Route:": "", - "Variant:": "", - "Stop Finder": "", - "Feed": "Agency", - "By ID": "", - "By Name": "", - "Search": "", - "No Stops Found": "", - "Date": "Data", - "Find Stops": "", - "(No Stop Selected)": "", - "Block": "", - "Recenter": "", - "Viewer": "", - "Quick": "", - "Flat": "", - "Bike Friendly": "", - "B": "", - "F": "", - "Q": "", - "All Routes": "", - "Save": "", - "Close": "", - "Travel Options": "", - "Geocoder": "", - "Arrive": "Arribada a", - "Now": "", - "Wheelchair accessible trip:": "Viatge amb accessibilitat:", - "Show Filtered Itineraries:": "", - "Travel by": "Mode de viatge", - "Preferred Routes": "", - "Edit": "Editar", - "None": "", - "Weight": "", - "Banned routes": "", - "Use": "", - "My Own Bike": "", - "A Shared Bike": "", - "Plan Your Trip": "Planificar el viatge", - "Additional parameters": "", - " to _direction": "", - " to _bus_direction": "", - "Start_template": "", - "Depart_itinerary": "Sortida des de", - "depart_itinerary": "Sortida des de", - "Start_popup": "", - "Depart_tripoptions": "Sortida des de" -} \ No newline at end of file diff --git a/src/client/classic-debug/js/otp/locale/de.json b/src/client/classic-debug/js/otp/locale/de.json deleted file mode 100644 index 5a0aa5316f4..00000000000 --- a/src/client/classic-debug/js/otp/locale/de.json +++ /dev/null @@ -1,238 +0,0 @@ -{ - "Transit": "ÖPNV", - "Bus Only": "nur Bus", - "Rail Only": "nur Bahn", - "Airplane Only": "", - "Transit, No Airplane": "", - "Bicycle Only": "Fahrrad", - "Bicycle & Transit": "ÖPNV und Fahrrad", - "Walk Only": "zu Fuß", - "Car Only": "", - "Taxi": "", - "Park and Ride": "Parken und Reisen", - "Ride and Kiss (Car Pickup)": "", - "Kiss and Ride (Car Dropoff)": "", - "Bike and Ride": "", - "Rented Bicycle": "Fahrradverleih", - "Transit & Rented Bicycle": "ÖPNV und Fahrradverleih", - "Rented Scooter": "", - "Transit & Rented Scooter": "ÖPNV und Fahrradverleih", - "Transit with flex access": "", - "Transit with flex egress": "", - "Transit with flex access and egress": "", - "Direct flex search": "", - "Recenter Map Here": "Karte hier zentrieren", - "Zoom In": "hineinzoomen", - "Zoom Out": "herauszoomen", - "Minimize all": "Alle Dialoge minimieren", - "Unminimize all": "Dialoge wiederanzeigen", - "Stop Viewer": "", - "Plan Trip": "", - "From Stop": "", - "To Stop": "", - "Routes Serving Stop": "", - "Bike Share Planner": "", - "Trip Options": "Einstellungen für Routensuche", - "PICK UP BIKE": "", - "ALTERNATE PICKUP": "", - "DROP OFF BIKE": "", - "ALTERNATE DROP OFF": "", - "BIKE STATION": "", - "Station:": "", - "%d bike available": "", - "%d bike available_plural": "", - "%d dock available": "", - "%d dock available_plural": "", - "Recommended Pick Up:": "", - "Bicycle rental": "Fahrradverleih", - "Recommended Drop Off:": "", - "Multimodal Trip Planner": "Multimodaler Routenplaner", - "Itineraries": "Routenvorschläge", - "This itinerary departs on a different day from the previous one": "", - "%d Itinerary Returned": "", - "%d Itinerary Returned_plural": "", - "Link to search": "Link für diese Suche erstellen", - "Previous Page": "Vorheriger", - "Next Page": "", - "CONTINUES AS": "Weiterfahren", - "%d min late": "%d min Verspätung", - "%d min late_plural": "%d min Verspätung", - "%d min early": "%d min zu früh", - "%d min early_plural": "%d min zu früh", - "on time": "pünktlich", - "This itinerary departs on a different day than the one searched for": "", - "Arrived at destination with a rented bicycle!": "", - "End": "Ankunft", - "Trip Summary": "", - "Travel": "Reise", - "Time": "Dauer", - "GenCost": "", - "Total Walk": "", - "Total Bike": "", - "Total drive": "", - "Elevation Gained": "", - "Elevation Lost": "", - "Transfers": "Umsteigepunkt", - "Fare": "Tarif", - "Valid": "Gültig bis", - "Link to Itinerary": "", - "Print": "drucken", - "Your Trip": "", - "Email": "", - "every %d min": "", - "every %d min_plural": "", - "Board at ": "", - "Stop": "", - "Time in transit": "", - "Route ID": "", - "Trip ID": "", - "Service Date": "", - "Trip Viewer": "", - "late as": "", - "Stay on board": "an Bord bleiben", - "Alight": "", - "at": "um", - "%(currency)s %(price)s": "", - "Start: %(location)s at %(time_date)s": "", - "Board": "", - "(%(agency_id)s Stop ID #%(stop_id)s),": "", - "End: %(location)s at %(time_date)s": "", - "(%(agencyId)s Stop ID #%(id)s),": "", - "\nView itinerary online:\n%(itinerary_link)s\n": "", - "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "", - "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", - "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", - "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "", - "The trip planner is taking way too long to process your request. Please try again later.": "", - "The request has errors that the server is not willing or able to process.": "", - "Origin is unknown. Can you be a bit more descriptive?": "", - "Destination is unknown. Can you be a bit more descriptive?": "", - "Both origin and destination are unknown. Can you be a bit more descriptive?": "", - "Both origin and destination are not wheelchair accessible": "", - "Origin is within a trivial distance of the destination.": "", - "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "", - "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "", - "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "", - "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "", - "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "", - "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "", - "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "", - "Set as Start Location": "", - "Set as End Location": "", - "Destination": "", - "Error %(error_id)d": "", - "No Trip Found": "", - "Your %(bike_share_name)s route": "", - "Your bike route": "", - "Walk to the %(bike_share_name)s dock.": "", - "Walk from the %(bike_share_name)s dock to your destination.": "", - "Your walk route": "", - "Your route using the scooter": "", - "Your driving route": "", - "north": "nord", - "northeast": "nordost", - "east": "ost", - "southeast": "südost", - "south": "süd", - "southwest": "südwest", - "west": "west", - "northwest": "nordwest", - "hard left": "scharf links", - "left": "links", - "slight left": "links halten", - "continue": "", - "slight right": "rechts halten", - "right": "rechts", - "hard right": "scharf rechts", - "elevator": "", - "U-turn left": "", - "U-turn right": "", - "Walk": "zu Fuß gehen", - "Cycle": "Fahrrad", - "Car": "Auto", - "Bus": "Bus", - "Subway": "U-Bahn", - "Train": "Bahn", - "Ferry": "Fähre", - "Light Rail": "", - "Cable Car": "Standseilbahn", - "Funicular": "Seilbahn", - "Aerial Tram": "", - "Airplane": "", - "Bicycle rental station": "Fahrradverleihstation", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "", - "Start on": "", - " heading ": "", - "to continue on": "weiter auf", - "on to": "", - "first": "Erster", - "second": "", - "third": "", - "fourth": "", - "fifth": "", - "sixth": "", - "seventh": "", - "eight": "", - "ninth": "", - "tenth": "", - "%d hr": "", - "%d hr_plural": "", - "%d min": "", - "%d min_plural": "", - "%d sec": "", - "%d sec_plural": "", - "OK": "OK", - "Minimize": "Minimieren", - "Bring to front": "in den Vordergrund", - "Send to back": "in den Hintergrund", - "Route:": "", - "Variant:": "", - "Stop Finder": "", - "Feed": "Agency", - "By ID": "", - "By Name": "", - "Search": "", - "No Stops Found": "", - "Date": "Datum", - "Find Stops": "", - "(No Stop Selected)": "", - "Block": "", - "Recenter": "", - "Viewer": "", - "Quick": "Schnellste", - "Flat": "Flach", - "Bike Friendly": "Fahrradgeeignet", - "B": "F", - "F": "Fl", - "Q": "S", - "All Routes": "alle Routen", - "Save": "Speichern", - "Close": "Schließen", - "Travel Options": "Routeneinstellungen", - "Geocoder": "Geocoder", - "Arrive": "Ankunft", - "Now": "Jetzt", - "Wheelchair accessible trip:": "barrierefreie Route:", - "Show Filtered Itineraries:": "", - "Travel by": "Fortbewegungsart/Verkehrsmittel", - "Preferred Routes": "bevorzugte Routen", - "Edit": "anpassen", - "None": "keine", - "Weight": "Gewichtung", - "Banned routes": "ausgeschlossene Routen", - "Use": "", - "My Own Bike": "", - "A Shared Bike": "", - "Plan Your Trip": "Route berechnen", - "Additional parameters": "", - " to _direction": "", - " to _bus_direction": "", - "Start_template": "Abfahrt", - "Depart_itinerary": "Abfahrt", - "depart_itinerary": "Abfahrt", - "Start_popup": "Abfahrt", - "Depart_tripoptions": "Abfahrt" -} \ No newline at end of file diff --git a/src/client/classic-debug/js/otp/locale/en.json b/src/client/classic-debug/js/otp/locale/en.json deleted file mode 100644 index 51e5565997c..00000000000 --- a/src/client/classic-debug/js/otp/locale/en.json +++ /dev/null @@ -1,238 +0,0 @@ -{ - "Transit": "Transit", - "Bus Only": "Bus Only", - "Rail Only": "Rail Only", - "Airplane Only": "Airplane Only", - "Transit, No Airplane": "", - "Bicycle Only": "Bicycle Only", - "Bicycle & Transit": "Bicycle & Transit", - "Walk Only": "Walk Only", - "Car Only": "Car Only", - "Taxi": "", - "Park and Ride": "Park and Ride", - "Ride and Kiss (Car Pickup)": "", - "Kiss and Ride (Car Dropoff)": "", - "Bike and Ride": "Bike and Ride", - "Rented Bicycle": "Rented Bicycle", - "Transit & Rented Bicycle": "Transit & Rented Bicycle", - "Rented Scooter": "", - "Transit & Rented Scooter": "Transit & Rented Bicycle", - "Transit with flex access": "", - "Transit with flex egress": "", - "Transit with flex access and egress": "", - "Direct flex search": "", - "Recenter Map Here": "Recenter Map Here", - "Zoom In": "Zoom In", - "Zoom Out": "Zoom Out", - "Minimize all": "Minimize all", - "Unminimize all": "Unminimize all", - "Stop Viewer": "Stop Viewer", - "Plan Trip": "Plan Trip", - "From Stop": "From Stop", - "To Stop": "To Stop", - "Routes Serving Stop": "Routes Serving Stop", - "Bike Share Planner": "Bike Share Planner", - "Trip Options": "Trip Options", - "PICK UP BIKE": "PICK UP BIKE", - "ALTERNATE PICKUP": "ALTERNATE PICKUP", - "DROP OFF BIKE": "DROP OFF BIKE", - "ALTERNATE DROP OFF": "ALTERNATE DROP OFF", - "BIKE STATION": "BIKE STATION", - "Station:": "Station:", - "%d bike available": "%d bike available", - "%d bike available_plural": "%d bikes available", - "%d dock available": "%d dock available", - "%d dock available_plural": "%d docks available", - "Recommended Pick Up:": "Recommended Pick Up:", - "Bicycle rental": "Bicycle rental", - "Recommended Drop Off:": "Recommended Drop Off:", - "Multimodal Trip Planner": "Multimodal Trip Planner", - "Itineraries": "Itineraries", - "This itinerary departs on a different day from the previous one": "", - "%d Itinerary Returned": "%d Itinerary Returned", - "%d Itinerary Returned_plural": "%d Itineraries Returned", - "Link to search": "Link to search", - "Previous Page": "Previous", - "Next Page": "", - "CONTINUES AS": "CONTINUES AS", - "%d min late": "%d min late", - "%d min late_plural": "%d mins late", - "%d min early": "%d min early", - "%d min early_plural": "%d mins early", - "on time": "on time", - "This itinerary departs on a different day than the one searched for": "", - "Arrived at destination with a rented bicycle!": "", - "End": "End", - "Trip Summary": "Trip Summary", - "Travel": "Travel", - "Time": "Time", - "GenCost": "Weight/Cost", - "Total Walk": "Total Walk", - "Total Bike": "Total Bike", - "Total drive": "Total drive", - "Elevation Gained": "", - "Elevation Lost": "Elevation Lost", - "Transfers": "Transfers", - "Fare": "Fare", - "Valid": "Valid", - "Link to Itinerary": "Link to Itinerary", - "Print": "Print", - "Your Trip": "Your Trip", - "Email": "Email", - "every %d min": "every %d min", - "every %d min_plural": "every %d mins", - "Board at ": "Board at ", - "Stop": "Stop", - "Time in transit": "Time in transit", - "Route ID": "", - "Trip ID": "", - "Service Date": "", - "Trip Viewer": "Trip Viewer", - "late as": "late as", - "Stay on board": "Stay on board", - "Alight": "Alight", - "at": "at", - "%(currency)s %(price)s": "%(currency)s %(price)s", - "Start: %(location)s at %(time_date)s": "Start: %(location)s at %(time_date)s", - "Board": "Board", - "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s Stop ID #%(stop_id)s),", - "End: %(location)s at %(time_date)s": "End: %(location)s at %(time_date)s", - "(%(agencyId)s Stop ID #%(id)s),": "", - "\nView itinerary online:\n%(itinerary_link)s\n": "\nView itinerary online:\n%(itinerary_link)s\n", - "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "We're sorry. The trip planner is temporarily unavailable. Please try again later.", - "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "Trip is not possible. You might be trying to plan a trip outside the map data boundary.", - "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", - "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.", - "The trip planner is taking way too long to process your request. Please try again later.": "The trip planner is taking way too long to process your request. Please try again later.", - "The request has errors that the server is not willing or able to process.": "The request has errors that the server is not willing or able to process.", - "Origin is unknown. Can you be a bit more descriptive?": "Origin is unknown. Can you be a bit more descriptive?", - "Destination is unknown. Can you be a bit more descriptive?": "Destination is unknown. Can you be a bit more descriptive?", - "Both origin and destination are unknown. Can you be a bit more descriptive?": "Both origin and destination are unknown. Can you be a bit more descriptive?", - "Both origin and destination are not wheelchair accessible": "Both origin and destination are not wheelchair accessible", - "Origin is within a trivial distance of the destination.": "Origin is within a trivial distance of the destination.", - "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.", - "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.", - "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "Both origin and destination are ambiguous. Please select from the following options, or be more specific.", - "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are", - "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1", - "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE", - "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set", - "Set as Start Location": "Set as Start Location", - "Set as End Location": "Set as End Location", - "Destination": "Destination", - "Error %(error_id)d": "Error %(error_id)d", - "No Trip Found": "No Trip Found", - "Your %(bike_share_name)s route": "Your %(bike_share_name)s route", - "Your bike route": "Your bike route", - "Walk to the %(bike_share_name)s dock.": "Walk to the %(bike_share_name)s dock.", - "Walk from the %(bike_share_name)s dock to your destination.": "Walk from the %(bike_share_name)s dock to your destination.", - "Your walk route": "Your walk route", - "Your route using the scooter": "", - "Your driving route": "Your bike route", - "north": "north", - "northeast": "northeast", - "east": "east", - "southeast": "southeast", - "south": "south", - "southwest": "southwest", - "west": "west", - "northwest": "northwest", - "hard left": "hard left", - "left": "left", - "slight left": "slight left", - "continue": "continue", - "slight right": "slight right", - "right": "right", - "hard right": "hard right", - "elevator": "elevator", - "U-turn left": "U-turn left", - "U-turn right": "U-turn right", - "Walk": "Walk", - "Cycle": "Cycle", - "Car": "Car", - "Bus": "Bus", - "Subway": "Subway", - "Train": "Train", - "Ferry": "Ferry", - "Light Rail": "Light Rail", - "Cable Car": "Cable Car", - "Funicular": "Funicular", - "Aerial Tram": "Aerial Tram", - "Airplane": "", - "Bicycle rental station": "Bicycle rental station", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s", - "Start on": "Start on", - " heading ": " heading ", - "to continue on": "to continue on", - "on to": "on to", - "first": "first", - "second": "second", - "third": "third", - "fourth": "fourth", - "fifth": "fifth", - "sixth": "sixth", - "seventh": "seventh", - "eight": "eight", - "ninth": "ninth", - "tenth": "tenth", - "%d hr": "%d hr", - "%d hr_plural": "%d hrs", - "%d min": "%d min", - "%d min_plural": "%d mins", - "%d sec": "%d sec", - "%d sec_plural": "%d secs", - "OK": "OK", - "Minimize": "Minimize", - "Bring to front": "Bring to front", - "Send to back": "Send to back", - "Route:": "Route:", - "Variant:": "Variant:", - "Stop Finder": "Stop Finder", - "Feed": "Agency", - "By ID": "By ID", - "By Name": "By Name", - "Search": "Search", - "No Stops Found": "No Stops Found", - "Date": "Date", - "Find Stops": "Find Stops", - "(No Stop Selected)": "(No Stop Selected)", - "Block": "Block", - "Recenter": "Recenter", - "Viewer": "Viewer", - "Quick": "Quick", - "Flat": "Flat", - "Bike Friendly": "Bike Friendly", - "B": "B", - "F": "F", - "Q": "Q", - "All Routes": "All Routes", - "Save": "Save", - "Close": "Close", - "Travel Options": "Travel Options", - "Geocoder": "Geocoder", - "Arrive": "Arrive", - "Now": "Now", - "Wheelchair accessible trip:": "Wheelchair accessible trip:", - "Show Filtered Itineraries:": "", - "Travel by": "Travel by", - "Preferred Routes": "Preferred Routes", - "Edit": "Edit", - "None": "None", - "Weight": "Weight", - "Banned routes": "Banned routes", - "Use": "Use", - "My Own Bike": "My Own Bike", - "A Shared Bike": "A Shared Bike", - "Plan Your Trip": "Plan Your Trip", - "Additional parameters": "", - " to _direction": " to ", - " to _bus_direction": " to ", - "Start_template": "Start", - "Depart_itinerary": "Depart", - "depart_itinerary": "depart", - "Start_popup": "Start", - "Depart_tripoptions": "Depart" -} \ No newline at end of file diff --git a/src/client/classic-debug/js/otp/locale/es.json b/src/client/classic-debug/js/otp/locale/es.json deleted file mode 100644 index fca9c112411..00000000000 --- a/src/client/classic-debug/js/otp/locale/es.json +++ /dev/null @@ -1,238 +0,0 @@ -{ - "Transit": "Transporte Público", - "Bus Only": "Sólo autobús", - "Rail Only": "Sólo tren", - "Airplane Only": "", - "Transit, No Airplane": "", - "Bicycle Only": "Sólo bicicletas", - "Bicycle & Transit": "Bicicleta y Transporte Público", - "Walk Only": "Sólo a pie", - "Car Only": "Comienza en", - "Taxi": "", - "Park and Ride": "Aparcar y Transporte Público", - "Ride and Kiss (Car Pickup)": "", - "Kiss and Ride (Car Dropoff)": "", - "Bike and Ride": "Bicicleta y Transporte Público", - "Rented Bicycle": "Alquiler bicicleta", - "Transit & Rented Bicycle": "Transporte Público y Alquiler de bicicleta", - "Rented Scooter": "", - "Transit & Rented Scooter": "Transporte Público y Alquiler de bicicleta", - "Transit with flex access": "", - "Transit with flex egress": "", - "Transit with flex access and egress": "", - "Direct flex search": "", - "Recenter Map Here": "Centrar Mapa Aquí", - "Zoom In": "Acercar", - "Zoom Out": "Alejar", - "Minimize all": "Minimizar todo", - "Unminimize all": "Ampliar todo", - "Stop Viewer": "Visor de parada", - "Plan Trip": "Calcular viaje", - "From Stop": "Desde parada", - "To Stop": "Hasta parada", - "Routes Serving Stop": "Rutas por la parada", - "Bike Share Planner": "Planificador de Bicicleta Compartida", - "Trip Options": "Opciones de viaje", - "PICK UP BIKE": "Recogida de bicicleta", - "ALTERNATE PICKUP": "Recogida alternativa", - "DROP OFF BIKE": "DEVOLUCIÓN DE BICICLETA", - "ALTERNATE DROP OFF": "DEVOLUCIÓN DE BICICLETA ALTERNATIVA", - "BIKE STATION": "Estación de bicicleta", - "Station:": "Estación:", - "%d bike available": "%d bike available", - "%d bike available_plural": "%d bikes available", - "%d dock available": "%d dock available", - "%d dock available_plural": "%d docks available", - "Recommended Pick Up:": "Recogida recomendada:", - "Bicycle rental": "alquiler de bicicleta", - "Recommended Drop Off:": "Devolución recomendada:", - "Multimodal Trip Planner": "Planificador multimodo", - "Itineraries": "Rutas", - "This itinerary departs on a different day from the previous one": "", - "%d Itinerary Returned": "%d Ruta encontrada", - "%d Itinerary Returned_plural": "%d Rutas encontradas", - "Link to search": "Enlace a búsqueda", - "Previous Page": "Anterior", - "Next Page": "", - "CONTINUES AS": "CONTINÚA COMO", - "%d min late": "%d min tarde", - "%d min late_plural": "%d mins tarde", - "%d min early": "%d min early", - "%d min early_plural": "%d mins early", - "on time": "puntual", - "This itinerary departs on a different day than the one searched for": "", - "Arrived at destination with a rented bicycle!": "", - "End": "Fin", - "Trip Summary": "Resumen de la ruta", - "Travel": "Viaje", - "Time": "Duración", - "GenCost": "", - "Total Walk": "Total a pie", - "Total Bike": "Total en bicicleta", - "Total drive": "", - "Elevation Gained": "", - "Elevation Lost": "", - "Transfers": "Transbordos", - "Fare": "Ticket", - "Valid": "Válido", - "Link to Itinerary": "Enlace a ruta", - "Print": "Imprimir", - "Your Trip": "Tu Viaje", - "Email": "Email", - "every %d min": "cada %d min", - "every %d min_plural": "cada %d mins", - "Board at ": "Desde ", - "Stop": "Parada", - "Time in transit": "Durante", - "Route ID": "", - "Trip ID": "", - "Service Date": "", - "Trip Viewer": "Visor de ruta", - "late as": "no más tarde que", - "Stay on board": "mantente montado", - "Alight": "hasta ", - "at": "en", - "%(currency)s %(price)s": "%(currency)s %(price)s", - "Start: %(location)s at %(time_date)s": "Comienza: %(location)s a las %(time_date)s", - "Board": "Toma", - "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s ID Parada #%(stop_id)s),", - "End: %(location)s at %(time_date)s": "Finaliza: %(location)s a las %(time_date)s", - "(%(agencyId)s Stop ID #%(id)s),": "", - "\nView itinerary online:\n%(itinerary_link)s\n": "\nVer ruta online:\n%(itinerary_link)s\n", - "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Lo sentimos. El planificador de ruta está fuera de servicio temporalmente. Inténtelo más tarde.", - "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", - "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", - "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Tiempos no disponibles. La información disponible podría no ser válida para la fecha actual o no hay rutas disponibles para tu viaje.", - "The trip planner is taking way too long to process your request. Please try again later.": "El planificador de rutas está tardando demasiado. Por favor, inténtalo más tarde.", - "The request has errors that the server is not willing or able to process.": "Error en la petición, el server no puede procesar la información.", - "Origin is unknown. Can you be a bit more descriptive?": "Origen desconocido. ¿Puedes ser un poco más descriptivo?", - "Destination is unknown. Can you be a bit more descriptive?": "Destino desconocido. ¿Puedes ser un poco más descriptivo?", - "Both origin and destination are unknown. Can you be a bit more descriptive?": "Origen y destino desconocidos ¿Puedes ser un poco más descriptivo?", - "Both origin and destination are not wheelchair accessible": "Origen y destino no son accesibles a silla de ruedas.", - "Origin is within a trivial distance of the destination.": "Origen y destino están demasiado cerca.", - "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "El planificador de rutas no está seguro de tu origen. Por favor, seleccione una de las siguientes opciones o introduzca un origen más exacto.", - "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "El planificador de rutas no está seguro de tu destino. Por favor, seleccione una de las siguientes opciones o introduzca un destino más exacto.", - "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "Origen y destino son ambiguos. Por favor, seleccione una de las siguientes opciones o introduzca un destino más exacto.", - "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "El triángulo de Seguridad, Llano y Tiempo debe ser seleccionado si está disponible.", - "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "El valor del triángulo de Seguridad, Llano y Tiempo debe sumar 1.", - "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "Si el triángulo de Seguridad, Llano y Tiempo está disponible, debe ser un TRIÁNGULO.", - "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "Si el tipo de optimización es triángulo, los factores de Seguridad, Llano y Tiempo tienen que estar seleccionados.", - "Set as Start Location": "Ruta desde aquí", - "Set as End Location": "Ruta hacia aquí", - "Destination": "Fin", - "Error %(error_id)d": "Error %(error_id)d", - "No Trip Found": "Viaje no encontrado", - "Your %(bike_share_name)s route": "Tu ruta %(bike_share_name)s", - "Your bike route": "Tu ruta en bicicleta", - "Walk to the %(bike_share_name)s dock.": "Camina hacia la estación %(bike_share_name)s.", - "Walk from the %(bike_share_name)s dock to your destination.": "Camina desde la estación %(bike_share_name)s hacia tu destino.", - "Your walk route": "Tu ruta a pie", - "Your route using the scooter": "", - "Your driving route": "Tu ruta en bicicleta", - "north": "Norte", - "northeast": "Nordeste", - "east": "Este", - "southeast": "Sureste", - "south": "Sur", - "southwest": "Suroeste", - "west": "Oeste", - "northwest": "Noroeste", - "hard left": "Izquierda fuerte", - "left": "izquierda", - "slight left": "Izquierda suave", - "continue": "continúa", - "slight right": "Derecha suave", - "right": "derecha", - "hard right": "Derecha fuerte", - "elevator": "ascensor", - "U-turn left": "Gira a la izquierda", - "U-turn right": "Gira a la derecha", - "Walk": "Camina", - "Cycle": "Bicicleta", - "Car": "Coche", - "Bus": "Autobús", - "Subway": "Metro", - "Train": "Tren", - "Ferry": "Barco", - "Light Rail": "Tranvía", - "Cable Car": "Bus Tranvía", - "Funicular": "Funicular", - "Aerial Tram": "Funicular", - "Airplane": "", - "Bicycle rental station": "estación de alquiler de bicicleta", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Toma la rotonda sentido contrario a las agujas del reloj hasta la %(ordinal_exit_number)s salida dirección %(street_name)s", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Toma la rotonda sentido contrario a las agujas del reloj hasta la %(ordinal_exit_number)s salida hacia %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Toma la rotonda sentido a las agujas del reloj hasta la %(ordinal_exit_number)s salida dirección %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Toma la rotonda sentido a las agujas del reloj hasta la %(ordinal_exit_number)s salida hacia %(street_name)s", - "Start on": "Comienza en", - " heading ": " dirección ", - "to continue on": "hacia", - "on to": "dirección", - "first": "primera", - "second": "segunda", - "third": "tercera", - "fourth": "cuarta", - "fifth": "quinta", - "sixth": "sexta", - "seventh": "séptima", - "eight": "octava", - "ninth": "novena", - "tenth": "décima", - "%d hr": "%d hr", - "%d hr_plural": "%d hrs", - "%d min": "%d min", - "%d min_plural": "%d mins", - "%d sec": "%d seg", - "%d sec_plural": "%d segs", - "OK": "Vale", - "Minimize": "Minimizar", - "Bring to front": "Traer al frente", - "Send to back": "Mandar al fondo", - "Route:": "Línea:", - "Variant:": "Variante:", - "Stop Finder": "Buscador de paradas", - "Feed": "Compañía", - "By ID": "Número:", - "By Name": "Nombre:", - "Search": "Buscar", - "No Stops Found": "Paradas no encontradas", - "Date": "Fecha", - "Find Stops": "Buscar paradas", - "(No Stop Selected)": "(Sin parada seleccionada)", - "Block": "Transbordo sin cambio de vehículo", - "Recenter": "Centrar", - "Viewer": "Visor", - "Quick": "Rápido", - "Flat": "Sin cuestas", - "Bike Friendly": "Adaptado a bicicleta", - "B": "B", - "F": "P", - "Q": "R", - "All Routes": "Todas las líneas", - "Save": "Guardar", - "Close": "Cerrar", - "Travel Options": "Opciones de viaje", - "Geocoder": "Geocoder", - "Arrive": "Llegar a las", - "Now": "Ahora", - "Wheelchair accessible trip:": "Ruta accesible a silla de ruedas:", - "Show Filtered Itineraries:": "", - "Travel by": "Viajar en", - "Preferred Routes": "Líneas favoritas", - "Edit": "Editar", - "None": "Niguna", - "Weight": "Prioridad", - "Banned routes": "Líneas prohibidas", - "Use": "Usar", - "My Own Bike": "Mi propia bicileta", - "A Shared Bike": "Una bicicleta compartida", - "Plan Your Trip": "Calcular Viaje", - "Additional parameters": "", - " to _direction": " dirección ", - " to _bus_direction": " dirección ", - "Start_template": "Inicio", - "Depart_itinerary": "Comienza", - "depart_itinerary": "Comienza", - "Start_popup": "Inicio", - "Depart_tripoptions": "Salir a las" -} \ No newline at end of file diff --git a/src/client/classic-debug/js/otp/locale/fr.json b/src/client/classic-debug/js/otp/locale/fr.json deleted file mode 100644 index 53b4d78be17..00000000000 --- a/src/client/classic-debug/js/otp/locale/fr.json +++ /dev/null @@ -1,238 +0,0 @@ -{ - "Transit": "Transports en commun", - "Bus Only": "Bus uniquement", - "Rail Only": "Ferré uniquement", - "Airplane Only": "", - "Transit, No Airplane": "", - "Bicycle Only": "Vélo uniquement", - "Bicycle & Transit": "Transports en commun + Vélo", - "Walk Only": "Marche seulement", - "Car Only": "Partir de", - "Taxi": "", - "Park and Ride": "Parc Relais", - "Ride and Kiss (Car Pickup)": "", - "Kiss and Ride (Car Dropoff)": "", - "Bike and Ride": "Parc Relais Vélo", - "Rented Bicycle": "Vélo Libre Service", - "Transit & Rented Bicycle": "Transports en commun et Vélo Libre Service", - "Rented Scooter": "", - "Transit & Rented Scooter": "Transports en commun et Vélo Libre Service", - "Transit with flex access": "", - "Transit with flex egress": "", - "Transit with flex access and egress": "", - "Direct flex search": "", - "Recenter Map Here": "Centrer la carte ici", - "Zoom In": "Zoomer", - "Zoom Out": "Dézoomer", - "Minimize all": "Tout minimiser", - "Unminimize all": "Tout restaurer", - "Stop Viewer": "Visualisateur d'arrêt", - "Plan Trip": "Organiser un voyage", - "From Stop": "De l'arrêt", - "To Stop": "À l'arrêt", - "Routes Serving Stop": "Lignes desservant l'arrêt", - "Bike Share Planner": "Organisation en Vélo Libre Service", - "Trip Options": "Paramètres de l'itinéraire", - "PICK UP BIKE": "Récupérer un vélo", - "ALTERNATE PICKUP": "Alternative de récupération de vélo", - "DROP OFF BIKE": "Déposer le vélo", - "ALTERNATE DROP OFF": "Alternative de dépôt de vélo", - "BIKE STATION": "Station de vélos", - "Station:": "Station :", - "%d bike available": "%d vélo disponible", - "%d bike available_plural": "%d vélos disponibles", - "%d dock available": "%d emplacements disponibles", - "%d dock available_plural": "%d emplacements disponibles", - "Recommended Pick Up:": "Station de récupération de vélo recommandée :", - "Bicycle rental": "Station de vélo libre service", - "Recommended Drop Off:": "Station de dépôt de vélo recommandée", - "Multimodal Trip Planner": "Planificateur d'itinéraires multimodal", - "Itineraries": "Itinéraires", - "This itinerary departs on a different day from the previous one": "", - "%d Itinerary Returned": "%d itinéraire trouvé", - "%d Itinerary Returned_plural": "%d itinéraires trouvés", - "Link to search": "Lien vers cette recherche", - "Previous Page": "Précédent", - "Next Page": "", - "CONTINUES AS": "Continue comme", - "%d min late": "en retard de %d min", - "%d min late_plural": "en retard de %d mins", - "%d min early": "en avance de %d min", - "%d min early_plural": "en avance de %d mins", - "on time": "à l'heure", - "This itinerary departs on a different day than the one searched for": "", - "Arrived at destination with a rented bicycle!": "", - "End": "Arrivée", - "Trip Summary": "Résumé du voyage", - "Travel": "Voyage", - "Time": "Durée", - "GenCost": "", - "Total Walk": "Total de marche", - "Total Bike": "Total de vélo", - "Total drive": "", - "Elevation Gained": "", - "Elevation Lost": "", - "Transfers": "correspondances", - "Fare": "Tarif", - "Valid": "Valide le", - "Link to Itinerary": "Lien vers l'itinéraire", - "Print": "Imprimer", - "Your Trip": "Votre voyage", - "Email": "Courriel", - "every %d min": "toutes les %d min", - "every %d min_plural": "toutes les %d mins", - "Board at ": "Montez à ", - "Stop": "Arrêt", - "Time in transit": "Temps de correspondance", - "Route ID": "", - "Trip ID": "", - "Service Date": "", - "Trip Viewer": "Visualisateur de voyage", - "late as": "en retard à", - "Stay on board": "rester à bord", - "Alight": "Descendre", - "at": "à", - "%(currency)s %(price)s": "%(price)s %(currency)s", - "Start: %(location)s at %(time_date)s": "Départ : %(location)s à %(time_date)s", - "Board": "Monter", - "(%(agency_id)s Stop ID #%(stop_id)s),": "arrêt #%(stop_id)s) de (%(agency_id)s,", - "End: %(location)s at %(time_date)s": "Arrivée : %(location)s à %(time_date)s", - "(%(agencyId)s Stop ID #%(id)s),": "", - "\nView itinerary online:\n%(itinerary_link)s\n": "\nVoir l'itinéraire en ligne :\n%(itinerary_link)s\n", - "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Nous sommes désolé. Le planificateur de voyage est temporairement indisponible. Merci de réessayer plus tard.", - "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", - "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", - "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Aucune durée de voyage disponible. La date est peut être passée ou trop loin dans le futur, ou il n'y a peut être pas de transports en service pour votre trajet à l'heure choisie.", - "The trip planner is taking way too long to process your request. Please try again later.": "Le planificateur de voyage prend largement trop de temps à étudier votre demande. Merci de réessayer plus tard.", - "The request has errors that the server is not willing or able to process.": "La requête renvoie des erreurs que le serveur ne souhaite ou ne peut pas traiter.", - "Origin is unknown. Can you be a bit more descriptive?": "L'origine est inconnue. Pouvez-vous être plus précis ?", - "Destination is unknown. Can you be a bit more descriptive?": "La destination est inconnue. Pouvez-vous être plus précis ?", - "Both origin and destination are unknown. Can you be a bit more descriptive?": "L'origine et la destination sont toutes deux inconnues. Pouvez-vous être plus précis ?", - "Both origin and destination are not wheelchair accessible": "Ni l'origine ni la destination ne sont accessibles en fauteuil roulant", - "Origin is within a trivial distance of the destination.": "L'origine est à une distance trop courte de la destination.", - "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "Le planificateur de voyage n'est pas sûr du lieu d'où vous voulez partir. Merci de le sélectionner parmi les options suivantes, ou d'être plus précis.", - "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "Le planificateur de voyage n'est pas sûr du lieu où vous désirez vous rendre. Merci de le sélectionner parmi les options suivantes, ou d'être plus précis.", - "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "L'origine et la destination sont toutes deux ambigües. Merci de les sélectionner parmi les options suivantes, ou d'être plus précis.", - "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "Toutes les options triangleSafetyFactor, triangleSlopeFactor, et triangleTimeFactor doivent être paramétrées si l'une d'elles l'est", - "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "Les valeurs de triangleSafetyFactor, triangleSlopeFactor, et triangleTimeFactor doivent avoir pour addition 1", - "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "Si triangleSafetyFactor, triangleSlopeFactor, et triangleTimeFactor sont fournis, OptimizeType doit être TRIANGLE", - "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "Si OptimizeType est TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, et triangleTimeFactor doivent être paramétrées", - "Set as Start Location": "Définir comme point de départ", - "Set as End Location": "Définir comme point d'arrivée", - "Destination": "Destination", - "Error %(error_id)d": "Erreur %(error_id)d", - "No Trip Found": "Aucun voyage trouvé", - "Your %(bike_share_name)s route": "Votre itinéraire en %(bike_share_name)s", - "Your bike route": "Votre itinéraire en vélo", - "Walk to the %(bike_share_name)s dock.": "Marcher jusqu'à l'emplacement %(bike_share_name)s.", - "Walk from the %(bike_share_name)s dock to your destination.": "Marcher de l'emplacement %(bike_share_name)s jusqu'à votre destination", - "Your walk route": "Votre itinéraire à pieds", - "Your route using the scooter": "", - "Your driving route": "Votre itinéraire en vélo", - "north": "nord", - "northeast": "nord-est", - "east": "est", - "southeast": "sud-est", - "south": "sud", - "southwest": "sud-ouest", - "west": "ouest", - "northwest": "nord-ouest", - "hard left": "complètement à gauche", - "left": "à gauche", - "slight left": "légèrement à gauche", - "continue": "continuer", - "slight right": "légèrement à droite", - "right": "à droite", - "hard right": "complètement à droite", - "elevator": "ascenseur", - "U-turn left": "virage en U à gauche", - "U-turn right": "virage en U à droite", - "Walk": "Marche à pied", - "Cycle": "Vélo", - "Car": "Voiture", - "Bus": "Bus", - "Subway": "Métro", - "Train": "Train", - "Ferry": "Ferry", - "Light Rail": "Tram ou Trolley", - "Cable Car": "Tramway funiculaire", - "Funicular": "Funiculaire", - "Aerial Tram": "Téléphérique", - "Airplane": "", - "Bicycle rental station": "Station de vélo libre service", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendre le rond-point dans le sens contraire des aiguilles d'une montre jusqu'à la %(ordinal_exit_number)s sortie sur %(street_name)s", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendre le rond-point dans le sens contraire des aiguilles d'une montre jusqu'à la %(ordinal_exit_number)s sortie sur %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendre le rond-point dans le sens des aiguilles d'une montre jusqu'à la %(ordinal_exit_number)s sortie sur %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendre le rond-point dans le sens des aiguilles d'une montre jusqu'à la %(ordinal_exit_number)s sortie sur %(street_name)s", - "Start on": "Partir de", - " heading ": " vers le ", - "to continue on": "pour continuer sur", - "on to": "sur", - "first": "première", - "second": "seconde", - "third": "troisième", - "fourth": "quatrième", - "fifth": "cinquième", - "sixth": "sixième", - "seventh": "septième", - "eight": "huitième", - "ninth": "neuvième", - "tenth": "dixième", - "%d hr": "%d h", - "%d hr_plural": "%d h", - "%d min": "%d min", - "%d min_plural": "%d mins", - "%d sec": "%d s", - "%d sec_plural": "%d s", - "OK": "OK", - "Minimize": "Minimiser", - "Bring to front": "Placer au dessus", - "Send to back": "Placer en dessous", - "Route:": "Ligne :", - "Variant:": "Variante :", - "Stop Finder": "Recherche d'arrêt", - "Feed": "Transporteur", - "By ID": "Par identifiant", - "By Name": "Par nom", - "Search": "Recherche", - "No Stops Found": "Aucun arrêt trouvé", - "Date": "Date", - "Find Stops": "Trouver les arrêts", - "(No Stop Selected)": "(Aucun arrêt sélectionné)", - "Block": "Bloc", - "Recenter": "Recentrer", - "Viewer": "Visualisateur", - "Quick": "Le plus Rapide", - "Flat": "Le plus Plat", - "Bike Friendly": "Adapté au vélo", - "B": "A", - "F": "P", - "Q": "R", - "All Routes": "Tous les itinéraires", - "Save": "Sauvegarder", - "Close": "Fermer", - "Travel Options": "Paramètres de voyage", - "Geocoder": "Géocodeur", - "Arrive": "Arrivée", - "Now": "Maintenant", - "Wheelchair accessible trip:": "Accessible aux fauteuils roulants:", - "Show Filtered Itineraries:": "", - "Travel by": "Voyager par", - "Preferred Routes": "Itinéraires préférés", - "Edit": "Modifier", - "None": "Aucune", - "Weight": "Pondération", - "Banned routes": "Itinéraires à éviter", - "Use": "Utiliser", - "My Own Bike": "mon propre vélo", - "A Shared Bike": "un Vélo Libre Service", - "Plan Your Trip": "Calculer votre itinéraire", - "Additional parameters": "", - " to _direction": " jusqu'à ", - " to _bus_direction": " vers ", - "Start_template": "Départ", - "Depart_itinerary": "Départ", - "depart_itinerary": "Départ", - "Start_popup": "Départ", - "Depart_tripoptions": "Départ" -} \ No newline at end of file diff --git a/src/client/classic-debug/js/otp/locale/hu.json b/src/client/classic-debug/js/otp/locale/hu.json deleted file mode 100644 index 1e1e666e19e..00000000000 --- a/src/client/classic-debug/js/otp/locale/hu.json +++ /dev/null @@ -1,238 +0,0 @@ -{ - "Transit": "Tömegközlekedés", - "Bus Only": "Csak busz", - "Rail Only": "Csak vasút", - "Airplane Only": "Csak repülőgép", - "Transit, No Airplane": "Tömegközlekedés, repülés nélkül", - "Bicycle Only": "Csak kerékpár", - "Bicycle & Transit": "Kerékpár & tömegközlekedés", - "Walk Only": "Csak séta", - "Car Only": "Csak autó", - "Taxi": "Taxi", - "Park and Ride": "P+R (Park & Ride)", - "Ride and Kiss (Car Pickup)": "", - "Kiss and Ride (Car Dropoff)": "", - "Bike and Ride": "B+R (Bike & Ride)", - "Rented Bicycle": "Bérelt kerékpár", - "Transit & Rented Bicycle": "Tömegközlekedés és bérelt kerékpár", - "Rented Scooter": "", - "Transit & Rented Scooter": "Tömegközlekedés és bérelt kerékpár", - "Transit with flex access": "Tömegközlekedés rugalmas indulással", - "Transit with flex egress": "Tömegközlekedés rugalmas érkezéssel", - "Transit with flex access and egress": "Tömegközlekedés rugalmas indulással és érkezéssel", - "Direct flex search": "Közvetlen rugalmas keresés", - "Recenter Map Here": "Legyen itt a térkép középpontja", - "Zoom In": "Közelítés", - "Zoom Out": "Távolítás", - "Minimize all": "Minden kis méretűvé tétele", - "Unminimize all": "Minden kis méretűvé tételének megszüntetése", - "Stop Viewer": "Megállómegjelenítő", - "Plan Trip": "Utazás tervezése", - "From Stop": "Ettől a megállótól", - "To Stop": "Eddig a megállóig", - "Routes Serving Stop": "A megállót érintő járatok", - "Bike Share Planner": "Kerékpármegosztó-tervező", - "Trip Options": "Utazási beállítások", - "PICK UP BIKE": "KERÉKPÁR FELVÉTELE", - "ALTERNATE PICKUP": "MÁSIK FELVÉTELI HELY", - "DROP OFF BIKE": "KERÉKPÁR LEADÁSA", - "ALTERNATE DROP OFF": "MÁSIK LEADÁSI HELY", - "BIKE STATION": "KERÉKPÁRÁLLOMÁS", - "Station:": "Gyűjtőállomás:", - "%d bike available": "%d kerékpár elérhető", - "%d bike available_plural": "%d kerékpár elérhető", - "%d dock available": "%d dokkolóállás", - "%d dock available_plural": "%d dokkolállás", - "Recommended Pick Up:": "Ajánlott felvétel:", - "Bicycle rental": "Kerékpárbérlési hely", - "Recommended Drop Off:": "Ajánlott leadás:", - "Multimodal Trip Planner": "Multimodális utazástervező", - "Itineraries": "Útvonaltervek", - "This itinerary departs on a different day from the previous one": "Ez a útvonalterv az előző naptól eltérő napon kezdődik", - "%d Itinerary Returned": "%d útvonalatervet találtunk", - "%d Itinerary Returned_plural": "%d útvonaltervet találtunk", - "Link to search": "Link a kereséshez", - "Previous Page": "Előző", - "Next Page": "Következő", - "CONTINUES AS": "FOLYTATÁS MINT", - "%d min late": "%d perc késés", - "%d min late_plural": "%d perc késés", - "%d min early": "%d perccel korábban", - "%d min early_plural": "%d perccel korábban", - "on time": "pontos", - "This itinerary departs on a different day than the one searched for": "Ez az útvonalterv a tervezési naptól eltérő napon kezdődik", - "Arrived at destination with a rented bicycle!": "Bérelt kerékpárral való érkezés a célba!", - "End": "Érkezés", - "Trip Summary": "Utazás összefoglalója", - "Travel": "Utazás", - "Time": "Idő", - "GenCost": "Súly/Költség", - "Total Walk": "Séta összesen", - "Total Bike": "Kerékpárral összesen", - "Total drive": "Autóval összesen", - "Elevation Gained": "", - "Elevation Lost": "", - "Transfers": "Átszállások", - "Fare": "Viteldíj", - "Valid": "Érvényesség", - "Link to Itinerary": "Link az útvonaltervhez", - "Print": "Nyomtatás", - "Your Trip": "Az Ön utazása", - "Email": "E-mail", - "every %d min": "%d percenként", - "every %d min_plural": "%d percenként", - "Board at ": "Felszállás: ", - "Stop": "Megálló", - "Time in transit": "Közlekedési idő", - "Route ID": "", - "Trip ID": "", - "Service Date": "", - "Trip Viewer": "Utazásmegjelenítő", - "late as": "", - "Stay on board": "Maradjon a járművön", - "Alight": "Leszállás", - "at": "itt:", - "%(currency)s %(price)s": "%(currency)s %(price)s", - "Start: %(location)s at %(time_date)s": "Indulás: %(location)s (%(time_date)s)", - "Board": "Felszállás", - "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s megállóazonosító: #%(stop_id)s),", - "End: %(location)s at %(time_date)s": "Érkezés: %(location)s (%(time_date)s)", - "(%(agencyId)s Stop ID #%(id)s),": "(%(agencyId)s megállóazonosító: #%(id)s),", - "\nView itinerary online:\n%(itinerary_link)s\n": "\nOnline útvonalterv megtekintése:\n%(itinerary_link)s\n", - "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Sajnáljuk, az útvonaltervező átmenetileg nem elérhető. Kérjük, próbálja újra később.", - "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "Az utazás nem lehetséges. Lehet, hogy a térképadatok határain kívüli utat próbál tervezni.", - "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "Nem található ilyen utazás. Előfordulhat, hogy nincs tömegközlekedési szolgáltatás a megadott legnagyobb távolságon belül vagy a megadott időpontban, vagy a kezdő- vagy végpont nem érhető el biztonságosan.", - "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Nem áll rendelkezésre közlekedési idő. Előfordulhat, hogy a dátum elmúlt vagy túl messze van a jövőben, vagy az Ön által választott időpontban nincs tömegközlekedési szolgáltatás.", - "The trip planner is taking way too long to process your request. Please try again later.": "Az utazástervezőnek túl sokáig tart a kérés feldolgozása. Kérjük, próbálja újra később.", - "The request has errors that the server is not willing or able to process.": "A kérés olyan hibát tartalmaz, amelyet a szerver nem hajlandó vagy nem képes feldolgozni.", - "Origin is unknown. Can you be a bit more descriptive?": "A kiindulás pont ismeretlen. Le tudná írni egy kicsit gondosabban?", - "Destination is unknown. Can you be a bit more descriptive?": "Az úti cél ismeretlen. Le tudná írni egy kicsit gondosabban?", - "Both origin and destination are unknown. Can you be a bit more descriptive?": "A kiindulási és a célpont egyaránt ismeretlen. Le tudná-e írni egy kicsit gondosabban?", - "Both origin and destination are not wheelchair accessible": "Sem a kiindulási, sem a célpont nem akadálymentes", - "Origin is within a trivial distance of the destination.": "A kiindulási hely túl közel van a célponthoz.", - "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "Az útvonaltervező bizonytalan abban, hogy honnan szeretne indulni. Kérjük, válasszon az alábbi lehetőségek közül, vagy legyen pontosabb.", - "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "Az útvonaltervező bizonytalan abban, hogy hová szeretne érkezni. Kérjük, válasszon az alábbi lehetőségek közül, vagy legyen pontosabb.", - "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "Sem a kiindulási, sem a célpont nem egyértelmű. Kérjük, válasszon az alábbi lehetőségek közül, vagy legyen pontosabb.", - "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "A triangleSafetyFactor, a triangleSlopeFactor és a triangleTimeFactor értékeit egyaránt be kell állítani, ha vannak ilyenek", - "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "A triangleSafetyFactor, triangleSlopeFactor és triangleTimeFactor értékei összegének 1-nek kell lennie", - "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "Ha a triangleSafetyFactor, a triangleSlopeFactor és a triangleTimeFactor meg van adva, akkor az OptimizeType értékének TRIANGLE-nek kell lennie", - "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "Ha az OptimizeType értéke TRIANGLE, akkor be kell állítani a triangleSafetyFactor, a triangleSlopeFactor és a triangleTimeFactor értékeit", - "Set as Start Location": "Beállítás kiindulási helyként", - "Set as End Location": "Beállítás érkezési helyként", - "Destination": "Célpont", - "Error %(error_id)d": "Hiba: %(error_id)d", - "No Trip Found": "Nem található utazás", - "Your %(bike_share_name)s route": "Az Ön %(bike_share_name)s-útvonala", - "Your bike route": "Az Ön kerékpáros útvonala", - "Walk to the %(bike_share_name)s dock.": "Séta a dokkolóálláshoz (%(bike_share_name)s)", - "Walk from the %(bike_share_name)s dock to your destination.": "Séta a dokkolóállástól (%(bike_share_name)s) a célponthoz.", - "Your walk route": "Az Ön gyalogos útvonala", - "Your route using the scooter": "", - "Your driving route": "Az Ön kerékpáros útvonala", - "north": "észak", - "northeast": "északkelet", - "east": "kelet", - "southeast": "délkelet", - "south": "dél", - "southwest": "délnyugat", - "west": "nyugat", - "northwest": "északnyugat", - "hard left": "élesen balra", - "left": "balra", - "slight left": "enyhén balra", - "continue": "tovább", - "slight right": "enyhén jobbra", - "right": "jobbra", - "hard right": "élesen jobbra", - "elevator": "lift", - "U-turn left": "megfordulás balra", - "U-turn right": "megfordulás jobbra", - "Walk": "Séta", - "Cycle": "Kerékpározás", - "Car": "Autós útvonal", - "Bus": "Busz", - "Subway": "Metró", - "Train": "Vonat", - "Ferry": "Komp", - "Light Rail": "Villamos, könnyűvasút", - "Cable Car": "", - "Funicular": "Sikló", - "Aerial Tram": "Libegő", - "Airplane": "Repülőgép", - "Bicycle rental station": "Kerékpárkölcsönző állomás", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Hajtson be a körforgalomba az óramutató járásával ellentétesen, majd hajtson ki a(z) %(ordinal_exit_number)s kijáraton erre: %(street_name)s", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Hajtson be a körforgalomba az óramutató járásával ellentétesen, majd hajtson ki a(z) %(ordinal_exit_number)s kijáraton erre: %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Hajtson be a körforgalomba az óramutató járása szerinti irányba, majd hajtson ki a(z) %(ordinal_exit_number)s kijáraton erre: %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Hajtson be a körforgalomba az óramutató járása szerinti irányba, majd hajtson ki a(z) %(ordinal_exit_number)s kijáraton erre: %(street_name)s", - "Start on": "Induljon ezen:", - " heading ": " erre: ", - "to continue on": "menjen tovább ezen:", - "on to": "ezen:", - "first": "első", - "second": "második", - "third": "harmadik", - "fourth": "negyedik", - "fifth": "ötödik", - "sixth": "hatodik", - "seventh": "hetedik", - "eight": "nyolcadik", - "ninth": "kilencedik", - "tenth": "tizedik", - "%d hr": "%d óra", - "%d hr_plural": "%d óra", - "%d min": "%d perc", - "%d min_plural": "%d perc", - "%d sec": "%d másodperc", - "%d sec_plural": "%d másodperc", - "OK": "OK", - "Minimize": "Kis méretűvé tétel", - "Bring to front": "Előrehozás", - "Send to back": "Hátraküldés", - "Route:": "Útvonal:", - "Variant:": "Változat:", - "Stop Finder": "Megállókereső", - "Feed": "Feed", - "By ID": "Azonosító alapján", - "By Name": "Név alapján", - "Search": "Keresés", - "No Stops Found": "Nem található megálló", - "Date": "Dátum", - "Find Stops": "Megállóhelyek keresése", - "(No Stop Selected)": "(Nincs megálló kijelölve)", - "Block": "Blokk", - "Recenter": "Legyen ez a térkép középpontja", - "Viewer": "Megállómegtekintő", - "Quick": "Gyors", - "Flat": "Lapos", - "Bike Friendly": "Kerékpárosbarát", - "B": "K", - "F": "L", - "Q": "G", - "All Routes": "Minden útvonal", - "Save": "Mentés", - "Close": "Bezárás", - "Travel Options": "Utazás beállításai", - "Geocoder": "Geokóder", - "Arrive": "Érkezés", - "Now": "Most", - "Wheelchair accessible trip:": "Akadálymentes utazás:", - "Show Filtered Itineraries:": "Szűrt útvonaltervek megjelenítése:", - "Travel by": "Közlekedési eszköz:", - "Preferred Routes": "Előnyben részesített útvonalak", - "Edit": "Szerkesztés", - "None": "Nincs", - "Weight": "Súly", - "Banned routes": "Kerülendő útvonalak", - "Use": "Használt kerékpár:", - "My Own Bike": "saját", - "A Shared Bike": "bérelt", - "Plan Your Trip": "Tervezze meg utazását", - "Additional parameters": "További beállítások", - " to _direction": " eddig: ", - " to _bus_direction": " ide: ", - "Start_template": "Indulás", - "Depart_itinerary": "Indulás", - "depart_itinerary": "indulás", - "Start_popup": "Indulás", - "Depart_tripoptions": "Indulás" -} \ No newline at end of file diff --git a/src/client/classic-debug/js/otp/locale/it.json b/src/client/classic-debug/js/otp/locale/it.json deleted file mode 100644 index 0876aba1ef8..00000000000 --- a/src/client/classic-debug/js/otp/locale/it.json +++ /dev/null @@ -1,238 +0,0 @@ -{ - "Transit": "Mezzi pubblici", - "Bus Only": "Solo Bus", - "Rail Only": "Solo Treno", - "Airplane Only": "", - "Transit, No Airplane": "", - "Bicycle Only": "In bici", - "Bicycle & Transit": "Bici & mezzi pubblici", - "Walk Only": "A piedi", - "Car Only": "Partenza su", - "Taxi": "", - "Park and Ride": "Park & Ride", - "Ride and Kiss (Car Pickup)": "", - "Kiss and Ride (Car Dropoff)": "", - "Bike and Ride": "Bike & Ride", - "Rented Bicycle": "Bike sharing", - "Transit & Rented Bicycle": "Bike sharing & Ride", - "Rented Scooter": "", - "Transit & Rented Scooter": "Bike sharing & Ride", - "Transit with flex access": "", - "Transit with flex egress": "", - "Transit with flex access and egress": "", - "Direct flex search": "", - "Recenter Map Here": "Centra", - "Zoom In": "Zoom in", - "Zoom Out": "Zoom out", - "Minimize all": "Minimizza tutto", - "Unminimize all": "Ripristina tutto", - "Stop Viewer": "Orari", - "Plan Trip": "Calcola percorso", - "From Stop": "Da questa fermata", - "To Stop": "A questa fermata", - "Routes Serving Stop": "Linee", - "Bike Share Planner": "Bike Sharing", - "Trip Options": "Opzioni di viaggio", - "PICK UP BIKE": "Prendi la bici qui", - "ALTERNATE PICKUP": "Puoi prendere la bici anche qui", - "DROP OFF BIKE": "Lascia la bici qui", - "ALTERNATE DROP OFF": "Puoi lasciare la bici anche qui", - "BIKE STATION": "Stazione di Bike Sharing", - "Station:": "Stazione:", - "%d bike available": "%d bici disponibile", - "%d bike available_plural": "%d bici disponibili", - "%d dock available": "%d posto disponibile", - "%d dock available_plural": "%d posti disponibili", - "Recommended Pick Up:": "Prendi la bici:", - "Bicycle rental": "", - "Recommended Drop Off:": "Lascia la bici:", - "Multimodal Trip Planner": "Calcolo percorso multimodale", - "Itineraries": "Percorsi", - "This itinerary departs on a different day from the previous one": "", - "%d Itinerary Returned": "%d percorso trovato", - "%d Itinerary Returned_plural": "%d percorsi trovati", - "Link to search": "Link a questa ricerca", - "Previous Page": "Precedente", - "Next Page": "", - "CONTINUES AS": "Rimani a bordo", - "%d min late": "%d minuto di ritardo", - "%d min late_plural": "%d minuti di ritardo", - "%d min early": "%d minuto in anticipo", - "%d min early_plural": "%d minuti in anticipo", - "on time": "in orario", - "This itinerary departs on a different day than the one searched for": "", - "Arrived at destination with a rented bicycle!": "", - "End": "Arrivo", - "Trip Summary": "Riepilogo", - "Travel": "Partenza", - "Time": "Durata", - "GenCost": "", - "Total Walk": "A piedi", - "Total Bike": "In bici", - "Total drive": "", - "Elevation Gained": "", - "Elevation Lost": "", - "Transfers": "Cambi", - "Fare": "Costo", - "Valid": "Calcolato il ", - "Link to Itinerary": "Link a questo percorso", - "Print": "Stampa", - "Your Trip": "Il tuo percorso", - "Email": "Invia mail", - "every %d min": "ogni minuto", - "every %d min_plural": "ogni %d minuti", - "Board at ": "Parti da ", - "Stop": "Fermata", - "Time in transit": "Tempo a bordo", - "Route ID": "", - "Trip ID": "", - "Service Date": "", - "Trip Viewer": "Percorso", - "late as": "al più", - "Stay on board": "Rimani a bordo", - "Alight": "Scendi", - "at": "a", - "%(currency)s %(price)s": "%(currency)s %(price)s", - "Start: %(location)s at %(time_date)s": "Partenza: %(location)s alle %(time_date)s", - "Board": "Sali a bordo", - "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s fermata n.%(stop_id)s),", - "End: %(location)s at %(time_date)s": "Arrivo: %(location)s alle %(time_date)s", - "(%(agencyId)s Stop ID #%(id)s),": "", - "\nView itinerary online:\n%(itinerary_link)s\n": "\nConsulta il percorso online:\n%(itinerary_link)s\n", - "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Siamo spiacenti. Il servizio è momentaneamente indisponibile.Riprova più tardi.", - "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", - "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", - "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Nessun servizio di Trasporto Pubblico trovato. La data indicata potrebbe essere al di fuori del periodo preso in considerazione dal Calcolo Percorso.", - "The trip planner is taking way too long to process your request. Please try again later.": "Il servizio di Calcolo percorsi sta impiegando troppo tempo per processare la tua richiesta. Riprova più tardi.", - "The request has errors that the server is not willing or able to process.": "La richiesta contiene errori che il server non è in grado di trattare.", - "Origin is unknown. Can you be a bit more descriptive?": "Origine non riconosciuta. Puoi essere più esplicito?", - "Destination is unknown. Can you be a bit more descriptive?": "Destinazione non riconosciuta. Puoi essere più esplicito?", - "Both origin and destination are unknown. Can you be a bit more descriptive?": "Origine e destinazione non riconosciute. Puoi essere più esplicito?", - "Both origin and destination are not wheelchair accessible": "Origine e destinazione non accessibili in carrozzina", - "Origin is within a trivial distance of the destination.": "Origine troppo vicina alla destinazione.", - "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "Origine non riconosciuta. Seleziona fra le seguenti opzioni o specifica meglio l'origine.", - "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "Destinazione non riconosciuta. Seleziona fra le seguenti opzioni o specifica meglio la destinazione.", - "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "Origine e destinazione non riconosciute. Seleziona fra le seguenti opzioni o specifica meglio l'origine e la destinazione.", - "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "Specificare tutti e 3 i fattori: triangleSafetyFactor, triangleSlopeFactor e triangleTimeFactor", - "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "La somma dai fattori triangleSafetyFactor, triangleSlopeFactor e triangleTimeFactor dev'essere pari a 1", - "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "Se si forniscono i fattori triangleSafetyFactor, triangleSlopeFactor e triangleTimeFactor il parametro OptimizeType dev'essere settato a TRIANGLE", - "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "Se il parametro OptimizeType è settato a TRIANGLE, si devono fornire i fattori triangleSafetyFactor, triangleSlopeFactor e triangleTimeFactor ", - "Set as Start Location": "Imposta Partenza", - "Set as End Location": "Imposta Arrivo", - "Destination": "Destinazione", - "Error %(error_id)d": "Errore %(error_id)d", - "No Trip Found": "nessun percoro trovato", - "Your %(bike_share_name)s route": "Percorso con %(bike_share_name)s ", - "Your bike route": "Percorso in bici", - "Walk to the %(bike_share_name)s dock.": "A piedi verso la stazione %(bike_share_name)s", - "Walk from the %(bike_share_name)s dock to your destination.": "A piedi dalla stazione %(bike_share_name)s a destinazione", - "Your walk route": "Percorso a piedi", - "Your route using the scooter": "", - "Your driving route": "Percorso in bici", - "north": "nord", - "northeast": "nord-est", - "east": "est", - "southeast": "sud-est", - "south": "sud", - "southwest": "sud-ovest", - "west": "ovest", - "northwest": "nod-ovest", - "hard left": "a sinistra", - "left": "a sinistra", - "slight left": "tenere la sinistra", - "continue": "continuare", - "slight right": "tenere la destra", - "right": "a destra", - "hard right": "a destra", - "elevator": "ascensore", - "U-turn left": "inversione di marcia", - "U-turn right": "inversione di marcia", - "Walk": "A piedi", - "Cycle": "bici", - "Car": "auto", - "Bus": "bus", - "Subway": "metro", - "Train": "treno", - "Ferry": "Ferry", - "Light Rail": "tram", - "Cable Car": "tram", - "Funicular": "funivia", - "Aerial Tram": "tram", - "Airplane": "", - "Bicycle rental station": "", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendere la rotonda in senso antiorario, %(ordinal_exit_number)s uscita, %(street_name)s", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendere la rotonda in senso antiorario, %(ordinal_exit_number)s uscita, %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendere la rotonda in senso orario, %(ordinal_exit_number)s uscita, %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Prendere la rotonda in senso orario, %(ordinal_exit_number)s uscita, %(street_name)s", - "Start on": "Partenza su", - " heading ": " in direzione ", - "to continue on": "continua su", - "on to": "su", - "first": "prima", - "second": "seconda", - "third": "terza", - "fourth": "quarta", - "fifth": "quinta", - "sixth": "sesta", - "seventh": "settima", - "eight": "ottava", - "ninth": "nona", - "tenth": "decima", - "%d hr": "%d h", - "%d hr_plural": "%d h", - "%d min": "%d m", - "%d min_plural": "%d m", - "%d sec": "%d s", - "%d sec_plural": "%d s", - "OK": "OK", - "Minimize": "Riduci a icona", - "Bring to front": "Porta in primo piano", - "Send to back": "Porta in secondo piano", - "Route:": "Linea:", - "Variant:": "Percorso:", - "Stop Finder": "Ricerca Fermata", - "Feed": "Azienda TPL", - "By ID": "Numero", - "By Name": "Nome", - "Search": "Cerca", - "No Stops Found": "Nessuna fermata trovata", - "Date": "Data", - "Find Stops": "Cerca fermata", - "(No Stop Selected)": "(nessuna fermata selezionata)", - "Block": "Turno", - "Recenter": "Centra", - "Viewer": "Passaggi", - "Quick": "Veloce", - "Flat": "Pianeggiante", - "Bike Friendly": "Sicuro", - "B": "S", - "F": "P", - "Q": "V", - "All Routes": "Linee", - "Save": "Salva", - "Close": "Chiudi", - "Travel Options": "Opzioni di viaggio", - "Geocoder": "Geocoder", - "Arrive": "Arrivo", - "Now": "Ora", - "Wheelchair accessible trip:": "Percorso accessibile:", - "Show Filtered Itineraries:": "", - "Travel by": "Modalità", - "Preferred Routes": "Linee preferite", - "Edit": "Modifica", - "None": "Nessuna", - "Weight": "Peso", - "Banned routes": "Linee da evitare", - "Use": "Usa", - "My Own Bike": "bici propria", - "A Shared Bike": "bike sharing", - "Plan Your Trip": "Calcola", - "Additional parameters": "", - " to _direction": " fino a ", - " to _bus_direction": " in direzione ", - "Start_template": "Partenza", - "Depart_itinerary": "Parti da", - "depart_itinerary": "Partenza", - "Start_popup": "Partenza", - "Depart_tripoptions": "Partenza" -} \ No newline at end of file diff --git a/src/client/classic-debug/js/otp/locale/no.json b/src/client/classic-debug/js/otp/locale/no.json deleted file mode 100644 index 5a64e60d2a6..00000000000 --- a/src/client/classic-debug/js/otp/locale/no.json +++ /dev/null @@ -1,238 +0,0 @@ -{ - "Transit": "Kollektivtransport", - "Bus Only": "Buss", - "Rail Only": "Tog", - "Airplane Only": "Fly", - "Transit, No Airplane": "", - "Bicycle Only": "Sykkel", - "Bicycle & Transit": "Sykkel & Kollektivtransport", - "Walk Only": "Gå", - "Car Only": "Start fra", - "Taxi": "", - "Park and Ride": "Park and Ride", - "Ride and Kiss (Car Pickup)": "", - "Kiss and Ride (Car Dropoff)": "", - "Bike and Ride": "Bike and Ride", - "Rented Bicycle": "Bysykkel", - "Transit & Rented Bicycle": "Kollektivtransport & Bysykkel", - "Rented Scooter": "", - "Transit & Rented Scooter": "Kollektivtransport & Bysykkel", - "Transit with flex access": "", - "Transit with flex egress": "", - "Transit with flex access and egress": "", - "Direct flex search": "", - "Recenter Map Here": "Sentrer kart her", - "Zoom In": "Zoom inn", - "Zoom Out": "Zoom ut", - "Minimize all": "Minimer vinduer", - "Unminimize all": "Vis vinduer", - "Stop Viewer": "Vis Stoppested", - "Plan Trip": "Reiseplanlegger", - "From Stop": "Fra stoppested", - "To Stop": "Til stoppested", - "Routes Serving Stop": "Ruter fra stoppested", - "Bike Share Planner": "Bike Share Planner", - "Trip Options": "Reise søk", - "PICK UP BIKE": "PICK UP BIKE", - "ALTERNATE PICKUP": "ALTERNATE PICKUP", - "DROP OFF BIKE": "DROP OFF BIKE", - "ALTERNATE DROP OFF": "ALTERNATE DROP OFF", - "BIKE STATION": "BIKE STATION", - "Station:": "Stasjon:", - "%d bike available": "%d sykkel tilgjengelig", - "%d bike available_plural": "%d sykler tilgjengelig", - "%d dock available": "%d plass ledig", - "%d dock available_plural": "%d plasser ledig", - "Recommended Pick Up:": "Anbefalt Pick Up:", - "Bicycle rental": "Bysykkel", - "Recommended Drop Off:": "Anbefalt Drop Off:", - "Multimodal Trip Planner": "Reiseplanlegger", - "Itineraries": "Vis Reiseplaner", - "This itinerary departs on a different day from the previous one": "", - "%d Itinerary Returned": "%d Reise alternativ", - "%d Itinerary Returned_plural": "%d Reise alternativer", - "Link to search": "Link til søk", - "Previous Page": "Forrige", - "Next Page": "", - "CONTINUES AS": "FORTSETTER SOM", - "%d min late": "%d minutt forsinket", - "%d min late_plural": "%d minutter forsinket", - "%d min early": "%d minutt fortidlig", - "%d min early_plural": "%d minutter fortidlig", - "on time": "i rute", - "This itinerary departs on a different day than the one searched for": "", - "Arrived at destination with a rented bicycle!": "", - "End": "Til", - "Trip Summary": "Reise oversikt", - "Travel": "Start", - "Time": "Reisetid", - "GenCost": "Kost", - "Total Walk": "Gangeavstand", - "Total Bike": "Sykkel distanse", - "Total drive": "Bil distanse", - "Elevation Gained": "", - "Elevation Lost": "", - "Transfers": "Bytter", - "Fare": "Pris", - "Valid": "Gyldig", - "Link to Itinerary": "Link til reise", - "Print": "Skriv ut", - "Your Trip": "Din reise", - "Email": "e-post", - "every %d min": "hvert minutt", - "every %d min_plural": "hvert %d minutt", - "Board at ": "Påstigning ", - "Stop": "Stoppested", - "Time in transit": "Tid kollektivtransport", - "Route ID": "", - "Trip ID": "", - "Service Date": "", - "Trip Viewer": "Vis Rute", - "late as": "sent som", - "Stay on board": "Bli om bord", - "Alight": "Avstigning", - "at": "på", - "%(currency)s %(price)s": "%(currency)s %(price)s", - "Start: %(location)s at %(time_date)s": "Fra: %(location)s klokka %(time_date)s", - "Board": "Påstigning", - "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s Stoppested ID #%(stop_id)s),", - "End: %(location)s at %(time_date)s": "Ankomst: %(location)s klokka %(time_date)s", - "(%(agencyId)s Stop ID #%(id)s),": "", - "\nView itinerary online:\n%(itinerary_link)s\n": "\nVis reiseplan:\n%(itinerary_link)s\n", - "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Beklager. Reiseplanleggeren er midlertidig utilgjengelig. Venligst forsøk igjen senere.", - "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", - "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "Ingen reise funnet. Sjekk at fra/til sted er innenfor angitt gangavstand til destinasjon, stopested, bysykkel-stativ og/eller påstigningspunkt for bil.", - "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Ingen kolektivreiser funnet for denne dagen.", - "The trip planner is taking way too long to process your request. Please try again later.": "Reiseplanleggeren svarer ikke på forspørsel. Prøv igjen senere.", - "The request has errors that the server is not willing or able to process.": "Ugyldig input data. Server er ikke i stand til å behandle 'RouteRequest'.", - "Origin is unknown. Can you be a bit more descriptive?": "Avreisested er ukjent. Kan du spesifisere nærmere?", - "Destination is unknown. Can you be a bit more descriptive?": "Reisemålet er ukjent. Kan du spesifisere nærmere?", - "Both origin and destination are unknown. Can you be a bit more descriptive?": "Både fra/til sted er ukjent. Kan du spesifisere nærmere?", - "Both origin and destination are not wheelchair accessible": "Både fra/til sted er utilgjengelig for rullestolukjent.", - "Origin is within a trivial distance of the destination.": "Du kan klare å gå? Det er bare noen få meter.", - "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.", - "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.", - "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "Both origin and destination are ambiguous. Please select from the following options, or be more specific.", - "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are", - "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1", - "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE", - "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set", - "Set as Start Location": "Reis herfra", - "Set as End Location": "Reis hit", - "Destination": "Destinasjon", - "Error %(error_id)d": "Feil %(error_id)d", - "No Trip Found": "Ingen tur tilgjenglig", - "Your %(bike_share_name)s route": "Din %(bike_share_name)s rute", - "Your bike route": "Din sykkel rute", - "Walk to the %(bike_share_name)s dock.": "Gå til %(bike_share_name)s sykkelstativ.", - "Walk from the %(bike_share_name)s dock to your destination.": "Walk from the %(bike_share_name)s dock to your destination.", - "Your walk route": "Your walk route", - "Your route using the scooter": "", - "Your driving route": "Din sykkel rute", - "north": "nord", - "northeast": "nordøst", - "east": "øst", - "southeast": "sørøst", - "south": "sør", - "southwest": "sørvest", - "west": "vest", - "northwest": "nordvest", - "hard left": "skart venstre", - "left": "venstre", - "slight left": "svakt venstre", - "continue": "fortsett", - "slight right": "svakt høyre", - "right": "høyre", - "hard right": "skart høyre", - "elevator": "heis", - "U-turn left": "U-sving venstre", - "U-turn right": "U-sving høyre", - "Walk": "Gå", - "Cycle": "Sykkel", - "Car": "Bil", - "Bus": "Buss", - "Subway": "T-bane", - "Train": "Tog", - "Ferry": "Ferje", - "Light Rail": "Trikk", - "Cable Car": "Cable Car", - "Funicular": "Kabelbane", - "Aerial Tram": "Tau bane", - "Airplane": "Fly", - "Bicycle rental station": "Bysykkelstativ", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Følg rundkjøringen mot klokka ta %(ordinal_exit_number)s avkjøring til %(street_name)s", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Følg rundkjøring mot klokka, ta %(ordinal_exit_number)s avkjøring til %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Følg rundkjøring med klokka, ta %(ordinal_exit_number)s avkjøring til %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Følg rundkjøring med klokka, ta %(ordinal_exit_number)s avkjøring til %(street_name)s", - "Start on": "Start fra", - " heading ": " mot ", - "to continue on": "fortsett på", - "on to": "på", - "first": "første", - "second": "andre", - "third": "tredje", - "fourth": "fjerde", - "fifth": "femte", - "sixth": "sjette", - "seventh": "syvende", - "eight": "åttende", - "ninth": "niende", - "tenth": "tidende", - "%d hr": "%d time", - "%d hr_plural": "%d timer", - "%d min": "%d minutt", - "%d min_plural": "%d minutter", - "%d sec": "%d sekund", - "%d sec_plural": "%d sekunder", - "OK": "OK", - "Minimize": "Minimer vinduer", - "Bring to front": "Flytt fremst", - "Send to back": "Flytt bakerst", - "Route:": "Rute:", - "Variant:": "Alternativ:", - "Stop Finder": "Søk Stoppested", - "Feed": "Agency", - "By ID": "Med ID", - "By Name": "Med Navn", - "Search": "Søk", - "No Stops Found": "Stoppested ikke funnet", - "Date": "Date", - "Find Stops": "Søk Stoppested", - "(No Stop Selected)": "(Ingen Stoppested valgt)", - "Block": "Block", - "Recenter": "Sentrer", - "Viewer": "Vis", - "Quick": "Rask", - "Flat": "Flat", - "Bike Friendly": "Sykkel vennlig", - "B": "B", - "F": "F", - "Q": "R", - "All Routes": "Alle Ruter", - "Save": "Lagre", - "Close": "Lukk", - "Travel Options": "Reise Resultater", - "Geocoder": "Geocoder", - "Arrive": "Ankomst", - "Now": "Nå", - "Wheelchair accessible trip:": "Tilgjenelig for rullestol:", - "Show Filtered Itineraries:": "", - "Travel by": "Reis med", - "Preferred Routes": "Foretrukket rute", - "Edit": "Endre", - "None": "Ingen", - "Weight": "Weight", - "Banned routes": "Untatt rute", - "Use": "Bruk", - "My Own Bike": "Egen Sykkel", - "A Shared Bike": "Bysykkel", - "Plan Your Trip": "Planlegg Reise", - "Additional parameters": "", - " to _direction": " til ", - " to _bus_direction": " til ", - "Start_template": "Fra", - "Depart_itinerary": "Avgang", - "depart_itinerary": "Avreise", - "Start_popup": "Start", - "Depart_tripoptions": "Avgang" -} \ No newline at end of file diff --git a/src/client/classic-debug/js/otp/locale/pl.json b/src/client/classic-debug/js/otp/locale/pl.json deleted file mode 100644 index 5cf5a9c71b5..00000000000 --- a/src/client/classic-debug/js/otp/locale/pl.json +++ /dev/null @@ -1,247 +0,0 @@ -{ - "Transit": "komunikacją publiczną", - "Bus Only": "wyłącznie autobusami", - "Rail Only": "wyłącznie koleją", - "Airplane Only": "", - "Transit, No Airplane": "", - "Bicycle Only": "wyłącznie rowerem", - "Bicycle & Transit": "rowerem & komunikacją publiczną", - "Walk Only": "wyłącznie pieszo", - "Car Only": "Rozpocznij na ulicy", - "Taxi": "", - "Park and Ride": "schemat P+R (Park and Ride)", - "Ride and Kiss (Car Pickup)": "", - "Kiss and Ride (Car Dropoff)": "", - "Bike and Ride": "schemat B+R (Bike and Ride)", - "Rented Bicycle": "wypożyczonym rowerem", - "Transit & Rented Bicycle": "kom. publiczną & wypoż. rowerem", - "Rented Scooter": "", - "Transit & Rented Scooter": "kom. publiczną & wypoż. rowerem", - "Transit with flex access": "", - "Transit with flex egress": "", - "Transit with flex access and egress": "", - "Direct flex search": "", - "Recenter Map Here": "Wyśrodkuj mapę w tym miejscu", - "Zoom In": "Przybliż", - "Zoom Out": "Oddal", - "Minimize all": "Minimalizuj wszystko", - "Unminimize all": "Maskymalizuj wszystko", - "Stop Viewer": "Zatrzymaj podgląd", - "Plan Trip": "Zaplanuj podróż", - "From Stop": "Z przystanku", - "To Stop": "Do przystanku", - "Routes Serving Stop": "Trasy obsługujące dany przystanek", - "Bike Share Planner": "Planner wypożyczenia roweru", - "Trip Options": "Trasa", - "PICK UP BIKE": "WYPOŻYCZ ROWER", - "ALTERNATE PICKUP": "ALTERNATYWNY PUNKT WYPOŻYCZENIA", - "DROP OFF BIKE": "ODDAJ ROWER", - "ALTERNATE DROP OFF": "ALTERNATYWNY PUNKT ODDANIA ROWERU", - "BIKE STATION": "STACJA ROWEROWA", - "Station:": "Stacja:", - "%d bike available_0": "%d dostępny rower", - "%d bike available_1": "%d dostępne rowery", - "%d bike available_2": "%d dostępnych rowerów", - "%d dock available_0": "%d dostępna stacja", - "%d dock available_1": "%d dostępne stacje", - "%d dock available_2": "%d dostępnych stacji", - "Recommended Pick Up:": "Rekomendowane miejsce wypożyczenia roweru:", - "Bicycle rental": "Wypożyczalnia rowerów", - "Recommended Drop Off:": "Rekomendowane miejsce oddania roweru:", - "Multimodal Trip Planner": "Planner Podróży", - "Itineraries": "Trasy", - "This itinerary departs on a different day from the previous one": "", - "%d Itinerary Returned_0": "%d zwrócona trasa", - "%d Itinerary Returned_1": "%d zwrócone trasy", - "%d Itinerary Returned_2": "%d zwróconych tras", - "Link to search": "Link do wyszukiwania", - "Previous Page": "Poprzednia", - "Next Page": "", - "CONTINUES AS": "POZOSTAŃ", - "%d min late_0": "%d minuta opóźnienia", - "%d min late_1": "%d minuty opóźnienia", - "%d min late_2": "%d minut opóźnienia", - "%d min early_0": "%d minuta przed czasem", - "%d min early_1": "%d minuty przed czasem", - "%d min early_2": "%d minut przed czasem", - "on time": "na czas", - "This itinerary departs on a different day than the one searched for": "", - "Arrived at destination with a rented bicycle!": "", - "End": "Koniec", - "Trip Summary": "Podsumowanie podróży", - "Travel": "Podróż", - "Time": "Czas trwania podróży", - "GenCost": "", - "Total Walk": "Długość trasy do pokonania pieszo", - "Total Bike": "Długośc trasy do pokonania rowerem", - "Total drive": "", - "Elevation Gained": "", - "Elevation Lost": "", - "Transfers": "Przesiadki", - "Fare": "Koszt", - "Valid": "Aktualna", - "Link to Itinerary": "Link do trasy", - "Print": "Drukuj", - "Your Trip": "Zaplanowana podróż", - "Email": "Adres e-mail", - "every %d min_0": "co %d minutę", - "every %d min_1": "co %d minuty", - "every %d min_2": "co %d minut", - "Board at ": "Wyjazd o", - "Stop": "Przystanek", - "Time in transit": "Czas spędzony w komunikacji publicznej", - "Route ID": "", - "Trip ID": "", - "Service Date": "", - "Trip Viewer": "Podgląd podróży", - "late as": "dopiero jak", - "Stay on board": "Kontynuuj podróż", - "Alight": "Wysiądź", - "at": "na przystanku", - "%(currency)s %(price)s": "%(currency)s %(price)s", - "Start: %(location)s at %(time_date)s": "Początek: %(location)s o %(time_date)s", - "Board": "Wyjazd", - "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s ID przystanku #%(stop_id)s),", - "End: %(location)s at %(time_date)s": "Koniec: %(location)s o %(time_date)s", - "(%(agencyId)s Stop ID #%(id)s),": "", - "\nView itinerary online:\n%(itinerary_link)s\n": "\nWyświetl trasę w trybie online:\n%(itinerary_link)s\n", - "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Przepraszamy. Planer podróży jest obecnie niedostępny. Prosimy o ponowienie próby w późniejszym czasie.", - "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", - "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", - "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Brak informacji o rozkładzie komunikacji publicznej. Obowiązujące dane mogą być nieaktualne, bądź niekompatybilne w wybranym czasie z zaplanowaną trasą.", - "The trip planner is taking way too long to process your request. Please try again later.": "Planer podróży nie jest w stanie przetwożyć powierzonego mu zadania. Prosimy o ponowienie próby w późniejszym czasie.", - "The request has errors that the server is not willing or able to process.": "Wybrane zapytanie posiada błędy, których serwer nie jest w stanie obsłużyć.", - "Origin is unknown. Can you be a bit more descriptive?": "Wystąpił problem z określeniem lokalizacji startowej. Czy mógłbyś sprecyzować zapytanie?", - "Destination is unknown. Can you be a bit more descriptive?": "Wystąpił problem z określeniem lokalizacji końcowej. Czy mógłbyś sprecyzować zapytanie?", - "Both origin and destination are unknown. Can you be a bit more descriptive?": "Wystąpił problem z określeniem lokalizacji startowej oraz końcowej. Czy mógłbyś sprecyzować zapytanie?", - "Both origin and destination are not wheelchair accessible": "Zarówno lokalizacja startowa, jak i końcowa, nie oferuje udogodnień dla osób niepełnosprawnych.", - "Origin is within a trivial distance of the destination.": "Lokalizacja początkowa jest zlokalizowana w nieznacznej odległości od miejsca docelowego.", - "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "Planer podróży nie może zinterpretować lokalizacji początkowej. Prosimy o wybranie jednej z poniższych opcji, bądź sprecyzować zapytanie.", - "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "Planer podróży nie może zinterpretować lokalizacji końcowej. Prosimy o wybranie jednej z poniższych opcji, bądź sprecyzować zapytanie.", - "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "Zarówno lokalizacja początkowa, jak i końcowa nie została poprawnie ziterpretowana przez planer podróży. Prosimy o wybranie pozycji dostępnych na liście poniżej, bądź sprecyzować zapytanie.", - "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "Każdy z parametrów triangleSafetyFactor (bezpieczeństwo), triangleSlopeFactor (nachylenie) i triangleTimeFactor (czas) musi zostać ustawiony, jeśli na trasie znajdują się dane punkty.", - "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "Suma wartości w parametrach triangleSafetyFactor, triangleSlopeFactor i triangleTimeFactor musi wynieśc równo 1.", - "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "Jeśli zostały wprowadzone parametry triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor, wartość OptimizeType musi wskazywać na TRIANGLE (TRÓJKĄT)", - "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "Jeśli wartość pola OptimizeType wskazuje na TRIANGLE (TRÓJKĄT), należy podać parametry zmiennych triangleSafetyFactor, triangleSlopeFactor oraz triangleTimeFactor.", - "Set as Start Location": "Wybierz jako punkt początkowy", - "Set as End Location": "Wybierz jako punkt końcowy", - "Destination": "Cel", - "Error %(error_id)d": "Błąd %(error_id)d", - "No Trip Found": "Trasa nie została wyznaczona", - "Your %(bike_share_name)s route": "Twoja trasa : %(bike_share_name)s", - "Your bike route": "Trasa pokonana rowerem", - "Walk to the %(bike_share_name)s dock.": "Przejdź do doku %(bike_share_name)s", - "Walk from the %(bike_share_name)s dock to your destination.": "Przejdź z doku %(bike_share_name)s do punktu docelowego", - "Your walk route": "Trasa pokonana pieszo", - "Your route using the scooter": "", - "Your driving route": "Trasa pokonana rowerem", - "north": "północ", - "northeast": "północny wschód", - "east": "wschód", - "southeast": "południowy wschód", - "south": "południe", - "southwest": "południowy zachód", - "west": "zachód", - "northwest": "północny zachód", - "hard left": "ostro w lewo", - "left": "lewo", - "slight left": "łagodnie w lewo", - "continue": "utrzymuj kierunek", - "slight right": "łagodnie w prawo", - "right": "prawo", - "hard right": "ostro w prawo", - "elevator": "wzniesienie", - "U-turn left": "nawrót w lewo", - "U-turn right": "nawrót w prawo", - "Walk": "Spacer", - "Cycle": "Rower", - "Car": "Samochód", - "Bus": "Autobus", - "Subway": "Metro", - "Train": "Pociąg", - "Ferry": "Prom", - "Light Rail": "Light Rail", - "Cable Car": "Kolejka linowa", - "Funicular": "Kolej linowo-terenowa", - "Aerial Tram": "Kolej linowa", - "Airplane": "", - "Bicycle rental station": "Stacja wypożyczalni rowerów", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Przejedź przez rondo przeciwnie do ruchów wskazówki zegara do %(ordinal_exit_number)s wyjazdu na ulicę %(street_name)s", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Przejedź przez rondo przeciwnie do ruchów wskazówki zegara do %(ordinal_exit_number)s wyjazdu na ulicę %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Przejedź przez rondo zgodnie z ruchem wskazówki zegara do %(ordinal_exit_number)s wyjazdu na ulicę %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Przejedź przez rondo zgodnie z ruchem wskazówki zegara do %(ordinal_exit_number)s wyjazdu na ulicę %(street_name)s", - "Start on": "Rozpocznij na ulicy", - " heading ": "kierując się na", - "to continue on": "kieruj się w stronę", - "on to": "ulicy", - "first": "pierwszego", - "second": "drugiego", - "third": "trzeciego", - "fourth": "czwartego", - "fifth": "piątego", - "sixth": "szóstego", - "seventh": "siódmego", - "eight": "ósmego", - "ninth": "dziewiątego", - "tenth": "dziesiątego", - "%d hr_0": "%d h", - "%d hr_1": "%d h", - "%d hr_2": "%d h", - "%d min_0": "%d min", - "%d min_1": "%d min", - "%d min_2": "%d min", - "%d sec_0": "%d sek", - "%d sec_1": "%d sek", - "%d sec_2": "%d sek", - "OK": "OK", - "Minimize": "Minimalizuj", - "Bring to front": "Przenieś na wierzch", - "Send to back": "Przesuń na spód", - "Route:": "Trasa przejazdu:", - "Variant:": "Wariant:", - "Stop Finder": "Wyszukiwarka przystanków", - "Feed": "Agencja", - "By ID": "ID", - "By Name": "Nazwa", - "Search": "Szukaj", - "No Stops Found": "Nie znaleziono przystanków", - "Date": "Data", - "Find Stops": "Wyszukaj przystanki", - "(No Stop Selected)": "Nie wybrano przystanków", - "Block": "Zablokuj", - "Recenter": "Wyśrodkuj", - "Viewer": "Podgląd", - "Quick": "Szybki", - "Flat": "Równy teren", - "Bike Friendly": "Przyjazny dla rowerzystów", - "B": "B", - "F": "F", - "Q": "Q", - "All Routes": "Wszystkie trasy", - "Save": "Zapisz", - "Close": "Zamknij", - "Travel Options": "Opcje podróży", - "Geocoder": "Geocoder", - "Arrive": "Czas przyjazdu", - "Now": "Teraz", - "Wheelchair accessible trip:": "Wycieczka zawierająca udogodnienia dla osób niepełnosprawnych", - "Show Filtered Itineraries:": "", - "Travel by": "Podróżuj", - "Preferred Routes": "Preferowane trasy", - "Edit": "Edytuj", - "None": "Brak", - "Weight": "Waga", - "Banned routes": "Wyłączone trasy", - "Use": "Użyj", - "My Own Bike": "własnego roweru", - "A Shared Bike": "wypożyczonego roweru", - "Plan Your Trip": "Zaplanuj swoją podróż", - "Additional parameters": "", - " to _direction": "w kierunku", - " to _bus_direction": "w kierunku", - "Start_template": "Start", - "Depart_itinerary": "Wyjazd ze stacji", - "depart_itinerary": "odjazd", - "Start_popup": "Początek", - "Depart_tripoptions": "Czas wyjazdu" -} \ No newline at end of file diff --git a/src/client/classic-debug/js/otp/locale/pt.json b/src/client/classic-debug/js/otp/locale/pt.json deleted file mode 100644 index 9d15e4afe1a..00000000000 --- a/src/client/classic-debug/js/otp/locale/pt.json +++ /dev/null @@ -1,238 +0,0 @@ -{ - "Transit": "Vários", - "Bus Only": "Autocarro apenas", - "Rail Only": "Só ferroviário", - "Airplane Only": "", - "Transit, No Airplane": "", - "Bicycle Only": "Bicicleta apenas", - "Bicycle & Transit": "Bicicleta & vários", - "Walk Only": "Só a pé", - "Car Only": "Origem em", - "Taxi": "", - "Park and Ride": "Estacionar e conduzir", - "Ride and Kiss (Car Pickup)": "", - "Kiss and Ride (Car Dropoff)": "", - "Bike and Ride": "Bicicleta e conduzir", - "Rented Bicycle": "Bicicleta alugada", - "Transit & Rented Bicycle": "Vários & bicicletas alugadas", - "Rented Scooter": "", - "Transit & Rented Scooter": "Vários & bicicletas alugadas", - "Transit with flex access": "", - "Transit with flex egress": "", - "Transit with flex access and egress": "", - "Direct flex search": "", - "Recenter Map Here": "Mapa mais recente aqui", - "Zoom In": "Zoom In", - "Zoom Out": "Zoom Out", - "Minimize all": "Minimizar tudo", - "Unminimize all": "Maximizar tudo", - "Stop Viewer": "Visualizardor de paragens", - "Plan Trip": "Planear rota", - "From Stop": "Da paragem", - "To Stop": "Para a paragem", - "Routes Serving Stop": "Paragens servindo as linhas", - "Bike Share Planner": "Planeador de partilha de bicicletas", - "Trip Options": "Opções de viagem", - "PICK UP BIKE": "APANHAR UMA BICICLETA", - "ALTERNATE PICKUP": "APANHAR DE BICICLETA ALTERNATIVO", - "DROP OFF BIKE": "LARGAR A BICICLETA", - "ALTERNATE DROP OFF": "LARGAR DE BICICLETA ALTERNATIVO", - "BIKE STATION": "ESTAÇÃO DE BICICLETAS", - "Station:": "Estação:", - "%d bike available": "%d bicicleta disponível", - "%d bike available_plural": "%d bicicletas disponíveis", - "%d dock available": "%d dock disponível", - "%d dock available_plural": "%d docks disponíveis", - "Recommended Pick Up:": "Apanhar de bicicleta recomendado:", - "Bicycle rental": "Aluguer de bicicletas", - "Recommended Drop Off:": "Largar de bicicleta recomendado:", - "Multimodal Trip Planner": "Planeador de rotas multi-modal", - "Itineraries": "Itinerários", - "This itinerary departs on a different day from the previous one": "", - "%d Itinerary Returned": "%d Itinerário devolvido", - "%d Itinerary Returned_plural": "%d Itinerários devolvidos", - "Link to search": "Link para pesquisa", - "Previous Page": "Anterior", - "Next Page": "", - "CONTINUES AS": "CONTINUAR COMO", - "%d min late": "%d min mais tarde", - "%d min late_plural": "%d mins mais tarde", - "%d min early": "%d min mais cedo", - "%d min early_plural": "%d mins mais cedo", - "on time": "a tempo", - "This itinerary departs on a different day than the one searched for": "", - "Arrived at destination with a rented bicycle!": "", - "End": "Destino", - "Trip Summary": "Sumário da rota", - "Travel": "Viagem", - "Time": "Tempo", - "GenCost": "", - "Total Walk": "Total a pé", - "Total Bike": "Total de bicicleta", - "Total drive": "", - "Elevation Gained": "", - "Elevation Lost": "", - "Transfers": "Transferências", - "Fare": "Tarifa", - "Valid": "Válido", - "Link to Itinerary": "Link para o itenerário", - "Print": "Imprimir", - "Your Trip": "A tua rota", - "Email": "Email", - "every %d min": "A cada %d min", - "every %d min_plural": " A cada %d mins", - "Board at ": "Entrar às", - "Stop": "Paragem", - "Time in transit": "Tempo em viagem", - "Route ID": "", - "Trip ID": "", - "Service Date": "", - "Trip Viewer": "Visualizador de rotas", - "late as": "tão tarde como", - "Stay on board": "Mantenha-se em viagem", - "Alight": "Iluminado", - "at": "às", - "%(currency)s %(price)s": "%(currency)s %(price)s", - "Start: %(location)s at %(time_date)s": "Partida: %(location)s às %(time_date)s", - "Board": "Entrar", - "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s ID Paragem #%(stop_id)s),", - "End: %(location)s at %(time_date)s": "Destino: %(location)s at %(time_date)s", - "(%(agencyId)s Stop ID #%(id)s),": "", - "\nView itinerary online:\n%(itinerary_link)s\n": "\nVer itinerário online:\n%(itinerary_link)s\n", - "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Pedimos desculpa. O planeador de rotas está temporariamente indisponível. Tente mais tarde.", - "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", - "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", - "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Não há tempos de trânsito disponíveis. Não há informação acerca dos transportes para esta data.", - "The trip planner is taking way too long to process your request. Please try again later.": "O planeador de rotas está a demorar demasiado tempo para processar o seu pedido. Tente mais tarde.", - "The request has errors that the server is not willing or able to process.": "O seu pedido tem erros e o servidor não está a conseguir processá-lo.", - "Origin is unknown. Can you be a bit more descriptive?": "Origem desconhecida. Pode ser mais descritivo?", - "Destination is unknown. Can you be a bit more descriptive?": "Destino indisponível. Pode ser mais descritivo?", - "Both origin and destination are unknown. Can you be a bit more descriptive?": "Origem e destino desconhecidos. Pode ser mais descritivo?", - "Both origin and destination are not wheelchair accessible": "Origem e destino não acessível a cadeiras de rodas.", - "Origin is within a trivial distance of the destination.": "Origem a uma distância demasiado pequena do destino.", - "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "O planeador de rotas está inseguro em relação à localização da sua origem. Selecione uma das seguintes opções ou seja mais específico.", - "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "O planeador de rotas está inseguro em relação à localização do seu destino. Selecione uma das seguintes opções ou seja mais específico.", - "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "Origem e destino ambíguos. Selecione uma das seguintes opções ou seja mais específico.", - "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "Todo o triangleSafetyFactor, triangleSlopeFactor, e triangleTimeFactor deve ser definido se algum for", - "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "Os valores de triangleSafetyFactor, triangleSlopeFactor, e triangleTimeFactor devem somar com valor 1", - "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "Se o triangleSafetyFactor, triangleSlopeFactor, e triangleTimeFactor forem fornecidos, OptimizeType deve ser um TRIANGLE", - "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "Se OptimizeType é TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, e triangleTimeFactor devem ser definidos", - "Set as Start Location": "Definir como local de origem", - "Set as End Location": "Definir como local de destino", - "Destination": "Destino", - "Error %(error_id)d": "Erro %(error_id)d", - "No Trip Found": "Nenhuma rota encontrada", - "Your %(bike_share_name)s route": "A sua rota %(bike_share_name)s ", - "Your bike route": "A sua rota de bicicleta", - "Walk to the %(bike_share_name)s dock.": "Andar para a dock %(bike_share_name)s .", - "Walk from the %(bike_share_name)s dock to your destination.": "Andar da dock %(bike_share_name)s para o seu destino.", - "Your walk route": "A sua rota a pé", - "Your route using the scooter": "", - "Your driving route": "A sua rota de bicicleta", - "north": "norte", - "northeast": "nordeste", - "east": "este", - "southeast": "sudeste", - "south": "sul", - "southwest": "sudoeste", - "west": "oeste", - "northwest": "nordeste", - "hard left": "esquerda apertada", - "left": "esquerda", - "slight left": "esquerda ligeira", - "continue": "continuar", - "slight right": "direita ligeira", - "right": "direita", - "hard right": "direita apertada", - "elevator": "elevador", - "U-turn left": "cotovelo à esquerda", - "U-turn right": "cotovelo à direita", - "Walk": "A pé", - "Cycle": "Bicicleta", - "Car": "Carro", - "Bus": "Autocarro", - "Subway": "Metro", - "Train": "Comboio", - "Ferry": "Ferry", - "Light Rail": "Ferroviário leve", - "Cable Car": "Eléctrico", - "Funicular": "Teleférico", - "Aerial Tram": "Teleférico", - "Airplane": "", - "Bicycle rental station": "Estação de aluguer de bicicletas", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Entrar na rotuda no sentido contrário aos ponteiros do relógio na %(ordinal_exit_number)s saída em direção a %(street_name)s", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Entrar na rotunda no sentido contrário aos ponteiros do relógio, na %(ordinal_exit_number)s saída em direcção a %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Entrar na rotuda no sentido dos ponteiros do relógio na %(ordinal_exit_number)s saída em direção a %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "Entrar na rotunda no sentido dos ponteiros do relógio, na %(ordinal_exit_number)s saída em direcção a %(street_name)s", - "Start on": "Origem em", - " heading ": "em direcção a", - "to continue on": "a continuar em", - "on to": "para", - "first": "primeiro", - "second": "segundo", - "third": "terceiro", - "fourth": "quarto", - "fifth": "quinto", - "sixth": "sexto", - "seventh": "sétimo", - "eight": "oitavo", - "ninth": "nono", - "tenth": "décimo", - "%d hr": "%d hr", - "%d hr_plural": "%d hrs", - "%d min": "%d min", - "%d min_plural": "%d mins", - "%d sec": "%d sec", - "%d sec_plural": "%d secs", - "OK": "OK", - "Minimize": "Minimzar", - "Bring to front": "Trazer prá frente", - "Send to back": "Mandar para trás", - "Route:": "Rota:", - "Variant:": "Variante:", - "Stop Finder": "Pesquisar paragem", - "Feed": "Companhia", - "By ID": "Por ID", - "By Name": "Por Nome", - "Search": "Pesquisar", - "No Stops Found": "Nenhuma paragem encontrada", - "Date": "Data", - "Find Stops": "Procurar paragens", - "(No Stop Selected)": "(Nenhuma paragem selecionada)", - "Block": "Bloquear", - "Recenter": "Mais recente", - "Viewer": "Visualizador", - "Quick": "Rápido", - "Flat": "Plano", - "Bike Friendly": "Amigo às bicicletas", - "B": "B", - "F": "F", - "Q": "Q", - "All Routes": "Todas as rotas", - "Save": "Guardar", - "Close": "Fechar", - "Travel Options": "Opções de viagem", - "Geocoder": "Geocoder", - "Arrive": "Chegada", - "Now": "Agora", - "Wheelchair accessible trip:": "Rota acessível a cadeira de rodas", - "Show Filtered Itineraries:": "", - "Travel by": "Viagem por", - "Preferred Routes": "Rotas favoritas", - "Edit": "Editar", - "None": "Nenhum", - "Weight": "Peso", - "Banned routes": "Rotas banidas", - "Use": "Utilizar", - "My Own Bike": "A minha bicicleta", - "A Shared Bike": "Uma bicicleta partilhada", - "Plan Your Trip": "Planear a sua viagem", - "Additional parameters": "", - " to _direction": "Para", - " to _bus_direction": "Para", - "Start_template": "Começar", - "Depart_itinerary": "Partida", - "depart_itinerary": "partida", - "Start_popup": "Origem", - "Depart_tripoptions": "Partir" -} \ No newline at end of file diff --git a/src/client/classic-debug/js/otp/locale/sl.json b/src/client/classic-debug/js/otp/locale/sl.json deleted file mode 100644 index c99ad81f704..00000000000 --- a/src/client/classic-debug/js/otp/locale/sl.json +++ /dev/null @@ -1,256 +0,0 @@ -{ - "Transit": "Javni prevoz", - "Bus Only": "Avtobus", - "Rail Only": "Vlak", - "Airplane Only": "", - "Transit, No Airplane": "", - "Bicycle Only": "Kolo", - "Bicycle & Transit": "Kolo & Javni prevoz", - "Walk Only": "Pešačenje", - "Car Only": "Začnite na", - "Taxi": "", - "Park and Ride": "Parkiraj in se pelji", - "Ride and Kiss (Car Pickup)": "", - "Kiss and Ride (Car Dropoff)": "", - "Bike and Ride": "", - "Rented Bicycle": "Izposojeno kolo", - "Transit & Rented Bicycle": "Izposojeno kolo & Javni prevoz", - "Rented Scooter": "", - "Transit & Rented Scooter": "Izposojeno kolo & Javni prevoz", - "Transit with flex access": "", - "Transit with flex egress": "", - "Transit with flex access and egress": "", - "Direct flex search": "", - "Recenter Map Here": "Prikaži karto tukaj", - "Zoom In": "Približaj", - "Zoom Out": "Oddalji", - "Minimize all": "Skrči vse", - "Unminimize all": "Razširi vse", - "Stop Viewer": "Pregledovalnik postaj", - "Plan Trip": "Načrtuj pot", - "From Stop": "Začetna postaja", - "To Stop": "Končna postaja", - "Routes Serving Stop": "Avtobusi, ki ustavljajo na postaji", - "Bike Share Planner": "Planer za izposojena kolesa", - "Trip Options": "Nastavitve poti", - "PICK UP BIKE": "IZPOSOJA KOLESA", - "ALTERNATE PICKUP": "ALTERNATIVNO MESTO IZPOSOJE", - "DROP OFF BIKE": "VRNITEV KOLESA", - "ALTERNATE DROP OFF": "ALTERNATIVNO MESTO VRNITVE KOLESA", - "BIKE STATION": "IZPOSOJEVALNA POSTAJA", - "Station:": "Postaja:", - "%d bike available_0": "%d koles na voljo", - "%d bike available_1": "%d kolo na voljo", - "%d bike available_2": "%d kolesi na voljo", - "%d bike available_3": "%d kolesa na voljo", - "%d dock available_0": "%d prostorov na voljo", - "%d dock available_1": "%d prostor na voljo", - "%d dock available_2": "%d prostora na voljo", - "%d dock available_3": "%d prostori na voljo", - "Recommended Pick Up:": "Predlagana postaja za izposojo kolesa:", - "Bicycle rental": "postaje za izposojo koles", - "Recommended Drop Off:": "Predlagana postaja za vrnitev kolesa:", - "Multimodal Trip Planner": "Načrtovalnik poti", - "Itineraries": "Načrti poti", - "This itinerary departs on a different day from the previous one": "", - "%d Itinerary Returned_0": "%d vrnjenih načrtov poti", - "%d Itinerary Returned_1": "%d vrnjen načrt poti", - "%d Itinerary Returned_2": "%d vrnjena načrta poti", - "%d Itinerary Returned_3": "%d vrnjeni načrti poti", - "Link to search": "Iskanje", - "Previous Page": "Prejšnja", - "Next Page": "", - "CONTINUES AS": "SE NADALJUJE KOT", - "%d min late_0": "%d min. zamude", - "%d min late_1": "%d min. zamude", - "%d min late_2": "%d min. zamude", - "%d min late_3": "%d min. zamude", - "%d min early_0": "%d min. prehitro", - "%d min early_1": "%d min. prehitro", - "%d min early_2": "%d min. prehitro", - "%d min early_3": "%d min. prehitro", - "on time": "pravočasno", - "This itinerary departs on a different day than the one searched for": "", - "Arrived at destination with a rented bicycle!": "", - "End": "Konec", - "Trip Summary": "Povzetek poti", - "Travel": "Potuj ob", - "Time": "Trajanje", - "GenCost": "", - "Total Walk": "Skupno hoje", - "Total Bike": "Skupno kolesarjenja", - "Total drive": "", - "Elevation Gained": "", - "Elevation Lost": "", - "Transfers": "Št. prestopov", - "Fare": "Cena", - "Valid": "Veljavno", - "Link to Itinerary": "Načrt poti", - "Print": "Natisni", - "Your Trip": "Vaša pot", - "Email": "E-pošta", - "every %d min_0": "vsakih %d min", - "every %d min_1": "vsako %d min", - "every %d min_2": "vsaki %d min", - "every %d min_3": "vsake %d min", - "Board at ": "Vstop na ", - "Stop": "Postaja", - "Time in transit": "Časa na vožnji", - "Route ID": "", - "Trip ID": "", - "Service Date": "", - "Trip Viewer": "Pregledovalnik poti", - "late as": "", - "Stay on board": "Ostanite v vozilu", - "Alight": "Izstop", - "at": "na", - "%(currency)s %(price)s": "%(price)s %(currency)s", - "Start: %(location)s at %(time_date)s": "Začetek: %(location)s ob %(time_date)s", - "Board": "Vstop", - "(%(agency_id)s Stop ID #%(stop_id)s),": "(%(agency_id)s),", - "End: %(location)s at %(time_date)s": "Konec: %(location)s ob %(time_date)s", - "(%(agencyId)s Stop ID #%(id)s),": "", - "\nView itinerary online:\n%(itinerary_link)s\n": "\nOglejte si načrt poti na spletu:\n%(itinerary_link)s\n", - "We're sorry. The trip planner is temporarily unavailable. Please try again later.": "Opravičujemo se. Daljinar trenutno ni na voljo. Prosimo poskusite kasneje.", - "Trip is not possible. You might be trying to plan a trip outside the map data boundary.": "", - "No trip found. There may be no transit service within the maximum specified distance or at the specified time, or your start or end point might not be safely accessible.": "", - "No transit times available. The date may be past or too far in the future or there may not be transit service for your trip at the time you chose.": "Podatki o voznih redih niso na voljo. Mogoče je datum preveč v preteklosti ali prihodnosti ali pa javni prevoz ne obstaja za pot, ki jo načrtujete.", - "The trip planner is taking way too long to process your request. Please try again later.": "Daljinar potrebuje preveč časa za obdelavo vašega zahtevka. Prosimo poskusite znova kasneje.", - "The request has errors that the server is not willing or able to process.": "Zahtevek ima napake, ki jih strežnik ne more obdelati.", - "Origin is unknown. Can you be a bit more descriptive?": "Začetek poti ni znan. Prosimo bodite bolj natančni.", - "Destination is unknown. Can you be a bit more descriptive?": "Konec poti ni znan. Prosimo bodite bolj natančni.", - "Both origin and destination are unknown. Can you be a bit more descriptive?": "Začetek in konec sta neznana. Prosimo bodite bolj natančni.", - "Both origin and destination are not wheelchair accessible": "Do začetka in konca ni mogoče priti z vozičkom.", - "Origin is within a trivial distance of the destination.": "Začetek je trivialno oddaljen od konec.", - "The trip planner is unsure of the location you want to start from. Please select from the following options, or be more specific.": "", - "The trip planner is unsure of the destination you want to go to. Please select from the following options, or be more specific.": "", - "Both origin and destination are ambiguous. Please select from the following options, or be more specific.": "", - "All of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set if any are": "", - "The values of triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must sum to 1": "", - "If triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor are provided, OptimizeType must be TRIANGLE": "", - "If OptimizeType is TRIANGLE, triangleSafetyFactor, triangleSlopeFactor, and triangleTimeFactor must be set": "", - "Set as Start Location": "Začetek poti", - "Set as End Location": "Konec poti", - "Destination": "Konec", - "Error %(error_id)d": "Napaka %(error_id)d", - "No Trip Found": "Ne najdemo poti", - "Your %(bike_share_name)s route": "Kolesarjenje s kolesom izposojenim pri %(bike_share_name)s", - "Your bike route": "Kolesarska pot", - "Walk to the %(bike_share_name)s dock.": "Hodite do postaje podjetja %(bike_share_name)s.", - "Walk from the %(bike_share_name)s dock to your destination.": "Hodite od postaje podjetja %(bike_share_name)s do vašega cilja.", - "Your walk route": "Pot peš", - "Your route using the scooter": "", - "Your driving route": "Kolesarska pot", - "north": "sever", - "northeast": "severovzhod", - "east": "vzhod", - "southeast": "jugovzhod", - "south": "jug", - "southwest": "jugozahod", - "west": "zahod", - "northwest": "severozahod", - "hard left": "ostro levo", - "left": "levo", - "slight left": "rahlo levo", - "continue": "nadaljujte", - "slight right": "rahlo desno", - "right": "desno", - "hard right": "ostro desno", - "elevator": "pojdite z dvigalom", - "U-turn left": "Polkrožno obrnite v levo", - "U-turn right": "Polkrožno obrnite v desno", - "Walk": "Pešačite", - "Cycle": "Kolesarite", - "Car": "Avto", - "Bus": "Avtobus", - "Subway": "Podzemna železnica", - "Train": "Vlak", - "Ferry": "", - "Light Rail": "Tramvaj", - "Cable Car": "", - "Funicular": "", - "Aerial Tram": "Gondola", - "Airplane": "", - "Bicycle rental station": "postaje za izposojo koles", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "V krožišču vozite v nasprotni smeri urinega kazalca in pri %(ordinal_exit_number)s izvozu zavijte na %(street_name)s", - "Take roundabout counterclockwise to %(ordinal_exit_number)s exit on %(street_name)s": "V krožišču vozite v nasprotni smeri urinega kazalca in pri %(ordinal_exit_number)s izvozu zavijte na %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "V krožišču vozite v smeri urinega kazalca in pri %(ordinal_exit_number)s izvozu zavijte na %(street_name)s", - "Take roundabout clockwise to %(ordinal_exit_number)s exit on %(street_name)s": "V krožišču vozite v smeri urinega kazalca in pri %(ordinal_exit_number)s izvozu zavijte na %(street_name)s", - "Start on": "Začnite na", - " heading ": " v smeri ", - "to continue on": "nadaljujte na", - "on to": "na", - "first": "prvem", - "second": "drugem", - "third": "tretjem", - "fourth": "četrtem", - "fifth": "petem", - "sixth": "šestem", - "seventh": "sedmem", - "eight": "osmem", - "ninth": "devetem", - "tenth": "desetem", - "%d hr_0": "%d ur", - "%d hr_1": "%d ura", - "%d hr_2": "%d uri", - "%d hr_3": "%d ure", - "%d min_0": "%d min.", - "%d min_1": "%d min.", - "%d min_2": "%d min.", - "%d min_3": "%d min.", - "%d sec_0": "%d sek.", - "%d sec_1": "%d sek.", - "%d sec_2": "%d sek.", - "%d sec_3": "%d sek.", - "OK": "V redu", - "Minimize": "Skrči", - "Bring to front": "Postavi v ospredje", - "Send to back": "Pošlji v ozadje", - "Route:": "Linija:", - "Variant:": "Različica:", - "Stop Finder": "Iskalnik postaj", - "Feed": "", - "By ID": "Po ID-ju", - "By Name": "Po imenu", - "Search": "Poišči", - "No Stops Found": "Ni najdenih postaj", - "Date": "Datum", - "Find Stops": "Poišči postaje", - "(No Stop Selected)": "(Nobena postaja ni bila izbrana)", - "Block": "Blok", - "Recenter": "Prikaži na karti", - "Viewer": "Pregledovalnik", - "Quick": "Hitro", - "Flat": "Položno", - "Bike Friendly": "Kolesarju prijazno", - "B": "K", - "F": "P", - "Q": "H", - "All Routes": "Vse linije", - "Save": "Shrani", - "Close": "Zapri", - "Travel Options": "Možnosti potovanja", - "Geocoder": "", - "Arrive": "Prihod do", - "Now": "Zdaj", - "Wheelchair accessible trip:": "Primerno za invalidske vozičke:", - "Show Filtered Itineraries:": "", - "Travel by": "Način potovanja ", - "Preferred Routes": "Priljubljene linije", - "Edit": "Uredi", - "None": "Brez", - "Weight": "Utež", - "Banned routes": "Neželene linije", - "Use": "Uporabi", - "My Own Bike": "Lastno kolo", - "A Shared Bike": "Izposojeno kolo", - "Plan Your Trip": "Načrtuj pot", - "Additional parameters": "", - " to _direction": " do ", - " to _bus_direction": " smer ", - "Start_template": "Začetek", - "Depart_itinerary": "Odhod", - "depart_itinerary": "začni pot", - "Start_popup": "Začetek", - "Depart_tripoptions": "Odhod ob" -} \ No newline at end of file diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/FlexStopTimesForTest.java b/src/ext-test/java/org/opentripplanner/ext/flex/FlexStopTimesForTest.java deleted file mode 100644 index 8437a62e6da..00000000000 --- a/src/ext-test/java/org/opentripplanner/ext/flex/FlexStopTimesForTest.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.opentripplanner.ext.flex; - -import static org.opentripplanner.model.StopTime.MISSING_VALUE; - -import org.opentripplanner._support.geometry.Polygons; -import org.opentripplanner.framework.time.TimeUtils; -import org.opentripplanner.model.StopTime; -import org.opentripplanner.transit.model._data.TransitModelForTest; -import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.model.site.StopLocation; - -public class FlexStopTimesForTest { - - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); - private static final StopLocation AREA_STOP = TEST_MODEL - .areaStop("area") - .withGeometry(Polygons.BERLIN) - .build(); - private static final RegularStop REGULAR_STOP = TEST_MODEL.stop("stop").build(); - - public static StopTime area(String startTime, String endTime) { - return area(AREA_STOP, endTime, startTime); - } - - public static StopTime area(StopLocation areaStop, String endTime, String startTime) { - var stopTime = new StopTime(); - stopTime.setStop(areaStop); - stopTime.setFlexWindowStart(TimeUtils.time(startTime)); - stopTime.setFlexWindowEnd(TimeUtils.time(endTime)); - return stopTime; - } - - public static StopTime regularArrival(String arrivalTime) { - return regularStopTime(TimeUtils.time(arrivalTime), MISSING_VALUE); - } - - public static StopTime regularStopTime(String arrivalTime, String departureTime) { - return regularStopTime(TimeUtils.time(arrivalTime), TimeUtils.time(departureTime)); - } - - public static StopTime regularStopTime(int arrivalTime, int departureTime) { - var stopTime = new StopTime(); - stopTime.setStop(REGULAR_STOP); - stopTime.setArrivalTime(arrivalTime); - stopTime.setDepartureTime(departureTime); - return stopTime; - } - - public static StopTime regularDeparture(String departureTime) { - return regularStopTime(MISSING_VALUE, TimeUtils.time(departureTime)); - } -} diff --git a/src/ext-test/java/org/opentripplanner/ext/vehicleparking/noi/NoiUpdaterTest.java b/src/ext-test/java/org/opentripplanner/ext/vehicleparking/noi/NoiUpdaterTest.java deleted file mode 100644 index f931e3d964e..00000000000 --- a/src/ext-test/java/org/opentripplanner/ext/vehicleparking/noi/NoiUpdaterTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.opentripplanner.ext.vehicleparking.noi; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.time.Duration; -import org.junit.jupiter.api.Test; -import org.opentripplanner.test.support.ResourceLoader; -import org.opentripplanner.updater.spi.HttpHeaders; - -class NoiUpdaterTest { - - @Test - void parse() { - var uri = ResourceLoader.of(this).uri("stations.json"); - var parameters = new NoiUpdaterParameters( - "noi", - uri, - "noi", - Duration.ofSeconds(30), - HttpHeaders.empty() - ); - var updater = new NoiUpdater(parameters); - updater.update(); - var lots = updater.getUpdates(); - - assertEquals(14, lots.size()); - - lots.forEach(l -> assertNotNull(l.getName())); - - var first = lots.getFirst(); - assertEquals("noi:105", first.getId().toString()); - assertEquals("(46.49817, 11.35726)", first.getCoordinate().toString()); - assertEquals("P05 - Laurin", first.getName().toString()); - assertEquals(57, first.getAvailability().getCarSpaces()); - assertEquals(90, first.getCapacity().getCarSpaces()); - - var last = lots.getLast(); - assertEquals( - "noi:935af00d-aa5f-eb11-9889-501ac5928d31-0.8458736393052522", - last.getId().toString() - ); - assertEquals("(46.5057, 11.3395)", last.getCoordinate().toString()); - assertEquals( - "Parksensoren Bozen - PNI Parksensor Nr.10 Commissariato - Viale Eugenio di savoia", - last.getName().toString() - ); - assertEquals(0, last.getAvailability().getCarSpaces()); - assertEquals(1, last.getCapacity().getCarSpaces()); - } -} diff --git a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/hubs.json b/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/hubs.json deleted file mode 100644 index da4c64a63fa..00000000000 --- a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/hubs.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "results": [ - { - "id": 321, - "name": { - "fi": "HubYksi", - "sv": "HubEn", - "en": "HubOne" - }, - "location": { - "crs": { - "type": "name", - "properties": { - "name": "EPSG:4326" - } - }, - "type": "Point", - "coordinates": [ - 24.804913, - 60.176064 - ] - }, - "facilityIds": [ - 990, - 1037 - ], - "address": { - "streetAddress": null, - "postalCode": null, - "city": { - "fi": "Espoo", - "sv": "Esbo", - "en": "Espoo" - } - }, - "modifiedAt": null, - "modifiedBy": null - }, - { - "id": 129, - "name": { - "fi": "HubKaksi", - "sv": "HubTvå", - "en": "HubTwo" - }, - "location": { - "crs": { - "type": "name", - "properties": { - "name": "EPSG:4326" - } - }, - "type": "Point", - "coordinates": [ - 25.101168, - 60.45744 - ] - }, - "facilityIds": [ - 894 - ], - "address": { - "streetAddress": null, - "postalCode": null, - "city": { - "fi": "Järvenpää", - "sv": "Träskända", - "en": "Järvenpää" - } - }, - "modifiedAt": null, - "modifiedBy": null - } - ], - "hasMore": false -} \ No newline at end of file diff --git a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/utilizations.json b/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/utilizations.json deleted file mode 100644 index c8c87fbe823..00000000000 --- a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/hslpark/utilizations.json +++ /dev/null @@ -1,20 +0,0 @@ -[ - { - "facilityId": 990, - "capacityType": "CAR", - "usage": "PARK_AND_RIDE", - "timestamp": "2021-12-21T08:42:39.000+02:00", - "spacesAvailable": 600, - "capacity": 1365, - "openNow": true - }, - { - "facilityId": 894, - "capacityType": "BICYCLE", - "usage": "PARK_AND_RIDE", - "timestamp": "2019-12-31T11:58:13.000+02:00", - "spacesAvailable": 43, - "capacity": 80, - "openNow": true - } -] diff --git a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/noi/stations.json b/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/noi/stations.json deleted file mode 100644 index 2bbb07ac98b..00000000000 --- a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/noi/stations.json +++ /dev/null @@ -1,159 +0,0 @@ -{ - "last_updated": 1711368767, - "ttl": 0, - "version": "3.0.0", - "data": { - "stations": [ - { - "type": "station", - "station_id": "105", - "name": "P05 - Laurin", - "lat": 46.498174, - "lon": 11.357255, - "city": "Bolzano - Bozen", - "capacity": 90, - "free": 57 - }, - { - "type": "station", - "station_id": "TRENTO:areaexsitviacanestrinip1", - "name": "Area ex SIT via Canestrini - P1", - "lat": 46.0691, - "lon": 11.1162, - "address": "Lung'Adige Monte Grappa", - "city": "Trento", - "capacity": 300, - "free": 0 - }, - { - "type": "station", - "station_id": "ROVERETO:asm", - "name": "A.S.M.", - "lat": 45.893593, - "lon": 11.036507, - "address": "Piazzale ex-A.S.M - Via Manzoni - Rovereto", - "city": "Rovereto", - "capacity": 145, - "free": 42 - }, - { - "type": "station", - "station_id": "ROVERETO:centrostorico", - "name": "Centro Storico", - "lat": 45.890306, - "lon": 11.045004, - "address": "Viale dei Colli - Rovereto", - "city": "Rovereto", - "capacity": 143, - "free": 20 - }, - { - "type": "station", - "station_id": "ROVERETO:mart", - "name": "Mart", - "lat": 45.894705, - "lon": 11.044661, - "address": "Mart - Via Sticcotta - Rovereto", - "city": "Rovereto", - "capacity": 224, - "free": 224 - }, - { - "type": "sensor", - "station_id": "001bc50670100557-0.30188412882192206", - "group_name": "area viale Druso", - "group_id": "area_viale_druso", - "name": "piazzetta Mazzoni 3", - "lat": 46.495025, - "lon": 11.347069, - "address": "area viale Druso", - "city": "Bolzano - Bozen", - "free": false - }, - { - "type": "sensor", - "station_id": "001bc50670100541-0.9632040952321754", - "group_name": "Via A. Rosmini 22-26", - "group_id": "via_a_rosmini_22_26", - "name": "Via A. Rosmini 22-26", - "lat": 46.498292, - "lon": 11.348031, - "address": "Via A. Rosmini 22-26", - "city": "Bolzano - Bozen", - "free": false - }, - { - "type": "sensor", - "station_id": "001bc50670112a6b-0.6239539554369709", - "group_name": "Via Amalfi", - "group_id": "via_amalfi", - "name": "Via Amalfi angolo Via Druso", - "lat": 46.495283, - "lon": 11.332472, - "address": "Via Amalfi", - "city": "Bolzano - Bozen", - "free": false - }, - { - "type": "sensor", - "station_id": "001bc5067010064d-0.18879954213280836", - "group_name": "area viale Druso", - "group_id": "area_viale_druso", - "name": "piazzetta Mazzoni 4", - "lat": 46.495056, - "lon": 11.347056, - "address": "area viale Druso", - "city": "Bolzano - Bozen", - "free": false - }, - { - "type": "sensor", - "station_id": "001bc50670112976-0.4989211141789258", - "group_name": "Viale Druso 237", - "group_id": "viale_druso_237", - "name": "Viale Druso 237", - "lat": 46.495, - "lon": 11.328703, - "address": "Viale Druso 237", - "city": "Bolzano - Bozen", - "free": true - }, - { - "type": "sensor", - "station_id": "9398a35b-ef3d-eb11-b9ed-0050f244b601-0.12775006754129703", - "group_id": "", - "name": "Parksensoren Bozen - PNI Parksensor Nr.3 Siegesplatz Parkplatz", - "lat": 46.501, - "lon": 11.3431, - "free": true - }, - { - "type": "sensor", - "station_id": "7776d25f-f03d-eb11-b9ed-0050f244b601-0.4355636862513992", - "group_id": "", - "name": "Parksensoren Bozen - PNI Parksensor Nr.5 DucaDaostastrasse", - "lat": 46.4953, - "lon": 11.3396, - "free": false - }, - { - "type": "sensor", - "station_id": "e3e26add-ee3d-eb11-b9ed-0050f244b601-0.8423578257530036", - "group_id": "", - "name": "Parksensoren Bozen - PNI Parksensor Nr.4 Bahnhof BZ Richtung Rittnerseilbahn", - "lat": 46.497, - "lon": 11.3583, - "free": false - }, - { - "type": "sensor", - "station_id": "935af00d-aa5f-eb11-9889-501ac5928d31-0.8458736393052522", - "group_id": "", - "name": "Parksensoren Bozen - PNI Parksensor Nr.10 Commissariato - Viale Eugenio di savoia", - "lat": 46.5057, - "lon": 11.3395, - "free": false - } - ] - } -} \ No newline at end of file diff --git a/src/ext-test/resources/smoovebikerental/smoove.json b/src/ext-test/resources/smoovebikerental/smoove.json deleted file mode 100644 index 364d947b504..00000000000 --- a/src/ext-test/resources/smoovebikerental/smoove.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "result" : [ - { - "name" : "A04 Hamn", - "operative" : true, - "coordinates" : "60.167913, 24.952269", - "style" : "Station on", - "avl_bikes" : 1, - "free_slots" : 11, - "total_slots" : 12 - }, - { - "name" : "B05 Fake", - "operative" : false, - "coordinates" : "60, 24", - "style" : "Station off", - "avl_bikes" : 5, - "free_slots" : 5, - "total_slots" : 5 - }, - { - "name" : "B06 Foo", - "operative" : true, - "coordinates" : "61,25", - "style" : "Station on", - "avl_bikes" : 5, - "free_slots" : 5, - "total_slots" : 5 - }, - { - "name" : "B08 Invalid", - "operative" : true, - "coordinates" : "", - "style" : "Station on", - "avl_bikes" : 5, - "free_slots" : 5, - "total_slots" : 5 - }, - { - "name" : "B09 Full", - "operative" : true, - "coordinates" : "60.168913, 24.953269", - "style" : "Station on", - "avl_bikes" : 12, - "free_slots" : 0, - "total_slots" : 12 - } - ] -} diff --git a/src/ext/java/org/opentripplanner/ext/datastore/gs/package-info.java b/src/ext/java/org/opentripplanner/ext/datastore/gs/package-info.java deleted file mode 100644 index 82ebac6c832..00000000000 --- a/src/ext/java/org/opentripplanner/ext/datastore/gs/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Add support for Google Cloud Storage, getting all input files and storing the graph.obj in the - * cloud. - *

    - * This implementation will use the existing {@link org.opentripplanner.standalone.config.OtpConfigLoader} - * to load config from the local disk. - */ -package org.opentripplanner.ext.datastore.gs; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/package-info.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/package-info.java deleted file mode 100644 index 7b66666ee5d..00000000000 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * This package contains the JAX-RS-annotated REST resource classes for the OpenTripPlanner public - * API, i.e. the Jersey REST endpoints. - */ -package org.opentripplanner.ext.restapi.resources; diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/noi/NoiUpdater.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/noi/NoiUpdater.java deleted file mode 100644 index d5ef7e63d13..00000000000 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/noi/NoiUpdater.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.opentripplanner.ext.vehicleparking.noi; - -import com.fasterxml.jackson.databind.JsonNode; -import org.opentripplanner.framework.geometry.WgsCoordinate; -import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.framework.tostring.ToStringBuilder; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; -import org.opentripplanner.routing.vehicle_parking.VehicleParkingState; -import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.updater.spi.GenericJsonDataSource; - -/** - * Vehicle parking updater class for NOI's open data hub format APIs. - */ -public class NoiUpdater extends GenericJsonDataSource { - - private static final String JSON_PARSE_PATH = "data/stations"; - private final NoiUpdaterParameters params; - - public NoiUpdater(NoiUpdaterParameters parameters) { - super(parameters.url().toString(), JSON_PARSE_PATH, parameters.httpHeaders()); - this.params = parameters; - } - - @Override - protected VehicleParking parseElement(JsonNode jsonNode) { - var type = jsonNode.path("type").textValue(); - VehicleParkingSpaces capacity, availability; - if (type.equals("station")) { - capacity = extractSpaces(jsonNode, "capacity"); - availability = extractSpaces(jsonNode, "free"); - } else if (type.equals("sensor")) { - capacity = VehicleParkingSpaces.builder().carSpaces(1).build(); - var isFree = jsonNode.path("free").asBoolean(); - availability = VehicleParkingSpaces.builder().carSpaces(isFree ? 1 : 0).build(); - } else { - throw new IllegalArgumentException("Unknown type '%s'".formatted(type)); - } - - var vehicleParkId = new FeedScopedId(params.feedId(), jsonNode.path("station_id").asText()); - var name = new NonLocalizedString(jsonNode.path("name").asText()); - double lat = jsonNode.path("lat").asDouble(); - double lon = jsonNode.path("lon").asDouble(); - var coordinate = new WgsCoordinate(lat, lon); - VehicleParking.VehicleParkingEntranceCreator entrance = builder -> - builder - .entranceId(new FeedScopedId(params.feedId(), vehicleParkId.getId() + "/entrance")) - .coordinate(coordinate) - .walkAccessible(true) - .carAccessible(true); - - return VehicleParking - .builder() - .id(vehicleParkId) - .name(name) - .state(VehicleParkingState.OPERATIONAL) - .coordinate(coordinate) - .capacity(capacity) - .availability(availability) - .carPlaces(true) - .entrance(entrance) - .build(); - } - - private static VehicleParkingSpaces extractSpaces(JsonNode jsonNode, String free) { - return VehicleParkingSpaces.builder().carSpaces(jsonNode.get(free).asInt()).build(); - } - - @Override - public String toString() { - return ToStringBuilder - .of(this.getClass()) - .addStr("url", this.params.url().toString()) - .toString(); - } -} diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/noi/NoiUpdaterParameters.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/noi/NoiUpdaterParameters.java deleted file mode 100644 index b34769c9dd2..00000000000 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/noi/NoiUpdaterParameters.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.opentripplanner.ext.vehicleparking.noi; - -import static org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters.UpdateType.FULL; - -import java.net.URI; -import java.time.Duration; -import org.opentripplanner.updater.spi.HttpHeaders; -import org.opentripplanner.updater.vehicle_parking.VehicleParkingSourceType; -import org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters; - -/** - * Class that extends {@link VehicleParkingUpdaterParameters} with parameters required by {@link - * NoiUpdater}. - */ -public record NoiUpdaterParameters( - String configRef, - URI url, - String feedId, - Duration frequency, - HttpHeaders httpHeaders -) - implements VehicleParkingUpdaterParameters { - @Override - public VehicleParkingSourceType sourceType() { - return VehicleParkingSourceType.NOI_OPEN_DATA_HUB; - } - - @Override - public UpdateType updateType() { - return FULL; - } -} diff --git a/src/main/java/org/opentripplanner/api/parameter/package-info.java b/src/main/java/org/opentripplanner/api/parameter/package-info.java deleted file mode 100644 index ed9df0c1f61..00000000000 --- a/src/main/java/org/opentripplanner/api/parameter/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * This package contains classes which interpret incoming HTTP query parameters. Query parameters - * arrive as Strings, and Jersey will automatically call constructors with a single String - * argument. - */ -package org.opentripplanner.api.parameter; diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/PassThroughLocationMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/mapping/PassThroughLocationMapper.java deleted file mode 100644 index 951467e8727..00000000000 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/PassThroughLocationMapper.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.opentripplanner.apis.transmodel.mapping; - -import static java.util.stream.Collectors.collectingAndThen; -import static java.util.stream.Collectors.toList; - -import java.util.List; -import java.util.Map; -import java.util.Objects; -import org.opentripplanner.routing.api.request.PassThroughPoint; -import org.opentripplanner.transit.service.TransitService; - -class PassThroughLocationMapper { - - static List toLocations( - final TransitService transitService, - final List> passThroughPoints - ) { - return passThroughPoints - .stream() - .map(p -> handlePoint(transitService, p)) - .filter(Objects::nonNull) - .collect(toList()); - // TODO Propagate an error if a stopplace is unknown and fails lookup. - } - - private static PassThroughPoint handlePoint( - final TransitService transitService, - Map map - ) { - final List stops = (List) map.get("placeIds"); - final String name = (String) map.get("name"); - if (stops == null) { - return null; - } - - return stops - .stream() - .map(TransitIdMapper::mapIDToDomain) - .flatMap(id -> { - var stopLocations = transitService.getStopOrChildStops(id); - if (stopLocations.isEmpty()) { - throw new RuntimeException("No match for %s.".formatted(id)); - } - return stopLocations.stream(); - }) - .collect(collectingAndThen(toList(), sls -> new PassThroughPoint(sls, name))); - } -} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java deleted file mode 100644 index 21cdfee9ef7..00000000000 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ /dev/null @@ -1,178 +0,0 @@ -package org.opentripplanner.apis.vectortiles; - -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.opentripplanner.apis.vectortiles.model.StyleBuilder; -import org.opentripplanner.apis.vectortiles.model.StyleSpec; -import org.opentripplanner.apis.vectortiles.model.TileSource; -import org.opentripplanner.apis.vectortiles.model.TileSource.RasterSource; -import org.opentripplanner.apis.vectortiles.model.VectorSourceLayer; -import org.opentripplanner.apis.vectortiles.model.ZoomDependentNumber; -import org.opentripplanner.apis.vectortiles.model.ZoomDependentNumber.ZoomStop; -import org.opentripplanner.service.vehiclerental.street.StreetVehicleRentalLink; -import org.opentripplanner.street.model.edge.AreaEdge; -import org.opentripplanner.street.model.edge.BoardingLocationToStopLink; -import org.opentripplanner.street.model.edge.Edge; -import org.opentripplanner.street.model.edge.ElevatorHopEdge; -import org.opentripplanner.street.model.edge.EscalatorEdge; -import org.opentripplanner.street.model.edge.PathwayEdge; -import org.opentripplanner.street.model.edge.StreetEdge; -import org.opentripplanner.street.model.edge.StreetTransitEntranceLink; -import org.opentripplanner.street.model.edge.StreetTransitStopLink; -import org.opentripplanner.street.model.edge.StreetVehicleParkingLink; -import org.opentripplanner.street.model.edge.TemporaryFreeEdge; -import org.opentripplanner.street.model.edge.TemporaryPartialStreetEdge; -import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex; - -/** - * A Mapbox/Mapblibre style specification for rendering debug information about transit and - * street data. - */ -public class DebugStyleSpec { - - private static final TileSource BACKGROUND_SOURCE = new RasterSource( - "background", - List.of("https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"), - 19, - 256, - "© OpenStreetMap Contributors" - ); - private static final String MAGENTA = "#f21d52"; - private static final String BRIGHT_GREEN = "#22DD9E"; - private static final String DARK_GREEN = "#136b04"; - private static final String PURPLE = "#BC55F2"; - private static final String BLACK = "#140d0e"; - private static final int MAX_ZOOM = 23; - private static final ZoomDependentNumber LINE_WIDTH = new ZoomDependentNumber( - 1.3f, - List.of(new ZoomStop(13, 0.5f), new ZoomStop(MAX_ZOOM, 10)) - ); - private static final ZoomDependentNumber CIRCLE_STROKE = new ZoomDependentNumber( - 1, - List.of(new ZoomStop(15, 0.2f), new ZoomStop(MAX_ZOOM, 3)) - ); - private static final Class[] EDGES_TO_DISPLAY = new Class[] { - StreetEdge.class, - AreaEdge.class, - EscalatorEdge.class, - PathwayEdge.class, - ElevatorHopEdge.class, - TemporaryPartialStreetEdge.class, - TemporaryFreeEdge.class, - }; - - static StyleSpec build( - VectorSourceLayer regularStops, - VectorSourceLayer areaStops, - VectorSourceLayer groupStops, - VectorSourceLayer edges, - VectorSourceLayer vertices - ) { - var vectorSources = Stream - .of(regularStops, edges, vertices) - .map(VectorSourceLayer::vectorSource); - var allSources = Stream - .concat(Stream.of(BACKGROUND_SOURCE), vectorSources) - .collect(Collectors.toSet()); - return new StyleSpec( - "OTP Debug Tiles", - allSources, - List.of( - StyleBuilder.ofId("background").typeRaster().source(BACKGROUND_SOURCE).minZoom(0), - StyleBuilder - .ofId("edge") - .typeLine() - .vectorSourceLayer(edges) - .lineColor(MAGENTA) - .edgeFilter(EDGES_TO_DISPLAY) - .lineWidth(LINE_WIDTH) - .minZoom(6) - .maxZoom(MAX_ZOOM) - .intiallyHidden(), - StyleBuilder - .ofId("edge-name") - .typeSymbol() - .lineText("name") - .vectorSourceLayer(edges) - .edgeFilter(EDGES_TO_DISPLAY) - .minZoom(17) - .maxZoom(MAX_ZOOM) - .intiallyHidden(), - StyleBuilder - .ofId("link") - .typeLine() - .vectorSourceLayer(edges) - .lineColor(BRIGHT_GREEN) - .edgeFilter( - StreetTransitStopLink.class, - StreetTransitEntranceLink.class, - BoardingLocationToStopLink.class, - StreetVehicleRentalLink.class, - StreetVehicleParkingLink.class - ) - .lineWidth(LINE_WIDTH) - .minZoom(13) - .maxZoom(MAX_ZOOM) - .intiallyHidden(), - StyleBuilder - .ofId("vertex") - .typeCircle() - .vectorSourceLayer(vertices) - .circleStroke(BLACK, CIRCLE_STROKE) - .circleRadius( - new ZoomDependentNumber(1, List.of(new ZoomStop(15, 1), new ZoomStop(MAX_ZOOM, 7))) - ) - .circleColor(PURPLE) - .minZoom(15) - .maxZoom(MAX_ZOOM) - .intiallyHidden(), - StyleBuilder - .ofId("parking-vertex") - .typeCircle() - .vectorSourceLayer(vertices) - .vertexFilter(VehicleParkingEntranceVertex.class) - .circleStroke(BLACK, CIRCLE_STROKE) - .circleRadius( - new ZoomDependentNumber(1, List.of(new ZoomStop(13, 1.4f), new ZoomStop(MAX_ZOOM, 10))) - ) - .circleColor(DARK_GREEN) - .minZoom(13) - .maxZoom(MAX_ZOOM) - .intiallyHidden(), - StyleBuilder - .ofId("area-stop") - .typeFill() - .vectorSourceLayer(areaStops) - .fillColor(BRIGHT_GREEN) - .fillOpacity(0.5f) - .fillOutlineColor(BLACK) - .minZoom(6) - .maxZoom(MAX_ZOOM), - StyleBuilder - .ofId("group-stop") - .typeFill() - .vectorSourceLayer(groupStops) - .fillColor(BRIGHT_GREEN) - .fillOpacity(0.5f) - .fillOutlineColor(BLACK) - .minZoom(6) - .maxZoom(MAX_ZOOM), - StyleBuilder - .ofId("regular-stop") - .typeCircle() - .vectorSourceLayer(regularStops) - .circleStroke( - BLACK, - new ZoomDependentNumber(1, List.of(new ZoomStop(11, 0.5f), new ZoomStop(MAX_ZOOM, 5))) - ) - .circleRadius( - new ZoomDependentNumber(1, List.of(new ZoomStop(11, 0.5f), new ZoomStop(MAX_ZOOM, 10))) - ) - .circleColor("#fcf9fa") - .minZoom(10) - .maxZoom(MAX_ZOOM) - ) - ); - } -} diff --git a/src/main/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategy.java b/src/main/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategy.java deleted file mode 100644 index 0369e3e29db..00000000000 --- a/src/main/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategy.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.opentripplanner.astar.strategy; - -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. - */ -public class MaxCountSkipEdgeStrategy< - State extends AStarState, Edge extends AStarEdge -> - implements SkipEdgeStrategy { - - private final int maxCount; - private final Predicate shouldIncreaseCount; - - private int visited; - - public MaxCountSkipEdgeStrategy(int count, Predicate shouldIncreaseCount) { - this.maxCount = count; - this.shouldIncreaseCount = shouldIncreaseCount; - this.visited = 0; - } - - @Override - public boolean shouldSkipEdge(State current, Edge edge) { - if (shouldIncreaseCount.test(current)) { - visited++; - } - return visited > maxCount; - } -} diff --git a/src/main/java/org/opentripplanner/graph_builder/issues/package-info.java b/src/main/java/org/opentripplanner/graph_builder/issues/package-info.java deleted file mode 100644 index db899fdd206..00000000000 --- a/src/main/java/org/opentripplanner/graph_builder/issues/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Graph builder data import issues represent errors or exceptional conditions encountered during - * the graph building process. They contain descriptive messages and potentially references to the - * objects in the graph that they annotate which facilitate visualization and cataloging/mapping of - * problems. - */ -package org.opentripplanner.graph_builder.issues; diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/BikeAccessMapper.java b/src/main/java/org/opentripplanner/gtfs/mapping/BikeAccessMapper.java deleted file mode 100644 index 12f7edcf8c1..00000000000 --- a/src/main/java/org/opentripplanner/gtfs/mapping/BikeAccessMapper.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.opentripplanner.gtfs.mapping; - -import org.onebusaway.gtfs.model.Route; -import org.onebusaway.gtfs.model.Trip; -import org.opentripplanner.transit.model.network.BikeAccess; - -/** - * Model bike access for GTFS trips. - *

    - * The GTFS bike extensions is originally discussed at: https://groups.google.com/d/msg/gtfs-changes/QqaGOuNmG7o/xyqORy-T4y0J - *

    - * It proposes "route_bikes_allowed" in routes.txt and "trip_bikes_allowed" in trips.txt with the - * following semantics: - *

    - * 2: bikes allowed
    1: no bikes allowed
    0: no information (same as field omitted)
    - *

    - * The values in trips.txt override the values in routes.txt. - *

    - * An alternative proposal is discussed in: https://groups.google.com/d/msg/gtfs-changes/rEiSeKNc4cs/gTTnQ_yXtPgJ - *

    - * Here, the field "bikes_allowed" is used in both routes.txt and trip.txt with the following - * semantics: - *

    - * 2: no bikes allowed
    1: bikes allowed
    0: no information (same as field omitted)
    - *

    - * Here, the 0,1,2 semantics have been changed to match the convention used in the - * "wheelchair_accessible" field in trips.txt. - *

    - * A number of feeds are still using the original proposal and a number of feeds have been updated - * to use the new proposal. For now, we support both, using "bikes_allowed" if specified and then - * "trip_bikes_allowed". - */ -class BikeAccessMapper { - - public static BikeAccess mapForTrip(Trip rhs) { - //noinspection deprecation - return mapValues(rhs.getBikesAllowed(), rhs.getTripBikesAllowed()); - } - - public static BikeAccess mapForRoute(Route rhs) { - //noinspection deprecation - return mapValues(rhs.getBikesAllowed(), rhs.getRouteBikesAllowed()); - } - - private static BikeAccess mapValues(int bikesAllowed, int legacyBikesAllowed) { - if (bikesAllowed != 0) { - switch (bikesAllowed) { - case 1: - return BikeAccess.ALLOWED; - case 2: - return BikeAccess.NOT_ALLOWED; - default: - return BikeAccess.UNKNOWN; - } - } else if (legacyBikesAllowed != 0) { - switch (legacyBikesAllowed) { - case 1: - return BikeAccess.NOT_ALLOWED; - case 2: - return BikeAccess.ALLOWED; - default: - return BikeAccess.UNKNOWN; - } - } - - return BikeAccess.UNKNOWN; - } -} diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/BrandingMapper.java b/src/main/java/org/opentripplanner/gtfs/mapping/BrandingMapper.java deleted file mode 100644 index 5e370335d4e..00000000000 --- a/src/main/java/org/opentripplanner/gtfs/mapping/BrandingMapper.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.opentripplanner.gtfs.mapping; - -import javax.annotation.Nullable; -import org.onebusaway.gtfs.model.Route; -import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.model.organization.Branding; - -/** Responsible for mapping GTFS Route into the OTP Branding model. */ -public class BrandingMapper { - - /** - * Convert GTFS Route entity into OTP Branding model. - * - * @param route GTFS Route entity - * @return OTP branding model. Null if route branding url is not present. - */ - @Nullable - public Branding map(Route route) { - if (route.getBrandingUrl() == null) { - return null; - } - // Make an id from the url, the id is required - var id = new FeedScopedId(route.getId().getAgencyId(), route.getBrandingUrl()); - return Branding.of(id).withUrl(route.getBrandingUrl()).build(); - } -} diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/StopAreaMapper.java b/src/main/java/org/opentripplanner/gtfs/mapping/StopAreaMapper.java deleted file mode 100644 index 55c836aa458..00000000000 --- a/src/main/java/org/opentripplanner/gtfs/mapping/StopAreaMapper.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.opentripplanner.gtfs.mapping; - -import static org.opentripplanner.gtfs.mapping.AgencyAndIdMapper.mapAgencyAndId; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import org.onebusaway.gtfs.model.Location; -import org.onebusaway.gtfs.model.Stop; -import org.opentripplanner.framework.collection.MapUtils; -import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.transit.model.site.GroupStop; -import org.opentripplanner.transit.model.site.GroupStopBuilder; -import org.opentripplanner.transit.service.StopModelBuilder; - -/** - * For a while GTFS Flex location groups were replaced by GTFS Fares v2 stop areas. After a few - * months, this decision was reverted and a new style of location groups were re-added to the Flex - * spec. - * @deprecated Arcadis tooling still produces stop areas and for a while we will support both. Please don't rely - * on this as the class will be removed in the future! - */ -@Deprecated -public class StopAreaMapper { - - private final StopMapper stopMapper; - - private final LocationMapper locationMapper; - - private final Map mappedStopAreas = new HashMap<>(); - private final StopModelBuilder stopModel; - - public StopAreaMapper( - StopMapper stopMapper, - LocationMapper locationMapper, - StopModelBuilder stopModel - ) { - this.stopMapper = stopMapper; - this.locationMapper = locationMapper; - this.stopModel = stopModel; - } - - Collection map(Collection allAreas) { - return MapUtils.mapToList(allAreas, this::map); - } - - /** Map from GTFS to OTP model, {@code null} safe. */ - GroupStop map(org.onebusaway.gtfs.model.StopArea original) { - return original == null ? null : mappedStopAreas.computeIfAbsent(original, this::doMap); - } - - private GroupStop doMap(org.onebusaway.gtfs.model.StopArea element) { - GroupStopBuilder groupStopBuilder = stopModel - .groupStop(mapAgencyAndId(element.getId())) - .withName(new NonLocalizedString(element.getName())); - - for (org.onebusaway.gtfs.model.StopLocation location : element.getLocations()) { - switch (location) { - case Stop stop -> groupStopBuilder.addLocation(stopMapper.map(stop)); - case Location loc -> groupStopBuilder.addLocation(locationMapper.map(loc)); - case org.onebusaway.gtfs.model.StopArea ignored -> throw new RuntimeException( - "Nested GroupStops are not allowed" - ); - case null, default -> throw new RuntimeException( - "Unknown location type: " + location.getClass().getSimpleName() - ); - } - } - - return groupStopBuilder.build(); - } -} diff --git a/src/main/java/org/opentripplanner/model/RealTimeTripUpdate.java b/src/main/java/org/opentripplanner/model/RealTimeTripUpdate.java deleted file mode 100644 index e5bcc6c0322..00000000000 --- a/src/main/java/org/opentripplanner/model/RealTimeTripUpdate.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.opentripplanner.model; - -import java.time.LocalDate; -import java.util.Objects; -import javax.annotation.Nullable; -import org.opentripplanner.transit.model.network.TripPattern; -import org.opentripplanner.transit.model.timetable.TripOnServiceDate; -import org.opentripplanner.transit.model.timetable.TripTimes; - -/** - * Represents the real-time update of a single trip. - * @param pattern the pattern to which belongs the updated trip. This can be a new pattern created in real-time. - * @param updatedTripTimes the new trip times for the updated trip. - * @param serviceDate the service date for which this update applies (updates are valid only for one service date) - * @param addedTripOnServiceDate optionally if this trip update adds a new trip, the TripOnServiceDate corresponding to this new trip. - * @param tripCreation true if this update creates a new trip, not present in scheduled data. - * @param routeCreation true if an added trip cannot be registered under an existing route and a new route must be created. - */ -public record RealTimeTripUpdate( - TripPattern pattern, - TripTimes updatedTripTimes, - LocalDate serviceDate, - @Nullable TripOnServiceDate addedTripOnServiceDate, - boolean tripCreation, - boolean routeCreation -) { - public RealTimeTripUpdate { - Objects.requireNonNull(pattern); - Objects.requireNonNull(updatedTripTimes); - Objects.requireNonNull(serviceDate); - } - - /** - * Create a real-time update for an existing trip. - */ - public RealTimeTripUpdate( - TripPattern pattern, - TripTimes updatedTripTimes, - LocalDate serviceDate - ) { - this(pattern, updatedTripTimes, serviceDate, null, false, false); - } -} diff --git a/src/main/java/org/opentripplanner/netex/loader/parser/package-info.java b/src/main/java/org/opentripplanner/netex/loader/parser/package-info.java deleted file mode 100644 index a0b9cd00721..00000000000 --- a/src/main/java/org/opentripplanner/netex/loader/parser/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -package org.opentripplanner.netex.loader.parser; -// TODO OTP2 - This package need Unit tests diff --git a/src/main/java/org/opentripplanner/openstreetmap/model/OSMMemberType.java b/src/main/java/org/opentripplanner/openstreetmap/model/OSMMemberType.java deleted file mode 100644 index 6cb9974b9d8..00000000000 --- a/src/main/java/org/opentripplanner/openstreetmap/model/OSMMemberType.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.opentripplanner.openstreetmap.model; - -public enum OSMMemberType { - NODE, - WAY, - RELATION, -} diff --git a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/ConstantSpeedMapper.java b/src/main/java/org/opentripplanner/openstreetmap/tagmapping/ConstantSpeedMapper.java deleted file mode 100644 index b233b3f549e..00000000000 --- a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/ConstantSpeedMapper.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.opentripplanner.openstreetmap.tagmapping; - -import static org.opentripplanner.openstreetmap.wayproperty.WayPropertiesBuilder.withModes; -import static org.opentripplanner.street.model.StreetTraversalPermission.ALL; -import static org.opentripplanner.street.model.StreetTraversalPermission.CAR; -import static org.opentripplanner.street.model.StreetTraversalPermission.NONE; -import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN; -import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN_AND_BICYCLE; - -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; -import org.opentripplanner.street.model.StreetTraversalPermission; - -/** - * OSM way properties for optimizing distance (not traveling time) in routing. - */ -class ConstantSpeedFinlandMapper implements OsmTagMapper { - - private float speed; - - public ConstantSpeedFinlandMapper() { - super(); - this.speed = 22.22f; // 80 kmph by default - } - - public ConstantSpeedFinlandMapper(float speed) { - super(); - this.speed = speed; - } - - @Override - public void populateProperties(WayPropertySet props) { - props.setCarSpeed("highway=*", speed); - // Read the rest from the default set - new FinlandMapper().populateProperties(props); - props.maxPossibleCarSpeed = speed; - } - - @Override - public float getCarSpeedForWay(OSMWithTags way, boolean backward) { - /* - * Set the same 80 km/h speed for all roads, so that car routing finds shortest path - */ - return speed; - } - - @Override - public Float getMaxUsedCarSpeed(WayPropertySet wayPropertySet) { - // This is needed because the way property set uses normal speed limits from Finland mapper - // to set the walk safety limits which resets the maximum used car speed to be something else - // than what is used for the street edge car speeds. - return speed; - } -} diff --git a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/OsmTagMapper.java b/src/main/java/org/opentripplanner/openstreetmap/tagmapping/OsmTagMapper.java deleted file mode 100644 index 8bcfbfdf65a..00000000000 --- a/src/main/java/org/opentripplanner/openstreetmap/tagmapping/OsmTagMapper.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.opentripplanner.openstreetmap.tagmapping; - -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; - -/** - * Interface for populating a {@link WayPropertySet} that determine how OSM streets can be traversed - * in various modes and named. - * - * @author bdferris, novalis, seime - */ -public interface OsmTagMapper { - void populateProperties(WayPropertySet wayPropertySet); - - default boolean doesTagValueDisallowThroughTraffic(String tagValue) { - return ( - "no".equals(tagValue) || - "destination".equals(tagValue) || - "private".equals(tagValue) || - "customers".equals(tagValue) || - "delivery".equals(tagValue) - ); - } - - default float getCarSpeedForWay(OSMWithTags way, boolean backward) { - return way.getOsmProvider().getWayPropertySet().getCarSpeedForWay(way, backward); - } - - default Float getMaxUsedCarSpeed(WayPropertySet wayPropertySet) { - return wayPropertySet.maxUsedCarSpeed; - } - - default boolean isGeneralNoThroughTraffic(OSMWithTags way) { - String access = way.getTag("access"); - return doesTagValueDisallowThroughTraffic(access); - } - - default boolean isVehicleThroughTrafficExplicitlyDisallowed(OSMWithTags way) { - String vehicle = way.getTag("vehicle"); - if (vehicle != null) { - return doesTagValueDisallowThroughTraffic(vehicle); - } else { - return isGeneralNoThroughTraffic(way); - } - } - - /** - * Returns true if through traffic for motor vehicles is not allowed. - */ - default boolean isMotorVehicleThroughTrafficExplicitlyDisallowed(OSMWithTags way) { - String motorVehicle = way.getTag("motor_vehicle"); - if (motorVehicle != null) { - return doesTagValueDisallowThroughTraffic(motorVehicle); - } else { - return isVehicleThroughTrafficExplicitlyDisallowed(way); - } - } - - /** - * Returns true if through traffic for bicycle is not allowed. - */ - default boolean isBicycleNoThroughTrafficExplicitlyDisallowed(OSMWithTags way) { - String bicycle = way.getTag("bicycle"); - if (bicycle != null) { - return doesTagValueDisallowThroughTraffic(bicycle); - } else { - return isVehicleThroughTrafficExplicitlyDisallowed(way); - } - } - - /** - * Returns true if through traffic for walk is not allowed. - */ - default boolean isWalkNoThroughTrafficExplicitlyDisallowed(OSMWithTags way) { - String foot = way.getTag("foot"); - if (foot != null) { - return doesTagValueDisallowThroughTraffic(foot); - } else { - return isGeneralNoThroughTraffic(way); - } - } -} diff --git a/src/main/java/org/opentripplanner/raptor/configure/RaptorConfig.java b/src/main/java/org/opentripplanner/raptor/configure/RaptorConfig.java deleted file mode 100644 index f1477ecc9f3..00000000000 --- a/src/main/java/org/opentripplanner/raptor/configure/RaptorConfig.java +++ /dev/null @@ -1,150 +0,0 @@ -package org.opentripplanner.raptor.configure; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.IntPredicate; -import javax.annotation.Nullable; -import org.opentripplanner.framework.concurrent.OtpRequestThreadFactory; -import org.opentripplanner.raptor.api.model.RaptorTripSchedule; -import org.opentripplanner.raptor.api.request.RaptorRequest; -import org.opentripplanner.raptor.api.request.RaptorTuningParameters; -import org.opentripplanner.raptor.rangeraptor.DefaultRangeRaptorWorker; -import org.opentripplanner.raptor.rangeraptor.context.SearchContext; -import org.opentripplanner.raptor.rangeraptor.internalapi.Heuristics; -import org.opentripplanner.raptor.rangeraptor.internalapi.PassThroughPointsService; -import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorker; -import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerResult; -import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerState; -import org.opentripplanner.raptor.rangeraptor.internalapi.RoutingStrategy; -import org.opentripplanner.raptor.rangeraptor.multicriteria.configure.McRangeRaptorConfig; -import org.opentripplanner.raptor.rangeraptor.standard.configure.StdRangeRaptorConfig; -import org.opentripplanner.raptor.rangeraptor.transit.RaptorSearchWindowCalculator; -import org.opentripplanner.raptor.spi.RaptorTransitDataProvider; - -/** - * This class is responsible for creating a new search and holding application scoped Raptor state. - *

    - * This class should have APPLICATION scope. It manage a threadPool, and hold a reference to the - * application tuning parameters. - * - * @param The TripSchedule type defined by the user of the raptor API. - */ -public class RaptorConfig { - - private final ExecutorService threadPool; - private final RaptorTuningParameters tuningParameters; - - /** The service is not final, because it depends on the request. */ - private PassThroughPointsService passThroughPointsService = null; - - public RaptorConfig(RaptorTuningParameters tuningParameters) { - this.tuningParameters = tuningParameters; - this.threadPool = createNewThreadPool(tuningParameters.searchThreadPoolSize()); - } - - public static RaptorConfig defaultConfigForTest() { - return new RaptorConfig<>(new RaptorTuningParameters() {}); - } - - public SearchContext context(RaptorTransitDataProvider transit, RaptorRequest request) { - // The passThroughPointsService is needed to create the context, so we initialize it here. - this.passThroughPointsService = createPassThroughPointsService(request); - return new SearchContext<>(request, tuningParameters, transit, acceptC2AtDestination()); - } - - public RaptorWorker createStdWorker( - RaptorTransitDataProvider transitData, - RaptorRequest request - ) { - var context = context(transitData, request); - var stdConfig = new StdRangeRaptorConfig<>(context); - return createWorker(context, stdConfig.state(), stdConfig.strategy()); - } - - public RaptorWorker createMcWorker( - RaptorTransitDataProvider transitData, - RaptorRequest request, - Heuristics heuristics - ) { - final SearchContext context = context(transitData, request); - return new McRangeRaptorConfig<>(context, passThroughPointsService) - .createWorker( - heuristics, - (state, routingStrategy) -> createWorker(context, state, routingStrategy) - ); - } - - public RaptorWorker createHeuristicSearch( - RaptorTransitDataProvider transitData, - RaptorRequest request - ) { - var context = context(transitData, request); - var stdConfig = new StdRangeRaptorConfig<>(context); - return createWorker(context, stdConfig.state(), stdConfig.strategy()); - } - - public Heuristics createHeuristic( - RaptorTransitDataProvider transitData, - RaptorRequest request, - RaptorWorkerResult results - ) { - var context = context(transitData, request); - return new StdRangeRaptorConfig<>(context).createHeuristics(results); - } - - public boolean isMultiThreaded() { - return threadPool != null; - } - - public ExecutorService threadPool() { - return threadPool; - } - - public void shutdown() { - if (threadPool != null) { - threadPool.shutdown(); - } - } - - public RaptorSearchWindowCalculator searchWindowCalculator() { - return new RaptorSearchWindowCalculator(tuningParameters.dynamicSearchWindowCoefficients()); - } - - /* private factory methods */ - - private static PassThroughPointsService createPassThroughPointsService(RaptorRequest request) { - return McRangeRaptorConfig.passThroughPointsService(request.multiCriteria()); - } - - private RaptorWorker createWorker( - SearchContext ctx, - RaptorWorkerState workerState, - RoutingStrategy routingStrategy - ) { - return new DefaultRangeRaptorWorker<>( - workerState, - routingStrategy, - ctx.transit(), - ctx.slackProvider(), - ctx.accessPaths(), - ctx.roundProvider(), - ctx.calculator(), - ctx.createLifeCyclePublisher(), - ctx.performanceTimers(), - ctx.useConstrainedTransfers() - ); - } - - private IntPredicate acceptC2AtDestination() { - return passThroughPointsService.isNoop() - ? null - : passThroughPointsService.acceptC2AtDestination(); - } - - @Nullable - private ExecutorService createNewThreadPool(int size) { - return size > 0 - ? Executors.newFixedThreadPool(size, OtpRequestThreadFactory.of("raptor-%d")) - : null; - } -} diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorWorker.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorWorker.java deleted file mode 100644 index fc5786b2407..00000000000 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RaptorWorker.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.opentripplanner.raptor.rangeraptor.internalapi; - -import org.opentripplanner.raptor.api.model.RaptorTripSchedule; - -/** - * The worker performs the travel search. There are multiple implementations, even some that do not - * return paths. - * - * @param The TripSchedule type defined by the user of the raptor API. - */ -public interface RaptorWorker { - /** - * Perform the routing request. - */ - RaptorWorkerResult route(); -} diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RoundProvider.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RoundProvider.java deleted file mode 100644 index 21bd86f8133..00000000000 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/RoundProvider.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.opentripplanner.raptor.rangeraptor.internalapi; - -import org.opentripplanner.raptor.rangeraptor.transit.RoundTracker; - -/** - * Keep track of current Raptor round. The provider is injected where needed instead of passing the - * current round down the call stack. This is faster than passing the round on the stack because the - * round is access so frequently thet in most cases it is cached in the CPU registry - at least - * tests indicate this. - *

    - * - * @see RoundTracker - */ -public interface RoundProvider { - /** - * The current Raptor round. - */ - int round(); - - /** - * Return true if this round is the first round, calculating the first transit path. Access is - * calculated in round zero (0). - */ - boolean isFirstRound(); -} diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/StopArrivalParetoSet.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/StopArrivalParetoSet.java deleted file mode 100644 index ca653be6fc9..00000000000 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/StopArrivalParetoSet.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.opentripplanner.raptor.rangeraptor.multicriteria; - -import java.util.List; -import javax.annotation.Nullable; -import org.opentripplanner.raptor.api.model.RaptorAccessEgress; -import org.opentripplanner.raptor.api.model.RaptorTripSchedule; -import org.opentripplanner.raptor.api.view.ArrivalView; -import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrival; -import org.opentripplanner.raptor.rangeraptor.path.DestinationArrivalPaths; -import org.opentripplanner.raptor.util.paretoset.ParetoComparator; -import org.opentripplanner.raptor.util.paretoset.ParetoSetEventListener; -import org.opentripplanner.raptor.util.paretoset.ParetoSetEventListenerComposite; -import org.opentripplanner.raptor.util.paretoset.ParetoSetWithMarker; - -/** - * A pareto optimal set of stop arrivals for a given stop. - * - * @param The TripSchedule type defined by the user of the raptor API. - */ -class StopArrivalParetoSet - extends ParetoSetWithMarker> { - - /** - * Use the factory methods in this class to create a new instance. - */ - private StopArrivalParetoSet( - ParetoComparator> comparator, - ParetoSetEventListener> listener - ) { - super(comparator, listener); - } - - /** - * Create a stop arrivals pareto set and attach an optional {@code paretoSetEventListener} - * (debug handler). - */ - static StopArrivalParetoSet createStopArrivalSet( - ParetoComparator> comparator, - @Nullable ParetoSetEventListener> paretoSetEventListener - ) { - return new StopArrivalParetoSet<>(comparator, paretoSetEventListener); - } - - /** - * Create a new StopArrivalParetoSet and attach a debugger if it exist. Also attach a {@link - * CalculateTransferToDestination} listener which will create new destination arrivals for each - * accepted egress stop arrival. - */ - static StopArrivalParetoSet createEgressStopArrivalSet( - ParetoComparator> comparator, - List egressPaths, - DestinationArrivalPaths destinationArrivals, - @Nullable ParetoSetEventListener> paretoSetEventListener - ) { - ParetoSetEventListener> listener; - - listener = new CalculateTransferToDestination<>(egressPaths, destinationArrivals); - - if (paretoSetEventListener != null) { - listener = new ParetoSetEventListenerComposite<>(paretoSetEventListener, listener); - } - - return new StopArrivalParetoSet<>(comparator, listener); - } -} diff --git a/src/main/java/org/opentripplanner/routing/alertpatch/AlertUrl.java b/src/main/java/org/opentripplanner/routing/alertpatch/AlertUrl.java deleted file mode 100644 index b13fad6e97b..00000000000 --- a/src/main/java/org/opentripplanner/routing/alertpatch/AlertUrl.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.opentripplanner.routing.alertpatch; - -public class AlertUrl { - - public String uri; - public String label; -} diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressRouter.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressRouter.java deleted file mode 100644 index f6a0526fa66..00000000000 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/AccessEgressRouter.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.opentripplanner.routing.algorithm.raptoradapter.router.street; - -import java.time.Duration; -import java.util.Collection; -import org.opentripplanner.ext.dataoverlay.routing.DataOverlayContext; -import org.opentripplanner.framework.application.OTPRequestTimeoutException; -import org.opentripplanner.graph_builder.module.nearbystops.StreetNearbyStopFinder; -import org.opentripplanner.routing.api.request.RouteRequest; -import org.opentripplanner.routing.api.request.request.StreetRequest; -import org.opentripplanner.routing.graphfinder.NearbyStop; -import org.opentripplanner.street.search.TemporaryVerticesContainer; -import org.opentripplanner.transit.service.TransitService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This uses a street search to find paths to all the access/egress stop within range - */ -public class AccessEgressRouter { - - private static final Logger LOG = LoggerFactory.getLogger(AccessEgressRouter.class); - - private AccessEgressRouter() {} - - /** - * @param fromTarget whether to route from or towards the point provided in the routing request - * (access or egress) - * @return Transfer objects by access/egress stop - */ - public static Collection streetSearch( - RouteRequest request, - TemporaryVerticesContainer verticesContainer, - StreetRequest streetRequest, - DataOverlayContext dataOverlayContext, - boolean fromTarget, - Duration durationLimit, - int maxStopCount - ) { - OTPRequestTimeoutException.checkForTimeout(); - var nearbyStopFinder = new StreetNearbyStopFinder( - durationLimit, - maxStopCount, - dataOverlayContext - ); - Collection nearbyStopList = nearbyStopFinder.findNearbyStops( - fromTarget ? verticesContainer.getToVertices() : verticesContainer.getFromVertices(), - fromTarget, - request, - streetRequest - ); - - LOG.debug("Found {} {} stops", nearbyStopList.size(), fromTarget ? "egress" : "access"); - - return nearbyStopList; - } -} diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/package-info.java b/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/package-info.java deleted file mode 100644 index 22163201b6e..00000000000 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Package documentation - */ -package org.opentripplanner.routing.algorithm.transferoptimization; diff --git a/src/main/java/org/opentripplanner/routing/api/request/PassThroughPoint.java b/src/main/java/org/opentripplanner/routing/api/request/PassThroughPoint.java deleted file mode 100644 index fa63c2e5668..00000000000 --- a/src/main/java/org/opentripplanner/routing/api/request/PassThroughPoint.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.opentripplanner.routing.api.request; - -import java.util.List; -import javax.annotation.Nullable; -import org.opentripplanner.transit.model.site.StopLocation; - -/** - * Defines one pass-through point which the journey must pass through. - */ -public record PassThroughPoint(List stopLocations, @Nullable String name) { - /** - * Get the one or multiple stops of the pass-through point, of which only one is required to be - * passed through. - */ - @Override - public List stopLocations() { - return stopLocations; - } - - /** - * Get an optional name of the pass-through point for debugging and logging. - */ - @Override - @Nullable - public String name() { - return name; - } -} diff --git a/src/main/java/org/opentripplanner/street/search/state/EdgeTraverser.java b/src/main/java/org/opentripplanner/street/search/state/EdgeTraverser.java deleted file mode 100644 index 8755f014e14..00000000000 --- a/src/main/java/org/opentripplanner/street/search/state/EdgeTraverser.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.opentripplanner.street.search.state; - -import java.util.Collection; -import java.util.Optional; -import org.opentripplanner.street.model.edge.Edge; - -/** - * This is a very reduced version of the A* algorithm: from an initial state a number of edges are - * traversed in sequential order. It doesn't take into account the potential other paths that are - * possible. - *

    - * This is not a general search algorithm! It's only useful for calculating cost and time of - * traversing a predetermined set of edges. - */ -public class EdgeTraverser { - - public static Optional traverseEdges(final State s, final Collection edges) { - var state = s; - for (Edge e : edges) { - var afterTraversal = e.traverse(state); - if (afterTraversal.length > 1) { - throw new IllegalStateException( - "Expected only a single state returned from edge %s but received %s".formatted( - e, - afterTraversal.length - ) - ); - } - if (State.isEmpty(afterTraversal)) { - return Optional.empty(); - } else { - state = afterTraversal[0]; - } - } - return Optional.ofNullable(state); - } -} diff --git a/src/main/java/org/opentripplanner/updater/trip/metrics/StreamingTripUpdateMetrics.java b/src/main/java/org/opentripplanner/updater/trip/metrics/StreamingTripUpdateMetrics.java deleted file mode 100644 index c53a398f3dc..00000000000 --- a/src/main/java/org/opentripplanner/updater/trip/metrics/StreamingTripUpdateMetrics.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.opentripplanner.updater.trip.metrics; - -import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.Metrics; -import io.micrometer.core.instrument.Tag; -import io.micrometer.core.instrument.Tags; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import org.opentripplanner.updater.spi.UpdateError; -import org.opentripplanner.updater.spi.UpdateResult; -import org.opentripplanner.updater.spi.UpdateSuccess; -import org.opentripplanner.updater.trip.UrlUpdaterParameters; - -/** - * Records micrometer metrics for trip updaters that stream trip updates into the system, for - * example GTFS-RT via MQTT. - *

    - * It records the trip update as counters (continuously increasing numbers) since the concept of - * "latest update" doesn't exist for them. - *

    - * Use your metrics database to convert the counters to rates. - */ -public class StreamingTripUpdateMetrics extends TripUpdateMetrics { - - protected static final String METRICS_PREFIX = "streaming_trip_updates"; - private final Counter successfulCounter; - private final Counter failureCounter; - private final Counter warningsCounter; - private final Map failuresByType = new HashMap<>(); - private final Map warningsByType = new HashMap<>(); - - public StreamingTripUpdateMetrics(UrlUpdaterParameters parameters) { - super(parameters); - this.successfulCounter = getCounter("successful", "Total successfully applied trip updates"); - this.failureCounter = getCounter("failed", "Total failed trip updates"); - this.warningsCounter = getCounter("warnings", "Total warnings for successful trip updates"); - } - - public void setCounters(UpdateResult result) { - this.successfulCounter.increment(result.successful()); - this.failureCounter.increment(result.failed()); - this.warningsCounter.increment(result.warnings().size()); - - setFailures(result); - setWarnings(result); - } - - private void setWarnings(UpdateResult result) { - for (var warningType : result.warnings()) { - var counter = warningsByType.get(warningType); - if (Objects.isNull(counter)) { - counter = - getCounter( - "warning_type", - "Total warnings by type generated by successful trip updates", - Tag.of("warningType", warningType.name()) - ); - warningsByType.put(warningType, counter); - } - counter.increment(); - } - } - - private void setFailures(UpdateResult result) { - for (var errorType : result.failures().keySet()) { - var counter = failuresByType.get(errorType); - if (Objects.isNull(counter)) { - counter = - getCounter( - "failure_type", - "Total failed trip updates by type", - Tag.of("errorType", errorType.name()) - ); - failuresByType.put(errorType, counter); - } - counter.increment(result.failures().get(errorType).size()); - } - } - - private Counter getCounter(String name, String description, Tag... tags) { - var finalTags = Tags.concat(Arrays.stream(tags).toList(), baseTags); - return Counter - .builder(METRICS_PREFIX + "." + name) - .description(description) - .tags(finalTags) - .register(Metrics.globalRegistry); - } -} diff --git a/src/main/java/org/opentripplanner/visualizer/package-info.java b/src/main/java/org/opentripplanner/visualizer/package-info.java deleted file mode 100644 index e189c27956f..00000000000 --- a/src/main/java/org/opentripplanner/visualizer/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * This package contains classes used for visualizing OpenTripPlanner graphs. This graph visualizer - * is intended for debugging purposes and may therefore have arcane developer-oriented features and - * grow new UI components as needed. - */ -package org.opentripplanner.visualizer; diff --git a/src/test/java/org/opentripplanner/TestOtpModel.java b/src/test/java/org/opentripplanner/TestOtpModel.java deleted file mode 100644 index a2fc5305ce9..00000000000 --- a/src/test/java/org/opentripplanner/TestOtpModel.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.opentripplanner; - -import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.transit.service.TransitModel; - -public record TestOtpModel(Graph graph, TransitModel transitModel) { - public TestOtpModel index() { - transitModel.index(); - graph.index(transitModel.getStopModel()); - return this; - } -} diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/BikesAllowedMapperTest.java b/src/test/java/org/opentripplanner/apis/gtfs/mapping/BikesAllowedMapperTest.java deleted file mode 100644 index 5ed267f1f4f..00000000000 --- a/src/test/java/org/opentripplanner/apis/gtfs/mapping/BikesAllowedMapperTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.opentripplanner.apis.gtfs.mapping; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.Arrays; -import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model.network.BikeAccess; - -class BikesAllowedMapperTest { - - @Test - void mapping() { - Arrays - .stream(BikeAccess.values()) - .filter(ba -> ba != BikeAccess.UNKNOWN) - .forEach(d -> { - var mapped = BikesAllowedMapper.map(d); - assertEquals(d.toString(), mapped.toString()); - }); - } -} diff --git a/src/test/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategyTest.java b/src/test/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategyTest.java deleted file mode 100644 index 88976591ea1..00000000000 --- a/src/test/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategyTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.opentripplanner.astar.strategy; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; -import org.opentripplanner.graph_builder.module.nearbystops.StreetNearbyStopFinder; -import org.opentripplanner.street.search.state.TestStateBuilder; - -class MaxCountSkipEdgeStrategyTest { - - @Test - void countStops() { - var state = TestStateBuilder.ofWalking().stop().build(); - var strategy = new MaxCountSkipEdgeStrategy<>(1, StreetNearbyStopFinder::hasReachedStop); - assertFalse(strategy.shouldSkipEdge(state, null)); - assertTrue(strategy.shouldSkipEdge(state, null)); - } - - @Test - void doNotCountStop() { - var state = TestStateBuilder.ofWalking().build(); - var strategy = new MaxCountSkipEdgeStrategy<>(1, StreetNearbyStopFinder::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, StreetNearbyStopFinder::hasReachedStop); - assertFalse(strategy.shouldSkipEdge(state, null)); - } -} diff --git a/src/test/java/org/opentripplanner/framework/time/DateUtilsTest.java b/src/test/java/org/opentripplanner/framework/time/DateUtilsTest.java deleted file mode 100644 index d89eea5d73b..00000000000 --- a/src/test/java/org/opentripplanner/framework/time/DateUtilsTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.opentripplanner.framework.time; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.time.DateUtils.secToHHMM; - -import java.time.LocalDate; -import java.time.ZoneId; -import java.time.ZonedDateTime; -import org.junit.jupiter.api.Test; -import org.opentripplanner._support.time.ZoneIds; - -public class DateUtilsTest { - - // Create some time constants: T_(_)? - private static final int T00_00 = 0; - private static final int T00_00_01 = 1; - private static final int T00_00_59 = 59; - private static final int T00_01 = 60; - private static final int T00_05 = 300; - private static final int T08_07 = (8 * 60 + 7) * 60; - private static final int T08_47 = (8 * 60 + 47) * 60; - private static final int T35_00 = 35 * 3600; - - // Create some negative time constants: N_(_)? - private static final int N00_00_01 = -1; - private static final int N00_00_59 = -59; - private static final int N00_05 = -300; - private static final int N08_00 = -8 * 3600; - private static final int N08_07 = -(8 * 60 + 7) * 60; - private static final int N08_47 = -(8 * 60 + 47) * 60; - - public static final ZoneId UTC = ZoneIds.UTC; - - @Test - public final void testToDate() { - ZonedDateTime date = DateUtils.toZonedDateTime("1970-01-01", "00:00", UTC); - assertEquals("1970-01-01", date.toLocalDate().toString()); - assertEquals(0, date.toEpochSecond()); - - date = DateUtils.toZonedDateTime(null, "00:00", UTC); - assertEquals(LocalDate.now(UTC).toString(), date.toLocalDate().toString()); - assertEquals(0, date.toEpochSecond() % TimeUtils.ONE_DAY_SECONDS); - } - - @Test - public final void testSecToHHMM() { - assertEquals("0:00", secToHHMM(T00_00), "Handle zero"); - assertEquals("0:00", secToHHMM(T00_00_01), "Skip seconds(1 sec)"); - assertEquals("0:00", secToHHMM(T00_00_59), "Skip seconds(59 sec), round down"); - assertEquals("0:01", secToHHMM(T00_01), "1 minute with leading zero"); - assertEquals("0:05", secToHHMM(T00_05), "5 minutes"); - assertEquals("8:07", secToHHMM(T08_07), "Hour and min with leading zero on minute"); - assertEquals("8:47", secToHHMM(T08_47), "8 hours and 47 minutes"); - assertEquals("35:00", secToHHMM(T35_00), "allow ServiceTime beyond 24 hours"); - - // Negative times - assertEquals("-0:00", secToHHMM(N00_00_01), "1 sec - round to minus zero"); - assertEquals("-0:00", secToHHMM(N00_00_59), "59 sec - round down with minus sign"); - assertEquals("-0:05", secToHHMM(N00_05), "minus 5 min"); - assertEquals("-8:00", secToHHMM(N08_00)); - assertEquals("-8:07", secToHHMM(N08_07)); - assertEquals("-8:47", secToHHMM(N08_47)); - } -} diff --git a/src/test/java/org/opentripplanner/graph_builder/module/TestStreetLinkerModule.java b/src/test/java/org/opentripplanner/graph_builder/module/TestStreetLinkerModule.java deleted file mode 100644 index 38680c357c4..00000000000 --- a/src/test/java/org/opentripplanner/graph_builder/module/TestStreetLinkerModule.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.opentripplanner.graph_builder.module; - -import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.transit.service.TransitModel; - -public class TestStreetLinkerModule { - - /** For test only */ - public static void link(Graph graph, TransitModel model) { - new StreetLinkerModule(graph, model, DataImportIssueStore.NOOP, false).buildGraph(); - } -} diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/StopAreaMapperTest.java b/src/test/java/org/opentripplanner/gtfs/mapping/StopAreaMapperTest.java deleted file mode 100644 index d58bcfcdd31..00000000000 --- a/src/test/java/org/opentripplanner/gtfs/mapping/StopAreaMapperTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.opentripplanner.gtfs.mapping; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.graph_builder.issue.api.DataImportIssueStore.NOOP; - -import java.util.Set; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import org.junit.jupiter.api.Test; -import org.onebusaway.gtfs.model.AgencyAndId; -import org.onebusaway.gtfs.model.Area; -import org.onebusaway.gtfs.model.Location; -import org.onebusaway.gtfs.model.Stop; -import org.onebusaway.gtfs.model.StopArea; -import org.opentripplanner._support.geometry.Polygons; -import org.opentripplanner.transit.service.StopModel; - -class StopAreaMapperTest { - - private static final String NAME = "Floxjam"; - private static final AgencyAndId AREA_ID = agencyAndId("flox"); - - @Test - void map() { - var stopModel = StopModel.of(); - var stopMapper = new StopMapper(new TranslationHelper(), ignored -> null, stopModel); - var locationMapper = new LocationMapper(stopModel, NOOP); - var mapper = new StopAreaMapper(stopMapper, locationMapper, stopModel); - - var area = new Area(); - area.setId(AREA_ID); - area.setName(NAME); - - var stop1 = stop("stop1"); - var stop2 = stop("stop2"); - var location = location("location"); - - var stopArea = new StopArea(); - stopArea.setArea(area); - stopArea.addLocation(stop1); - stopArea.addLocation(stop2); - stopArea.addLocation(location); - var areaStop = mapper.map(stopArea); - - assertEquals(NAME, areaStop.getName().toString()); - var stopIds = areaStop - .getChildLocations() - .stream() - .map(l -> l.getId().toString()) - .collect(Collectors.toSet()); - assertEquals(Set.of("1:location", "1:stop1", "1:stop2"), stopIds); - } - - private static Stop stop(String id) { - var stop = new Stop(); - stop.setId(agencyAndId(id)); - stop.setLat(1); - stop.setLon(2); - stop.setName("A stop"); - return stop; - } - - private static Location location(String id) { - var stop = new Location(); - stop.setId(agencyAndId(id)); - stop.setName("A stop"); - stop.setGeometry(Polygons.toGeoJson(Polygons.BERLIN)); - return stop; - } - - @Nonnull - private static AgencyAndId agencyAndId(String id) { - return new AgencyAndId("1", id); - } -} diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/TransitModeMapperTest.java b/src/test/java/org/opentripplanner/gtfs/mapping/TransitModeMapperTest.java deleted file mode 100644 index b2e5b1a8a4d..00000000000 --- a/src/test/java/org/opentripplanner/gtfs/mapping/TransitModeMapperTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.opentripplanner.gtfs.mapping; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.transit.model.basic.TransitMode.CARPOOL; -import static org.opentripplanner.transit.model.basic.TransitMode.TAXI; - -import java.util.stream.Stream; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.transit.model.basic.TransitMode; - -class TransitModeMapperTest { - - static Stream testCases() { - return Stream.of( - Arguments.of(1500, TAXI), - Arguments.of(1510, TAXI), - Arguments.of(1551, CARPOOL), - Arguments.of(1555, CARPOOL), - Arguments.of(1560, CARPOOL), - Arguments.of(1561, TAXI), - Arguments.of(1580, TAXI) - ); - } - - @ParameterizedTest(name = "{0} should map to {1}") - @MethodSource("testCases") - void map(int mode, TransitMode expectedMode) { - assertEquals(expectedMode, TransitModeMapper.mapMode(mode)); - } -} diff --git a/src/test/java/org/opentripplanner/mmri/package-info.java b/src/test/java/org/opentripplanner/mmri/package-info.java deleted file mode 100644 index 563a92abdc5..00000000000 --- a/src/test/java/org/opentripplanner/mmri/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/** - * What is this package doing here? - *

    - * In 2013, significant improvements were made to OTP as part of a precommercial procurement project - * in The Netherlands called MMRI ("MultiModale ReisInformatie" => "multimodal travel information"). - * This project is itself part of a larger project called "Better Benutten" => "better utilization". - * Most effort concentrated on the implementation of GTFS-RT updates and related improvements to the - * architecture of OTP. Additionally, a testing module was developed to verify that all the planners - * that were involved in the project (not just OTP) met a minimum set of requirements. OTP was first - * to pass all tests, ahead of two different solutions. Unfortunately, having two sets of tests does - * not make it simpler to continuously verify that OTP still functions correctly, which is why these - * MMRI tests have now been added to OTP's own test suite. These versions are intended to be a close - * approximation of reality, but several minor shortcuts have been taken, like applying trip updates - * directly to the graph instead of going through the thread-safe graph writer framework. Given that - * thread-safety is a technical issue and not a functional one, this is considered to be - * acceptable. - *

    - * The test cases are described here. and in - * here - */ -package org.opentripplanner.mmri; diff --git a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/OsmTagMapperTest.java b/src/test/java/org/opentripplanner/openstreetmap/tagmapping/OsmTagMapperTest.java deleted file mode 100644 index 164faa644c2..00000000000 --- a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/OsmTagMapperTest.java +++ /dev/null @@ -1,213 +0,0 @@ -package org.opentripplanner.openstreetmap.tagmapping; - -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.openstreetmap.wayproperty.MixinPropertiesBuilder.ofBicycleSafety; -import static org.opentripplanner.openstreetmap.wayproperty.WayPropertiesBuilder.withModes; -import static org.opentripplanner.street.model.StreetTraversalPermission.CAR; - -import org.junit.jupiter.api.Test; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; - -public class OsmTagMapperTest { - - @Test - public void isMotorThroughTrafficExplicitlyDisallowed() { - OSMWithTags o = new OSMWithTags(); - OsmTagMapper osmTagMapper = new DefaultMapper(); - - assertFalse(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(o)); - - o.addTag("access", "something"); - assertFalse(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(o)); - - o.addTag("access", "destination"); - assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(o)); - - o.addTag("access", "private"); - assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(o)); - - assertTrue( - osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed( - way("motor_vehicle", "destination") - ) - ); - } - - @Test - public void constantSpeedCarRouting() { - OsmTagMapper osmTagMapper = new ConstantSpeedFinlandMapper(20f); - - var slowWay = new OSMWithTags(); - slowWay.addTag("highway", "residential"); - assertEquals(20f, osmTagMapper.getCarSpeedForWay(slowWay, true)); - - var fastWay = new OSMWithTags(); - fastWay.addTag("highway", "motorway"); - fastWay.addTag("maxspeed", "120 kmph"); - assertEquals(20f, osmTagMapper.getCarSpeedForWay(fastWay, true)); - } - - @Test - public void isBicycleNoThroughTrafficExplicitlyDisallowed() { - OsmTagMapper osmTagMapper = new DefaultMapper(); - assertTrue( - osmTagMapper.isBicycleNoThroughTrafficExplicitlyDisallowed(way("bicycle", "destination")) - ); - assertTrue( - osmTagMapper.isBicycleNoThroughTrafficExplicitlyDisallowed(way("access", "destination")) - ); - } - - @Test - public void isWalkNoThroughTrafficExplicitlyDisallowed() { - OsmTagMapper osmTagMapper = new DefaultMapper(); - assertTrue(osmTagMapper.isWalkNoThroughTrafficExplicitlyDisallowed(way("foot", "destination"))); - assertTrue( - osmTagMapper.isWalkNoThroughTrafficExplicitlyDisallowed(way("access", "destination")) - ); - } - - @Test - public void mixin() { - var source = new DefaultMapper(); - var wps = new WayPropertySet(); - - wps.setProperties("tag=imaginary", withModes(CAR).bicycleSafety(2)); - - wps.setMixinProperties("foo=bar", ofBicycleSafety(0.5)); - source.populateProperties(wps); - - var withoutFoo = new OSMWithTags(); - withoutFoo.addTag("tag", "imaginary"); - assertEquals(2, wps.getDataForWay(withoutFoo).bicycleSafety().back()); - - // the mixin for foo=bar reduces the bike safety factor - var withFoo = new OSMWithTags(); - withFoo.addTag("tag", "imaginary"); - withFoo.addTag("foo", "bar"); - assertEquals(1, wps.getDataForWay(withFoo).bicycleSafety().back()); - } - - @Test - public void testAccessNo() { - OSMWithTags tags = new OSMWithTags(); - OsmTagMapper osmTagMapper = new DefaultMapper(); - - tags.addTag("access", "no"); - - assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); - assertTrue(osmTagMapper.isBicycleNoThroughTrafficExplicitlyDisallowed(tags)); - assertTrue(osmTagMapper.isWalkNoThroughTrafficExplicitlyDisallowed(tags)); - } - - @Test - public void testAccessPrivate() { - OSMWithTags tags = new OSMWithTags(); - OsmTagMapper osmTagMapper = new DefaultMapper(); - - tags.addTag("access", "private"); - - assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); - assertTrue(osmTagMapper.isBicycleNoThroughTrafficExplicitlyDisallowed(tags)); - assertTrue(osmTagMapper.isWalkNoThroughTrafficExplicitlyDisallowed(tags)); - } - - @Test - public void testFootModifier() { - OSMWithTags tags = new OSMWithTags(); - OsmTagMapper osmTagMapper = new DefaultMapper(); - - tags.addTag("access", "private"); - tags.addTag("foot", "yes"); - - assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); - assertTrue(osmTagMapper.isBicycleNoThroughTrafficExplicitlyDisallowed(tags)); - assertFalse(osmTagMapper.isWalkNoThroughTrafficExplicitlyDisallowed(tags)); - } - - @Test - public void testVehicleDenied() { - OSMWithTags tags = new OSMWithTags(); - OsmTagMapper osmTagMapper = new DefaultMapper(); - - tags.addTag("vehicle", "destination"); - - assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); - assertTrue(osmTagMapper.isBicycleNoThroughTrafficExplicitlyDisallowed(tags)); - assertFalse(osmTagMapper.isWalkNoThroughTrafficExplicitlyDisallowed(tags)); - } - - @Test - public void testVehicleDeniedMotorVehiclePermissive() { - OSMWithTags tags = new OSMWithTags(); - OsmTagMapper osmTagMapper = new DefaultMapper(); - - tags.addTag("vehicle", "destination"); - tags.addTag("motor_vehicle", "designated"); - - assertFalse(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); - assertTrue(osmTagMapper.isBicycleNoThroughTrafficExplicitlyDisallowed(tags)); - assertFalse(osmTagMapper.isWalkNoThroughTrafficExplicitlyDisallowed(tags)); - } - - @Test - public void testVehicleDeniedBicyclePermissive() { - OSMWithTags tags = new OSMWithTags(); - OsmTagMapper osmTagMapper = new DefaultMapper(); - - tags.addTag("vehicle", "destination"); - tags.addTag("bicycle", "designated"); - - assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); - assertFalse(osmTagMapper.isBicycleNoThroughTrafficExplicitlyDisallowed(tags)); - assertFalse(osmTagMapper.isWalkNoThroughTrafficExplicitlyDisallowed(tags)); - } - - @Test - public void testMotorcycleModifier() { - OSMWithTags tags = new OSMWithTags(); - OsmTagMapper osmTagMapper = new DefaultMapper(); - - tags.addTag("access", "private"); - tags.addTag("motor_vehicle", "yes"); - - assertFalse(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); - assertTrue(osmTagMapper.isBicycleNoThroughTrafficExplicitlyDisallowed(tags)); - assertTrue(osmTagMapper.isWalkNoThroughTrafficExplicitlyDisallowed(tags)); - } - - @Test - public void testBicycleModifier() { - OSMWithTags tags = new OSMWithTags(); - OsmTagMapper osmTagMapper = new DefaultMapper(); - - tags.addTag("access", "private"); - tags.addTag("bicycle", "yes"); - - assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); - assertFalse(osmTagMapper.isBicycleNoThroughTrafficExplicitlyDisallowed(tags)); - assertTrue(osmTagMapper.isWalkNoThroughTrafficExplicitlyDisallowed(tags)); - } - - @Test - public void testBicyclePermissive() { - OSMWithTags tags = new OSMWithTags(); - OsmTagMapper osmTagMapper = new DefaultMapper(); - - tags.addTag("access", "private"); - tags.addTag("bicycle", "permissive"); - - assertTrue(osmTagMapper.isMotorVehicleThroughTrafficExplicitlyDisallowed(tags)); - assertFalse(osmTagMapper.isBicycleNoThroughTrafficExplicitlyDisallowed(tags)); - assertTrue(osmTagMapper.isWalkNoThroughTrafficExplicitlyDisallowed(tags)); - } - - public OSMWithTags way(String key, String value) { - var way = new OSMWithTags(); - way.addTag(key, value); - return way; - } -} diff --git a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/PortlandMapperTest.java b/src/test/java/org/opentripplanner/openstreetmap/tagmapping/PortlandMapperTest.java deleted file mode 100644 index 26f45fd8c32..00000000000 --- a/src/test/java/org/opentripplanner/openstreetmap/tagmapping/PortlandMapperTest.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.opentripplanner.openstreetmap.tagmapping; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.carTunnel; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.cobblestones; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.fiveLanes; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.footwaySidewalk; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.highwayTertiary; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.highwayTertiaryWithSidewalk; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.highwayTrunk; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.noSidewalk; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.noSidewalkHighSpeed; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.pedestrianTunnel; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.sidewalkBoth; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.southeastLaBonitaWay; -import static org.opentripplanner.openstreetmap.wayproperty.specifier.WayTestData.southwestMayoStreet; - -import java.util.stream.Stream; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.openstreetmap.model.OSMWithTags; -import org.opentripplanner.openstreetmap.wayproperty.WayPropertySet; - -public class PortlandMapperTest { - - static double delta = 0.1; - - static WayPropertySet wps = new WayPropertySet(); - - static Stream cases() { - return Stream.of( - Arguments.of(southeastLaBonitaWay(), 0.8), - Arguments.of(southwestMayoStreet(), 0.9), - Arguments.of(sidewalkBoth(), 0.96), - Arguments.of(pedestrianTunnel(), 1.0), - Arguments.of(highwayTertiaryWithSidewalk(), 1.056), - Arguments.of(cobblestones(), 1.2), - Arguments.of(noSidewalk(), 1.2), - Arguments.of(carTunnel(), 1.2), - Arguments.of(footwaySidewalk(), 1.32), - Arguments.of(highwayTertiary(), 1.32), - Arguments.of(highwayTrunk(), 1.44), - Arguments.of(fiveLanes(), 1.584), - Arguments.of(noSidewalkHighSpeed(), 7.19) - ); - } - - static { - var source = new PortlandMapper(); - source.populateProperties(wps); - } - - @ParameterizedTest(name = "way {0} should have walk safety factor {1}") - @MethodSource("cases") - void walkSafety(OSMWithTags way, double expected) { - var score = wps.getDataForWay(way); - - var ws = score.walkSafety(); - assertEquals(expected, ws.forward(), delta); - assertEquals(expected, ws.back(), delta); - } -} diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/D02_TransitModeReluctanceTest.java b/src/test/java/org/opentripplanner/raptor/moduletests/D02_TransitModeReluctanceTest.java deleted file mode 100644 index 970ae42a3ef..00000000000 --- a/src/test/java/org/opentripplanner/raptor/moduletests/D02_TransitModeReluctanceTest.java +++ /dev/null @@ -1,99 +0,0 @@ -package org.opentripplanner.raptor.moduletests; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.raptor._data.api.PathUtils.pathsToString; -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.util.stream.Stream; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.raptor.RaptorService; -import org.opentripplanner.raptor._data.RaptorTestConstants; -import org.opentripplanner.raptor._data.transit.TestAccessEgress; -import org.opentripplanner.raptor._data.transit.TestTransitData; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; -import org.opentripplanner.raptor.api.request.RaptorProfile; -import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; -import org.opentripplanner.raptor.configure.RaptorConfig; -import org.opentripplanner.raptor.moduletests.support.ModuleTestDebugLogging; -import org.opentripplanner.raptor.moduletests.support.RaptorModuleTestConfig; - -/** - * FEATURE UNDER TEST - *

    - * Raptor should return transit option with the lowest cost when to rides are equal, but have - * different transit-reluctance. - */ -public class D02_TransitModeReluctanceTest implements RaptorTestConstants { - - public static final double[] PREFER_R1 = { 0.99, 1.0 }; - public static final double[] PREFER_R2 = { 0.9, 0.89 }; - private final TestTransitData data = new TestTransitData(); - private final RaptorRequestBuilder requestBuilder = new RaptorRequestBuilder<>(); - private final RaptorService raptorService = new RaptorService<>( - RaptorConfig.defaultConfigForTest() - ); - - @BeforeEach - public void setup() { - // Given 2 identical routes R1 and R2 - data.withRoute( - route(pattern("R1", STOP_A, STOP_B)) - .withTimetable(schedule("00:01, 00:02:40").transitReluctanceIndex(0)) - ); - data.withRoute( - route(pattern("R2", STOP_A, STOP_B)) - .withTimetable(schedule("00:01, 00:02:40").transitReluctanceIndex(1)) - ); - - requestBuilder - .searchParams() - .addAccessPaths(TestAccessEgress.walk(STOP_A, D30s)) - .addEgressPaths(TestAccessEgress.walk(STOP_B, D20s)) - .earliestDepartureTime(T00_00) - .latestArrivalTime(T00_10) - .timetable(true); - - requestBuilder.profile(RaptorProfile.MULTI_CRITERIA); - - ModuleTestDebugLogging.setupDebugLogging(data, requestBuilder); - } - - static Stream testCases() { - return RaptorModuleTestConfig - .multiCriteria() - .build() - .stream() - .flatMap(config -> - Stream.of( - Arguments.of( - PREFER_R1, - config, - "Walk 30s ~ A ~ BUS R1 0:01 0:02:40 ~ B ~ Walk 20s " + "[0:00:30 0:03 2m30s Tₓ0 C₁799]" - ), - Arguments.of( - PREFER_R2, - config, - "Walk 30s ~ A ~ BUS R2 0:01 0:02:40 ~ B ~ Walk 20s " + "[0:00:30 0:03 2m30s Tₓ0 C₁789]" - ) - ) - ); - } - - @ParameterizedTest(name = "Transit reluctance [R1, R2]: {0}, profile: {1}") - @MethodSource("testCases") - void testTransitReluctance( - double[] transitReluctance, - RaptorModuleTestConfig testConfig, - String expected - ) { - data.mcCostParamsBuilder().transitReluctanceFactors(transitReluctance); - var request = testConfig.apply(requestBuilder).build(); - var response = raptorService.route(request, data); - assertEquals(expected, pathsToString(response)); - } -} diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/D03_UnpreferredRouteTest.java b/src/test/java/org/opentripplanner/raptor/moduletests/D03_UnpreferredRouteTest.java deleted file mode 100644 index 41f2fb2ca12..00000000000 --- a/src/test/java/org/opentripplanner/raptor/moduletests/D03_UnpreferredRouteTest.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.opentripplanner.raptor.moduletests; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.raptor._data.api.PathUtils.pathsToString; -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.util.BitSet; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.opentripplanner.raptor.RaptorService; -import org.opentripplanner.raptor._data.RaptorTestConstants; -import org.opentripplanner.raptor._data.transit.TestAccessEgress; -import org.opentripplanner.raptor._data.transit.TestTransitData; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; -import org.opentripplanner.raptor.api.request.RaptorProfile; -import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; -import org.opentripplanner.raptor.configure.RaptorConfig; -import org.opentripplanner.raptor.moduletests.support.ModuleTestDebugLogging; -import org.opentripplanner.routing.api.request.framework.CostLinearFunction; -import org.opentripplanner.transit.model._data.TransitModelForTest; -import org.opentripplanner.transit.model.framework.FeedScopedId; - -/** - * FEATURE UNDER TEST - *

    - * On transit options with identical cost, raptor should drop the unpreferred one which is modeled - * by route penalty. - */ -public class D03_UnpreferredRouteTest implements RaptorTestConstants { - - private static final String EXPECTED = - "Walk 30s ~ A ~ BUS %s 0:01 0:02:40 ~ B ~ Walk 20s " + "[0:00:30 0:03 2m30s Tₓ0 C₁%d]"; - private static final FeedScopedId ROUTE_ID_1 = TransitModelForTest.id("1"); - private static final FeedScopedId ROUTE_ID_2 = TransitModelForTest.id("2"); - private static final CostLinearFunction UNPREFERRED_C1 = CostLinearFunction.of("5m + 1t"); - private final TestTransitData data = new TestTransitData(); - private final RaptorRequestBuilder requestBuilder = new RaptorRequestBuilder<>(); - private final RaptorService raptorService = new RaptorService<>( - RaptorConfig.defaultConfigForTest() - ); - - @BeforeEach - public void setup() { - // Given 2 identical routes R1 and R2 - data.withRoute( - route(pattern("R1", STOP_A, STOP_B).withRoute(TransitModelForTest.route(ROUTE_ID_1).build())) - .withTimetable(schedule("00:01, 00:02:40")) - ); - data.withRoute( - route(pattern("R2", STOP_A, STOP_B).withRoute(TransitModelForTest.route(ROUTE_ID_2).build())) - .withTimetable(schedule("00:01, 00:02:40")) - ); - - requestBuilder - .searchParams() - .addAccessPaths(TestAccessEgress.walk(STOP_A, D30s)) - .addEgressPaths(TestAccessEgress.walk(STOP_B, D20s)) - .earliestDepartureTime(T00_00) - .latestArrivalTime(T00_10) - .timetable(true); - - requestBuilder.profile(RaptorProfile.MULTI_CRITERIA); - - ModuleTestDebugLogging.setupDebugLogging(data, requestBuilder); - } - - @Test - public void unpreferR1() { - unpreferRoute(ROUTE_ID_1); - - var request = requestBuilder.build(); - var response = raptorService.route(request, data); - - // Verify R1 is preferred and the cost is correct - assertEquals(expected("R2", 800), pathsToString(response)); - } - - @Test - public void unpreferR2() { - unpreferRoute(ROUTE_ID_2); - - var request = requestBuilder.build(); - var response = raptorService.route(request, data); - - assertEquals(expected("R1", 800), pathsToString(response)); - } - - private void unpreferRoute(FeedScopedId routeId) { - final BitSet patterns = new BitSet(); - for (var pattern : data.getPatterns()) { - if (pattern.route().getId().equals(routeId)) { - patterns.set(pattern.patternIndex()); - } - } - data.mcCostParamsBuilder().unpreferredPatterns(patterns); - data.mcCostParamsBuilder().unpreferredCost(UNPREFERRED_C1); - } - - private static String expected(String route, int cost) { - return String.format(EXPECTED, route, cost); - } -} diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapperTest.java b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapperTest.java deleted file mode 100644 index 47542782884..00000000000 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapperTest.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.time.Duration; -import java.time.ZonedDateTime; -import java.util.List; -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.transit.TestAccessEgress; -import org.opentripplanner.raptor._data.transit.TestTripSchedule; -import org.opentripplanner.raptor.api.model.RaptorAccessEgress; -import org.opentripplanner.raptor.api.request.RaptorRequest; -import org.opentripplanner.routing.api.request.PassThroughPoint; -import org.opentripplanner.routing.api.request.RouteRequest; -import org.opentripplanner.routing.api.request.framework.CostLinearFunction; -import org.opentripplanner.transit.model._data.TransitModelForTest; -import org.opentripplanner.transit.model.site.StopLocation; - -class RaptorRequestMapperTest { - - private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); - private static final StopLocation STOP_A = TEST_MODEL.stop("Stop:A").build(); - private static final List ACCESS = List.of(TestAccessEgress.walk(12, 45)); - private static final List EGRESS = List.of(TestAccessEgress.walk(144, 54)); - private static final Duration D0s = Duration.ofSeconds(0); - - private static final CostLinearFunction R1 = CostLinearFunction.of("50 + 1.0x"); - private static final CostLinearFunction R2 = CostLinearFunction.of("0 + 1.5x"); - private static final CostLinearFunction R3 = CostLinearFunction.of("30 + 2.0x"); - - static List testCasesRelaxedCost() { - return List.of( - Arguments.of(CostLinearFunction.NORMAL, 0, 0), - Arguments.of(CostLinearFunction.NORMAL, 10, 10), - Arguments.of(R1, 0, 5000), - Arguments.of(R1, 7, 5007), - Arguments.of(R2, 0, 0), - Arguments.of(R2, 100, 150), - Arguments.of(R3, 0, 3000), - Arguments.of(R3, 100, 3200) - ); - } - - @ParameterizedTest - @MethodSource("testCasesRelaxedCost") - void mapRelaxCost(CostLinearFunction input, int cost, int expected) { - var calcCost = RaptorRequestMapper.mapRelaxCost(input); - assertEquals(expected, calcCost.relax(cost)); - } - - @Test - void testPassThroughPoints() { - var req = new RouteRequest(); - - req.setPassThroughPoints(List.of(new PassThroughPoint(List.of(STOP_A), "Via A"))); - - var result = map(req); - - assertTrue(result.multiCriteria().hasPassThroughPoints()); - assertEquals( - "[(Via A, stops: " + STOP_A.getIndex() + ")]", - result.multiCriteria().passThroughPoints().toString() - ); - } - - @Test - void testPassThroughPointsTurnTransitGroupPriorityOff() { - var req = new RouteRequest(); - - // Set pass-through and relax transit-group-priority - req.setPassThroughPoints(List.of(new PassThroughPoint(List.of(STOP_A), "Via A"))); - req.withPreferences(p -> - p.withTransit(t -> t.withRelaxTransitGroupPriority(CostLinearFunction.of("30m + 1.2t"))) - ); - - var result = map(req); - - // transit-group-priority CANNOT be used with pass-through and is turned off... - assertTrue(result.multiCriteria().transitPriorityCalculator().isEmpty()); - } - - private static RaptorRequest map(RouteRequest request) { - return RaptorRequestMapper.mapRequest( - request, - ZonedDateTime.now(), - false, - ACCESS, - EGRESS, - null - ); - } -} diff --git a/src/test/java/org/opentripplanner/updater/GtfsRealtimeFuzzyTripMatcherTest.java b/src/test/java/org/opentripplanner/updater/GtfsRealtimeFuzzyTripMatcherTest.java deleted file mode 100644 index ffd150095b6..00000000000 --- a/src/test/java/org/opentripplanner/updater/GtfsRealtimeFuzzyTripMatcherTest.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.opentripplanner.updater; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - -import com.google.transit.realtime.GtfsRealtime.TripDescriptor; -import org.junit.jupiter.api.Test; -import org.opentripplanner.GtfsTest; -import org.opentripplanner.transit.service.DefaultTransitService; - -public class GtfsRealtimeFuzzyTripMatcherTest extends GtfsTest { - - @Test - public void testMatch() { - String feedId = transitModel.getFeedIds().iterator().next(); - - GtfsRealtimeFuzzyTripMatcher matcher = new GtfsRealtimeFuzzyTripMatcher( - new DefaultTransitService(transitModel) - ); - TripDescriptor trip1 = TripDescriptor - .newBuilder() - .setRouteId("1") - .setDirectionId(0) - .setStartTime("06:47:00") - .setStartDate("20090915") - .build(); - assertEquals("10W1020", matcher.match(feedId, trip1).getTripId()); - trip1 = - TripDescriptor - .newBuilder() - .setRouteId("4") - .setDirectionId(0) - .setStartTime("00:02:00") - .setStartDate("20090915") - .build(); - assertEquals("40W1890", matcher.match(feedId, trip1).getTripId()); - // Test matching with "real time", when schedule uses time grater than 24:00 - trip1 = - TripDescriptor - .newBuilder() - .setRouteId("4") - .setDirectionId(0) - .setStartTime("12:00:00") - .setStartDate("20090915") - .build(); - // No departure at this time - assertFalse(trip1.hasTripId()); - trip1 = - TripDescriptor - .newBuilder() - .setRouteId("1") - .setStartTime("06:47:00") - .setStartDate("20090915") - .build(); - // Missing direction id - assertFalse(trip1.hasTripId()); - } - - @Override - public String getFeedName() { - return "portland/portland.gtfs.zip"; - } -} diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java deleted file mode 100644 index a40bd8bd797..00000000000 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java +++ /dev/null @@ -1,383 +0,0 @@ -package org.opentripplanner.updater.trip; - -import static org.opentripplanner.updater.trip.UpdateIncrementality.DIFFERENTIAL; -import static org.opentripplanner.updater.trip.UpdateIncrementality.FULL_DATASET; - -import com.google.transit.realtime.GtfsRealtime; -import java.time.Duration; -import java.time.LocalDate; -import java.time.ZoneId; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import org.opentripplanner.DateTimeHelper; -import org.opentripplanner.ext.siri.SiriTimetableSnapshotSource; -import org.opentripplanner.ext.siri.updater.EstimatedTimetableHandler; -import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.model.StopTime; -import org.opentripplanner.model.TimetableSnapshot; -import org.opentripplanner.model.calendar.CalendarServiceData; -import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.transit.model._data.TransitModelForTest; -import org.opentripplanner.transit.model.framework.Deduplicator; -import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.model.network.Route; -import org.opentripplanner.transit.model.network.TripPattern; -import org.opentripplanner.transit.model.organization.Operator; -import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.model.site.Station; -import org.opentripplanner.transit.model.site.StopLocation; -import org.opentripplanner.transit.model.timetable.Trip; -import org.opentripplanner.transit.model.timetable.TripOnServiceDate; -import org.opentripplanner.transit.model.timetable.TripTimes; -import org.opentripplanner.transit.model.timetable.TripTimesFactory; -import org.opentripplanner.transit.model.timetable.TripTimesStringBuilder; -import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; -import org.opentripplanner.transit.service.TransitService; -import org.opentripplanner.updater.DefaultRealTimeUpdateContext; -import org.opentripplanner.updater.TimetableSnapshotSourceParameters; -import org.opentripplanner.updater.spi.UpdateResult; -import uk.org.siri.siri20.EstimatedTimetableDeliveryStructure; - -/** - * This class exists so that you can share the data building logic for GTFS and Siri tests. - * Since it's not possible to add a Siri and GTFS updater to the transit model at the same time, - * they each have their own test environment. - *

    - * It is however a goal to change that and then these two can be combined. - */ -public final class RealtimeTestEnvironment { - - private static final TimetableSnapshotSourceParameters PARAMETERS = new TimetableSnapshotSourceParameters( - Duration.ZERO, - false - ); - public static final LocalDate SERVICE_DATE = LocalDate.of(2024, 5, 8); - public static final FeedScopedId SERVICE_ID = TransitModelForTest.id("CAL_1"); - public static final String STOP_A1_ID = "A1"; - public static final String STOP_B1_ID = "B1"; - public static final String STOP_C1_ID = "C1"; - private final TransitModelForTest testModel = TransitModelForTest.of(); - public final ZoneId timeZone = ZoneId.of(TransitModelForTest.TIME_ZONE_ID); - public final Station stationA = testModel.station("A").build(); - public final Station stationB = testModel.station("B").build(); - public final Station stationC = testModel.station("C").build(); - public final Station stationD = testModel.station("D").build(); - public final RegularStop stopA1 = testModel.stop(STOP_A1_ID).withParentStation(stationA).build(); - public final RegularStop stopB1 = testModel.stop(STOP_B1_ID).withParentStation(stationB).build(); - public final RegularStop stopB2 = testModel.stop("B2").withParentStation(stationB).build(); - public final RegularStop stopC1 = testModel.stop(STOP_C1_ID).withParentStation(stationC).build(); - public final RegularStop stopD1 = testModel.stop("D1").withParentStation(stationD).build(); - public final StopModel stopModel = testModel - .stopModelBuilder() - .withRegularStop(stopA1) - .withRegularStop(stopB1) - .withRegularStop(stopB2) - .withRegularStop(stopC1) - .withRegularStop(stopD1) - .build(); - public final FeedScopedId operator1Id = TransitModelForTest.id("TestOperator1"); - public final FeedScopedId route1Id = TransitModelForTest.id("TestRoute1"); - public final Trip trip1; - public final Trip trip2; - public final Operator operator1; - public final TransitModel transitModel; - private final SiriTimetableSnapshotSource siriSource; - private final TimetableSnapshotSource gtfsSource; - private final DateTimeHelper dateTimeHelper; - - private enum SourceType { - GTFS_RT, - SIRI, - } - - /** - * Siri and GTFS-RT cannot be run at the same time, so you need to decide. - */ - public static RealtimeTestEnvironment siri() { - return new RealtimeTestEnvironment(SourceType.SIRI); - } - - /** - * Siri and GTFS-RT cannot be run at the same time, so you need to decide. - */ - public static RealtimeTestEnvironment gtfs() { - return new RealtimeTestEnvironment(SourceType.GTFS_RT); - } - - private RealtimeTestEnvironment(SourceType sourceType) { - transitModel = new TransitModel(stopModel, new Deduplicator()); - transitModel.initTimeZone(timeZone); - transitModel.addAgency(TransitModelForTest.AGENCY); - - operator1 = Operator.of(operator1Id).withName("Operator 1").build(); - transitModel.getOperators().add(operator1); - - Route route1 = TransitModelForTest.route(route1Id).withOperator(operator1).build(); - - trip1 = - createTrip( - "TestTrip1", - route1, - List.of(new StopCall(stopA1, 10, 11), new StopCall(stopB1, 20, 21)) - ); - trip2 = - createTrip( - "TestTrip2", - route1, - List.of( - new StopCall(stopA1, 60, 61), - new StopCall(stopB1, 70, 71), - new StopCall(stopC1, 80, 81) - ) - ); - - CalendarServiceData calendarServiceData = new CalendarServiceData(); - calendarServiceData.putServiceDatesForServiceId( - SERVICE_ID, - List.of(SERVICE_DATE.minusDays(1), SERVICE_DATE, SERVICE_DATE.plusDays(1)) - ); - transitModel.getServiceCodes().put(SERVICE_ID, 0); - transitModel.updateCalendarServiceData(true, calendarServiceData, DataImportIssueStore.NOOP); - - transitModel.index(); - - // SIRI and GTFS-RT cannot be registered with the transit model at the same time - // we are actively refactoring to remove this restriction - // for the time being you cannot run a SIRI and GTFS-RT test at the same time - if (sourceType == SourceType.SIRI) { - siriSource = new SiriTimetableSnapshotSource(PARAMETERS, transitModel); - gtfsSource = null; - } else { - gtfsSource = new TimetableSnapshotSource(PARAMETERS, transitModel); - siriSource = null; - } - dateTimeHelper = new DateTimeHelper(timeZone, RealtimeTestEnvironment.SERVICE_DATE); - } - - public static FeedScopedId id(String id) { - return TransitModelForTest.id(id); - } - - /** - * Returns a new fresh TransitService - */ - public TransitService getTransitService() { - return new DefaultTransitService(transitModel); - } - - /** - * Find the current TripTimes for a trip id on a serviceDate - */ - public TripTimes getTripTimesForTrip(FeedScopedId tripId, LocalDate serviceDate) { - var transitService = getTransitService(); - var trip = transitService.getTripOnServiceDateById(tripId).getTrip(); - var pattern = transitService.getPatternForTrip(trip, serviceDate); - var timetable = transitService.getTimetableForTripPattern(pattern, serviceDate); - return timetable.getTripTimes(trip); - } - - public String getFeedId() { - return TransitModelForTest.FEED_ID; - } - - private EstimatedTimetableHandler getEstimatedTimetableHandler(boolean fuzzyMatching) { - return new EstimatedTimetableHandler(siriSource, fuzzyMatching, getFeedId()); - } - - public TripPattern getPatternForTrip(FeedScopedId tripId) { - return getPatternForTrip(tripId, RealtimeTestEnvironment.SERVICE_DATE); - } - - public TripPattern getPatternForTrip(FeedScopedId tripId, LocalDate serviceDate) { - var transitService = getTransitService(); - var trip = transitService.getTripOnServiceDateById(tripId); - return transitService.getPatternForTrip(trip.getTrip(), serviceDate); - } - - /** - * Find the current TripTimes for a trip id on the default serviceDate - */ - public TripTimes getTripTimesForTrip(Trip trip) { - return getTripTimesForTrip(trip.getId(), SERVICE_DATE); - } - - /** - * Find the current TripTimes for a trip id on the default serviceDate - */ - public TripTimes getTripTimesForTrip(String id) { - return getTripTimesForTrip(id(id), SERVICE_DATE); - } - - public DateTimeHelper getDateTimeHelper() { - return dateTimeHelper; - } - - public TripPattern getPatternForTrip(Trip trip) { - return getTransitService().getPatternForTrip(trip); - } - - public TimetableSnapshot getTimetableSnapshot() { - if (siriSource != null) { - return siriSource.getTimetableSnapshot(); - } else { - return gtfsSource.getTimetableSnapshot(); - } - } - - public String getRealtimeTimetable(String tripId) { - return getRealtimeTimetable(id(tripId), SERVICE_DATE); - } - - public String getRealtimeTimetable(Trip trip) { - return getRealtimeTimetable(trip.getId(), SERVICE_DATE); - } - - public String getRealtimeTimetable(FeedScopedId tripId, LocalDate serviceDate) { - var tt = getTripTimesForTrip(tripId, serviceDate); - var pattern = getPatternForTrip(tripId); - - return TripTimesStringBuilder.encodeTripTimes(tt, pattern); - } - - public String getScheduledTimetable(String tripId) { - return getScheduledTimetable(id(tripId)); - } - - public String getScheduledTimetable(FeedScopedId tripId) { - var pattern = getPatternForTrip(tripId); - var tt = pattern.getScheduledTimetable().getTripTimes(tripId); - - return TripTimesStringBuilder.encodeTripTimes(tt, pattern); - } - - // SIRI updates - - public UpdateResult applyEstimatedTimetableWithFuzzyMatcher( - List updates - ) { - return applyEstimatedTimetable(updates, true); - } - - public UpdateResult applyEstimatedTimetable(List updates) { - return applyEstimatedTimetable(updates, false); - } - - // GTFS-RT updates - - public UpdateResult applyTripUpdate(GtfsRealtime.TripUpdate update) { - return applyTripUpdates(List.of(update), FULL_DATASET); - } - - public UpdateResult applyTripUpdate( - GtfsRealtime.TripUpdate update, - UpdateIncrementality incrementality - ) { - return applyTripUpdates(List.of(update), incrementality); - } - - public UpdateResult applyTripUpdates( - List updates, - UpdateIncrementality incrementality - ) { - Objects.requireNonNull(gtfsSource, "Test environment is configured for SIRI only"); - UpdateResult updateResult = gtfsSource.applyTripUpdates( - null, - BackwardsDelayPropagationType.REQUIRED_NO_DATA, - incrementality, - updates, - getFeedId() - ); - commitTimetableSnapshot(); - return updateResult; - } - - // private methods - - private UpdateResult applyEstimatedTimetable( - List updates, - boolean fuzzyMatching - ) { - Objects.requireNonNull(siriSource, "Test environment is configured for GTFS-RT only"); - UpdateResult updateResult = getEstimatedTimetableHandler(fuzzyMatching) - .applyUpdate( - updates, - DIFFERENTIAL, - new DefaultRealTimeUpdateContext( - new Graph(), - transitModel, - siriSource.getTimetableSnapshotBuffer() - ) - ); - commitTimetableSnapshot(); - return updateResult; - } - - private void commitTimetableSnapshot() { - if (siriSource != null) { - siriSource.flushBuffer(); - } - if (gtfsSource != null) { - gtfsSource.flushBuffer(); - } - } - - private Trip createTrip(String id, Route route, List stops) { - var trip = Trip - .of(id(id)) - .withRoute(route) - .withHeadsign(I18NString.of("Headsign of %s".formatted(id))) - .withServiceId(SERVICE_ID) - .build(); - - var tripOnServiceDate = TripOnServiceDate - .of(trip.getId()) - .withTrip(trip) - .withServiceDate(SERVICE_DATE) - .build(); - - transitModel.addTripOnServiceDate(tripOnServiceDate.getId(), tripOnServiceDate); - - var stopTimes = IntStream - .range(0, stops.size()) - .mapToObj(i -> { - var stop = stops.get(i); - return createStopTime(trip, i, stop.stop(), stop.arrivalTime(), stop.departureTime()); - }) - .collect(Collectors.toList()); - - TripTimes tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, null); - - final TripPattern pattern = TransitModelForTest - .tripPattern(id + "Pattern", route) - .withStopPattern(TransitModelForTest.stopPattern(stops.stream().map(StopCall::stop).toList())) - .build(); - pattern.add(tripTimes); - - transitModel.addTripPattern(pattern.getId(), pattern); - - return trip; - } - - private StopTime createStopTime( - Trip trip, - int stopSequence, - StopLocation stop, - int arrivalTime, - int departureTime - ) { - var st = new StopTime(); - st.setTrip(trip); - st.setStopSequence(stopSequence); - st.setStop(stop); - st.setArrivalTime(arrivalTime); - st.setDepartureTime(departureTime); - return st; - } - - private record StopCall(RegularStop stop, int arrivalTime, int departureTime) {} -} diff --git a/src/test/resources/gbfs/tieroslo/geofencing_zones.json b/src/test/resources/gbfs/tieroslo/geofencing_zones.json deleted file mode 100644 index 19189f4f86b..00000000000 --- a/src/test/resources/gbfs/tieroslo/geofencing_zones.json +++ /dev/null @@ -1,2310 +0,0 @@ -{ - "last_updated": 1669995505, - "ttl": 0, - "version": "2.3", - "data": { - "geofencing_zones": { - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "name": "OSLO Summer 2021", - "rules": [ - { - "vehicle_type_id": [ - "YTI:VehicleType:escooter_oslo", - "YTI:VehicleType:ebicycle_oslo" - ], - "ride_allowed": true, - "ride_through_allowed": true - } - ] - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - 10.687577, - 59.917346 - ], - [ - 10.689719, - 59.91757 - ], - [ - 10.693149, - 59.915496 - ], - [ - 10.693549, - 59.915603 - ], - [ - 10.695344, - 59.915406 - ], - [ - 10.696433, - 59.9152 - ], - [ - 10.697358, - 59.914945 - ], - [ - 10.703902, - 59.910901 - ], - [ - 10.704973, - 59.910023 - ], - [ - 10.706125, - 59.910367 - ], - [ - 10.708318, - 59.90981 - ], - [ - 10.709048, - 59.90921 - ], - [ - 10.709194, - 59.907373 - ], - [ - 10.709308, - 59.906807 - ], - [ - 10.710676, - 59.906546 - ], - [ - 10.712482, - 59.906047 - ], - [ - 10.715777, - 59.906964 - ], - [ - 10.717585, - 59.907176 - ], - [ - 10.718362, - 59.907068 - ], - [ - 10.720131, - 59.906389 - ], - [ - 10.722097, - 59.906165 - ], - [ - 10.724074, - 59.907995 - ], - [ - 10.725487, - 59.908637 - ], - [ - 10.726011, - 59.908948 - ], - [ - 10.727579, - 59.909715 - ], - [ - 10.729922, - 59.910772 - ], - [ - 10.731534, - 59.910969 - ], - [ - 10.734022, - 59.910463 - ], - [ - 10.734379, - 59.909063 - ], - [ - 10.734218, - 59.907531 - ], - [ - 10.735753, - 59.905218 - ], - [ - 10.738504, - 59.903317 - ], - [ - 10.741168, - 59.902322 - ], - [ - 10.743451, - 59.902637 - ], - [ - 10.744563, - 59.903929 - ], - [ - 10.74708, - 59.906759 - ], - [ - 10.749004, - 59.907773 - ], - [ - 10.751673, - 59.907154 - ], - [ - 10.75142, - 59.904713 - ], - [ - 10.752924, - 59.904548 - ], - [ - 10.753226, - 59.904059 - ], - [ - 10.753523, - 59.903061 - ], - [ - 10.750778, - 59.901725 - ], - [ - 10.752392, - 59.900919 - ], - [ - 10.75685, - 59.902768 - ], - [ - 10.757897, - 59.902216 - ], - [ - 10.75732, - 59.901444 - ], - [ - 10.756139, - 59.900651 - ], - [ - 10.754918, - 59.898621 - ], - [ - 10.754512, - 59.897874 - ], - [ - 10.754745, - 59.897098 - ], - [ - 10.755141, - 59.896554 - ], - [ - 10.755718, - 59.895909 - ], - [ - 10.755684, - 59.895421 - ], - [ - 10.75486, - 59.894861 - ], - [ - 10.75628, - 59.894047 - ], - [ - 10.757165221094933, - 59.89390175879156 - ], - [ - 10.759106447045964, - 59.89147857906161 - ], - [ - 10.761746326879063, - 59.88890934390498 - ], - [ - 10.764488740333803, - 59.886756017380435 - ], - [ - 10.767790076895182, - 59.884918153072604 - ], - [ - 10.768649096133226, - 59.883717148821795 - ], - [ - 10.774173632442148, - 59.883563457076114 - ], - [ - 10.774906116394662, - 59.88327546158081 - ], - [ - 10.774591630458728, - 59.88282789499579 - ], - [ - 10.776189, - 59.882927 - ], - [ - 10.776783, - 59.882649 - ], - [ - 10.778223, - 59.88239 - ], - [ - 10.779364, - 59.88221 - ], - [ - 10.78106, - 59.88226 - ], - [ - 10.78352, - 59.881761 - ], - [ - 10.784643, - 59.88144 - ], - [ - 10.78564, - 59.880914 - ], - [ - 10.786738, - 59.880499 - ], - [ - 10.78852, - 59.879795 - ], - [ - 10.788919, - 59.879665 - ], - [ - 10.789433, - 59.879383 - ], - [ - 10.790716, - 59.879292 - ], - [ - 10.792192, - 59.879244 - ], - [ - 10.799489, - 59.879952 - ], - [ - 10.80197, - 59.879402 - ], - [ - 10.806901, - 59.87959 - ], - [ - 10.810856, - 59.880185 - ], - [ - 10.805831, - 59.887359 - ], - [ - 10.801735, - 59.892648 - ], - [ - 10.803608, - 59.894296 - ], - [ - 10.804989, - 59.894104 - ], - [ - 10.805318, - 59.893477 - ], - [ - 10.80519, - 59.892795 - ], - [ - 10.805487, - 59.89217 - ], - [ - 10.805705, - 59.891759 - ], - [ - 10.806059, - 59.891418 - ], - [ - 10.80841, - 59.888222 - ], - [ - 10.815093, - 59.887873 - ], - [ - 10.821355, - 59.890048 - ], - [ - 10.822055, - 59.891379 - ], - [ - 10.821592, - 59.894541 - ], - [ - 10.820849, - 59.897019 - ], - [ - 10.82081, - 59.898294 - ], - [ - 10.820285, - 59.899129 - ], - [ - 10.820063, - 59.900453 - ], - [ - 10.819054, - 59.90147 - ], - [ - 10.821037, - 59.903571 - ], - [ - 10.821163, - 59.903519 - ], - [ - 10.822416, - 59.903528 - ], - [ - 10.822439, - 59.903451 - ], - [ - 10.823081, - 59.903455 - ], - [ - 10.823077, - 59.903521 - ], - [ - 10.822077, - 59.904421 - ], - [ - 10.822345, - 59.904619 - ], - [ - 10.82239, - 59.904733 - ], - [ - 10.821725, - 59.905312 - ], - [ - 10.820101, - 59.907008 - ], - [ - 10.820445, - 59.908342 - ], - [ - 10.818684, - 59.911458 - ], - [ - 10.818111, - 59.912228 - ], - [ - 10.823407, - 59.912687 - ], - [ - 10.824883, - 59.913119 - ], - [ - 10.822054, - 59.914982 - ], - [ - 10.820256, - 59.916701 - ], - [ - 10.818784, - 59.917621 - ], - [ - 10.818894, - 59.917652 - ], - [ - 10.818823, - 59.917706 - ], - [ - 10.8184, - 59.917827 - ], - [ - 10.818414, - 59.917968 - ], - [ - 10.818182, - 59.918099 - ], - [ - 10.818195, - 59.918179 - ], - [ - 10.818002, - 59.918324 - ], - [ - 10.818065, - 59.918537 - ], - [ - 10.817746, - 59.918747 - ], - [ - 10.817771853184778, - 59.919060015777795 - ], - [ - 10.817641535436191, - 59.919334313241 - ], - [ - 10.817253369762122, - 59.92016471317217 - ], - [ - 10.817067537520016, - 59.921261284050956 - ], - [ - 10.817737023934322, - 59.922733200931205 - ], - [ - 10.814197529700122, - 59.92460810083015 - ], - [ - 10.810978161382877, - 59.9264397852684 - ], - [ - 10.812405069001775, - 59.92660364907742 - ], - [ - 10.813117506743577, - 59.92712347193087 - ], - [ - 10.813882519011425, - 59.92802623695317 - ], - [ - 10.81558560488797, - 59.92881325879451 - ], - [ - 10.819868304249026, - 59.930211473383615 - ], - [ - 10.824304829920784, - 59.9316174994396 - ], - [ - 10.83025248260097, - 59.93448904912082 - ], - [ - 10.832611785455912, - 59.936347545299554 - ], - [ - 10.829367317734333, - 59.93953928328541 - ], - [ - 10.819790907558911, - 59.940711418196614 - ], - [ - 10.81881548029232, - 59.941866346895225 - ], - [ - 10.81031703932274, - 59.943246252399135 - ], - [ - 10.802510433894849, - 59.94232820122942 - ], - [ - 10.800143, - 59.94264 - ], - [ - 10.797091, - 59.943181 - ], - [ - 10.794973, - 59.947701 - ], - [ - 10.792395, - 59.948248 - ], - [ - 10.794348, - 59.950349 - ], - [ - 10.795747, - 59.9514 - ], - [ - 10.797669, - 59.952565 - ], - [ - 10.79768, - 59.953333 - ], - [ - 10.793784, - 59.95392 - ], - [ - 10.79339, - 59.956074 - ], - [ - 10.797104, - 59.956691 - ], - [ - 10.795132, - 59.959956 - ], - [ - 10.794082, - 59.960799 - ], - [ - 10.793441, - 59.960794 - ], - [ - 10.791472, - 59.960936 - ], - [ - 10.788484, - 59.960297 - ], - [ - 10.786342, - 59.960273 - ], - [ - 10.784512, - 59.96229 - ], - [ - 10.784255, - 59.96301 - ], - [ - 10.785606, - 59.964267 - ], - [ - 10.785628, - 59.965209 - ], - [ - 10.783802, - 59.966468 - ], - [ - 10.781205, - 59.965769 - ], - [ - 10.780721, - 59.966028 - ], - [ - 10.780177, - 59.966117 - ], - [ - 10.77965, - 59.966055 - ], - [ - 10.778763, - 59.965858 - ], - [ - 10.778379, - 59.965797 - ], - [ - 10.777944, - 59.965853 - ], - [ - 10.777004, - 59.966234 - ], - [ - 10.769503, - 59.967927 - ], - [ - 10.766244, - 59.967631 - ], - [ - 10.765191, - 59.965302 - ], - [ - 10.76122, - 59.965685 - ], - [ - 10.754526, - 59.965425 - ], - [ - 10.751988, - 59.9647 - ], - [ - 10.750515, - 59.964404 - ], - [ - 10.748898, - 59.964421 - ], - [ - 10.746719, - 59.964153 - ], - [ - 10.744433, - 59.963341 - ], - [ - 10.739722, - 59.963308 - ], - [ - 10.737243, - 59.963478 - ], - [ - 10.73483, - 59.963531 - ], - [ - 10.734494, - 59.967231 - ], - [ - 10.73258, - 59.968011 - ], - [ - 10.73374, - 59.964376 - ], - [ - 10.733217, - 59.962427 - ], - [ - 10.734604, - 59.961139 - ], - [ - 10.732683, - 59.959511 - ], - [ - 10.732454, - 59.957576 - ], - [ - 10.732339, - 59.956654 - ], - [ - 10.731767, - 59.955778 - ], - [ - 10.729022, - 59.9544 - ], - [ - 10.727162, - 59.953346 - ], - [ - 10.727, - 59.952709 - ], - [ - 10.726269, - 59.951945 - ], - [ - 10.724372, - 59.949613 - ], - [ - 10.722744, - 59.948744 - ], - [ - 10.720964, - 59.947867 - ], - [ - 10.719147, - 59.947458 - ], - [ - 10.716952, - 59.947768 - ], - [ - 10.717625, - 59.950161 - ], - [ - 10.716953304599347, - 59.95123857393473 - ], - [ - 10.716361743887454, - 59.951196807911636 - ], - [ - 10.714308, - 59.950961 - ], - [ - 10.7123, - 59.950721 - ], - [ - 10.711077, - 59.950103 - ], - [ - 10.710495, - 59.950611 - ], - [ - 10.70858, - 59.950256 - ], - [ - 10.706861, - 59.949741 - ], - [ - 10.708201, - 59.952176 - ], - [ - 10.708676, - 59.954882 - ], - [ - 10.708067, - 59.95738 - ], - [ - 10.7072, - 59.958238 - ], - [ - 10.705126, - 59.958376 - ], - [ - 10.703478, - 59.958013 - ], - [ - 10.700792, - 59.957345 - ], - [ - 10.697309, - 59.957191 - ], - [ - 10.695678, - 59.955528 - ], - [ - 10.694974, - 59.954029 - ], - [ - 10.694844, - 59.953168 - ], - [ - 10.693603, - 59.952752 - ], - [ - 10.692661, - 59.953666 - ], - [ - 10.691528, - 59.95491 - ], - [ - 10.690429, - 59.956215 - ], - [ - 10.690447, - 59.959074 - ], - [ - 10.689576, - 59.959484 - ], - [ - 10.685242, - 59.959649 - ], - [ - 10.680987, - 59.959724 - ], - [ - 10.678302, - 59.959411 - ], - [ - 10.676037, - 59.958745 - ], - [ - 10.674125216549873, - 59.957909368938346 - ], - [ - 10.67322992850205, - 59.95743845698356 - ], - [ - 10.672213433099746, - 59.957073737876684 - ], - [ - 10.666666, - 59.956539 - ], - [ - 10.664284, - 59.956772 - ], - [ - 10.662673, - 59.956543 - ], - [ - 10.65942, - 59.955745 - ], - [ - 10.658216, - 59.955569 - ], - [ - 10.654555, - 59.956926 - ], - [ - 10.65292, - 59.957484 - ], - [ - 10.651637, - 59.958384 - ], - [ - 10.651486, - 59.959286 - ], - [ - 10.650796, - 59.95996 - ], - [ - 10.647778, - 59.961542 - ], - [ - 10.64712, - 59.962482 - ], - [ - 10.646076, - 59.9629 - ], - [ - 10.640822, - 59.96219 - ], - [ - 10.639926, - 59.961995 - ], - [ - 10.630801, - 59.961333 - ], - [ - 10.632761, - 59.954949 - ], - [ - 10.634492, - 59.952681 - ], - [ - 10.634186, - 59.952483 - ], - [ - 10.633764, - 59.952135 - ], - [ - 10.634263, - 59.951901 - ], - [ - 10.634572, - 59.951578 - ], - [ - 10.63479, - 59.95062 - ], - [ - 10.635518, - 59.949692 - ], - [ - 10.635869, - 59.947503 - ], - [ - 10.635935, - 59.946419 - ], - [ - 10.636382, - 59.945364 - ], - [ - 10.635548, - 59.944527 - ], - [ - 10.634821, - 59.94371 - ], - [ - 10.633683, - 59.943055 - ], - [ - 10.633628, - 59.942171 - ], - [ - 10.633083, - 59.941489 - ], - [ - 10.63261, - 59.940036 - ], - [ - 10.632291, - 59.938903 - ], - [ - 10.633838, - 59.937789 - ], - [ - 10.634985, - 59.936781 - ], - [ - 10.635825, - 59.935926 - ], - [ - 10.634147, - 59.933758 - ], - [ - 10.633299, - 59.93226 - ], - [ - 10.631951, - 59.931097 - ], - [ - 10.629841, - 59.93033 - ], - [ - 10.627535, - 59.929842 - ], - [ - 10.627202, - 59.929558 - ], - [ - 10.62783, - 59.928948 - ], - [ - 10.62824, - 59.928668 - ], - [ - 10.627808, - 59.927866 - ], - [ - 10.62595, - 59.927039 - ], - [ - 10.625788, - 59.926851 - ], - [ - 10.626434, - 59.926353 - ], - [ - 10.62701, - 59.926144 - ], - [ - 10.627806, - 59.925847 - ], - [ - 10.628272, - 59.925301 - ], - [ - 10.627081, - 59.92463 - ], - [ - 10.626299, - 59.924299 - ], - [ - 10.625889, - 59.923806 - ], - [ - 10.625752, - 59.923353 - ], - [ - 10.625976, - 59.922638 - ], - [ - 10.627122, - 59.922431 - ], - [ - 10.627907, - 59.922338 - ], - [ - 10.628355, - 59.922162 - ], - [ - 10.628967, - 59.922014 - ], - [ - 10.629751, - 59.921695 - ], - [ - 10.630176, - 59.921335 - ], - [ - 10.629969, - 59.920491 - ], - [ - 10.63008, - 59.920209 - ], - [ - 10.630297, - 59.91959 - ], - [ - 10.63057, - 59.919256 - ], - [ - 10.630619, - 59.918453 - ], - [ - 10.631062, - 59.918122 - ], - [ - 10.631561, - 59.918051 - ], - [ - 10.632437, - 59.918529 - ], - [ - 10.632973, - 59.918476 - ], - [ - 10.633472, - 59.918293 - ], - [ - 10.634406, - 59.917735 - ], - [ - 10.634705, - 59.917042 - ], - [ - 10.634257, - 59.916489 - ], - [ - 10.633487, - 59.916275 - ], - [ - 10.63336, - 59.916172 - ], - [ - 10.63331, - 59.91598 - ], - [ - 10.633315, - 59.914699 - ], - [ - 10.634435, - 59.914175 - ], - [ - 10.635022, - 59.914218 - ], - [ - 10.635022, - 59.914623 - ], - [ - 10.635539, - 59.914922 - ], - [ - 10.63602, - 59.914995 - ], - [ - 10.636347, - 59.914927 - ], - [ - 10.638346, - 59.914527 - ], - [ - 10.640538, - 59.914083 - ], - [ - 10.64214, - 59.911986 - ], - [ - 10.64676, - 59.91294 - ], - [ - 10.649693, - 59.91406 - ], - [ - 10.649041, - 59.91244 - ], - [ - 10.65145, - 59.912597 - ], - [ - 10.652128, - 59.913311 - ], - [ - 10.654842, - 59.914189 - ], - [ - 10.656544, - 59.914563 - ], - [ - 10.65577, - 59.915611 - ], - [ - 10.655881, - 59.91591 - ], - [ - 10.657296, - 59.916305 - ], - [ - 10.660673, - 59.916977 - ], - [ - 10.66344, - 59.917713 - ], - [ - 10.664669, - 59.917915 - ], - [ - 10.666225, - 59.918045 - ], - [ - 10.667923, - 59.918365 - ], - [ - 10.671949, - 59.919449 - ], - [ - 10.672596, - 59.919468 - ], - [ - 10.67297, - 59.919106 - ], - [ - 10.67254, - 59.918542 - ], - [ - 10.67034, - 59.916935 - ], - [ - 10.667644, - 59.915772 - ], - [ - 10.666052, - 59.91499 - ], - [ - 10.66424, - 59.914329 - ], - [ - 10.662968, - 59.913975 - ], - [ - 10.662679, - 59.912894 - ], - [ - 10.662802, - 59.91271 - ], - [ - 10.662855, - 59.912525 - ], - [ - 10.662892, - 59.912248 - ], - [ - 10.663268, - 59.912123 - ], - [ - 10.663674, - 59.911903 - ], - [ - 10.663718, - 59.911682 - ], - [ - 10.666089, - 59.911342 - ], - [ - 10.666437, - 59.911073 - ], - [ - 10.666612, - 59.910603 - ], - [ - 10.667331, - 59.910313 - ], - [ - 10.666122, - 59.909331 - ], - [ - 10.665722, - 59.908822 - ], - [ - 10.664803, - 59.908294 - ], - [ - 10.663568, - 59.907353 - ], - [ - 10.664236, - 59.90647 - ], - [ - 10.664365, - 59.905735 - ], - [ - 10.664373, - 59.90399 - ], - [ - 10.664338, - 59.902448 - ], - [ - 10.666901, - 59.90081 - ], - [ - 10.668391, - 59.899236 - ], - [ - 10.668717, - 59.898815 - ], - [ - 10.669702, - 59.89854 - ], - [ - 10.670936, - 59.898469 - ], - [ - 10.671516, - 59.89844 - ], - [ - 10.672208, - 59.898521 - ], - [ - 10.672678, - 59.898752 - ], - [ - 10.673036, - 59.898886 - ], - [ - 10.672998, - 59.898393 - ], - [ - 10.673574, - 59.898072 - ], - [ - 10.674904, - 59.898919 - ], - [ - 10.675568, - 59.898951 - ], - [ - 10.676719, - 59.900216 - ], - [ - 10.677554, - 59.900122 - ], - [ - 10.678753, - 59.898899 - ], - [ - 10.677605, - 59.89743 - ], - [ - 10.677497, - 59.896483 - ], - [ - 10.682677, - 59.897315 - ], - [ - 10.684746, - 59.897508 - ], - [ - 10.685371, - 59.898127 - ], - [ - 10.685312, - 59.898734 - ], - [ - 10.688495, - 59.899716 - ], - [ - 10.694208, - 59.901146 - ], - [ - 10.698902, - 59.902867 - ], - [ - 10.697001, - 59.904053 - ], - [ - 10.692517, - 59.902632 - ], - [ - 10.691911, - 59.902705 - ], - [ - 10.687294, - 59.901715 - ], - [ - 10.686957, - 59.902824 - ], - [ - 10.687309, - 59.90323 - ], - [ - 10.689902, - 59.903918 - ], - [ - 10.693765, - 59.90566 - ], - [ - 10.694209, - 59.906718 - ], - [ - 10.696105, - 59.90734 - ], - [ - 10.695788, - 59.907558 - ], - [ - 10.694281, - 59.907216 - ], - [ - 10.693907, - 59.907558 - ], - [ - 10.693459, - 59.907877 - ], - [ - 10.693087, - 59.908858 - ], - [ - 10.690732, - 59.909233 - ], - [ - 10.691793, - 59.909689 - ], - [ - 10.692658, - 59.910216 - ], - [ - 10.692771, - 59.910641 - ], - [ - 10.693086, - 59.910997 - ], - [ - 10.693085, - 59.91143 - ], - [ - 10.69305, - 59.911802 - ], - [ - 10.692947, - 59.912254 - ], - [ - 10.692032, - 59.913482 - ], - [ - 10.68968, - 59.915085 - ], - [ - 10.687044, - 59.915443 - ], - [ - 10.687544, - 59.916644 - ], - [ - 10.687577, - 59.917346 - ] - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "name": "NP Frogner og vigelandsparken", - "rules": [ - { - "vehicle_type_id": [ - "YTI:VehicleType:escooter_oslo", - "YTI:VehicleType:ebicycle_oslo" - ], - "ride_allowed": false, - "ride_through_allowed": true - } - ] - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - 10.708611, - 59.925037 - ], - [ - 10.710421, - 59.926146 - ], - [ - 10.711554, - 59.926854 - ], - [ - 10.708529, - 59.927892 - ], - [ - 10.707201, - 59.92841 - ], - [ - 10.706745, - 59.928559 - ], - [ - 10.706106, - 59.928492 - ], - [ - 10.706014, - 59.928846 - ], - [ - 10.706405, - 59.929097 - ], - [ - 10.70664, - 59.92958 - ], - [ - 10.706775, - 59.929681 - ], - [ - 10.706859, - 59.929941 - ], - [ - 10.707147, - 59.930235 - ], - [ - 10.70715, - 59.930376 - ], - [ - 10.70715, - 59.930477 - ], - [ - 10.706916, - 59.930666 - ], - [ - 10.706978, - 59.930341 - ], - [ - 10.706758, - 59.930177 - ], - [ - 10.706167, - 59.93003 - ], - [ - 10.705945, - 59.930157 - ], - [ - 10.704796, - 59.930488 - ], - [ - 10.703563, - 59.930424 - ], - [ - 10.701887, - 59.930109 - ], - [ - 10.701477, - 59.930108 - ], - [ - 10.701197, - 59.93012 - ], - [ - 10.700728, - 59.930271 - ], - [ - 10.700423, - 59.930114 - ], - [ - 10.699743, - 59.929839 - ], - [ - 10.698705, - 59.929562 - ], - [ - 10.697002, - 59.929257 - ], - [ - 10.695299, - 59.929069 - ], - [ - 10.693864, - 59.9301 - ], - [ - 10.693765, - 59.929788 - ], - [ - 10.69312, - 59.929715 - ], - [ - 10.692991, - 59.929577 - ], - [ - 10.692781, - 59.929426 - ], - [ - 10.692649, - 59.929149 - ], - [ - 10.690892, - 59.928511 - ], - [ - 10.689455, - 59.928667 - ], - [ - 10.689256, - 59.928503 - ], - [ - 10.688056, - 59.928913 - ], - [ - 10.688308, - 59.928455 - ], - [ - 10.688322, - 59.927437 - ], - [ - 10.6882, - 59.92726 - ], - [ - 10.687977, - 59.927132 - ], - [ - 10.686372, - 59.926403 - ], - [ - 10.685361, - 59.925709 - ], - [ - 10.685413, - 59.925398 - ], - [ - 10.686845, - 59.924708 - ], - [ - 10.687428, - 59.924598 - ], - [ - 10.68836, - 59.924319 - ], - [ - 10.689365, - 59.92514 - ], - [ - 10.690181, - 59.924913 - ], - [ - 10.691551, - 59.926037 - ], - [ - 10.691175, - 59.926257 - ], - [ - 10.691406, - 59.926521 - ], - [ - 10.691672, - 59.926558 - ], - [ - 10.691904, - 59.92651 - ], - [ - 10.691996, - 59.926328 - ], - [ - 10.692174, - 59.926046 - ], - [ - 10.692962, - 59.925435 - ], - [ - 10.695119, - 59.925454 - ], - [ - 10.695092, - 59.926223 - ], - [ - 10.696203, - 59.927011 - ], - [ - 10.697195, - 59.927393 - ], - [ - 10.697659, - 59.927373 - ], - [ - 10.697755, - 59.927388 - ], - [ - 10.697895, - 59.927363 - ], - [ - 10.697938, - 59.927109 - ], - [ - 10.697925, - 59.926836 - ], - [ - 10.698022, - 59.926771 - ], - [ - 10.698009, - 59.926638 - ], - [ - 10.698007, - 59.926075 - ], - [ - 10.697944, - 59.925487 - ], - [ - 10.698123, - 59.925005 - ], - [ - 10.698141, - 59.924788 - ], - [ - 10.697858, - 59.924587 - ], - [ - 10.697884, - 59.924382 - ], - [ - 10.69796, - 59.924008 - ], - [ - 10.697985, - 59.923959 - ], - [ - 10.697985, - 59.923924 - ], - [ - 10.697971, - 59.923892 - ], - [ - 10.698013, - 59.923875 - ], - [ - 10.698029, - 59.923859 - ], - [ - 10.698038, - 59.923818 - ], - [ - 10.69804, - 59.923801 - ], - [ - 10.698029, - 59.92378 - ], - [ - 10.698014, - 59.923748 - ], - [ - 10.697866, - 59.92372 - ], - [ - 10.69693, - 59.923741 - ], - [ - 10.695022, - 59.923042 - ], - [ - 10.693212, - 59.922751 - ], - [ - 10.69208, - 59.922151 - ], - [ - 10.690058, - 59.921156 - ], - [ - 10.691843, - 59.920241 - ], - [ - 10.69467, - 59.921056 - ], - [ - 10.695619, - 59.921537 - ], - [ - 10.696359, - 59.922142 - ], - [ - 10.697861, - 59.923276 - ], - [ - 10.69825, - 59.923495 - ], - [ - 10.698502, - 59.923519 - ], - [ - 10.6986, - 59.92353 - ], - [ - 10.698673, - 59.923527 - ], - [ - 10.698737, - 59.923521 - ], - [ - 10.698789, - 59.92351 - ], - [ - 10.698868, - 59.92348 - ], - [ - 10.699029, - 59.923386 - ], - [ - 10.699408, - 59.923512 - ], - [ - 10.699998, - 59.923536 - ], - [ - 10.700497, - 59.923551 - ], - [ - 10.700976, - 59.923514 - ], - [ - 10.701528, - 59.923438 - ], - [ - 10.702418, - 59.923253 - ], - [ - 10.703044, - 59.923132 - ], - [ - 10.703605, - 59.923008 - ], - [ - 10.704098, - 59.922928 - ], - [ - 10.704186, - 59.922934 - ], - [ - 10.704307, - 59.922921 - ], - [ - 10.704602, - 59.922899 - ], - [ - 10.70489, - 59.922898 - ], - [ - 10.705659, - 59.923388 - ], - [ - 10.706335, - 59.923788 - ], - [ - 10.706632, - 59.92394 - ], - [ - 10.707189, - 59.924234 - ], - [ - 10.70738, - 59.924331 - ], - [ - 10.707741, - 59.924549 - ], - [ - 10.707929, - 59.924627 - ], - [ - 10.708104, - 59.924722 - ], - [ - 10.708288, - 59.924831 - ], - [ - 10.708416, - 59.924911 - ], - [ - 10.708509, - 59.924953 - ], - [ - 10.70854, - 59.92499 - ], - [ - 10.708611, - 59.925037 - ] - ] - ] - ] - } - } - ] - } - } -} \ No newline at end of file diff --git a/src/test/resources/netex/nordic/build-config.json b/src/test/resources/netex/nordic/build-config.json deleted file mode 100644 index 4a8351d1c8b..00000000000 --- a/src/test/resources/netex/nordic/build-config.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "transitServiceStart": "2017-12-21", - "transitServiceEnd": "2018-01-31", - "netexDefaults" : { - "moduleFilePattern" : "netex_.*\\.zip", - "sharedFilePattern" : "_stops.xml", - "sharedGroupFilePattern" : "_(\\w{3})_shared_data.xml", - "groupFilePattern" : "(\\w{3})_.*\\.xml", - "feedId": "EN" - } -} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/alerts.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/alerts.json deleted file mode 100644 index eb7b3d24154..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/alerts.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "data" : { - "alerts" : [ - { - "id" : "QWxlcnQ6RjpuZWl0aGVyLWhlYWRlci1ub3ItZGVzY3JpcHRpb24", - "alertHeaderText" : "", - "alertDescriptionText" : "", - "alertUrl" : null, - "alertDescriptionTextTranslations" : [ ], - "alertHeaderTextTranslations" : [ ] - }, - { - "id" : "QWxlcnQ6Rjpuby1oZWFkZXI", - "alertHeaderText" : "Second string", - "alertDescriptionText" : "Second string", - "alertUrl" : null, - "alertDescriptionTextTranslations" : [ - { - "language" : null, - "text" : "Second string" - }, - { - "language" : "de", - "text" : "Zweite Zeichenabfolge" - }, - { - "language" : "fi", - "text" : "Etkö ole varma, mitä tämä tarkoittaa" - } - ], - "alertHeaderTextTranslations" : [ ] - }, - { - "id" : "QWxlcnQ6Rjphbi1hbGVydA", - "alertHeaderText" : "A header", - "alertDescriptionText" : "A description", - "alertUrl" : "https://example.com", - "alertDescriptionTextTranslations" : [ ], - "alertHeaderTextTranslations" : [ ] - }, - { - "id" : "QWxlcnQ6Rjpuby1kZXNjcmlwdGlvbg", - "alertHeaderText" : "First string", - "alertDescriptionText" : "First string", - "alertUrl" : null, - "alertDescriptionTextTranslations" : [ ], - "alertHeaderTextTranslations" : [ - { - "text" : "First string", - "language" : null - }, - { - "text" : "Erste Zeichenabfolge", - "language" : "de" - }, - { - "text" : "Minulla ei ole aavistustakaan kuinka puhua suomea", - "language" : "fi" - } - ] - } - ] - } -} \ No newline at end of file diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/feedinfo.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/feedinfo.json deleted file mode 100644 index 3cf3bd06d66..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/feedinfo.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "data" : { - "feeds" : [ - { - "agencies" : [ - { - "name" : "speedtransit", - "url" : "www.otp-foo.bar" - } - ], - "publisher" : { - "name" : "publisher", - "url" : "www.z.org" - } - } - ] - } -} \ No newline at end of file diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/nearest.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/nearest.json deleted file mode 100644 index b6b5b7ee674..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/nearest.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "data" : { - "nearest" : { - "edges" : [ - { - "node" : { - "place" : { - "id" : "U3RvcDpGOkE", - "gtfsId" : "F:A", - "parentStation" : null - } - } - }, - { - "node" : { - "place" : { - "stationId" : "Network-1:FooStation" - } - } - }, - { - "node" : { - "place" : { - "vehicleId" : "Network-1:free-floating-bicycle" - } - } - } - ] - } - } -} \ No newline at end of file diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/patterns.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/patterns.json deleted file mode 100644 index b23ced4f954..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/patterns.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "data" : { - "patterns" : [ - { - "code" : "F:BUS", - "headsign" : "Trip Headsign", - "trips" : [ - { - "gtfsId" : "F:123", - "stoptimes" : [ - { - "stop" : { - "gtfsId" : "F:Stop_0", - "name" : "Stop_0" - }, - "headsign" : "Stop headsign at stop 10", - "scheduledArrival" : 39600, - "scheduledDeparture" : 39600, - "stopPosition" : 10, - "realtimeState" : "SCHEDULED", - "pickupType" : "SCHEDULED", - "dropoffType" : "SCHEDULED" - }, - { - "stop" : { - "gtfsId" : "F:Stop_1", - "name" : "Stop_1" - }, - "headsign" : "Stop headsign at stop 20", - "scheduledArrival" : 39900, - "scheduledDeparture" : 39900, - "stopPosition" : 20, - "realtimeState" : "SCHEDULED", - "pickupType" : "SCHEDULED", - "dropoffType" : "SCHEDULED" - }, - { - "stop" : { - "gtfsId" : "F:Stop_2", - "name" : "Stop_2" - }, - "headsign" : "Stop headsign at stop 30", - "scheduledArrival" : 40200, - "scheduledDeparture" : 40200, - "stopPosition" : 30, - "realtimeState" : "SCHEDULED", - "pickupType" : "SCHEDULED", - "dropoffType" : "SCHEDULED" - } - ], - "occupancy" : { - "occupancyStatus" : "FEW_SEATS_AVAILABLE" - } - } - ], - "vehiclePositions" : [ - { - "vehicleId" : "F:vehicle-1", - "label" : null, - "lat" : null, - "lon" : null, - "stopRelationship" : null, - "speed" : null, - "heading" : null, - "lastUpdated" : 31556889864403199, - "trip" : { - "gtfsId" : "F:123" - } - }, - { - "vehicleId" : "F:vehicle-2", - "label" : "vehicle2", - "lat" : 60.0, - "lon" : 80.0, - "stopRelationship" : { - "status" : "IN_TRANSIT_TO", - "stop" : { - "gtfsId" : "F:Stop_0" - } - }, - "speed" : 10.2, - "heading" : 80.0, - "lastUpdated" : -31557014167219200, - "trip" : { - "gtfsId" : "F:123" - } - } - ] - } - ] - } -} \ No newline at end of file diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json deleted file mode 100644 index ea58480be8e..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json +++ /dev/null @@ -1,344 +0,0 @@ -{ - "data" : { - "plan" : { - "itineraries" : [ - { - "start" : "2020-02-02T11:00:00Z", - "end" : "2020-02-02T12:00:00Z", - "startTime" : 1580641200000, - "endTime" : 1580644800000, - "generalizedCost" : 4072, - "accessibilityScore" : 0.5, - "emissionsPerPerson" : { - "co2" : 123.0 - }, - "numberOfTransfers" : 1, - "walkDistance" : 28.0, - "walkTime" : 20, - "legs" : [ - { - "mode" : "WALK", - "start" : { - "scheduledTime" : "2020-02-02T11:00:00Z", - "estimated" : null - }, - "end" : { - "scheduledTime" : "2020-02-02T11:00:20Z", - "estimated" : null - }, - "from" : { - "name" : "A", - "lat" : 5.0, - "lon" : 8.0, - "arrival" : { - "scheduledTime" : "2020-02-02T11:00:00Z", - "estimated" : null - }, - "departure" : { - "scheduledTime" : "2020-02-02T11:00:00Z", - "estimated" : null - }, - "departureTime" : 1580641200000, - "arrivalTime" : 1580641200000 - }, - "to" : { - "name" : "B", - "lat" : 6.0, - "lon" : 8.5, - "arrival" : { - "scheduledTime" : "2020-02-02T11:00:20Z", - "estimated" : null - }, - "departure" : { - "scheduledTime" : "2020-02-02T11:00:20Z", - "estimated" : null - }, - "departureTime" : 1580641220000, - "arrivalTime" : 1580641220000 - }, - "startTime" : 1580641200000, - "endTime" : 1580641220000, - "generalizedCost" : 40, - "headsign" : null, - "trip" : null, - "intermediatePlaces" : null, - "alerts" : [ ], - "rideHailingEstimate" : null, - "accessibilityScore" : null - }, - { - "mode" : "BUS", - "start" : { - "scheduledTime" : "2020-02-02T10:51:00Z", - "estimated" : { - "time" : "2020-02-02T11:01:00Z", - "delay" : "PT10M" - } - }, - "end" : { - "scheduledTime" : "2020-02-02T11:05:00Z", - "estimated" : { - "time" : "2020-02-02T11:15:00Z", - "delay" : "PT10M" - } - }, - "from" : { - "name" : "B", - "lat" : 6.0, - "lon" : 8.5, - "arrival" : { - "scheduledTime" : "2020-02-02T10:51:00Z", - "estimated" : { - "delay" : "PT10M", - "time" : "2020-02-02T11:01:00Z" - } - }, - "departure" : { - "scheduledTime" : "2020-02-02T10:51:00Z", - "estimated" : { - "delay" : "PT10M", - "time" : "2020-02-02T11:01:00Z" - } - }, - "departureTime" : 1580641260000, - "arrivalTime" : 1580641260000 - }, - "to" : { - "name" : "C", - "lat" : 7.0, - "lon" : 9.0, - "arrival" : { - "scheduledTime" : "2020-02-02T11:05:00Z", - "estimated" : { - "delay" : "PT10M", - "time" : "2020-02-02T11:15:00Z" - } - }, - "departure" : { - "scheduledTime" : "2020-02-02T11:05:00Z", - "estimated" : { - "delay" : "PT10M", - "time" : "2020-02-02T11:15:00Z" - } - }, - "departureTime" : 1580642100000, - "arrivalTime" : 1580642100000 - }, - "startTime" : 1580641260000, - "endTime" : 1580642100000, - "generalizedCost" : 992, - "headsign" : "Headsign at boarding (stop index 5)", - "trip" : { - "tripHeadsign" : "Trip headsign 122" - }, - "intermediatePlaces" : [ - { - "arrival" : { - "scheduledTime" : "2020-02-02T11:01:00Z", - "estimated" : { - "time" : "2020-02-02T11:11:00Z", - "delay" : "PT10M" - } - }, - "departure" : { - "scheduledTime" : "2020-02-02T11:01:00Z", - "estimated" : { - "time" : "2020-02-02T11:11:00Z", - "delay" : "PT10M" - } - }, - "stop" : { - "name" : "B" - } - } - ], - "alerts" : [ ], - "rideHailingEstimate" : null, - "accessibilityScore" : null - }, - { - "mode" : "RAIL", - "start" : { - "scheduledTime" : "2020-02-02T11:20:00Z", - "estimated" : { - "time" : "2020-02-02T11:30:00Z", - "delay" : "PT10M" - } - }, - "end" : { - "scheduledTime" : "2020-02-02T11:40:00Z", - "estimated" : { - "time" : "2020-02-02T11:50:00Z", - "delay" : "PT10M" - } - }, - "from" : { - "name" : "C", - "lat" : 7.0, - "lon" : 9.0, - "arrival" : { - "scheduledTime" : "2020-02-02T11:20:00Z", - "estimated" : { - "delay" : "PT10M", - "time" : "2020-02-02T11:30:00Z" - } - }, - "departure" : { - "scheduledTime" : "2020-02-02T11:20:00Z", - "estimated" : { - "delay" : "PT10M", - "time" : "2020-02-02T11:30:00Z" - } - }, - "departureTime" : 1580643000000, - "arrivalTime" : 1580643000000 - }, - "to" : { - "name" : "D", - "lat" : 8.0, - "lon" : 9.5, - "arrival" : { - "scheduledTime" : "2020-02-02T11:40:00Z", - "estimated" : { - "delay" : "PT10M", - "time" : "2020-02-02T11:50:00Z" - } - }, - "departure" : { - "scheduledTime" : "2020-02-02T11:40:00Z", - "estimated" : { - "delay" : "PT10M", - "time" : "2020-02-02T11:50:00Z" - } - }, - "departureTime" : 1580644200000, - "arrivalTime" : 1580644200000 - }, - "startTime" : 1580643000000, - "endTime" : 1580644200000, - "generalizedCost" : 2040, - "headsign" : "Headsign at boarding (stop index 5)", - "trip" : { - "tripHeadsign" : "Trip headsign 439" - }, - "intermediatePlaces" : [ - { - "arrival" : { - "scheduledTime" : "2020-02-02T11:30:00Z", - "estimated" : { - "time" : "2020-02-02T11:40:00Z", - "delay" : "PT10M" - } - }, - "departure" : { - "scheduledTime" : "2020-02-02T11:30:00Z", - "estimated" : { - "time" : "2020-02-02T11:40:00Z", - "delay" : "PT10M" - } - }, - "stop" : { - "name" : "C" - } - } - ], - "alerts" : [ - { - "id" : "QWxlcnQ6Rjphbi1hbGVydA", - "alertHeaderText" : "A header", - "alertDescriptionText" : "A description", - "alertEffect" : "REDUCED_SERVICE", - "alertCause" : "MAINTENANCE", - "alertSeverityLevel" : "SEVERE", - "alertUrl" : "https://example.com", - "effectiveStartDate" : 1676459008, - "effectiveEndDate" : 1676545408, - "entities" : [ - { - "name" : "A", - "gtfsId" : "F:A", - "lat" : 5.0, - "lon" : 8.0 - } - ] - } - ], - "rideHailingEstimate" : null, - "accessibilityScore" : null - }, - { - "mode" : "CAR", - "start" : { - "scheduledTime" : "2020-02-02T11:50:00Z", - "estimated" : null - }, - "end" : { - "scheduledTime" : "2020-02-02T12:00:00Z", - "estimated" : null - }, - "from" : { - "name" : "D", - "lat" : 8.0, - "lon" : 9.5, - "arrival" : { - "scheduledTime" : "2020-02-02T11:50:00Z", - "estimated" : null - }, - "departure" : { - "scheduledTime" : "2020-02-02T11:50:00Z", - "estimated" : null - }, - "departureTime" : 1580644200000, - "arrivalTime" : 1580644200000 - }, - "to" : { - "name" : "E", - "lat" : 9.0, - "lon" : 10.0, - "arrival" : { - "scheduledTime" : "2020-02-02T12:00:00Z", - "estimated" : null - }, - "departure" : { - "scheduledTime" : "2020-02-02T12:00:00Z", - "estimated" : null - }, - "departureTime" : 1580644800000, - "arrivalTime" : 1580644800000 - }, - "startTime" : 1580644200000, - "endTime" : 1580644800000, - "generalizedCost" : 1000, - "headsign" : null, - "trip" : null, - "intermediatePlaces" : null, - "alerts" : [ ], - "rideHailingEstimate" : { - "provider" : { - "id" : "uber" - }, - "productName" : "UberX", - "minPrice" : { - "currency" : { - "code" : "EUR", - "digits" : 2 - }, - "amount" : 10.0 - }, - "maxPrice" : { - "currency" : { - "code" : "EUR", - "digits" : 2 - }, - "amount" : 20.0 - }, - "arrival" : "PT10M" - }, - "accessibilityScore" : null - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-fares.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-fares.json deleted file mode 100644 index 1defc81ded1..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-fares.json +++ /dev/null @@ -1,191 +0,0 @@ -{ - "data" : { - "plan" : { - "itineraries" : [ - { - "legs" : [ - { - "mode" : "WALK", - "from" : { - "name" : "A", - "lat" : 5.0, - "lon" : 8.0, - "departureTime" : 1580641200000, - "arrivalTime" : 1580641200000 - }, - "to" : { - "name" : "B", - "lat" : 6.0, - "lon" : 8.5, - "departureTime" : 1580641220000, - "arrivalTime" : 1580641220000 - }, - "startTime" : 1580641200000, - "endTime" : 1580641220000, - "generalizedCost" : 40, - "fareProducts" : [ ] - }, - { - "mode" : "BUS", - "from" : { - "name" : "B", - "lat" : 6.0, - "lon" : 8.5, - "departureTime" : 1580641260000, - "arrivalTime" : 1580641260000 - }, - "to" : { - "name" : "C", - "lat" : 7.0, - "lon" : 9.0, - "departureTime" : 1580642100000, - "arrivalTime" : 1580642100000 - }, - "startTime" : 1580641260000, - "endTime" : 1580642100000, - "generalizedCost" : 992, - "fareProducts" : [ - { - "id" : "5d8f889c-42cb-3bcc-89d5-480b995c78c8", - "product" : { - "id" : "F:day-pass", - "name" : "day-pass", - "__typename" : "DefaultFareProduct", - "price" : { - "currency" : { - "digits" : 2, - "code" : "EUR" - }, - "amount" : 10.0 - }, - "riderCategory" : { - "id" : "F:senior-citizens", - "name" : "Senior citizens" - }, - "medium" : { - "id" : "F:oyster", - "name" : "TfL Oyster Card" - } - } - }, - { - "id" : "09bb5f2b-6af9-3355-8b5d-5e93a27ce280", - "product" : { - "id" : "F:single-ticket", - "name" : "single-ticket", - "__typename" : "DefaultFareProduct", - "price" : { - "currency" : { - "digits" : 2, - "code" : "EUR" - }, - "amount" : 10.0 - }, - "riderCategory" : { - "id" : "F:senior-citizens", - "name" : "Senior citizens" - }, - "medium" : { - "id" : "F:oyster", - "name" : "TfL Oyster Card" - } - } - } - ] - }, - { - "mode" : "RAIL", - "from" : { - "name" : "C", - "lat" : 7.0, - "lon" : 9.0, - "departureTime" : 1580643000000, - "arrivalTime" : 1580643000000 - }, - "to" : { - "name" : "D", - "lat" : 8.0, - "lon" : 9.5, - "departureTime" : 1580644200000, - "arrivalTime" : 1580644200000 - }, - "startTime" : 1580643000000, - "endTime" : 1580644200000, - "generalizedCost" : 2040, - "fareProducts" : [ - { - "id" : "5d8f889c-42cb-3bcc-89d5-480b995c78c8", - "product" : { - "id" : "F:day-pass", - "name" : "day-pass", - "__typename" : "DefaultFareProduct", - "price" : { - "currency" : { - "digits" : 2, - "code" : "EUR" - }, - "amount" : 10.0 - }, - "riderCategory" : { - "id" : "F:senior-citizens", - "name" : "Senior citizens" - }, - "medium" : { - "id" : "F:oyster", - "name" : "TfL Oyster Card" - } - } - }, - { - "id" : "46190ddd-93b0-3136-adb7-a18394f8b0ef", - "product" : { - "id" : "F:single-ticket", - "name" : "single-ticket", - "__typename" : "DefaultFareProduct", - "price" : { - "currency" : { - "digits" : 2, - "code" : "EUR" - }, - "amount" : 10.0 - }, - "riderCategory" : { - "id" : "F:senior-citizens", - "name" : "Senior citizens" - }, - "medium" : { - "id" : "F:oyster", - "name" : "TfL Oyster Card" - } - } - } - ] - }, - { - "mode" : "CAR", - "from" : { - "name" : "D", - "lat" : 8.0, - "lon" : 9.5, - "departureTime" : 1580644200000, - "arrivalTime" : 1580644200000 - }, - "to" : { - "name" : "E", - "lat" : 9.0, - "lon" : 10.0, - "departureTime" : 1580644800000, - "arrivalTime" : 1580644800000 - }, - "startTime" : 1580644200000, - "endTime" : 1580644800000, - "generalizedCost" : 1000, - "fareProducts" : [ ] - } - ], - "fares" : [ ] - } - ] - } - } -} \ No newline at end of file diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-stop-positions.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-stop-positions.json deleted file mode 100644 index 8b7e9771958..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-stop-positions.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "data" : { - "plan" : { - "itineraries" : [ - { - "startTime" : 1580641200000, - "endTime" : 1580644800000, - "generalizedCost" : 4072, - "accessibilityScore" : 0.5, - "legs" : [ - { - "mode" : "WALK", - "from" : { - "name" : "A", - "lat" : 5.0, - "lon" : 8.0, - "departureTime" : 1580641200000, - "arrivalTime" : 1580641200000, - "stopPosition" : null - }, - "to" : { - "name" : "B", - "lat" : 6.0, - "lon" : 8.5, - "departureTime" : 1580641220000, - "arrivalTime" : 1580641220000, - "stopPosition" : null - }, - "startTime" : 1580641200000, - "endTime" : 1580641220000, - "generalizedCost" : 40 - }, - { - "mode" : "BUS", - "from" : { - "name" : "B", - "lat" : 6.0, - "lon" : 8.5, - "departureTime" : 1580641260000, - "arrivalTime" : 1580641260000, - "stopPosition" : { - "__typename" : "PositionAtStop", - "position" : 0 - } - }, - "to" : { - "name" : "C", - "lat" : 7.0, - "lon" : 9.0, - "departureTime" : 1580642100000, - "arrivalTime" : 1580642100000, - "stopPosition" : { - "__typename" : "PositionAtStop", - "position" : 0 - } - }, - "startTime" : 1580641260000, - "endTime" : 1580642100000, - "generalizedCost" : 992 - }, - { - "mode" : "RAIL", - "from" : { - "name" : "C", - "lat" : 7.0, - "lon" : 9.0, - "departureTime" : 1580643000000, - "arrivalTime" : 1580643000000, - "stopPosition" : { - "__typename" : "PositionAtStop", - "position" : 0 - } - }, - "to" : { - "name" : "D", - "lat" : 8.0, - "lon" : 9.5, - "departureTime" : 1580644200000, - "arrivalTime" : 1580644200000, - "stopPosition" : { - "__typename" : "PositionAtStop", - "position" : 0 - } - }, - "startTime" : 1580643000000, - "endTime" : 1580644200000, - "generalizedCost" : 2040 - }, - { - "mode" : "CAR", - "from" : { - "name" : "D", - "lat" : 8.0, - "lon" : 9.5, - "departureTime" : 1580644200000, - "arrivalTime" : 1580644200000, - "stopPosition" : null - }, - "to" : { - "name" : "E", - "lat" : 9.0, - "lon" : 10.0, - "departureTime" : 1580644800000, - "arrivalTime" : 1580644800000, - "stopPosition" : null - }, - "startTime" : 1580644200000, - "endTime" : 1580644800000, - "generalizedCost" : 1000 - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-tutorial.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-tutorial.json deleted file mode 100644 index d213443f7cd..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-tutorial.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "data" : { - "plan" : { - "itineraries" : [ - { - "start" : "2020-02-02T11:00:00Z", - "end" : "2020-02-02T12:00:00Z", - "legs" : [ - { - "mode" : "WALK", - "from" : { - "name" : "A", - "lat" : 5.0, - "lon" : 8.0, - "departure" : { - "scheduledTime" : "2020-02-02T11:00:00Z", - "estimated" : null - } - }, - "to" : { - "name" : "B", - "lat" : 6.0, - "lon" : 8.5, - "arrival" : { - "scheduledTime" : "2020-02-02T11:00:20Z", - "estimated" : null - } - }, - "route" : null, - "legGeometry" : null - }, - { - "mode" : "BUS", - "from" : { - "name" : "B", - "lat" : 6.0, - "lon" : 8.5, - "departure" : { - "scheduledTime" : "2020-02-02T10:51:00Z", - "estimated" : { - "time" : "2020-02-02T11:01:00Z", - "delay" : "PT10M" - } - } - }, - "to" : { - "name" : "C", - "lat" : 7.0, - "lon" : 9.0, - "arrival" : { - "scheduledTime" : "2020-02-02T11:05:00Z", - "estimated" : { - "time" : "2020-02-02T11:15:00Z", - "delay" : "PT10M" - } - } - }, - "route" : { - "gtfsId" : "F:BUS", - "longName" : "Long name for BUS", - "shortName" : "RBUS" - }, - "legGeometry" : { - "points" : "_{rc@_d{r@????_ibE_t`B" - } - }, - { - "mode" : "RAIL", - "from" : { - "name" : "C", - "lat" : 7.0, - "lon" : 9.0, - "departure" : { - "scheduledTime" : "2020-02-02T11:20:00Z", - "estimated" : { - "time" : "2020-02-02T11:30:00Z", - "delay" : "PT10M" - } - } - }, - "to" : { - "name" : "D", - "lat" : 8.0, - "lon" : 9.5, - "arrival" : { - "scheduledTime" : "2020-02-02T11:40:00Z", - "estimated" : { - "time" : "2020-02-02T11:50:00Z", - "delay" : "PT10M" - } - } - }, - "route" : { - "gtfsId" : "F:2", - "longName" : null, - "shortName" : "R2" - }, - "legGeometry" : { - "points" : "_evi@_y|u@????_ibE_t`B" - } - }, - { - "mode" : "CAR", - "from" : { - "name" : "D", - "lat" : 8.0, - "lon" : 9.5, - "departure" : { - "scheduledTime" : "2020-02-02T11:50:00Z", - "estimated" : null - } - }, - "to" : { - "name" : "E", - "lat" : 9.0, - "lon" : 10.0, - "arrival" : { - "scheduledTime" : "2020-02-02T12:00:00Z", - "estimated" : null - } - }, - "route" : null, - "legGeometry" : null - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/planConnection.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/planConnection.json deleted file mode 100644 index 53ab016cc93..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/planConnection.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "data" : { - "planConnection" : { - "searchDateTime" : "2023-01-27T21:08:35+01:00", - "routingErrors" : [ ], - "pageInfo" : { - "hasNextPage" : false, - "hasPreviousPage" : false, - "startCursor" : null, - "endCursor" : null, - "searchWindowUsed" : null - }, - "edges" : [ - { - "cursor" : "NoCursor", - "node" : { - "start" : "2020-02-02T11:00:00Z", - "end" : "2020-02-02T12:00:00Z", - "legs" : [ - { - "mode" : "WALK" - }, - { - "mode" : "BUS" - }, - { - "mode" : "RAIL" - }, - { - "mode" : "CAR" - } - ] - } - } - ] - } - } -} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/rental-vehicle.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/rental-vehicle.json deleted file mode 100644 index 9017fe77a93..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/rental-vehicle.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "data": { - "rentalVehicle": { - "vehicleId":"Network-1:free-floating-bicycle", - "name":"free-floating-bicycle", - "allowPickupNow":true, - "lon":19.01, - "lat":47.52, - "rentalUris":null, - "operative":true, - "vehicleType": { - "formFactor":"BICYCLE", - "propulsionType":"HUMAN" - }, - "rentalNetwork": { - "networkId":"Network-1", - "url":"https://foo.bar" - } - } - } -} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/routes-extended.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/routes-extended.json deleted file mode 100644 index 8856972ce4e..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/routes-extended.json +++ /dev/null @@ -1,188 +0,0 @@ -{ - "data" : { - "routes" : [ - { - "longName" : "Long name for CARPOOL", - "shortName" : "RCARPOOL", - "gtfsId" : "F:CARPOOL", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "CARPOOL", - "sortOrder" : 12, - "bikesAllowed" : "ALLOWED", - "patterns" : [ ] - }, - { - "longName" : "Long name for SUBWAY", - "shortName" : "RSUBWAY", - "gtfsId" : "F:SUBWAY", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "SUBWAY", - "sortOrder" : 2, - "bikesAllowed" : "NO_INFORMATION", - "patterns" : [ ] - }, - { - "longName" : "Long name for BUS", - "shortName" : "RBUS", - "gtfsId" : "F:BUS", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "BUS", - "sortOrder" : 3, - "bikesAllowed" : "ALLOWED", - "patterns" : [ ] - }, - { - "longName" : "Long name for FERRY", - "shortName" : "RFERRY", - "gtfsId" : "F:FERRY", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "FERRY", - "sortOrder" : 5, - "bikesAllowed" : "NO_INFORMATION", - "patterns" : [ ] - }, - { - "longName" : "Long name for COACH", - "shortName" : "RCOACH", - "gtfsId" : "F:COACH", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "COACH", - "sortOrder" : 1, - "bikesAllowed" : "NOT_ALLOWED", - "patterns" : [ ] - }, - { - "longName" : "Long name for TRAM", - "shortName" : "RTRAM", - "gtfsId" : "F:TRAM", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "TRAM", - "sortOrder" : 4, - "bikesAllowed" : "NOT_ALLOWED", - "patterns" : [ ] - }, - { - "longName" : "Long name for CABLE_CAR", - "shortName" : "RCABLE_CAR", - "gtfsId" : "F:CABLE_CAR", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "CABLE_CAR", - "sortOrder" : 7, - "bikesAllowed" : "NOT_ALLOWED", - "patterns" : [ ] - }, - { - "longName" : "Long name for FUNICULAR", - "shortName" : "RFUNICULAR", - "gtfsId" : "F:FUNICULAR", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "FUNICULAR", - "sortOrder" : 9, - "bikesAllowed" : "ALLOWED", - "patterns" : [ ] - }, - { - "longName" : "Long name for RAIL", - "shortName" : "RRAIL", - "gtfsId" : "F:RAIL", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "RAIL", - "sortOrder" : null, - "bikesAllowed" : "ALLOWED", - "patterns" : [ ] - }, - { - "longName" : "Long name for MONORAIL", - "shortName" : "RMONORAIL", - "gtfsId" : "F:MONORAIL", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "MONORAIL", - "sortOrder" : 11, - "bikesAllowed" : "NO_INFORMATION", - "patterns" : [ ] - }, - { - "longName" : "Long name for GONDOLA", - "shortName" : "RGONDOLA", - "gtfsId" : "F:GONDOLA", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "GONDOLA", - "sortOrder" : 8, - "bikesAllowed" : "NO_INFORMATION", - "patterns" : [ ] - }, - { - "longName" : "Long name for TROLLEYBUS", - "shortName" : "RTROLLEYBUS", - "gtfsId" : "F:TROLLEYBUS", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "TROLLEYBUS", - "sortOrder" : 10, - "bikesAllowed" : "NOT_ALLOWED", - "patterns" : [ ] - }, - { - "longName" : "Long name for AIRPLANE", - "shortName" : "RAIRPLANE", - "gtfsId" : "F:AIRPLANE", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "AIRPLANE", - "sortOrder" : 6, - "bikesAllowed" : "ALLOWED", - "patterns" : [ ] - }, - { - "longName" : "Long name for TAXI", - "shortName" : "RTAXI", - "gtfsId" : "F:TAXI", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "TAXI", - "sortOrder" : 13, - "bikesAllowed" : "NOT_ALLOWED", - "patterns" : [ ] - } - ] - } -} \ No newline at end of file diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/routes-tutorial.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/routes-tutorial.json deleted file mode 100644 index e2bdb289c32..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/routes-tutorial.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "data" : { - "routes" : [ - { - "longName" : "Long name for CARPOOL", - "shortName" : "RCARPOOL", - "gtfsId" : "F:CARPOOL", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "CARPOOL" - }, - { - "longName" : "Long name for SUBWAY", - "shortName" : "RSUBWAY", - "gtfsId" : "F:SUBWAY", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "SUBWAY" - }, - { - "longName" : "Long name for BUS", - "shortName" : "RBUS", - "gtfsId" : "F:BUS", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "BUS" - }, - { - "longName" : "Long name for FERRY", - "shortName" : "RFERRY", - "gtfsId" : "F:FERRY", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "FERRY" - }, - { - "longName" : "Long name for COACH", - "shortName" : "RCOACH", - "gtfsId" : "F:COACH", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "COACH" - }, - { - "longName" : "Long name for TRAM", - "shortName" : "RTRAM", - "gtfsId" : "F:TRAM", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "TRAM" - }, - { - "longName" : "Long name for CABLE_CAR", - "shortName" : "RCABLE_CAR", - "gtfsId" : "F:CABLE_CAR", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "CABLE_CAR" - }, - { - "longName" : "Long name for FUNICULAR", - "shortName" : "RFUNICULAR", - "gtfsId" : "F:FUNICULAR", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "FUNICULAR" - }, - { - "longName" : "Long name for RAIL", - "shortName" : "RRAIL", - "gtfsId" : "F:RAIL", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "RAIL" - }, - { - "longName" : "Long name for MONORAIL", - "shortName" : "RMONORAIL", - "gtfsId" : "F:MONORAIL", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "MONORAIL" - }, - { - "longName" : "Long name for GONDOLA", - "shortName" : "RGONDOLA", - "gtfsId" : "F:GONDOLA", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "GONDOLA" - }, - { - "longName" : "Long name for TROLLEYBUS", - "shortName" : "RTROLLEYBUS", - "gtfsId" : "F:TROLLEYBUS", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "TROLLEYBUS" - }, - { - "longName" : "Long name for AIRPLANE", - "shortName" : "RAIRPLANE", - "gtfsId" : "F:AIRPLANE", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "AIRPLANE" - }, - { - "longName" : "Long name for TAXI", - "shortName" : "RTAXI", - "gtfsId" : "F:TAXI", - "agency" : { - "gtfsId" : "F:A1", - "name" : "Agency Test" - }, - "mode" : "TAXI" - } - ] - } -} \ No newline at end of file diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/stops.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/stops.json deleted file mode 100644 index 307b07b58aa..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/stops.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "data" : { - "stops" : [ - { - "gtfsId" : "F:A", - "lat" : 5.0, - "lon" : 8.0, - "name" : "A", - "vehicleMode" : "BUS" - }, - { - "gtfsId" : "F:B", - "lat" : 6.0, - "lon" : 8.5, - "name" : "B", - "vehicleMode" : "BUS" - }, - { - "gtfsId" : "F:C", - "lat" : 7.0, - "lon" : 9.0, - "name" : "C", - "vehicleMode" : "BUS" - }, - { - "gtfsId" : "F:D", - "lat" : 8.0, - "lon" : 9.5, - "name" : "D", - "vehicleMode" : "BUS" - }, - { - "gtfsId" : "F:E", - "lat" : 9.0, - "lon" : 10.0, - "name" : "E", - "vehicleMode" : "BUS" - }, - { - "gtfsId" : "F:F", - "lat" : 9.0, - "lon" : 10.5, - "name" : "F", - "vehicleMode" : "BUS" - }, - { - "gtfsId" : "F:G", - "lat" : 9.5, - "lon" : 11.0, - "name" : "G", - "vehicleMode" : "BUS" - }, - { - "gtfsId" : "F:H", - "lat" : 10.0, - "lon" : 11.5, - "name" : "H", - "vehicleMode" : "BUS" - } - ] - } -} \ No newline at end of file diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/vehicle-parking.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/vehicle-parking.json deleted file mode 100644 index 196c00de6f4..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/vehicle-parking.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "data" : { - "vehicleParkings" : [ - { - "name" : "parking", - "vehicleParkingId" : "F:parking-1" - } - ] - } -} \ No newline at end of file diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/vehicle-rental-station.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/vehicle-rental-station.json deleted file mode 100644 index ad1ce76d9be..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/vehicle-rental-station.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "data" : { - "vehicleRentalStation" : { - "stationId" : "Network-1:FooStation", - "name" : "FooStation", - "vehiclesAvailable" : 10, - "availableVehicles" : { - "byType" : [ - { - "vehicleType" : { - "formFactor" : "BICYCLE", - "propulsionType" : "ELECTRIC" - }, - "count" : 5 - }, - { - "vehicleType" : { - "formFactor" : "BICYCLE", - "propulsionType" : "HUMAN" - }, - "count" : 5 - } - ], - "total" : 10 - }, - "spacesAvailable" : 10, - "availableSpaces" : { - "byType" : [ - { - "vehicleType" : { - "formFactor" : "BICYCLE", - "propulsionType" : "ELECTRIC" - }, - "count" : 3 - }, - { - "vehicleType" : { - "formFactor" : "BICYCLE", - "propulsionType" : "HUMAN" - }, - "count" : 7 - } - ], - "total" : 10 - }, - "allowDropoff" : false, - "allowPickup" : false, - "allowDropoffNow" : false, - "allowPickupNow" : false, - "lon" : 18.99, - "lat" : 47.51, - "capacity" : null, - "allowOverloading" : false, - "rentalUris" : null, - "operative" : false, - "rentalNetwork" : { - "networkId" : "Network-1", - "url" : "https://foo.bar" - } - } - } -} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json deleted file mode 100644 index 703663dc7ec..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "data" : { - "plan" : { - "itineraries" : [ - { - "legs" : [ - { - "steps" : [ - { - "streetName" : "street", - "area" : false, - "relativeDirection" : "DEPART", - "absoluteDirection" : "NORTHEAST" - }, - { - "streetName" : "elevator", - "area" : false, - "relativeDirection" : "ELEVATOR", - "absoluteDirection" : null - } - ] - }, - { - "steps" : [ ] - }, - { - "steps" : [ ] - }, - { - "steps" : [ ] - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/alerts.graphql b/src/test/resources/org/opentripplanner/apis/gtfs/queries/alerts.graphql deleted file mode 100644 index 33ff47dd33b..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/queries/alerts.graphql +++ /dev/null @@ -1,18 +0,0 @@ -{ - alerts { - id - alertHeaderText - alertDescriptionText - alertUrl - # these translations are a bit questionable, the above fields are already translated into the - # language selected in the request - alertDescriptionTextTranslations { - language - text - } - alertHeaderTextTranslations { - text - language - } - } -} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-extended.graphql b/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-extended.graphql deleted file mode 100644 index 76bf8aa84e0..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-extended.graphql +++ /dev/null @@ -1,157 +0,0 @@ -{ - plan( - from: { lat: 52.3092, lon: 13.0291 } - to: { lat: 52.5147, lon: 13.3927 } - date: "2023-02-15" - time: "11:37" - parking: { - unpreferredCost: 555 - preferred: [{ not: [{ tags: ["a", "b", "c"] }] }] - filters: [{ select: [{ tags: ["e"] }] }] - } - transportModes: [{ mode: CAR, qualifier: HAIL }] - ) { - itineraries { - start - end - # next two are deprecated - startTime - endTime - generalizedCost - accessibilityScore - emissionsPerPerson { - co2 - } - numberOfTransfers - walkDistance - walkTime - legs { - mode - start { - scheduledTime - estimated { - time - delay - } - } - end { - scheduledTime - estimated { - time - delay - } - } - from { - name - lat - lon - arrival { - scheduledTime - estimated { - delay - time - } - } - departure { - scheduledTime - estimated { - delay - time - } - } - departureTime - arrivalTime - } - to { - name - lat - lon - arrival { - scheduledTime - estimated { - delay - time - } - } - departure { - scheduledTime - estimated { - delay - time - } - } - departureTime - arrivalTime - } - startTime - endTime - mode - generalizedCost - headsign - trip { - tripHeadsign - } - intermediatePlaces { - arrival { - scheduledTime - estimated { - time - delay - } - } - departure { - scheduledTime - estimated { - time - delay - } - } - stop { - name - } - } - alerts { - id - alertHeaderText - alertDescriptionText - alertEffect - alertCause - alertSeverityLevel - alertUrl - effectiveStartDate - effectiveEndDate - entities { - ... on Stop { - name - gtfsId - lat - lon - } - } - } - rideHailingEstimate { - provider { - id - } - productName - minPrice { - currency { - code - digits - } - amount - } - maxPrice { - currency { - code - digits - } - amount - } - arrival - } - accessibilityScore - } - } - } -} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-fares.graphql b/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-fares.graphql deleted file mode 100644 index c5081b1c8ed..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-fares.graphql +++ /dev/null @@ -1,71 +0,0 @@ -{ - plan( - from: { lat: 52.3092, lon: 13.0291 } - to: { lat: 52.5147, lon: 13.3927 } - date: "2023-02-15" - time: "11:37" - transportModes: [{ mode: TRANSIT }] - ) { - itineraries { - legs { - mode - from { - name - lat - lon - departureTime - arrivalTime - } - to { - name - lat - lon - departureTime - arrivalTime - } - startTime - endTime - mode - generalizedCost - fareProducts { - id - product { - id - name - __typename - ... on DefaultFareProduct { - price { - currency { - digits - code - } - amount - } - } - riderCategory { - id - name - } - medium { - id - name - } - } - } - } - fares { - type - cents - currency - components { - currency - cents - fareId - routes { - gtfsId - } - } - } - } - } -} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-stop-positions.graphql b/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-stop-positions.graphql deleted file mode 100644 index dd2217e4288..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-stop-positions.graphql +++ /dev/null @@ -1,43 +0,0 @@ -{ - plan(fromPlace: "from", toPlace: "to", date: "2023-02-15", time: "11:37") { - itineraries { - startTime - endTime - generalizedCost - accessibilityScore - legs { - mode - from { - name - lat - lon - departureTime - arrivalTime - stopPosition { - __typename - ... on PositionAtStop { - position - } - } - } - to { - name - lat - lon - departureTime - arrivalTime - stopPosition { - __typename - ... on PositionAtStop { - position - } - } - } - startTime - endTime - mode - generalizedCost - } - } - } -} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-tutorial.graphql b/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-tutorial.graphql deleted file mode 100644 index dd461060029..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-tutorial.graphql +++ /dev/null @@ -1,53 +0,0 @@ -{ - plan( - # these coordinates are in Portland, change this to YOUR origin - from: { lat: 45.5552, lon: -122.6534 } - # these coordinates are in Portland, change this to YOUR destination - to: { lat: 45.4908, lon: -122.5519 } - # use the correct date and time of your request - date: "2023-02-15" - time: "11:37" - # choose the transport modes you need - transportModes: [{ mode: WALK }, { mode: TRANSIT }] - ) { - itineraries { - start - end - legs { - mode - from { - name - lat - lon - departure { - scheduledTime - estimated { - time - delay - } - } - } - to { - name - lat - lon - arrival { - scheduledTime - estimated { - time - delay - } - } - } - route { - gtfsId - longName - shortName - } - legGeometry { - points - } - } - } - } -} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/planConnection.graphql b/src/test/resources/org/opentripplanner/apis/gtfs/queries/planConnection.graphql deleted file mode 100644 index 5691f130119..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/queries/planConnection.graphql +++ /dev/null @@ -1,103 +0,0 @@ -{ - planConnection( - dateTime: { earliestDeparture: "2023-06-13T14:30+03:00" } - searchWindow: "PT2H30M" - first: 5 - origin: { - location: { coordinate: { latitude: 45.5552, longitude: -122.6534 } } - label: "Home" - } - destination: { - location: { coordinate: { latitude: 45.4908, longitude: -122.5519 } } - label: "Work" - } - modes: { - directOnly: false - transitOnly: false - direct: [WALK] - transit: { - access: [BICYCLE_RENTAL, WALK] - transfer: [WALK] - egress: [BICYCLE_RENTAL, WALK] - transit: [{ mode: TRAM, cost: { reluctance: 1.3 } }, { mode: BUS }] - } - } - preferences: { - accessibility: { wheelchair: { enabled: true } } - street: { - car: { - reluctance: 6.5 - rental: { - allowedNetworks: ["foo", "bar"] - bannedNetworks: ["foobar"] - } - parking: { - unpreferredCost: 200 - preferred: [{ select: [{ tags: ["best-park"] }] }] - filters: [{ not: [{ tags: ["worst-park"] }] }] - } - } - bicycle: { - reluctance: 3.0 - speed: 7.4 - optimization: { type: SAFEST_STREETS } - boardCost: 200 - walk: { - speed: 1.3 - cost: { mountDismountCost: 100, reluctance: 3.5 } - mountDismountTime: "PT5S" - } - rental: { - destinationBicyclePolicy: { allowKeeping: true, keepingCost: 300 } - allowedNetworks: ["foo", "bar"] - bannedNetworks: ["foobar"] - } - parking: { - unpreferredCost: 200 - preferred: [{ select: [{ tags: ["best-park"] }] }] - filters: [{ not: [{ tags: ["worst-park"] }] }] - } - } - walk: { speed: 2.4, reluctance: 1.5, safetyFactor: 0.5, boardCost: 200 } - } - transit: { - board: { waitReluctance: 3.2, slack: "PT1M30S" } - alight: { slack: "PT0S" } - transfer: { - cost: 200 - slack: "PT2M" - maximumAdditionalTransfers: 2 - maximumTransfers: 5 - } - timetable: { - excludeRealTimeUpdates: false - includePlannedCancellations: false - includeRealTimeCancellations: true - } - } - } - locale: "en" - ) { - searchDateTime - routingErrors { - code - } - pageInfo { - hasNextPage - hasPreviousPage - startCursor - endCursor - searchWindowUsed - } - edges { - cursor - node { - start - end - legs { - mode - } - } - } - } -} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql b/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql deleted file mode 100644 index 5f3df71f8e7..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql +++ /dev/null @@ -1,9 +0,0 @@ -{ - stops { - gtfsId - lat - lon - name - vehicleMode - } -} diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql b/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql deleted file mode 100644 index c88958840d4..00000000000 --- a/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql +++ /dev/null @@ -1,20 +0,0 @@ -{ - plan( - fromPlace: "from" - toPlace: "to" - date: "2023-02-15" - time: "11:37" - transportModes: [{ mode: WALK }] - ) { - itineraries { - legs { - steps { - streetName - area - relativeDirection - absoluteDirection - } - } - } - } -} diff --git a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json deleted file mode 100644 index 5a2ed9572e2..00000000000 --- a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json +++ /dev/null @@ -1,307 +0,0 @@ -{ - "name" : "OTP Debug Tiles", - "sources" : { - "background" : { - "id" : "background", - "tiles" : [ - "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png" - ], - "maxzoom" : 19, - "tileSize" : 256, - "attribution" : "© OpenStreetMap Contributors", - "type" : "raster" - }, - "vectorSource" : { - "id" : "vectorSource", - "url" : "https://example.com", - "type" : "vector" - } - }, - "layers" : [ - { - "id" : "background", - "type" : "raster", - "source" : "background", - "minzoom" : 0 - }, - { - "id" : "edge", - "type" : "line", - "source" : "vectorSource", - "source-layer" : "edges", - "minzoom" : 6, - "maxzoom" : 23, - "paint" : { - "line-color" : "#f21d52", - "line-width" : { - "base" : 1.3, - "stops" : [ - [ - 13, - 0.5 - ], - [ - 23, - 10.0 - ] - ] - } - }, - "filter" : [ - "in", - "class", - "StreetEdge", - "AreaEdge", - "EscalatorEdge", - "PathwayEdge", - "ElevatorHopEdge", - "TemporaryPartialStreetEdge", - "TemporaryFreeEdge" - ], - "layout" : { - "line-cap" : "round", - "visibility" : "none" - } - }, - { - "id" : "edge-name", - "type" : "symbol", - "source" : "vectorSource", - "source-layer" : "edges", - "minzoom" : 17, - "maxzoom" : 23, - "paint" : { - "text-color" : "#000", - "text-halo-color" : "#fff", - "text-halo-blur" : 4, - "text-halo-width" : 3 - }, - "filter" : [ - "in", - "class", - "StreetEdge", - "AreaEdge", - "EscalatorEdge", - "PathwayEdge", - "ElevatorHopEdge", - "TemporaryPartialStreetEdge", - "TemporaryFreeEdge" - ], - "layout" : { - "symbol-placement" : "line", - "symbol-spacing" : 500, - "text-field" : "{name}", - "text-font" : [ - "KlokanTech Noto Sans Regular" - ], - "text-size" : { - "base" : 14.0, - "stops" : [ - [ - 14, - 12.0 - ], - [ - 20, - 14.0 - ] - ] - }, - "text-max-width" : 5, - "text-keep-upright" : true, - "text-rotation-alignment" : "map", - "visibility" : "none" - } - }, - { - "id" : "link", - "type" : "line", - "source" : "vectorSource", - "source-layer" : "edges", - "minzoom" : 13, - "maxzoom" : 23, - "paint" : { - "line-color" : "#22DD9E", - "line-width" : { - "base" : 1.3, - "stops" : [ - [ - 13, - 0.5 - ], - [ - 23, - 10.0 - ] - ] - } - }, - "filter" : [ - "in", - "class", - "StreetTransitStopLink", - "StreetTransitEntranceLink", - "BoardingLocationToStopLink", - "StreetVehicleRentalLink", - "StreetVehicleParkingLink" - ], - "layout" : { - "line-cap" : "round", - "visibility" : "none" - } - }, - { - "id" : "vertex", - "type" : "circle", - "source" : "vectorSource", - "source-layer" : "vertices", - "minzoom" : 15, - "maxzoom" : 23, - "paint" : { - "circle-stroke-color" : "#140d0e", - "circle-stroke-width" : { - "base" : 1.0, - "stops" : [ - [ - 15, - 0.2 - ], - [ - 23, - 3.0 - ] - ] - }, - "circle-radius" : { - "base" : 1.0, - "stops" : [ - [ - 15, - 1.0 - ], - [ - 23, - 7.0 - ] - ] - }, - "circle-color" : "#BC55F2" - }, - "layout" : { - "visibility" : "none" - } - }, - { - "id" : "parking-vertex", - "type" : "circle", - "source" : "vectorSource", - "source-layer" : "vertices", - "minzoom" : 13, - "maxzoom" : 23, - "paint" : { - "circle-stroke-color" : "#140d0e", - "circle-stroke-width" : { - "base" : 1.0, - "stops" : [ - [ - 15, - 0.2 - ], - [ - 23, - 3.0 - ] - ] - }, - "circle-radius" : { - "base" : 1.0, - "stops" : [ - [ - 13, - 1.4 - ], - [ - 23, - 10.0 - ] - ] - }, - "circle-color" : "#136b04" - }, - "filter" : [ - "in", - "class", - "VehicleParkingEntranceVertex" - ], - "layout" : { - "visibility" : "none" - } - }, - { - "id" : "area-stop", - "type" : "fill", - "source" : "vectorSource", - "source-layer" : "stops", - "minzoom" : 6, - "maxzoom" : 23, - "paint" : { - "fill-color" : "#22DD9E", - "fill-opacity" : 0.5, - "fill-outline-color" : "#140d0e" - } - }, - { - "id" : "group-stop", - "type" : "fill", - "source" : "vectorSource", - "source-layer" : "stops", - "minzoom" : 6, - "maxzoom" : 23, - "paint" : { - "fill-color" : "#22DD9E", - "fill-opacity" : 0.5, - "fill-outline-color" : "#140d0e" - } - }, - { - "id" : "regular-stop", - "type" : "circle", - "source" : "vectorSource", - "source-layer" : "stops", - "minzoom" : 10, - "maxzoom" : 23, - "paint" : { - "circle-stroke-color" : "#140d0e", - "circle-stroke-width" : { - "base" : 1.0, - "stops" : [ - [ - 11, - 0.5 - ], - [ - 23, - 5.0 - ] - ] - }, - "circle-radius" : { - "base" : 1.0, - "stops" : [ - [ - 11, - 0.5 - ], - [ - 23, - 10.0 - ] - ] - }, - "circle-color" : "#fcf9fa" - } - } - ], - "version" : 8, - "glyphs" : "https://cdn.jsdelivr.net/gh/klokantech/klokantech-gl-fonts@master/{fontstack}/{range}.pbf" -} \ No newline at end of file diff --git a/src/test/resources/portland/router-config.json b/src/test/resources/portland/router-config.json deleted file mode 100644 index 7a73a41bfdf..00000000000 --- a/src/test/resources/portland/router-config.json +++ /dev/null @@ -1,2 +0,0 @@ -{ -} \ No newline at end of file diff --git a/src/test/resources/speedtest/travelSearch-expected-results-bd.csv b/src/test/resources/speedtest/travelSearch-expected-results-bd.csv deleted file mode 100644 index 117eecc4a12..00000000000 --- a/src/test/resources/speedtest/travelSearch-expected-results-bd.csv +++ /dev/null @@ -1,3 +0,0 @@ -tcId,nTransfers,duration,cost,walkDistance,startTime,endTime,agencies,modes,routes,stops,details -1,0,43m25s,-1,0,12:00:00,12:43:25,,,,,Unknown transit 0tx 43m25s -2,0,43m25s,-1,0,12:00:00,12:43:25,,,,,Unknown transit 0tx 43m25s diff --git a/src/test/resources/speedtest/travelSearch-expected-results-btr.csv b/src/test/resources/speedtest/travelSearch-expected-results-btr.csv deleted file mode 100644 index 634b7b15b1e..00000000000 --- a/src/test/resources/speedtest/travelSearch-expected-results-btr.csv +++ /dev/null @@ -1,5 +0,0 @@ -tcId,nTransfers,duration,cost,walkDistance,startTime,endTime,agencies,modes,routes,stops,details -1,0,1h11m14s,-1,0,12:48:46,14:00:00,,,,,Unknown transit 0tx 1h11m14s -1,1,1h9m14s,-1,0,12:50:46,14:00:00,,,,,Unknown transit 1tx 1h9m14s -2,0,1h11m14s,-1,0,12:48:46,14:00:00,,,,,Unknown transit 0tx 1h11m14s -2,1,1h9m14s,-1,0,12:50:46,14:00:00,,,,,Unknown transit 1tx 1h9m14s diff --git a/src/test/resources/standalone/config/build-config.json b/src/test/resources/standalone/config/build-config.json deleted file mode 100644 index 63df4608944..00000000000 --- a/src/test/resources/standalone/config/build-config.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "transitServiceStart": "-P3M", - "transitServiceEnd": "P1Y", - "osmCacheDataInMem" : true, - "localFileNamePatterns" : { - "osm" : "(i?)\\.osm\\.pbf$", - "dem" : "(i?)\\.dem\\.tiff?$", - "gtfs" : "(?i)gtfs", - "netex" : "(?i)netex" - }, - - "osmDefaults": { - "timeZone": "Europe/Rome", - "osmTagMapping": "default" - }, - "osm": [{ - "source" : "gs://my-bucket/otp-work-dir/norway.osm.pbf", - "timeZone" : "Europe/Oslo", - "osmTagMapping" : "norway" - }], - "demDefaults": { - "elevationUnitMultiplier" : 1.0 - }, - "dem": [{ - "source" : "gs://my-bucket/otp-work-dir/norway.dem.tiff", - "elevationUnitMultiplier" : 2.5 - }], - "netexDefaults" : { - "feedId" : "EN", - "sharedFilePattern" : "_stops.xml", - "sharedGroupFilePattern" : "_(\\w{3})_shared_data.xml", - "groupFilePattern" : "(\\w{3})_.*\\.xml", - "ignoreFilePattern" : "(temp|tmp)", - "ferryIdsNotAllowedForBicycle" : ["RUT:B107", "RUT:B209"] - }, - "gtfsDefaults" : { - "stationTransferPreference" : "recommended", - "removeRepeatedStops" : true, - "discardMinTransferTimes": false, - "blockBasedInterlining": true, - "maxInterlineDistance": 200 - }, - "islandPruning" : { - "islandWithStopsMaxSize": 2, - "islandWithoutStopsMaxSize": 10, - "adaptivePruningFactor": 50.0, - "adaptivePruningDistance": 250 - }, - "transitFeeds" : [ - { - "type" : "gtfs", - "feedId" : "SE", - "source" : "https://skanetrafiken.se/download/sweden.gtfs.zip" - }, - { - "type" : "netex", - "feedId" : "NO", - "source" : "gs://BUCKET/OTP_GCS_WORK_DIR/norway-netex.obj", - "sharedFilePattern" : "_stops.xml", - "sharedGroupFilePattern" : "_(\\w{3})_shared_data.xml", - "groupFilePattern" : "(\\w{3})_.*\\.xml", - "ignoreFilePattern" : "(temp|tmp)" - //"ferryIdsNotAllowedForBicycle" : ["RUT:B107", "RUT:B209"] - } - ], - "transferRequests": [ - { - "modes": "WALK" - }, - { - "modes": "WALK", - "wheelchairAccessibility": { - "enabled": true - } - } - ], - "stopConsolidationFile": "consolidated-stops.csv", - "emissions": { - "carAvgCo2PerKm": 170, - "carAvgOccupancy": 1.3 - } -} diff --git a/test/performance/washington-state/build-config.json b/test/performance/washington-state/build-config.json index 76cd2da6247..a8d0d5a43bb 100644 --- a/test/performance/washington-state/build-config.json +++ b/test/performance/washington-state/build-config.json @@ -1,127 +1,67 @@ { - "transitServiceStart": "2022-01-01", - "transitServiceEnd": "2022-12-31", + "transitServiceStart": "2024-09-01", + "transitServiceEnd": "2024-12-31", "transitModelTimeZone": "America/Los_Angeles", "transitFeeds": [ { "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Community_Transit-20221020T085912Z.gtfs.zip", + "source": "https://otp-performance.leonard.io/data/washington-state-new/catholiccommunity-wa-us-king--flex-v2.zip", + "feedId": "ccsww-kc" + }, + { + "type": "gtfs", + "source": "https://otp-performance.leonard.io/data/washington-state-new/community-transit.gtfs.zip", "feedId": "commtrans" }, { "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Everett_Transit-20221022T085914Z.gtfs.zip", - "feedId": "everett" + "source": "https://otp-performance.leonard.io/data/washington-state-new/communitytransit-wa-us--flex-v2.zip", + "feedId": "commtrans-flex" }, { "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Homage_Senior_Services-20221013T085917Z.gtfs.zip", + "source": "https://otp-performance.leonard.io/data/washington-state-new/homage-wa-us-darrington--flex-v2.zip", "feedId": "homage" }, { "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Island_Transit-20221013T085915Z.gtfs.zip", - "feedId": "island-transit" + "source": "https://otp-performance.leonard.io/data/washington-state-new/hopelink-wa-us--flex-v2.zip", + "feedId": "hopelink" }, { "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/King_County_Metro-20221022T085912Z.gtfs.zip", + "source": "https://otp-performance.leonard.io/data/washington-state-new/kcm.gtfs.zip", "feedId": "kcm" }, { "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Kitsap_Transit-20221021T090015Z.gtfs.zip", + "source": "https://otp-performance.leonard.io/data/washington-state-new/kitsap.gtfs.zip", "feedId": "kitsap" }, { "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Muckleshoot_Indian_Tribe-20221012T214902Z.gtfs.zip", - "feedId": "muckleshoot" - }, - { - "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Pierce_County_Ferries-20221012T215215Z.gtfs.zip", - "feedId": "pierce-ferries" - }, - { - "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Pierce_County_Human_Services-20221021T085916Z.gtfs.zip", - "feedId": "pierce-human-services" - }, - { - "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Pierce_County_Human_Services_Flex-20221012T215555Z.gtfs.zip", - "feedId": "pierce-flex" - }, - { - "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Pierce_Transit-20221022T085914Z.gtfs.zip", - "feedId": "pierce-transit" - }, - { - "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Puget_Sound_Educational_Service_District-20221012T215720Z.gtfs.zip", - "feedId": "pudget-sound-educational" - }, - { - "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Seattle_Childrens_Hospital-20221019T085918Z.gtfs.zip", - "feedId": "childrens-hospital" - }, - { - "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Seattle_Monorail-20221019T085918Z.gtfs.zip", + "source": "https://otp-performance.leonard.io/data/washington-state-new/monorail.gtfs.zip", "feedId": "monorail" }, { "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Skagit_Transit-20221012T212605Z.gtfs.zip", - "feedId": "skagit" - }, - { - "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Snoqualmie_Valley_Transportation-20221012T221032Z.gtfs.zip", - "feedId": "snoqualmie" - }, - { - "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Snoqualmie_Valley_Transportation_Flex-20221012T221125Z.gtfs.zip", - "feedId": "snoqualmie-flex" - }, - { - "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Solid_Ground-20221012T221409Z.gtfs.zip", - "feedId": "solid-ground" - }, - { - "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Sound_Generations-20221012T221622Z.gtfs.zip", - "feedId": "sound-generations" - }, - { - "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Sound_Transit-20221022T085914Z.gtfs.zip", - "feedId": "sound-transit" - }, - { - "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/WA_State_Ferry-20221024T085913Z.gtfs.zip", - "feedId": "state-ferry" + "source": "https://otp-performance.leonard.io/data/washington-state-new/pierce-transit.gtfs.zip", + "feedId": "pierce" }, { "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/WSDOT_Public_Transportation-20221012T213935Z.gtfs.zip", - "feedId": "wsdot" + "source": "https://otp-performance.leonard.io/data/washington-state-new/soundgenerations-wa-us-hyde--flex-v2.zip", + "feedId": "hyde" }, { "type": "gtfs", - "source": "https://otp-performance.leonard.io/data/washington-state/Whatcom_Transportation_Authority-20221012T213144Z.gtfs.zip", - "feedId": "whatcom" + "source": "https://otp-performance.leonard.io/data/washington-state-new/soundgenerations-wa-us-volunteer--flex-v2.zip", + "feedId": "volunteer" } ], "osm": [ { - "source": "https://otp-performance.leonard.io/data/washington-state/nw-washington-state-2022-12-01.osm.pbf" + "source": "https://otp-performance.leonard.io/data/washington-state-new/north-east-washington-2024-17-10.osm.pbf" } ] } \ No newline at end of file diff --git a/test/performance/washington-state/generate_test_cases.py b/test/performance/washington-state/generate_test_cases.py index 49c09db6e65..c3ac9d2c672 100755 --- a/test/performance/washington-state/generate_test_cases.py +++ b/test/performance/washington-state/generate_test_cases.py @@ -17,14 +17,6 @@ "coordinates": "47.3978844,-122.30898", "name": "Des Moines" }, - { - "coordinates": "47.340218616,-122.2246170043", - "name": "North Auburn" - }, - { - "coordinates": "47.31322426310727,-122.336540222167", - "name": "Federal Way" - }, { "coordinates": "47.571024,-122.3877811", "name": "West Seattle" @@ -47,19 +39,19 @@ }, ] -failing_cases = [16, 64, 70, 82, 88, 120, 128, 130, 132, 134, 136, 138, 146, 152, 154, 158, 164, 172] +failing_cases = [] rows = [] modes = [ { - "mode": "TRANSIT|WALK", - "category": "transit", + "mode": "FLEX_DIRECT|WALK", + "category": "flex-direct", "window": "" }, { "mode": "FLEX_ACCESS|FLEX_EGRESS|TRANSIT", - "category": "flex", + "category": "flex-and-transit", "window": "6h" } ] diff --git a/test/performance/washington-state/speed-test-config.json b/test/performance/washington-state/speed-test-config.json index 1b48a48e370..ad40304cc66 100644 --- a/test/performance/washington-state/speed-test-config.json +++ b/test/performance/washington-state/speed-test-config.json @@ -1,6 +1,6 @@ { // Run all test-cases on the given date - "testDate": "2022-11-01", + "testDate": "2024-10-17", "feedId": "1", // Default: "graph.obj" "graph": "graph.obj", diff --git a/test/performance/washington-state/travelSearch-expected-results.csv b/test/performance/washington-state/travelSearch-expected-results.csv index c84d7613624..07291b54946 100644 --- a/test/performance/washington-state/travelSearch-expected-results.csv +++ b/test/performance/washington-state/travelSearch-expected-results.csv @@ -1,452 +1,267 @@ tcId,nTransfers,duration,cost,walkDistance,startTime,endTime,agencies,modes,routes,stops,details -1,1,01:29:01,8356,2443,10:26:48,11:55:49,Metro Transit,BUS,160|165,kcm:57375|kcm:57430|kcm:57429|kcm:47570,Walk 18m28s ~ 108th Ave SE & SE 220th Pl(57375) ~ BUS 160 10:45:16 10:49:28 ~ 104th Ave SE & SE 240th St(57430) ~ Walk 1m27s ~ SE 240th St & 104th Ave SE(57429) ~ BUS 165 10:59 11:44 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m49s -1,0,01:32:34,8788,3546,10:23:15,11:55:49,Metro Transit,BUS,165,kcm:57448|kcm:47570,Walk 33m35s ~ SE 240th St & 116th Ave SE(57448) ~ BUS 165 10:56:50 11:44 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m49s -1,1,01:31:01,8476,2443,10:57:48,12:28:49,Metro Transit,BUS,160|165,kcm:57375|kcm:57430|kcm:57429|kcm:47570,Walk 18m28s ~ 108th Ave SE & SE 220th Pl(57375) ~ BUS 160 11:16:16 11:20:28 ~ 104th Ave SE & SE 240th St(57430) ~ Walk 1m27s ~ SE 240th St & 104th Ave SE(57429) ~ BUS 165 11:29 12:17 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m49s -2,2,00:47:37,4659,0,10:01:27,10:49:04,Metro Transit|Sound Generations,BUS,Hyde Shuttle|165|Hyde Shuttle,sound-generations:area_558|kcm:61180|kcm:47570|sound-generations:area_551,sound-generations:area_558(area_558) ~ BUS null 10:01:27 10:25:37Walk 0s ~ Pacific Hwy S & S 240th St(61180) ~ BUS 165 10:27:37 10:44 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:46 10:49:04 -2,2,00:52:47,5067,137,10:02:55,10:55:42,Metro Transit|Sound Generations,BUS,Hyde Shuttle|A Line|Hyde Shuttle,sound-generations:area_558|kcm:60800|kcm:60810|sound-generations:area_551,sound-generations:area_558(area_558) ~ BUS null 10:02:55 10:25:12Walk 1m48s ~ Pacific Hwy S & Kent Des Moines Rd(60800) ~ BUS A Line 10:29 10:30:38 ~ Pacific Hwy S & S 224th St(60810) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:32:38 10:55:42 -2,1,00:54:22,5143,917,10:01:27,10:55:49,Metro Transit|Sound Generations,BUS,Hyde Shuttle|165,sound-generations:area_558|kcm:61180|kcm:47570,sound-generations:area_558(area_558) ~ BUS null 10:01:27 10:25:37Walk 0s ~ Pacific Hwy S & S 240th St(61180) ~ BUS 165 10:27:37 10:44 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m49s -3,0,02:46:50,19487,12867,10:00:00,12:46:50,,,,,Walk 2h46m50s -3,1,01:20:03,8318,3143,10:26:48,11:46:51,Metro Transit,BUS,160|165,kcm:57375|kcm:57430|kcm:57429|kcm:50480,Walk 18m28s ~ 108th Ave SE & SE 220th Pl(57375) ~ BUS 160 10:45:16 10:49:28 ~ 104th Ave SE & SE 240th St(57430) ~ Walk 1m27s ~ SE 240th St & 104th Ave SE(57429) ~ BUS 165 10:59 11:25:38 ~ Pacific Hwy S & Kent Des Moines Rd(50480) ~ Walk 21m13s -3,0,01:23:36,8749,4246,10:23:15,11:46:51,Metro Transit,BUS,165,kcm:57448|kcm:50480,Walk 33m35s ~ SE 240th St & 116th Ave SE(57448) ~ BUS 165 10:56:50 11:25:38 ~ Pacific Hwy S & Kent Des Moines Rd(50480) ~ Walk 21m13s -4,2,00:35:06,3908,0,10:01:27,10:36:33,Metro Transit|Sound Generations,BUS,Hyde Shuttle|165|Hyde Shuttle,sound-generations:area_558|kcm:61180|kcm:47270|sound-generations:area_551,sound-generations:area_558(area_558) ~ BUS null 10:01:27 10:25:37Walk 0s ~ Pacific Hwy S & S 240th St(61180) ~ BUS 165 10:27:37 10:30:13 ~ S 240th St & 21st Ave S(47270) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:32:13 10:36:33 -4,2,00:36:03,4063,137,10:02:55,10:38:58,Metro Transit|Sound Generations,BUS,Hyde Shuttle|A Line|Hyde Shuttle,sound-generations:area_558|kcm:60800|kcm:60810|sound-generations:area_551,sound-generations:area_558(area_558) ~ BUS null 10:02:55 10:25:12Walk 1m48s ~ Pacific Hwy S & Kent Des Moines Rd(60800) ~ BUS A Line 10:29 10:30:38 ~ Pacific Hwy S & S 224th St(60810) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:32:38 10:38:58 -4,2,00:34:10,3998,202,10:10:18,10:44:28,Metro Transit|Sound Generations,BUS,Hyde Shuttle|156|Hyde Shuttle,sound-generations:area_558|kcm:48980|kcm:48990|sound-generations:area_551,sound-generations:area_558(area_558) ~ BUS null 10:10:18 10:33:40Walk 2m40s ~ 24th Ave S & S 230th St(48980) ~ BUS 156 10:38:20 10:39:02 ~ 24th Ave S & S 226th St(48990) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:41:02 10:44:28 -5,0,00:48:36,4732,1635,10:12:48,11:01:24,Metro Transit,BUS,160,kcm:57375|kcm:58255,Walk 18m28s ~ 108th Ave SE & SE 220th Pl(57375) ~ BUS 160 10:31:16 10:58:37 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -5,0,00:49:19,4775,1635,10:26:48,11:16:07,Metro Transit,BUS,160,kcm:57375|kcm:58255,Walk 18m28s ~ 108th Ave SE & SE 220th Pl(57375) ~ BUS 160 10:45:16 11:13:20 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -6,1,00:31:41,3260,212,10:00:01,10:31:42,Metro Transit|Sound Generations,BUS,Hyde Shuttle|160,sound-generations:area_558|kcm:58148|kcm:58255,sound-generations:area_558(area_558) ~ BUS null 10:00:01 10:18Walk 0s ~ Central Ave S & E Meeker St(58148) ~ BUS 160 10:20 10:28:55 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -6,1,00:31:41,3260,212,10:15:01,10:46:42,Metro Transit|Sound Generations,BUS,Hyde Shuttle|160,sound-generations:area_558|kcm:58148|kcm:58255,sound-generations:area_558(area_558) ~ BUS null 10:15:01 10:33Walk 0s ~ Central Ave S & E Meeker St(58148) ~ BUS 160 10:35 10:43:55 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -6,1,00:32:14,3293,212,10:29:10,11:01:24,Metro Transit|Sound Generations,BUS,Hyde Shuttle|160,sound-generations:area_558|kcm:58180|kcm:58255,sound-generations:area_558(area_558) ~ BUS null 10:29:10 10:49:40Walk 0s ~ Central Ave S & S 259th St(58180) ~ BUS 160 10:51:40 10:58:37 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -7,2,01:58:18,11174,3077,10:12:48,12:11:06,Metro Transit,BUS,160|183|903,kcm:57375|kcm:62213|kcm:57459|kcm:80431|kcm:80439|kcm:60605,Walk 18m28s ~ 108th Ave SE & SE 220th Pl(57375) ~ BUS 160 10:31:16 10:46:43 ~ E Smith St & State Ave N(62213) ~ Walk 2m50s ~ Kent Sounder Station - Bay 9(57459) ~ BUS 183 11:00 11:37 ~ Federal Way TC - Bay 1(80431) ~ Walk 33s ~ Federal Way TC - Bay 9(80439) ~ BUS 903 11:45 11:52:43 ~ 1st Way S & S 333rd St(60605) ~ Walk 18m23s -7,1,02:02:04,11857,4532,10:12:48,12:14:52,Metro Transit,BUS,160|183,kcm:57375|kcm:62213|kcm:57459|kcm:80431,Walk 18m28s ~ 108th Ave SE & SE 220th Pl(57375) ~ BUS 160 10:31:16 10:46:43 ~ E Smith St & State Ave N(62213) ~ Walk 2m50s ~ Kent Sounder Station - Bay 9(57459) ~ BUS 183 11:00 11:37 ~ Federal Way TC - Bay 1(80431) ~ Walk 37m52s -7,1,01:49:15,9066,1761,10:26:48,12:16:03,Metro Transit,BUS,160|181,kcm:57375|kcm:57784|kcm:57775|kcm:83784,Walk 18m28s ~ 108th Ave SE & SE 220th Pl(57375) ~ BUS 160 10:45:16 11:26 ~ 2nd St SW & A St SW(57784) ~ Walk 1m12s ~ Auburn Transit Center - Bay 3(57775) ~ BUS 181 11:44 12:12:47 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -8,2,00:48:03,4857,230,10:05:03,10:53:06,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|A Line|Road to Independence,sound-generations:area_558|kcm:61220|kcm:61280|pudget-sound-educational:area_622,sound-generations:area_558(area_558) ~ BUS null 10:05:03 10:30:17Walk 0s ~ Pacific Hwy S & S 260th St(61220) ~ BUS A Line 10:32:17 10:39:16 ~ Pacific Hwy S & S Dash Point Rd(61280) ~ Walk 8s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:41:24 10:50:20Walk 2m46s -8,2,00:48:07,4855,220,10:05:03,10:53:10,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|A Line|Road to Independence,sound-generations:area_558|kcm:61220|kcm:61300|pudget-sound-educational:area_622,sound-generations:area_558(area_558) ~ BUS null 10:05:03 10:30:17Walk 0s ~ Pacific Hwy S & S 260th St(61220) ~ BUS A Line 10:32:17 10:41:16 ~ Pacific Hwy S & S 308th St(61300) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:43:16 10:50:24Walk 2m46s -8,2,00:48:03,4857,230,10:15:03,11:03:06,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|A Line|Road to Independence,sound-generations:area_558|kcm:61220|kcm:61280|pudget-sound-educational:area_622,sound-generations:area_558(area_558) ~ BUS null 10:15:03 10:40:17Walk 0s ~ Pacific Hwy S & S 260th St(61220) ~ BUS A Line 10:42:17 10:49:16 ~ Pacific Hwy S & S Dash Point Rd(61280) ~ Walk 8s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:51:24 11:00:20Walk 2m46s -9,2,01:58:54,10301,1850,10:03:06,12:02:00,Metro Transit,BUS,160|101|50,kcm:57185|kcm:46440|kcm:79520|kcm:99252|kcm:31871,Walk 18m31s ~ 108th Ave SE & SE 220th Pl(57185) ~ BUS 160 10:21:37 10:49:04 ~ S 3rd St & Rainier Ave S(46440) ~ Walk 2m29s ~ SW Sunset Blvd & Rainier Ave S(79520) ~ BUS 101 10:59 11:16 ~ SODO Busway & S Spokane St(99252) ~ BUS 50 11:32:28 11:58:35 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -9,3,01:59:27,11425,2468,10:12:48,12:12:15,Metro Transit|Sound Transit,BUS|RAIL,160|S Line|C Line|128,kcm:57375|kcm:57451|sound-transit:S_KE_NB|sound-transit:S_KS|kcm:1562|kcm:20041|kcm:32011|kcm:31871,Walk 18m28s ~ 108th Ave SE & SE 220th Pl(57375) ~ BUS 160 10:31:16 10:48 ~ Kent Sounder Station - Bay 1(57451) ~ Walk 2m9s ~ Kent Station (Northbound)(S_KE_NB) ~ RAIL S Line 10:55 11:22 ~ King Street Station(S_KS) ~ Walk 9m13s ~ Alaskan Way S & S Jackson St(1562) ~ BUS C Line 11:38:40 11:58 ~ SW Alaska St & California Ave SW - Bay 3(20041) ~ Walk 42s ~ SW Alaska St & 44th Ave SW - Bay 4(32011) ~ BUS 128 12:05 12:08:50 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -9,2,02:01:05,11597,3386,10:12:48,12:13:53,Metro Transit|Sound Transit,BUS|RAIL,160|S Line|C Line,kcm:57375|kcm:57451|sound-transit:S_KE_NB|sound-transit:S_KS|kcm:1562|kcm:20041,Walk 18m28s ~ 108th Ave SE & SE 220th Pl(57375) ~ BUS 160 10:31:16 10:48 ~ Kent Sounder Station - Bay 1(57451) ~ Walk 2m9s ~ Kent Station (Northbound)(S_KE_NB) ~ RAIL S Line 10:55 11:22 ~ King Street Station(S_KS) ~ Walk 9m13s ~ Alaskan Way S & S Jackson St(1562) ~ BUS C Line 11:38:40 11:58 ~ SW Alaska St & California Ave SW - Bay 3(20041) ~ Walk 15m53s -10,3,01:16:01,7089,176,10:02:33,11:18:34,Metro Transit|Sound Generations,BUS,Hyde Shuttle|160|101|Hyde Shuttle,sound-generations:area_558|kcm:57200|kcm:46440|kcm:79520|kcm:99252|sound-generations:area_560,sound-generations:area_558(area_558) ~ BUS null 10:02:33 10:06:59Walk 0s ~ 108th Ave SE & SE 212th St(57200) ~ BUS 160 10:08:59 10:35:04 ~ S 3rd St & Rainier Ave S(46440) ~ Walk 2m29s ~ SW Sunset Blvd & Rainier Ave S(79520) ~ BUS 101 10:44 11:01 ~ SODO Busway & S Spokane St(99252) ~ Walk 0s ~ sound-generations:area_560(area_560) ~ BUS null 11:03 11:18:34 -10,2,01:09:25,5967,0,10:10:09,11:19:34,Metro Transit|Sound Generations,BUS,Hyde Shuttle|150|Hyde Shuttle,sound-generations:area_558|kcm:58087|kcm:99252|sound-generations:area_560,sound-generations:area_558(area_558) ~ BUS null 10:10:09 10:30:57Walk 0s ~ West Valley Hwy S & S 190th St(58087) ~ BUS 150 10:32:57 11:02 ~ SODO Busway & S Spokane St(99252) ~ Walk 0s ~ sound-generations:area_560(area_560) ~ BUS null 11:04 11:19:34 -10,3,01:16:55,7143,176,10:16:39,11:33:34,Metro Transit|Sound Generations,BUS,Hyde Shuttle|160|101|Hyde Shuttle,sound-generations:area_558|kcm:57200|kcm:46440|kcm:79520|kcm:99252|sound-generations:area_560,sound-generations:area_558(area_558) ~ BUS null 10:16:39 10:21:05Walk 0s ~ 108th Ave SE & SE 212th St(57200) ~ BUS 160 10:23:05 10:49:04 ~ S 3rd St & Rainier Ave S(46440) ~ Walk 2m29s ~ SW Sunset Blvd & Rainier Ave S(79520) ~ BUS 101 10:59 11:16 ~ SODO Busway & S Spokane St(99252) ~ Walk 0s ~ sound-generations:area_560(area_560) ~ BUS null 11:18 11:33:34 -11,1,01:52:12,10210,3103,10:12:48,12:05:00,Metro Transit|Sound Transit,BUS,160|578,kcm:57375|kcm:57784|pierce-transit:18728|pierce-transit:10401,Walk 18m28s ~ 108th Ave SE & SE 220th Pl(57375) ~ BUS 160 10:31:16 11:11 ~ 2nd St SW & A St SW(57784) ~ Walk 1m29s ~ Auburn Station - Bay 4(18728) ~ BUS 578 11:17 11:44 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m -11,1,01:56:12,10450,3103,10:41:48,12:38:00,Metro Transit|Sound Transit,BUS,160|578,kcm:57375|kcm:57784|pierce-transit:18728|pierce-transit:10401,Walk 18m28s ~ 108th Ave SE & SE 220th Pl(57375) ~ BUS 160 11:00:16 11:42 ~ 2nd St SW & A St SW(57784) ~ Walk 1m29s ~ Auburn Station - Bay 4(18728) ~ BUS 578 11:49 12:17 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m -12,2,00:53:59,5041,0,10:00:01,10:54:00,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|160|Road to Independence,sound-generations:area_558|kcm:58148|kcm:58230|pudget-sound-educational:area_622,sound-generations:area_558(area_558) ~ BUS null 10:00:01 10:18Walk 0s ~ Central Ave S & E Meeker St(58148) ~ BUS 160 10:20 10:26:26 ~ Auburn Way N & 85th Ave S(58230) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:28:26 10:54 -12,2,00:49:15,4775,25,10:11:57,11:01:12,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|160|Road to Independence,sound-generations:area_558|kcm:57375|kcm:57407|pudget-sound-educational:area_622,sound-generations:area_558(area_558) ~ BUS null 10:11:57 10:15:16Walk 0s ~ 108th Ave SE & SE 220th Pl(57375) ~ BUS 160 10:17:16 10:23:01 ~ 104th Ave SE & SE 248th St(57407) ~ Walk 21s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:25:22 11:01:12 -12,2,00:49:30,4772,0,10:11:57,11:01:27,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|160|Road to Independence,sound-generations:area_558|kcm:57375|kcm:57405|pudget-sound-educational:area_622,sound-generations:area_558(area_558) ~ BUS null 10:11:57 10:15:16Walk 0s ~ 108th Ave SE & SE 220th Pl(57375) ~ BUS 160 10:17:16 10:22:14 ~ 104th Ave SE & SE 244th St(57405) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:24:14 11:01:27 -13,3,03:10:03,15594,2462,11:02:37,14:12:40,Metro Transit|Sound Transit,BUS,160|101|554|208,kcm:57185|kcm:46440|kcm:79520|kcm:620|kcm:1480|kcm:64590|kcm:64593|kcm:64399,Walk 18m31s ~ 108th Ave SE & SE 220th Pl(57185) ~ BUS 160 11:21:08 11:49:04 ~ S 3rd St & Rainier Ave S(46440) ~ Walk 2m29s ~ SW Sunset Blvd & Rainier Ave S(79520) ~ BUS 101 11:59 12:24 ~ 4th Ave S & S Jackson St(620) ~ Walk 5m26s ~ S Jackson St & Maynard Ave S(1480) ~ BUS 554 12:46:10 13:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 13:30 14:06:59 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -14,4,03:47:39,17037,509,10:10:09,13:57:48,Metro Transit|Sound Generations|Sound Transit,BUS,Hyde Shuttle|150|545|224|629,sound-generations:area_558|kcm:58087|kcm:620|kcm:72488|kcm:68803|kcm:64397,sound-generations:area_558(area_558) ~ BUS null 10:10:09 10:30:57Walk 0s ~ West Valley Hwy S & S 190th St(58087) ~ BUS 150 10:32:57 11:11 ~ 4th Ave S & S Jackson St(620) ~ BUS 545 11:21 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -14,3,02:47:31,13055,858,11:25:09,14:12:40,Metro Transit|Sound Generations|Sound Transit,BUS,Hyde Shuttle|150|554|208,sound-generations:area_558|kcm:58087|kcm:620|kcm:1480|kcm:64590|kcm:64593|kcm:64399,sound-generations:area_558(area_558) ~ BUS null 11:25:09 11:45:57Walk 0s ~ West Valley Hwy S & S 190th St(58087) ~ BUS 150 11:47:57 12:27 ~ 4th Ave S & S Jackson St(620) ~ Walk 5m26s ~ S Jackson St & Maynard Ave S(1480) ~ BUS 554 12:46:10 13:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 13:30 14:06:59 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -15,2,01:55:50,10661,2593,10:12:48,12:08:38,Metro Transit|Sound Transit,BUS|RAIL,160|S Line|3,kcm:57375|kcm:57451|sound-transit:S_KE_NB|sound-transit:S_KS|kcm:1540|kcm:41350,Walk 18m28s ~ 108th Ave SE & SE 220th Pl(57375) ~ BUS 160 10:31:16 10:48 ~ Kent Sounder Station - Bay 1(57451) ~ Walk 2m9s ~ Kent Station (Northbound)(S_KE_NB) ~ RAIL S Line 10:55 11:22 ~ King Street Station(S_KS) ~ Walk 11m5s ~ James St & 5th Ave(1540) ~ BUS 3 11:36 12:05:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -15,2,02:08:32,11023,2052,10:15:06,12:23:38,Metro Transit,BUS,160|101|3,kcm:57185|kcm:46440|kcm:79520|kcm:691|kcm:575|kcm:41350,Walk 18m31s ~ 108th Ave SE & SE 220th Pl(57185) ~ BUS 160 10:33:37 11:01:04 ~ S 3rd St & Rainier Ave S(46440) ~ Walk 2m29s ~ SW Sunset Blvd & Rainier Ave S(79520) ~ BUS 101 11:14 11:45 ~ 4th Ave & Union St(691) ~ Walk 3m5s ~ 3rd Ave & Pike St(575) ~ BUS 3 11:58 12:20:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -15,2,02:04:30,11977,3653,10:32:37,12:37:07,Metro Transit,BUS,160|101|E Line,kcm:57185|kcm:46440|kcm:79520|kcm:691|kcm:575|kcm:6320,Walk 18m31s ~ 108th Ave SE & SE 220th Pl(57185) ~ BUS 160 10:51:08 11:19:04 ~ S 3rd St & Rainier Ave S(46440) ~ Walk 2m29s ~ SW Sunset Blvd & Rainier Ave S(79520) ~ BUS 101 11:29 11:59 ~ 4th Ave & Union St(691) ~ Walk 3m5s ~ 3rd Ave & Pike St(575) ~ BUS E Line 12:05 12:12:02 ~ Aurora Ave N & Lynn St(6320) ~ Walk 25m5s -17,2,01:28:33,8382,1712,10:03:06,11:31:39,Metro Transit|Sound Transit,BUS|TRAM,160|101|1-Line,kcm:57185|kcm:46440|kcm:79520|kcm:99254|sound-transit:99111|sound-transit:99121,Walk 18m31s ~ 108th Ave SE & SE 220th Pl(57185) ~ BUS 160 10:21:37 10:49:04 ~ S 3rd St & Rainier Ave S(46440) ~ Walk 2m29s ~ SW Sunset Blvd & Rainier Ave S(79520) ~ BUS 101 10:59 11:18:40 ~ SODO Busway & S Lander St(99254) ~ Walk 49s ~ SODO Station(99111) ~ TRAM 1-Line 11:28 11:31 ~ Beacon Hill Station(99121) ~ Walk 39s -17,2,01:26:33,8262,1712,10:15:06,11:41:39,Metro Transit|Sound Transit,BUS|TRAM,160|101|1-Line,kcm:57185|kcm:46440|kcm:79520|kcm:99254|sound-transit:99111|sound-transit:99121,Walk 18m31s ~ 108th Ave SE & SE 220th Pl(57185) ~ BUS 160 10:33:37 11:01:04 ~ S 3rd St & Rainier Ave S(46440) ~ Walk 2m29s ~ SW Sunset Blvd & Rainier Ave S(79520) ~ BUS 101 11:14 11:33:40 ~ SODO Busway & S Lander St(99254) ~ Walk 49s ~ SODO Station(99111) ~ TRAM 1-Line 11:38 11:41 ~ Beacon Hill Station(99121) ~ Walk 39s -17,1,01:40:47,9688,3338,10:03:06,11:43:53,Metro Transit,BUS,160|101,kcm:57185|kcm:46440|kcm:79520|kcm:99264,Walk 18m31s ~ 108th Ave SE & SE 220th Pl(57185) ~ BUS 160 10:21:37 10:49:04 ~ S 3rd St & Rainier Ave S(46440) ~ Walk 2m29s ~ SW Sunset Blvd & Rainier Ave S(79520) ~ BUS 101 10:59 11:20:45 ~ SODO Busway & S Holgate St(99264) ~ Walk 23m8s -18,2,01:01:30,5571,108,10:10:09,11:11:39,Metro Transit|Sound Generations|Sound Transit,BUS|TRAM,Hyde Shuttle|150|1-Line,sound-generations:area_558|kcm:58087|kcm:99254|sound-transit:99111|sound-transit:99121,sound-generations:area_558(area_558) ~ BUS null 10:10:09 10:30:57Walk 0s ~ West Valley Hwy S & S 190th St(58087) ~ BUS 150 10:32:57 11:04:40 ~ SODO Busway & S Lander St(99254) ~ Walk 49s ~ SODO Station(99111) ~ TRAM 1-Line 11:08 11:11 ~ Beacon Hill Station(99121) ~ Walk 39s -18,2,01:13:34,6592,523,10:12:55,11:26:29,Metro Transit|Sound Generations|Sound Transit,BUS|TRAM,Hyde Shuttle|A Line|1-Line,sound-generations:area_558|kcm:60800|kcm:60850|sound-transit:99914|sound-transit:99240,sound-generations:area_558(area_558) ~ BUS null 10:12:55 10:35:12Walk 1m48s ~ Pacific Hwy S & Kent Des Moines Rd(60800) ~ BUS A Line 10:39 10:45:46 ~ International Blvd & S 200th St(60850) ~ Walk 4m23s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:56 11:25 ~ Beacon Hill Station(99240) ~ Walk 1m29s -18,1,01:19:44,7238,1734,10:10:09,11:29:53,Metro Transit|Sound Generations,BUS,Hyde Shuttle|150,sound-generations:area_558|kcm:58087|kcm:99264,sound-generations:area_558(area_558) ~ BUS null 10:10:09 10:30:57Walk 0s ~ West Valley Hwy S & S 190th St(58087) ~ BUS 150 10:32:57 11:06:45 ~ SODO Busway & S Holgate St(99264) ~ Walk 23m8s -19,2,01:45:45,10022,2530,10:04:53,11:50:38,Metro Transit,BUS,165|F Line|160,kcm:47580|kcm:53720|kcm:53975|kcm:59860|kcm:59902|kcm:57375,Walk 12m10s ~ 1st Ave S & S 176th St(47580) ~ BUS 165 10:17:03 10:24:32 ~ 4th Ave SW & SW 156th St(53720) ~ Walk 9s ~ 4th Ave SW & SW 156th St(53975) ~ BUS F Line 10:26:42 11:02 ~ Rainier Ave S & S 7th St(59860) ~ Walk 2m14s ~ S 7th St & Rainier Ave S(59902) ~ BUS 160 11:09:47 11:32:16 ~ 108th Ave SE & SE 220th Pl(57375) ~ Walk 18m22s -19,1,01:29:18,8290,2335,10:25:15,11:54:33,Metro Transit,BUS,165|160,kcm:48620|kcm:57127|kcm:57130|kcm:57185,Walk 10m11s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 10:35:26 11:21 ~ SE 240th St & 104th Ave SE(57127) ~ Walk 1m45s ~ 104th Ave SE & SE 240th St(57130) ~ BUS 160 11:31:23 11:36:08 ~ 108th Ave SE & SE 220th Pl(57185) ~ Walk 18m25s -19,0,01:31:19,8631,3439,10:25:15,11:56:34,Metro Transit,BUS,165,kcm:48620|kcm:57141,Walk 10m11s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 10:35:26 11:22:44 ~ SE 240th St & 116th Ave SE(57141) ~ Walk 33m50s -20,2,00:43:59,4441,0,10:02:15,10:46:14,Metro Transit|Sound Generations,BUS,Hyde Shuttle|165|Hyde Shuttle,sound-generations:area_551|kcm:48620|kcm:48950|sound-generations:area_558,sound-generations:area_551(area_551) ~ BUS null 10:02:15 10:04:26Walk 0s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 10:06:26 10:21:30 ~ Pacific Hwy S & S 240th St(48950) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 10:23:30 10:46:14 -20,2,00:49:19,4890,179,10:05:35,10:54:54,Metro Transit|Sound Generations,BUS,Hyde Shuttle|156|Hyde Shuttle,sound-generations:area_551|kcm:50310|kcm:50461|sound-generations:area_558,sound-generations:area_551(area_551) ~ BUS null 10:05:35 10:14:48Walk 0s ~ 8th Ave S & S 198th St(50310) ~ BUS 156 10:16:48 10:27:31 ~ Kent Des Moines Rd & 24th Ave S(50461) ~ Walk 2m20s ~ sound-generations:area_558(area_558) ~ BUS null 10:31:51 10:54:54 -20,2,00:55:24,5177,71,10:11:43,11:07:07,Metro Transit|Sound Generations,BUS,Hyde Shuttle|161|Hyde Shuttle,sound-generations:area_551|kcm:50145|kcm:84352|sound-generations:area_558,sound-generations:area_551(area_551) ~ BUS null 10:11:43 10:21:51Walk 1m3s ~ S 156th Way & Des Moines Memorial Dr S(50145) ~ BUS 161 10:24:54 10:52:36 ~ 84th Ave S & S 212th St(84352) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 10:54:36 11:07:07 -21,0,01:36:56,11279,7450,10:00:00,11:36:56,,,,,Walk 1h36m56s -21,0,00:39:19,4773,2458,10:25:15,11:04:34,Metro Transit,BUS,165,kcm:48620|kcm:48810,Walk 10m11s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 10:35:26 10:43 ~ Marine View Dr S & S 223rd St(48810) ~ Walk 21m34s -22,2,00:19:11,2953,0,10:02:15,10:21:26,Metro Transit|Sound Generations,BUS,Hyde Shuttle|165|Hyde Shuttle,sound-generations:area_551|kcm:48620|kcm:48800|sound-generations:area_551,sound-generations:area_551(area_551) ~ BUS null 10:02:15 10:04:26Walk 0s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 10:06:26 10:13:32 ~ Marine View Dr S & S 220th St(48800) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:15:32 10:21:26 -22,2,00:25:34,3336,0,10:05:35,10:31:09,Metro Transit|Sound Generations,BUS,Hyde Shuttle|156|Hyde Shuttle,sound-generations:area_551|kcm:50310|kcm:50450|sound-generations:area_551,sound-generations:area_551(area_551) ~ BUS null 10:05:35 10:14:48Walk 0s ~ 8th Ave S & S 198th St(50310) ~ BUS 156 10:16:48 10:26:31 ~ 24th Ave S & S 226th St(50450) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:28:31 10:31:09 -22,1,00:29:41,3480,672,10:05:35,10:35:16,Metro Transit|Sound Generations,BUS,Hyde Shuttle|156,sound-generations:area_551|kcm:50310|kcm:50450,sound-generations:area_551(area_551) ~ BUS null 10:05:35 10:14:48Walk 0s ~ 8th Ave S & S 198th St(50310) ~ BUS 156 10:16:48 10:26:31 ~ 24th Ave S & S 226th St(50450) ~ Walk 8m45s -23,1,01:21:52,6870,1024,10:25:15,11:47:07,Metro Transit,BUS,165|160,kcm:48620|kcm:57452|kcm:57451|kcm:58255,Walk 10m11s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 10:35:26 11:15 ~ Kent Sounder Station - Bay 2(57452) ~ Walk 29s ~ Kent Sounder Station - Bay 1(57451) ~ BUS 160 11:33 11:44:20 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -23,1,01:07:52,6030,1024,10:55:15,12:03:07,Metro Transit,BUS,165|160,kcm:48620|kcm:57452|kcm:57451|kcm:58255,Walk 10m11s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 11:05:26 11:45 ~ Kent Sounder Station - Bay 2(57452) ~ Walk 29s ~ Kent Sounder Station - Bay 1(57451) ~ BUS 160 11:49 12:00:20 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -24,2,00:54:51,5093,0,10:02:15,10:57:06,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|165|Road to Independence,sound-generations:area_551|kcm:48620|kcm:50717|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:02:15 10:04:26Walk 0s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 10:06:26 10:37:05 ~ 64th Ave S & W James St(50717) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:39:05 10:57:06 -24,2,01:01:25,5530,62,10:04:40,11:06:05,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|A Line|Road to Independence,sound-generations:area_551|kcm:61230|kcm:61280|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:04:40 10:31:03Walk 50s ~ Pacific Hwy S & S 268th St(61230) ~ BUS A Line 10:33:53 10:39:16 ~ Pacific Hwy S & S Dash Point Rd(61280) ~ Walk 8s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:41:24 11:06:05 -24,2,01:00:33,5555,168,10:05:32,11:06:05,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|A Line|Road to Independence,sound-generations:area_551|kcm:61240|kcm:61280|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:05:32 10:30:27Walk 2m12s ~ Pacific Hwy S & S 272nd St(61240) ~ BUS A Line 10:34:39 10:39:16 ~ Pacific Hwy S & S Dash Point Rd(61280) ~ Walk 8s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:41:24 11:06:05 -25,2,01:16:39,7336,1267,10:25:15,11:41:54,Metro Transit,BUS,165|A Line|187,kcm:48620|kcm:48950|kcm:61180|kcm:80431|kcm:80433|kcm:83784,Walk 10m11s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 10:35:26 10:50:30 ~ Pacific Hwy S & S 240th St(48950) ~ Walk 2m5s ~ Pacific Hwy S & S 240th St(61180) ~ BUS A Line 10:58:04 11:20 ~ Federal Way TC - Bay 1(80431) ~ Walk 1m4s ~ Federal Way TC - Bay 3(80433) ~ BUS 187 11:32 11:38:38 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -25,1,01:20:02,8403,3270,10:25:15,11:45:17,Metro Transit,BUS,165|A Line,kcm:48620|kcm:48950|kcm:61180|kcm:61313,Walk 10m11s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 10:35:26 10:50:30 ~ Pacific Hwy S & S 240th St(48950) ~ Walk 2m5s ~ Pacific Hwy S & S 240th St(61180) ~ BUS A Line 10:58:04 11:14:51 ~ S 316th St & Pacific Hwy S(61313) ~ Walk 30m26s -25,2,01:20:48,7585,1267,10:55:15,12:16:03,Metro Transit,BUS,165|A Line|181,kcm:48620|kcm:48950|kcm:61180|kcm:80431|kcm:80433|kcm:83784,Walk 10m11s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 11:05:26 11:20:30 ~ Pacific Hwy S & S 240th St(48950) ~ Walk 2m5s ~ Pacific Hwy S & S 240th St(61180) ~ BUS A Line 11:29:08 11:52 ~ Federal Way TC - Bay 1(80431) ~ Walk 1m4s ~ Federal Way TC - Bay 3(80433) ~ BUS 181 12:05 12:12:47 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -26,2,00:48:26,4916,282,10:04:40,10:53:06,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|A Line|Road to Independence,sound-generations:area_551|kcm:61230|kcm:61280|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:04:40 10:31:03Walk 50s ~ Pacific Hwy S & S 268th St(61230) ~ BUS A Line 10:33:53 10:39:16 ~ Pacific Hwy S & S Dash Point Rd(61280) ~ Walk 8s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:41:24 10:50:20Walk 2m46s -26,2,00:47:34,4942,388,10:05:32,10:53:06,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|A Line|Road to Independence,sound-generations:area_551|kcm:61240|kcm:61280|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:05:32 10:30:27Walk 2m12s ~ Pacific Hwy S & S 272nd St(61240) ~ BUS A Line 10:34:39 10:39:16 ~ Pacific Hwy S & S Dash Point Rd(61280) ~ Walk 8s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:41:24 10:50:20Walk 2m46s -26,2,00:48:30,4913,272,10:04:40,10:53:10,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|A Line|Road to Independence,sound-generations:area_551|kcm:61230|kcm:61300|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:04:40 10:31:03Walk 50s ~ Pacific Hwy S & S 268th St(61230) ~ BUS A Line 10:33:53 10:41:16 ~ Pacific Hwy S & S 308th St(61300) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:43:16 10:50:24Walk 2m46s -27,2,01:26:22,7887,1227,10:04:53,11:31:15,Metro Transit,BUS,165|131|128,kcm:47580|kcm:52301|kcm:52304|kcm:53870|kcm:31871,Walk 12m10s ~ 1st Ave S & S 176th St(47580) ~ BUS 165 10:17:03 10:27 ~ Burien Transit Center - Bay 1(52301) ~ Walk 37s ~ Burien Transit Center - Bay 4(52304) ~ BUS 131 10:30 10:39:43 ~ 4th Ave SW & SW 112th St(53870) ~ BUS 128 10:50:26 11:27:50 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -27,1,01:39:26,9604,3370,10:04:53,11:44:19,Metro Transit,BUS,165|120,kcm:47580|kcm:52301|kcm:52303|kcm:21620,Walk 12m10s ~ 1st Ave S & S 176th St(47580) ~ BUS 165 10:17:03 10:27 ~ Burien Transit Center - Bay 1(52301) ~ Walk 1m6s ~ Burien Transit Center - Bay 3(52303) ~ BUS 120 10:36 11:12 ~ Delridge Way SW & SW Andover St(21620) ~ Walk 32m19s -27,2,01:45:32,10721,3516,10:05:43,11:51:15,Metro Transit,BUS,F Line|120|128,kcm:47646|kcm:52304|kcm:52303|kcm:21450|kcm:21440|kcm:31871,Walk 39m22s ~ SW 156th St & 2nd Ave SW(47646) ~ BUS F Line 10:45:05 10:48 ~ Burien Transit Center - Bay 4(52304) ~ Walk 37s ~ Burien Transit Center - Bay 3(52303) ~ BUS 120 10:56 11:24 ~ Delridge Way SW & SW Myrtle St(21450) ~ Walk 2m9s ~ SW Orchard St & Delridge Way SW(21440) ~ BUS 128 11:31 11:47:50 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -28,2,00:49:08,4750,0,10:00:22,10:49:30,Metro Transit|Sound Generations,BUS,Hyde Shuttle|60|Hyde Shuttle,sound-generations:area_551|kcm:21170|kcm:22184|sound-generations:area_560,sound-generations:area_551(area_551) ~ BUS null 10:00:22 10:18:46Walk 0s ~ SW Roxbury St & 5th Pl SW(21170) ~ BUS 60 10:20:46 10:26:05 ~ Delridge Way SW & SW Henderson St(22184) ~ Walk 0s ~ sound-generations:area_560(area_560) ~ BUS null 10:28:05 10:49:30 -28,2,00:51:23,4927,57,10:04:58,10:56:21,Metro Transit|Sound Generations,BUS,Hyde Shuttle|21|Hyde Shuttle,sound-generations:area_551|kcm:22261|kcm:22750|sound-generations:area_560,sound-generations:area_551(area_551) ~ BUS null 10:04:58 10:32:01Walk 48s ~ SW Roxbury St & 30th Ave SW(22261) ~ BUS 21 10:34:49 10:44:32 ~ 35th Ave SW & SW Findlay St(22750) ~ Walk 0s ~ sound-generations:area_560(area_560) ~ BUS null 10:46:32 10:56:21 -28,2,00:51:26,4894,9,10:08:36,11:00:02,Metro Transit|Sound Generations,BUS,Hyde Shuttle|120|Hyde Shuttle,sound-generations:area_551|kcm:39431|kcm:31731|sound-generations:area_560,sound-generations:area_551(area_551) ~ BUS null 10:08:36 10:30Walk 0s ~ 15th Ave SW & SW Roxbury St - Bay 2(39431) ~ BUS 120 10:32 10:37 ~ 26th Ave SW & SW Barton St - Bay 2(31731) ~ Walk 7s ~ sound-generations:area_560(area_560) ~ BUS null 10:39:07 11:00:02 -29,2,02:12:45,11617,2538,10:25:15,12:38:00,Metro Transit|Sound Transit,BUS,165|A Line|578,kcm:48620|kcm:48950|kcm:61180|kcm:80431|pierce-transit:4136|pierce-transit:10401,Walk 10m11s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 10:35:26 10:50:30 ~ Pacific Hwy S & S 240th St(48950) ~ Walk 2m5s ~ Pacific Hwy S & S 240th St(61180) ~ BUS A Line 10:58:04 11:20 ~ Federal Way TC - Bay 1(80431) ~ Walk 27s ~ Federal Way TC - Bay 2(4136) ~ BUS 578 11:32 12:17 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m -29,2,02:03:54,10186,1290,10:55:15,12:59:09,Metro Transit|Pierce Transit|Sound Transit,BUS,165|574|402,kcm:48620|kcm:53508|pierce-transit:3818|pierce-transit:29410|pierce-transit:1332,Walk 10m11s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 11:05:26 11:24:33 ~ Kent Des Moines Rd & I-5 Ramp(53508) ~ Walk 41s ~ I-5 & Kent - Des Moines Fwy Station(3818) ~ BUS 574 11:49 12:00 ~ Federal Way TC - Bay 5(29410) ~ BUS 402 12:11 12:53 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m9s -30,2,01:04:14,5656,0,10:02:15,11:06:29,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|165|Road to Independence,sound-generations:area_551|kcm:48620|kcm:50717|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:02:15 10:04:26Walk 0s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 10:06:26 10:37:05 ~ 64th Ave S & W James St(50717) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:39:05 11:06:29 -30,2,01:10:26,6064,52,10:04:40,11:15:06,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|A Line|Road to Independence,sound-generations:area_551|kcm:61230|kcm:61310|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:04:40 10:31:03Walk 50s ~ Pacific Hwy S & S 268th St(61230) ~ BUS A Line 10:33:53 10:42 ~ Pacific Hwy S & S 312th St(61310) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:44 11:15:06 -30,2,01:09:34,6090,158,10:05:32,11:15:06,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|A Line|Road to Independence,sound-generations:area_551|kcm:61240|kcm:61310|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:05:32 10:30:27Walk 2m12s ~ Pacific Hwy S & S 272nd St(61240) ~ BUS A Line 10:34:39 10:42 ~ Pacific Hwy S & S 312th St(61310) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:44 11:15:06 -31,4,03:52:55,18169,1615,10:04:53,13:57:48,Metro Transit|Sound Transit,BUS,165|131|545|224|629,kcm:47580|kcm:52301|kcm:52304|kcm:619|kcm:620|kcm:72488|kcm:68803|kcm:64397,Walk 12m10s ~ 1st Ave S & S 176th St(47580) ~ BUS 165 10:17:03 10:27 ~ Burien Transit Center - Bay 1(52301) ~ Walk 37s ~ Burien Transit Center - Bay 4(52304) ~ BUS 131 10:30 11:16 ~ 4th Ave S & S Jackson St(619) ~ Walk 1m46s ~ 4th Ave S & S Jackson St(620) ~ BUS 545 11:21 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -31,3,03:09:47,15081,1777,11:02:53,14:12:40,Metro Transit|Sound Transit,BUS,165|131|554|208,kcm:47580|kcm:52301|kcm:52304|kcm:619|kcm:375|kcm:64590|kcm:64593|kcm:64399,Walk 12m10s ~ 1st Ave S & S 176th St(47580) ~ BUS 165 11:15:03 11:25 ~ Burien Transit Center - Bay 1(52301) ~ Walk 37s ~ Burien Transit Center - Bay 4(52304) ~ BUS 131 11:28 12:16 ~ 4th Ave S & S Jackson St(619) ~ Walk 4m21s ~ 2nd Ave Ext S & Yesler Way(375) ~ BUS 554 12:24 12:52 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 13:30 14:06:59 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -31,3,03:09:13,17227,4645,11:03:27,14:12:40,Metro Transit|Sound Transit,BUS|TRAM,F Line|1-Line|554|208,kcm:50130|kcm:60922|sound-transit:99905|sound-transit:99260|kcm:1480|kcm:64590|kcm:64593|kcm:64399,Walk 39m32s ~ S 156th St & 1st Ave S(50130) ~ BUS F Line 11:42:59 11:52 ~ Tukwila International Blvd Station - Bay 2(60922) ~ Walk 3m51s ~ Tukwila Int'l Blvd Station(99905) ~ TRAM 1-Line 12:03 12:30 ~ Stadium Station(99260) ~ Walk 12m41s ~ S Jackson St & Maynard Ave S(1480) ~ BUS 554 12:46:10 13:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 13:30 14:06:59 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -32,5,03:33:58,16543,145,10:22:13,13:56:11,Metro Transit|Snoqualmie Valley Transportation|Sound Generations|Sound Transit,BUS,Hyde Shuttle|131|545|224|629|Dial-A-Ride,sound-generations:area_551|kcm:49588|kcm:619|kcm:620|kcm:72488|kcm:68803|kcm:64366|snoqualmie-flex:area_486,sound-generations:area_551(area_551) ~ BUS null 10:22:13 10:41:46Walk 14s ~ 8th Ave SW & SW 99th St(49588) ~ BUS 131 10:44 11:16 ~ 4th Ave S & S Jackson St(619) ~ Walk 1m46s ~ 4th Ave S & S Jackson St(620) ~ BUS 545 11:21 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:25:48 ~ Sr 203 & NE 40th St(64366) ~ Walk 8s ~ snoqualmie-flex:area_485(area_485) ~ BUS null 13:27:56 13:56:11 -32,4,03:35:35,16411,646,10:22:13,13:57:48,Metro Transit|Sound Generations|Sound Transit,BUS,Hyde Shuttle|131|545|224|629,sound-generations:area_551|kcm:49588|kcm:619|kcm:620|kcm:72488|kcm:68803|kcm:64397,sound-generations:area_551(area_551) ~ BUS null 10:22:13 10:41:46Walk 14s ~ 8th Ave SW & SW 99th St(49588) ~ BUS 131 10:44 11:16 ~ 4th Ave S & S Jackson St(619) ~ Walk 1m46s ~ 4th Ave S & S Jackson St(620) ~ BUS 545 11:21 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -33,2,01:48:45,9225,1215,10:04:53,11:53:38,Metro Transit,BUS,165|131|3,kcm:47580|kcm:52301|kcm:52304|kcm:605|kcm:41350,Walk 12m10s ~ 1st Ave S & S 176th St(47580) ~ BUS 165 10:17:03 10:27 ~ Burien Transit Center - Bay 1(52301) ~ Walk 37s ~ Burien Transit Center - Bay 4(52304) ~ BUS 131 10:30 11:27 ~ 3rd Ave & Bell St(605) ~ BUS 3 11:33:07 11:50:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -33,2,01:50:45,9345,1215,10:32:53,12:23:38,Metro Transit,BUS,165|131|3,kcm:47580|kcm:52301|kcm:52304|kcm:605|kcm:41350,Walk 12m10s ~ 1st Ave S & S 176th St(47580) ~ BUS 165 10:45:03 10:55 ~ Burien Transit Center - Bay 1(52301) ~ Walk 37s ~ Burien Transit Center - Bay 4(52304) ~ BUS 131 10:59 11:57 ~ 3rd Ave & Bell St(605) ~ BUS 3 12:03:07 12:20:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -33,3,02:09:19,12795,3471,10:33:27,12:42:46,Metro Transit|Sound Transit,BUS|TRAM,F Line|1-Line|5|2,kcm:50130|kcm:60922|sound-transit:99905|sound-transit:532|kcm:531|kcm:605|kcm:2820,Walk 39m32s ~ S 156th St & 1st Ave S(50130) ~ BUS F Line 11:12:59 11:22 ~ Tukwila International Blvd Station - Bay 2(60922) ~ Walk 3m51s ~ Tukwila Int'l Blvd Station(99905) ~ TRAM 1-Line 11:33 12:04 ~ Pioneer Square Station(532) ~ Walk 1m29s ~ 3rd Ave & James St(531) ~ BUS 5 12:09:47 12:18:02 ~ 3rd Ave & Bell St(605) ~ BUS 2 12:21:14 12:40:45 ~ 6th Ave W & W Mcgraw St(2820) ~ Walk 2m1s -34,3,01:20:55,7741,659,10:00:09,11:21:04,Metro Transit|Sound Generations,BUS,Hyde Shuttle|125|125|E Line|Hyde Shuttle,sound-generations:area_551|kcm:21292|kcm:21350|kcm:21620|kcm:575|kcm:6237|sound-generations:area_555,sound-generations:area_551(area_551) ~ BUS null 10:00:09 10:21:48Walk 40s ~ 16th Ave SW & SW Roxbury St - Bay 5(21292) ~ Walk 7m45s ~ 16th Ave SW & SW Henderson St(21350) ~ BUS 125 10:32:13 10:45 ~ Delridge Way SW & SW Andover St(21620) ~ BUS 125 10:45 10:59 ~ 3rd Ave & Pike St(575) ~ BUS E Line 11:05 11:08:18 ~ 7th Ave N & Harrison St(6237) ~ Walk 15s ~ sound-generations:area_555(area_555) ~ BUS null 11:10:33 11:21:04 -34,2,01:15:04,6313,12,10:12:29,11:27:33,Metro Transit|Sound Generations,BUS,Hyde Shuttle|132|28|Hyde Shuttle,sound-generations:area_551|kcm:49700|kcm:30635|kcm:6237|sound-generations:area_555,sound-generations:area_551(area_551) ~ BUS null 10:12:29 10:29:39Walk 0s ~ Des Moines Memorial Dr S & S 96th St(49700) ~ BUS 132 10:31:39 11:00 ~ 4th Ave S & S Royal Brougham Way(30635) ~ BUS 28 11:00 11:14:47 ~ 7th Ave N & Harrison St(6237) ~ Walk 15s ~ sound-generations:area_555(area_555) ~ BUS null 11:17:02 11:27:33 -34,1,01:31:23,8054,1835,10:12:29,11:43:52,Metro Transit|Sound Generations,BUS,Hyde Shuttle|132|28,sound-generations:area_551|kcm:49700|kcm:30635|kcm:6320,sound-generations:area_551(area_551) ~ BUS null 10:12:29 10:29:39Walk 0s ~ Des Moines Memorial Dr S & S 96th St(49700) ~ BUS 132 10:31:39 11:00 ~ 4th Ave S & S Royal Brougham Way(30635) ~ BUS 28 11:00 11:18:47 ~ Aurora Ave N & Lynn St(6320) ~ Walk 25m5s -35,2,01:01:36,6463,1206,10:04:53,11:06:29,Metro Transit|Sound Transit,BUS|TRAM,165|F Line|1-Line,kcm:47580|kcm:53720|kcm:53975|kcm:60922|sound-transit:99905|sound-transit:99240,Walk 12m10s ~ 1st Ave S & S 176th St(47580) ~ BUS 165 10:17:03 10:24:32 ~ 4th Ave SW & SW 156th St(53720) ~ Walk 9s ~ 4th Ave SW & SW 156th St(53975) ~ BUS F Line 10:26:42 10:37 ~ Tukwila International Blvd Station - Bay 2(60922) ~ Walk 3m51s ~ Tukwila Int'l Blvd Station(99905) ~ TRAM 1-Line 10:43 11:05 ~ Beacon Hill Station(99240) ~ Walk 1m29s -35,1,01:23:02,8715,3334,10:03:27,11:26:29,Metro Transit|Sound Transit,BUS|TRAM,F Line|1-Line,kcm:50130|kcm:60922|sound-transit:99905|sound-transit:99240,Walk 39m32s ~ S 156th St & 1st Ave S(50130) ~ BUS F Line 10:42:59 10:52 ~ Tukwila International Blvd Station - Bay 2(60922) ~ Walk 3m51s ~ Tukwila Int'l Blvd Station(99905) ~ TRAM 1-Line 11:03 11:25 ~ Beacon Hill Station(99240) ~ Walk 1m29s -35,1,01:30:01,8636,2785,10:04:53,11:34:54,Metro Transit,BUS,165|131,kcm:47580|kcm:52301|kcm:52304|kcm:30600,Walk 12m10s ~ 1st Ave S & S 176th St(47580) ~ BUS 165 10:17:03 10:27 ~ Burien Transit Center - Bay 1(52301) ~ Walk 37s ~ Burien Transit Center - Bay 4(52304) ~ BUS 131 10:30 11:11:03 ~ 4th Ave S & S Holgate St(30600) ~ Walk 23m51s -36,2,00:55:04,5413,321,10:01:25,10:56:29,Metro Transit|Sound Generations|Sound Transit,BUS|TRAM,Hyde Shuttle|F Line|1-Line,sound-generations:area_551|kcm:50145|kcm:60922|sound-transit:99905|sound-transit:99240,sound-generations:area_551(area_551) ~ BUS null 10:01:25 10:11:33Walk 1m3s ~ S 156th Way & Des Moines Memorial Dr S(50145) ~ BUS F Line 10:14:36 10:22 ~ Tukwila International Blvd Station - Bay 2(60922) ~ Walk 3m51s ~ Tukwila Int'l Blvd Station(99905) ~ TRAM 1-Line 10:33 10:55 ~ Beacon Hill Station(99240) ~ Walk 1m29s -36,1,00:52:13,4553,308,10:10:01,11:02:14,Metro Transit|Sound Generations,BUS,Hyde Shuttle|60,sound-generations:area_551|kcm:21110|kcm:41880,sound-generations:area_551(area_551) ~ BUS null 10:10:01 10:28:47Walk 0s ~ SW Roxbury St & 8th Ave SW(21110) ~ BUS 60 10:30:47 10:58 ~ 15th Ave S & S Stevens St(41880) ~ Walk 4m14s -36,2,00:49:45,5060,380,10:12:29,11:02:14,Metro Transit|Sound Generations,BUS,Hyde Shuttle|132|60,sound-generations:area_551|kcm:49700|kcm:31680|kcm:32140|kcm:41880,sound-generations:area_551(area_551) ~ BUS null 10:12:29 10:29:39Walk 0s ~ Des Moines Memorial Dr S & S 96th St(49700) ~ BUS 132 10:31:39 10:34:53 ~ S Cloverdale St & 12th Ave S(31680) ~ Walk 55s ~ S Cloverdale St & 12th Ave S(32140) ~ BUS 60 10:39:31 10:58 ~ 15th Ave S & S Stevens St(41880) ~ Walk 4m14s -37,0,02:46:43,19483,12868,10:00:00,12:46:43,,,,,Walk 2h46m43s -37,1,01:23:27,8626,3284,10:01:06,11:24:33,Metro Transit,BUS,165|160,kcm:48960|kcm:57127|kcm:57130|kcm:57185,Walk 22m47s ~ Pacific Hwy S & Kent Des Moines Rd(48960) ~ BUS 165 10:23:53 10:51 ~ SE 240th St & 104th Ave SE(57127) ~ Walk 1m45s ~ 104th Ave SE & SE 240th St(57130) ~ BUS 160 11:01:23 11:06:08 ~ 108th Ave SE & SE 220th Pl(57185) ~ Walk 18m25s -37,0,01:25:28,8967,4388,10:01:06,11:26:34,Metro Transit,BUS,165,kcm:48960|kcm:57141,Walk 22m47s ~ Pacific Hwy S & Kent Des Moines Rd(48960) ~ BUS 165 10:23:53 10:52:44 ~ SE 240th St & 116th Ave SE(57141) ~ Walk 33m50s -38,2,00:47:28,4948,406,10:00:24,10:47:52,Metro Transit|Sound Generations,BUS,Hyde Shuttle|183|Hyde Shuttle,sound-generations:area_551|kcm:47971|kcm:47974|kcm:53056|sound-generations:area_558,sound-generations:area_551(area_551) ~ BUS null 10:00:24 10:13:08Walk 1m19s ~ S 272nd St & Pacific Hwy S(47971) ~ Walk 3m56s ~ S 272nd St & S Star Lake Rd(47974) ~ BUS 183 10:20:23 10:23:56 ~ Military Rd S & S 264th St(53056) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 10:25:56 10:47:52 -38,2,00:39:29,4228,77,10:09:09,10:48:38,Metro Transit|Sound Generations,BUS,Hyde Shuttle|A Line|Hyde Shuttle,sound-generations:area_551|kcm:61190|kcm:61201|sound-generations:area_558,sound-generations:area_551(area_551) ~ BUS null 10:09:09 10:16:21Walk 1m2s ~ Pacific Hwy S & S 246th St(61190) ~ BUS A Line 10:19:23 10:20:41 ~ Pacific Hwy S & S 252nd St(61201) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 10:22:41 10:48:38 -38,2,00:38:01,4244,225,10:11:51,10:49:52,Metro Transit|Sound Generations,BUS,Hyde Shuttle|165|Hyde Shuttle,sound-generations:area_551|kcm:48930|kcm:47263|sound-generations:area_558,sound-generations:area_551(area_551) ~ BUS null 10:11:51 10:16:49Walk 0s ~ S 240th St & 21st Ave S(48930) ~ BUS 165 10:18:49 10:20 ~ Highline College(47263) ~ Walk 3m4s ~ sound-generations:area_558(area_558) ~ BUS null 10:25:04 10:49:52 -39,0,01:36:57,11280,7450,10:00:00,11:36:57,,,,,Walk 1h36m57s -39,0,00:40:49,4933,2548,10:15:00,10:55:49,Metro Transit,BUS,165,kcm:47390|kcm:47570,Walk 21m ~ Marine View Dr S & S 223rd St(47390) ~ BUS 165 10:36 10:44 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m49s -39,0,00:48:56,5603,2817,10:29:27,11:18:23,Metro Transit,BUS,156,kcm:48990|kcm:49190,Walk 9m35s ~ 24th Ave S & S 226th St(48990) ~ BUS 156 10:39:02 10:51:04 ~ 8th Ave S & Des Moines Memorial Dr S(49190) ~ Walk 27m19s -40,2,00:20:26,3028,0,10:00:38,10:21:04,Metro Transit|Sound Generations,BUS,Hyde Shuttle|165|Hyde Shuttle,sound-generations:area_551|kcm:47390|kcm:47570|sound-generations:area_551,sound-generations:area_551(area_551) ~ BUS null 10:00:38 10:06Walk 0s ~ Marine View Dr S & S 223rd St(47390) ~ BUS 165 10:08 10:16 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:18 10:21:04 -40,1,00:27:11,3512,917,10:00:38,10:27:49,Metro Transit|Sound Generations,BUS,Hyde Shuttle|165,sound-generations:area_551|kcm:47390|kcm:47570,sound-generations:area_551(area_551) ~ BUS null 10:00:38 10:06Walk 0s ~ Marine View Dr S & S 223rd St(47390) ~ BUS 165 10:08 10:16 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m49s -40,2,00:24:33,3275,0,10:05:02,10:29:35,Metro Transit|Sound Generations,BUS,Hyde Shuttle|156|Hyde Shuttle,sound-generations:area_551|kcm:47406|kcm:49150|sound-generations:area_551,sound-generations:area_551(area_551) ~ BUS null 10:05:02 10:11:06Walk 0s ~ S 216th St & 11th Ave S(47406) ~ BUS 156 10:13:06 10:18:53 ~ 8th Ave S & S 194th St(49150) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:20:53 10:29:35 -41,1,01:00:18,6263,1973,10:01:06,11:01:24,Metro Transit,BUS,165|160,kcm:48960|kcm:57452|kcm:57451|kcm:58255,Walk 22m47s ~ Pacific Hwy S & Kent Des Moines Rd(48960) ~ BUS 165 10:23:53 10:45 ~ Kent Sounder Station - Bay 2(57452) ~ Walk 29s ~ Kent Sounder Station - Bay 1(57451) ~ BUS 160 10:48 10:58:37 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -41,2,01:21:47,8189,2019,10:09:20,11:31:07,Metro Transit,BUS,A Line|183|160,kcm:61170|kcm:61240|kcm:47974|kcm:57452|kcm:57451|kcm:58255,Walk 15m57s ~ Pacific Hwy S & S 224th St(61170) ~ BUS A Line 10:25:17 10:34:39 ~ Pacific Hwy S & S 272nd St(61240) ~ Walk 7m32s ~ S 272nd St & S Star Lake Rd(47974) ~ BUS 183 10:48:23 11:08 ~ Kent Sounder Station - Bay 2(57452) ~ Walk 29s ~ Kent Sounder Station - Bay 1(57451) ~ BUS 160 11:17 11:28:20 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -41,1,01:17:01,7266,1973,10:30:06,11:47:07,Metro Transit,BUS,165|160,kcm:48960|kcm:57452|kcm:57451|kcm:58255,Walk 22m47s ~ Pacific Hwy S & Kent Des Moines Rd(48960) ~ BUS 165 10:52:53 11:15 ~ Kent Sounder Station - Bay 2(57452) ~ Walk 29s ~ Kent Sounder Station - Bay 1(57451) ~ BUS 160 11:33 11:44:20 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -42,2,00:42:19,4639,406,10:00:24,10:42:43,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|183|Road to Independence,sound-generations:area_551|kcm:47971|kcm:47974|kcm:53050|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:00:24 10:13:08Walk 1m19s ~ S 272nd St & Pacific Hwy S(47971) ~ Walk 3m56s ~ S 272nd St & S Star Lake Rd(47974) ~ BUS 183 10:20:23 10:22:23 ~ Military Rd S & S 272nd St(53050) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:24:23 10:42:43 -42,2,00:36:28,4114,171,10:08:49,10:45:17,Puget Sound Educational Service District|Sound Generations|Sound Transit,BUS,Hyde Shuttle|574|Road to Independence,sound-generations:area_551|pierce-transit:3818|pierce-transit:25846|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:08:49 10:14:45Walk 2m15s ~ I-5 & Kent - Des Moines Fwy Station(3818) ~ BUS 574 10:19 10:22 ~ Star Lake Fwy Station(25846) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:24 10:45:17 -42,1,00:40:22,4625,1357,10:06:20,10:46:42,Metro Transit|Sound Generations,BUS,Hyde Shuttle|160,sound-generations:area_558|kcm:58150|kcm:58255,Walk 14m53s ~ sound-generations:area_558(area_558) ~ BUS null 10:21:13 10:34:05Walk 0s ~ Central Ave S & E Russell St(58150) ~ BUS 160 10:36:05 10:43:55 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -43,1,00:54:31,5614,1550,10:19:20,11:13:51,Metro Transit,BUS,A Line|181,kcm:61170|kcm:80431|kcm:80433|kcm:83784,Walk 15m57s ~ Pacific Hwy S & S 224th St(61170) ~ BUS A Line 10:35:17 10:59 ~ Federal Way TC - Bay 1(80431) ~ Walk 1m4s ~ Federal Way TC - Bay 3(80433) ~ BUS 181 11:04 11:10:35 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -43,1,00:49:26,5758,2172,10:24:25,11:13:51,Metro Transit|Sound Transit,BUS,574|181,pierce-transit:3818|pierce-transit:29410|kcm:80433|kcm:83784,Walk 24m35s ~ I-5 & Kent - Des Moines Fwy Station(3818) ~ BUS 574 10:49 11:00 ~ Federal Way TC - Bay 5(29410) ~ Walk 33s ~ Federal Way TC - Bay 3(80433) ~ BUS 181 11:04 11:10:35 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -43,0,01:05:35,7142,3553,10:09:20,11:14:55,Metro Transit,BUS,A Line,kcm:61170|kcm:61313,Walk 15m57s ~ Pacific Hwy S & S 224th St(61170) ~ BUS A Line 10:25:17 10:44:29 ~ S 316th St & Pacific Hwy S(61313) ~ Walk 30m26s -44,2,00:40:00,4665,626,10:00:24,10:40:24,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|183|Road to Independence,sound-generations:area_551|kcm:47971|kcm:47974|kcm:50734|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:00:24 10:13:08Walk 1m19s ~ S 272nd St & Pacific Hwy S(47971) ~ Walk 3m56s ~ S 272nd St & S Star Lake Rd(47974) ~ BUS 183 10:20:23 10:21 ~ S 272nd St & 26th Ave S(50734) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:23 10:37:38Walk 2m46s -44,2,00:33:26,4098,391,10:08:49,10:42:15,Puget Sound Educational Service District|Sound Generations|Sound Transit,BUS,Hyde Shuttle|574|Road to Independence,sound-generations:area_551|pierce-transit:3818|pierce-transit:25846|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:08:49 10:14:45Walk 2m15s ~ I-5 & Kent - Des Moines Fwy Station(3818) ~ BUS 574 10:19 10:22 ~ Star Lake Fwy Station(25846) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:24 10:39:29Walk 2m46s -44,2,00:33:57,4069,307,10:09:09,10:43:06,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|A Line|Road to Independence,sound-generations:area_551|kcm:61190|kcm:61280|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:09:09 10:16:21Walk 1m2s ~ Pacific Hwy S & S 246th St(61190) ~ BUS A Line 10:19:23 10:29:16 ~ Pacific Hwy S & S Dash Point Rd(61280) ~ Walk 8s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:31:24 10:40:20Walk 2m46s -45,2,01:42:38,9397,1963,10:06:22,11:49:00,Metro Transit|Sound Transit,BUS|TRAM,635|1-Line|50,kcm:47417|kcm:47200|sound-transit:99914|sound-transit:99256|kcm:99261|kcm:31871,Walk 18m33s ~ S 216th St & 20th Ave S(47417) ~ BUS 635 10:24:55 10:31 ~ S 200th St & 28th Ave S(47200) ~ Walk 2m30s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:36 11:08 ~ SODO Station(99256) ~ Walk 2m7s ~ S Lander St & SODO Busway(99261) ~ BUS 50 11:22 11:45:35 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -45,1,01:48:10,8969,1694,10:03:05,11:51:15,Metro Transit,BUS,A Line|128,kcm:60810|kcm:60921|kcm:60923|kcm:31871,Walk 17m33s ~ Pacific Hwy S & S 224th St(60810) ~ BUS A Line 10:20:38 10:40 ~ Tukwila International Blvd Station - Bay 1(60921) ~ Walk 2m28s ~ Tukwila International Blvd Station - Bay 3(60923) ~ BUS 128 10:51 11:47:50 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -45,2,01:38:55,9193,2004,10:23:05,12:02:00,Metro Transit|Sound Transit,BUS|TRAM,A Line|1-Line|50,kcm:60810|kcm:60850|sound-transit:99914|sound-transit:99256|kcm:99261|kcm:31871,Walk 17m33s ~ Pacific Hwy S & S 224th St(60810) ~ BUS A Line 10:40:38 10:45:46 ~ International Blvd & S 200th St(60850) ~ Walk 4m23s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:56 11:28 ~ SODO Station(99256) ~ Walk 2m7s ~ S Lander St & SODO Busway(99261) ~ BUS 50 11:35 11:58:35 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -46,2,00:59:51,5399,9,10:00:11,11:00:02,Metro Transit|Sound Generations,BUS,Hyde Shuttle|120|Hyde Shuttle,sound-generations:area_551|kcm:39431|kcm:31731|sound-generations:area_560,sound-generations:area_551(area_551) ~ BUS null 10:00:11 10:30Walk 0s ~ 15th Ave SW & SW Roxbury St - Bay 2(39431) ~ BUS 120 10:32 10:37 ~ 26th Ave SW & SW Barton St - Bay 2(31731) ~ Walk 7s ~ sound-generations:area_560(area_560) ~ BUS null 10:39:07 11:00:02 -46,2,00:51:21,4883,0,10:09:41,11:01:02,Metro Transit|Sound Generations,BUS,Hyde Shuttle|132|Hyde Shuttle,sound-generations:area_551|kcm:49700|kcm:49720|sound-generations:area_560,sound-generations:area_551(area_551) ~ BUS null 10:09:41 10:29:39Walk 0s ~ Des Moines Memorial Dr S & S 96th St(49700) ~ BUS 132 10:31:39 10:33:52 ~ 14th Ave S & S Trenton St(49720) ~ Walk 0s ~ sound-generations:area_560(area_560) ~ BUS null 10:35:52 11:01:02 -46,2,00:59:51,5399,9,10:10:11,11:10:02,Metro Transit|Sound Generations,BUS,Hyde Shuttle|120|Hyde Shuttle,sound-generations:area_551|kcm:39431|kcm:31731|sound-generations:area_560,sound-generations:area_551(area_551) ~ BUS null 10:10:11 10:40Walk 0s ~ 15th Ave SW & SW Roxbury St - Bay 2(39431) ~ BUS 120 10:42 10:47 ~ 26th Ave SW & SW Barton St - Bay 2(31731) ~ Walk 7s ~ sound-generations:area_560(area_560) ~ BUS null 10:49:07 11:10:02 -47,1,01:36:49,8326,1794,10:19:20,11:56:09,Metro Transit|Pierce Transit,BUS,A Line|402,kcm:61170|kcm:80431|pierce-transit:29410|pierce-transit:1332,Walk 15m57s ~ Pacific Hwy S & S 224th St(61170) ~ BUS A Line 10:35:17 10:59 ~ Federal Way TC - Bay 1(80431) ~ Walk 1m37s ~ Federal Way TC - Bay 5(29410) ~ BUS 402 11:10 11:50 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m9s -47,1,01:31:44,8410,2334,10:24:25,11:56:09,Pierce Transit|Sound Transit,BUS,574|402,pierce-transit:3818|pierce-transit:29410|pierce-transit:1332,Walk 24m35s ~ I-5 & Kent - Des Moines Fwy Station(3818) ~ BUS 574 10:49 11:00 ~ Federal Way TC - Bay 5(29410) ~ BUS 402 11:10 11:50 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m9s -47,1,01:58:40,10378,2821,10:39:20,12:38:00,Metro Transit|Sound Transit,BUS,A Line|578,kcm:61170|kcm:80431|pierce-transit:4136|pierce-transit:10401,Walk 15m57s ~ Pacific Hwy S & S 224th St(61170) ~ BUS A Line 10:55:17 11:20 ~ Federal Way TC - Bay 1(80431) ~ Walk 27s ~ Federal Way TC - Bay 2(4136) ~ BUS 578 11:32 12:17 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m -48,2,00:50:58,5158,406,10:00:24,10:51:22,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|183|Road to Independence,sound-generations:area_551|kcm:47971|kcm:47974|kcm:50734|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:00:24 10:13:08Walk 1m19s ~ S 272nd St & Pacific Hwy S(47971) ~ Walk 3m56s ~ S 272nd St & S Star Lake Rd(47974) ~ BUS 183 10:20:23 10:21 ~ S 272nd St & 26th Ave S(50734) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:23 10:51:22 -48,2,00:44:24,4590,171,10:08:49,10:53:13,Puget Sound Educational Service District|Sound Generations|Sound Transit,BUS,Hyde Shuttle|574|Road to Independence,sound-generations:area_551|pierce-transit:3818|pierce-transit:25846|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:08:49 10:14:45Walk 2m15s ~ I-5 & Kent - Des Moines Fwy Station(3818) ~ BUS 574 10:19 10:22 ~ Star Lake Fwy Station(25846) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:24 10:53:13 -48,2,00:51:25,5200,428,10:09:09,11:00:34,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|A Line|Road to Independence,sound-generations:area_551|kcm:61190|kcm:61230|pudget-sound-educational:area_622,sound-generations:area_551(area_551) ~ BUS null 10:09:09 10:16:21Walk 1m2s ~ Pacific Hwy S & S 246th St(61190) ~ BUS A Line 10:19:23 10:23:53 ~ Pacific Hwy S & S 268th St(61230) ~ Walk 4m44s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:30:37 11:00:34 -49,4,03:51:26,18600,2321,10:06:22,13:57:48,Metro Transit|Sound Transit,BUS|TRAM,635|1-Line|545|224|629,kcm:47417|kcm:47200|sound-transit:99914|sound-transit:99260|kcm:21765|kcm:72488|kcm:68803|kcm:64397,Walk 18m33s ~ S 216th St & 20th Ave S(47417) ~ BUS 635 10:24:55 10:31 ~ S 200th St & 28th Ave S(47200) ~ Walk 2m30s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:36 11:10 ~ Stadium Station(99260) ~ Walk 3m13s ~ 6th Ave S & S Royal Brougham Way(21765) ~ BUS 545 11:17 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -49,3,02:49:27,14769,3036,11:23:13,14:12:40,Metro Transit|Sound Transit,BUS|TRAM,A Line|1-Line|554|208,kcm:60810|kcm:60850|sound-transit:99914|sound-transit:99260|kcm:1480|kcm:64590|kcm:64593|kcm:64399,Walk 17m33s ~ Pacific Hwy S & S 224th St(60810) ~ BUS A Line 11:40:46 11:46:20 ~ International Blvd & S 200th St(60850) ~ Walk 4m23s ~ Angle Lake Station(99914) ~ TRAM 1-Line 11:56 12:30 ~ Stadium Station(99260) ~ Walk 12m41s ~ S Jackson St & Maynard Ave S(1480) ~ BUS 554 12:46:10 13:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 13:30 14:06:59 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -50,5,03:42:23,17048,145,10:13:48,13:56:11,Metro Transit|Snoqualmie Valley Transportation|Sound Generations|Sound Transit,BUS,Hyde Shuttle|131|545|224|629|Dial-A-Ride,sound-generations:area_551|kcm:49588|kcm:619|kcm:620|kcm:72488|kcm:68803|kcm:64366|snoqualmie-flex:area_486,sound-generations:area_551(area_551) ~ BUS null 10:13:48 10:41:46Walk 14s ~ 8th Ave SW & SW 99th St(49588) ~ BUS 131 10:44 11:16 ~ 4th Ave S & S Jackson St(619) ~ Walk 1m46s ~ 4th Ave S & S Jackson St(620) ~ BUS 545 11:21 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:25:48 ~ Sr 203 & NE 40th St(64366) ~ Walk 8s ~ snoqualmie-flex:area_485(area_485) ~ BUS null 13:27:56 13:56:11 -50,4,03:44:00,16916,646,10:13:48,13:57:48,Metro Transit|Sound Generations|Sound Transit,BUS,Hyde Shuttle|131|545|224|629,sound-generations:area_551|kcm:49588|kcm:619|kcm:620|kcm:72488|kcm:68803|kcm:64397,sound-generations:area_551(area_551) ~ BUS null 10:13:48 10:41:46Walk 14s ~ 8th Ave SW & SW 99th St(49588) ~ BUS 131 10:44 11:16 ~ 4th Ave S & S Jackson St(619) ~ Walk 1m46s ~ 4th Ave S & S Jackson St(620) ~ BUS 545 11:21 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -50,5,03:40:06,17479,910,10:17:42,13:57:48,Metro Transit|Sound Generations|Sound Transit,BUS|TRAM,Hyde Shuttle|635|1-Line|545|224|629,sound-generations:area_551|kcm:47206|kcm:47200|sound-transit:99914|sound-transit:99260|kcm:21765|kcm:72488|kcm:68803|kcm:64397,sound-generations:area_551(area_551) ~ BUS null 10:17:42 10:23:48Walk 12s ~ 24th Ave S & S 216th St(47206) ~ BUS 635 10:26 10:31 ~ S 200th St & 28th Ave S(47200) ~ Walk 2m30s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:36 11:10 ~ Stadium Station(99260) ~ Walk 3m13s ~ 6th Ave S & S Royal Brougham Way(21765) ~ BUS 545 11:17 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -51,3,01:47:16,10250,1913,10:06:22,11:53:38,Metro Transit|Sound Transit,BUS|TRAM,635|1-Line|131|3,kcm:47417|kcm:47200|sound-transit:99914|sound-transit:532|kcm:531|kcm:605|kcm:41350,Walk 18m33s ~ S 216th St & 20th Ave S(47417) ~ BUS 635 10:24:55 10:31 ~ S 200th St & 28th Ave S(47200) ~ Walk 2m30s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:36 11:14 ~ Pioneer Square Station(532) ~ Walk 1m29s ~ 3rd Ave & James St(531) ~ BUS 131 11:17:57 11:27 ~ 3rd Ave & Bell St(605) ~ BUS 3 11:33:07 11:50:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -51,2,01:54:47,11093,3289,10:06:22,12:01:09,Metro Transit|Sound Transit,BUS|TRAM,635|1-Line|62,kcm:47417|kcm:47200|sound-transit:99914|sound-transit:532|kcm:531|kcm:18590,Walk 18m33s ~ S 216th St & 20th Ave S(47417) ~ BUS 635 10:24:55 10:31 ~ S 200th St & 28th Ave S(47200) ~ Walk 2m30s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:36 11:14 ~ Pioneer Square Station(532) ~ Walk 1m29s ~ 3rd Ave & James St(531) ~ BUS 62 11:19:55 11:39:36 ~ Dexter Ave N & 4th Ave N(18590) ~ Walk 21m33s -51,3,01:55:33,10767,1954,10:13:05,12:08:38,Metro Transit|Sound Transit,BUS|TRAM,A Line|1-Line|40|3,kcm:60810|kcm:60850|sound-transit:99914|sound-transit:532|kcm:531|kcm:600|kcm:41350,Walk 17m33s ~ Pacific Hwy S & S 224th St(60810) ~ BUS A Line 10:30:38 10:35:46 ~ International Blvd & S 200th St(60850) ~ Walk 4m23s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:46 11:24 ~ Pioneer Square Station(532) ~ Walk 1m29s ~ 3rd Ave & James St(531) ~ BUS 40 11:31:37 11:38:03 ~ 3rd Ave & Virginia St(600) ~ BUS 3 11:45:57 12:05:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -52,2,01:17:52,6481,12,10:09:41,11:27:33,Metro Transit|Sound Generations,BUS,Hyde Shuttle|132|28|Hyde Shuttle,sound-generations:area_551|kcm:49700|kcm:30635|kcm:6237|sound-generations:area_555,sound-generations:area_551(area_551) ~ BUS null 10:09:41 10:29:39Walk 0s ~ Des Moines Memorial Dr S & S 96th St(49700) ~ BUS 132 10:31:39 11:00 ~ 4th Ave S & S Royal Brougham Way(30635) ~ BUS 28 11:00 11:14:47 ~ 7th Ave N & Harrison St(6237) ~ Walk 15s ~ sound-generations:area_555(area_555) ~ BUS null 11:17:02 11:27:33 -52,1,01:34:11,8222,1835,10:09:41,11:43:52,Metro Transit|Sound Generations,BUS,Hyde Shuttle|132|28,sound-generations:area_551|kcm:49700|kcm:30635|kcm:6320,sound-generations:area_551(area_551) ~ BUS null 10:09:41 10:29:39Walk 0s ~ Des Moines Memorial Dr S & S 96th St(49700) ~ BUS 132 10:31:39 11:00 ~ 4th Ave S & S Royal Brougham Way(30635) ~ BUS 28 11:00 11:18:47 ~ Aurora Ave N & Lynn St(6320) ~ Walk 25m5s -52,3,01:30:16,7833,24,10:13:48,11:44:04,Metro Transit|Sound Generations,BUS,Hyde Shuttle|131|E Line|Hyde Shuttle,sound-generations:area_551|kcm:49588|kcm:600|kcm:6237|sound-generations:area_555,sound-generations:area_551(area_551) ~ BUS null 10:13:48 10:41:46Walk 14s ~ 8th Ave SW & SW 99th St(49588) ~ BUS 131 10:44 11:25:09 ~ 3rd Ave & Virginia St(600) ~ BUS E Line 11:28:57 11:31:18 ~ 7th Ave N & Harrison St(6237) ~ Walk 15s ~ sound-generations:area_555(area_555) ~ BUS null 11:33:33 11:44:04 -53,1,01:00:07,6049,1684,10:06:22,11:06:29,Metro Transit|Sound Transit,BUS|TRAM,635|1-Line,kcm:47417|kcm:47200|sound-transit:99914|sound-transit:99240,Walk 18m33s ~ S 216th St & 20th Ave S(47417) ~ BUS 635 10:24:55 10:31 ~ S 200th St & 28th Ave S(47200) ~ Walk 2m30s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:36 11:05 ~ Beacon Hill Station(99240) ~ Walk 1m29s -53,1,01:03:24,6265,1725,10:13:05,11:16:29,Metro Transit|Sound Transit,BUS|TRAM,A Line|1-Line,kcm:60810|kcm:60850|sound-transit:99914|sound-transit:99240,Walk 17m33s ~ Pacific Hwy S & S 224th St(60810) ~ BUS A Line 10:30:38 10:35:46 ~ International Blvd & S 200th St(60850) ~ Walk 4m23s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:46 11:15 ~ Beacon Hill Station(99240) ~ Walk 1m29s -53,1,01:03:24,6265,1725,10:23:05,11:26:29,Metro Transit|Sound Transit,BUS|TRAM,A Line|1-Line,kcm:60810|kcm:60850|sound-transit:99914|sound-transit:99240,Walk 17m33s ~ Pacific Hwy S & S 224th St(60810) ~ BUS A Line 10:40:38 10:45:46 ~ International Blvd & S 200th St(60850) ~ Walk 4m23s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:56 11:25 ~ Beacon Hill Station(99240) ~ Walk 1m29s -54,2,00:53:16,5275,386,10:03:13,10:56:29,Metro Transit|Sound Generations|Sound Transit,BUS|TRAM,Hyde Shuttle|A Line|1-Line,sound-generations:area_551|kcm:60810|kcm:60850|sound-transit:99914|sound-transit:99240,sound-generations:area_551(area_551) ~ BUS null 10:03:13 10:08:38Walk 0s ~ Pacific Hwy S & S 224th St(60810) ~ BUS A Line 10:10:38 10:15:46 ~ International Blvd & S 200th St(60850) ~ Walk 4m23s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:26 10:55 ~ Beacon Hill Station(99240) ~ Walk 1m29s -54,1,00:55:19,5420,1239,10:01:10,10:56:29,Sound Generations|Sound Transit,BUS|TRAM,Hyde Shuttle|1-Line,sound-generations:area_551|kcm:47202|sound-transit:99914|sound-transit:99240,sound-generations:area_551(area_551) ~ BUS null 10:01:10 10:08:47Walk 28s ~ 24th Ave S & S 208th St(47202) ~ Walk 14m45s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:26 10:55 ~ Beacon Hill Station(99240) ~ Walk 1m29s -54,1,01:00:38,5058,308,10:01:36,11:02:14,Metro Transit|Sound Generations,BUS,Hyde Shuttle|60,sound-generations:area_551|kcm:21110|kcm:41880,sound-generations:area_551(area_551) ~ BUS null 10:01:36 10:28:47Walk 0s ~ SW Roxbury St & 8th Ave SW(21110) ~ BUS 60 10:30:47 10:58 ~ 15th Ave S & S Stevens St(41880) ~ Walk 4m14s -55,0,00:45:18,4538,1641,10:06:44,10:52:02,Metro Transit,BUS,160,kcm:57915|kcm:57185,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 10:09:32 10:33:37 ~ 108th Ave SE & SE 220th Pl(57185) ~ Walk 18m25s -55,0,00:47:32,4672,1641,10:22:01,11:09:33,Metro Transit,BUS,160,kcm:57915|kcm:57185,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 10:24:49 10:51:08 ~ 108th Ave SE & SE 220th Pl(57185) ~ Walk 18m25s -55,0,00:47:32,4672,1641,10:37:01,11:24:33,Metro Transit,BUS,160,kcm:57915|kcm:57185,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 10:39:49 11:06:08 ~ 108th Ave SE & SE 220th Pl(57185) ~ Walk 18m25s -56,1,00:31:12,3231,213,10:06:44,10:37:56,Metro Transit|Sound Generations,BUS,160|Hyde Shuttle,kcm:57915|kcm:57990|sound-generations:area_558,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 10:09:32 10:17:01 ~ Central Ave S & S 259th St(57990) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 10:19:01 10:37:56 -56,2,00:38:01,4103,28,10:07:12,10:45:13,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|161|Hyde Shuttle,pudget-sound-educational:area_622|kcm:57452|kcm:80640|sound-generations:area_558,pudget-sound-educational:area_622(area_622) ~ BUS null 10:07:12 10:24:36Walk 24s ~ Kent Sounder Station - Bay 2(57452) ~ BUS 161 10:27 10:30:28 ~ Central Ave N & S 228th St(80640) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 10:32:28 10:45:13 -56,0,00:45:18,4538,1641,10:06:44,10:52:02,Metro Transit,BUS,160,kcm:57915|kcm:57185,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 10:09:32 10:33:37 ~ 108th Ave SE & SE 220th Pl(57185) ~ Walk 18m25s -57,1,01:19:05,6879,1267,10:06:44,11:25:49,Metro Transit,BUS,160|165,kcm:57915|kcm:57453|kcm:57459|kcm:47570,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 10:09:32 10:21 ~ Kent Sounder Station - Bay 3(57453) ~ Walk 2m2s ~ Kent Sounder Station - Bay 9(57459) ~ BUS 165 10:37 11:14 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m49s -57,1,01:18:48,6862,1267,10:37:01,11:55:49,Metro Transit,BUS,160|165,kcm:57915|kcm:57453|kcm:57459|kcm:47570,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 10:39:49 10:52 ~ Kent Sounder Station - Bay 3(57453) ~ Walk 2m2s ~ Kent Sounder Station - Bay 9(57459) ~ BUS 165 11:07 11:44 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m49s -57,1,01:21:48,7042,1267,11:07:01,12:28:49,Metro Transit,BUS,160|165,kcm:57915|kcm:57453|kcm:57459|kcm:47570,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 11:09:49 11:22 ~ Kent Sounder Station - Bay 3(57453) ~ Walk 2m2s ~ Kent Sounder Station - Bay 9(57459) ~ BUS 165 11:37 12:17 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m49s -58,2,00:58:29,5511,275,10:06:25,11:04:54,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|A Line|Hyde Shuttle,pudget-sound-educational:area_622|kcm:60750|kcm:60752|sound-generations:area_551,pudget-sound-educational:area_622(area_622) ~ BUS null 10:06:25 10:28:19Walk 1m9s ~ Pacific Hwy S & S 272nd St(60750) ~ BUS A Line 10:31:28 10:32:02 ~ Pacific Hwy S & S 268th St(60752) ~ Walk 2m40s ~ sound-generations:area_551(area_551) ~ BUS null 10:36:42 11:04:54 -58,2,00:58:42,5459,187,10:06:25,11:05:07,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|A Line|Hyde Shuttle,pudget-sound-educational:area_622|kcm:60750|kcm:48949|sound-generations:area_551,pudget-sound-educational:area_622(area_622) ~ BUS null 10:06:25 10:28:19Walk 1m9s ~ Pacific Hwy S & S 272nd St(60750) ~ BUS A Line 10:31:28 10:37:16 ~ Pacific Hwy S & S 240th St(48949) ~ Walk 1m26s ~ sound-generations:area_551(area_551) ~ BUS null 10:40:42 11:05:07 -58,2,00:59:17,5423,88,10:06:25,11:05:42,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|A Line|Hyde Shuttle,pudget-sound-educational:area_622|kcm:60750|kcm:60810|sound-generations:area_551,pudget-sound-educational:area_622(area_622) ~ BUS null 10:06:25 10:28:19Walk 1m9s ~ Pacific Hwy S & S 272nd St(60750) ~ BUS A Line 10:31:28 10:40:38 ~ Pacific Hwy S & S 224th St(60810) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:42:38 11:05:42 -59,1,01:10:07,6841,1967,10:06:44,11:16:51,Metro Transit,BUS,160|165,kcm:57915|kcm:57453|kcm:57459|kcm:50480,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 10:09:32 10:21 ~ Kent Sounder Station - Bay 3(57453) ~ Walk 2m2s ~ Kent Sounder Station - Bay 9(57459) ~ BUS 165 10:37 10:55:38 ~ Pacific Hwy S & Kent Des Moines Rd(50480) ~ Walk 21m13s -59,2,01:17:02,7684,1717,10:11:08,11:28:10,Metro Transit|Sound Transit,BUS,160|578|A Line,kcm:58255|kcm:57784|pierce-transit:8770|pierce-transit:7910|kcm:80438|kcm:60810,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 10:13:55 10:25 ~ 2nd St SW & A St SW(57784) ~ Walk 1m10s ~ Auburn Station - Bay 3(8770) ~ BUS 578 10:34 10:46 ~ Federal Way TC - Bay 7(7910) ~ Walk 1m15s ~ Federal Way TC - Bay 8(80438) ~ BUS A Line 10:50 11:10:38 ~ Pacific Hwy S & S 224th St(60810) ~ Walk 17m32s -59,1,01:09:50,6824,1967,10:37:01,11:46:51,Metro Transit,BUS,160|165,kcm:57915|kcm:57453|kcm:57459|kcm:50480,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 10:39:49 10:52 ~ Kent Sounder Station - Bay 3(57453) ~ Walk 2m2s ~ Kent Sounder Station - Bay 9(57459) ~ BUS 165 11:07 11:25:38 ~ Pacific Hwy S & Kent Des Moines Rd(50480) ~ Walk 21m13s -60,2,00:40:44,4310,88,10:06:25,10:47:09,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|A Line|Hyde Shuttle,pudget-sound-educational:area_622|kcm:60750|kcm:60800|sound-generations:area_551,pudget-sound-educational:area_622(area_622) ~ BUS null 10:06:25 10:28:19Walk 1m9s ~ Pacific Hwy S & S 272nd St(60750) ~ BUS A Line 10:31:28 10:39 ~ Pacific Hwy S & Kent Des Moines Rd(60800) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:41 10:47:09 -60,1,00:41:47,4711,1358,10:06:44,10:48:31,Metro Transit|Sound Generations,BUS,160|Hyde Shuttle,kcm:57915|kcm:57990|sound-generations:area_558,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 10:09:32 10:17:01 ~ Central Ave S & S 259th St(57990) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 10:19:01 10:33:39Walk 14m52s -60,2,00:40:44,4310,88,10:16:25,10:57:09,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|A Line|Hyde Shuttle,pudget-sound-educational:area_622|kcm:60750|kcm:60800|sound-generations:area_551,pudget-sound-educational:area_622(area_622) ~ BUS null 10:16:25 10:38:19Walk 1m9s ~ Pacific Hwy S & S 272nd St(60750) ~ BUS A Line 10:41:28 10:49 ~ Pacific Hwy S & Kent Des Moines Rd(60800) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:51 10:57:09 -61,1,00:47:43,4473,550,10:26:08,11:13:51,Metro Transit,BUS,160|181,kcm:58255|kcm:57784|kcm:57775|kcm:83784,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 10:28:55 10:40 ~ 2nd St SW & A St SW(57784) ~ Walk 1m12s ~ Auburn Transit Center - Bay 3(57775) ~ BUS 181 10:44 11:10:35 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -61,2,01:00:46,5967,710,10:41:08,11:41:54,Metro Transit|Sound Transit,BUS,160|578|187,kcm:58255|kcm:57784|pierce-transit:8770|pierce-transit:7910|kcm:80433|kcm:83784,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 10:43:55 10:55 ~ 2nd St SW & A St SW(57784) ~ Walk 1m10s ~ Auburn Station - Bay 3(8770) ~ BUS 578 11:04 11:16 ~ Federal Way TC - Bay 7(7910) ~ Walk 2m22s ~ Federal Way TC - Bay 3(80433) ~ BUS 187 11:32 11:38:38 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -61,1,01:03:19,5409,550,10:41:08,11:44:27,Metro Transit,BUS,160|181,kcm:58255|kcm:57784|kcm:57775|kcm:83784,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 10:43:55 10:55 ~ 2nd St SW & A St SW(57784) ~ Walk 1m12s ~ Auburn Transit Center - Bay 3(57775) ~ BUS 181 11:14 11:41:11 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -62,1,00:31:50,3302,254,10:10:04,10:41:54,Metro Transit|Puget Sound Educational Service District,BUS,Road to Independence|187,pudget-sound-educational:area_622|kcm:60640|kcm:83784,pudget-sound-educational:area_622(area_622) ~ BUS null 10:10:04 10:32:51Walk 0s ~ S 320th St & 20th Ave S(60640) ~ BUS 187 10:34:51 10:38:38 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -62,1,00:32:23,3335,254,10:11:28,10:43:51,Metro Transit|Puget Sound Educational Service District,BUS,Road to Independence|181,pudget-sound-educational:area_622|kcm:60638|kcm:83784,pudget-sound-educational:area_622(area_622) ~ BUS null 10:11:28 10:33:23Walk 0s ~ S 320th St & 23rd Ave S(60638) ~ BUS 181 10:35:23 10:40:35 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -62,1,00:38:16,3820,433,10:22:01,11:00:17,Metro Transit|Puget Sound Educational Service District,BUS,160|Road to Independence,kcm:57915|kcm:57950|pudget-sound-educational:area_622,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 10:24:49 10:28:17 ~ Auburn Way N & S 277th St(57950) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:30:17 10:57:31Walk 2m46s -63,2,01:55:16,9112,546,10:06:44,12:02:00,Metro Transit,BUS,160|150|50,kcm:57915|kcm:57453|kcm:57458|kcm:99252|kcm:31871,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 10:09:32 10:21 ~ Kent Sounder Station - Bay 3(57453) ~ Walk 1m24s ~ Kent Sounder Station - Bay 8(57458) ~ BUS 150 10:32 11:17 ~ SODO Busway & S Spokane St(99252) ~ BUS 50 11:32:28 11:58:35 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -63,3,01:46:07,9735,1278,10:26:08,12:12:15,Metro Transit|Sound Transit,BUS|RAIL,160|S Line|C Line|128,kcm:58255|kcm:57784|sound-transit:S_AU_NB|sound-transit:S_KS|kcm:1562|kcm:20041|kcm:32011|kcm:31871,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 10:28:55 10:40 ~ 2nd St SW & A St SW(57784) ~ Walk 2m5s ~ Auburn Station (Northbound)(S_AU_NB) ~ RAIL S Line 10:48 11:22 ~ King Street Station(S_KS) ~ Walk 9m13s ~ Alaskan Way S & S Jackson St(1562) ~ BUS C Line 11:38:40 11:58 ~ SW Alaska St & California Ave SW - Bay 3(20041) ~ Walk 42s ~ SW Alaska St & 44th Ave SW - Bay 4(32011) ~ BUS 128 12:05 12:08:50 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -63,2,01:47:45,9907,2196,10:26:08,12:13:53,Metro Transit|Sound Transit,BUS|RAIL,160|S Line|C Line,kcm:58255|kcm:57784|sound-transit:S_AU_NB|sound-transit:S_KS|kcm:1562|kcm:20041,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 10:28:55 10:40 ~ 2nd St SW & A St SW(57784) ~ Walk 2m5s ~ Auburn Station (Northbound)(S_AU_NB) ~ RAIL S Line 10:48 11:22 ~ King Street Station(S_KS) ~ Walk 9m13s ~ Alaskan Way S & S Jackson St(1562) ~ BUS C Line 11:38:40 11:58 ~ SW Alaska St & California Ave SW - Bay 3(20041) ~ Walk 15m53s -65,2,01:03:01,6196,835,10:26:08,11:29:09,Metro Transit|Pierce Transit|Sound Transit,BUS,160|578|425,kcm:58255|kcm:57784|pierce-transit:18728|pierce-transit:10401|pierce-transit:26645|pierce-transit:1332,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 10:28:55 10:40 ~ 2nd St SW & A St SW(57784) ~ Walk 1m29s ~ Auburn Station - Bay 4(18728) ~ BUS 578 10:47 11:14 ~ Puyallup Station - Bay 3(10401) ~ Walk 48s ~ Puyallup Station - Bay 2(26645) ~ BUS 425 11:19 11:23 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m9s -65,1,01:08:52,6710,1892,10:26:08,11:35:00,Metro Transit|Sound Transit,BUS,160|578,kcm:58255|kcm:57784|pierce-transit:18728|pierce-transit:10401,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 10:28:55 10:40 ~ 2nd St SW & A St SW(57784) ~ Walk 1m29s ~ Auburn Station - Bay 4(18728) ~ BUS 578 10:47 11:14 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m -65,1,01:09:10,6728,1892,10:55:50,12:05:00,Metro Transit|Sound Transit,BUS,160|578,kcm:58255|kcm:57784|pierce-transit:18728|pierce-transit:10401,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 10:58:37 11:11 ~ 2nd St SW & A St SW(57784) ~ Walk 1m29s ~ Auburn Station - Bay 4(18728) ~ BUS 578 11:17 11:44 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m -66,1,00:32:54,3333,213,10:06:44,10:39:38,Metro Transit|Puget Sound Educational Service District,BUS,160|Road to Independence,kcm:57915|kcm:57950|pudget-sound-educational:area_622,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 10:09:32 10:12:47 ~ Auburn Way N & S 277th St(57950) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:14:47 10:39:38 -66,1,00:33:36,3375,212,10:11:08,10:44:44,Metro Transit|Puget Sound Educational Service District,BUS,160|Road to Independence,kcm:58255|kcm:57901|pudget-sound-educational:area_622,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 10:13:55 10:18 ~ Auburn Way N & 15th St NE(57901) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:20 10:44:44 -66,2,00:36:13,3975,0,10:14:52,10:51:05,Pierce Transit|Puget Sound Educational Service District,BUS,Road to Independence|402|Road to Independence,pudget-sound-educational:area_622|pierce-transit:13268|pierce-transit:1010|pudget-sound-educational:area_622,pudget-sound-educational:area_622(area_622) ~ BUS null 10:14:52 10:38Walk 0s ~ Meridian N & Spencer(13268) ~ BUS 402 10:40 10:41 ~ Meridian N & Valley Ave E(1010) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:43 10:51:05 -67,4,03:46:40,17251,880,10:11:08,13:57:48,Metro Transit|Sound Transit,BUS,160|578|545|224|629,kcm:58255|kcm:57784|pierce-transit:8770|pierce-transit:13217|kcm:700|kcm:72488|kcm:68803|kcm:64397,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 10:13:55 10:25 ~ 2nd St SW & A St SW(57784) ~ Walk 1m10s ~ Auburn Station - Bay 3(8770) ~ BUS 578 10:34 11:19 ~ 4th Ave & Pike St(13217) ~ Walk 1m11s ~ 4th Ave & Pike St(700) ~ BUS 545 11:26 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -67,3,03:02:07,14126,1098,11:10:33,14:12:40,Metro Transit|Sound Transit,BUS,160|578|554|208,kcm:58255|kcm:57784|pierce-transit:8770|pierce-transit:13217|kcm:280|kcm:64590|kcm:64593|kcm:64399,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 11:13:20 11:26 ~ 2nd St SW & A St SW(57784) ~ Walk 1m10s ~ Auburn Station - Bay 3(8770) ~ BUS 578 11:36 12:21 ~ 4th Ave & Pike St(13217) ~ Walk 4m17s ~ 2nd Ave & Stewart St(280) ~ BUS 554 12:37:53 13:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 13:30 14:06:59 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -68,4,03:37:46,16578,700,10:20:02,13:57:48,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS,Road to Independence|578|545|224|629,pudget-sound-educational:area_622|pierce-transit:7910|pierce-transit:13217|kcm:700|kcm:72488|kcm:68803|kcm:64397,pudget-sound-educational:area_622(area_622) ~ BUS null 10:20:02 10:42:20Walk 1m40s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 10:46 11:19 ~ 4th Ave & Pike St(13217) ~ Walk 1m11s ~ 4th Ave & Pike St(700) ~ BUS 545 11:26 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -68,3,02:50:38,13298,918,11:22:02,14:12:40,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS,Road to Independence|578|554|208,pudget-sound-educational:area_622|pierce-transit:7910|pierce-transit:13217|kcm:280|kcm:64590|kcm:64593|kcm:64399,pudget-sound-educational:area_622(area_622) ~ BUS null 11:22:02 11:44:20Walk 1m40s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 11:48 12:21 ~ 4th Ave & Pike St(13217) ~ Walk 4m17s ~ 2nd Ave & Stewart St(280) ~ BUS 554 12:37:53 13:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 13:30 14:06:59 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -69,2,01:42:30,8465,704,10:11:08,11:53:38,Metro Transit|Sound Transit,BUS,160|578|3,kcm:58255|kcm:57784|pierce-transit:8770|pierce-transit:13217|kcm:575|kcm:41350,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 10:13:55 10:25 ~ 2nd St SW & A St SW(57784) ~ Walk 1m10s ~ Auburn Station - Bay 3(8770) ~ BUS 578 10:34 11:19 ~ 4th Ave & Pike St(13217) ~ Walk 2m32s ~ 3rd Ave & Pike St(575) ~ BUS 3 11:28 11:50:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -69,2,01:42:30,8972,1403,10:26:08,12:08:38,Metro Transit|Sound Transit,BUS|RAIL,160|S Line|3,kcm:58255|kcm:57784|sound-transit:S_AU_NB|sound-transit:S_KS|kcm:1540|kcm:41350,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 10:28:55 10:40 ~ 2nd St SW & A St SW(57784) ~ Walk 2m5s ~ Auburn Station (Northbound)(S_AU_NB) ~ RAIL S Line 10:48 11:22 ~ King Street Station(S_KS) ~ Walk 11m5s ~ James St & 5th Ave(1540) ~ BUS 3 11:36 12:05:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -69,2,01:42:30,8465,704,10:41:08,12:23:38,Metro Transit|Sound Transit,BUS,160|578|3,kcm:58255|kcm:57784|pierce-transit:8770|pierce-transit:13217|kcm:575|kcm:41350,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 10:43:55 10:55 ~ 2nd St SW & A St SW(57784) ~ Walk 1m10s ~ Auburn Station - Bay 3(8770) ~ BUS 578 11:04 11:49 ~ 4th Ave & Pike St(13217) ~ Walk 2m32s ~ 3rd Ave & Pike St(575) ~ BUS 3 11:58 12:20:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -71,2,01:24:55,7192,408,10:06:44,11:31:39,Metro Transit|Sound Transit,BUS|TRAM,160|150|1-Line,kcm:57915|kcm:57453|kcm:57458|kcm:99254|sound-transit:99111|sound-transit:99121,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 10:09:32 10:21 ~ Kent Sounder Station - Bay 3(57453) ~ Walk 1m24s ~ Kent Sounder Station - Bay 8(57458) ~ BUS 150 10:32 11:19:40 ~ SODO Busway & S Lander St(99254) ~ Walk 49s ~ SODO Station(99111) ~ TRAM 1-Line 11:28 11:31 ~ Beacon Hill Station(99121) ~ Walk 39s -71,2,01:19:38,6875,408,10:22:01,11:41:39,Metro Transit|Sound Transit,BUS|TRAM,160|150|1-Line,kcm:57915|kcm:57453|kcm:57458|kcm:99254|sound-transit:99111|sound-transit:99121,Walk 2m48s ~ Auburn Way N & 37th St NE(57915) ~ BUS 160 10:24:49 10:37 ~ Kent Sounder Station - Bay 3(57453) ~ Walk 1m24s ~ Kent Sounder Station - Bay 8(57458) ~ BUS 150 10:47 11:34:40 ~ SODO Busway & S Lander St(99254) ~ Walk 49s ~ SODO Station(99111) ~ TRAM 1-Line 11:38 11:41 ~ Beacon Hill Station(99121) ~ Walk 39s -71,2,01:15:31,7239,1237,10:26:08,11:41:39,Metro Transit|Sound Transit,BUS|RAIL|TRAM,160|S Line|1-Line,kcm:58255|kcm:57784|sound-transit:S_AU_NB|sound-transit:S_KS|sound-transit:99101|sound-transit:99121,Walk 2m47s ~ Auburn Way N & 37th St NE(58255) ~ BUS 160 10:28:55 10:40 ~ 2nd St SW & A St SW(57784) ~ Walk 2m5s ~ Auburn Station (Northbound)(S_AU_NB) ~ RAIL S Line 10:48 11:22 ~ King Street Station(S_KS) ~ Walk 11m18s ~ Stadium Station(99101) ~ TRAM 1-Line 11:36 11:41 ~ Beacon Hill Station(99121) ~ Walk 39s -72,2,01:09:06,6049,138,10:02:33,11:11:39,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS|TRAM,Road to Independence|150|1-Line,pudget-sound-educational:area_622|kcm:59773|kcm:99254|sound-transit:99111|sound-transit:99121,pudget-sound-educational:area_622(area_622) ~ BUS null 10:02:33 10:17:31Walk 27s ~ W James St & Lincoln Ave N(59773) ~ BUS 150 10:19:58 11:04:40 ~ SODO Busway & S Lander St(99254) ~ Walk 49s ~ SODO Station(99111) ~ TRAM 1-Line 11:08 11:11 ~ Beacon Hill Station(99121) ~ Walk 39s -72,2,01:20:04,6947,474,10:06:25,11:26:29,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS|TRAM,Road to Independence|A Line|1-Line,pudget-sound-educational:area_622|kcm:60750|kcm:60850|sound-transit:99914|sound-transit:99240,pudget-sound-educational:area_622(area_622) ~ BUS null 10:06:25 10:28:19Walk 1m9s ~ Pacific Hwy S & S 272nd St(60750) ~ BUS A Line 10:31:28 10:45:46 ~ International Blvd & S 200th St(60850) ~ Walk 4m23s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:56 11:25 ~ Beacon Hill Station(99240) ~ Walk 1m29s -72,1,01:27:20,7716,1764,10:02:33,11:29:53,Metro Transit|Puget Sound Educational Service District,BUS,Road to Independence|150,pudget-sound-educational:area_622|kcm:59773|kcm:99264,pudget-sound-educational:area_622(area_622) ~ BUS null 10:02:33 10:17:31Walk 27s ~ W James St & Lincoln Ave N(59773) ~ BUS 150 10:19:58 11:06:45 ~ SODO Busway & S Holgate St(99264) ~ Walk 23m8s -73,1,01:30:16,7950,1790,10:24:17,11:54:33,Metro Transit,BUS,181|160,kcm:83706|kcm:57774|kcm:57185,Walk 4m38s ~ S 320th St & 1st Ave S(83706) ~ BUS 181 10:28:55 10:55 ~ Auburn Transit Center - Bay 2(57774) ~ BUS 160 10:58 11:36:08 ~ 108th Ave SE & SE 220th Pl(57185) ~ Walk 18m25s -73,2,01:52:11,11453,3963,10:32:22,12:24:33,Metro Transit,BUS,A Line|165|160,kcm:60660|kcm:48949|kcm:48950|kcm:57127|kcm:57130|kcm:57185,Walk 30m30s ~ Pacific Hwy S & S 316th St(60660) ~ BUS A Line 11:02:52 11:17:16 ~ Pacific Hwy S & S 240th St(48949) ~ Walk 56s ~ Pacific Hwy S & S 240th St(48950) ~ BUS 165 11:20:30 11:51 ~ SE 240th St & 104th Ave SE(57127) ~ Walk 1m45s ~ 104th Ave SE & SE 240th St(57130) ~ BUS 160 12:01:23 12:06:08 ~ 108th Ave SE & SE 220th Pl(57185) ~ Walk 18m25s -73,1,01:54:12,11794,5067,10:32:22,12:26:34,Metro Transit,BUS,A Line|165,kcm:60660|kcm:48949|kcm:48950|kcm:57141,Walk 30m30s ~ Pacific Hwy S & S 316th St(60660) ~ BUS A Line 11:02:52 11:17:16 ~ Pacific Hwy S & S 240th St(48949) ~ Walk 56s ~ Pacific Hwy S & S 240th St(48950) ~ BUS 165 11:20:30 11:52:44 ~ SE 240th St & 116th Ave SE(57141) ~ Walk 33m50s -74,2,00:46:15,4743,220,10:02:16,10:48:31,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|183|Hyde Shuttle,pudget-sound-educational:area_622|kcm:53050|kcm:50709|sound-generations:area_558,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:05:02 10:20:23Walk 0s ~ Military Rd S & S 272nd St(53050) ~ BUS 183 10:22:23 10:28:58 ~ Reith Rd & Lake Fenwick Rd S(50709) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 10:30:58 10:48:31 -74,2,00:50:20,4988,220,10:05:04,10:55:24,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|183|Hyde Shuttle,pudget-sound-educational:area_622|kcm:58785|kcm:50779|sound-generations:area_558,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:07:50 10:27:43Walk 0s ~ W Meeker St & Frager Rd(58785) ~ BUS 183 10:29:43 10:33:54 ~ W James St & 64th Ave S(50779) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 10:35:54 10:55:24 -74,2,00:45:23,4691,220,10:13:59,10:59:22,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|183|Hyde Shuttle,pudget-sound-educational:area_622|kcm:58781|kcm:50781|sound-generations:area_558,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:16:45 10:36:48Walk 0s ~ W Meeker St & Frager Rd(58781) ~ BUS 183 10:38:48 10:39:48 ~ Reith Rd & Lake Fenwick Rd S(50781) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 10:41:48 10:59:22 -75,1,01:23:27,8713,3408,10:02:22,11:25:49,Metro Transit,BUS,A Line|165,kcm:60660|kcm:48949|kcm:61180|kcm:47570,Walk 30m30s ~ Pacific Hwy S & S 316th St(60660) ~ BUS A Line 10:32:52 10:47:16 ~ Pacific Hwy S & S 240th St(48949) ~ Walk 2m7s ~ Pacific Hwy S & S 240th St(61180) ~ BUS 165 10:57:37 11:14 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m49s -75,2,01:24:06,8942,2885,10:24:17,11:48:23,Metro Transit,BUS,181|A Line|156,kcm:83706|kcm:80438|kcm:60830|kcm:47403|kcm:49190,Walk 4m38s ~ S 320th St & 1st Ave S(83706) ~ BUS 181 10:28:55 10:36 ~ Federal Way TC - Bay 8(80438) ~ BUS A Line 10:40 11:02:22 ~ International Blvd & S 216th St(60830) ~ Walk 6m18s ~ S 216th St & 24th Ave S(47403) ~ BUS 156 11:11 11:21:04 ~ 8th Ave S & Des Moines Memorial Dr S(49190) ~ Walk 27m19s -75,1,01:36:01,10501,4862,10:12:22,11:48:23,Metro Transit,BUS,A Line|156,kcm:60660|kcm:60830|kcm:47403|kcm:49190,Walk 30m30s ~ Pacific Hwy S & S 316th St(60660) ~ BUS A Line 10:42:52 11:02:22 ~ International Blvd & S 216th St(60830) ~ Walk 6m18s ~ S 216th St & 24th Ave S(47403) ~ BUS 156 11:11 11:21:04 ~ 8th Ave S & Des Moines Memorial Dr S(49190) ~ Walk 27m19s -76,2,00:50:32,5125,395,10:02:33,10:53:05,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|A Line|Hyde Shuttle,pudget-sound-educational:area_622|kcm:60670|kcm:60750|sound-generations:area_551,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:05:19 10:12Walk 0s ~ Pacific Hwy S & S 312th St(60670) ~ BUS A Line 10:14 10:21:28 ~ Pacific Hwy S & S 272nd St(60750) ~ Walk 2m23s ~ sound-generations:area_551(area_551) ~ BUS null 10:25:51 10:53:05 -76,2,00:50:32,5125,395,10:12:33,11:03:05,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|A Line|Hyde Shuttle,pudget-sound-educational:area_622|kcm:60670|kcm:60750|sound-generations:area_551,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:15:19 10:22Walk 0s ~ Pacific Hwy S & S 312th St(60670) ~ BUS A Line 10:24 10:31:28 ~ Pacific Hwy S & S 272nd St(60750) ~ Walk 2m23s ~ sound-generations:area_551(area_551) ~ BUS null 10:35:51 11:03:05 -76,2,00:50:32,5125,395,10:22:33,11:13:05,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|A Line|Hyde Shuttle,pudget-sound-educational:area_622|kcm:60670|kcm:60750|sound-generations:area_551,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:25:19 10:32Walk 0s ~ Pacific Hwy S & S 312th St(60670) ~ BUS A Line 10:34 10:41:28 ~ Pacific Hwy S & S 272nd St(60750) ~ Walk 2m23s ~ sound-generations:area_551(area_551) ~ BUS null 10:45:51 11:13:05 -77,0,01:05:48,7247,3678,10:02:22,11:08:10,Metro Transit,BUS,A Line,kcm:60660|kcm:60810,Walk 30m30s ~ Pacific Hwy S & S 316th St(60660) ~ BUS A Line 10:32:52 10:50:38 ~ Pacific Hwy S & S 224th St(60810) ~ Walk 17m32s -77,1,00:53:53,5688,1701,10:24:17,11:18:10,Metro Transit,BUS,181|A Line,kcm:83706|kcm:80438|kcm:60810,Walk 4m38s ~ S 320th St & 1st Ave S(83706) ~ BUS 181 10:28:55 10:36 ~ Federal Way TC - Bay 8(80438) ~ BUS A Line 10:40 11:00:38 ~ Pacific Hwy S & S 224th St(60810) ~ Walk 17m32s -77,0,01:05:48,7247,3678,10:12:22,11:18:10,Metro Transit,BUS,A Line,kcm:60660|kcm:60810,Walk 30m30s ~ Pacific Hwy S & S 316th St(60660) ~ BUS A Line 10:42:52 11:00:38 ~ Pacific Hwy S & S 224th St(60810) ~ Walk 17m32s -78,2,00:34:36,4044,220,10:02:33,10:37:09,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|A Line|Hyde Shuttle,pudget-sound-educational:area_622|kcm:60670|kcm:60800|sound-generations:area_551,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:05:19 10:12Walk 0s ~ Pacific Hwy S & S 312th St(60670) ~ BUS A Line 10:14 10:29 ~ Pacific Hwy S & Kent Des Moines Rd(60800) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:31 10:37:09 -78,2,00:34:36,4044,220,10:12:33,10:47:09,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|A Line|Hyde Shuttle,pudget-sound-educational:area_622|kcm:60670|kcm:60800|sound-generations:area_551,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:15:19 10:22Walk 0s ~ Pacific Hwy S & S 312th St(60670) ~ BUS A Line 10:24 10:39 ~ Pacific Hwy S & Kent Des Moines Rd(60800) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:41 10:47:09 -78,1,00:45:37,5087,1559,10:02:33,10:48:10,Metro Transit|Puget Sound Educational Service District,BUS,Road to Independence|A Line,pudget-sound-educational:area_622|kcm:60670|kcm:60810,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:05:19 10:12Walk 0s ~ Pacific Hwy S & S 312th St(60670) ~ BUS A Line 10:14 10:30:38 ~ Pacific Hwy S & S 224th St(60810) ~ Walk 17m32s -79,1,00:48:20,4530,575,10:24:17,11:12:37,Metro Transit,BUS,181|160,kcm:83706|kcm:57774|kcm:57915,Walk 4m38s ~ S 320th St & 1st Ave S(83706) ~ BUS 181 10:28:55 10:55 ~ Auburn Transit Center - Bay 2(57774) ~ BUS 160 10:58 11:09:49 ~ Auburn Way N & 37th St NE(57915) ~ Walk 2m48s -79,1,01:03:20,5430,575,10:54:17,11:57:37,Metro Transit,BUS,181|160,kcm:83706|kcm:57774|kcm:57915,Walk 4m38s ~ S 320th St & 1st Ave S(83706) ~ BUS 181 10:58:55 11:27 ~ Auburn Transit Center - Bay 2(57774) ~ BUS 160 11:43 11:54:49 ~ Auburn Way N & 37th St NE(57915) ~ Walk 2m48s -79,2,01:12:20,6650,679,10:59:17,12:11:37,Metro Transit|Sound Transit,BUS,187|578|160,kcm:83706|kcm:80433|pierce-transit:4136|pierce-transit:18728|kcm:57774|kcm:57915,Walk 4m38s ~ S 320th St & 1st Ave S(83706) ~ BUS 187 11:03:55 11:10 ~ Federal Way TC - Bay 3(80433) ~ Walk 37s ~ Federal Way TC - Bay 2(4136) ~ BUS 578 11:32 11:49 ~ Auburn Station - Bay 4(18728) ~ Walk 44s ~ Auburn Transit Center - Bay 2(57774) ~ BUS 160 11:57 12:08:49 ~ Auburn Way N & 37th St NE(57915) ~ Walk 2m48s -80,2,00:35:50,4118,220,10:03:45,10:39:35,Pierce Transit|Puget Sound Educational Service District,BUS,Road to Independence|402|Road to Independence,pudget-sound-educational:area_622|pierce-transit:1797|pierce-transit:1004|pudget-sound-educational:area_622,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:06:31 10:15Walk 0s ~ Pacific Hwy & S 336th St(1797) ~ BUS 402 10:17 10:20 ~ Enchanted Pkwy & S 352nd(1004) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:22 10:39:35 -80,1,00:34:47,3479,254,10:07:19,10:42:06,Metro Transit|Puget Sound Educational Service District,BUS,181|Road to Independence,kcm:83784|kcm:83711|pudget-sound-educational:area_622,Walk 3m16s ~ SW 320th St & 1st Ave S(83784) ~ BUS 181 10:10:35 10:11:10 ~ SW 320th St & 3rd Pl SW(83711) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:13:10 10:42:06 -80,2,00:43:58,4670,308,10:12:33,10:56:31,Metro Transit|Puget Sound Educational Service District,BUS,Road to Independence|A Line|Road to Independence,pudget-sound-educational:area_622|kcm:60670|kcm:60750|pudget-sound-educational:area_622,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:15:19 10:22Walk 0s ~ Pacific Hwy S & S 312th St(60670) ~ BUS A Line 10:24 10:31:28 ~ Pacific Hwy S & S 272nd St(60750) ~ Walk 1m9s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:34:37 10:56:31 -81,3,01:47:58,9555,922,10:24:17,12:12:15,Metro Transit|Sound Transit,BUS,181|578|C Line|128,kcm:83706|kcm:80438|pierce-transit:7910|pierce-transit:13217|kcm:431|kcm:20041|kcm:32011|kcm:31871,Walk 4m38s ~ S 320th St & 1st Ave S(83706) ~ BUS 181 10:28:55 10:36 ~ Federal Way TC - Bay 8(80438) ~ Walk 1m15s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 10:46 11:19 ~ 4th Ave & Pike St(13217) ~ Walk 2m36s ~ 3rd Ave & Pike St(431) ~ BUS C Line 11:33 11:58 ~ SW Alaska St & California Ave SW - Bay 3(20041) ~ Walk 42s ~ SW Alaska St & 44th Ave SW - Bay 4(32011) ~ BUS 128 12:05 12:08:50 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -81,1,02:04:39,11789,4236,10:09:14,12:13:53,Metro Transit|Sound Transit,BUS,578|C Line,pierce-transit:7910|pierce-transit:13217|kcm:431|kcm:20041,Walk 36m46s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 10:46 11:19 ~ 4th Ave & Pike St(13217) ~ Walk 2m36s ~ 3rd Ave & Pike St(431) ~ BUS C Line 11:33 11:58 ~ SW Alaska St & California Ave SW - Bay 3(20041) ~ Walk 15m53s -81,1,02:19:53,11605,2694,10:12:22,12:32:15,Metro Transit,BUS,A Line|128,kcm:60660|kcm:60921|kcm:60923|kcm:31871,Walk 30m30s ~ Pacific Hwy S & S 316th St(60660) ~ BUS A Line 10:42:52 11:20 ~ Tukwila International Blvd Station - Bay 1(60921) ~ Walk 2m28s ~ Tukwila International Blvd Station - Bay 3(60923) ~ BUS 128 11:32 12:28:50 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -83,2,01:28:48,8640,2051,10:00:21,11:29:09,Metro Transit|Pierce Transit|Sound Transit,BUS,903|578|425,kcm:60646|kcm:80439|pierce-transit:4136|pierce-transit:10401|pierce-transit:26645|pierce-transit:1332,Walk 19m4s ~ S 333rd St & 1st Way S(60646) ~ BUS 903 10:19:25 10:28 ~ Federal Way TC - Bay 9(80439) ~ Walk 1m ~ Federal Way TC - Bay 2(4136) ~ BUS 578 10:31 11:14 ~ Puyallup Station - Bay 3(10401) ~ Walk 48s ~ Puyallup Station - Bay 2(26645) ~ BUS 425 11:19 11:23 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m9s -83,1,01:34:39,9153,3108,10:00:21,11:35:00,Metro Transit|Sound Transit,BUS,903|578,kcm:60646|kcm:80439|pierce-transit:4136|pierce-transit:10401,Walk 19m4s ~ S 333rd St & 1st Way S(60646) ~ BUS 903 10:19:25 10:28 ~ Federal Way TC - Bay 9(80439) ~ Walk 1m ~ Federal Way TC - Bay 2(4136) ~ BUS 578 10:31 11:14 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m -83,1,01:01:52,5891,1322,10:54:17,11:56:09,Metro Transit|Pierce Transit,BUS,181|402,kcm:83706|kcm:61330|pierce-transit:1792|pierce-transit:1332,Walk 4m38s ~ S 320th St & 1st Ave S(83706) ~ BUS 181 10:58:55 11:02:47 ~ S 320th St & Pacific Hwy S(61330) ~ Walk 6m31s ~ Pacific Hwy & S 324th St(1792) ~ BUS 402 11:14 11:50 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m9s -84,2,00:41:39,4467,220,10:03:45,10:45:24,Pierce Transit|Puget Sound Educational Service District,BUS,Road to Independence|402|Road to Independence,pudget-sound-educational:area_622|pierce-transit:1797|pierce-transit:1004|pudget-sound-educational:area_622,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:06:31 10:15Walk 0s ~ Pacific Hwy & S 336th St(1797) ~ BUS 402 10:17 10:20 ~ Enchanted Pkwy & S 352nd(1004) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:22 10:45:24 -84,1,00:40:36,3828,254,10:07:19,10:47:55,Metro Transit|Puget Sound Educational Service District,BUS,181|Road to Independence,kcm:83784|kcm:83711|pudget-sound-educational:area_622,Walk 3m16s ~ SW 320th St & 1st Ave S(83784) ~ BUS 181 10:10:35 10:11:10 ~ SW 320th St & 3rd Pl SW(83711) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:13:10 10:47:55 -84,2,00:46:27,4755,220,10:13:33,11:00:00,Pierce Transit|Puget Sound Educational Service District,BUS,Road to Independence|409|Road to Independence,pudget-sound-educational:area_622|pierce-transit:326261448|pierce-transit:1133|pudget-sound-educational:area_622,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:16:19 10:46Walk 0s ~ 29th St NE & 5th Ave NE(326261448) ~ BUS 409 10:48 10:49 ~ Main Ave E & 15th St SE(1133) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:51 11:00 -85,4,03:33:31,16578,1034,10:24:17,13:57:48,Metro Transit|Sound Transit,BUS,181|578|545|224|629,kcm:83706|kcm:80438|pierce-transit:7910|pierce-transit:13217|kcm:700|kcm:72488|kcm:68803|kcm:64397,Walk 4m38s ~ S 320th St & 1st Ave S(83706) ~ BUS 181 10:28:55 10:36 ~ Federal Way TC - Bay 8(80438) ~ Walk 1m15s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 10:46 11:19 ~ 4th Ave & Pike St(13217) ~ Walk 1m11s ~ 4th Ave & Pike St(700) ~ BUS 545 11:26 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -85,3,03:48:34,18639,3430,10:09:14,13:57:48,Metro Transit|Sound Transit,BUS,578|545|224|629,pierce-transit:7910|pierce-transit:13217|kcm:700|kcm:72488|kcm:68803|kcm:64397,Walk 36m46s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 10:46 11:19 ~ 4th Ave & Pike St(13217) ~ Walk 1m11s ~ 4th Ave & Pike St(700) ~ BUS 545 11:26 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -85,3,02:48:23,13417,1252,11:24:17,14:12:40,Metro Transit|Sound Transit,BUS,181|578|554|208,kcm:83706|kcm:80438|pierce-transit:7910|pierce-transit:13217|kcm:280|kcm:64590|kcm:64593|kcm:64399,Walk 4m38s ~ S 320th St & 1st Ave S(83706) ~ BUS 181 11:28:55 11:36 ~ Federal Way TC - Bay 8(80438) ~ Walk 1m15s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 11:48 12:21 ~ 4th Ave & Pike St(13217) ~ Walk 4m17s ~ 2nd Ave & Stewart St(280) ~ BUS 554 12:37:53 13:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 13:30 14:06:59 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -86,4,03:26:19,16078,942,10:31:29,13:57:48,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS,Road to Independence|578|545|224|629,pudget-sound-educational:area_622|kcm:80437|pierce-transit:7910|pierce-transit:13217|kcm:700|kcm:72488|kcm:68803|kcm:64397,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:34:15 10:42:05Walk 1m42s ~ Federal Way TC - Bay 7(80437) ~ Walk 13s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 10:46 11:19 ~ 4th Ave & Pike St(13217) ~ Walk 1m11s ~ 4th Ave & Pike St(700) ~ BUS 545 11:26 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -86,3,03:48:34,18639,3430,10:09:14,13:57:48,Metro Transit|Sound Transit,BUS,578|545|224|629,pierce-transit:7910|pierce-transit:13217|kcm:700|kcm:72488|kcm:68803|kcm:64397,Walk 36m46s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 10:46 11:19 ~ 4th Ave & Pike St(13217) ~ Walk 1m11s ~ 4th Ave & Pike St(700) ~ BUS 545 11:26 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -86,3,02:39:11,12798,1160,11:33:29,14:12:40,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS,Road to Independence|578|554|208,pudget-sound-educational:area_622|kcm:80437|pierce-transit:7910|pierce-transit:13217|kcm:280|kcm:64590|kcm:64593|kcm:64399,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 11:36:15 11:44:05Walk 1m42s ~ Federal Way TC - Bay 7(80437) ~ Walk 13s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 11:48 12:21 ~ 4th Ave & Pike St(13217) ~ Walk 4m17s ~ 2nd Ave & Stewart St(280) ~ BUS 554 12:37:53 13:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 13:30 14:06:59 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -87,2,01:29:21,7792,858,10:24:17,11:53:38,Metro Transit|Sound Transit,BUS,181|578|3,kcm:83706|kcm:80438|pierce-transit:7910|pierce-transit:13217|kcm:575|kcm:41350,Walk 4m38s ~ S 320th St & 1st Ave S(83706) ~ BUS 181 10:28:55 10:36 ~ Federal Way TC - Bay 8(80438) ~ Walk 1m15s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 10:46 11:19 ~ 4th Ave & Pike St(13217) ~ Walk 2m32s ~ 3rd Ave & Pike St(575) ~ BUS 3 11:28 11:50:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -87,1,01:44:24,9854,3254,10:09:14,11:53:38,Metro Transit|Sound Transit,BUS,578|3,pierce-transit:7910|pierce-transit:13217|kcm:575|kcm:41350,Walk 36m46s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 10:46 11:19 ~ 4th Ave & Pike St(13217) ~ Walk 2m32s ~ 3rd Ave & Pike St(575) ~ BUS 3 11:28 11:50:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -87,2,01:24:21,7542,936,10:59:17,12:23:38,Metro Transit|Sound Transit,BUS,187|578|3,kcm:83706|kcm:80433|pierce-transit:7910|pierce-transit:13217|kcm:575|kcm:41350,Walk 4m38s ~ S 320th St & 1st Ave S(83706) ~ BUS 187 11:03:55 11:10 ~ Federal Way TC - Bay 3(80433) ~ Walk 2m22s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 11:16 11:49 ~ 4th Ave & Pike St(13217) ~ Walk 2m32s ~ 3rd Ave & Pike St(575) ~ BUS 3 11:58 12:20:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -89,1,01:34:07,8841,2725,10:02:22,11:36:29,Metro Transit|Sound Transit,BUS|TRAM,A Line|1-Line,kcm:60660|kcm:60850|sound-transit:99914|sound-transit:99240,Walk 30m30s ~ Pacific Hwy S & S 316th St(60660) ~ BUS A Line 10:32:52 10:55:46 ~ International Blvd & S 200th St(60850) ~ Walk 4m23s ~ Angle Lake Station(99914) ~ TRAM 1-Line 11:06 11:35 ~ Beacon Hill Station(99240) ~ Walk 1m29s -89,2,01:22:12,7282,748,10:24:17,11:46:29,Metro Transit|Sound Transit,BUS|TRAM,181|A Line|1-Line,kcm:83706|kcm:80438|kcm:60850|sound-transit:99914|sound-transit:99240,Walk 4m38s ~ S 320th St & 1st Ave S(83706) ~ BUS 181 10:28:55 10:36 ~ Federal Way TC - Bay 8(80438) ~ BUS A Line 10:40 11:05:46 ~ International Blvd & S 200th St(60850) ~ Walk 4m23s ~ Angle Lake Station(99914) ~ TRAM 1-Line 11:16 11:45 ~ Beacon Hill Station(99240) ~ Walk 1m29s -89,1,01:34:07,8841,2725,10:12:22,11:46:29,Metro Transit|Sound Transit,BUS|TRAM,A Line|1-Line,kcm:60660|kcm:60850|sound-transit:99914|sound-transit:99240,Walk 30m30s ~ Pacific Hwy S & S 316th St(60660) ~ BUS A Line 10:42:52 11:05:46 ~ International Blvd & S 200th St(60850) ~ Walk 4m23s ~ Angle Lake Station(99914) ~ TRAM 1-Line 11:16 11:45 ~ Beacon Hill Station(99240) ~ Walk 1m29s -90,2,01:13:56,6681,606,10:02:33,11:16:29,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS|TRAM,Road to Independence|A Line|1-Line,pudget-sound-educational:area_622|kcm:60670|kcm:60850|sound-transit:99914|sound-transit:99240,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:05:19 10:12Walk 0s ~ Pacific Hwy S & S 312th St(60670) ~ BUS A Line 10:14 10:35:46 ~ International Blvd & S 200th St(60850) ~ Walk 4m23s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:46 11:15 ~ Beacon Hill Station(99240) ~ Walk 1m29s -90,3,01:18:10,7644,760,10:03:29,11:21:39,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS|TRAM,Road to Independence|578|101|1-Line,pudget-sound-educational:area_622|kcm:80437|pierce-transit:7910|pierce-transit:13217|kcm:1230|kcm:99271|sound-transit:99101|sound-transit:99121,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:06:15 10:14:05Walk 1m42s ~ Federal Way TC - Bay 7(80437) ~ Walk 13s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 10:18 10:53 ~ 4th Ave & Pike St(13217) ~ Walk 3m11s ~ Union St & 4th Ave(1230) ~ BUS 101 11:02:47 11:11:44 ~ SODO Busway & S Royal Brougham Way(99271) ~ Walk 1m50s ~ Stadium Station(99101) ~ TRAM 1-Line 11:16 11:21 ~ Beacon Hill Station(99121) ~ Walk 39s -90,2,01:13:56,6681,606,10:12:33,11:26:29,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS|TRAM,Road to Independence|A Line|1-Line,pudget-sound-educational:area_622|kcm:60670|kcm:60850|sound-transit:99914|sound-transit:99240,Walk 2m46s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:15:19 10:22Walk 0s ~ Pacific Hwy S & S 312th St(60670) ~ BUS A Line 10:24 10:45:46 ~ International Blvd & S 200th St(60850) ~ Walk 4m23s ~ Angle Lake Station(99914) ~ TRAM 1-Line 10:56 11:25 ~ Beacon Hill Station(99240) ~ Walk 1m29s -91,2,01:59:45,10446,1981,10:05:53,12:05:38,Metro Transit,BUS,50|101|160,kcm:31970|kcm:99253|kcm:79610|kcm:59891|kcm:57375,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:09:01 10:33:54 ~ SODO Busway & S Spokane St(99253) ~ BUS 101 10:48 11:03 ~ SW Sunset Blvd & Hardie Ave SW(79610) ~ Walk 4m34s ~ Rainier Ave S & S 3rd Pl(59891) ~ BUS 160 11:22:49 11:47:16 ~ 108th Ave SE & SE 220th Pl(57375) ~ Walk 18m22s -91,2,01:58:45,10512,2158,10:21:53,12:20:38,Metro Transit,BUS,50|101|160,kcm:31970|kcm:99254|kcm:99263|kcm:79610|kcm:59891|kcm:57375,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:25:01 10:48 ~ SODO Busway & S Lander St(99254) ~ Walk 2m30s ~ SODO Busway & S Lander St(99263) ~ BUS 101 11:00:45 11:18 ~ SW Sunset Blvd & Hardie Ave SW(79610) ~ Walk 4m34s ~ Rainier Ave S & S 3rd Pl(59891) ~ BUS 160 11:37:22 12:02:16 ~ 108th Ave SE & SE 220th Pl(57375) ~ Walk 18m22s -91,2,01:58:45,10386,1981,10:35:53,12:34:38,Metro Transit,BUS,50|101|160,kcm:31970|kcm:99253|kcm:79610|kcm:59891|kcm:57375,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:39:01 11:03:54 ~ SODO Busway & S Spokane St(99253) ~ BUS 101 11:18 11:33 ~ SW Sunset Blvd & Hardie Ave SW(79610) ~ Walk 4m34s ~ Rainier Ave S & S 3rd Pl(59891) ~ BUS 160 11:51:22 12:16:16 ~ 108th Ave SE & SE 220th Pl(57375) ~ Walk 18m22s -92,2,01:10:03,6139,188,10:07:53,11:17:56,Metro Transit|Sound Generations,BUS,Hyde Shuttle|150|Hyde Shuttle,sound-generations:area_560|kcm:45870|kcm:99253|kcm:58134|sound-generations:area_558,sound-generations:area_560(area_560) ~ BUS null 10:07:53 10:21:25Walk 0s ~ 4th Ave S & S Spokane St(45870) ~ Walk 2m35s ~ SODO Busway & S Spokane St(99253) ~ BUS 150 10:26 10:54:35 ~ West Valley Hwy & Todd Blvd(58134) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 10:56:35 11:17:56 -92,2,01:10:03,6139,188,10:22:53,11:32:56,Metro Transit|Sound Generations,BUS,Hyde Shuttle|150|Hyde Shuttle,sound-generations:area_560|kcm:45870|kcm:99253|kcm:58134|sound-generations:area_558,sound-generations:area_560(area_560) ~ BUS null 10:22:53 10:36:25Walk 0s ~ 4th Ave S & S Spokane St(45870) ~ Walk 2m35s ~ SODO Busway & S Spokane St(99253) ~ BUS 150 10:41 11:09:35 ~ West Valley Hwy & Todd Blvd(58134) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 11:11:35 11:32:56 -92,2,01:10:03,6139,188,10:37:53,11:47:56,Metro Transit|Sound Generations,BUS,Hyde Shuttle|150|Hyde Shuttle,sound-generations:area_560|kcm:45870|kcm:99253|kcm:58134|sound-generations:area_558,sound-generations:area_560(area_560) ~ BUS null 10:37:53 10:51:25Walk 0s ~ 4th Ave S & S Spokane St(45870) ~ Walk 2m35s ~ SODO Busway & S Spokane St(99253) ~ BUS 150 10:56 11:24:35 ~ West Valley Hwy & Todd Blvd(58134) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 11:26:35 11:47:56 -93,2,01:22:43,7563,1087,10:21:53,11:44:36,Metro Transit,BUS,50|120|165,kcm:31970|kcm:21600|kcm:22010|kcm:52305|kcm:48620,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:25:01 10:36:44 ~ Delridge Way SW & SW Genesee St(21600) ~ Walk 1m12s ~ Delridge Way SW & SW Genesee St(22010) ~ BUS 120 10:48:18 11:24 ~ Burien Transit Center - Bay 5(52305) ~ BUS 165 11:27 11:34:26 ~ 1st Ave S & SW 178th St(48620) ~ Walk 10m10s -93,1,01:29:02,8787,3111,10:15:34,11:44:36,Metro Transit,BUS,120|165,kcm:21990|kcm:52305|kcm:48620,Walk 31m58s ~ Delridge Way SW & SW Andover St(21990) ~ BUS 120 10:47:32 11:24 ~ Burien Transit Center - Bay 5(52305) ~ BUS 165 11:27 11:34:26 ~ 1st Ave S & SW 178th St(48620) ~ Walk 10m10s -93,2,01:29:28,8011,1147,10:41:08,12:10:36,Metro Transit,BUS,128|120|165,kcm:31970|kcm:22160|kcm:22152|kcm:52305|kcm:48620,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 128 10:44:16 11:00 ~ SW Orchard St & Delridge Way SW(22160) ~ Walk 2m3s ~ Delridge Way SW & SW Myrtle St(22152) ~ BUS 120 11:14 11:44 ~ Burien Transit Center - Bay 5(52305) ~ BUS 165 11:53 12:00:26 ~ 1st Ave S & SW 178th St(48620) ~ Walk 10m10s -94,2,00:48:54,4736,0,10:09:43,10:58:37,Metro Transit|Sound Generations,BUS,Hyde Shuttle|128|Hyde Shuttle,sound-generations:area_560|kcm:22252|kcm:21104|sound-generations:area_551,sound-generations:area_560(area_560) ~ BUS null 10:09:43 10:31:59Walk 0s ~ Delridge Way SW & SW Henderson St(22252) ~ BUS 128 10:33:59 10:37:47 ~ 8th Ave SW & SW 99th St(21104) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:39:47 10:58:37 -94,1,00:59:53,4960,226,10:01:08,11:01:01,Metro Transit|Sound Generations,BUS,128|Hyde Shuttle,kcm:31970|kcm:49585|sound-generations:area_551,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 128 10:04:16 10:38:40 ~ 8th Ave SW & SW 102nd St(49585) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:40:40 11:01:01 -94,2,00:53:05,4987,0,10:13:02,11:06:07,Metro Transit|Sound Generations,BUS,Hyde Shuttle|132|Hyde Shuttle,sound-generations:area_560|kcm:49739|kcm:49750|sound-generations:area_551,sound-generations:area_560(area_560) ~ BUS null 10:13:02 10:39:03Walk 0s ~ 14th Ave S & S Trenton St(49739) ~ BUS 132 10:41:03 10:43:23 ~ Des Moines Memorial Dr S & S 96th St(49750) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:45:23 11:06:07 -95,1,01:41:05,8419,1524,10:01:08,11:42:13,Metro Transit,BUS,128|A Line,kcm:31970|kcm:60922|kcm:60921|kcm:61170,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 128 10:04:16 11:03 ~ Tukwila International Blvd Station - Bay 2(60922) ~ Walk 2m9s ~ Tukwila International Blvd Station - Bay 1(60921) ~ BUS A Line 11:10 11:26:17 ~ Pacific Hwy S & S 224th St(61170) ~ Walk 15m56s -95,2,01:36:20,8840,1729,10:05:53,11:42:13,Metro Transit|Sound Transit,BUS|TRAM,50|1-Line|A Line,kcm:31970|kcm:99263|sound-transit:99111|sound-transit:99913|kcm:61120|kcm:61170,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:09:01 10:32 ~ SODO Busway & S Lander St(99263) ~ Walk 2m1s ~ SODO Station(99111) ~ TRAM 1-Line 10:38 11:10 ~ Angle Lake Station(99913) ~ Walk 2m18s ~ International Blvd & S 200th St(61120) ~ BUS A Line 11:21:12 11:26:17 ~ Pacific Hwy S & S 224th St(61170) ~ Walk 15m56s -95,2,01:39:55,9149,1842,10:21:53,12:01:48,Metro Transit|Sound Transit,BUS|TRAM,50|1-Line|635,kcm:31970|kcm:99254|sound-transit:99111|sound-transit:99913|kcm:47200|kcm:47404,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:25:01 10:48 ~ SODO Busway & S Lander St(99254) ~ Walk 49s ~ SODO Station(99111) ~ TRAM 1-Line 10:58 11:30 ~ Angle Lake Station(99913) ~ Walk 1m37s ~ S 200th St & 28th Ave S(47200) ~ BUS 635 11:39 11:42:55 ~ S 216th St & 20th Ave S(47404) ~ Walk 18m53s -96,2,00:50:56,4858,0,10:13:02,11:03:58,Metro Transit|Sound Generations,BUS,Hyde Shuttle|132|Hyde Shuttle,sound-generations:area_560|kcm:49739|kcm:49750|sound-generations:area_551,sound-generations:area_560(area_560) ~ BUS null 10:13:02 10:39:03Walk 0s ~ 14th Ave S & S Trenton St(49739) ~ BUS 132 10:41:03 10:43:23 ~ Des Moines Memorial Dr S & S 96th St(49750) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:45:23 11:03:58 -96,1,01:06:18,5345,226,10:01:08,11:07:26,Metro Transit|Sound Generations,BUS,128|Hyde Shuttle,kcm:31970|kcm:49585|sound-generations:area_551,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 128 10:04:16 10:38:40 ~ 8th Ave SW & SW 102nd St(49585) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:40:40 11:07:26 -96,2,00:58:36,5318,0,10:17:09,11:15:45,Metro Transit|Sound Generations,BUS,Hyde Shuttle|120|Hyde Shuttle,sound-generations:area_560|kcm:21280|kcm:52050|sound-generations:area_551,sound-generations:area_560(area_560) ~ BUS null 10:17:09 10:41:12Walk 0s ~ SW Roxbury St & 20th Ave SW(21280) ~ BUS 120 10:43:12 10:45:53 ~ 15th Ave SW & SW 100th St(52050) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:47:53 11:15:45 -97,2,01:41:14,8227,482,10:05:53,11:47:07,Metro Transit,BUS,50|150|160,kcm:31970|kcm:99253|kcm:57455|kcm:57451|kcm:58255,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:09:01 10:33:54 ~ SODO Busway & S Spokane St(99253) ~ BUS 150 10:41 11:26 ~ Kent Sounder Station - Bay 5(57455) ~ Walk 44s ~ Kent Sounder Station - Bay 1(57451) ~ BUS 160 11:33 11:44:20 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -97,2,01:41:14,8353,659,10:21:53,12:03:07,Metro Transit,BUS,50|150|160,kcm:31970|kcm:99254|kcm:99263|kcm:57455|kcm:57451|kcm:58255,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:25:01 10:48 ~ SODO Busway & S Lander St(99254) ~ Walk 2m30s ~ SODO Busway & S Lander St(99263) ~ BUS 150 10:54 11:41 ~ Kent Sounder Station - Bay 5(57455) ~ Walk 44s ~ Kent Sounder Station - Bay 1(57451) ~ BUS 160 11:49 12:00:20 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -97,2,01:42:14,8287,482,10:35:53,12:18:07,Metro Transit,BUS,50|150|160,kcm:31970|kcm:99253|kcm:57455|kcm:57451|kcm:58255,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:39:01 11:03:54 ~ SODO Busway & S Spokane St(99253) ~ BUS 150 11:11 11:57 ~ Kent Sounder Station - Bay 5(57455) ~ Walk 44s ~ Kent Sounder Station - Bay 1(57451) ~ BUS 160 12:04 12:15:20 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -98,2,01:17:49,6605,188,10:07:53,11:25:42,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|150|Road to Independence,sound-generations:area_560|kcm:45870|kcm:99253|kcm:80580|pudget-sound-educational:area_622,sound-generations:area_560(area_560) ~ BUS null 10:07:53 10:21:25Walk 0s ~ 4th Ave S & S Spokane St(45870) ~ Walk 2m35s ~ SODO Busway & S Spokane St(99253) ~ BUS 150 10:26 11:08:20 ~ W James St & Lincoln Ave N(80580) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 11:10:20 11:25:42 -98,2,01:17:49,6605,188,10:22:53,11:40:42,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|150|Road to Independence,sound-generations:area_560|kcm:45870|kcm:99253|kcm:80580|pudget-sound-educational:area_622,sound-generations:area_560(area_560) ~ BUS null 10:22:53 10:36:25Walk 0s ~ 4th Ave S & S Spokane St(45870) ~ Walk 2m35s ~ SODO Busway & S Spokane St(99253) ~ BUS 150 10:41 11:23:20 ~ W James St & Lincoln Ave N(80580) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 11:25:20 11:40:42 -98,2,01:17:49,6605,188,10:37:53,11:55:42,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|150|Road to Independence,sound-generations:area_560|kcm:45870|kcm:99253|kcm:80580|pudget-sound-educational:area_622,sound-generations:area_560(area_560) ~ BUS null 10:37:53 10:51:25Walk 0s ~ 4th Ave S & S Spokane St(45870) ~ Walk 2m35s ~ SODO Busway & S Spokane St(99253) ~ BUS 150 10:56 11:38:20 ~ W James St & Lincoln Ave N(80580) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 11:40:20 11:55:42 -99,1,01:59:21,11465,4233,10:10:04,12:09:25,Metro Transit|Sound Transit,BUS,C Line|578,kcm:19862|kcm:539|pierce-transit:20510|pierce-transit:4136,Walk 15m56s ~ SW Alaska St & California Ave SW - Bay 1(19862) ~ BUS C Line 10:26 10:51:13 ~ 3rd Ave & Marion St(539) ~ Walk 2m7s ~ 2nd Ave & Marion St(20510) ~ BUS 578 11:00 11:32 ~ Federal Way TC - Bay 2(4136) ~ Walk 37m25s -99,3,01:54:55,10025,980,10:21:08,12:16:03,Metro Transit|Sound Transit,BUS,128|560|574|181,kcm:31970|kcm:22253|pierce-transit:27940|pierce-transit:13215|pierce-transit:29410|kcm:80433|kcm:83784,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 128 10:24:16 10:54:33 ~ Delridge Way SW & SW Barton St(22253) ~ Walk 6m ~ SW Roxbury St & 20th Ave SW(27940) ~ BUS 560 11:03 11:26 ~ SeaTac Airport Terminal - Bay 2(13215) ~ BUS 574 11:40 12:00 ~ Federal Way TC - Bay 5(29410) ~ Walk 33s ~ Federal Way TC - Bay 3(80433) ~ BUS 181 12:05 12:12:47 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -99,2,02:05:59,10581,1658,10:10:04,12:16:03,Metro Transit|Sound Transit,BUS,C Line|578|181,kcm:19862|kcm:539|pierce-transit:20510|pierce-transit:4136|kcm:80433|kcm:83784,Walk 15m56s ~ SW Alaska St & California Ave SW - Bay 1(19862) ~ BUS C Line 10:26 10:51:13 ~ 3rd Ave & Marion St(539) ~ Walk 2m7s ~ 2nd Ave & Marion St(20510) ~ BUS 578 11:00 11:32 ~ Federal Way TC - Bay 2(4136) ~ Walk 37s ~ Federal Way TC - Bay 3(80433) ~ BUS 181 12:05 12:12:47 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -100,3,01:12:19,7132,535,10:01:32,11:13:51,Metro Transit|Sound Generations|Sound Transit,BUS,Hyde Shuttle|24|578|181,sound-generations:area_560|kcm:30635|kcm:619|pierce-transit:30709|pierce-transit:4136|kcm:80433|kcm:83784,sound-generations:area_560(area_560) ~ BUS null 10:01:32 10:22:28Walk 1m32s ~ 4th Ave S & S Royal Brougham Way(30635) ~ BUS 24 10:26 10:28 ~ 4th Ave S & S Jackson St(619) ~ Walk 1m54s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 578 10:33 11:01 ~ Federal Way TC - Bay 2(4136) ~ Walk 37s ~ Federal Way TC - Bay 3(80433) ~ BUS 181 11:04 11:10:35 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -100,2,01:30:29,7594,494,10:07:53,11:38:22,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|150|Road to Independence,sound-generations:area_560|kcm:45870|kcm:99253|kcm:50779|pudget-sound-educational:area_622,sound-generations:area_560(area_560) ~ BUS null 10:07:53 10:21:25Walk 0s ~ 4th Ave S & S Spokane St(45870) ~ Walk 2m35s ~ SODO Busway & S Spokane St(99253) ~ BUS 150 10:26 11:06:18 ~ W James St & 64th Ave S(50779) ~ Walk 1m10s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 11:09:28 11:35:36Walk 2m46s -100,3,01:32:36,8124,220,10:09:39,11:42:15,Puget Sound Educational Service District|Sound Generations|Sound Transit,BUS,Hyde Shuttle|560|574|Road to Independence,sound-generations:area_560|pierce-transit:15709|pierce-transit:13215|pierce-transit:25846|pudget-sound-educational:area_622,sound-generations:area_560(area_560) ~ BUS null 10:09:39 10:31Walk 0s ~ Westwood Village - Bay 4(15709) ~ BUS 560 10:33 10:58 ~ SeaTac Airport Terminal - Bay 2(13215) ~ BUS 574 11:10 11:22 ~ Star Lake Fwy Station(25846) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 11:24 11:39:29Walk 2m46s -101,2,01:59:23,9816,1162,10:05:53,12:05:16,Metro Transit|Pierce Transit|Sound Transit,BUS,50|594|400,kcm:31970|kcm:99253|pierce-transit:597|pierce-transit:20163|pierce-transit:12938|pierce-transit:8058,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:09:01 10:33:54 ~ SODO Busway & S Spokane St(99253) ~ Walk 2s ~ Bus Wy & S Spokane St(597) ~ BUS 594 10:36 11:16 ~ Tacoma Dome Station - Zone E(20163) ~ Walk 1m10s ~ Tacoma Dome Station - Zone C(12938) ~ BUS 400 11:30 11:54 ~ 5th St SW & 9th Ave SW - Red Lot(8058) ~ Walk 11m16s -101,1,02:27:56,12211,2929,10:10:04,12:38:00,Metro Transit|Sound Transit,BUS,C Line|578,kcm:19862|kcm:539|pierce-transit:20510|pierce-transit:10401,Walk 15m56s ~ SW Alaska St & California Ave SW - Bay 1(19862) ~ BUS C Line 10:26 10:51:13 ~ 3rd Ave & Marion St(539) ~ Walk 2m7s ~ 2nd Ave & Marion St(20510) ~ BUS 578 11:00 12:17 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m -101,3,02:08:16,10752,899,10:50:53,12:59:09,Metro Transit|Pierce Transit|Sound Transit,BUS,50|150|578|402,kcm:31970|kcm:99254|kcm:620|pierce-transit:30709|pierce-transit:4136|pierce-transit:29410|pierce-transit:1332,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:54:01 11:17 ~ SODO Busway & S Lander St(99254) ~ BUS 150 11:19:40 11:26 ~ 4th Ave S & S Jackson St(620) ~ Walk 1m54s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 578 11:33 12:03 ~ Federal Way TC - Bay 2(4136) ~ Walk 1m10s ~ Federal Way TC - Bay 5(29410) ~ BUS 402 12:11 12:53 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m9s -102,3,01:30:43,8085,354,10:01:32,11:32:15,Metro Transit|Puget Sound Educational Service District|Sound Generations|Sound Transit,BUS,Hyde Shuttle|24|578|Road to Independence,sound-generations:area_560|kcm:30635|kcm:619|pierce-transit:30709|pierce-transit:4136|pudget-sound-educational:area_622,sound-generations:area_560(area_560) ~ BUS null 10:01:32 10:22:28Walk 1m32s ~ 4th Ave S & S Royal Brougham Way(30635) ~ BUS 24 10:26 10:28 ~ 4th Ave S & S Jackson St(619) ~ Walk 1m54s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 578 10:33 11:01 ~ Federal Way TC - Bay 2(4136) ~ Walk 1m59s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 11:04:59 11:32:15 -102,2,01:28:52,7268,188,10:07:53,11:36:45,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|150|Road to Independence,sound-generations:area_560|kcm:45870|kcm:99253|kcm:80580|pudget-sound-educational:area_622,sound-generations:area_560(area_560) ~ BUS null 10:07:53 10:21:25Walk 0s ~ 4th Ave S & S Spokane St(45870) ~ Walk 2m35s ~ SODO Busway & S Spokane St(99253) ~ BUS 150 10:26 11:08:20 ~ W James St & Lincoln Ave N(80580) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 11:10:20 11:36:45 -102,2,01:28:52,7268,188,10:22:53,11:51:45,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Hyde Shuttle|150|Road to Independence,sound-generations:area_560|kcm:45870|kcm:99253|kcm:80580|pudget-sound-educational:area_622,sound-generations:area_560(area_560) ~ BUS null 10:22:53 10:36:25Walk 0s ~ 4th Ave S & S Spokane St(45870) ~ Walk 2m35s ~ SODO Busway & S Spokane St(99253) ~ BUS 150 10:41 11:23:20 ~ W James St & Lincoln Ave N(80580) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 11:25:20 11:51:45 -103,4,03:21:55,15791,930,10:35:53,13:57:48,Metro Transit|Sound Transit,BUS,50|C Line|545|224|629,kcm:31970|kcm:33220|kcm:539|kcm:660|kcm:72488|kcm:68803|kcm:64397,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:39:01 10:44:45 ~ SW Alaska St & Fauntleroy Way SW(33220) ~ BUS C Line 10:47:29 11:11:13 ~ 3rd Ave & Marion St(539) ~ Walk 2m56s ~ 4th Ave & Madison St(660) ~ BUS 545 11:23:53 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -103,3,03:27:44,16270,1918,10:30:04,13:57:48,Metro Transit|Sound Transit,BUS,C Line|545|224|629,kcm:19862|kcm:539|kcm:660|kcm:72488|kcm:68803|kcm:64397,Walk 15m56s ~ SW Alaska St & California Ave SW - Bay 1(19862) ~ BUS C Line 10:46 11:11:13 ~ 3rd Ave & Marion St(539) ~ Walk 2m56s ~ 4th Ave & Madison St(660) ~ BUS 545 11:23:53 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -104,2,01:59:03,9899,1326,10:11:27,12:10:30,Metro Transit|Sound Generations|Sound Transit,BUS,Hyde Shuttle|554|208,sound-generations:area_560|kcm:21850|kcm:1480|kcm:64590|kcm:64593|kcm:64399,sound-generations:area_560(area_560) ~ BUS null 10:11:27 10:33:04Walk 0s ~ Airport Way S & S Royal Brougham Way(21850) ~ Walk 11m6s ~ S Jackson St & Maynard Ave S(1480) ~ BUS 554 10:46:10 11:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 11:31 12:04:49 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -104,3,03:05:58,13952,530,10:51:50,13:57:48,Metro Transit|Sound Generations|Sound Transit,BUS,Hyde Shuttle|545|224|629,sound-generations:area_560|kcm:21765|kcm:72488|kcm:68803|kcm:64397,sound-generations:area_560(area_560) ~ BUS null 10:51:50 11:14:44Walk 16s ~ 6th Ave S & S Royal Brougham Way(21765) ~ BUS 545 11:17 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -105,2,01:16:14,7909,2061,10:05:53,11:22:07,Metro Transit,BUS,50|C Line|E Line,kcm:31970|kcm:33220|kcm:558|kcm:6320,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:09:01 10:14:45 ~ SW Alaska St & Fauntleroy Way SW(33220) ~ BUS C Line 10:17:29 10:42 ~ 3rd Ave & Seneca St(558) ~ BUS E Line 10:48:24 10:57:02 ~ Aurora Ave N & Lynn St(6320) ~ Walk 25m5s -105,1,01:22:03,8388,3049,10:00:04,11:22:07,Metro Transit,BUS,C Line|E Line,kcm:19862|kcm:558|kcm:6320,Walk 15m56s ~ SW Alaska St & California Ave SW - Bay 1(19862) ~ BUS C Line 10:16 10:42 ~ 3rd Ave & Seneca St(558) ~ BUS E Line 10:48:24 10:57:02 ~ Aurora Ave N & Lynn St(6320) ~ Walk 25m5s -105,1,01:13:34,6683,1448,10:10:04,11:23:38,Metro Transit,BUS,C Line|3,kcm:19862|kcm:558|kcm:41350,Walk 15m56s ~ SW Alaska St & California Ave SW - Bay 1(19862) ~ BUS C Line 10:26 10:52 ~ 3rd Ave & Seneca St(558) ~ BUS 3 10:55:51 11:20:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -106,0,02:47:34,19399,12750,10:00:00,12:47:34,,,,,Walk 2h47m34s -107,1,00:35:46,3643,411,10:05:53,10:41:39,Metro Transit|Sound Transit,BUS|TRAM,50|1-Line,kcm:31970|kcm:99263|sound-transit:99111|sound-transit:99121,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:09:01 10:32 ~ SODO Busway & S Lander St(99263) ~ Walk 2m1s ~ SODO Station(99111) ~ TRAM 1-Line 10:38 10:41 ~ Beacon Hill Station(99121) ~ Walk 39s -107,0,00:44:49,4202,1263,10:05:53,10:50:42,Metro Transit,BUS,50,kcm:31970|kcm:30770,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:09:01 10:36:46 ~ S Columbian Way & S Spokane St(30770) ~ Walk 13m56s -107,1,00:39:46,3832,334,10:21:53,11:01:39,Metro Transit|Sound Transit,BUS|TRAM,50|1-Line,kcm:31970|kcm:99254|sound-transit:99111|sound-transit:99121,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:25:01 10:48 ~ SODO Busway & S Lander St(99254) ~ Walk 49s ~ SODO Station(99111) ~ TRAM 1-Line 10:58 11:01 ~ Beacon Hill Station(99121) ~ Walk 39s -108,1,00:24:25,2725,82,10:07:14,10:31:39,Sound Generations|Sound Transit,BUS|TRAM,Hyde Shuttle|1-Line,sound-generations:area_560|sound-transit:99111|sound-transit:99121,sound-generations:area_560(area_560) ~ BUS null 10:07:14 10:25:30Walk 30s ~ SODO Station(99111) ~ TRAM 1-Line 10:28 10:31 ~ Beacon Hill Station(99121) ~ Walk 39s -108,1,00:24:25,2725,82,10:17:14,10:41:39,Sound Generations|Sound Transit,BUS|TRAM,Hyde Shuttle|1-Line,sound-generations:area_560|sound-transit:99111|sound-transit:99121,sound-generations:area_560(area_560) ~ BUS null 10:17:14 10:35:30Walk 30s ~ SODO Station(99111) ~ TRAM 1-Line 10:38 10:41 ~ Beacon Hill Station(99121) ~ Walk 39s -108,0,00:44:49,4202,1263,10:05:53,10:50:42,Metro Transit,BUS,50,kcm:31970|kcm:30770,Walk 3m8s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:09:01 10:36:46 ~ S Columbian Way & S Spokane St(30770) ~ Walk 13m56s -109,1,01:26:19,8565,2975,10:13:14,11:39:33,Metro Transit|Sound Transit,BUS|RAIL,S Line|160,sound-transit:S_PU_NB|sound-transit:S_KE_NB|kcm:57453|kcm:57185,Walk 19m46s ~ Puyallup Station (Northbound)(S_PU_NB) ~ RAIL S Line 10:33 10:55 ~ Kent Station (Northbound)(S_KE_NB) ~ Walk 1m34s ~ Kent Sounder Station - Bay 3(57453) ~ BUS 160 11:07 11:21:08 ~ 108th Ave SE & SE 220th Pl(57185) ~ Walk 18m25s -109,2,01:54:40,10460,2399,10:14:53,12:09:33,Metro Transit|Pierce Transit|Sound Transit,BUS,400|578|160,pierce-transit:6085|pierce-transit:11956|pierce-transit:10401|pierce-transit:8770|kcm:57774|kcm:57185,Walk 11m7s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:26 10:29 ~ Puyallup Station - Bay 1(11956) ~ Walk 1m20s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 10:33 11:04 ~ Auburn Station - Bay 3(8770) ~ Walk 25s ~ Auburn Transit Center - Bay 2(57774) ~ BUS 160 11:13 11:51:08 ~ 108th Ave SE & SE 220th Pl(57185) ~ Walk 18m25s -109,1,01:55:37,10364,3032,10:43:56,12:39:33,Metro Transit|Sound Transit,BUS,578|160,pierce-transit:10401|pierce-transit:8770|kcm:57774|kcm:57185,Walk 21m4s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 11:05 11:36 ~ Auburn Station - Bay 3(8770) ~ Walk 25s ~ Auburn Transit Center - Bay 2(57774) ~ BUS 160 11:43 12:21:08 ~ 108th Ave SE & SE 220th Pl(57185) ~ Walk 18m25s -110,2,00:48:12,4694,0,10:08:12,10:56:24,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|160|Hyde Shuttle,pudget-sound-educational:area_622|kcm:57422|kcm:57180|sound-generations:area_558,pudget-sound-educational:area_622(area_622) ~ BUS null 10:08:12 10:43:44Walk 0s ~ 104th Ave SE & SE 240th St(57422) ~ BUS 160 10:45:44 10:50:18 ~ 108th Ave SE & SE 224th St(57180) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 10:52:18 10:56:24 -110,2,00:48:02,4684,0,10:11:20,10:59:22,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|183|Hyde Shuttle,pudget-sound-educational:area_622|kcm:58781|kcm:50781|sound-generations:area_558,pudget-sound-educational:area_622(area_622) ~ BUS null 10:11:20 10:36:48Walk 0s ~ W Meeker St & Frager Rd(58781) ~ BUS 183 10:38:48 10:39:48 ~ Reith Rd & Lake Fenwick Rd S(50781) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 10:41:48 10:59:22 -110,2,00:45:07,4509,0,10:16:08,11:01:15,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|165|Hyde Shuttle,pudget-sound-educational:area_622|kcm:57090|kcm:57141|sound-generations:area_558,pudget-sound-educational:area_622(area_622) ~ BUS null 10:16:08 10:44:49Walk 0s ~ E James St & Jason Ave N(57090) ~ BUS 165 10:46:49 10:52:44 ~ SE 240th St & 116th Ave SE(57141) ~ Walk 0s ~ sound-generations:area_558(area_558) ~ BUS null 10:54:44 11:01:15 -111,1,01:42:35,9173,2485,10:13:14,11:55:49,Metro Transit|Sound Transit,BUS|RAIL,S Line|165,sound-transit:S_PU_NB|sound-transit:S_KE_NB|kcm:57459|kcm:47570,Walk 19m46s ~ Puyallup Station (Northbound)(S_PU_NB) ~ RAIL S Line 10:33 10:55 ~ Kent Station (Northbound)(S_KE_NB) ~ Walk 1m32s ~ Kent Sounder Station - Bay 9(57459) ~ BUS 165 11:07 11:44 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m49s -111,2,02:13:56,11235,1898,10:14:53,12:28:49,Metro Transit|Pierce Transit|Sound Transit,BUS,400|574|165,pierce-transit:6085|pierce-transit:20163|pierce-transit:3046|pierce-transit:14363|kcm:21945|kcm:47570,Walk 11m7s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:26 10:49 ~ Tacoma Dome Station - Zone E(20163) ~ Walk 20s ~ Tacoma Dome Station - Zone A(3046) ~ BUS 574 10:58 11:26 ~ I-5 & Kent - Des Moines Fwy Station(14363) ~ Walk 1m56s ~ Kent Des Moines Park And Ride(21945) ~ BUS 165 11:52 12:17 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m49s -111,2,02:11:53,11657,2660,10:43:56,12:55:49,Metro Transit|Sound Transit,BUS,578|574|165,pierce-transit:10401|pierce-transit:7910|pierce-transit:12344|pierce-transit:14363|kcm:21945|kcm:47570,Walk 21m4s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 11:05 11:48 ~ Federal Way TC - Bay 7(7910) ~ Walk 31s ~ Federal Way TC - Bay 8(12344) ~ BUS 574 12:00 12:11 ~ I-5 & Kent - Des Moines Fwy Station(14363) ~ Walk 1m56s ~ Kent Des Moines Park And Ride(21945) ~ BUS 165 12:22 12:44 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m49s -112,2,01:09:25,6167,275,10:05:29,11:14:54,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|A Line|Hyde Shuttle,pudget-sound-educational:area_622|kcm:60750|kcm:60752|sound-generations:area_551,pudget-sound-educational:area_622(area_622) ~ BUS null 10:05:29 10:38:19Walk 1m9s ~ Pacific Hwy S & S 272nd St(60750) ~ BUS A Line 10:41:28 10:42:02 ~ Pacific Hwy S & S 268th St(60752) ~ Walk 2m40s ~ sound-generations:area_551(area_551) ~ BUS null 10:46:42 11:14:54 -112,2,01:09:38,6115,187,10:05:29,11:15:07,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|A Line|Hyde Shuttle,pudget-sound-educational:area_622|kcm:60750|kcm:48949|sound-generations:area_551,pudget-sound-educational:area_622(area_622) ~ BUS null 10:05:29 10:38:19Walk 1m9s ~ Pacific Hwy S & S 272nd St(60750) ~ BUS A Line 10:41:28 10:47:16 ~ Pacific Hwy S & S 240th St(48949) ~ Walk 1m26s ~ sound-generations:area_551(area_551) ~ BUS null 10:50:42 11:15:07 -112,2,01:10:13,6079,88,10:05:29,11:15:42,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|A Line|Hyde Shuttle,pudget-sound-educational:area_622|kcm:60750|kcm:60810|sound-generations:area_551,pudget-sound-educational:area_622(area_622) ~ BUS null 10:05:29 10:38:19Walk 1m9s ~ Pacific Hwy S & S 272nd St(60750) ~ BUS A Line 10:41:28 10:50:38 ~ Pacific Hwy S & S 224th St(60810) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:52:38 11:15:42 -113,1,01:33:37,9135,3185,10:13:14,11:46:51,Metro Transit|Sound Transit,BUS|RAIL,S Line|165,sound-transit:S_PU_NB|sound-transit:S_KE_NB|kcm:57459|kcm:50480,Walk 19m46s ~ Puyallup Station (Northbound)(S_PU_NB) ~ RAIL S Line 10:33 10:55 ~ Kent Station (Northbound)(S_KE_NB) ~ Walk 1m32s ~ Kent Sounder Station - Bay 9(57459) ~ BUS 165 11:07 11:25:38 ~ Pacific Hwy S & Kent Des Moines Rd(50480) ~ Walk 21m13s -113,1,01:35:13,8695,2428,10:13:05,11:48:18,Metro Transit|Pierce Transit,BUS,402|A Line,pierce-transit:1294|pierce-transit:2255|kcm:80438|kcm:60810,Walk 5m55s ~ Meridian S & 9th Ave SE(1294) ~ BUS 402 10:19 10:59 ~ 23rd Ave S & S 322nd St(2255) ~ Walk 8m40s ~ Federal Way TC - Bay 8(80438) ~ BUS A Line 11:10 11:30:46 ~ Pacific Hwy S & S 224th St(60810) ~ Walk 17m32s -113,2,01:43:25,9648,2235,10:14:53,11:58:18,Metro Transit|Pierce Transit|Sound Transit,BUS,400|574|A Line,pierce-transit:6085|pierce-transit:20163|pierce-transit:3046|pierce-transit:12344|kcm:80438|kcm:60810,Walk 11m7s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:26 10:49 ~ Tacoma Dome Station - Zone E(20163) ~ Walk 20s ~ Tacoma Dome Station - Zone A(3046) ~ BUS 574 10:58 11:15 ~ Federal Way TC - Bay 8(12344) ~ Walk 44s ~ Federal Way TC - Bay 8(80438) ~ BUS A Line 11:20 11:40:46 ~ Pacific Hwy S & S 224th St(60810) ~ Walk 17m32s -114,2,00:51:40,4966,88,10:05:29,10:57:09,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|A Line|Hyde Shuttle,pudget-sound-educational:area_622|kcm:60750|kcm:60800|sound-generations:area_551,pudget-sound-educational:area_622(area_622) ~ BUS null 10:05:29 10:38:19Walk 1m9s ~ Pacific Hwy S & S 272nd St(60750) ~ BUS A Line 10:41:28 10:49 ~ Pacific Hwy S & Kent Des Moines Rd(60800) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:51 10:57:09 -114,2,00:49:02,4744,0,10:13:32,11:02:34,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|165|Hyde Shuttle,pudget-sound-educational:area_622|kcm:50755|kcm:53506|sound-generations:area_551,pudget-sound-educational:area_622(area_622) ~ BUS null 10:13:32 10:38:22Walk 0s ~ W Meeker St & Washington Ave N(50755) ~ BUS 165 10:40:22 10:54:27 ~ Kent Des Moines Rd & I-5 Ramp(53506) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:56:27 11:02:34 -114,2,00:51:40,4966,88,10:15:29,11:07:09,Metro Transit|Puget Sound Educational Service District|Sound Generations,BUS,Road to Independence|A Line|Hyde Shuttle,pudget-sound-educational:area_622|kcm:60750|kcm:60800|sound-generations:area_551,pudget-sound-educational:area_622(area_622) ~ BUS null 10:15:29 10:48:19Walk 1m9s ~ Pacific Hwy S & S 272nd St(60750) ~ BUS A Line 10:51:28 10:59 ~ Pacific Hwy S & Kent Des Moines Rd(60800) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 11:01 11:07:09 -115,1,00:59:23,6042,1759,10:13:14,11:12:37,Metro Transit|Sound Transit,BUS|RAIL,S Line|160,sound-transit:S_PU_NB|sound-transit:S_AU_NB|kcm:57774|kcm:57915,Walk 19m46s ~ Puyallup Station (Northbound)(S_PU_NB) ~ RAIL S Line 10:33 10:48 ~ Auburn Station (Northbound)(S_AU_NB) ~ Walk 1m19s ~ Auburn Transit Center - Bay 2(57774) ~ BUS 160 10:58 11:09:49 ~ Auburn Way N & 37th St NE(57915) ~ Walk 2m48s -115,2,01:12:44,7039,1184,10:14:53,11:27:37,Metro Transit|Pierce Transit|Sound Transit,BUS,400|578|160,pierce-transit:6085|pierce-transit:11956|pierce-transit:10401|pierce-transit:8770|kcm:57774|kcm:57915,Walk 11m7s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:26 10:29 ~ Puyallup Station - Bay 1(11956) ~ Walk 1m20s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 10:33 11:04 ~ Auburn Station - Bay 3(8770) ~ Walk 25s ~ Auburn Transit Center - Bay 2(57774) ~ BUS 160 11:13 11:24:49 ~ Auburn Way N & 37th St NE(57915) ~ Walk 2m48s -115,1,01:13:41,6943,1817,10:43:56,11:57:37,Metro Transit|Sound Transit,BUS,578|160,pierce-transit:10401|pierce-transit:8770|kcm:57774|kcm:57915,Walk 21m4s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 11:05 11:36 ~ Auburn Station - Bay 3(8770) ~ Walk 25s ~ Auburn Transit Center - Bay 2(57774) ~ BUS 160 11:43 11:54:49 ~ Auburn Way N & 37th St NE(57915) ~ Walk 2m48s -116,1,00:38:51,3856,440,10:13:05,10:51:56,Pierce Transit|Puget Sound Educational Service District,BUS,402|Road to Independence,pierce-transit:1294|pierce-transit:1341|pudget-sound-educational:area_622,Walk 5m55s ~ Meridian S & 9th Ave SE(1294) ~ BUS 402 10:19 10:28 ~ Meridian N & Valley Ave E(1341) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:30 10:51:56 -116,2,00:36:00,3970,13,10:15:56,10:51:56,Pierce Transit|Puget Sound Educational Service District,BUS,Road to Independence|402|Road to Independence,pudget-sound-educational:area_622|pierce-transit:27124|pierce-transit:1341|pudget-sound-educational:area_622,pudget-sound-educational:area_622(area_622) ~ BUS null 10:15:56 10:18:45Walk 15s ~ 3rd St SE & 4th Ave SE(27124) ~ BUS 402 10:21 10:28 ~ Meridian N & Valley Ave E(1341) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:30 10:51:56 -116,2,00:42:07,4332,4,10:20:12,11:02:19,Pierce Transit|Puget Sound Educational Service District,BUS,Road to Independence|400|Road to Independence,pudget-sound-educational:area_622|pierce-transit:6085|pierce-transit:2626|pudget-sound-educational:area_622,pudget-sound-educational:area_622(area_622) ~ BUS null 10:20:12 10:23:57Walk 3s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:26 10:31 ~ Stewart Ave W & 15th St NW(2626) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:33 11:02:19 -117,1,01:00:46,5578,991,10:13:05,11:13:51,Metro Transit|Pierce Transit,BUS,402|181,pierce-transit:1294|pierce-transit:2255|kcm:60638|kcm:83784,Walk 5m55s ~ Meridian S & 9th Ave SE(1294) ~ BUS 402 10:19 10:59 ~ 23rd Ave S & S 322nd St(2255) ~ Walk 3m56s ~ S 320th St & 23rd Ave S(60638) ~ BUS 181 11:05:23 11:10:35 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -117,0,01:15:13,7182,2826,10:13:05,11:28:18,Pierce Transit,BUS,402,pierce-transit:1294|pierce-transit:2267,Walk 5m55s ~ Meridian S & 9th Ave SE(1294) ~ BUS 402 10:19 10:57 ~ 324th St S & 17th Ave S(2267) ~ Walk 31m18s -117,2,01:27:01,7922,1228,10:14:53,11:41:54,Metro Transit|Pierce Transit|Sound Transit,BUS,400|574|187,pierce-transit:6085|pierce-transit:20163|pierce-transit:3046|pierce-transit:12344|kcm:80433|kcm:83784,Walk 11m7s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:26 10:49 ~ Tacoma Dome Station - Zone E(20163) ~ Walk 20s ~ Tacoma Dome Station - Zone A(3046) ~ BUS 574 10:58 11:15 ~ Federal Way TC - Bay 8(12344) ~ Walk 1m51s ~ Federal Way TC - Bay 3(80433) ~ BUS 187 11:32 11:38:38 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -118,1,00:38:55,3727,254,10:02:59,10:41:54,Metro Transit|Puget Sound Educational Service District,BUS,Road to Independence|187,pudget-sound-educational:area_622|kcm:60640|kcm:83784,pudget-sound-educational:area_622(area_622) ~ BUS null 10:02:59 10:32:51Walk 0s ~ S 320th St & 20th Ave S(60640) ~ BUS 187 10:34:51 10:38:38 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -118,1,00:39:02,3734,254,10:04:49,10:43:51,Metro Transit|Puget Sound Educational Service District,BUS,Road to Independence|181,pudget-sound-educational:area_622|kcm:83663|kcm:83784,pudget-sound-educational:area_622(area_622) ~ BUS null 10:04:49 10:28:20Walk 0s ~ S 320th St & Military Rd S(83663) ~ BUS 181 10:30:20 10:40:35 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -118,1,00:51:42,4792,660,10:13:05,11:04:47,Pierce Transit|Puget Sound Educational Service District,BUS,402|Road to Independence,pierce-transit:1294|pierce-transit:1341|pudget-sound-educational:area_622,Walk 5m55s ~ Meridian S & 9th Ave SE(1294) ~ BUS 402 10:19 10:28 ~ Meridian N & Valley Ave E(1341) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 10:30 11:02:01Walk 2m46s -119,2,01:59:01,10704,2381,10:13:14,12:12:15,Metro Transit|Sound Transit,BUS|RAIL,S Line|C Line|128,sound-transit:S_PU_NB|sound-transit:S_KS|kcm:1562|kcm:20041|kcm:32011|kcm:31871,Walk 19m46s ~ Puyallup Station (Northbound)(S_PU_NB) ~ RAIL S Line 10:33 11:22 ~ King Street Station(S_KS) ~ Walk 9m13s ~ Alaskan Way S & S Jackson St(1562) ~ BUS C Line 11:38:40 11:58 ~ SW Alaska St & California Ave SW - Bay 3(20041) ~ Walk 42s ~ SW Alaska St & 44th Ave SW - Bay 4(32011) ~ BUS 128 12:05 12:08:50 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -119,1,02:00:39,10876,3299,10:13:14,12:13:53,Metro Transit|Sound Transit,BUS|RAIL,S Line|C Line,sound-transit:S_PU_NB|sound-transit:S_KS|kcm:1562|kcm:20041,Walk 19m46s ~ Puyallup Station (Northbound)(S_PU_NB) ~ RAIL S Line 10:33 11:22 ~ King Street Station(S_KS) ~ Walk 9m13s ~ Alaskan Way S & S Jackson St(1562) ~ BUS C Line 11:38:40 11:58 ~ SW Alaska St & California Ave SW - Bay 3(20041) ~ Walk 15m53s -119,2,02:04:07,10154,1239,10:14:53,12:19:00,Metro Transit|Pierce Transit|Sound Transit,BUS,400|594|50,pierce-transit:6085|pierce-transit:20163|pierce-transit:27454|pierce-transit:593|kcm:99261|kcm:31871,Walk 11m7s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:26 10:49 ~ Tacoma Dome Station - Zone E(20163) ~ Walk 47s ~ Tacoma Dome Station - Zone B(27454) ~ BUS 594 11:07 11:47 ~ Bus Wy & Lander St(593) ~ Walk 1m31s ~ S Lander St & SODO Busway(99261) ~ BUS 50 11:52 12:15:35 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -121,2,03:28:44,16046,2378,10:43:56,14:12:40,Metro Transit|Sound Transit,BUS,578|554|208,pierce-transit:10401|pierce-transit:13217|kcm:280|kcm:64590|kcm:64593|kcm:64399,Walk 21m4s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 11:05 12:21 ~ 4th Ave & Pike St(13217) ~ Walk 4m17s ~ 2nd Ave & Stewart St(280) ~ BUS 554 12:37:53 13:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 13:30 14:06:59 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -121,4,04:18:43,19355,1128,11:18:05,15:36:48,Metro Transit|Pierce Transit|Sound Transit,BUS,402|578|545|224|629,pierce-transit:1294|pierce-transit:11956|pierce-transit:10401|pierce-transit:13217|kcm:700|kcm:72488|kcm:68803|kcm:64397,Walk 5m55s ~ Meridian S & 9th Ave SE(1294) ~ BUS 402 11:24 11:29 ~ Puyallup Station - Bay 1(11956) ~ Walk 1m20s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 11:35 12:52 ~ 4th Ave & Pike St(13217) ~ Walk 1m11s ~ 4th Ave & Pike St(700) ~ BUS 545 12:56 13:31:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 13:54:31 14:28 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 14:43 15:30 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -121,3,04:22:52,19746,2160,11:13:56,15:36:48,Metro Transit|Sound Transit,BUS,578|545|224|629,pierce-transit:10401|pierce-transit:13217|kcm:700|kcm:72488|kcm:68803|kcm:64397,Walk 21m4s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 11:35 12:52 ~ 4th Ave & Pike St(13217) ~ Walk 1m11s ~ 4th Ave & Pike St(700) ~ BUS 545 12:56 13:31:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 13:54:31 14:28 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 14:43 15:30 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -122,5,03:43:14,17135,199,10:12:57,13:56:11,Metro Transit|Puget Sound Educational Service District|Snoqualmie Valley Transportation|Sound Transit,BUS,Road to Independence|578|545|224|629|Dial-A-Ride,pudget-sound-educational:area_622|pierce-transit:7910|pierce-transit:13217|kcm:700|kcm:72488|kcm:68803|kcm:64366|snoqualmie-flex:area_486,pudget-sound-educational:area_622(area_622) ~ BUS null 10:12:57 10:42:20Walk 1m40s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 10:46 11:19 ~ 4th Ave & Pike St(13217) ~ Walk 1m11s ~ 4th Ave & Pike St(700) ~ BUS 545 11:26 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:25:48 ~ Sr 203 & NE 40th St(64366) ~ Walk 8s ~ snoqualmie-flex:area_485(area_485) ~ BUS null 13:27:56 13:56:11 -122,4,03:44:51,17003,700,10:12:57,13:57:48,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS,Road to Independence|578|545|224|629,pudget-sound-educational:area_622|pierce-transit:7910|pierce-transit:13217|kcm:700|kcm:72488|kcm:68803|kcm:64397,pudget-sound-educational:area_622(area_622) ~ BUS null 10:12:57 10:42:20Walk 1m40s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 10:46 11:19 ~ 4th Ave & Pike St(13217) ~ Walk 1m11s ~ 4th Ave & Pike St(700) ~ BUS 545 11:26 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -122,3,02:57:43,13723,918,11:14:57,14:12:40,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS,Road to Independence|578|554|208,pudget-sound-educational:area_622|pierce-transit:7910|pierce-transit:13217|kcm:280|kcm:64590|kcm:64593|kcm:64399,pudget-sound-educational:area_622(area_622) ~ BUS null 11:14:57 11:44:20Walk 1m40s ~ Federal Way TC - Bay 7(7910) ~ BUS 578 11:48 12:21 ~ 4th Ave & Pike St(13217) ~ Walk 4m17s ~ 2nd Ave & Stewart St(280) ~ BUS 554 12:37:53 13:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 13:30 14:06:59 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -123,1,01:55:24,9941,2506,10:13:14,12:08:38,Metro Transit|Sound Transit,BUS|RAIL,S Line|3,sound-transit:S_PU_NB|sound-transit:S_KS|kcm:1540|kcm:41350,Walk 19m46s ~ Puyallup Station (Northbound)(S_PU_NB) ~ RAIL S Line 10:33 11:22 ~ King Street Station(S_KS) ~ Walk 11m5s ~ James St & 5th Ave(1540) ~ BUS 3 11:36 12:05:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -123,2,02:08:45,10516,1351,10:14:53,12:23:38,Metro Transit|Pierce Transit|Sound Transit,BUS,400|578|3,pierce-transit:6085|pierce-transit:11956|pierce-transit:10401|pierce-transit:13217|kcm:575|kcm:41350,Walk 11m7s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:26 10:29 ~ Puyallup Station - Bay 1(11956) ~ Walk 1m20s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 10:33 11:49 ~ 4th Ave & Pike St(13217) ~ Walk 2m32s ~ 3rd Ave & Pike St(575) ~ BUS 3 11:58 12:20:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -123,1,02:07:42,10300,1984,10:43:56,12:51:38,Metro Transit|Sound Transit,BUS,578|3,pierce-transit:10401|pierce-transit:13217|kcm:575|kcm:41350,Walk 21m4s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 11:05 12:21 ~ 4th Ave & Pike St(13217) ~ Walk 2m32s ~ 3rd Ave & Pike St(575) ~ BUS 3 12:26 12:48:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -124,1,01:55:24,9941,2506,10:13:14,12:08:38,Metro Transit|Sound Transit,BUS|RAIL,S Line|3,sound-transit:S_PU_NB|sound-transit:S_KS|kcm:1540|kcm:41350,Walk 19m46s ~ Puyallup Station (Northbound)(S_PU_NB) ~ RAIL S Line 10:33 11:22 ~ King Street Station(S_KS) ~ Walk 11m5s ~ James St & 5th Ave(1540) ~ BUS 3 11:36 12:05:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -124,1,02:08:55,10177,1715,10:43:56,12:52:51,Sound Generations|Sound Transit,BUS,578|Hyde Shuttle,pierce-transit:10401|pierce-transit:24330|sound-generations:area_555,Walk 21m4s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 11:05 12:30 ~ Howell St & Yale Ave(24330) ~ Walk 2m3s ~ sound-generations:area_555(area_555) ~ BUS null 12:34:03 12:52:51 -124,1,02:09:55,10237,1715,11:13:56,13:23:51,Sound Generations|Sound Transit,BUS,578|Hyde Shuttle,pierce-transit:10401|pierce-transit:24330|sound-generations:area_555,Walk 21m4s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 11:35 13:01 ~ Howell St & Yale Ave(24330) ~ Walk 2m3s ~ sound-generations:area_555(area_555) ~ BUS null 13:05:03 13:23:51 -125,1,01:28:25,8208,2340,10:13:14,11:41:39,Sound Transit,RAIL|TRAM,S Line|1-Line,sound-transit:S_PU_NB|sound-transit:S_KS|sound-transit:99101|sound-transit:99121,Walk 19m46s ~ Puyallup Station (Northbound)(S_PU_NB) ~ RAIL S Line 10:33 11:22 ~ King Street Station(S_KS) ~ Walk 11m18s ~ Stadium Station(99101) ~ TRAM 1-Line 11:36 11:41 ~ Beacon Hill Station(99121) ~ Walk 39s -125,0,01:47:21,10186,4338,10:13:14,12:00:35,Sound Transit,RAIL,S Line,sound-transit:S_PU_NB|sound-transit:S_KS,Walk 19m46s ~ Puyallup Station (Northbound)(S_PU_NB) ~ RAIL S Line 10:33 11:22 ~ King Street Station(S_KS) ~ Walk 38m35s -125,2,01:46:46,8936,989,10:14:53,12:01:39,Pierce Transit|Sound Transit,BUS|TRAM,400|594|1-Line,pierce-transit:6085|pierce-transit:20163|pierce-transit:27454|pierce-transit:593|sound-transit:99111|sound-transit:99121,Walk 11m7s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:26 10:49 ~ Tacoma Dome Station - Zone E(20163) ~ Walk 47s ~ Tacoma Dome Station - Zone B(27454) ~ BUS 594 11:07 11:47 ~ Bus Wy & Lander St(593) ~ Walk 46s ~ SODO Station(99111) ~ TRAM 1-Line 11:58 12:01 ~ Beacon Hill Station(99121) ~ Walk 39s -126,2,01:24:12,6955,138,10:07:27,11:31:39,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS|TRAM,Road to Independence|150|1-Line,pudget-sound-educational:area_622|kcm:59773|kcm:99254|sound-transit:99111|sound-transit:99121,pudget-sound-educational:area_622(area_622) ~ BUS null 10:07:27 10:32:31Walk 27s ~ W James St & Lincoln Ave N(59773) ~ BUS 150 10:34:58 11:19:40 ~ SODO Busway & S Lander St(99254) ~ Walk 49s ~ SODO Station(99111) ~ TRAM 1-Line 11:28 11:31 ~ Beacon Hill Station(99121) ~ Walk 39s -126,2,01:19:12,6655,138,10:22:27,11:41:39,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS|TRAM,Road to Independence|150|1-Line,pudget-sound-educational:area_622|kcm:59773|kcm:99254|sound-transit:99111|sound-transit:99121,pudget-sound-educational:area_622(area_622) ~ BUS null 10:22:27 10:47:31Walk 27s ~ W James St & Lincoln Ave N(59773) ~ BUS 150 10:49:58 11:34:40 ~ SODO Busway & S Lander St(99254) ~ Walk 49s ~ SODO Station(99111) ~ TRAM 1-Line 11:38 11:41 ~ Beacon Hill Station(99121) ~ Walk 39s -126,2,01:16:47,7129,987,10:24:52,11:41:39,Puget Sound Educational Service District|Sound Transit,BUS|RAIL|TRAM,Road to Independence|S Line|1-Line,pudget-sound-educational:area_622|sound-transit:S_KE_NB|sound-transit:S_KS|sound-transit:99101|sound-transit:99121,pudget-sound-educational:area_622(area_622) ~ BUS null 10:24:52 10:51:23Walk 1m37s ~ Kent Station (Northbound)(S_KE_NB) ~ RAIL S Line 10:55 11:22 ~ King Street Station(S_KS) ~ Walk 11m18s ~ Stadium Station(99101) ~ TRAM 1-Line 11:36 11:41 ~ Beacon Hill Station(99121) ~ Walk 39s -127,3,02:50:16,14302,2282,10:31:35,13:21:51,Metro Transit|Sound Transit,BUS,208|554|240|160,kcm:82425|kcm:64448|kcm:64502|kcm:67019|kcm:67015|kcm:46478|kcm:46465|kcm:57375,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 11:38 ~ I-90 Expressway Ramp & 142nd Pl SE - Bay 3(67019) ~ Walk 3m25s ~ Eastgate Park & Ride Acs & 140th Ave SE - Bay 2(67015) ~ BUS 240 11:48 12:30 ~ Renton Transit Center - Bay 3(46478) ~ Walk 1m42s ~ Renton Transit Center - Bay 8(46465) ~ BUS 160 12:34 13:03:29 ~ 108th Ave SE & SE 220th Pl(57375) ~ Walk 18m22s -129,5,02:39:01,14368,1606,10:31:35,13:10:36,Metro Transit|Sound Transit,BUS|TRAM,208|554|7|1-Line|F Line|165,kcm:82425|kcm:64448|kcm:64502|kcm:8494|kcm:8590|kcm:8681|sound-transit:55949|sound-transit:99900|kcm:60923|kcm:53720|kcm:53975|kcm:48620,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 11:52 ~ Rainier Ave S & S Charles St(8494) ~ Walk 1m31s ~ Rainier Ave S & S Charles St(8590) ~ BUS 7 12:01:06 12:08 ~ Rainier Ave S & S Forest St - Bay 4(8681) ~ Walk 2m40s ~ Mount Baker Station(55949) ~ TRAM 1-Line 12:13 12:33 ~ Tukwila Int'l Blvd Station(99900) ~ Walk 1m11s ~ Tukwila International Blvd Station - Bay 3(60923) ~ BUS F Line 12:37 12:48:59 ~ 4th Ave SW & SW 156th St(53720) ~ Walk 9s ~ 4th Ave SW & SW 156th St(53975) ~ BUS 165 12:54:44 13:00:26 ~ 1st Ave S & SW 178th St(48620) ~ Walk 10m10s -129,4,02:55:51,16445,3874,10:31:35,13:27:26,Metro Transit|Sound Transit,BUS|TRAM,208|554|7|1-Line|F Line,kcm:82425|kcm:64448|kcm:64502|kcm:8494|kcm:8590|kcm:8681|sound-transit:55949|sound-transit:99900|kcm:60923|kcm:47646,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 11:52 ~ Rainier Ave S & S Charles St(8494) ~ Walk 1m31s ~ Rainier Ave S & S Charles St(8590) ~ BUS 7 12:01:06 12:08 ~ Rainier Ave S & S Forest St - Bay 4(8681) ~ Walk 2m40s ~ Mount Baker Station(55949) ~ TRAM 1-Line 12:13 12:33 ~ Tukwila Int'l Blvd Station(99900) ~ Walk 1m11s ~ Tukwila International Blvd Station - Bay 3(60923) ~ BUS F Line 12:37 12:48:05 ~ SW 156th St & 2nd Ave SW(47646) ~ Walk 39m21s -129,3,03:09:05,15638,2601,10:31:35,13:40:40,Metro Transit|Sound Transit,BUS,208|554|150|156,kcm:82425|kcm:64448|kcm:64502|kcm:620|kcm:390|kcm:59312|kcm:50250,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 12:00 ~ 4th Ave S & S Jackson St(620) ~ Walk 1m52s ~ 2nd Ave Ext S & S Jackson St(390) ~ BUS 150 12:17 12:47 ~ Andover Park W & Baker Blvd - Bay 1(59312) ~ BUS 156 12:55 13:15:01 ~ 8th Ave S & Des Moines Memorial Dr S(50250) ~ Walk 25m39s -131,4,02:41:30,14267,2098,10:31:35,13:13:05,Metro Transit|Sound Transit,BUS|TRAM,208|554|7|1-Line|A Line,kcm:82425|kcm:64448|kcm:64502|kcm:8494|kcm:8590|kcm:8681|sound-transit:55949|sound-transit:99913|kcm:61120|kcm:61170,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 11:52 ~ Rainier Ave S & S Charles St(8494) ~ Walk 1m31s ~ Rainier Ave S & S Charles St(8590) ~ BUS 7 12:01:06 12:08 ~ Rainier Ave S & S Forest St - Bay 4(8681) ~ Walk 2m40s ~ Mount Baker Station(55949) ~ TRAM 1-Line 12:13 12:40 ~ Angle Lake Station(99913) ~ Walk 2m18s ~ International Blvd & S 200th St(61120) ~ BUS A Line 12:51:37 12:57:09 ~ Pacific Hwy S & S 224th St(61170) ~ Walk 15m56s -131,3,02:51:30,14724,2807,10:31:35,13:23:05,Metro Transit|Sound Transit,BUS|TRAM,208|554|1-Line|A Line,kcm:82425|kcm:64448|kcm:64502|kcm:620|sound-transit:99101|sound-transit:99913|kcm:61120|kcm:61170,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 12:00 ~ 4th Ave S & S Jackson St(620) ~ Walk 12m33s ~ Stadium Station(99101) ~ TRAM 1-Line 12:16 12:50 ~ Angle Lake Station(99913) ~ Walk 2m18s ~ International Blvd & S 200th St(61120) ~ BUS A Line 13:01:37 13:07:09 ~ Pacific Hwy S & S 224th St(61170) ~ Walk 15m56s -131,3,03:06:26,14542,1314,10:31:35,13:38:01,Metro Transit|Sound Transit,BUS,208|554|150|156,kcm:82425|kcm:64448|kcm:64502|kcm:620|kcm:390|kcm:59312|kcm:50450,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 12:00 ~ 4th Ave S & S Jackson St(620) ~ Walk 1m52s ~ 2nd Ave Ext S & S Jackson St(390) ~ BUS 150 12:17 12:47 ~ Andover Park W & Baker Blvd - Bay 1(59312) ~ BUS 156 12:55 13:29:16 ~ 24th Ave S & S 226th St(50450) ~ Walk 8m45s -133,3,03:03:32,14057,898,10:31:35,13:35:07,Metro Transit|Sound Transit,BUS,208|554|150|160,kcm:82425|kcm:64448|kcm:64502|kcm:620|kcm:390|kcm:57455|kcm:57451|kcm:58255,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 12:00 ~ 4th Ave S & S Jackson St(620) ~ Walk 1m52s ~ 2nd Ave Ext S & S Jackson St(390) ~ BUS 150 12:17 13:13 ~ Kent Sounder Station - Bay 5(57455) ~ Walk 44s ~ Kent Sounder Station - Bay 1(57451) ~ BUS 160 13:21 13:32:20 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -135,3,02:45:04,12993,948,10:31:35,13:16:39,Metro Transit|Sound Transit,BUS,208|554|577|181,kcm:82425|kcm:64448|kcm:64502|kcm:620|pierce-transit:30709|pierce-transit:4136|kcm:80433|kcm:83784,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 12:00 ~ 4th Ave S & S Jackson St(620) ~ Walk 1m54s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 577 12:17 12:47 ~ Federal Way TC - Bay 2(4136) ~ Walk 37s ~ Federal Way TC - Bay 3(80433) ~ BUS 181 13:05 13:13:23 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -135,2,02:52:50,14741,3523,10:31:35,13:24:25,Metro Transit|Sound Transit,BUS,208|554|577,kcm:82425|kcm:64448|kcm:64502|kcm:620|pierce-transit:30709|pierce-transit:4136,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 12:00 ~ 4th Ave S & S Jackson St(620) ~ Walk 1m54s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 577 12:17 12:47 ~ Federal Way TC - Bay 2(4136) ~ Walk 37m25s -137,3,02:17:25,11313,944,10:31:35,12:49:00,Metro Transit|Sound Transit,BUS,208|554|125|50,kcm:82425|kcm:64448|kcm:64502|kcm:648|kcm:481|kcm:21990|kcm:31871,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 12:02:35 ~ 4th Ave & Cherry St(648) ~ Walk 2m48s ~ 3rd Ave & Columbia St(481) ~ BUS 125 12:08 12:18 ~ Delridge Way SW & SW Andover St(21990) ~ BUS 50 12:30 12:45:35 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -137,2,02:18:23,12259,3027,10:31:35,12:49:58,Metro Transit|Sound Transit,BUS,208|554|125,kcm:82425|kcm:64448|kcm:64502|kcm:648|kcm:481|kcm:21990,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 12:02:35 ~ 4th Ave & Cherry St(648) ~ Walk 2m48s ~ 3rd Ave & Columbia St(481) ~ BUS 125 12:08 12:18 ~ Delridge Way SW & SW Andover St(21990) ~ Walk 31m58s -137,2,02:22:18,11723,1917,10:31:35,12:53:53,Metro Transit|Sound Transit,BUS,208|554|C Line,kcm:82425|kcm:64448|kcm:64502|kcm:648|kcm:481|kcm:20041,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 12:02:35 ~ 4th Ave & Cherry St(648) ~ Walk 2m48s ~ 3rd Ave & Columbia St(481) ~ BUS C Line 12:17 12:38 ~ SW Alaska St & California Ave SW - Bay 3(20041) ~ Walk 15m53s -139,3,03:30:34,15898,1193,10:31:35,14:02:09,Metro Transit|Pierce Transit|Sound Transit,BUS,208|554|577|402,kcm:82425|kcm:64448|kcm:64502|kcm:620|pierce-transit:30709|pierce-transit:4136|pierce-transit:29410|pierce-transit:1332,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 12:00 ~ 4th Ave S & S Jackson St(620) ~ Walk 1m54s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 577 12:17 12:47 ~ Federal Way TC - Bay 2(4136) ~ Walk 1m10s ~ Federal Way TC - Bay 5(29410) ~ BUS 402 13:10 13:56 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m9s -139,2,03:40:25,16627,2219,10:31:35,14:12:00,Metro Transit|Sound Transit,BUS,208|554|578,kcm:82425|kcm:64448|kcm:64502|kcm:620|pierce-transit:30709|pierce-transit:10401,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 12:00 ~ 4th Ave S & S Jackson St(620) ~ Walk 1m54s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 578 12:32 13:51 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m -140,3,02:46:40,12938,767,10:31:35,13:18:15,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS,208|554|577|Road to Independence,kcm:82425|kcm:64448|kcm:64502|kcm:620|pierce-transit:30709|pierce-transit:4136|pudget-sound-educational:area_622,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 12:00 ~ 4th Ave S & S Jackson St(620) ~ Walk 1m54s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 577 12:17 12:47 ~ Federal Way TC - Bay 2(4136) ~ Walk 1m59s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 12:50:59 13:18:15 -140,2,03:40:25,16627,2219,10:31:35,14:12:00,Metro Transit|Sound Transit,BUS,208|554|578,kcm:82425|kcm:64448|kcm:64502|kcm:620|pierce-transit:30709|pierce-transit:10401,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 12:00 ~ 4th Ave S & S Jackson St(620) ~ Walk 1m54s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 578 12:32 13:51 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m -141,2,02:06:03,10031,924,10:31:35,12:37:38,Metro Transit|Sound Transit,BUS,208|554|3,kcm:82425|kcm:64448|kcm:64502|kcm:730|kcm:600|kcm:41350,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 12:07:55 ~ 4th Ave & Lenora St(730) ~ Walk 2m24s ~ 3rd Ave & Virginia St(600) ~ BUS 3 12:14:57 12:34:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -142,2,01:59:04,9574,889,10:31:35,12:30:39,Metro Transit|Sound Generations|Sound Transit,BUS,208|554|Hyde Shuttle,kcm:82425|kcm:64448|kcm:64502|kcm:18440|sound-generations:area_555,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 12:09 ~ Blanchard St & 6th Ave(18440) ~ Walk 5m12s ~ sound-generations:area_555(area_555) ~ BUS null 12:16:12 12:30:39 -143,2,01:45:17,9177,1478,10:31:35,12:16:52,Metro Transit|Sound Transit,BUS,208|554|36,kcm:82425|kcm:64448|kcm:64502|kcm:8494|kcm:3710|kcm:3820,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 11:52 ~ Rainier Ave S & S Charles St(8494) ~ Walk 9m51s ~ 12th Ave S & S Weller St(3710) ~ BUS 36 12:04:36 12:13:36 ~ Beacon Ave S & S Stevens St(3820) ~ Walk 3m16s -143,1,01:49:13,9676,2668,10:31:35,12:20:48,Metro Transit|Sound Transit,BUS,208|554,kcm:82425|kcm:64448|kcm:64502|kcm:8494,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 11:52 ~ Rainier Ave S & S Charles St(8494) ~ Walk 28m48s -144,3,01:40:12,8854,621,10:31:35,12:11:47,Metro Transit|Sound Generations|Sound Transit,BUS,208|554|7|Hyde Shuttle,kcm:82425|kcm:64448|kcm:64502|kcm:8494|kcm:8590|kcm:8620|sound-generations:area_564,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 11:52 ~ Rainier Ave S & S Charles St(8494) ~ Walk 1m31s ~ Rainier Ave S & S Charles St(8590) ~ BUS 7 12:01:06 12:03:38 ~ Rainier Ave S & S State St(8620) ~ Walk 0s ~ sound-generations:area_564(area_564) ~ BUS null 12:05:38 12:11:47 -144,1,01:49:13,9676,2668,10:31:35,12:20:48,Metro Transit|Sound Transit,BUS,208|554,kcm:82425|kcm:64448|kcm:64502|kcm:8494,Walk 4m ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 11:00 ~ SE Bush St & Rainier Blvd S(64448) ~ Walk 3m19s ~ E Sunset Way & 1st Ave NE(64502) ~ BUS 554 11:22 11:52 ~ Rainier Ave S & S Charles St(8494) ~ Walk 28m48s -145,2,01:59:24,10455,2028,10:06:14,12:05:38,Metro Transit,BUS,2|101|160,kcm:2570|kcm:450|kcm:1230|kcm:79610|kcm:59891|kcm:57375,Walk 1m51s ~ W Mcgraw St & 6th Ave W(2570) ~ BUS 2 10:08:05 10:29 ~ 3rd Ave & Union St(450) ~ Walk 2m1s ~ Union St & 4th Ave(1230) ~ BUS 101 10:33:47 11:03 ~ SW Sunset Blvd & Hardie Ave SW(79610) ~ Walk 4m34s ~ Rainier Ave S & S 3rd Pl(59891) ~ BUS 160 11:22:49 11:47:16 ~ 108th Ave SE & SE 220th Pl(57375) ~ Walk 18m22s -145,2,02:03:09,10735,2100,10:17:29,12:20:38,Metro Transit,BUS,3|101|160,kcm:41300|kcm:480|kcm:340|kcm:79610|kcm:59891|kcm:57375,Walk 3m12s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 3 10:20:41 10:43:20 ~ 3rd Ave & Marion St(480) ~ Walk 1m32s ~ 2nd Ave & Marion St(340) ~ BUS 101 10:51 11:18 ~ SW Sunset Blvd & Hardie Ave SW(79610) ~ Walk 4m34s ~ Rainier Ave S & S 3rd Pl(59891) ~ BUS 160 11:37:22 12:02:16 ~ 108th Ave SE & SE 220th Pl(57375) ~ Walk 18m22s -145,2,02:02:09,10675,2100,10:32:29,12:34:38,Metro Transit,BUS,3|101|160,kcm:41300|kcm:480|kcm:340|kcm:79610|kcm:59891|kcm:57375,Walk 3m12s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 3 10:35:41 10:58:20 ~ 3rd Ave & Marion St(480) ~ Walk 1m32s ~ 2nd Ave & Marion St(340) ~ BUS 101 11:06 11:33 ~ SW Sunset Blvd & Hardie Ave SW(79610) ~ Walk 4m34s ~ Rainier Ave S & S 3rd Pl(59891) ~ BUS 160 11:51:22 12:16:16 ~ 108th Ave SE & SE 220th Pl(57375) ~ Walk 18m22s -147,2,01:38:22,8383,921,10:06:14,11:44:36,Metro Transit,BUS,2|120|165,kcm:2570|kcm:420|kcm:52305|kcm:48620,Walk 1m51s ~ W Mcgraw St & 6th Ave W(2570) ~ BUS 2 10:08:05 10:25:27 ~ 3rd Ave & Virginia St(420) ~ BUS 120 10:30 11:24 ~ Burien Transit Center - Bay 5(52305) ~ BUS 165 11:27 11:34:26 ~ 1st Ave S & SW 178th St(48620) ~ Walk 10m10s -147,2,01:52:34,9310,1022,10:18:02,12:10:36,Metro Transit,BUS,13|2|120|165,kcm:41300|kcm:2220|kcm:420|kcm:52305|kcm:48620,Walk 3m12s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 13 10:21:14 10:36 ~ 3rd Ave & Cedar St(2220) ~ BUS 2 10:36 10:40:27 ~ 3rd Ave & Virginia St(420) ~ BUS 120 10:50 11:44 ~ Burien Transit Center - Bay 5(52305) ~ BUS 165 11:53 12:00:26 ~ 1st Ave S & SW 178th St(48620) ~ Walk 10m10s -147,2,01:51:33,9601,1493,10:19:03,12:10:36,Metro Transit,BUS,1|14|120|165,kcm:2060|kcm:2220|kcm:420|kcm:52305|kcm:48620,Walk 9m8s ~ 10th Ave W & W Crockett St(2060) ~ BUS 1 10:28:11 10:40 ~ 3rd Ave & Cedar St(2220) ~ BUS 14 10:40 10:43:53 ~ 3rd Ave & Virginia St(420) ~ BUS 120 10:50 11:44 ~ Burien Transit Center - Bay 5(52305) ~ BUS 165 11:53 12:00:26 ~ 1st Ave S & SW 178th St(48620) ~ Walk 10m10s -148,4,01:17:46,7791,172,10:00:09,11:17:55,Metro Transit|Sound Generations,BUS,Hyde Shuttle|24|124|120|128|Hyde Shuttle,sound-generations:area_555|kcm:19410|kcm:2220|kcm:420|kcm:22174|kcm:22252|kcm:21080|sound-generations:area_551,sound-generations:area_555(area_555) ~ BUS null 10:00:09 10:08:26Walk 18s ~ Elliott Ave W & W Harrison St(19410) ~ BUS 24 10:10:44 10:14 ~ 3rd Ave & Cedar St(2220) ~ BUS 124 10:14 10:17:38 ~ 3rd Ave & Virginia St(420) ~ BUS 120 10:20 10:48:02 ~ Delridge Way SW & SW Henderson St(22174) ~ Walk 2m ~ Delridge Way SW & SW Henderson St(22252) ~ BUS 128 10:53:59 10:56 ~ SW Roxbury St & 15th Ave SW - Bay 3(21080) ~ Walk 9s ~ sound-generations:area_551(area_551) ~ BUS null 10:58:09 11:17:55 -148,3,01:17:48,7083,21,10:00:09,11:17:57,Metro Transit|Sound Generations,BUS,Hyde Shuttle|24|124|120|Hyde Shuttle,sound-generations:area_555|kcm:19410|kcm:2220|kcm:420|kcm:52030|sound-generations:area_551,sound-generations:area_555(area_555) ~ BUS null 10:00:09 10:08:26Walk 18s ~ Elliott Ave W & W Harrison St(19410) ~ BUS 24 10:10:44 10:14 ~ 3rd Ave & Cedar St(2220) ~ BUS 124 10:14 10:17:38 ~ 3rd Ave & Virginia St(420) ~ BUS 120 10:20 10:55 ~ 15th Ave SW & SW Roxbury St - Bay 1(52030) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:57 11:17:57 -148,3,01:20:29,7433,278,10:06:14,11:26:43,Metro Transit|Sound Generations,BUS,2|120|60|Hyde Shuttle,kcm:2570|kcm:420|kcm:22174|kcm:22252|kcm:21120|sound-generations:area_551,Walk 1m51s ~ W Mcgraw St & 6th Ave W(2570) ~ BUS 2 10:08:05 10:25:27 ~ 3rd Ave & Virginia St(420) ~ BUS 120 10:30 10:58:02 ~ Delridge Way SW & SW Henderson St(22174) ~ Walk 2m ~ Delridge Way SW & SW Henderson St(22252) ~ BUS 60 11:02:51 11:07:37 ~ SW Roxbury St & 5th Ave SW(21120) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 11:09:37 11:26:43 -149,3,01:55:34,10686,1845,10:06:14,12:01:48,Metro Transit|Sound Transit,BUS|TRAM,2|124|1-Line|635,kcm:2570|kcm:2220|kcm:21833|sound-transit:99101|sound-transit:99913|kcm:47200|kcm:47404,Walk 1m51s ~ W Mcgraw St & 6th Ave W(2570) ~ BUS 2 10:08:05 10:21 ~ 3rd Ave & Cedar St(2220) ~ BUS 124 10:28 10:45 ~ 6th Ave S & S Royal Brougham Way(21833) ~ Walk 2m12s ~ Stadium Station(99101) ~ TRAM 1-Line 10:56 11:30 ~ Angle Lake Station(99913) ~ Walk 1m37s ~ S 200th St & 28th Ave S(47200) ~ BUS 635 11:39 11:42:55 ~ S 216th St & 20th Ave S(47404) ~ Walk 18m53s -149,2,01:59:19,11327,3252,10:02:29,12:01:48,Metro Transit|Sound Transit,BUS|TRAM,3|1-Line|635,kcm:41300|kcm:1560|sound-transit:99101|sound-transit:99913|kcm:47200|kcm:47404,Walk 3m12s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 3 10:05:41 10:31 ~ James St & 3rd Ave(1560) ~ Walk 19m38s ~ Stadium Station(99101) ~ TRAM 1-Line 10:56 11:30 ~ Angle Lake Station(99913) ~ Walk 1m37s ~ S 200th St & 28th Ave S(47200) ~ BUS 635 11:39 11:42:55 ~ S 216th St & 20th Ave S(47404) ~ Walk 18m53s -149,2,01:55:59,9850,1437,10:06:14,12:02:13,Metro Transit,BUS,2|124|A Line,kcm:2570|kcm:2220|kcm:60922|kcm:60921|kcm:61170,Walk 1m51s ~ W Mcgraw St & 6th Ave W(2570) ~ BUS 2 10:08:05 10:21 ~ 3rd Ave & Cedar St(2220) ~ BUS 124 10:28 11:20 ~ Tukwila International Blvd Station - Bay 2(60922) ~ Walk 2m9s ~ Tukwila International Blvd Station - Bay 1(60921) ~ BUS A Line 11:30 11:46:17 ~ Pacific Hwy S & S 224th St(61170) ~ Walk 15m56s -150,4,01:24:11,8176,172,10:00:09,11:24:20,Metro Transit|Sound Generations,BUS,Hyde Shuttle|24|124|120|128|Hyde Shuttle,sound-generations:area_555|kcm:19410|kcm:2220|kcm:420|kcm:22174|kcm:22252|kcm:21080|sound-generations:area_551,sound-generations:area_555(area_555) ~ BUS null 10:00:09 10:08:26Walk 18s ~ Elliott Ave W & W Harrison St(19410) ~ BUS 24 10:10:44 10:14 ~ 3rd Ave & Cedar St(2220) ~ BUS 124 10:14 10:17:38 ~ 3rd Ave & Virginia St(420) ~ BUS 120 10:20 10:48:02 ~ Delridge Way SW & SW Henderson St(22174) ~ Walk 2m ~ Delridge Way SW & SW Henderson St(22252) ~ BUS 128 10:53:59 10:56 ~ SW Roxbury St & 15th Ave SW - Bay 3(21080) ~ Walk 9s ~ sound-generations:area_551(area_551) ~ BUS null 10:58:09 11:24:20 -150,3,01:24:13,7468,21,10:00:09,11:24:22,Metro Transit|Sound Generations,BUS,Hyde Shuttle|24|124|120|Hyde Shuttle,sound-generations:area_555|kcm:19410|kcm:2220|kcm:420|kcm:52030|sound-generations:area_551,sound-generations:area_555(area_555) ~ BUS null 10:00:09 10:08:26Walk 18s ~ Elliott Ave W & W Harrison St(19410) ~ BUS 24 10:10:44 10:14 ~ 3rd Ave & Cedar St(2220) ~ BUS 124 10:14 10:17:38 ~ 3rd Ave & Virginia St(420) ~ BUS 120 10:20 10:55 ~ 15th Ave SW & SW Roxbury St - Bay 1(52030) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:57 11:24:22 -150,3,01:26:54,7818,278,10:06:14,11:33:08,Metro Transit|Sound Generations,BUS,2|120|60|Hyde Shuttle,kcm:2570|kcm:420|kcm:22174|kcm:22252|kcm:21120|sound-generations:area_551,Walk 1m51s ~ W Mcgraw St & 6th Ave W(2570) ~ BUS 2 10:08:05 10:25:27 ~ 3rd Ave & Virginia St(420) ~ BUS 120 10:30 10:58:02 ~ Delridge Way SW & SW Henderson St(22174) ~ Walk 2m ~ Delridge Way SW & SW Henderson St(22252) ~ BUS 60 11:02:51 11:07:37 ~ SW Roxbury St & 5th Ave SW(21120) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 11:09:37 11:33:08 -151,2,01:56:53,9196,529,10:06:14,12:03:07,Metro Transit,BUS,2|150|160,kcm:2570|kcm:450|kcm:1230|kcm:57455|kcm:57451|kcm:58255,Walk 1m51s ~ W Mcgraw St & 6th Ave W(2570) ~ BUS 2 10:08:05 10:29 ~ 3rd Ave & Union St(450) ~ Walk 2m1s ~ Union St & 4th Ave(1230) ~ BUS 150 10:41:47 11:41 ~ Kent Sounder Station - Bay 5(57455) ~ Walk 44s ~ Kent Sounder Station - Bay 1(57451) ~ BUS 160 11:49 12:00:20 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -151,2,01:54:08,9098,611,10:17:29,12:11:37,Metro Transit|Sound Transit,BUS,3|578|160,kcm:41300|kcm:480|pierce-transit:20510|pierce-transit:18728|kcm:57774|kcm:57915,Walk 3m12s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 3 10:20:41 10:43:20 ~ 3rd Ave & Marion St(480) ~ Walk 1m27s ~ 2nd Ave & Marion St(20510) ~ BUS 578 11:00 11:49 ~ Auburn Station - Bay 4(18728) ~ Walk 44s ~ Auburn Transit Center - Bay 2(57774) ~ BUS 160 11:57 12:08:49 ~ Auburn Way N & 37th St NE(57915) ~ Walk 2m48s -151,2,01:53:35,9119,695,10:18:02,12:11:37,Metro Transit|Sound Transit,BUS,13|2|578|160,kcm:41300|kcm:2220|kcm:420|pierce-transit:2011772586|pierce-transit:18728|kcm:57774|kcm:57915,Walk 3m12s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 13 10:21:14 10:36 ~ 3rd Ave & Cedar St(2220) ~ BUS 2 10:36 10:40:27 ~ 3rd Ave & Virginia St(420) ~ Walk 2m52s ~ Stewart St & 3rd Ave(2011772586) ~ BUS 578 10:55 11:49 ~ Auburn Station - Bay 4(18728) ~ Walk 44s ~ Auburn Transit Center - Bay 2(57774) ~ BUS 160 11:57 12:08:49 ~ Auburn Way N & 37th St NE(57915) ~ Walk 2m48s -153,1,01:51:56,10276,3219,10:17:29,12:09:25,Metro Transit|Sound Transit,BUS,3|578,kcm:41300|kcm:480|pierce-transit:20510|pierce-transit:4136,Walk 3m12s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 3 10:20:41 10:43:20 ~ 3rd Ave & Marion St(480) ~ Walk 1m27s ~ 2nd Ave & Marion St(20510) ~ BUS 578 11:00 11:32 ~ Federal Way TC - Bay 2(4136) ~ Walk 37m25s -153,1,01:51:23,10297,3303,10:18:02,12:09:25,Metro Transit|Sound Transit,BUS,13|2|578,kcm:41300|kcm:2220|kcm:420|pierce-transit:2011772586|pierce-transit:4136,Walk 3m12s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 13 10:21:14 10:36 ~ 3rd Ave & Cedar St(2220) ~ BUS 2 10:36 10:40:27 ~ 3rd Ave & Virginia St(420) ~ Walk 2m52s ~ Stewart St & 3rd Ave(2011772586) ~ BUS 578 10:55 11:32 ~ Federal Way TC - Bay 2(4136) ~ Walk 37m25s -153,1,01:50:22,10535,3690,10:19:03,12:09:25,Metro Transit|Sound Transit,BUS,1|14|578,kcm:2060|kcm:2220|kcm:480|pierce-transit:20510|pierce-transit:4136,Walk 9m8s ~ 10th Ave W & W Crockett St(2060) ~ BUS 1 10:28:11 10:40 ~ 3rd Ave & Cedar St(2220) ~ BUS 14 10:40 10:49:59 ~ 3rd Ave & Marion St(480) ~ Walk 1m27s ~ 2nd Ave & Marion St(20510) ~ BUS 578 11:00 11:32 ~ Federal Way TC - Bay 2(4136) ~ Walk 37m25s -155,2,01:05:01,6025,440,10:06:14,11:11:15,Metro Transit,BUS,2|C Line|128,kcm:2570|kcm:420|kcm:20041|kcm:32011|kcm:31871,Walk 1m51s ~ W Mcgraw St & 6th Ave W(2570) ~ BUS 2 10:08:05 10:25:27 ~ 3rd Ave & Virginia St(420) ~ BUS C Line 10:30 10:57 ~ SW Alaska St & California Ave SW - Bay 3(20041) ~ Walk 42s ~ SW Alaska St & 44th Ave SW - Bay 4(32011) ~ BUS 128 11:04 11:07:50 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -155,1,01:06:39,6198,1358,10:06:14,11:12:53,Metro Transit,BUS,2|C Line,kcm:2570|kcm:420|kcm:20041,Walk 1m51s ~ W Mcgraw St & 6th Ave W(2570) ~ BUS 2 10:08:05 10:25:27 ~ 3rd Ave & Virginia St(420) ~ BUS C Line 10:30 10:57 ~ SW Alaska St & California Ave SW - Bay 3(20041) ~ Walk 15m53s -155,2,01:01:31,5848,486,10:17:29,11:19:00,Metro Transit,BUS,3|120|50,kcm:41300|kcm:420|kcm:21990|kcm:31871,Walk 3m12s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 3 10:20:41 10:36:53 ~ 3rd Ave & Virginia St(420) ~ BUS 120 10:40 10:57:32 ~ Delridge Way SW & SW Andover St(21990) ~ BUS 50 11:00 11:15:35 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -156,0,02:47:40,19401,12748,10:00:00,12:47:40,,,,,Walk 2h47m40s -157,1,02:20:31,11022,1915,10:17:29,12:38:00,Metro Transit|Sound Transit,BUS,3|578,kcm:41300|kcm:480|pierce-transit:20510|pierce-transit:10401,Walk 3m12s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 3 10:20:41 10:43:20 ~ 3rd Ave & Marion St(480) ~ Walk 1m27s ~ 2nd Ave & Marion St(20510) ~ BUS 578 11:00 12:17 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m -157,2,02:11:40,10353,889,10:47:29,12:59:09,Metro Transit|Pierce Transit|Sound Transit,BUS,3|578|402,kcm:41300|kcm:480|pierce-transit:20510|pierce-transit:4136|pierce-transit:29410|pierce-transit:1332,Walk 3m12s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 3 10:50:41 11:13:20 ~ 3rd Ave & Marion St(480) ~ Walk 1m27s ~ 2nd Ave & Marion St(20510) ~ BUS 578 11:30 12:03 ~ Federal Way TC - Bay 2(4136) ~ Walk 1m10s ~ Federal Way TC - Bay 5(29410) ~ BUS 402 12:11 12:53 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m9s -157,1,02:23:31,11202,1915,10:47:29,13:11:00,Metro Transit|Sound Transit,BUS,3|578,kcm:41300|kcm:480|pierce-transit:20510|pierce-transit:10401,Walk 3m12s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 3 10:50:41 11:13:20 ~ 3rd Ave & Marion St(480) ~ Walk 1m27s ~ 2nd Ave & Marion St(20510) ~ BUS 578 11:30 12:50 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m -159,2,02:04:16,9816,775,10:06:14,12:10:30,Metro Transit|Sound Transit,BUS,2|554|208,kcm:2570|kcm:430|kcm:280|kcm:64590|kcm:64593|kcm:64399,Walk 1m51s ~ W Mcgraw St & 6th Ave W(2570) ~ BUS 2 10:08:05 10:26:59 ~ 3rd Ave & Pine St(430) ~ Walk 2m6s ~ 2nd Ave & Stewart St(280) ~ BUS 554 10:37:53 11:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 11:31 12:04:49 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -159,3,03:09:46,14447,909,10:48:02,13:57:48,Metro Transit|Sound Transit,BUS,13|2|545|224|629,kcm:41300|kcm:2220|kcm:430|kcm:700|kcm:72488|kcm:68803|kcm:64397,Walk 3m12s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 13 10:51:14 11:06 ~ 3rd Ave & Cedar St(2220) ~ BUS 2 11:06 11:11:59 ~ 3rd Ave & Pine St(430) ~ Walk 2m30s ~ 4th Ave & Pike St(700) ~ BUS 545 11:26 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -160,2,02:00:19,9806,1115,10:10:11,12:10:30,Metro Transit|Sound Generations|Sound Transit,BUS,Hyde Shuttle|554|208,sound-generations:area_555|kcm:26665|kcm:1920|kcm:64590|kcm:64593|kcm:64399,sound-generations:area_555(area_555) ~ BUS null 10:10:11 10:24:49Walk 1m17s ~ Westlake Ave & 9th Ave(26665) ~ Walk 7m54s ~ Lenora St & 4th Ave(1920) ~ BUS 554 10:36 11:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 11:31 12:04:49 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -160,3,02:56:25,13718,1015,11:01:23,13:57:48,Metro Transit|Sound Generations|Sound Transit,BUS,Hyde Shuttle|545|224|629,sound-generations:area_555|kcm:10240|kcm:1051|kcm:72488|kcm:68803|kcm:64397,sound-generations:area_555(area_555) ~ BUS null 11:01:23 11:17:56Walk 2m1s ~ Boren Ave & Virginia St(10240) ~ Walk 5m11s ~ Olive Way & Boren Ave(1051) ~ BUS 545 11:27:08 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -161,1,00:52:05,4645,450,10:02:29,10:54:34,Metro Transit,BUS,3|36,kcm:41300|kcm:450|kcm:3820,Walk 3m12s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 3 10:05:41 10:25 ~ 3rd Ave & Union St(450) ~ BUS 36 10:30:15 10:51:18 ~ Beacon Ave S & S Stevens St(3820) ~ Walk 3m16s -161,2,00:51:53,5367,622,10:06:14,10:58:07,Metro Transit,BUS,2|27|60,kcm:2570|kcm:450|kcm:433|kcm:27500|kcm:3800,Walk 1m51s ~ W Mcgraw St & 6th Ave W(2570) ~ BUS 2 10:08:05 10:29 ~ 3rd Ave & Union St(450) ~ Walk 1m32s ~ 3rd Ave & Pike St(433) ~ BUS 27 10:33 10:40:48 ~ E Yesler Way & Broadway(27500) ~ BUS 60 10:44:43 10:53 ~ Beacon Ave S & S Bayview St(3800) ~ Walk 5m7s -161,1,00:58:38,4962,349,10:06:14,11:04:52,Metro Transit,BUS,2|36,kcm:2570|kcm:450|kcm:3820,Walk 1m51s ~ W Mcgraw St & 6th Ave W(2570) ~ BUS 2 10:08:05 10:29 ~ 3rd Ave & Union St(450) ~ BUS 36 10:40:15 11:01:36 ~ Beacon Ave S & S Stevens St(3820) ~ Walk 3m16s -162,2,00:41:30,4446,219,10:00:09,10:41:39,Metro Transit|Sound Generations|Sound Transit,BUS|TRAM,Hyde Shuttle|24|124|1-Line,sound-generations:area_555|kcm:19410|kcm:2220|kcm:21833|sound-transit:99101|sound-transit:99121,sound-generations:area_555(area_555) ~ BUS null 10:00:09 10:08:26Walk 18s ~ Elliott Ave W & W Harrison St(19410) ~ BUS 24 10:10:44 10:14 ~ 3rd Ave & Cedar St(2220) ~ BUS 124 10:14 10:31 ~ 6th Ave S & S Royal Brougham Way(21833) ~ Walk 2m12s ~ Stadium Station(99101) ~ TRAM 1-Line 10:36 10:41 ~ Beacon Hill Station(99121) ~ Walk 39s -162,2,00:46:01,4639,101,10:05:38,10:51:39,Sound Generations|Sound Transit,BUS|TRAM,Hyde Shuttle|545|1-Line,sound-generations:area_555|kcm:905|kcm:760|sound-transit:1108|sound-transit:99121,sound-generations:area_555(area_555) ~ BUS null 10:05:38 10:23:57Walk 25s ~ Stewart St & Yale Ave N(905) ~ BUS 545 10:26:22 10:28 ~ 5th Ave & Pine St(760) ~ Walk 20s ~ Westlake Station(1108) ~ TRAM 1-Line 10:39 10:51 ~ Beacon Hill Station(99121) ~ Walk 39s -162,1,00:49:12,4851,906,10:02:27,10:51:39,Sound Generations|Sound Transit,BUS|TRAM,Hyde Shuttle|1-Line,sound-generations:area_555|kcm:2275|sound-transit:99610|sound-transit:99121,sound-generations:area_555(area_555) ~ BUS null 10:02:27 10:21:05Walk 4m12s ~ E Denny Way & Bellevue Ave E(2275) ~ Walk 8m43s ~ Capitol Hill Station(99610) ~ TRAM 1-Line 10:36 10:51 ~ Beacon Hill Station(99121) ~ Walk 39s -163,2,01:31:07,8781,2053,10:03:31,11:34:38,Metro Transit|Sound Transit,BUS|TRAM,1-Line|101|160,sound-transit:99240|sound-transit:99256|kcm:99263|kcm:79610|kcm:59891|kcm:57375,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:05 10:08 ~ SODO Station(99256) ~ Walk 2m30s ~ SODO Busway & S Lander St(99263) ~ BUS 101 10:16 10:33 ~ SW Sunset Blvd & Hardie Ave SW(79610) ~ Walk 4m34s ~ Rainier Ave S & S 3rd Pl(59891) ~ BUS 160 10:51:49 11:16:16 ~ 108th Ave SE & SE 220th Pl(57375) ~ Walk 18m22s -163,2,01:37:07,9141,2053,10:13:31,11:50:38,Metro Transit|Sound Transit,BUS|TRAM,1-Line|101|160,sound-transit:99240|sound-transit:99256|kcm:99263|kcm:79610|kcm:59891|kcm:57375,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:15 10:18 ~ SODO Station(99256) ~ Walk 2m30s ~ SODO Busway & S Lander St(99263) ~ BUS 101 10:31 10:48 ~ SW Sunset Blvd & Hardie Ave SW(79610) ~ Walk 4m34s ~ Rainier Ave S & S 3rd Pl(59891) ~ BUS 160 11:07:49 11:32:16 ~ 108th Ave SE & SE 220th Pl(57375) ~ Walk 18m22s -163,1,01:44:26,10023,3496,10:06:12,11:50:38,Metro Transit,BUS,101|160,kcm:99266|kcm:79610|kcm:59891|kcm:57375,Walk 23m3s ~ SODO Busway & S Holgate St(99266) ~ BUS 101 10:29:15 10:48 ~ SW Sunset Blvd & Hardie Ave SW(79610) ~ Walk 4m34s ~ Rainier Ave S & S 3rd Pl(59891) ~ BUS 160 11:07:49 11:32:16 ~ 108th Ave SE & SE 220th Pl(57375) ~ Walk 18m22s -165,1,01:19:05,8303,3196,10:20:21,11:39:26,Metro Transit|Sound Transit,BUS|TRAM,1-Line|F Line,sound-transit:99121|sound-transit:99900|kcm:60923|kcm:47646,Walk 39s ~ Beacon Hill Station(99121) ~ TRAM 1-Line 10:21 10:43 ~ Tukwila Int'l Blvd Station(99900) ~ Walk 1m11s ~ Tukwila International Blvd Station - Bay 3(60923) ~ BUS F Line 10:49 11:00:05 ~ SW 156th St & 2nd Ave SW(47646) ~ Walk 39m21s -165,1,01:09:19,7067,2317,10:30:21,11:39:40,Metro Transit|Sound Transit,BUS|TRAM,1-Line|156,sound-transit:99121|sound-transit:99904|kcm:60903|kcm:50250,Walk 39s ~ Beacon Hill Station(99121) ~ TRAM 1-Line 10:31 10:56 ~ SeaTac/Airport Station(99904) ~ Walk 6m47s ~ S 176th St & 30th Ave S - Bay 3(60903) ~ BUS 156 11:07 11:14:01 ~ 8th Ave S & Des Moines Memorial Dr S(50250) ~ Walk 25m39s -165,2,01:14:15,6946,928,10:30:21,11:44:36,Metro Transit|Sound Transit,BUS|TRAM,1-Line|F Line|165,sound-transit:99121|sound-transit:99900|kcm:60923|kcm:53720|kcm:53975|kcm:48620,Walk 39s ~ Beacon Hill Station(99121) ~ TRAM 1-Line 10:31 10:53 ~ Tukwila Int'l Blvd Station(99900) ~ Walk 1m11s ~ Tukwila International Blvd Station - Bay 3(60923) ~ BUS F Line 11:04 11:15:59 ~ 4th Ave SW & SW 156th St(53720) ~ Walk 9s ~ 4th Ave SW & SW 156th St(53975) ~ BUS 165 11:28:44 11:34:26 ~ 1st Ave S & SW 178th St(48620) ~ Walk 10m10s -166,1,00:51:14,4544,380,10:00:51,10:52:05,Metro Transit|Sound Generations,BUS,60|Hyde Shuttle,kcm:42048|kcm:21170|sound-generations:area_551,Walk 5m12s ~ 15th Ave S & S Stevens St(42048) ~ BUS 60 10:06:03 10:32:46 ~ SW Roxbury St & 5th Pl SW(21170) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:34:46 10:52:05 -166,2,00:50:36,4852,21,10:01:29,10:52:05,Metro Transit|Sound Generations,BUS,Hyde Shuttle|60|Hyde Shuttle,sound-generations:area_564|kcm:42048|kcm:21170|sound-generations:area_551,sound-generations:area_564(area_564) ~ BUS null 10:01:29 10:03:45Walk 18s ~ 15th Ave S & S Stevens St(42048) ~ BUS 60 10:06:03 10:32:46 ~ SW Roxbury St & 5th Pl SW(21170) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:34:46 10:52:05 -166,1,00:51:14,4544,380,10:13:51,11:05:05,Metro Transit|Sound Generations,BUS,60|Hyde Shuttle,kcm:42048|kcm:21170|sound-generations:area_551,Walk 5m12s ~ 15th Ave S & S Stevens St(42048) ~ BUS 60 10:19:03 10:45:46 ~ SW Roxbury St & 5th Pl SW(21170) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:47:46 11:05:05 -167,1,01:00:52,5893,1420,10:10:21,11:11:13,Metro Transit|Sound Transit,BUS|TRAM,1-Line|A Line,sound-transit:99121|sound-transit:99913|kcm:61120|kcm:61170,Walk 39s ~ Beacon Hill Station(99121) ~ TRAM 1-Line 10:11 10:40 ~ Angle Lake Station(99913) ~ Walk 2m18s ~ International Blvd & S 200th St(61120) ~ BUS A Line 10:50:12 10:55:17 ~ Pacific Hwy S & S 224th St(61170) ~ Walk 15m56s -167,1,01:01:52,5953,1420,10:20:21,11:22:13,Metro Transit|Sound Transit,BUS|TRAM,1-Line|A Line,sound-transit:99121|sound-transit:99913|kcm:61120|kcm:61170,Walk 39s ~ Beacon Hill Station(99121) ~ TRAM 1-Line 10:21 10:50 ~ Angle Lake Station(99913) ~ Walk 2m18s ~ International Blvd & S 200th St(61120) ~ BUS A Line 11:01:12 11:06:17 ~ Pacific Hwy S & S 224th St(61170) ~ Walk 15m56s -167,1,01:01:27,6074,1610,10:30:21,11:31:48,Metro Transit|Sound Transit,BUS|TRAM,1-Line|635,sound-transit:99121|sound-transit:99913|kcm:47200|kcm:47404,Walk 39s ~ Beacon Hill Station(99121) ~ TRAM 1-Line 10:31 11:00 ~ Angle Lake Station(99913) ~ Walk 1m37s ~ S 200th St & 28th Ave S(47200) ~ BUS 635 11:09 11:12:55 ~ S 216th St & 20th Ave S(47404) ~ Walk 18m53s -168,1,00:57:39,4929,380,10:00:51,10:58:30,Metro Transit|Sound Generations,BUS,60|Hyde Shuttle,kcm:42048|kcm:21170|sound-generations:area_551,Walk 5m12s ~ 15th Ave S & S Stevens St(42048) ~ BUS 60 10:06:03 10:32:46 ~ SW Roxbury St & 5th Pl SW(21170) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:34:46 10:58:30 -168,2,00:57:01,5237,21,10:01:29,10:58:30,Metro Transit|Sound Generations,BUS,Hyde Shuttle|60|Hyde Shuttle,sound-generations:area_564|kcm:42048|kcm:21170|sound-generations:area_551,sound-generations:area_564(area_564) ~ BUS null 10:01:29 10:03:45Walk 18s ~ 15th Ave S & S Stevens St(42048) ~ BUS 60 10:06:03 10:32:46 ~ SW Roxbury St & 5th Pl SW(21170) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:34:46 10:58:30 -168,2,00:51:14,5025,206,10:10:21,11:01:35,Metro Transit|Sound Generations|Sound Transit,BUS|TRAM,1-Line|A Line|Hyde Shuttle,sound-transit:99121|sound-transit:99913|kcm:61120|kcm:61150|sound-generations:area_551,Walk 39s ~ Beacon Hill Station(99121) ~ TRAM 1-Line 10:11 10:40 ~ Angle Lake Station(99913) ~ Walk 2m18s ~ International Blvd & S 200th St(61120) ~ BUS A Line 10:50:12 10:53:30 ~ Pacific Hwy S & S 216th St(61150) ~ Walk 0s ~ sound-generations:area_551(area_551) ~ BUS null 10:55:30 11:01:35 -169,2,01:17:36,6862,554,10:13:31,11:31:07,Metro Transit|Sound Transit,BUS|TRAM,1-Line|150|160,sound-transit:99240|sound-transit:99256|kcm:99263|kcm:57455|kcm:57451|kcm:58255,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:15 10:18 ~ SODO Station(99256) ~ Walk 2m30s ~ SODO Busway & S Lander St(99263) ~ BUS 150 10:24 11:11 ~ Kent Sounder Station - Bay 5(57455) ~ Walk 44s ~ Kent Sounder Station - Bay 1(57451) ~ BUS 160 11:17 11:28:20 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -169,2,01:23:36,7222,554,10:23:31,11:47:07,Metro Transit|Sound Transit,BUS|TRAM,1-Line|150|160,sound-transit:99240|sound-transit:99256|kcm:99263|kcm:57455|kcm:57451|kcm:58255,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:25 10:28 ~ SODO Station(99256) ~ Walk 2m30s ~ SODO Busway & S Lander St(99263) ~ BUS 150 10:39 11:26 ~ Kent Sounder Station - Bay 5(57455) ~ Walk 44s ~ Kent Sounder Station - Bay 1(57451) ~ BUS 160 11:33 11:44:20 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -169,1,01:32:55,8225,1997,10:14:12,11:47:07,Metro Transit,BUS,150|160,kcm:99266|kcm:57455|kcm:57451|kcm:58255,Walk 23m3s ~ SODO Busway & S Holgate St(99266) ~ BUS 150 10:37:15 11:26 ~ Kent Sounder Station - Bay 5(57455) ~ Walk 44s ~ Kent Sounder Station - Bay 1(57451) ~ BUS 160 11:33 11:44:20 ~ Auburn Way N & 37th St NE(58255) ~ Walk 2m47s -170,2,01:12:11,6351,298,10:13:31,11:25:42,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS|TRAM,1-Line|150|Road to Independence,sound-transit:99240|sound-transit:99256|kcm:99263|kcm:80580|pudget-sound-educational:area_622,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:15 10:18 ~ SODO Station(99256) ~ Walk 2m30s ~ SODO Busway & S Lander St(99263) ~ BUS 150 10:24 11:08:20 ~ W James St & Lincoln Ave N(80580) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 11:10:20 11:25:42 -170,2,01:17:11,6651,298,10:23:31,11:40:42,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS|TRAM,1-Line|150|Road to Independence,sound-transit:99240|sound-transit:99256|kcm:99263|kcm:80580|pudget-sound-educational:area_622,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:25 10:28 ~ SODO Station(99256) ~ Walk 2m30s ~ SODO Busway & S Lander St(99263) ~ BUS 150 10:39 11:23:20 ~ W James St & Lincoln Ave N(80580) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 11:25:20 11:40:42 -170,1,01:26:30,7653,1741,10:14:12,11:40:42,Metro Transit|Puget Sound Educational Service District,BUS,150|Road to Independence,kcm:99266|kcm:80580|pudget-sound-educational:area_622,Walk 23m3s ~ SODO Busway & S Holgate St(99266) ~ BUS 150 10:37:15 11:23:20 ~ W James St & Lincoln Ave N(80580) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 11:25:20 11:40:42 -171,2,01:08:51,6341,576,10:05:00,11:13:51,Metro Transit|Sound Transit,BUS,36|578|181,kcm:3460|kcm:1530|pierce-transit:30709|pierce-transit:4136|kcm:80433|kcm:83784,Walk 2m25s ~ Beacon Ave S & S Stevens St(3460) ~ BUS 36 10:07:25 10:22 ~ S Jackson St & 5th Ave S(1530) ~ Walk 1m52s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 578 10:33 11:01 ~ Federal Way TC - Bay 2(4136) ~ Walk 37s ~ Federal Way TC - Bay 3(80433) ~ BUS 181 11:04 11:10:35 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -171,3,01:00:20,6596,799,10:13:31,11:13:51,Metro Transit|Sound Transit,BUS|TRAM,1-Line|24|578|181,sound-transit:99240|sound-transit:99260|kcm:30635|kcm:619|pierce-transit:30709|pierce-transit:4136|kcm:80433|kcm:83784,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:15 10:20 ~ Stadium Station(99260) ~ Walk 3m46s ~ 4th Ave S & S Royal Brougham Way(30635) ~ BUS 24 10:26 10:28 ~ 4th Ave S & S Jackson St(619) ~ Walk 1m54s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 578 10:33 11:01 ~ Federal Way TC - Bay 2(4136) ~ Walk 37s ~ Federal Way TC - Bay 3(80433) ~ BUS 181 11:04 11:10:35 ~ SW 320th St & 1st Ave S(83784) ~ Walk 3m16s -171,1,01:33:25,9097,3151,10:05:00,11:38:25,Metro Transit|Sound Transit,BUS,36|578,kcm:3460|kcm:1530|pierce-transit:30709|pierce-transit:4136,Walk 2m25s ~ Beacon Ave S & S Stevens St(3460) ~ BUS 36 10:07:25 10:22 ~ S Jackson St & 5th Ave S(1530) ~ Walk 1m52s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 578 10:33 11:01 ~ Federal Way TC - Bay 2(4136) ~ Walk 37m25s -173,1,00:44:29,4230,503,10:03:31,10:48:00,Metro Transit|Sound Transit,BUS|TRAM,1-Line|50,sound-transit:99240|sound-transit:99256|kcm:99261|kcm:31871,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:05 10:08 ~ SODO Station(99256) ~ Walk 2m7s ~ S Lander St & SODO Busway(99261) ~ BUS 50 10:21 10:44:35 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -173,1,00:37:29,3810,503,10:23:31,11:01:00,Metro Transit|Sound Transit,BUS|TRAM,1-Line|50,sound-transit:99240|sound-transit:99256|kcm:99261|kcm:31871,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:25 10:28 ~ SODO Station(99256) ~ Walk 2m7s ~ S Lander St & SODO Busway(99261) ~ BUS 50 10:33 10:57:35 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -173,0,00:46:48,4302,1227,10:14:12,11:01:00,Metro Transit,BUS,50,kcm:30530|kcm:31871,Walk 12m56s ~ S Columbian Way & S Spokane St(30530) ~ BUS 50 10:27:08 10:57:35 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m25s -174,1,00:24:22,2815,209,10:03:31,10:27:53,Sound Generations|Sound Transit,BUS|TRAM,1-Line|Hyde Shuttle,sound-transit:99240|sound-transit:99256|sound-generations:area_560,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:05 10:08 ~ SODO Station(99256) ~ Walk 1m20s ~ sound-generations:area_560(area_560) ~ BUS null 10:11:20 10:27:53 -174,1,00:24:22,2815,209,10:13:31,10:37:53,Sound Generations|Sound Transit,BUS|TRAM,1-Line|Hyde Shuttle,sound-transit:99240|sound-transit:99256|sound-generations:area_560,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:15 10:18 ~ SODO Station(99256) ~ Walk 1m20s ~ sound-generations:area_560(area_560) ~ BUS null 10:21:20 10:37:53 -174,1,00:24:22,2815,209,10:23:31,10:47:53,Sound Generations|Sound Transit,BUS|TRAM,1-Line|Hyde Shuttle,sound-transit:99240|sound-transit:99256|sound-generations:area_560,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:25 10:28 ~ SODO Station(99256) ~ Walk 1m20s ~ sound-generations:area_560(area_560) ~ BUS null 10:31:20 10:47:53 -175,2,01:51:09,9053,821,10:05:00,11:56:09,Metro Transit|Pierce Transit|Sound Transit,BUS,36|578|402,kcm:3460|kcm:1530|pierce-transit:30709|pierce-transit:4136|pierce-transit:29410|pierce-transit:1332,Walk 2m25s ~ Beacon Ave S & S Stevens St(3460) ~ BUS 36 10:07:25 10:22 ~ S Jackson St & 5th Ave S(1530) ~ Walk 1m52s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 578 10:33 11:01 ~ Federal Way TC - Bay 2(4136) ~ Walk 1m10s ~ Federal Way TC - Bay 5(29410) ~ BUS 402 11:10 11:50 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m9s -175,1,02:00:00,9723,1847,10:05:00,12:05:00,Metro Transit|Sound Transit,BUS,36|578,kcm:3460|kcm:1530|pierce-transit:30709|pierce-transit:10401,Walk 2m25s ~ Beacon Ave S & S Stevens St(3460) ~ BUS 36 10:07:25 10:22 ~ S Jackson St & 5th Ave S(1530) ~ Walk 1m52s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 578 10:33 11:44 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m -175,2,01:51:45,9310,1110,10:13:31,12:05:16,Pierce Transit|Sound Transit,BUS|TRAM,1-Line|594|400,sound-transit:99240|sound-transit:99260|pierce-transit:595|pierce-transit:20163|pierce-transit:12938|pierce-transit:8058,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:15 10:20 ~ Stadium Station(99260) ~ Walk 1m4s ~ Bus Wy & Royal Brougham St(595) ~ BUS 594 10:30 11:16 ~ Tacoma Dome Station - Zone E(20163) ~ Walk 1m10s ~ Tacoma Dome Station - Zone C(12938) ~ BUS 400 11:30 11:54 ~ 5th St SW & 9th Ave SW - Red Lot(8058) ~ Walk 11m16s -176,2,01:27:15,7294,395,10:05:00,11:32:15,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS,36|578|Road to Independence,kcm:3460|kcm:1530|pierce-transit:30709|pierce-transit:4136|pudget-sound-educational:area_622,Walk 2m25s ~ Beacon Ave S & S Stevens St(3460) ~ BUS 36 10:07:25 10:22 ~ S Jackson St & 5th Ave S(1530) ~ Walk 1m52s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 578 10:33 11:01 ~ Federal Way TC - Bay 2(4136) ~ Walk 1m59s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 11:04:59 11:32:15 -176,3,01:18:44,7549,618,10:13:31,11:32:15,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS|TRAM,1-Line|24|578|Road to Independence,sound-transit:99240|sound-transit:99260|kcm:30635|kcm:619|pierce-transit:30709|pierce-transit:4136|pudget-sound-educational:area_622,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:15 10:20 ~ Stadium Station(99260) ~ Walk 3m46s ~ 4th Ave S & S Royal Brougham Way(30635) ~ BUS 24 10:26 10:28 ~ 4th Ave S & S Jackson St(619) ~ Walk 1m54s ~ 2nd Ave Ext & Jackson St S(30709) ~ BUS 578 10:33 11:01 ~ Federal Way TC - Bay 2(4136) ~ Walk 1m59s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 11:04:59 11:32:15 -176,2,01:23:14,7014,298,10:13:31,11:36:45,Metro Transit|Puget Sound Educational Service District|Sound Transit,BUS|TRAM,1-Line|150|Road to Independence,sound-transit:99240|sound-transit:99256|kcm:99263|kcm:80580|pudget-sound-educational:area_622,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:15 10:18 ~ SODO Station(99256) ~ Walk 2m30s ~ SODO Busway & S Lander St(99263) ~ BUS 150 10:24 11:08:20 ~ W James St & Lincoln Ave N(80580) ~ Walk 0s ~ pudget-sound-educational:area_622(area_622) ~ BUS null 11:10:20 11:36:45 -177,2,01:45:30,8652,741,10:25:00,12:10:30,Metro Transit|Sound Transit,BUS,36|554|208,kcm:3460|kcm:1510|kcm:1480|kcm:64590|kcm:64593|kcm:64399,Walk 2m25s ~ Beacon Ave S & S Stevens St(3460) ~ BUS 36 10:27:25 10:40:54 ~ S Jackson St & Maynard Ave S(1510) ~ Walk 1m28s ~ S Jackson St & Maynard Ave S(1480) ~ BUS 554 10:46:10 11:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 11:31 12:04:49 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -177,1,01:47:04,9477,2553,10:23:26,12:10:30,Metro Transit|Sound Transit,BUS,554|208,kcm:8590|kcm:64590|kcm:64593|kcm:64399,Walk 27m34s ~ Rainier Ave S & S Charles St(8590) ~ BUS 554 10:51 11:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 11:31 12:04:49 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -177,3,02:54:17,13493,861,11:03:31,13:57:48,Metro Transit|Sound Transit,BUS|TRAM,1-Line|545|224|629,sound-transit:99240|sound-transit:99260|kcm:21765|kcm:72488|kcm:68803|kcm:64397,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 11:05 11:10 ~ Stadium Station(99260) ~ Walk 3m13s ~ 6th Ave S & S Royal Brougham Way(21765) ~ BUS 545 11:17 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -178,2,01:36:36,8393,1099,10:33:54,12:10:30,Metro Transit|Sound Generations|Sound Transit,BUS,Hyde Shuttle|554|208,sound-generations:area_564|kcm:8485|kcm:8590|kcm:64590|kcm:64593|kcm:64399,sound-generations:area_564(area_564) ~ BUS null 10:33:54 10:40:49Walk 31s ~ Rainier Ave S & I-90(8485) ~ Walk 7m40s ~ Rainier Ave S & S Charles St(8590) ~ BUS 554 10:51 11:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 11:31 12:04:49 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -178,1,01:47:04,9477,2553,10:23:26,12:10:30,Metro Transit|Sound Transit,BUS,554|208,kcm:8590|kcm:64590|kcm:64593|kcm:64399,Walk 27m34s ~ Rainier Ave S & S Charles St(8590) ~ BUS 554 10:51 11:12 ~ Issaquah Transit Center - Bay 6(64590) ~ Walk 1m1s ~ Issaquah Transit Center - Bay 4(64593) ~ BUS 208 11:31 12:04:49 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m41s -178,3,02:54:17,13493,861,11:03:31,13:57:48,Metro Transit|Sound Transit,BUS|TRAM,1-Line|545|224|629,sound-transit:99240|sound-transit:99260|kcm:21765|kcm:72488|kcm:68803|kcm:64397,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 11:05 11:10 ~ Stadium Station(99260) ~ Walk 3m13s ~ 6th Ave S & S Royal Brougham Way(21765) ~ BUS 545 11:17 12:01:45 ~ Redmond Way & 166th Ave NE(72488) ~ BUS 224 12:15:31 12:49 ~ Brown Ave NE & NE Richardson St(68803) ~ BUS 629 13:04 13:51 ~ Railroad Avenue Southeast Ave SE & SE Northern St(64397) ~ Walk 6m48s -179,2,00:50:07,5144,453,10:03:31,10:53:38,Metro Transit|Sound Transit,BUS|TRAM,1-Line|131|3,sound-transit:99240|sound-transit:532|kcm:531|kcm:605|kcm:41350,Walk 1m29s ~ Beacon Hill Station(99240) ~ TRAM 1-Line 10:05 10:14 ~ Pioneer Square Station(532) ~ Walk 1m29s ~ 3rd Ave & James St(531) ~ BUS 131 10:17:57 10:27 ~ 3rd Ave & Bell St(605) ~ BUS 3 10:33:07 10:50:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -179,1,00:53:47,4700,388,10:05:00,10:58:47,Metro Transit,BUS,36|13,kcm:3460|kcm:575|kcm:41350,Walk 2m25s ~ Beacon Ave S & S Stevens St(3460) ~ BUS 36 10:07:25 10:31 ~ 3rd Ave & Pike St(575) ~ BUS 13 10:34 10:55:44 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -179,1,00:53:38,4691,388,10:15:00,11:08:38,Metro Transit,BUS,36|3,kcm:3460|kcm:538|kcm:41350,Walk 2m25s ~ Beacon Ave S & S Stevens St(3460) ~ BUS 36 10:17:25 10:36:22 ~ 3rd Ave & Columbia St(538) ~ BUS 3 10:38:24 11:05:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m3s -180,0,01:55:43,13349,8814,10:00:00,11:55:43,,,,,Walk 1h55m43s +1,0,23m22s,2002,0,10:00:00,10:23:22,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:23:22 +1,0,23m22s,2002,0,10:00:00,10:23:22,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:23:22 +1,0,23m22s,2002,0,10:00:00,10:23:22,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:23:22 +2,1,36m2s,3945,788,10:40:34,11:16:36,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|165,volunteer:area_873|kcm:48550|kcm:48620,volunteer:area_873(area_873) ~ BUS null 10:40:34 10:59:42 ~ Walk 5s ~ 1st Ave S & SW 156th St(48550) ~ BUS 165 11:01:47 11:06:26 ~ 1st Ave S & SW 178th St(48620) ~ Walk 10m10s +2,1,1h4m17s,5712,884,10:21:11,11:25:28,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|165,volunteer:area_873|kcm:57448|kcm:47570,volunteer:area_873(area_873) ~ BUS null 10:21:11 10:24:50 ~ Walk 0s ~ SE 240th St & 116th Ave SE(57448) ~ BUS 165 10:26:50 11:14 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m28s +2,1,1h4m17s,5712,884,10:51:11,11:55:28,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|165,volunteer:area_873|kcm:57448|kcm:47570,volunteer:area_873(area_873) ~ BUS null 10:51:11 10:54:50 ~ Walk 0s ~ SE 240th St & 116th Ave SE(57448) ~ BUS 165 10:56:50 11:44 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m28s +3,0,18m45s,1725,0,10:00:00,10:18:45,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:18:45 +3,0,18m45s,1725,0,10:00:00,10:18:45,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:18:45 +3,0,18m45s,1725,0,10:00:00,10:18:45,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:18:45 +4,1,28m57s,3475,729,10:19:40,10:48:37,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|156,volunteer:area_873|kcm:48980|kcm:48990,volunteer:area_873(area_873) ~ BUS null 10:19:40 10:36:20 ~ Walk 0s ~ 24th Ave S & S 230th St(48980) ~ BUS 156 10:38:20 10:39:02 ~ 24th Ave S & S 226th St(48990) ~ Walk 9m35s +4,1,28m57s,3475,729,10:49:40,11:18:37,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|156,volunteer:area_873|kcm:48980|kcm:48990,volunteer:area_873(area_873) ~ BUS null 10:49:40 11:06:20 ~ Walk 0s ~ 24th Ave S & S 230th St(48980) ~ BUS 156 11:08:20 11:09:02 ~ 24th Ave S & S 226th St(48990) ~ Walk 9m35s +4,0,1h24m18s,8796,4255,10:23:15,11:47:33,Metro Transit,BUS,165,kcm:57448|kcm:50480,Walk 33m35s ~ SE 240th St & 116th Ave SE(57448) ~ BUS 165 10:56:50 11:25:40 ~ Pacific Hwy S & Kent Des Moines Rd(50480) ~ Walk 21m53s +5,0,31m32s,2556,89,10:00:00,10:31:32,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:30:19 ~ Walk 1m13s +5,0,31m32s,2556,89,10:00:00,10:31:32,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:30:19 ~ Walk 1m13s +5,0,31m32s,2556,89,10:00:00,10:31:32,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:30:19 ~ Walk 1m13s +6,1,45m11s,4547,878,10:01:00,10:46:11,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|50,volunteer:area_873|kcm:31890|kcm:31900,volunteer:area_873(area_873) ~ BUS null 10:01 10:31:33 ~ Walk 24s ~ California Ave SW & SW Hanford St(31890) ~ BUS 50 10:33:57 10:34:37 ~ California Ave SW & SW Stevens St(31900) ~ Walk 11m34s +6,1,36m29s,3577,264,10:33:47,11:10:16,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|128,volunteer:area_873|kcm:31850|kcm:31871,volunteer:area_873(area_873) ~ BUS null 10:33:47 11:03:15 ~ Walk 25s ~ California Ave SW & SW Andover St(31850) ~ BUS 128 11:05:40 11:06:50 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m26s +7,0,28m30s,2310,0,10:00:00,10:28:30,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_1083,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:28:30 +7,0,28m30s,2310,0,07:00:00,07:28:30,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_1083,ccsww-kc:area_897(area_897) ~ BUS null 7:00 7:28:30 +8,1,36m2s,3709,474,10:10:01,10:46:03,Pierce Transit|Volunteer Services: King County,BUS,Volunteer Services: King County|402,ccsww-kc:area_1083|pierce:1334|pierce:1294,ccsww-kc:area_897(area_897) ~ BUS null 10:10:01 10:36:52 ~ Walk 32s ~ Meridian S & 10th Ave SE(1334) ~ BUS 402 10:39:24 10:40:12 ~ Meridian S & 9th Ave SE(1294) ~ Walk 5m51s +8,1,41m,3997,457,11:04:55,11:45:55,Pierce Transit|Volunteer Services: King County,BUS,Volunteer Services: King County|402,ccsww-kc:area_1083|pierce:1338|pierce:1332,ccsww-kc:area_897(area_897) ~ BUS null 11:04:55 11:30:20 ~ Walk 0s ~ Meridian N & River Rd(1338) ~ BUS 402 11:32:20 11:39:31 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m24s +9,0,38m30s,2910,0,10:00:00,10:38:30,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:38:30 +9,0,38m30s,2910,0,10:00:00,10:38:30,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:38:30 +9,0,38m30s,2910,0,10:00:00,10:38:30,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:38:30 +10,1,46m38s,4213,294,10:23:47,11:10:25,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|SVT,volunteer:area_873|kcm:85395|kcm:82425,volunteer:area_873(area_873) ~ BUS null 10:23:47 11:00:09 ~ Walk 0s ~ 384th Ave SE & SE 92nd St(85395) ~ BUS SVT 11:02:09 11:06:26 ~ Railroad Ave S & SE King St(82425) ~ Walk 3m59s +10,1,52m29s,4665,434,11:18:00,12:10:29,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|208,volunteer:area_873|kcm:64425|kcm:64399,volunteer:area_873(area_873) ~ BUS null 11:18 11:50:44 ~ Walk 8s ~ Snoqualmie Pkwy & SE Jacobia St(64425) ~ BUS 208 11:52:52 12:04:49 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m40s +11,0,35m9s,2711,3,10:00:00,10:35:09,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:35:06 ~ Walk 3s +11,0,35m9s,2711,3,10:00:00,10:35:09,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:35:06 ~ Walk 3s +11,0,35m9s,2711,3,10:00:00,10:35:09,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:35:06 ~ Walk 3s +12,1,44m58s,4070,248,10:02:08,10:47:06,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|4,volunteer:area_873|kcm:4280|kcm:41350,volunteer:area_873(area_873) ~ BUS null 10:02:08 10:33:22 ~ Walk 6s ~ Taylor Ave N & Lee St(4280) ~ BUS 4 10:35:28 10:43:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m31s +13,0,25m36s,2136,0,10:00:00,10:25:36,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:25:36 +13,0,25m36s,2136,0,10:00:00,10:25:36,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:25:36 +13,0,25m36s,2136,0,10:00:00,10:25:36,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:25:36 +14,1,33m26s,3274,95,10:16:57,10:50:23,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|36,volunteer:area_873|kcm:30390|kcm:3470,volunteer:area_873(area_873) ~ BUS null 10:16:57 10:38:44 ~ Walk 0s ~ Beacon Ave S & S Spencer St(30390) ~ BUS 36 10:40:44 10:49 ~ Beacon Ave S & S Lander St(3470) ~ Walk 1m23s +14,1,33m26s,3274,95,10:46:57,11:20:23,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|36,volunteer:area_873|kcm:30390|kcm:3470,volunteer:area_873(area_873) ~ BUS null 10:46:57 11:08:44 ~ Walk 0s ~ Beacon Ave S & S Spencer St(30390) ~ BUS 36 11:10:44 11:19 ~ Beacon Ave S & S Lander St(3470) ~ Walk 1m23s +15,0,22m55s,1975,0,10:00:00,10:22:55,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:22:55 +15,0,22m55s,1975,0,10:00:00,10:22:55,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:22:55 +15,0,22m55s,1975,0,10:00:00,10:22:55,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:22:55 +16,2,29m24s,3566,0,10:00:14,10:29:38,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|160|Volunteer Transportation,volunteer:area_873|kcm:57190|kcm:57200|volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00:14 10:21:10 ~ Walk 0s ~ 108th Ave SE & SE 217th St(57190) ~ BUS 160 10:23:10 10:23:59 ~ 108th Ave SE & SE 212th St(57200) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:25:59 10:29:38 +16,1,46m28s,5295,1754,10:00:14,10:46:42,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|160,volunteer:area_873|kcm:57190|kcm:57200,volunteer:area_873(area_873) ~ BUS null 10:00:14 10:21:10 ~ Walk 0s ~ 108th Ave SE & SE 217th St(57190) ~ BUS 160 10:23:10 10:23:59 ~ 108th Ave SE & SE 212th St(57200) ~ Walk 22m43s +16,2,55m8s,5110,0,10:03:43,10:58:51,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|165|Volunteer Transportation,volunteer:area_873|kcm:48620|kcm:57141|volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:03:43 10:05:26 ~ Walk 0s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 10:07:26 10:53:10 ~ SE 240th St & 116th Ave SE(57141) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:55:10 10:58:51 +17,0,13m2s,1382,0,10:00:00,10:13:02,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:13:02 +17,0,13m2s,1382,0,10:00:00,10:13:02,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:13:02 +17,0,13m2s,1382,0,10:00:00,10:13:02,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:13:02 +18,2,17m32s,2854,0,10:11:03,10:28:35,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|165|Volunteer Transportation,volunteer:area_873|kcm:47540|kcm:47550|volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:11:03 10:13:54 ~ Walk 0s ~ 1st Ave S & S 186th St(47540) ~ BUS 165 10:15:54 10:16:20 ~ 1st Ave S & SW 185th St(47550) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:18:20 10:28:35 +18,1,31m21s,3972,1214,10:00:44,10:32:05,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|A Line,volunteer:area_873|kcm:61150|kcm:61170,volunteer:area_873(area_873) ~ BUS null 10:00:44 10:12:12 ~ Walk 0s ~ Pacific Hwy S & S 216th St(61150) ~ BUS A Line 10:14:12 10:16:08 ~ Pacific Hwy S & S 224th St(61170) ~ Walk 15m57s +18,1,33m5s,4412,1670,10:03:43,10:36:48,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|165,volunteer:area_873|kcm:48620|kcm:48810,volunteer:area_873(area_873) ~ BUS null 10:03:43 10:05:26 ~ Walk 0s ~ 1st Ave S & SW 178th St(48620) ~ BUS 165 10:07:26 10:15 ~ Marine View Dr S & S 223rd St(48810) ~ Walk 21m48s +19,0,27m49s,2333,89,10:00:00,10:27:49,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:26:36 ~ Walk 1m13s +19,0,27m49s,2333,89,10:00:00,10:27:49,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:26:36 ~ Walk 1m13s +19,0,27m49s,2333,89,10:00:00,10:27:49,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:26:36 ~ Walk 1m13s +20,1,44m39s,4065,262,10:11:22,10:56:01,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|50,volunteer:area_873|kcm:15395|kcm:31871,volunteer:area_873(area_873) ~ BUS null 10:11:22 10:30:16 ~ Walk 22s ~ 1st Ave S & S Hanford St(15395) ~ BUS 50 10:32:38 10:52:35 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m26s +20,1,42m36s,3948,267,10:27:40,11:10:16,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|128,volunteer:area_873|kcm:36190|kcm:31871,volunteer:area_873(area_873) ~ BUS null 10:27:40 10:45:49 ~ Walk 20s ~ 16th Ave SW & SW Webster St(36190) ~ BUS 128 10:48:09 11:06:50 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m26s +21,0,38m44s,2924,0,10:00:00,10:38:44,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_1083,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:38:44 +21,0,38m44s,2924,0,07:00:00,07:38:44,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_1083,ccsww-kc:area_897(area_897) ~ BUS null 7:00 7:38:44 +22,1,48m27s,4502,538,10:00:23,10:48:50,Pierce Transit|Volunteer Services: King County,BUS,Volunteer Services: King County|402,ccsww-kc:area_1083|pierce:1294|pierce:21821,ccsww-kc:area_897(area_897) ~ BUS null 10:00:23 10:37:53 ~ Walk 19s ~ Meridian S & 9th Ave SE(1294) ~ BUS 402 10:40:12 10:41:23 ~ 3rd St SE & 7th Ave SE(21821) ~ Walk 7m27s +22,1,1h19m39s,7173,1647,10:16:06,11:35:45,Sound Generations: Volunteer Transportation|Sound Transit,BUS,Volunteer Transportation|578,volunteer:area_873|pierce:18728|pierce:10401,volunteer:area_873(area_873) ~ BUS null 10:16:06 10:44:03 ~ Walk 57s ~ Auburn Station - Bay 4(18728) ~ BUS 578 10:47 11:14 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m45s +22,1,1h1m,5197,457,10:44:55,11:45:55,Pierce Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|402,volunteer:area_873|pierce:30893|pierce:1332,volunteer:area_873(area_873) ~ BUS null 10:44:55 11:06:51 ~ Walk 0s ~ 16th Ave S & S 344th St(30893) ~ BUS 402 11:08:51 11:39:31 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m24s +23,0,44m39s,3279,0,10:00:00,10:44:39,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:44:39 +23,0,44m39s,3279,0,10:00:00,10:44:39,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:44:39 +23,0,44m39s,3279,0,10:00:00,10:44:39,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:44:39 +24,1,52m47s,4582,294,10:17:38,11:10:25,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|SVT,volunteer:area_873|kcm:85395|kcm:82425,volunteer:area_873(area_873) ~ BUS null 10:17:38 11:00:09 ~ Walk 0s ~ 384th Ave SE & SE 92nd St(85395) ~ BUS SVT 11:02:09 11:06:26 ~ Railroad Ave S & SE King St(82425) ~ Walk 3m59s +24,1,1h2m34s,5265,426,11:07:55,12:10:29,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|208,volunteer:area_873|kcm:64416|kcm:64399,volunteer:area_873(area_873) ~ BUS null 11:07:55 11:40:52 ~ Walk 0s ~ I-90 & 270th Ave SE(64416) ~ BUS 208 11:42:52 12:04:49 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m40s +25,0,27m16s,2238,3,10:00:00,10:27:16,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:27:13 ~ Walk 3s +25,0,27m16s,2238,3,10:00:00,10:27:16,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:27:13 ~ Walk 3s +25,0,27m16s,2238,3,10:00:00,10:27:16,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:27:13 ~ Walk 3s +26,1,36m42s,3797,553,10:05:18,10:42:00,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|4,volunteer:area_873|kcm:3910|kcm:3920,volunteer:area_873(area_873) ~ BUS null 10:05:18 10:31:49 ~ Walk 17s ~ W Mcgraw St & 2nd Ave W(3910) ~ BUS 4 10:34:06 10:34:39 ~ Queen Anne Ave N & W Mcgraw St(3920) ~ Walk 7m21s +26,1,33m12s,3374,264,10:13:54,10:47:06,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|4,volunteer:area_873|kcm:41340|kcm:41350,volunteer:area_873(area_873) ~ BUS null 10:13:54 10:40:21 ~ Walk 22s ~ W Mcgraw St & Queen Anne Ave N(41340) ~ BUS 4 10:42:43 10:43:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m31s +27,0,21m53s,1913,0,10:00:00,10:21:53,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:21:53 +27,0,21m53s,1913,0,10:00:00,10:21:53,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:21:53 +27,0,21m53s,1913,0,10:00:00,10:21:53,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:21:53 +28,1,32m21s,3209,95,10:15:02,10:47:23,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|60,volunteer:area_873|kcm:40871|kcm:3470,volunteer:area_873(area_873) ~ BUS null 10:15:02 10:29:34 ~ Walk 0s ~ Corson Ave S & S Willow St(40871) ~ BUS 60 10:31:34 10:46 ~ Beacon Ave S & S Lander St(3470) ~ Walk 1m23s +28,1,32m21s,3209,95,10:39:02,11:11:23,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|60,volunteer:area_873|kcm:40871|kcm:3470,volunteer:area_873(area_873) ~ BUS null 10:39:02 10:53:34 ~ Walk 0s ~ Corson Ave S & S Willow St(40871) ~ BUS 60 10:55:34 11:10 ~ Beacon Ave S & S Lander St(3470) ~ Walk 1m23s +29,0,18m59s,1739,0,10:00:00,10:18:59,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:18:59 +29,0,18m59s,1739,0,10:00:00,10:18:59,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:18:59 +29,0,18m59s,1739,0,10:00:00,10:18:59,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:18:59 +30,2,25m36s,3338,0,10:01:26,10:27:02,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|160|Volunteer Transportation,volunteer:area_873|kcm:57180|kcm:57185|volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:01:26 10:19:36 ~ Walk 0s ~ 108th Ave SE & SE 224th St(57180) ~ BUS 160 10:21:36 10:22:22 ~ 108th Ave SE & SE 220th Pl(57185) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:24:22 10:27:02 +30,1,39m21s,4624,1428,10:01:26,10:40:47,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|160,volunteer:area_873|kcm:57180|kcm:57185,volunteer:area_873(area_873) ~ BUS null 10:01:26 10:19:36 ~ Walk 0s ~ 108th Ave SE & SE 224th St(57180) ~ BUS 160 10:21:36 10:22:22 ~ 108th Ave SE & SE 220th Pl(57185) ~ Walk 18m25s +30,1,28m31s,3405,667,10:20:33,10:49:04,Metro Transit|Sound Generations: Volunteer Transportation,BUS,156|Volunteer Transportation,kcm:50450|kcm:50461|volunteer:area_873,Walk 8m43s ~ 24th Ave S & S 226th St(50450) ~ BUS 156 10:29:16 10:30:10 ~ Kent Des Moines Rd & 24th Ave S(50461) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:32:10 10:49:04 +31,0,12m40s,1360,0,10:00:00,10:12:40,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:12:40 +31,0,12m40s,1360,0,10:00:00,10:12:40,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:12:40 +31,0,12m40s,1360,0,10:00:00,10:12:40,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:12:40 +32,1,25m33s,3398,898,10:02:55,10:28:28,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|165,volunteer:area_873|kcm:47390|kcm:47570,volunteer:area_873(area_873) ~ BUS null 10:02:55 10:05:49 ~ Walk 11s ~ Marine View Dr S & S 223rd St(47390) ~ BUS 165 10:08 10:17 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m28s +32,2,17m37s,2859,0,10:34:45,10:52:22,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|165|Volunteer Transportation,volunteer:area_873|kcm:48770|kcm:48780|volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:34:45 10:40:05 ~ Walk 0s ~ S 216th Pl & S 216th St(48770) ~ BUS 165 10:42:05 10:42:28 ~ S 216th Pl & 4th Pl S(48780) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:44:28 10:52:22 +32,1,24m33s,3338,898,10:30:55,10:55:28,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|165,volunteer:area_873|kcm:47390|kcm:47570,volunteer:area_873(area_873) ~ BUS null 10:30:55 10:33:49 ~ Walk 11s ~ Marine View Dr S & S 223rd St(47390) ~ BUS 165 10:36 10:44 ~ 1st Ave S & SW Normandy Rd(47570) ~ Walk 11m28s +33,0,28m46s,2390,89,10:00:00,10:28:46,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:27:33 ~ Walk 1m13s +33,0,28m46s,2390,89,10:00:00,10:28:46,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:27:33 ~ Walk 1m13s +33,0,28m46s,2390,89,10:00:00,10:28:46,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:27:33 ~ Walk 1m13s +34,1,33m56s,3424,264,10:02:05,10:36:01,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|50,volunteer:area_873|kcm:31850|kcm:31871,volunteer:area_873(area_873) ~ BUS null 10:02:05 10:28:47 ~ Walk 25s ~ California Ave SW & SW Andover St(31850) ~ BUS 50 10:31:12 10:32:35 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m26s +34,1,38m20s,4059,756,10:20:33,10:58:53,Metro Transit|Sound Generations: Volunteer Transportation,BUS,156|Volunteer Transportation,kcm:50450|kcm:50461|volunteer:area_873,Walk 8m43s ~ 24th Ave S & S 226th St(50450) ~ BUS 156 10:29:16 10:30:10 ~ Kent Des Moines Rd & 24th Ave S(50461) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:32:10 10:57:40 ~ Walk 1m13s +35,0,28m32s,2312,0,10:00:00,10:28:32,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_1083,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:28:32 +35,0,28m32s,2312,0,07:00:00,07:28:32,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_1083,ccsww-kc:area_897(area_897) ~ BUS null 7:00 7:28:32 +36,1,36m4s,3711,474,10:09:59,10:46:03,Pierce Transit|Volunteer Services: King County,BUS,Volunteer Services: King County|402,ccsww-kc:area_1083|pierce:1334|pierce:1294,ccsww-kc:area_897(area_897) ~ BUS null 10:09:59 10:36:52 ~ Walk 32s ~ Meridian S & 10th Ave SE(1334) ~ BUS 402 10:39:24 10:40:12 ~ Meridian S & 9th Ave SE(1294) ~ Walk 5m51s +36,1,52m14s,4671,457,10:53:41,11:45:55,Pierce Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|402,volunteer:area_873|pierce:30893|pierce:1332,volunteer:area_873(area_873) ~ BUS null 10:53:41 11:06:51 ~ Walk 0s ~ 16th Ave S & S 344th St(30893) ~ BUS 402 11:08:51 11:39:31 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m24s +36,2,1h15m30s,7027,970,10:47:44,12:03:14,Pierce Transit|Sound Generations: Volunteer Transportation|Sound Transit,BUS,Volunteer Transportation|574|400,volunteer:area_873|pierce:3818|pierce:377411996|pierce:12938|pierce:8058,volunteer:area_873(area_873) ~ BUS null 10:47:44 10:52 ~ Walk 0s ~ I-5 & Kent - Des Moines Fwy Station(3818) ~ BUS 574 10:54 11:21 ~ Tacoma Dome Station - Zone H(377411996) ~ Walk 1m49s ~ Tacoma Dome Station - Zone C(12938) ~ BUS 400 11:28 11:51:06 ~ 5th St SW & 9th Ave SW - Red Lot(8058) ~ Walk 12m8s +37,0,44m44s,3284,0,10:00:00,10:44:44,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:44:44 +37,0,44m44s,3284,0,10:00:00,10:44:44,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:44:44 +37,0,44m44s,3284,0,10:00:00,10:44:44,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:44:44 +38,1,52m52s,4587,294,10:17:33,11:10:25,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|SVT,volunteer:area_873|kcm:85395|kcm:82425,volunteer:area_873(area_873) ~ BUS null 10:17:33 11:00:09 ~ Walk 0s ~ 384th Ave SE & SE 92nd St(85395) ~ BUS SVT 11:02:09 11:06:26 ~ Railroad Ave S & SE King St(82425) ~ Walk 3m59s +38,1,1h2m39s,5270,426,11:07:50,12:10:29,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|208,volunteer:area_873|kcm:64416|kcm:64399,volunteer:area_873(area_873) ~ BUS null 11:07:50 11:40:52 ~ Walk 0s ~ I-90 & 270th Ave SE(64416) ~ BUS 208 11:42:52 12:04:49 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m40s +39,0,32m23s,2545,3,10:00:00,10:32:23,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:32:20 ~ Walk 3s +39,0,32m23s,2545,3,10:00:00,10:32:23,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:32:20 ~ Walk 3s +39,0,32m23s,2545,3,10:00:00,10:32:23,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:32:20 ~ Walk 3s +40,1,42m12s,3904,248,10:04:54,10:47:06,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|4,volunteer:area_873|kcm:4280|kcm:41350,volunteer:area_873(area_873) ~ BUS null 10:04:54 10:33:22 ~ Walk 6s ~ Taylor Ave N & Lee St(4280) ~ BUS 4 10:35:28 10:43:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m31s +40,1,42m12s,3904,248,10:49:54,11:32:06,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|4,volunteer:area_873|kcm:4280|kcm:41350,volunteer:area_873(area_873) ~ BUS null 10:49:54 11:18:22 ~ Walk 6s ~ Taylor Ave N & Lee St(4280) ~ BUS 4 11:20:28 11:28:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m31s +41,0,22m50s,1970,0,10:00:00,10:22:50,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:22:50 +41,0,22m50s,1970,0,10:00:00,10:22:50,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:22:50 +41,0,22m50s,1970,0,10:00:00,10:22:50,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:22:50 +42,1,30m40s,3108,95,10:19:43,10:50:23,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|36,volunteer:area_873|kcm:30390|kcm:3470,volunteer:area_873(area_873) ~ BUS null 10:19:43 10:38:44 ~ Walk 0s ~ Beacon Ave S & S Spencer St(30390) ~ BUS 36 10:40:44 10:49 ~ Beacon Ave S & S Lander St(3470) ~ Walk 1m23s +42,1,30m40s,3108,95,10:49:43,11:20:23,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|36,volunteer:area_873|kcm:30390|kcm:3470,volunteer:area_873(area_873) ~ BUS null 10:49:43 11:08:44 ~ Walk 0s ~ Beacon Ave S & S Spencer St(30390) ~ BUS 36 11:10:44 11:19 ~ Beacon Ave S & S Lander St(3470) ~ Walk 1m23s +43,0,32m7s,2591,89,10:00:00,10:32:07,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,Walk 1m13s ~ volunteer:area_873(area_873) ~ BUS null 10:01:13 10:32:07 +43,0,32m7s,2591,89,10:00:00,10:32:07,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,Walk 1m13s ~ hopelink:area_1085(area_1085) ~ BUS null 10:01:13 10:32:07 +43,0,32m7s,2591,89,10:00:00,10:32:07,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,Walk 1m13s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:01:13 10:32:07 +44,2,42m20s,4407,89,10:05:35,10:47:55,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|160|Volunteer Transportation,volunteer:area_873|kcm:59370|kcm:57340|volunteer:area_873,Walk 1m13s ~ volunteer:area_873(area_873) ~ BUS null 10:06:48 10:31:38 ~ Walk 0s ~ S Carr Rd & Talbot Rd S(59370) ~ BUS 160 10:33:38 10:42:04 ~ 108th Ave SE & SE 204th St(57340) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:44:04 10:47:55 +44,1,52m29s,5477,1517,10:00:18,10:52:47,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|160,volunteer:area_873|kcm:57180|kcm:57185,Walk 1m13s ~ volunteer:area_873(area_873) ~ BUS null 10:01:31 10:31:36 ~ Walk 0s ~ 108th Ave SE & SE 224th St(57180) ~ BUS 160 10:33:36 10:34:22 ~ 108th Ave SE & SE 220th Pl(57185) ~ Walk 18m25s +44,1,39m25s,3727,219,10:45:16,11:24:41,Metro Transit|Sound Generations: Volunteer Transportation,BUS,50|Volunteer Transportation,kcm:31970|kcm:22820|volunteer:area_873,Walk 2m45s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:48:01 10:55:34 ~ 35th Ave SW & SW Avalon Way(22820) ~ Walk 11s ~ volunteer:area_873(area_873) ~ BUS null 10:57:45 11:24:41 +45,0,27m6s,2290,89,10:00:00,10:27:06,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,Walk 1m13s ~ volunteer:area_873(area_873) ~ BUS null 10:01:13 10:27:06 +45,0,27m6s,2290,89,10:00:00,10:27:06,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,Walk 1m13s ~ hopelink:area_1085(area_1085) ~ BUS null 10:01:13 10:27:06 +45,0,27m6s,2290,89,10:00:00,10:27:06,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,Walk 1m13s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:01:13 10:27:06 +46,1,39m8s,4197,879,10:07:28,10:46:36,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|165,volunteer:area_873|kcm:48570|kcm:48620,Walk 1m13s ~ volunteer:area_873(area_873) ~ BUS null 10:08:41 10:30:21 ~ Walk 7s ~ 1st Ave S & SW 160th St(48570) ~ BUS 165 10:32:28 10:36:26 ~ 1st Ave S & SW 178th St(48620) ~ Walk 10m10s +46,1,38m21s,3657,214,10:21:31,10:59:52,Metro Transit|Sound Generations: Volunteer Transportation,BUS,128|Volunteer Transportation,kcm:31970|kcm:22170|volunteer:area_873,Walk 2m45s ~ California Ave SW & SW Spokane St(31970) ~ BUS 128 10:24:16 10:40:20 ~ Dumar Way SW & SW Orchard St(22170) ~ Walk 13s ~ volunteer:area_873(area_873) ~ BUS null 10:42:33 10:59:52 +46,1,38m21s,3657,214,11:01:31,11:39:52,Metro Transit|Sound Generations: Volunteer Transportation,BUS,128|Volunteer Transportation,kcm:31970|kcm:22170|volunteer:area_873,Walk 2m45s ~ California Ave SW & SW Spokane St(31970) ~ BUS 128 11:04:16 11:20:20 ~ Dumar Way SW & SW Orchard St(22170) ~ Walk 13s ~ volunteer:area_873(area_873) ~ BUS null 11:22:33 11:39:52 +47,0,29m17s,2421,89,10:00:00,10:29:17,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,Walk 1m13s ~ volunteer:area_873(area_873) ~ BUS null 10:01:13 10:29:17 +47,0,29m17s,2421,89,10:00:00,10:29:17,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,Walk 1m13s ~ hopelink:area_1085(area_1085) ~ BUS null 10:01:13 10:29:17 +47,0,29m17s,2421,89,10:00:00,10:29:17,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,Walk 1m13s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:01:13 10:29:17 +48,1,36m35s,3557,219,10:45:16,11:21:51,Metro Transit|Sound Generations: Volunteer Transportation,BUS,50|Volunteer Transportation,kcm:31970|kcm:22820|volunteer:area_873,Walk 2m45s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:48:01 10:55:34 ~ 35th Ave SW & SW Avalon Way(22820) ~ Walk 11s ~ volunteer:area_873(area_873) ~ BUS null 10:57:45 11:21:51 +50,1,1h30m1s,7860,1736,10:05:44,11:35:45,Sound Generations: Volunteer Transportation|Sound Transit,BUS,Volunteer Transportation|578,volunteer:area_873|pierce:18728|pierce:10401,Walk 1m13s ~ volunteer:area_873(area_873) ~ BUS null 10:06:57 10:44:03 ~ Walk 57s ~ Auburn Station - Bay 4(18728) ~ BUS 578 10:47 11:14 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m45s +50,1,55m14s,4676,219,10:45:16,11:40:30,Metro Transit|Volunteer Services: King County,BUS,50|Volunteer Services: King County,kcm:31970|kcm:22820|ccsww-kc:area_1083,Walk 2m45s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:48:01 10:55:34 ~ 35th Ave SW & SW Avalon Way(22820) ~ Walk 11s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:57:45 11:40:30 +50,1,1h12m25s,5946,546,10:33:30,11:45:55,Pierce Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|402,volunteer:area_873|pierce:30893|pierce:1332,Walk 1m13s ~ volunteer:area_873(area_873) ~ BUS null 10:34:43 11:06:51 ~ Walk 0s ~ 16th Ave S & S 344th St(30893) ~ BUS 402 11:08:51 11:39:31 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m24s +51,0,42m42s,3226,89,10:00:00,10:42:42,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,Walk 1m13s ~ volunteer:area_873(area_873) ~ BUS null 10:01:13 10:42:42 +51,0,42m42s,3226,89,10:00:00,10:42:42,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,Walk 1m13s ~ hopelink:area_1085(area_1085) ~ BUS null 10:01:13 10:42:42 +51,0,42m42s,3226,89,10:00:00,10:42:42,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,Walk 1m13s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:01:13 10:42:42 +52,1,49m50s,4352,219,10:45:16,11:35:06,Metro Transit|Sound Generations: Volunteer Transportation,BUS,50|Volunteer Transportation,kcm:31970|kcm:22820|volunteer:area_873,Walk 2m45s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:48:01 10:55:34 ~ 35th Ave SW & SW Avalon Way(22820) ~ Walk 11s ~ volunteer:area_873(area_873) ~ BUS null 10:57:45 11:35:06 +53,0,19m58s,1865,92,10:00:00,10:19:58,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,Walk 1m13s ~ volunteer:area_873(area_873) ~ BUS null 10:01:13 10:19:55 ~ Walk 3s +53,0,19m58s,1865,92,10:00:00,10:19:58,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,Walk 1m13s ~ hopelink:area_1085(area_1085) ~ BUS null 10:01:13 10:19:55 ~ Walk 3s +53,0,19m58s,1865,92,10:00:00,10:19:58,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,Walk 1m13s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:01:13 10:19:55 ~ Walk 3s +54,1,27m16s,3001,222,10:25:16,10:52:32,Metro Transit|Sound Generations: Volunteer Transportation,BUS,50|Volunteer Transportation,kcm:31970|kcm:22820|volunteer:area_873,Walk 2m45s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:28:01 10:35:34 ~ 35th Ave SW & SW Avalon Way(22820) ~ Walk 11s ~ volunteer:area_873(area_873) ~ BUS null 10:37:45 10:52:29 ~ Walk 3s +54,1,27m16s,3001,222,10:45:16,11:12:32,Metro Transit|Sound Generations: Volunteer Transportation,BUS,50|Volunteer Transportation,kcm:31970|kcm:22820|volunteer:area_873,Walk 2m45s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:48:01 10:55:34 ~ 35th Ave SW & SW Avalon Way(22820) ~ Walk 11s ~ volunteer:area_873(area_873) ~ BUS null 10:57:45 11:12:29 ~ Walk 3s +54,1,27m44s,3171,423,10:48:20,11:16:04,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|2,volunteer:area_873|kcm:2820|kcm:2830,Walk 1m13s ~ volunteer:area_873(area_873) ~ BUS null 10:49:33 11:08:39 ~ Walk 6s ~ 6th Ave W & W Mcgraw St(2820) ~ BUS 2 11:10:45 11:11:37 ~ 6th Ave W & W Smith St(2830) ~ Walk 4m27s +55,0,13m48s,1492,89,10:00:00,10:13:48,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,Walk 1m13s ~ volunteer:area_873(area_873) ~ BUS null 10:01:13 10:13:48 +55,0,13m48s,1492,89,10:00:00,10:13:48,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,Walk 1m13s ~ hopelink:area_1085(area_1085) ~ BUS null 10:01:13 10:13:48 +55,0,13m48s,1492,89,10:00:00,10:13:48,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,Walk 1m13s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:01:13 10:13:48 +56,1,18m,2424,202,10:05:23,10:23:23,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|60,volunteer:area_873|kcm:41850|kcm:3470,Walk 1m13s ~ volunteer:area_873(area_873) ~ BUS null 10:06:36 10:17:08 ~ Walk 19s ~ 15th Ave S & S Spokane St(41850) ~ BUS 60 10:19:27 10:22 ~ Beacon Ave S & S Lander St(3470) ~ Walk 1m23s +56,1,21m6s,2628,219,10:25:16,10:46:22,Metro Transit|Sound Generations: Volunteer Transportation,BUS,50|Volunteer Transportation,kcm:31970|kcm:22820|volunteer:area_873,Walk 2m45s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:28:01 10:35:34 ~ 35th Ave SW & SW Avalon Way(22820) ~ Walk 11s ~ volunteer:area_873(area_873) ~ BUS null 10:37:45 10:46:22 +56,1,42m7s,4037,438,10:05:16,10:47:23,Metro Transit,BUS,50|60,kcm:31970|kcm:30770|kcm:41850|kcm:3470,Walk 2m45s ~ California Ave SW & SW Spokane St(31970) ~ BUS 50 10:08:01 10:33:46 ~ S Columbian Way & S Spokane St(30770) ~ Walk 3m11s ~ 15th Ave S & S Spokane St(41850) ~ BUS 60 10:43:27 10:46 ~ Beacon Ave S & S Lander St(3470) ~ Walk 1m23s +58,2,1h9m7s,6673,984,10:14:12,11:23:19,Pierce Transit|Sound Generations: Volunteer Transportation|Sound Transit,BUS,400|578|Volunteer Transportation,pierce:6085|pierce:11956|pierce:10401|pierce:8770|volunteer:area_873,Walk 11m22s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:25:34 10:29 ~ Puyallup Station - Bay 1(11956) ~ Walk 1m20s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 10:33 11:04 ~ Auburn Station - Bay 3(8770) ~ Walk 38s ~ volunteer:area_873(area_873) ~ BUS null 11:06:38 11:23:19 +58,1,1h12m8s,6703,1622,10:11:11,11:23:19,Sound Generations: Volunteer Transportation|Sound Transit,BUS,578|Volunteer Transportation,pierce:10401|pierce:8770|volunteer:area_873,Walk 21m49s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 10:33 11:04 ~ Auburn Station - Bay 3(8770) ~ Walk 38s ~ volunteer:area_873(area_873) ~ BUS null 11:06:38 11:23:19 +58,1,59m3s,5068,440,10:34:17,11:33:20,Pierce Transit|Sound Generations: Volunteer Transportation,BUS,402|Volunteer Transportation,pierce:1294|pierce:1003|volunteer:area_873,Walk 5m55s ~ Meridian S & 9th Ave SE(1294) ~ BUS 402 10:40:12 11:12:13 ~ Enchanted Pkwy & S 352nd St(1003) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 11:14:13 11:33:20 +60,1,1h2m48s,5293,440,10:34:17,11:37:05,Pierce Transit|Sound Generations: Volunteer Transportation,BUS,402|Volunteer Transportation,pierce:1294|pierce:1003|volunteer:area_873,Walk 5m55s ~ Meridian S & 9th Ave SE(1294) ~ BUS 402 10:40:12 11:12:13 ~ Enchanted Pkwy & S 352nd St(1003) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 11:14:13 11:37:05 +60,2,1h35m43s,8169,850,10:14:12,11:49:55,Pierce Transit|Sound Generations: Volunteer Transportation|Sound Transit,BUS,400|574|Volunteer Transportation,pierce:6085|pierce:20163|pierce:3046|pierce:16997|volunteer:area_873,Walk 11m22s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:25:34 10:49 ~ Tacoma Dome Station - Zone E(20163) ~ Walk 20s ~ Tacoma Dome Station - Zone A(3046) ~ BUS 574 10:59 11:39:08 ~ 188th St S & 42nd Av S(16997) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 11:41:08 11:49:55 +60,1,1h22m38s,7333,1622,10:43:11,12:05:49,Sound Generations: Volunteer Transportation|Sound Transit,BUS,578|Volunteer Transportation,pierce:10401|pierce:8770|volunteer:area_873,Walk 21m49s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 11:05 11:36 ~ Auburn Station - Bay 3(8770) ~ Walk 38s ~ volunteer:area_873(area_873) ~ BUS null 11:38:38 12:05:49 +62,1,1h13m33s,6788,1622,10:11:11,11:24:44,Sound Generations: Volunteer Transportation|Sound Transit,BUS,578|Volunteer Transportation,pierce:10401|pierce:8770|volunteer:area_873,Walk 21m49s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 10:33 11:04 ~ Auburn Station - Bay 3(8770) ~ Walk 38s ~ volunteer:area_873(area_873) ~ BUS null 11:06:38 11:24:44 +62,1,57m6s,4951,440,10:34:17,11:31:23,Pierce Transit|Sound Generations: Volunteer Transportation,BUS,402|Volunteer Transportation,pierce:1294|pierce:1003|volunteer:area_873,Walk 5m55s ~ Meridian S & 9th Ave SE(1294) ~ BUS 402 10:40:12 11:12:13 ~ Enchanted Pkwy & S 352nd St(1003) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 11:14:13 11:31:23 +62,2,1h21m50s,7357,880,10:14:12,11:36:02,Pierce Transit|Sound Generations: Volunteer Transportation|Sound Transit,BUS,400|574|Volunteer Transportation,pierce:6085|pierce:20163|pierce:3046|pierce:14363|volunteer:area_873,Walk 11m22s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:25:34 10:49 ~ Tacoma Dome Station - Zone E(20163) ~ Walk 20s ~ Tacoma Dome Station - Zone A(3046) ~ BUS 574 10:59 11:28 ~ I-5 & Kent - Des Moines Fwy Station(14363) ~ Walk 25s ~ volunteer:area_873(area_873) ~ BUS null 11:30:25 11:36:02 +64,1,1h13m16s,5985,529,10:34:17,11:47:33,Pierce Transit|Sound Generations: Volunteer Transportation,BUS,402|Volunteer Transportation,pierce:1294|pierce:1003|volunteer:area_873,Walk 5m55s ~ Meridian S & 9th Ave SE(1294) ~ BUS 402 10:40:12 11:12:13 ~ Enchanted Pkwy & S 352nd St(1003) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 11:14:13 11:46:20 ~ Walk 1m13s +64,1,1h53m25s,9252,1726,10:11:11,12:04:36,Sound Generations: Volunteer Transportation|Sound Transit,BUS,578|Volunteer Transportation,pierce:10401|pierce:24707|volunteer:area_873,Walk 21m49s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 10:33 11:47 ~ 4th Ave & University(24707) ~ Walk 49s ~ volunteer:area_873(area_873) ~ BUS null 11:49:49 12:03:23 ~ Walk 1m13s +64,2,2h1m49s,9933,1126,10:14:12,12:16:01,Metro Transit|Pierce Transit|Sound Transit,BUS,400|594|50,pierce:6085|pierce:20163|pierce:27454|pierce:596|kcm:99252|kcm:31871,Walk 11m22s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:25:34 10:49 ~ Tacoma Dome Station - Zone E(20163) ~ Walk 47s ~ Tacoma Dome Station - Zone B(27454) ~ BUS 594 11:07 11:44 ~ Bus Wy & S Spokane St(596) ~ Walk 1s ~ SODO Busway & S Spokane St(99252) ~ BUS 50 11:48:43 12:12:35 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m26s +66,2,1h28m6s,7812,984,10:14:12,11:42:18,Pierce Transit|Sound Generations: Volunteer Transportation|Sound Transit,BUS,400|578|Volunteer Transportation,pierce:6085|pierce:11956|pierce:10401|pierce:8770|volunteer:area_873,Walk 11m22s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:25:34 10:29 ~ Puyallup Station - Bay 1(11956) ~ Walk 1m20s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 10:33 11:04 ~ Auburn Station - Bay 3(8770) ~ Walk 38s ~ volunteer:area_873(area_873) ~ BUS null 11:06:38 11:42:18 +66,1,1h31m7s,7842,1622,10:11:11,11:42:18,Sound Generations: Volunteer Transportation|Sound Transit,BUS,578|Volunteer Transportation,pierce:10401|pierce:8770|volunteer:area_873,Walk 21m49s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 10:33 11:04 ~ Auburn Station - Bay 3(8770) ~ Walk 38s ~ volunteer:area_873(area_873) ~ BUS null 11:06:38 11:42:18 +66,1,1h18m,6205,440,10:34:17,11:52:17,Pierce Transit|Sound Generations: Volunteer Transportation,BUS,402|Volunteer Transportation,pierce:1294|pierce:1003|volunteer:area_873,Walk 5m55s ~ Meridian S & 9th Ave SE(1294) ~ BUS 402 10:40:12 11:12:13 ~ Enchanted Pkwy & S 352nd St(1003) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 11:14:13 11:52:17 +68,1,1h16m48s,6136,443,10:34:17,11:51:05,Pierce Transit|Sound Generations: Volunteer Transportation,BUS,402|Volunteer Transportation,pierce:1294|pierce:1003|volunteer:area_873,Walk 5m55s ~ Meridian S & 9th Ave SE(1294) ~ BUS 402 10:40:12 11:12:13 ~ Enchanted Pkwy & S 352nd St(1003) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 11:14:13 11:51:02 ~ Walk 3s +68,2,2h13m46s,10807,1358,10:14:12,12:27:58,Metro Transit|Pierce Transit|Sound Transit,BUS,400|578|13,pierce:6085|pierce:11956|pierce:10401|pierce:13217|kcm:575|kcm:41350,Walk 11m22s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:25:34 10:29 ~ Puyallup Station - Bay 1(11956) ~ Walk 1m20s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 10:33 11:49 ~ 4th Ave & Pine St(13217) ~ Walk 3m9s ~ 3rd Ave & Pike St(575) ~ BUS 13 12:02 12:24:27 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m31s +68,1,2h16m47s,10837,1996,10:11:11,12:27:58,Metro Transit|Sound Transit,BUS,578|13,pierce:10401|pierce:13217|kcm:575|kcm:41350,Walk 21m49s ~ Puyallup Station - Bay 3(10401) ~ BUS 578 10:33 11:49 ~ 4th Ave & Pine St(13217) ~ Walk 3m9s ~ 3rd Ave & Pike St(575) ~ BUS 13 12:02 12:24:27 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m31s +70,1,1h7m18s,5563,440,10:34:17,11:41:35,Pierce Transit|Sound Generations: Volunteer Transportation,BUS,402|Volunteer Transportation,pierce:1294|pierce:1003|volunteer:area_873,Walk 5m55s ~ Meridian S & 9th Ave SE(1294) ~ BUS 402 10:40:12 11:12:13 ~ Enchanted Pkwy & S 352nd St(1003) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 11:14:13 11:41:35 +70,1,1h58m48s,10232,2626,10:14:12,12:13:00,Pierce Transit|Sound Transit,BUS,400|594,pierce:6085|pierce:20163|pierce:27454|pierce:590,Walk 11m22s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:25:34 10:49 ~ Tacoma Dome Station - Zone E(20163) ~ Walk 47s ~ Tacoma Dome Station - Zone B(27454) ~ BUS 594 11:07 11:48:46 ~ Bus Wy & Holgate St(590) ~ Walk 24m14s +70,2,1h59m54s,9794,1104,10:14:12,12:14:06,Metro Transit|Pierce Transit|Sound Transit,BUS,400|594|36,pierce:6085|pierce:20163|pierce:27454|pierce:267|kcm:1471|kcm:3810,Walk 11m22s ~ Fairview Dr & 9th Ave SW Red Lot(6085) ~ BUS 400 10:25:34 10:49 ~ Tacoma Dome Station - Zone E(20163) ~ Walk 47s ~ Tacoma Dome Station - Zone B(27454) ~ BUS 594 11:07 11:53 ~ 4th Ave S & Jackson St(267) ~ Walk 1m55s ~ S Jackson St & 5th Ave S(1471) ~ BUS 36 12:00 12:12 ~ Beacon Ave S & S Lander St(3810) ~ Walk 2m6s +71,0,38m41s,2921,0,10:00:00,10:38:41,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:38:41 +71,0,38m41s,2921,0,10:00:00,10:38:41,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:38:41 +71,0,38m41s,2921,0,10:00:00,10:38:41,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:38:41 +72,2,47m6s,4628,0,10:02:51,10:49:57,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|160|Volunteer Transportation,volunteer:area_873|kcm:57350|kcm:57375|volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:02:51 10:41 ~ Walk 0s ~ 108th Ave SE & SE 208th St(57350) ~ BUS 160 10:43 10:45:16 ~ 108th Ave SE & SE 220th Pl(57375) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:47:16 10:49:57 +72,2,45m9s,4511,0,10:17:26,11:02:35,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|165|Volunteer Transportation,volunteer:area_873|kcm:62173|kcm:57448|volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:17:26 10:49 ~ Walk 0s ~ 132nd Ave SE & SE 256th St(62173) ~ BUS 165 10:51 10:56:50 ~ SE 240th St & 116th Ave SE(57448) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:58:50 11:02:35 +72,1,1h47s,5906,1423,10:02:51,11:03:38,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|160,volunteer:area_873|kcm:57350|kcm:57375,volunteer:area_873(area_873) ~ BUS null 10:02:51 10:41 ~ Walk 0s ~ 108th Ave SE & SE 208th St(57350) ~ BUS 160 10:43 10:45:16 ~ 108th Ave SE & SE 220th Pl(57375) ~ Walk 18m22s +73,0,44m55s,3295,0,10:00:00,10:44:55,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:44:55 +73,0,44m55s,3295,0,10:00:00,10:44:55,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:44:55 +73,0,44m55s,3295,0,10:00:00,10:44:55,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:44:55 +74,2,50m16s,4818,0,10:02:13,10:52:29,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|165|Volunteer Transportation,volunteer:area_873|kcm:47590|kcm:47600|volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:02:13 10:44:39 ~ Walk 0s ~ 1st Ave S & S 170th St(47590) ~ BUS 165 10:46:39 10:47:22 ~ 1st Ave S & S 168th St(47600) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:49:22 10:52:29 +74,1,59m6s,4961,294,10:31:36,11:30:42,Metro Transit|Sound Generations: Volunteer Transportation,BUS,208|Volunteer Transportation,kcm:82425|kcm:64470|volunteer:area_873,Walk 3m59s ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 10:55:11 ~ I-90 & 270th Ave SE(64470) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:57:11 11:30:42 +76,1,55m36s,5030,667,10:12:37,11:08:13,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|156,volunteer:area_873|kcm:50445|kcm:50450,volunteer:area_873(area_873) ~ BUS null 10:12:37 10:56:34 ~ Walk 0s ~ 24th Ave S & S 223rd St(50445) ~ BUS 156 10:58:34 10:59:31 ~ 24th Ave S & S 226th St(50450) ~ Walk 8m42s +76,1,59m30s,4985,294,10:31:36,11:31:06,Metro Transit|Sound Generations: Volunteer Transportation,BUS,208|Volunteer Transportation,kcm:82425|kcm:64470|volunteer:area_873,Walk 3m59s ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 10:55:11 ~ I-90 & 270th Ave SE(64470) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:57:11 11:31:06 +77,0,41m36s,3160,89,10:00:00,10:41:36,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:40:23 ~ Walk 1m13s +77,0,41m36s,3160,89,10:00:00,10:41:36,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:40:23 ~ Walk 1m13s +77,0,41m36s,3160,89,10:00:00,10:41:36,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:40:23 ~ Walk 1m13s +78,1,46m33s,4181,264,10:03:43,10:50:16,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|128,volunteer:area_873|kcm:31850|kcm:31871,volunteer:area_873(area_873) ~ BUS null 10:03:43 10:43:15 ~ Walk 25s ~ California Ave SW & SW Andover St(31850) ~ BUS 128 10:45:40 10:46:50 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m26s +78,1,55m47s,4827,383,10:31:36,11:27:23,Metro Transit|Sound Generations: Volunteer Transportation,BUS,208|Volunteer Transportation,kcm:82425|kcm:64470|volunteer:area_873,Walk 3m59s ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 10:55:11 ~ I-90 & 270th Ave SE(64470) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:57:11 11:26:10 ~ Walk 1m13s +80,1,58m58s,4953,294,10:31:36,11:30:34,Metro Transit|Volunteer Services: King County,BUS,208|Volunteer Services: King County,kcm:82425|kcm:64415|ccsww-kc:area_1083,Walk 3m59s ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 10:44:31 ~ Snoqualmie Pkwy & Swenson Dr SE(64415) ~ Walk 0s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:46:31 11:30:34 +80,1,1h27m34s,7648,1647,10:08:11,11:35:45,Sound Generations: Volunteer Transportation|Sound Transit,BUS,Volunteer Transportation|578,volunteer:area_873|pierce:18728|pierce:10401,volunteer:area_873(area_873) ~ BUS null 10:08:11 10:44:03 ~ Walk 57s ~ Auburn Station - Bay 4(18728) ~ BUS 578 10:47 11:14 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m45s +80,1,1h17m45s,6202,457,10:28:10,11:45:55,Pierce Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|402,volunteer:area_873|pierce:30893|pierce:1332,volunteer:area_873(area_873) ~ BUS null 10:28:10 11:06:51 ~ Walk 0s ~ 16th Ave S & S 344th St(30893) ~ BUS 402 11:08:51 11:39:31 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m24s +81,0,41m43s,3105,3,10:00:00,10:41:43,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:41:40 ~ Walk 3s +81,0,41m43s,3105,3,10:00:00,10:41:43,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:41:40 ~ Walk 3s +81,0,41m43s,3105,3,10:00:00,10:41:43,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:41:40 ~ Walk 3s +82,1,47m39s,4241,264,10:14:27,11:02:06,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|4,volunteer:area_873|kcm:41340|kcm:41350,volunteer:area_873(area_873) ~ BUS null 10:14:27 10:55:21 ~ Walk 22s ~ W Mcgraw St & Queen Anne Ave N(41340) ~ BUS 4 10:57:43 10:58:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m31s +82,1,55m52s,4770,297,10:31:36,11:27:28,Metro Transit|Sound Generations: Volunteer Transportation,BUS,208|Volunteer Transportation,kcm:82425|kcm:64470|volunteer:area_873,Walk 3m59s ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 10:55:11 ~ I-90 & 270th Ave SE(64470) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:57:11 11:27:25 ~ Walk 3s +83,0,33m51s,2631,0,10:00:00,10:33:51,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:33:51 +83,0,33m51s,2631,0,10:00:00,10:33:51,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:33:51 +83,0,33m51s,2631,0,10:00:00,10:33:51,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:33:51 +84,1,39m45s,3665,113,10:19:38,10:59:23,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|60,volunteer:area_873|kcm:41850|kcm:3470,volunteer:area_873(area_873) ~ BUS null 10:19:38 10:53:08 ~ Walk 19s ~ 15th Ave S & S Spokane St(41850) ~ BUS 60 10:55:27 10:58 ~ Beacon Ave S & S Lander St(3470) ~ Walk 1m23s +84,1,48m,4295,294,10:31:36,11:19:36,Metro Transit|Sound Generations: Volunteer Transportation,BUS,208|Volunteer Transportation,kcm:82425|kcm:64470|volunteer:area_873,Walk 3m59s ~ Railroad Ave S & SE King St(82425) ~ BUS 208 10:35:35 10:55:11 ~ I-90 & 270th Ave SE(64470) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:57:11 11:19:36 +85,0,34m42s,2684,3,10:00:00,10:34:42,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,Walk 3s ~ volunteer:area_873(area_873) ~ BUS null 10:00:03 10:34:42 +85,0,34m42s,2684,3,10:00:00,10:34:42,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,Walk 3s ~ hopelink:area_1085(area_1085) ~ BUS null 10:00:03 10:34:42 +85,0,34m42s,2684,3,10:00:00,10:34:42,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,Walk 3s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:00:03 10:34:42 +86,2,40m43s,4248,3,10:09:14,10:49:57,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|160|Volunteer Transportation,volunteer:area_873|kcm:57350|kcm:57375|volunteer:area_873,Walk 3s ~ volunteer:area_873(area_873) ~ BUS null 10:09:17 10:41 ~ Walk 0s ~ 108th Ave SE & SE 208th St(57350) ~ BUS 160 10:43 10:45:16 ~ 108th Ave SE & SE 220th Pl(57375) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:47:16 10:49:57 +86,1,54m24s,5526,1426,10:09:14,11:03:38,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|160,volunteer:area_873|kcm:57350|kcm:57375,Walk 3s ~ volunteer:area_873(area_873) ~ BUS null 10:09:17 10:41 ~ Walk 0s ~ 108th Ave SE & SE 208th St(57350) ~ BUS 160 10:43 10:45:16 ~ 108th Ave SE & SE 220th Pl(57375) ~ Walk 18m22s +86,1,43m45s,3991,239,10:30:22,11:14:07,Metro Transit|Sound Generations: Volunteer Transportation,BUS,4|Volunteer Transportation,kcm:41300|kcm:4020|volunteer:area_873,Walk 3m19s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 4 10:33:41 10:41:02 ~ Taylor Ave N & Prospect St(4020) ~ Walk 6s ~ volunteer:area_873(area_873) ~ BUS null 10:43:08 11:14:07 +87,0,26m,2162,3,10:00:00,10:26:00,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,Walk 3s ~ volunteer:area_873(area_873) ~ BUS null 10:00:03 10:26 +87,0,26m,2162,3,10:00:00,10:26:00,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,Walk 3s ~ hopelink:area_1085(area_1085) ~ BUS null 10:00:03 10:26 +87,0,26m,2162,3,10:00:00,10:26:00,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,Walk 3s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:00:03 10:26 +88,1,35m3s,3469,239,10:15:22,10:50:25,Metro Transit|Sound Generations: Volunteer Transportation,BUS,4|Volunteer Transportation,kcm:41300|kcm:4020|volunteer:area_873,Walk 3m19s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 4 10:18:41 10:26:02 ~ Taylor Ave N & Prospect St(4020) ~ Walk 6s ~ volunteer:area_873(area_873) ~ BUS null 10:28:08 10:50:25 +88,1,35m3s,3469,239,10:45:22,11:20:25,Metro Transit|Sound Generations: Volunteer Transportation,BUS,4|Volunteer Transportation,kcm:41300|kcm:4020|volunteer:area_873,Walk 3m19s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 4 10:48:41 10:56:02 ~ Taylor Ave N & Prospect St(4020) ~ Walk 6s ~ volunteer:area_873(area_873) ~ BUS null 10:58:08 11:20:25 +89,0,31m52s,2514,3,10:00:00,10:31:52,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,Walk 3s ~ volunteer:area_873(area_873) ~ BUS null 10:00:03 10:31:52 +89,0,31m52s,2514,3,10:00:00,10:31:52,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,Walk 3s ~ hopelink:area_1085(area_1085) ~ BUS null 10:00:03 10:31:52 +89,0,31m52s,2514,3,10:00:00,10:31:52,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,Walk 3s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:00:03 10:31:52 +90,1,40m55s,3821,239,10:00:22,10:41:17,Metro Transit|Sound Generations: Volunteer Transportation,BUS,4|Volunteer Transportation,kcm:41300|kcm:4020|volunteer:area_873,Walk 3m19s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 4 10:03:41 10:11:02 ~ Taylor Ave N & Prospect St(4020) ~ Walk 6s ~ volunteer:area_873(area_873) ~ BUS null 10:13:08 10:41:17 +91,0,18m7s,1754,92,10:00:00,10:18:07,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,Walk 3s ~ volunteer:area_873(area_873) ~ BUS null 10:00:03 10:16:54 ~ Walk 1m13s +91,0,18m7s,1754,92,10:00:00,10:18:07,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,Walk 3s ~ hopelink:area_1085(area_1085) ~ BUS null 10:00:03 10:16:54 ~ Walk 1m13s +91,0,18m7s,1754,92,10:00:00,10:18:07,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,Walk 3s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:00:03 10:16:54 ~ Walk 1m13s +92,1,23m9s,2755,228,10:23:52,10:47:01,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|128,volunteer:area_873|kcm:31950|kcm:31970,Walk 3s ~ volunteer:area_873(area_873) ~ BUS null 10:23:55 10:40:44 ~ Walk 23s ~ California Ave SW & SW Hanford St(31950) ~ BUS 128 10:43:07 10:44:16 ~ California Ave SW & SW Spokane St(31970) ~ Walk 2m45s +92,1,23m4s,2775,267,10:27:12,10:50:16,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|128,volunteer:area_873|kcm:31850|kcm:31871,Walk 3s ~ volunteer:area_873(area_873) ~ BUS null 10:27:15 10:43:15 ~ Walk 25s ~ California Ave SW & SW Andover St(31850) ~ BUS 128 10:45:40 10:46:50 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m26s +94,1,1h10m9s,5518,160,10:06:05,11:16:14,Metro Transit|Volunteer Services: King County,BUS,2|Volunteer Services: King County,kcm:2570|kcm:102|ccsww-kc:area_1083,Walk 2m ~ W Mcgraw St & 6th Ave W(2570) ~ BUS 2 10:08:05 10:32 ~ Spring St & 4th Ave(102) ~ Walk 31s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:34:31 11:16:14 +94,1,1h32m36s,7953,1650,10:03:09,11:35:45,Sound Generations: Volunteer Transportation|Sound Transit,BUS,Volunteer Transportation|578,volunteer:area_873|pierce:18728|pierce:10401,Walk 3s ~ volunteer:area_873(area_873) ~ BUS null 10:03:12 10:44:03 ~ Walk 57s ~ Auburn Station - Bay 4(18728) ~ BUS 578 10:47 11:14 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m45s +94,1,1h15m,6040,460,10:30:55,11:45:55,Pierce Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|402,volunteer:area_873|pierce:30893|pierce:1332,Walk 3s ~ volunteer:area_873(area_873) ~ BUS null 10:30:58 11:06:51 ~ Walk 0s ~ 16th Ave S & S 344th St(30893) ~ BUS 402 11:08:51 11:39:31 ~ Meridian S & 9th Ave SW(1332) ~ Walk 6m24s +95,0,41m47s,3109,3,10:00:00,10:41:47,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,Walk 3s ~ volunteer:area_873(area_873) ~ BUS null 10:00:03 10:41:47 +95,0,41m47s,3109,3,10:00:00,10:41:47,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,Walk 3s ~ hopelink:area_1085(area_1085) ~ BUS null 10:00:03 10:41:47 +95,0,41m47s,3109,3,10:00:00,10:41:47,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,Walk 3s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:00:03 10:41:47 +96,1,59m42s,5096,429,11:10:47,12:10:29,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|208,volunteer:area_873|kcm:64416|kcm:64399,Walk 3s ~ volunteer:area_873(area_873) ~ BUS null 11:10:50 11:40:52 ~ Walk 0s ~ I-90 & 270th Ave SE(64416) ~ BUS 208 11:42:52 12:04:49 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m40s +96,1,50m40s,4406,239,11:29:22,12:20:02,Metro Transit|Sound Generations: Volunteer Transportation,BUS,4|Volunteer Transportation,kcm:41300|kcm:4020|volunteer:area_873,Walk 3m19s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 4 11:32:41 11:40:02 ~ Taylor Ave N & Prospect St(4020) ~ Walk 6s ~ volunteer:area_873(area_873) ~ BUS null 11:42:08 12:20:02 +97,0,15m48s,1550,3,10:00:00,10:15:48,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,Walk 3s ~ volunteer:area_873(area_873) ~ BUS null 10:00:03 10:15:48 +97,0,15m48s,1550,3,10:00:00,10:15:48,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,Walk 3s ~ hopelink:area_1085(area_1085) ~ BUS null 10:00:03 10:15:48 +97,0,15m48s,1550,3,10:00:00,10:15:48,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,Walk 3s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:00:03 10:15:48 +98,1,19m44s,2465,118,10:23:22,10:43:06,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|36,volunteer:area_873|kcm:3800|kcm:3810,Walk 3s ~ volunteer:area_873(area_873) ~ BUS null 10:23:25 10:38 ~ Walk 0s ~ Beacon Ave S & S Bayview St(3800) ~ BUS 36 10:40 10:41 ~ Beacon Ave S & S Lander St(3810) ~ Walk 2m6s +98,1,47m1s,4184,242,10:06:05,10:53:06,Metro Transit,BUS,2|36,kcm:2570|kcm:430|kcm:3810,Walk 2m ~ W Mcgraw St & 6th Ave W(2570) ~ BUS 2 10:08:05 10:26:54 ~ 3rd Ave & Pine St(430) ~ BUS 36 10:30 10:51 ~ Beacon Ave S & S Lander St(3810) ~ Walk 2m6s +98,1,47m44s,4302,348,10:15:22,11:03:06,Metro Transit,BUS,4|36,kcm:41300|kcm:450|kcm:3810,Walk 3m19s ~ 3rd Ave W & W Mcgraw St(41300) ~ BUS 4 10:18:41 10:38 ~ 3rd Ave & Union St(450) ~ BUS 36 10:41:55 11:01 ~ Beacon Ave S & S Lander St(3810) ~ Walk 2m6s +99,0,25m40s,2140,0,10:00:00,10:25:40,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:25:40 +99,0,25m40s,2140,0,10:00:00,10:25:40,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:25:40 +99,0,25m40s,2140,0,10:00:00,10:25:40,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:25:40 +100,2,31m3s,3665,0,10:00:21,10:31:24,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|160|Volunteer Transportation,volunteer:area_873|kcm:57210|kcm:57220|volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00:21 10:23 ~ Walk 0s ~ 108th Ave SE & SE 208th St(57210) ~ BUS 160 10:25 10:25:35 ~ 108th Ave SE & SE 204th St(57220) ~ Walk 0s ~ volunteer:area_873(area_873) ~ BUS null 10:27:35 10:31:24 +100,1,30m4s,3096,138,10:43:54,11:13:58,Metro Transit|Sound Generations: Volunteer Transportation,BUS,107|Volunteer Transportation,kcm:3810|kcm:42070|volunteer:area_873,Walk 2m6s ~ Beacon Ave S & S Lander St(3810) ~ BUS 107 10:46 10:48:10 ~ 15th Ave S & S Spokane St(42070) ~ Walk 28s ~ volunteer:area_873(area_873) ~ BUS null 10:50:38 11:13:58 +101,0,20m45s,1845,0,10:00:00,10:20:45,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:20:45 +101,0,20m45s,1845,0,10:00:00,10:20:45,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:20:45 +101,0,20m45s,1845,0,10:00:00,10:20:45,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:20:45 +102,1,28m53s,3026,136,10:13:54,10:42:47,Metro Transit|Sound Generations: Volunteer Transportation,BUS,107|Volunteer Transportation,kcm:3810|kcm:41740|volunteer:area_873,Walk 2m6s ~ Beacon Ave S & S Lander St(3810) ~ BUS 107 10:16 10:25 ~ 13th Ave S & S Bailey St(41740) ~ Walk 17s ~ volunteer:area_873(area_873) ~ BUS null 10:27:17 10:42:47 +103,0,22m50s,1970,0,10:00:00,10:22:50,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:22:50 +103,0,22m50s,1970,0,10:00:00,10:22:50,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:22:50 +103,0,22m50s,1970,0,10:00:00,10:22:50,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:22:50 +104,1,27m14s,2926,138,10:28:54,10:56:08,Metro Transit|Sound Generations: Volunteer Transportation,BUS,107|Volunteer Transportation,kcm:3810|kcm:42070|volunteer:area_873,Walk 2m6s ~ Beacon Ave S & S Lander St(3810) ~ BUS 107 10:31 10:33:10 ~ 15th Ave S & S Spokane St(42070) ~ Walk 28s ~ volunteer:area_873(area_873) ~ BUS null 10:35:38 10:56:08 +105,0,12m56s,1440,89,10:00:00,10:12:56,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:11:43 ~ Walk 1m13s +105,0,12m56s,1440,89,10:00:00,10:12:56,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:11:43 ~ Walk 1m13s +105,0,12m56s,1440,89,10:00:00,10:12:56,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:11:43 ~ Walk 1m13s +106,1,18m17s,2454,227,10:04:54,10:23:11,Metro Transit|Sound Generations: Volunteer Transportation,BUS,60|Volunteer Transportation,kcm:3810|kcm:42070|volunteer:area_873,Walk 2m6s ~ Beacon Ave S & S Lander St(3810) ~ BUS 60 10:07 10:10:05 ~ 15th Ave S & S Spokane St(42070) ~ Walk 28s ~ volunteer:area_873(area_873) ~ BUS null 10:12:33 10:21:58 ~ Walk 1m13s +106,1,17m22s,2399,227,10:28:54,10:46:16,Metro Transit|Sound Generations: Volunteer Transportation,BUS,107|Volunteer Transportation,kcm:3810|kcm:42070|volunteer:area_873,Walk 2m6s ~ Beacon Ave S & S Lander St(3810) ~ BUS 107 10:31 10:33:10 ~ 15th Ave S & S Spokane St(42070) ~ Walk 28s ~ volunteer:area_873(area_873) ~ BUS null 10:35:38 10:45:03 ~ Walk 1m13s +106,1,42m7s,4071,492,10:13:54,10:56:01,Metro Transit,BUS,107|50,kcm:3810|kcm:42070|kcm:30530|kcm:31871,Walk 2m6s ~ Beacon Ave S & S Lander St(3810) ~ BUS 107 10:16 10:18:10 ~ 15th Ave S & S Spokane St(42070) ~ Walk 2m19s ~ S Columbian Way & S Spokane St(30530) ~ BUS 50 10:25:43 10:52:35 ~ California Ave SW & SW Spokane St(31871) ~ Walk 3m26s +107,0,41m29s,3089,0,10:00:00,10:41:29,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_1083,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:41:29 +107,0,41m29s,3089,0,07:00:00,07:41:29,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_1083,ccsww-kc:area_897(area_897) ~ BUS null 7:00 7:41:29 +108,1,57m14s,5274,878,10:06:00,11:03:14,Pierce Transit|Volunteer Services: King County,BUS,Volunteer Services: King County|400,ccsww-kc:area_1083|pierce:12970|pierce:8058,ccsww-kc:area_897(area_897) ~ BUS null 10:06 10:47:31 ~ Walk 17s ~ 5th St SW & Pioneer Ave W(12970) ~ BUS 400 10:49:48 10:51:06 ~ 5th St SW & 9th Ave SW - Red Lot(8058) ~ Walk 12m8s +108,1,51m4s,4664,558,10:29:05,11:20:09,Metro Transit|Volunteer Services: King County,BUS,107|Volunteer Services: King County,kcm:41870|kcm:41880|ccsww-kc:area_1083,Walk 7m34s ~ 15th Ave S & S Hanford St(41870) ~ BUS 107 10:36:39 10:37:12 ~ 15th Ave S & S Stevens St(41880) ~ Walk 27s ~ ccsww-kc:area_897(area_897) ~ BUS null 10:39:39 11:20:09 +108,1,1h23m34s,7408,1647,10:12:11,11:35:45,Sound Generations: Volunteer Transportation|Sound Transit,BUS,Volunteer Transportation|578,volunteer:area_873|pierce:18728|pierce:10401,volunteer:area_873(area_873) ~ BUS null 10:12:11 10:44:03 ~ Walk 57s ~ Auburn Station - Bay 4(18728) ~ BUS 578 10:47 11:14 ~ Puyallup Station - Bay 3(10401) ~ Walk 21m45s +109,0,33m12s,2592,0,10:00:00,10:33:12,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:33:12 +109,0,33m12s,2592,0,10:00:00,10:33:12,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:33:12 +109,0,33m12s,2592,0,10:00:00,10:33:12,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:33:12 +110,1,39m12s,3767,294,10:00:22,10:39:34,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|208,volunteer:area_873|kcm:85386|kcm:82425,volunteer:area_873(area_873) ~ BUS null 10:00:22 10:31:55 ~ Walk 0s ~ Railroad Ave SE & Meadowbrook Way SE(85386) ~ BUS 208 10:33:55 10:35:35 ~ Railroad Ave S & SE King St(82425) ~ Walk 3m59s +110,1,38m33s,3621,172,10:35:43,11:14:16,Metro Transit|Sound Generations: Volunteer Transportation,BUS,36|Volunteer Transportation,kcm:3460|kcm:3470|volunteer:area_873,Walk 2m42s ~ Beacon Ave S & S Stevens St(3460) ~ BUS 36 10:38:25 10:39 ~ Beacon Ave S & S Lander St(3470) ~ Walk 18s ~ volunteer:area_873(area_873) ~ BUS null 10:41:18 11:14:16 +110,1,51m7s,4578,426,11:19:22,12:10:29,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|208,volunteer:area_873|kcm:64416|kcm:64399,volunteer:area_873(area_873) ~ BUS null 11:19:22 11:40:52 ~ Walk 0s ~ I-90 & 270th Ave SE(64416) ~ BUS 208 11:42:52 12:04:49 ~ Railroad Ave SE & SE River St(64399) ~ Walk 5m40s +111,0,16m18s,1580,3,10:00:00,10:16:18,Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation,volunteer:area_873,volunteer:area_873(area_873) ~ BUS null 10:00 10:16:15 ~ Walk 3s +111,0,16m18s,1580,3,10:00:00,10:16:18,Hopelink Transportation,BUS,Medicaid Transportation,hopelink:area_1085,hopelink:area_1085(area_1085) ~ BUS null 10:00 10:16:15 ~ Walk 3s +111,0,16m18s,1580,3,10:00:00,10:16:18,Volunteer Services: King County,BUS,Volunteer Services: King County,ccsww-kc:area_897,ccsww-kc:area_897(area_897) ~ BUS null 10:00 10:16:15 ~ Walk 3s +112,1,22m10s,2703,253,10:02:23,10:24:33,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|13,volunteer:area_873|kcm:41290|kcm:41300,volunteer:area_873(area_873) ~ BUS null 10:02:23 10:18:37 ~ Walk 22s ~ 3rd Ave W & W Smith St(41290) ~ BUS 13 10:20:59 10:21:14 ~ 3rd Ave W & W Mcgraw St(41300) ~ Walk 3m19s +112,1,26m38s,2970,248,10:20:28,10:47:06,Metro Transit|Sound Generations: Volunteer Transportation,BUS,Volunteer Transportation|4,volunteer:area_873|kcm:4280|kcm:41350,volunteer:area_873(area_873) ~ BUS null 10:20:28 10:33:22 ~ Walk 6s ~ Taylor Ave N & Lee St(4280) ~ BUS 4 10:35:28 10:43:35 ~ W Mcgraw St & 3rd Ave W(41350) ~ Walk 3m31s +112,1,21m10s,2565,141,10:28:54,10:50:04,Metro Transit|Sound Generations: Volunteer Transportation,BUS,107|Volunteer Transportation,kcm:3810|kcm:42070|volunteer:area_873,Walk 2m6s ~ Beacon Ave S & S Lander St(3810) ~ BUS 107 10:31 10:33:10 ~ 15th Ave S & S Spokane St(42070) ~ Walk 28s ~ volunteer:area_873(area_873) ~ BUS null 10:35:38 10:50:01 ~ Walk 3s diff --git a/test/performance/washington-state/travelSearch.csv b/test/performance/washington-state/travelSearch.csv index 66fa3dac2d5..28daf760405 100644 --- a/test/performance/washington-state/travelSearch.csv +++ b/test/performance/washington-state/travelSearch.csv @@ -1,163 +1,113 @@ testCaseId,description,departure,fromLat,fromLon,toLat,toLon,origin,destination,modes,category -1,Hilshire Terrace to Normandy Park (transit),10:00,47.40648236,-122.18101501,47.44306609375831,-122.34237670,Hilshire Terrace,Normandy Park,TRANSIT|WALK,transit -2,Hilshire Terrace to Normandy Park (flex),10:00,47.40648236,-122.18101501,47.44306609375831,-122.34237670,Hilshire Terrace,Normandy Park,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -3,Hilshire Terrace to Des Moines (transit),10:00,47.40648236,-122.18101501,47.3978844,-122.30898,Hilshire Terrace,Des Moines,TRANSIT|WALK,transit -4,Hilshire Terrace to Des Moines (flex),10:00,47.40648236,-122.18101501,47.3978844,-122.30898,Hilshire Terrace,Des Moines,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -5,Hilshire Terrace to North Auburn (transit),10:00,47.40648236,-122.18101501,47.340218616,-122.2246170043,Hilshire Terrace,North Auburn,TRANSIT|WALK,transit -6,Hilshire Terrace to North Auburn (flex),10:00,47.40648236,-122.18101501,47.340218616,-122.2246170043,Hilshire Terrace,North Auburn,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -7,Hilshire Terrace to Federal Way (transit),10:00,47.40648236,-122.18101501,47.31322426310727,-122.336540222167,Hilshire Terrace,Federal Way,TRANSIT|WALK,transit -8,Hilshire Terrace to Federal Way (flex),10:00,47.40648236,-122.18101501,47.31322426310727,-122.336540222167,Hilshire Terrace,Federal Way,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -9,Hilshire Terrace to West Seattle (transit),10:00,47.40648236,-122.18101501,47.571024,-122.3877811,Hilshire Terrace,West Seattle,TRANSIT|WALK,transit -10,Hilshire Terrace to West Seattle (flex),10:00,47.40648236,-122.18101501,47.571024,-122.3877811,Hilshire Terrace,West Seattle,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -11,Hilshire Terrace to Puyallup (transit),10:00,47.40648236,-122.18101501,47.18399599096,-122.28950500488,Hilshire Terrace,Puyallup,TRANSIT|WALK,transit -12,Hilshire Terrace to Puyallup (flex),10:00,47.40648236,-122.18101501,47.18399599096,-122.28950500488,Hilshire Terrace,Puyallup,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -13,Hilshire Terrace to Snoqualmie (transit),10:00,47.40648236,-122.18101501,47.52827129,-121.827821731,Hilshire Terrace,Snoqualmie,TRANSIT|WALK,transit -14,Hilshire Terrace to Snoqualmie (flex),10:00,47.40648236,-122.18101501,47.52827129,-121.827821731,Hilshire Terrace,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -15,Hilshire Terrace to Queen Anne (transit),10:00,47.40648236,-122.18101501,47.6394849792,-122.3636627197,Hilshire Terrace,Queen Anne,TRANSIT|WALK,transit -17,Hilshire Terrace to Beacon Hill (transit),10:00,47.40648236,-122.18101501,47.578668036563016,-122.31139183,Hilshire Terrace,Beacon Hill,TRANSIT|WALK,transit -18,Hilshire Terrace to Beacon Hill (flex),10:00,47.40648236,-122.18101501,47.578668036563016,-122.31139183,Hilshire Terrace,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -19,Normandy Park to Hilshire Terrace (transit),10:00,47.44306609375831,-122.34237670,47.40648236,-122.18101501,Normandy Park,Hilshire Terrace,TRANSIT|WALK,transit -20,Normandy Park to Hilshire Terrace (flex),10:00,47.44306609375831,-122.34237670,47.40648236,-122.18101501,Normandy Park,Hilshire Terrace,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -21,Normandy Park to Des Moines (transit),10:00,47.44306609375831,-122.34237670,47.3978844,-122.30898,Normandy Park,Des Moines,TRANSIT|WALK,transit -22,Normandy Park to Des Moines (flex),10:00,47.44306609375831,-122.34237670,47.3978844,-122.30898,Normandy Park,Des Moines,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -23,Normandy Park to North Auburn (transit),10:00,47.44306609375831,-122.34237670,47.340218616,-122.2246170043,Normandy Park,North Auburn,TRANSIT|WALK,transit -24,Normandy Park to North Auburn (flex),10:00,47.44306609375831,-122.34237670,47.340218616,-122.2246170043,Normandy Park,North Auburn,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -25,Normandy Park to Federal Way (transit),10:00,47.44306609375831,-122.34237670,47.31322426310727,-122.336540222167,Normandy Park,Federal Way,TRANSIT|WALK,transit -26,Normandy Park to Federal Way (flex),10:00,47.44306609375831,-122.34237670,47.31322426310727,-122.336540222167,Normandy Park,Federal Way,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -27,Normandy Park to West Seattle (transit),10:00,47.44306609375831,-122.34237670,47.571024,-122.3877811,Normandy Park,West Seattle,TRANSIT|WALK,transit -28,Normandy Park to West Seattle (flex),10:00,47.44306609375831,-122.34237670,47.571024,-122.3877811,Normandy Park,West Seattle,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -29,Normandy Park to Puyallup (transit),10:00,47.44306609375831,-122.34237670,47.18399599096,-122.28950500488,Normandy Park,Puyallup,TRANSIT|WALK,transit -30,Normandy Park to Puyallup (flex),10:00,47.44306609375831,-122.34237670,47.18399599096,-122.28950500488,Normandy Park,Puyallup,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -31,Normandy Park to Snoqualmie (transit),10:00,47.44306609375831,-122.34237670,47.52827129,-121.827821731,Normandy Park,Snoqualmie,TRANSIT|WALK,transit -32,Normandy Park to Snoqualmie (flex),10:00,47.44306609375831,-122.34237670,47.52827129,-121.827821731,Normandy Park,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -33,Normandy Park to Queen Anne (transit),10:00,47.44306609375831,-122.34237670,47.6394849792,-122.3636627197,Normandy Park,Queen Anne,TRANSIT|WALK,transit -34,Normandy Park to Queen Anne (flex),10:00,47.44306609375831,-122.34237670,47.6394849792,-122.3636627197,Normandy Park,Queen Anne,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -35,Normandy Park to Beacon Hill (transit),10:00,47.44306609375831,-122.34237670,47.578668036563016,-122.31139183,Normandy Park,Beacon Hill,TRANSIT|WALK,transit -36,Normandy Park to Beacon Hill (flex),10:00,47.44306609375831,-122.34237670,47.578668036563016,-122.31139183,Normandy Park,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -37,Des Moines to Hilshire Terrace (transit),10:00,47.3978844,-122.30898,47.40648236,-122.18101501,Des Moines,Hilshire Terrace,TRANSIT|WALK,transit -38,Des Moines to Hilshire Terrace (flex),10:00,47.3978844,-122.30898,47.40648236,-122.18101501,Des Moines,Hilshire Terrace,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -39,Des Moines to Normandy Park (transit),10:00,47.3978844,-122.30898,47.44306609375831,-122.34237670,Des Moines,Normandy Park,TRANSIT|WALK,transit -40,Des Moines to Normandy Park (flex),10:00,47.3978844,-122.30898,47.44306609375831,-122.34237670,Des Moines,Normandy Park,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -41,Des Moines to North Auburn (transit),10:00,47.3978844,-122.30898,47.340218616,-122.2246170043,Des Moines,North Auburn,TRANSIT|WALK,transit -42,Des Moines to North Auburn (flex),10:00,47.3978844,-122.30898,47.340218616,-122.2246170043,Des Moines,North Auburn,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -43,Des Moines to Federal Way (transit),10:00,47.3978844,-122.30898,47.31322426310727,-122.336540222167,Des Moines,Federal Way,TRANSIT|WALK,transit -44,Des Moines to Federal Way (flex),10:00,47.3978844,-122.30898,47.31322426310727,-122.336540222167,Des Moines,Federal Way,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -45,Des Moines to West Seattle (transit),10:00,47.3978844,-122.30898,47.571024,-122.3877811,Des Moines,West Seattle,TRANSIT|WALK,transit -46,Des Moines to West Seattle (flex),10:00,47.3978844,-122.30898,47.571024,-122.3877811,Des Moines,West Seattle,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -47,Des Moines to Puyallup (transit),10:00,47.3978844,-122.30898,47.18399599096,-122.28950500488,Des Moines,Puyallup,TRANSIT|WALK,transit -48,Des Moines to Puyallup (flex),10:00,47.3978844,-122.30898,47.18399599096,-122.28950500488,Des Moines,Puyallup,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -49,Des Moines to Snoqualmie (transit),10:00,47.3978844,-122.30898,47.52827129,-121.827821731,Des Moines,Snoqualmie,TRANSIT|WALK,transit -50,Des Moines to Snoqualmie (flex),10:00,47.3978844,-122.30898,47.52827129,-121.827821731,Des Moines,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -51,Des Moines to Queen Anne (transit),10:00,47.3978844,-122.30898,47.6394849792,-122.3636627197,Des Moines,Queen Anne,TRANSIT|WALK,transit -52,Des Moines to Queen Anne (flex),10:00,47.3978844,-122.30898,47.6394849792,-122.3636627197,Des Moines,Queen Anne,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -53,Des Moines to Beacon Hill (transit),10:00,47.3978844,-122.30898,47.578668036563016,-122.31139183,Des Moines,Beacon Hill,TRANSIT|WALK,transit -54,Des Moines to Beacon Hill (flex),10:00,47.3978844,-122.30898,47.578668036563016,-122.31139183,Des Moines,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -55,North Auburn to Hilshire Terrace (transit),10:00,47.340218616,-122.2246170043,47.40648236,-122.18101501,North Auburn,Hilshire Terrace,TRANSIT|WALK,transit -56,North Auburn to Hilshire Terrace (flex),10:00,47.340218616,-122.2246170043,47.40648236,-122.18101501,North Auburn,Hilshire Terrace,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -57,North Auburn to Normandy Park (transit),10:00,47.340218616,-122.2246170043,47.44306609375831,-122.34237670,North Auburn,Normandy Park,TRANSIT|WALK,transit -58,North Auburn to Normandy Park (flex),10:00,47.340218616,-122.2246170043,47.44306609375831,-122.34237670,North Auburn,Normandy Park,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -59,North Auburn to Des Moines (transit),10:00,47.340218616,-122.2246170043,47.3978844,-122.30898,North Auburn,Des Moines,TRANSIT|WALK,transit -60,North Auburn to Des Moines (flex),10:00,47.340218616,-122.2246170043,47.3978844,-122.30898,North Auburn,Des Moines,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -61,North Auburn to Federal Way (transit),10:00,47.340218616,-122.2246170043,47.31322426310727,-122.336540222167,North Auburn,Federal Way,TRANSIT|WALK,transit -62,North Auburn to Federal Way (flex),10:00,47.340218616,-122.2246170043,47.31322426310727,-122.336540222167,North Auburn,Federal Way,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -63,North Auburn to West Seattle (transit),10:00,47.340218616,-122.2246170043,47.571024,-122.3877811,North Auburn,West Seattle,TRANSIT|WALK,transit -65,North Auburn to Puyallup (transit),10:00,47.340218616,-122.2246170043,47.18399599096,-122.28950500488,North Auburn,Puyallup,TRANSIT|WALK,transit -66,North Auburn to Puyallup (flex),10:00,47.340218616,-122.2246170043,47.18399599096,-122.28950500488,North Auburn,Puyallup,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -67,North Auburn to Snoqualmie (transit),10:00,47.340218616,-122.2246170043,47.52827129,-121.827821731,North Auburn,Snoqualmie,TRANSIT|WALK,transit -68,North Auburn to Snoqualmie (flex),10:00,47.340218616,-122.2246170043,47.52827129,-121.827821731,North Auburn,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -69,North Auburn to Queen Anne (transit),10:00,47.340218616,-122.2246170043,47.6394849792,-122.3636627197,North Auburn,Queen Anne,TRANSIT|WALK,transit -71,North Auburn to Beacon Hill (transit),10:00,47.340218616,-122.2246170043,47.578668036563016,-122.31139183,North Auburn,Beacon Hill,TRANSIT|WALK,transit -72,North Auburn to Beacon Hill (flex),10:00,47.340218616,-122.2246170043,47.578668036563016,-122.31139183,North Auburn,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -73,Federal Way to Hilshire Terrace (transit),10:00,47.31322426310727,-122.336540222167,47.40648236,-122.18101501,Federal Way,Hilshire Terrace,TRANSIT|WALK,transit -74,Federal Way to Hilshire Terrace (flex),10:00,47.31322426310727,-122.336540222167,47.40648236,-122.18101501,Federal Way,Hilshire Terrace,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -75,Federal Way to Normandy Park (transit),10:00,47.31322426310727,-122.336540222167,47.44306609375831,-122.34237670,Federal Way,Normandy Park,TRANSIT|WALK,transit -76,Federal Way to Normandy Park (flex),10:00,47.31322426310727,-122.336540222167,47.44306609375831,-122.34237670,Federal Way,Normandy Park,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -77,Federal Way to Des Moines (transit),10:00,47.31322426310727,-122.336540222167,47.3978844,-122.30898,Federal Way,Des Moines,TRANSIT|WALK,transit -78,Federal Way to Des Moines (flex),10:00,47.31322426310727,-122.336540222167,47.3978844,-122.30898,Federal Way,Des Moines,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -79,Federal Way to North Auburn (transit),10:00,47.31322426310727,-122.336540222167,47.340218616,-122.2246170043,Federal Way,North Auburn,TRANSIT|WALK,transit -80,Federal Way to North Auburn (flex),10:00,47.31322426310727,-122.336540222167,47.340218616,-122.2246170043,Federal Way,North Auburn,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -81,Federal Way to West Seattle (transit),10:00,47.31322426310727,-122.336540222167,47.571024,-122.3877811,Federal Way,West Seattle,TRANSIT|WALK,transit -83,Federal Way to Puyallup (transit),10:00,47.31322426310727,-122.336540222167,47.18399599096,-122.28950500488,Federal Way,Puyallup,TRANSIT|WALK,transit -84,Federal Way to Puyallup (flex),10:00,47.31322426310727,-122.336540222167,47.18399599096,-122.28950500488,Federal Way,Puyallup,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -85,Federal Way to Snoqualmie (transit),10:00,47.31322426310727,-122.336540222167,47.52827129,-121.827821731,Federal Way,Snoqualmie,TRANSIT|WALK,transit -86,Federal Way to Snoqualmie (flex),10:00,47.31322426310727,-122.336540222167,47.52827129,-121.827821731,Federal Way,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -87,Federal Way to Queen Anne (transit),10:00,47.31322426310727,-122.336540222167,47.6394849792,-122.3636627197,Federal Way,Queen Anne,TRANSIT|WALK,transit -89,Federal Way to Beacon Hill (transit),10:00,47.31322426310727,-122.336540222167,47.578668036563016,-122.31139183,Federal Way,Beacon Hill,TRANSIT|WALK,transit -90,Federal Way to Beacon Hill (flex),10:00,47.31322426310727,-122.336540222167,47.578668036563016,-122.31139183,Federal Way,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -91,West Seattle to Hilshire Terrace (transit),10:00,47.571024,-122.3877811,47.40648236,-122.18101501,West Seattle,Hilshire Terrace,TRANSIT|WALK,transit -92,West Seattle to Hilshire Terrace (flex),10:00,47.571024,-122.3877811,47.40648236,-122.18101501,West Seattle,Hilshire Terrace,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -93,West Seattle to Normandy Park (transit),10:00,47.571024,-122.3877811,47.44306609375831,-122.34237670,West Seattle,Normandy Park,TRANSIT|WALK,transit -94,West Seattle to Normandy Park (flex),10:00,47.571024,-122.3877811,47.44306609375831,-122.34237670,West Seattle,Normandy Park,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -95,West Seattle to Des Moines (transit),10:00,47.571024,-122.3877811,47.3978844,-122.30898,West Seattle,Des Moines,TRANSIT|WALK,transit -96,West Seattle to Des Moines (flex),10:00,47.571024,-122.3877811,47.3978844,-122.30898,West Seattle,Des Moines,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -97,West Seattle to North Auburn (transit),10:00,47.571024,-122.3877811,47.340218616,-122.2246170043,West Seattle,North Auburn,TRANSIT|WALK,transit -98,West Seattle to North Auburn (flex),10:00,47.571024,-122.3877811,47.340218616,-122.2246170043,West Seattle,North Auburn,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -99,West Seattle to Federal Way (transit),10:00,47.571024,-122.3877811,47.31322426310727,-122.336540222167,West Seattle,Federal Way,TRANSIT|WALK,transit -100,West Seattle to Federal Way (flex),10:00,47.571024,-122.3877811,47.31322426310727,-122.336540222167,West Seattle,Federal Way,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -101,West Seattle to Puyallup (transit),10:00,47.571024,-122.3877811,47.18399599096,-122.28950500488,West Seattle,Puyallup,TRANSIT|WALK,transit -102,West Seattle to Puyallup (flex),10:00,47.571024,-122.3877811,47.18399599096,-122.28950500488,West Seattle,Puyallup,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -103,West Seattle to Snoqualmie (transit),10:00,47.571024,-122.3877811,47.52827129,-121.827821731,West Seattle,Snoqualmie,TRANSIT|WALK,transit -104,West Seattle to Snoqualmie (flex),10:00,47.571024,-122.3877811,47.52827129,-121.827821731,West Seattle,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -105,West Seattle to Queen Anne (transit),10:00,47.571024,-122.3877811,47.6394849792,-122.3636627197,West Seattle,Queen Anne,TRANSIT|WALK,transit -106,West Seattle to Queen Anne (flex),10:00,47.571024,-122.3877811,47.6394849792,-122.3636627197,West Seattle,Queen Anne,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -107,West Seattle to Beacon Hill (transit),10:00,47.571024,-122.3877811,47.578668036563016,-122.31139183,West Seattle,Beacon Hill,TRANSIT|WALK,transit -108,West Seattle to Beacon Hill (flex),10:00,47.571024,-122.3877811,47.578668036563016,-122.31139183,West Seattle,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -109,Puyallup to Hilshire Terrace (transit),10:00,47.18399599096,-122.28950500488,47.40648236,-122.18101501,Puyallup,Hilshire Terrace,TRANSIT|WALK,transit -110,Puyallup to Hilshire Terrace (flex),10:00,47.18399599096,-122.28950500488,47.40648236,-122.18101501,Puyallup,Hilshire Terrace,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -111,Puyallup to Normandy Park (transit),10:00,47.18399599096,-122.28950500488,47.44306609375831,-122.34237670,Puyallup,Normandy Park,TRANSIT|WALK,transit -112,Puyallup to Normandy Park (flex),10:00,47.18399599096,-122.28950500488,47.44306609375831,-122.34237670,Puyallup,Normandy Park,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -113,Puyallup to Des Moines (transit),10:00,47.18399599096,-122.28950500488,47.3978844,-122.30898,Puyallup,Des Moines,TRANSIT|WALK,transit -114,Puyallup to Des Moines (flex),10:00,47.18399599096,-122.28950500488,47.3978844,-122.30898,Puyallup,Des Moines,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -115,Puyallup to North Auburn (transit),10:00,47.18399599096,-122.28950500488,47.340218616,-122.2246170043,Puyallup,North Auburn,TRANSIT|WALK,transit -116,Puyallup to North Auburn (flex),10:00,47.18399599096,-122.28950500488,47.340218616,-122.2246170043,Puyallup,North Auburn,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -117,Puyallup to Federal Way (transit),10:00,47.18399599096,-122.28950500488,47.31322426310727,-122.336540222167,Puyallup,Federal Way,TRANSIT|WALK,transit -118,Puyallup to Federal Way (flex),10:00,47.18399599096,-122.28950500488,47.31322426310727,-122.336540222167,Puyallup,Federal Way,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -119,Puyallup to West Seattle (transit),10:00,47.18399599096,-122.28950500488,47.571024,-122.3877811,Puyallup,West Seattle,TRANSIT|WALK,transit -121,Puyallup to Snoqualmie (transit),10:00,47.18399599096,-122.28950500488,47.52827129,-121.827821731,Puyallup,Snoqualmie,TRANSIT|WALK,transit -122,Puyallup to Snoqualmie (flex),10:00,47.18399599096,-122.28950500488,47.52827129,-121.827821731,Puyallup,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -123,Puyallup to Queen Anne (transit),10:00,47.18399599096,-122.28950500488,47.6394849792,-122.3636627197,Puyallup,Queen Anne,TRANSIT|WALK,transit -124,Puyallup to Queen Anne (flex),10:00,47.18399599096,-122.28950500488,47.6394849792,-122.3636627197,Puyallup,Queen Anne,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -125,Puyallup to Beacon Hill (transit),10:00,47.18399599096,-122.28950500488,47.578668036563016,-122.31139183,Puyallup,Beacon Hill,TRANSIT|WALK,transit -126,Puyallup to Beacon Hill (flex),10:00,47.18399599096,-122.28950500488,47.578668036563016,-122.31139183,Puyallup,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -127,Snoqualmie to Hilshire Terrace (transit),10:00,47.52827129,-121.827821731,47.40648236,-122.18101501,Snoqualmie,Hilshire Terrace,TRANSIT|WALK,transit -129,Snoqualmie to Normandy Park (transit),10:00,47.52827129,-121.827821731,47.44306609375831,-122.34237670,Snoqualmie,Normandy Park,TRANSIT|WALK,transit -131,Snoqualmie to Des Moines (transit),10:00,47.52827129,-121.827821731,47.3978844,-122.30898,Snoqualmie,Des Moines,TRANSIT|WALK,transit -133,Snoqualmie to North Auburn (transit),10:00,47.52827129,-121.827821731,47.340218616,-122.2246170043,Snoqualmie,North Auburn,TRANSIT|WALK,transit -135,Snoqualmie to Federal Way (transit),10:00,47.52827129,-121.827821731,47.31322426310727,-122.336540222167,Snoqualmie,Federal Way,TRANSIT|WALK,transit -137,Snoqualmie to West Seattle (transit),10:00,47.52827129,-121.827821731,47.571024,-122.3877811,Snoqualmie,West Seattle,TRANSIT|WALK,transit -139,Snoqualmie to Puyallup (transit),10:00,47.52827129,-121.827821731,47.18399599096,-122.28950500488,Snoqualmie,Puyallup,TRANSIT|WALK,transit -140,Snoqualmie to Puyallup (flex),10:00,47.52827129,-121.827821731,47.18399599096,-122.28950500488,Snoqualmie,Puyallup,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -141,Snoqualmie to Queen Anne (transit),10:00,47.52827129,-121.827821731,47.6394849792,-122.3636627197,Snoqualmie,Queen Anne,TRANSIT|WALK,transit -142,Snoqualmie to Queen Anne (flex),10:00,47.52827129,-121.827821731,47.6394849792,-122.3636627197,Snoqualmie,Queen Anne,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -143,Snoqualmie to Beacon Hill (transit),10:00,47.52827129,-121.827821731,47.578668036563016,-122.31139183,Snoqualmie,Beacon Hill,TRANSIT|WALK,transit -144,Snoqualmie to Beacon Hill (flex),10:00,47.52827129,-121.827821731,47.578668036563016,-122.31139183,Snoqualmie,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -145,Queen Anne to Hilshire Terrace (transit),10:00,47.6394849792,-122.3636627197,47.40648236,-122.18101501,Queen Anne,Hilshire Terrace,TRANSIT|WALK,transit -147,Queen Anne to Normandy Park (transit),10:00,47.6394849792,-122.3636627197,47.44306609375831,-122.34237670,Queen Anne,Normandy Park,TRANSIT|WALK,transit -148,Queen Anne to Normandy Park (flex),10:00,47.6394849792,-122.3636627197,47.44306609375831,-122.34237670,Queen Anne,Normandy Park,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -149,Queen Anne to Des Moines (transit),10:00,47.6394849792,-122.3636627197,47.3978844,-122.30898,Queen Anne,Des Moines,TRANSIT|WALK,transit -150,Queen Anne to Des Moines (flex),10:00,47.6394849792,-122.3636627197,47.3978844,-122.30898,Queen Anne,Des Moines,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -151,Queen Anne to North Auburn (transit),10:00,47.6394849792,-122.3636627197,47.340218616,-122.2246170043,Queen Anne,North Auburn,TRANSIT|WALK,transit -153,Queen Anne to Federal Way (transit),10:00,47.6394849792,-122.3636627197,47.31322426310727,-122.336540222167,Queen Anne,Federal Way,TRANSIT|WALK,transit -155,Queen Anne to West Seattle (transit),10:00,47.6394849792,-122.3636627197,47.571024,-122.3877811,Queen Anne,West Seattle,TRANSIT|WALK,transit -156,Queen Anne to West Seattle (flex),10:00,47.6394849792,-122.3636627197,47.571024,-122.3877811,Queen Anne,West Seattle,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -157,Queen Anne to Puyallup (transit),10:00,47.6394849792,-122.3636627197,47.18399599096,-122.28950500488,Queen Anne,Puyallup,TRANSIT|WALK,transit -159,Queen Anne to Snoqualmie (transit),10:00,47.6394849792,-122.3636627197,47.52827129,-121.827821731,Queen Anne,Snoqualmie,TRANSIT|WALK,transit -160,Queen Anne to Snoqualmie (flex),10:00,47.6394849792,-122.3636627197,47.52827129,-121.827821731,Queen Anne,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -161,Queen Anne to Beacon Hill (transit),10:00,47.6394849792,-122.3636627197,47.578668036563016,-122.31139183,Queen Anne,Beacon Hill,TRANSIT|WALK,transit -162,Queen Anne to Beacon Hill (flex),10:00,47.6394849792,-122.3636627197,47.578668036563016,-122.31139183,Queen Anne,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -163,Beacon Hill to Hilshire Terrace (transit),10:00,47.578668036563016,-122.31139183,47.40648236,-122.18101501,Beacon Hill,Hilshire Terrace,TRANSIT|WALK,transit -165,Beacon Hill to Normandy Park (transit),10:00,47.578668036563016,-122.31139183,47.44306609375831,-122.34237670,Beacon Hill,Normandy Park,TRANSIT|WALK,transit -166,Beacon Hill to Normandy Park (flex),10:00,47.578668036563016,-122.31139183,47.44306609375831,-122.34237670,Beacon Hill,Normandy Park,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -167,Beacon Hill to Des Moines (transit),10:00,47.578668036563016,-122.31139183,47.3978844,-122.30898,Beacon Hill,Des Moines,TRANSIT|WALK,transit -168,Beacon Hill to Des Moines (flex),10:00,47.578668036563016,-122.31139183,47.3978844,-122.30898,Beacon Hill,Des Moines,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -169,Beacon Hill to North Auburn (transit),10:00,47.578668036563016,-122.31139183,47.340218616,-122.2246170043,Beacon Hill,North Auburn,TRANSIT|WALK,transit -170,Beacon Hill to North Auburn (flex),10:00,47.578668036563016,-122.31139183,47.340218616,-122.2246170043,Beacon Hill,North Auburn,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -171,Beacon Hill to Federal Way (transit),10:00,47.578668036563016,-122.31139183,47.31322426310727,-122.336540222167,Beacon Hill,Federal Way,TRANSIT|WALK,transit -173,Beacon Hill to West Seattle (transit),10:00,47.578668036563016,-122.31139183,47.571024,-122.3877811,Beacon Hill,West Seattle,TRANSIT|WALK,transit -174,Beacon Hill to West Seattle (flex),10:00,47.578668036563016,-122.31139183,47.571024,-122.3877811,Beacon Hill,West Seattle,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -175,Beacon Hill to Puyallup (transit),10:00,47.578668036563016,-122.31139183,47.18399599096,-122.28950500488,Beacon Hill,Puyallup,TRANSIT|WALK,transit -176,Beacon Hill to Puyallup (flex),10:00,47.578668036563016,-122.31139183,47.18399599096,-122.28950500488,Beacon Hill,Puyallup,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -177,Beacon Hill to Snoqualmie (transit),10:00,47.578668036563016,-122.31139183,47.52827129,-121.827821731,Beacon Hill,Snoqualmie,TRANSIT|WALK,transit -178,Beacon Hill to Snoqualmie (flex),10:00,47.578668036563016,-122.31139183,47.52827129,-121.827821731,Beacon Hill,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex -179,Beacon Hill to Queen Anne (transit),10:00,47.578668036563016,-122.31139183,47.6394849792,-122.3636627197,Beacon Hill,Queen Anne,TRANSIT|WALK,transit -180,Beacon Hill to Queen Anne (flex),10:00,47.578668036563016,-122.31139183,47.6394849792,-122.3636627197,Beacon Hill,Queen Anne,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex +1,Hilshire Terrace to Normandy Park (flex-direct),10:00,47.40648236,-122.18101501,47.44306609375831,-122.34237670,Hilshire Terrace,Normandy Park,FLEX_DIRECT|WALK,flex-direct +2,Hilshire Terrace to Normandy Park (flex-and-transit),10:00,47.40648236,-122.18101501,47.44306609375831,-122.34237670,Hilshire Terrace,Normandy Park,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +3,Hilshire Terrace to Des Moines (flex-direct),10:00,47.40648236,-122.18101501,47.3978844,-122.30898,Hilshire Terrace,Des Moines,FLEX_DIRECT|WALK,flex-direct +4,Hilshire Terrace to Des Moines (flex-and-transit),10:00,47.40648236,-122.18101501,47.3978844,-122.30898,Hilshire Terrace,Des Moines,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +5,Hilshire Terrace to West Seattle (flex-direct),10:00,47.40648236,-122.18101501,47.571024,-122.3877811,Hilshire Terrace,West Seattle,FLEX_DIRECT|WALK,flex-direct +6,Hilshire Terrace to West Seattle (flex-and-transit),10:00,47.40648236,-122.18101501,47.571024,-122.3877811,Hilshire Terrace,West Seattle,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +7,Hilshire Terrace to Puyallup (flex-direct),10:00,47.40648236,-122.18101501,47.18399599096,-122.28950500488,Hilshire Terrace,Puyallup,FLEX_DIRECT|WALK,flex-direct +8,Hilshire Terrace to Puyallup (flex-and-transit),10:00,47.40648236,-122.18101501,47.18399599096,-122.28950500488,Hilshire Terrace,Puyallup,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +9,Hilshire Terrace to Snoqualmie (flex-direct),10:00,47.40648236,-122.18101501,47.52827129,-121.827821731,Hilshire Terrace,Snoqualmie,FLEX_DIRECT|WALK,flex-direct +10,Hilshire Terrace to Snoqualmie (flex-and-transit),10:00,47.40648236,-122.18101501,47.52827129,-121.827821731,Hilshire Terrace,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +11,Hilshire Terrace to Queen Anne (flex-direct),10:00,47.40648236,-122.18101501,47.6394849792,-122.3636627197,Hilshire Terrace,Queen Anne,FLEX_DIRECT|WALK,flex-direct +12,Hilshire Terrace to Queen Anne (flex-and-transit),10:00,47.40648236,-122.18101501,47.6394849792,-122.3636627197,Hilshire Terrace,Queen Anne,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +13,Hilshire Terrace to Beacon Hill (flex-direct),10:00,47.40648236,-122.18101501,47.578668036563016,-122.31139183,Hilshire Terrace,Beacon Hill,FLEX_DIRECT|WALK,flex-direct +14,Hilshire Terrace to Beacon Hill (flex-and-transit),10:00,47.40648236,-122.18101501,47.578668036563016,-122.31139183,Hilshire Terrace,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +15,Normandy Park to Hilshire Terrace (flex-direct),10:00,47.44306609375831,-122.34237670,47.40648236,-122.18101501,Normandy Park,Hilshire Terrace,FLEX_DIRECT|WALK,flex-direct +16,Normandy Park to Hilshire Terrace (flex-and-transit),10:00,47.44306609375831,-122.34237670,47.40648236,-122.18101501,Normandy Park,Hilshire Terrace,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +17,Normandy Park to Des Moines (flex-direct),10:00,47.44306609375831,-122.34237670,47.3978844,-122.30898,Normandy Park,Des Moines,FLEX_DIRECT|WALK,flex-direct +18,Normandy Park to Des Moines (flex-and-transit),10:00,47.44306609375831,-122.34237670,47.3978844,-122.30898,Normandy Park,Des Moines,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +19,Normandy Park to West Seattle (flex-direct),10:00,47.44306609375831,-122.34237670,47.571024,-122.3877811,Normandy Park,West Seattle,FLEX_DIRECT|WALK,flex-direct +20,Normandy Park to West Seattle (flex-and-transit),10:00,47.44306609375831,-122.34237670,47.571024,-122.3877811,Normandy Park,West Seattle,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +21,Normandy Park to Puyallup (flex-direct),10:00,47.44306609375831,-122.34237670,47.18399599096,-122.28950500488,Normandy Park,Puyallup,FLEX_DIRECT|WALK,flex-direct +22,Normandy Park to Puyallup (flex-and-transit),10:00,47.44306609375831,-122.34237670,47.18399599096,-122.28950500488,Normandy Park,Puyallup,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +23,Normandy Park to Snoqualmie (flex-direct),10:00,47.44306609375831,-122.34237670,47.52827129,-121.827821731,Normandy Park,Snoqualmie,FLEX_DIRECT|WALK,flex-direct +24,Normandy Park to Snoqualmie (flex-and-transit),10:00,47.44306609375831,-122.34237670,47.52827129,-121.827821731,Normandy Park,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +25,Normandy Park to Queen Anne (flex-direct),10:00,47.44306609375831,-122.34237670,47.6394849792,-122.3636627197,Normandy Park,Queen Anne,FLEX_DIRECT|WALK,flex-direct +26,Normandy Park to Queen Anne (flex-and-transit),10:00,47.44306609375831,-122.34237670,47.6394849792,-122.3636627197,Normandy Park,Queen Anne,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +27,Normandy Park to Beacon Hill (flex-direct),10:00,47.44306609375831,-122.34237670,47.578668036563016,-122.31139183,Normandy Park,Beacon Hill,FLEX_DIRECT|WALK,flex-direct +28,Normandy Park to Beacon Hill (flex-and-transit),10:00,47.44306609375831,-122.34237670,47.578668036563016,-122.31139183,Normandy Park,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +29,Des Moines to Hilshire Terrace (flex-direct),10:00,47.3978844,-122.30898,47.40648236,-122.18101501,Des Moines,Hilshire Terrace,FLEX_DIRECT|WALK,flex-direct +30,Des Moines to Hilshire Terrace (flex-and-transit),10:00,47.3978844,-122.30898,47.40648236,-122.18101501,Des Moines,Hilshire Terrace,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +31,Des Moines to Normandy Park (flex-direct),10:00,47.3978844,-122.30898,47.44306609375831,-122.34237670,Des Moines,Normandy Park,FLEX_DIRECT|WALK,flex-direct +32,Des Moines to Normandy Park (flex-and-transit),10:00,47.3978844,-122.30898,47.44306609375831,-122.34237670,Des Moines,Normandy Park,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +33,Des Moines to West Seattle (flex-direct),10:00,47.3978844,-122.30898,47.571024,-122.3877811,Des Moines,West Seattle,FLEX_DIRECT|WALK,flex-direct +34,Des Moines to West Seattle (flex-and-transit),10:00,47.3978844,-122.30898,47.571024,-122.3877811,Des Moines,West Seattle,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +35,Des Moines to Puyallup (flex-direct),10:00,47.3978844,-122.30898,47.18399599096,-122.28950500488,Des Moines,Puyallup,FLEX_DIRECT|WALK,flex-direct +36,Des Moines to Puyallup (flex-and-transit),10:00,47.3978844,-122.30898,47.18399599096,-122.28950500488,Des Moines,Puyallup,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +37,Des Moines to Snoqualmie (flex-direct),10:00,47.3978844,-122.30898,47.52827129,-121.827821731,Des Moines,Snoqualmie,FLEX_DIRECT|WALK,flex-direct +38,Des Moines to Snoqualmie (flex-and-transit),10:00,47.3978844,-122.30898,47.52827129,-121.827821731,Des Moines,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +39,Des Moines to Queen Anne (flex-direct),10:00,47.3978844,-122.30898,47.6394849792,-122.3636627197,Des Moines,Queen Anne,FLEX_DIRECT|WALK,flex-direct +40,Des Moines to Queen Anne (flex-and-transit),10:00,47.3978844,-122.30898,47.6394849792,-122.3636627197,Des Moines,Queen Anne,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +41,Des Moines to Beacon Hill (flex-direct),10:00,47.3978844,-122.30898,47.578668036563016,-122.31139183,Des Moines,Beacon Hill,FLEX_DIRECT|WALK,flex-direct +42,Des Moines to Beacon Hill (flex-and-transit),10:00,47.3978844,-122.30898,47.578668036563016,-122.31139183,Des Moines,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +43,West Seattle to Hilshire Terrace (flex-direct),10:00,47.571024,-122.3877811,47.40648236,-122.18101501,West Seattle,Hilshire Terrace,FLEX_DIRECT|WALK,flex-direct +44,West Seattle to Hilshire Terrace (flex-and-transit),10:00,47.571024,-122.3877811,47.40648236,-122.18101501,West Seattle,Hilshire Terrace,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +45,West Seattle to Normandy Park (flex-direct),10:00,47.571024,-122.3877811,47.44306609375831,-122.34237670,West Seattle,Normandy Park,FLEX_DIRECT|WALK,flex-direct +46,West Seattle to Normandy Park (flex-and-transit),10:00,47.571024,-122.3877811,47.44306609375831,-122.34237670,West Seattle,Normandy Park,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +47,West Seattle to Des Moines (flex-direct),10:00,47.571024,-122.3877811,47.3978844,-122.30898,West Seattle,Des Moines,FLEX_DIRECT|WALK,flex-direct +48,West Seattle to Des Moines (flex-and-transit),10:00,47.571024,-122.3877811,47.3978844,-122.30898,West Seattle,Des Moines,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +49,West Seattle to Puyallup (flex-direct),10:00,47.571024,-122.3877811,47.18399599096,-122.28950500488,West Seattle,Puyallup,FLEX_DIRECT|WALK,flex-direct +50,West Seattle to Puyallup (flex-and-transit),10:00,47.571024,-122.3877811,47.18399599096,-122.28950500488,West Seattle,Puyallup,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +51,West Seattle to Snoqualmie (flex-direct),10:00,47.571024,-122.3877811,47.52827129,-121.827821731,West Seattle,Snoqualmie,FLEX_DIRECT|WALK,flex-direct +52,West Seattle to Snoqualmie (flex-and-transit),10:00,47.571024,-122.3877811,47.52827129,-121.827821731,West Seattle,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +53,West Seattle to Queen Anne (flex-direct),10:00,47.571024,-122.3877811,47.6394849792,-122.3636627197,West Seattle,Queen Anne,FLEX_DIRECT|WALK,flex-direct +54,West Seattle to Queen Anne (flex-and-transit),10:00,47.571024,-122.3877811,47.6394849792,-122.3636627197,West Seattle,Queen Anne,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +55,West Seattle to Beacon Hill (flex-direct),10:00,47.571024,-122.3877811,47.578668036563016,-122.31139183,West Seattle,Beacon Hill,FLEX_DIRECT|WALK,flex-direct +56,West Seattle to Beacon Hill (flex-and-transit),10:00,47.571024,-122.3877811,47.578668036563016,-122.31139183,West Seattle,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +57,Puyallup to Hilshire Terrace (flex-direct),10:00,47.18399599096,-122.28950500488,47.40648236,-122.18101501,Puyallup,Hilshire Terrace,FLEX_DIRECT|WALK,flex-direct +58,Puyallup to Hilshire Terrace (flex-and-transit),10:00,47.18399599096,-122.28950500488,47.40648236,-122.18101501,Puyallup,Hilshire Terrace,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +59,Puyallup to Normandy Park (flex-direct),10:00,47.18399599096,-122.28950500488,47.44306609375831,-122.34237670,Puyallup,Normandy Park,FLEX_DIRECT|WALK,flex-direct +60,Puyallup to Normandy Park (flex-and-transit),10:00,47.18399599096,-122.28950500488,47.44306609375831,-122.34237670,Puyallup,Normandy Park,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +61,Puyallup to Des Moines (flex-direct),10:00,47.18399599096,-122.28950500488,47.3978844,-122.30898,Puyallup,Des Moines,FLEX_DIRECT|WALK,flex-direct +62,Puyallup to Des Moines (flex-and-transit),10:00,47.18399599096,-122.28950500488,47.3978844,-122.30898,Puyallup,Des Moines,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +63,Puyallup to West Seattle (flex-direct),10:00,47.18399599096,-122.28950500488,47.571024,-122.3877811,Puyallup,West Seattle,FLEX_DIRECT|WALK,flex-direct +64,Puyallup to West Seattle (flex-and-transit),10:00,47.18399599096,-122.28950500488,47.571024,-122.3877811,Puyallup,West Seattle,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +65,Puyallup to Snoqualmie (flex-direct),10:00,47.18399599096,-122.28950500488,47.52827129,-121.827821731,Puyallup,Snoqualmie,FLEX_DIRECT|WALK,flex-direct +66,Puyallup to Snoqualmie (flex-and-transit),10:00,47.18399599096,-122.28950500488,47.52827129,-121.827821731,Puyallup,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +67,Puyallup to Queen Anne (flex-direct),10:00,47.18399599096,-122.28950500488,47.6394849792,-122.3636627197,Puyallup,Queen Anne,FLEX_DIRECT|WALK,flex-direct +68,Puyallup to Queen Anne (flex-and-transit),10:00,47.18399599096,-122.28950500488,47.6394849792,-122.3636627197,Puyallup,Queen Anne,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +69,Puyallup to Beacon Hill (flex-direct),10:00,47.18399599096,-122.28950500488,47.578668036563016,-122.31139183,Puyallup,Beacon Hill,FLEX_DIRECT|WALK,flex-direct +70,Puyallup to Beacon Hill (flex-and-transit),10:00,47.18399599096,-122.28950500488,47.578668036563016,-122.31139183,Puyallup,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +71,Snoqualmie to Hilshire Terrace (flex-direct),10:00,47.52827129,-121.827821731,47.40648236,-122.18101501,Snoqualmie,Hilshire Terrace,FLEX_DIRECT|WALK,flex-direct +72,Snoqualmie to Hilshire Terrace (flex-and-transit),10:00,47.52827129,-121.827821731,47.40648236,-122.18101501,Snoqualmie,Hilshire Terrace,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +73,Snoqualmie to Normandy Park (flex-direct),10:00,47.52827129,-121.827821731,47.44306609375831,-122.34237670,Snoqualmie,Normandy Park,FLEX_DIRECT|WALK,flex-direct +74,Snoqualmie to Normandy Park (flex-and-transit),10:00,47.52827129,-121.827821731,47.44306609375831,-122.34237670,Snoqualmie,Normandy Park,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +75,Snoqualmie to Des Moines (flex-direct),10:00,47.52827129,-121.827821731,47.3978844,-122.30898,Snoqualmie,Des Moines,FLEX_DIRECT|WALK,flex-direct +76,Snoqualmie to Des Moines (flex-and-transit),10:00,47.52827129,-121.827821731,47.3978844,-122.30898,Snoqualmie,Des Moines,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +77,Snoqualmie to West Seattle (flex-direct),10:00,47.52827129,-121.827821731,47.571024,-122.3877811,Snoqualmie,West Seattle,FLEX_DIRECT|WALK,flex-direct +78,Snoqualmie to West Seattle (flex-and-transit),10:00,47.52827129,-121.827821731,47.571024,-122.3877811,Snoqualmie,West Seattle,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +79,Snoqualmie to Puyallup (flex-direct),10:00,47.52827129,-121.827821731,47.18399599096,-122.28950500488,Snoqualmie,Puyallup,FLEX_DIRECT|WALK,flex-direct +80,Snoqualmie to Puyallup (flex-and-transit),10:00,47.52827129,-121.827821731,47.18399599096,-122.28950500488,Snoqualmie,Puyallup,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +81,Snoqualmie to Queen Anne (flex-direct),10:00,47.52827129,-121.827821731,47.6394849792,-122.3636627197,Snoqualmie,Queen Anne,FLEX_DIRECT|WALK,flex-direct +82,Snoqualmie to Queen Anne (flex-and-transit),10:00,47.52827129,-121.827821731,47.6394849792,-122.3636627197,Snoqualmie,Queen Anne,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +83,Snoqualmie to Beacon Hill (flex-direct),10:00,47.52827129,-121.827821731,47.578668036563016,-122.31139183,Snoqualmie,Beacon Hill,FLEX_DIRECT|WALK,flex-direct +84,Snoqualmie to Beacon Hill (flex-and-transit),10:00,47.52827129,-121.827821731,47.578668036563016,-122.31139183,Snoqualmie,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +85,Queen Anne to Hilshire Terrace (flex-direct),10:00,47.6394849792,-122.3636627197,47.40648236,-122.18101501,Queen Anne,Hilshire Terrace,FLEX_DIRECT|WALK,flex-direct +86,Queen Anne to Hilshire Terrace (flex-and-transit),10:00,47.6394849792,-122.3636627197,47.40648236,-122.18101501,Queen Anne,Hilshire Terrace,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +87,Queen Anne to Normandy Park (flex-direct),10:00,47.6394849792,-122.3636627197,47.44306609375831,-122.34237670,Queen Anne,Normandy Park,FLEX_DIRECT|WALK,flex-direct +88,Queen Anne to Normandy Park (flex-and-transit),10:00,47.6394849792,-122.3636627197,47.44306609375831,-122.34237670,Queen Anne,Normandy Park,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +89,Queen Anne to Des Moines (flex-direct),10:00,47.6394849792,-122.3636627197,47.3978844,-122.30898,Queen Anne,Des Moines,FLEX_DIRECT|WALK,flex-direct +90,Queen Anne to Des Moines (flex-and-transit),10:00,47.6394849792,-122.3636627197,47.3978844,-122.30898,Queen Anne,Des Moines,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +91,Queen Anne to West Seattle (flex-direct),10:00,47.6394849792,-122.3636627197,47.571024,-122.3877811,Queen Anne,West Seattle,FLEX_DIRECT|WALK,flex-direct +92,Queen Anne to West Seattle (flex-and-transit),10:00,47.6394849792,-122.3636627197,47.571024,-122.3877811,Queen Anne,West Seattle,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +93,Queen Anne to Puyallup (flex-direct),10:00,47.6394849792,-122.3636627197,47.18399599096,-122.28950500488,Queen Anne,Puyallup,FLEX_DIRECT|WALK,flex-direct +94,Queen Anne to Puyallup (flex-and-transit),10:00,47.6394849792,-122.3636627197,47.18399599096,-122.28950500488,Queen Anne,Puyallup,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +95,Queen Anne to Snoqualmie (flex-direct),10:00,47.6394849792,-122.3636627197,47.52827129,-121.827821731,Queen Anne,Snoqualmie,FLEX_DIRECT|WALK,flex-direct +96,Queen Anne to Snoqualmie (flex-and-transit),10:00,47.6394849792,-122.3636627197,47.52827129,-121.827821731,Queen Anne,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +97,Queen Anne to Beacon Hill (flex-direct),10:00,47.6394849792,-122.3636627197,47.578668036563016,-122.31139183,Queen Anne,Beacon Hill,FLEX_DIRECT|WALK,flex-direct +98,Queen Anne to Beacon Hill (flex-and-transit),10:00,47.6394849792,-122.3636627197,47.578668036563016,-122.31139183,Queen Anne,Beacon Hill,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +99,Beacon Hill to Hilshire Terrace (flex-direct),10:00,47.578668036563016,-122.31139183,47.40648236,-122.18101501,Beacon Hill,Hilshire Terrace,FLEX_DIRECT|WALK,flex-direct +100,Beacon Hill to Hilshire Terrace (flex-and-transit),10:00,47.578668036563016,-122.31139183,47.40648236,-122.18101501,Beacon Hill,Hilshire Terrace,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +101,Beacon Hill to Normandy Park (flex-direct),10:00,47.578668036563016,-122.31139183,47.44306609375831,-122.34237670,Beacon Hill,Normandy Park,FLEX_DIRECT|WALK,flex-direct +102,Beacon Hill to Normandy Park (flex-and-transit),10:00,47.578668036563016,-122.31139183,47.44306609375831,-122.34237670,Beacon Hill,Normandy Park,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +103,Beacon Hill to Des Moines (flex-direct),10:00,47.578668036563016,-122.31139183,47.3978844,-122.30898,Beacon Hill,Des Moines,FLEX_DIRECT|WALK,flex-direct +104,Beacon Hill to Des Moines (flex-and-transit),10:00,47.578668036563016,-122.31139183,47.3978844,-122.30898,Beacon Hill,Des Moines,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +105,Beacon Hill to West Seattle (flex-direct),10:00,47.578668036563016,-122.31139183,47.571024,-122.3877811,Beacon Hill,West Seattle,FLEX_DIRECT|WALK,flex-direct +106,Beacon Hill to West Seattle (flex-and-transit),10:00,47.578668036563016,-122.31139183,47.571024,-122.3877811,Beacon Hill,West Seattle,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +107,Beacon Hill to Puyallup (flex-direct),10:00,47.578668036563016,-122.31139183,47.18399599096,-122.28950500488,Beacon Hill,Puyallup,FLEX_DIRECT|WALK,flex-direct +108,Beacon Hill to Puyallup (flex-and-transit),10:00,47.578668036563016,-122.31139183,47.18399599096,-122.28950500488,Beacon Hill,Puyallup,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +109,Beacon Hill to Snoqualmie (flex-direct),10:00,47.578668036563016,-122.31139183,47.52827129,-121.827821731,Beacon Hill,Snoqualmie,FLEX_DIRECT|WALK,flex-direct +110,Beacon Hill to Snoqualmie (flex-and-transit),10:00,47.578668036563016,-122.31139183,47.52827129,-121.827821731,Beacon Hill,Snoqualmie,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit +111,Beacon Hill to Queen Anne (flex-direct),10:00,47.578668036563016,-122.31139183,47.6394849792,-122.3636627197,Beacon Hill,Queen Anne,FLEX_DIRECT|WALK,flex-direct +112,Beacon Hill to Queen Anne (flex-and-transit),10:00,47.578668036563016,-122.31139183,47.6394849792,-122.3636627197,Beacon Hill,Queen Anne,FLEX_ACCESS|FLEX_EGRESS|TRANSIT,flex-and-transit diff --git a/utils/pom.xml b/utils/pom.xml new file mode 100644 index 00000000000..2e70554a678 --- /dev/null +++ b/utils/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + org.opentripplanner + otp-root + 2.7.0-SNAPSHOT + + + utils + OpenTripPlanner - Utils + + + + + com.google.code.findbugs + jsr305 + + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-params + test + + + diff --git a/src/main/java/org/opentripplanner/framework/collection/CollectionUtils.java b/utils/src/main/java/org/opentripplanner/utils/collection/CollectionUtils.java similarity index 75% rename from src/main/java/org/opentripplanner/framework/collection/CollectionUtils.java rename to utils/src/main/java/org/opentripplanner/utils/collection/CollectionUtils.java index 1e86f49770f..bb53ec11037 100644 --- a/src/main/java/org/opentripplanner/framework/collection/CollectionUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/collection/CollectionUtils.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.collection; +package org.opentripplanner.utils.collection; import java.util.Collection; import java.util.Map; @@ -37,6 +37,10 @@ public static String toString(@Nullable Collection c, String nullText) { /** * A null-safe version of isEmpty() for a collection. *

    + * The main strategy for handling collections in OTP is to avoid nullable collection fields and + * use empty collections instead. So, before using this method check if the variable/field is + * indeed `@Nullable`. + *

    * If the collection is {@code null} then {@code true} is returned. *

    * If the collection is empty then {@code true} is returned. @@ -47,6 +51,19 @@ public static boolean isEmpty(@Nullable Collection c) { return c == null || c.isEmpty(); } + /** + * A null-safe version of isEmpty() for a collection. + *

    + * If the collection is {@code null} then {@code true} is returned. + *

    + * If the collection is empty then {@code true} is returned. + *

    + * Otherwise {@code false} is returned. + */ + public static boolean isEmpty(@Nullable Map m) { + return m == null || m.isEmpty(); + } + /** * Look up the given key in a Map, return null if the key is null. * This prevents a NullPointerException if the underlying implementation of the map does not diff --git a/src/main/java/org/opentripplanner/framework/collection/CollectionsView.java b/utils/src/main/java/org/opentripplanner/utils/collection/CollectionsView.java similarity index 97% rename from src/main/java/org/opentripplanner/framework/collection/CollectionsView.java rename to utils/src/main/java/org/opentripplanner/utils/collection/CollectionsView.java index 4ca6ae5f555..599846f9d86 100644 --- a/src/main/java/org/opentripplanner/framework/collection/CollectionsView.java +++ b/utils/src/main/java/org/opentripplanner/utils/collection/CollectionsView.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.collection; +package org.opentripplanner.utils.collection; import java.io.Serializable; import java.util.AbstractCollection; diff --git a/src/main/java/org/opentripplanner/framework/collection/CompositeComparator.java b/utils/src/main/java/org/opentripplanner/utils/collection/CompositeComparator.java similarity index 93% rename from src/main/java/org/opentripplanner/framework/collection/CompositeComparator.java rename to utils/src/main/java/org/opentripplanner/utils/collection/CompositeComparator.java index 286df07370a..0c2cf445504 100644 --- a/src/main/java/org/opentripplanner/framework/collection/CompositeComparator.java +++ b/utils/src/main/java/org/opentripplanner/utils/collection/CompositeComparator.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.collection; +package org.opentripplanner.utils.collection; import java.util.Comparator; diff --git a/src/main/java/org/opentripplanner/framework/collection/ListSection.java b/utils/src/main/java/org/opentripplanner/utils/collection/ListSection.java similarity index 90% rename from src/main/java/org/opentripplanner/framework/collection/ListSection.java rename to utils/src/main/java/org/opentripplanner/utils/collection/ListSection.java index d9878aa34b1..ce582f32e65 100644 --- a/src/main/java/org/opentripplanner/framework/collection/ListSection.java +++ b/utils/src/main/java/org/opentripplanner/utils/collection/ListSection.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.collection; +package org.opentripplanner.utils.collection; /** * This enum is used to signal which part of a list an operation apply to. You may remove elements diff --git a/src/main/java/org/opentripplanner/framework/collection/ListUtils.java b/utils/src/main/java/org/opentripplanner/utils/collection/ListUtils.java similarity index 80% rename from src/main/java/org/opentripplanner/framework/collection/ListUtils.java rename to utils/src/main/java/org/opentripplanner/utils/collection/ListUtils.java index 5964a1674e3..658bf768179 100644 --- a/src/main/java/org/opentripplanner/framework/collection/ListUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/collection/ListUtils.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.collection; +package org.opentripplanner.utils.collection; import java.util.ArrayList; import java.util.Arrays; @@ -7,6 +7,7 @@ import java.util.List; import java.util.Set; import java.util.function.Function; +import javax.annotation.Nullable; public class ListUtils { @@ -69,4 +70,13 @@ public static List ofNullable(T input) { return List.of(input); } } + + /** + * This method converts the given collection to an instance of a List. If the input is + * {@code null} an empty collection is returned. If not the {@link List#copyOf(Collection)} is + * called. + */ + public static List nullSafeImmutableList(@Nullable Collection c) { + return (c == null) ? List.of() : List.copyOf(c); + } } diff --git a/src/main/java/org/opentripplanner/framework/collection/MapUtils.java b/utils/src/main/java/org/opentripplanner/utils/collection/MapUtils.java similarity index 74% rename from src/main/java/org/opentripplanner/framework/collection/MapUtils.java rename to utils/src/main/java/org/opentripplanner/utils/collection/MapUtils.java index c68527b6d0e..0a67e01b9fb 100644 --- a/src/main/java/org/opentripplanner/framework/collection/MapUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/collection/MapUtils.java @@ -1,27 +1,15 @@ -package org.opentripplanner.framework.collection; +package org.opentripplanner.utils.collection; -import gnu.trove.map.TLongObjectMap; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; public class MapUtils { - public static void addToMapSet(TLongObjectMap> mapSet, long key, U value) { - Set set = mapSet.get(key); - if (set == null) { - set = new HashSet<>(); - mapSet.put(key, set); - } - set.add(value); - } - /** * Map a collection of objects of type S to a list of type T using the provided * mapping function. diff --git a/src/main/java/org/opentripplanner/framework/collection/SetUtils.java b/utils/src/main/java/org/opentripplanner/utils/collection/SetUtils.java similarity index 88% rename from src/main/java/org/opentripplanner/framework/collection/SetUtils.java rename to utils/src/main/java/org/opentripplanner/utils/collection/SetUtils.java index b8f773aab72..fec99c8b28c 100644 --- a/src/main/java/org/opentripplanner/framework/collection/SetUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/collection/SetUtils.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.collection; +package org.opentripplanner.utils.collection; import java.util.Arrays; import java.util.Collection; diff --git a/src/main/java/org/opentripplanner/framework/lang/ArrayUtils.java b/utils/src/main/java/org/opentripplanner/utils/lang/ArrayUtils.java similarity index 87% rename from src/main/java/org/opentripplanner/framework/lang/ArrayUtils.java rename to utils/src/main/java/org/opentripplanner/utils/lang/ArrayUtils.java index a3a67cb67cd..afd8e59ec0b 100644 --- a/src/main/java/org/opentripplanner/framework/lang/ArrayUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/lang/ArrayUtils.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import javax.annotation.Nullable; diff --git a/src/main/java/org/opentripplanner/framework/lang/BitSetUtils.java b/utils/src/main/java/org/opentripplanner/utils/lang/BitSetUtils.java similarity index 97% rename from src/main/java/org/opentripplanner/framework/lang/BitSetUtils.java rename to utils/src/main/java/org/opentripplanner/utils/lang/BitSetUtils.java index 1f5bdb91fab..afb9654e56e 100644 --- a/src/main/java/org/opentripplanner/framework/lang/BitSetUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/lang/BitSetUtils.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; /** * A compact bit set utility class. It rely on the client to store the bit set himself (either as a diff --git a/src/main/java/org/opentripplanner/framework/lang/Box.java b/utils/src/main/java/org/opentripplanner/utils/lang/Box.java similarity index 95% rename from src/main/java/org/opentripplanner/framework/lang/Box.java rename to utils/src/main/java/org/opentripplanner/utils/lang/Box.java index ae54a3c5b7f..e7d32acdbe9 100644 --- a/src/main/java/org/opentripplanner/framework/lang/Box.java +++ b/utils/src/main/java/org/opentripplanner/utils/lang/Box.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import java.util.Objects; import javax.annotation.Nullable; diff --git a/src/main/java/org/opentripplanner/framework/lang/DoubleUtils.java b/utils/src/main/java/org/opentripplanner/utils/lang/DoubleUtils.java similarity index 95% rename from src/main/java/org/opentripplanner/framework/lang/DoubleUtils.java rename to utils/src/main/java/org/opentripplanner/utils/lang/DoubleUtils.java index 0267e9e3b5d..a285ade8ad5 100644 --- a/src/main/java/org/opentripplanner/framework/lang/DoubleUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/lang/DoubleUtils.java @@ -1,6 +1,6 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; -import static org.opentripplanner.framework.lang.OtpNumberFormat.formatTwoDecimals; +import static org.opentripplanner.utils.lang.OtpNumberFormat.formatTwoDecimals; import java.math.BigDecimal; import java.math.RoundingMode; diff --git a/src/main/java/org/opentripplanner/framework/lang/IntBox.java b/utils/src/main/java/org/opentripplanner/utils/lang/IntBox.java similarity index 95% rename from src/main/java/org/opentripplanner/framework/lang/IntBox.java rename to utils/src/main/java/org/opentripplanner/utils/lang/IntBox.java index 3e7a828a526..c564f6f8e25 100644 --- a/src/main/java/org/opentripplanner/framework/lang/IntBox.java +++ b/utils/src/main/java/org/opentripplanner/utils/lang/IntBox.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; /** * An IntBox is a writable container for an int. The most common use-case for this class is to diff --git a/src/main/java/org/opentripplanner/framework/lang/IntRange.java b/utils/src/main/java/org/opentripplanner/utils/lang/IntRange.java similarity index 98% rename from src/main/java/org/opentripplanner/framework/lang/IntRange.java rename to utils/src/main/java/org/opentripplanner/utils/lang/IntRange.java index c8ff5b45d46..88477cbce27 100644 --- a/src/main/java/org/opentripplanner/framework/lang/IntRange.java +++ b/utils/src/main/java/org/opentripplanner/utils/lang/IntRange.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import java.util.Objects; import java.util.Optional; diff --git a/src/main/java/org/opentripplanner/framework/lang/IntUtils.java b/utils/src/main/java/org/opentripplanner/utils/lang/IntUtils.java similarity index 98% rename from src/main/java/org/opentripplanner/framework/lang/IntUtils.java rename to utils/src/main/java/org/opentripplanner/utils/lang/IntUtils.java index de4904dcd7c..31dbd9fa72b 100644 --- a/src/main/java/org/opentripplanner/framework/lang/IntUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/lang/IntUtils.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/main/java/org/opentripplanner/framework/lang/MemEfficientArrayBuilder.java b/utils/src/main/java/org/opentripplanner/utils/lang/MemEfficientArrayBuilder.java similarity index 95% rename from src/main/java/org/opentripplanner/framework/lang/MemEfficientArrayBuilder.java rename to utils/src/main/java/org/opentripplanner/utils/lang/MemEfficientArrayBuilder.java index 8b3a6ba6cd0..740cfa2e60c 100644 --- a/src/main/java/org/opentripplanner/framework/lang/MemEfficientArrayBuilder.java +++ b/utils/src/main/java/org/opentripplanner/utils/lang/MemEfficientArrayBuilder.java @@ -1,8 +1,7 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import java.util.Arrays; import java.util.Objects; -import javax.annotation.Nonnull; /** * This array builder is used to minimize the creation of new objects (arrays). It takes an array as base, @@ -20,7 +19,7 @@ public final class MemEfficientArrayBuilder { private final T[] original; private T[] array = null; - private MemEfficientArrayBuilder(@Nonnull T[] original) { + private MemEfficientArrayBuilder(T[] original) { this.original = Objects.requireNonNull(original); } diff --git a/src/main/java/org/opentripplanner/framework/lang/ObjectUtils.java b/utils/src/main/java/org/opentripplanner/utils/lang/ObjectUtils.java similarity index 97% rename from src/main/java/org/opentripplanner/framework/lang/ObjectUtils.java rename to utils/src/main/java/org/opentripplanner/utils/lang/ObjectUtils.java index a3f18748987..da619cdeb79 100644 --- a/src/main/java/org/opentripplanner/framework/lang/ObjectUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/lang/ObjectUtils.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import java.util.function.Function; import java.util.function.Supplier; diff --git a/src/main/java/org/opentripplanner/framework/lang/OtpNumberFormat.java b/utils/src/main/java/org/opentripplanner/utils/lang/OtpNumberFormat.java similarity index 98% rename from src/main/java/org/opentripplanner/framework/lang/OtpNumberFormat.java rename to utils/src/main/java/org/opentripplanner/utils/lang/OtpNumberFormat.java index 1ff2aca37a3..3dd1e0d76e7 100644 --- a/src/main/java/org/opentripplanner/framework/lang/OtpNumberFormat.java +++ b/utils/src/main/java/org/opentripplanner/utils/lang/OtpNumberFormat.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import java.math.BigInteger; import java.text.DecimalFormat; diff --git a/src/main/java/org/opentripplanner/framework/lang/Sandbox.java b/utils/src/main/java/org/opentripplanner/utils/lang/Sandbox.java similarity index 93% rename from src/main/java/org/opentripplanner/framework/lang/Sandbox.java rename to utils/src/main/java/org/opentripplanner/utils/lang/Sandbox.java index 67c9644fc0f..5b4d83e7772 100644 --- a/src/main/java/org/opentripplanner/framework/lang/Sandbox.java +++ b/utils/src/main/java/org/opentripplanner/utils/lang/Sandbox.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import static java.lang.annotation.ElementType.CONSTRUCTOR; import static java.lang.annotation.ElementType.FIELD; diff --git a/src/main/java/org/opentripplanner/framework/lang/StringUtils.java b/utils/src/main/java/org/opentripplanner/utils/lang/StringUtils.java similarity index 93% rename from src/main/java/org/opentripplanner/framework/lang/StringUtils.java rename to utils/src/main/java/org/opentripplanner/utils/lang/StringUtils.java index 9eff448d0c7..c1a2219da72 100644 --- a/src/main/java/org/opentripplanner/framework/lang/StringUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/lang/StringUtils.java @@ -1,7 +1,6 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import java.util.regex.Pattern; -import javax.annotation.Nonnull; /** * OTP String utils extending the Java lang String... @@ -120,7 +119,7 @@ public static String padRight(String value, char ch, int width) { } /** Replace single quotes with double quotes. */ - public static String quoteReplace(@Nonnull String text) { + public static String quoteReplace(String text) { return text.replace('\'', '\"'); } @@ -133,6 +132,14 @@ public static String kebabCase(String input) { return input.toLowerCase().replace('_', '-'); } + /** + * Create a URL-friendly "slug" version of the string, so "Entur Routebanken" becomes + * "entur-routebanken". + */ + public static String slugify(String input) { + return input.toLowerCase().replace('_', '-').replaceAll("\\s+", "-"); + } + /** * Detects unprintable control characters like newlines, tabs and invisible whitespace * like 'ZERO WIDTH SPACE' (U+200B) that don't have an immediate visual representation. diff --git a/src/main/java/org/opentripplanner/framework/logging/ProgressTracker.java b/utils/src/main/java/org/opentripplanner/utils/logging/ProgressTracker.java similarity index 98% rename from src/main/java/org/opentripplanner/framework/logging/ProgressTracker.java rename to utils/src/main/java/org/opentripplanner/utils/logging/ProgressTracker.java index 4be70e2abdf..4922186bfc6 100644 --- a/src/main/java/org/opentripplanner/framework/logging/ProgressTracker.java +++ b/utils/src/main/java/org/opentripplanner/utils/logging/ProgressTracker.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.logging; +package org.opentripplanner.utils.logging; import java.io.InputStream; import java.io.OutputStream; @@ -7,8 +7,8 @@ import java.time.Instant; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; -import org.opentripplanner.framework.text.FileSizeToTextConverter; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.utils.text.FileSizeToTextConverter; +import org.opentripplanner.utils.time.DurationUtils; /** * The progress tracker notify the caller based a time interval. diff --git a/src/main/java/org/opentripplanner/framework/logging/ProgressTrackerInputStream.java b/utils/src/main/java/org/opentripplanner/utils/logging/ProgressTrackerInputStream.java similarity index 98% rename from src/main/java/org/opentripplanner/framework/logging/ProgressTrackerInputStream.java rename to utils/src/main/java/org/opentripplanner/utils/logging/ProgressTrackerInputStream.java index 1e5a5386275..6e3b71bfe66 100644 --- a/src/main/java/org/opentripplanner/framework/logging/ProgressTrackerInputStream.java +++ b/utils/src/main/java/org/opentripplanner/utils/logging/ProgressTrackerInputStream.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.logging; +package org.opentripplanner.utils.logging; import java.io.IOException; import java.io.InputStream; diff --git a/src/main/java/org/opentripplanner/framework/logging/ProgressTrackerOutputStream.java b/utils/src/main/java/org/opentripplanner/utils/logging/ProgressTrackerOutputStream.java similarity index 96% rename from src/main/java/org/opentripplanner/framework/logging/ProgressTrackerOutputStream.java rename to utils/src/main/java/org/opentripplanner/utils/logging/ProgressTrackerOutputStream.java index 38095634bdd..5f4583b8ed7 100644 --- a/src/main/java/org/opentripplanner/framework/logging/ProgressTrackerOutputStream.java +++ b/utils/src/main/java/org/opentripplanner/utils/logging/ProgressTrackerOutputStream.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.logging; +package org.opentripplanner.utils.logging; import java.io.IOException; import java.io.OutputStream; diff --git a/src/main/java/org/opentripplanner/framework/logging/Throttle.java b/utils/src/main/java/org/opentripplanner/utils/logging/Throttle.java similarity index 96% rename from src/main/java/org/opentripplanner/framework/logging/Throttle.java rename to utils/src/main/java/org/opentripplanner/utils/logging/Throttle.java index ed8a2c1bef4..393bef0c19a 100644 --- a/src/main/java/org/opentripplanner/framework/logging/Throttle.java +++ b/utils/src/main/java/org/opentripplanner/utils/logging/Throttle.java @@ -1,7 +1,7 @@ -package org.opentripplanner.framework.logging; +package org.opentripplanner.utils.logging; import java.time.Duration; -import org.opentripplanner.framework.time.TimeUtils; +import org.opentripplanner.utils.time.TimeUtils; /** * This class can be used to throttle (logging) events. diff --git a/src/main/java/org/opentripplanner/framework/text/CharacterEscapeFormatter.java b/utils/src/main/java/org/opentripplanner/utils/text/CharacterEscapeFormatter.java similarity index 98% rename from src/main/java/org/opentripplanner/framework/text/CharacterEscapeFormatter.java rename to utils/src/main/java/org/opentripplanner/utils/text/CharacterEscapeFormatter.java index 2bd5bf14b71..46faba6e806 100644 --- a/src/main/java/org/opentripplanner/framework/text/CharacterEscapeFormatter.java +++ b/utils/src/main/java/org/opentripplanner/utils/text/CharacterEscapeFormatter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.text; +package org.opentripplanner.utils.text; /** * This class is used to escape characters in a string, removing a special character from diff --git a/src/main/java/org/opentripplanner/framework/text/FileSizeToTextConverter.java b/utils/src/main/java/org/opentripplanner/utils/text/FileSizeToTextConverter.java similarity index 93% rename from src/main/java/org/opentripplanner/framework/text/FileSizeToTextConverter.java rename to utils/src/main/java/org/opentripplanner/utils/text/FileSizeToTextConverter.java index e110d626480..41b04fd3194 100644 --- a/src/main/java/org/opentripplanner/framework/text/FileSizeToTextConverter.java +++ b/utils/src/main/java/org/opentripplanner/utils/text/FileSizeToTextConverter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.text; +package org.opentripplanner.utils.text; import java.util.Locale; diff --git a/src/main/java/org/opentripplanner/framework/text/HexString.java b/utils/src/main/java/org/opentripplanner/utils/text/HexString.java similarity index 91% rename from src/main/java/org/opentripplanner/framework/text/HexString.java rename to utils/src/main/java/org/opentripplanner/utils/text/HexString.java index e85a139b624..16d5c56c58b 100644 --- a/src/main/java/org/opentripplanner/framework/text/HexString.java +++ b/utils/src/main/java/org/opentripplanner/utils/text/HexString.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.text; +package org.opentripplanner.utils.text; /** * Converts a byte array to its hexadecimal representation diff --git a/src/main/java/org/opentripplanner/framework/text/MarkdownFormatter.java b/utils/src/main/java/org/opentripplanner/utils/text/MarkdownFormatter.java similarity index 98% rename from src/main/java/org/opentripplanner/framework/text/MarkdownFormatter.java rename to utils/src/main/java/org/opentripplanner/utils/text/MarkdownFormatter.java index 6fdb495a0d5..95e54a1bb3f 100644 --- a/src/main/java/org/opentripplanner/framework/text/MarkdownFormatter.java +++ b/utils/src/main/java/org/opentripplanner/utils/text/MarkdownFormatter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.text; +package org.opentripplanner.utils.text; import javax.annotation.Nullable; diff --git a/src/main/java/org/opentripplanner/framework/text/Table.java b/utils/src/main/java/org/opentripplanner/utils/text/Table.java similarity index 96% rename from src/main/java/org/opentripplanner/framework/text/Table.java rename to utils/src/main/java/org/opentripplanner/utils/text/Table.java index 940868b82e2..bf13c23bcf5 100644 --- a/src/main/java/org/opentripplanner/framework/text/Table.java +++ b/utils/src/main/java/org/opentripplanner/utils/text/Table.java @@ -1,11 +1,11 @@ -package org.opentripplanner.framework.text; +package org.opentripplanner.utils.text; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; -import org.opentripplanner.framework.lang.ObjectUtils; -import org.opentripplanner.framework.lang.StringUtils; +import org.opentripplanner.utils.lang.ObjectUtils; +import org.opentripplanner.utils.lang.StringUtils; /** * This class is responsible for creating a pretty table that can be printed to a terminal window. diff --git a/src/main/java/org/opentripplanner/framework/text/TableBuilder.java b/utils/src/main/java/org/opentripplanner/utils/text/TableBuilder.java similarity index 98% rename from src/main/java/org/opentripplanner/framework/text/TableBuilder.java rename to utils/src/main/java/org/opentripplanner/utils/text/TableBuilder.java index 12e80fd62a8..e573cce6c37 100644 --- a/src/main/java/org/opentripplanner/framework/text/TableBuilder.java +++ b/utils/src/main/java/org/opentripplanner/utils/text/TableBuilder.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.text; +package org.opentripplanner.utils.text; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/main/java/org/opentripplanner/framework/text/TableRowFormatter.java b/utils/src/main/java/org/opentripplanner/utils/text/TableRowFormatter.java similarity index 93% rename from src/main/java/org/opentripplanner/framework/text/TableRowFormatter.java rename to utils/src/main/java/org/opentripplanner/utils/text/TableRowFormatter.java index 3e7e3c727f9..9db03403a0a 100644 --- a/src/main/java/org/opentripplanner/framework/text/TableRowFormatter.java +++ b/utils/src/main/java/org/opentripplanner/utils/text/TableRowFormatter.java @@ -1,9 +1,9 @@ -package org.opentripplanner.framework.text; +package org.opentripplanner.utils.text; import java.util.List; import java.util.function.Function; -import org.opentripplanner.framework.lang.ObjectUtils; -import org.opentripplanner.framework.lang.StringUtils; +import org.opentripplanner.utils.lang.ObjectUtils; +import org.opentripplanner.utils.lang.StringUtils; class TableRowFormatter { diff --git a/src/main/java/org/opentripplanner/framework/time/CountdownTimer.java b/utils/src/main/java/org/opentripplanner/utils/time/CountdownTimer.java similarity index 97% rename from src/main/java/org/opentripplanner/framework/time/CountdownTimer.java rename to utils/src/main/java/org/opentripplanner/utils/time/CountdownTimer.java index 5d6d89147a8..674e512c535 100644 --- a/src/main/java/org/opentripplanner/framework/time/CountdownTimer.java +++ b/utils/src/main/java/org/opentripplanner/utils/time/CountdownTimer.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.time; +package org.opentripplanner.utils.time; import java.time.Duration; import java.util.function.LongSupplier; diff --git a/src/main/java/org/opentripplanner/framework/time/DateUtils.java b/utils/src/main/java/org/opentripplanner/utils/time/DateUtils.java similarity index 84% rename from src/main/java/org/opentripplanner/framework/time/DateUtils.java rename to utils/src/main/java/org/opentripplanner/utils/time/DateUtils.java index d212af56b79..e773b4e89ea 100644 --- a/src/main/java/org/opentripplanner/framework/time/DateUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/time/DateUtils.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.time; +package org.opentripplanner.utils.time; import java.time.Duration; import java.time.Instant; @@ -10,18 +10,13 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.List; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * @author Frank Purcell (p u r c e l l f @ t r i m e t . o r g) October 20, 2009 */ public class DateUtils { - private static final Logger LOG = LoggerFactory.getLogger(DateUtils.class); - private static final int SANITY_CHECK_CUTOFF_YEAR = 1000; // NOTE: don't change the order of these strings...the simplest should be on the @@ -54,9 +49,6 @@ public class DateUtils { */ @Nullable public static ZonedDateTime toZonedDateTime(String date, String time, ZoneId tz) { - //LOG.debug("JVM default timezone is {}", TimeZone.getDefault()); - LOG.debug("Parsing date {} and time {}", date, time); - LOG.debug("using timezone {}", tz); ZonedDateTime retVal = ZonedDateTime.ofInstant(Instant.now(), tz); if (date != null) { LocalDate localDate = parseDate(date); @@ -81,12 +73,11 @@ public static ZonedDateTime toZonedDateTime(String date, String time, ZoneId tz) retVal = LocalDateTime.of(retVal.toLocalDate(), localTime).atZone(tz); } } - LOG.debug("resulting date is {}", retVal); return retVal; } // TODO: could be replaced with Apache's DateFormat.parseDate ??? - public static LocalDate parseDate(@Nonnull String input) { + public static LocalDate parseDate(String input) { LocalDate retVal = null; try { String newString = input @@ -139,30 +130,6 @@ public static int getIntegerFromString(String input) { } } - /** - * Converts the given time in seconds to a String in the format h:mm. - * - * @param seconds the time in seconds. - * @return a String representing the time in the format h:mm - */ - public static String secToHHMM(int seconds) { - int min; - String sign = ""; - - if (seconds >= 0) { - min = seconds / 60; - sign = ""; - } else { - min = -seconds / 60; - sign = "-"; - } - - int mm = min % 60; - int hh = min / 60; - - return String.format("%s%d:%02d", sign, hh, mm); - } - public static String trim(String str) { String retVal = str; try { @@ -228,11 +195,9 @@ public static LocalTime parseTime(String time) { if (hms.length > 2) { sec = Integer.parseInt(trim(hms[2])); } - return LocalTime.of(hour, min, sec); - } catch (Exception ignore) { - LOG.info("Time '{}' didn't parse", time); - return null; + } catch (Exception e) { + throw new RuntimeException("Could not parse time: " + time, e); } } } diff --git a/src/main/java/org/opentripplanner/framework/time/DurationUtils.java b/utils/src/main/java/org/opentripplanner/utils/time/DurationUtils.java similarity index 84% rename from src/main/java/org/opentripplanner/framework/time/DurationUtils.java rename to utils/src/main/java/org/opentripplanner/utils/time/DurationUtils.java index 9d16ed7d269..d73faecee03 100644 --- a/src/main/java/org/opentripplanner/framework/time/DurationUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/time/DurationUtils.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.time; +package org.opentripplanner.utils.time; import static java.util.Locale.ROOT; @@ -187,43 +187,45 @@ public static Duration requireNonNegative(Duration value) { } /** - * Checks that duration is not negative and not over 2 days. + * Checks that duration is positive and less than the given {@code maxLimit} (exclusive). * * @param subject used to identify name of the problematic value when throwing an exception. */ - public static Duration requireNonNegativeLong(Duration value, String subject) { + public static Duration requireNonNegative(Duration value, Duration maxLimit, String subject) { Objects.requireNonNull(value); if (value.isNegative()) { throw new IllegalArgumentException( - "Duration %s can't be negative: %s.".formatted(subject, value) + "Duration %s can't be negative: %s".formatted(subject, value) ); } - if (value.compareTo(Duration.ofDays(2)) > 0) { + if (value.compareTo(maxLimit) >= 0) { throw new IllegalArgumentException( - "Duration %s can't be longer than two days: %s.".formatted(subject, value) + "Duration %s can't be longer or equals too %s: %s".formatted( + subject, + durationToStr(maxLimit), + value + ) ); } return value; } + /** + * Checks that duration is not negative and not over 2 days. + * + * @param subject used to identify name of the problematic value when throwing an exception. + */ + public static Duration requireNonNegativeMax2days(Duration value, String subject) { + return requireNonNegative(value, Duration.ofDays(2), subject); + } + /** * Checks that duration is not negative and not over 2 hours. * * @param subject used to identify name of the problematic value when throwing an exception. */ - public static Duration requireNonNegativeMedium(Duration value, String subject) { - Objects.requireNonNull(value); - if (value.isNegative()) { - throw new IllegalArgumentException( - "Duration %s can't be negative: %s.".formatted(subject, value) - ); - } - if (value.compareTo(Duration.ofHours(2)) > 0) { - throw new IllegalArgumentException( - "Duration %s can't be longer than two hours: %s.".formatted(subject, value) - ); - } - return value; + public static Duration requireNonNegativeMax2hours(Duration value, String subject) { + return requireNonNegative(value, Duration.ofHours(2), subject); } /** @@ -231,19 +233,8 @@ public static Duration requireNonNegativeMedium(Duration value, String subject) * * @param subject used to identify name of the problematic value when throwing an exception. */ - public static Duration requireNonNegativeShort(Duration value, String subject) { - Objects.requireNonNull(value); - if (value.isNegative()) { - throw new IllegalArgumentException( - "Duration %s can't be negative: %s.".formatted(subject, value) - ); - } - if (value.compareTo(Duration.ofMinutes(30)) > 0) { - throw new IllegalArgumentException( - "Duration %s can't be longer than 30 minutes: %s.".formatted(subject, value) - ); - } - return value; + public static Duration requireNonNegativeMax30minutes(Duration value, String subject) { + return requireNonNegative(value, Duration.ofMinutes(30), subject); } /** diff --git a/src/main/java/org/opentripplanner/framework/time/LocalDateUtils.java b/utils/src/main/java/org/opentripplanner/utils/time/LocalDateUtils.java similarity index 95% rename from src/main/java/org/opentripplanner/framework/time/LocalDateUtils.java rename to utils/src/main/java/org/opentripplanner/utils/time/LocalDateUtils.java index dd11065bb12..6b5bf1f8f2f 100644 --- a/src/main/java/org/opentripplanner/framework/time/LocalDateUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/time/LocalDateUtils.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.time; +package org.opentripplanner.utils.time; import java.time.LocalDate; import java.time.Period; diff --git a/src/main/java/org/opentripplanner/framework/time/OffsetDateTimeParser.java b/utils/src/main/java/org/opentripplanner/utils/time/OffsetDateTimeParser.java similarity index 97% rename from src/main/java/org/opentripplanner/framework/time/OffsetDateTimeParser.java rename to utils/src/main/java/org/opentripplanner/utils/time/OffsetDateTimeParser.java index 8b40697977a..1bf33c2959f 100644 --- a/src/main/java/org/opentripplanner/framework/time/OffsetDateTimeParser.java +++ b/utils/src/main/java/org/opentripplanner/utils/time/OffsetDateTimeParser.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.time; +package org.opentripplanner.utils.time; import java.text.ParseException; import java.time.OffsetDateTime; diff --git a/src/main/java/org/opentripplanner/framework/time/RelativeTime.java b/utils/src/main/java/org/opentripplanner/utils/time/RelativeTime.java similarity index 98% rename from src/main/java/org/opentripplanner/framework/time/RelativeTime.java rename to utils/src/main/java/org/opentripplanner/utils/time/RelativeTime.java index b01486f8d7f..b4b13a7c68b 100644 --- a/src/main/java/org/opentripplanner/framework/time/RelativeTime.java +++ b/utils/src/main/java/org/opentripplanner/utils/time/RelativeTime.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.time; +package org.opentripplanner.utils.time; import java.time.LocalDate; import java.time.LocalTime; diff --git a/src/main/java/org/opentripplanner/framework/time/ServiceDateUtils.java b/utils/src/main/java/org/opentripplanner/utils/time/ServiceDateUtils.java similarity index 99% rename from src/main/java/org/opentripplanner/framework/time/ServiceDateUtils.java rename to utils/src/main/java/org/opentripplanner/utils/time/ServiceDateUtils.java index a2652015155..e8243ec6355 100644 --- a/src/main/java/org/opentripplanner/framework/time/ServiceDateUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/time/ServiceDateUtils.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.time; +package org.opentripplanner.utils.time; import java.text.ParseException; import java.time.Duration; diff --git a/src/main/java/org/opentripplanner/framework/time/TimeUtils.java b/utils/src/main/java/org/opentripplanner/utils/time/TimeUtils.java similarity index 98% rename from src/main/java/org/opentripplanner/framework/time/TimeUtils.java rename to utils/src/main/java/org/opentripplanner/utils/time/TimeUtils.java index 9cc5594cb76..2c1bde17f1b 100644 --- a/src/main/java/org/opentripplanner/framework/time/TimeUtils.java +++ b/utils/src/main/java/org/opentripplanner/utils/time/TimeUtils.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.time; +package org.opentripplanner.utils.time; import java.security.SecureRandom; import java.time.Duration; @@ -14,7 +14,6 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.annotation.Nonnull; /** * Time utility methods. See the unit test for examples on how to use this class. @@ -108,7 +107,7 @@ public static int time(String hhmmss, int defaultValue) { * very helpful when specifying a schedule using a sting instead of using a int array with seconds * past midnight. */ - public static int[] times(@Nonnull String input) { + public static int[] times(String input) { return Arrays.stream(input.split("[ ,;]+")).mapToInt(TimeUtils::time).toArray(); } diff --git a/src/main/java/org/opentripplanner/framework/tostring/MultiLineToStringBuilder.java b/utils/src/main/java/org/opentripplanner/utils/tostring/MultiLineToStringBuilder.java similarity index 96% rename from src/main/java/org/opentripplanner/framework/tostring/MultiLineToStringBuilder.java rename to utils/src/main/java/org/opentripplanner/utils/tostring/MultiLineToStringBuilder.java index 32f5762843a..a3d794aef63 100644 --- a/src/main/java/org/opentripplanner/framework/tostring/MultiLineToStringBuilder.java +++ b/utils/src/main/java/org/opentripplanner/utils/tostring/MultiLineToStringBuilder.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.tostring; +package org.opentripplanner.utils.tostring; import java.time.Duration; import java.util.ArrayList; @@ -8,7 +8,7 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; -import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.utils.time.DurationUtils; /** * When debug logging it is much more readable if the logging is nicely formatted with line-breaks. diff --git a/src/main/java/org/opentripplanner/framework/tostring/ToStringBuilder.java b/utils/src/main/java/org/opentripplanner/utils/tostring/ToStringBuilder.java similarity index 96% rename from src/main/java/org/opentripplanner/framework/tostring/ToStringBuilder.java rename to utils/src/main/java/org/opentripplanner/utils/tostring/ToStringBuilder.java index 6480b6f1187..de40951ff75 100644 --- a/src/main/java/org/opentripplanner/framework/tostring/ToStringBuilder.java +++ b/utils/src/main/java/org/opentripplanner/utils/tostring/ToStringBuilder.java @@ -1,7 +1,7 @@ -package org.opentripplanner.framework.tostring; +package org.opentripplanner.utils.tostring; import static java.lang.Boolean.TRUE; -import static org.opentripplanner.framework.time.DurationUtils.durationToStr; +import static org.opentripplanner.utils.time.DurationUtils.durationToStr; import java.time.Duration; import java.time.Instant; @@ -15,12 +15,11 @@ import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opentripplanner.framework.lang.ObjectUtils; -import org.opentripplanner.framework.lang.OtpNumberFormat; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; +import org.opentripplanner.utils.lang.ObjectUtils; +import org.opentripplanner.utils.lang.OtpNumberFormat; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; /** * This toString builder which add elements to a compact string of the form: @@ -372,7 +371,7 @@ private ToStringBuilder addIfNotIgnored( return addIt(name, mapToString.apply(value)); } - private ToStringBuilder addIt(String name, @Nonnull String value) { + private ToStringBuilder addIt(String name, String value) { addLabel(name); addValue(value); return this; @@ -387,7 +386,7 @@ private void addLabel(String name) { sb.append(name); } - private void addValue(@Nonnull String value) { + private void addValue(String value) { sb.append(FIELD_VALUE_SEP); sb.append(value); } diff --git a/src/main/java/org/opentripplanner/framework/tostring/ValueObjectToStringBuilder.java b/utils/src/main/java/org/opentripplanner/utils/tostring/ValueObjectToStringBuilder.java similarity index 96% rename from src/main/java/org/opentripplanner/framework/tostring/ValueObjectToStringBuilder.java rename to utils/src/main/java/org/opentripplanner/utils/tostring/ValueObjectToStringBuilder.java index 14584a8dd4a..e80323ee0fb 100644 --- a/src/main/java/org/opentripplanner/framework/tostring/ValueObjectToStringBuilder.java +++ b/utils/src/main/java/org/opentripplanner/utils/tostring/ValueObjectToStringBuilder.java @@ -1,11 +1,11 @@ -package org.opentripplanner.framework.tostring; +package org.opentripplanner.utils.tostring; import java.time.Duration; import java.time.Instant; import java.util.function.Function; -import org.opentripplanner.framework.lang.OtpNumberFormat; -import org.opentripplanner.framework.time.DurationUtils; -import org.opentripplanner.framework.time.TimeUtils; +import org.opentripplanner.utils.lang.OtpNumberFormat; +import org.opentripplanner.utils.time.DurationUtils; +import org.opentripplanner.utils.time.TimeUtils; /** * Use this to-string-builder to build value objects. A [ValueObject](http://wiki.c2.com/?ValueObject) diff --git a/src/test/java/org/opentripplanner/framework/collection/CollectionUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/collection/CollectionUtilsTest.java similarity index 60% rename from src/test/java/org/opentripplanner/framework/collection/CollectionUtilsTest.java rename to utils/src/test/java/org/opentripplanner/utils/collection/CollectionUtilsTest.java index ae33e493bcc..a79f91e3464 100644 --- a/src/test/java/org/opentripplanner/framework/collection/CollectionUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/collection/CollectionUtilsTest.java @@ -1,13 +1,17 @@ -package org.opentripplanner.framework.collection; +package org.opentripplanner.utils.collection; 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 com.google.type.Month; import java.time.Duration; +import java.time.Month; import java.util.ArrayList; +import java.util.Collection; import java.util.EnumSet; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import org.junit.jupiter.api.Test; @@ -15,6 +19,13 @@ class CollectionUtilsTest { public static final String NULL_STRING = ""; + @Test + void testIsEmpty() { + assertTrue(CollectionUtils.isEmpty((List) null)); + assertTrue(CollectionUtils.isEmpty(List.of())); + assertFalse(CollectionUtils.isEmpty(List.of(1))); + } + @Test void testToString() { assertEquals("", CollectionUtils.toString(null, NULL_STRING)); @@ -40,4 +51,18 @@ void testToString() { Set set = new HashSet<>(list); assertEquals("[, APRIL, JUNE, PT3H]", CollectionUtils.toString(set, NULL_STRING)); } + + @Test + void testIsEmptyMap() { + assertTrue(CollectionUtils.isEmpty((Map) null)); + assertTrue(CollectionUtils.isEmpty(Map.of())); + assertFalse(CollectionUtils.isEmpty(Map.of(1, 1))); + } + + @Test + void testIsEmptyCollection() { + assertTrue(CollectionUtils.isEmpty((Collection) null)); + assertTrue(CollectionUtils.isEmpty(List.of())); + assertFalse(CollectionUtils.isEmpty(Set.of(1))); + } } diff --git a/src/test/java/org/opentripplanner/framework/collection/CollectionsViewTest.java b/utils/src/test/java/org/opentripplanner/utils/collection/CollectionsViewTest.java similarity index 97% rename from src/test/java/org/opentripplanner/framework/collection/CollectionsViewTest.java rename to utils/src/test/java/org/opentripplanner/utils/collection/CollectionsViewTest.java index 4196ff98e08..191540f3876 100644 --- a/src/test/java/org/opentripplanner/framework/collection/CollectionsViewTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/collection/CollectionsViewTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.collection; +package org.opentripplanner.utils.collection; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/src/test/java/org/opentripplanner/framework/collection/CompositeComparatorTest.java b/utils/src/test/java/org/opentripplanner/utils/collection/CompositeComparatorTest.java similarity index 94% rename from src/test/java/org/opentripplanner/framework/collection/CompositeComparatorTest.java rename to utils/src/test/java/org/opentripplanner/utils/collection/CompositeComparatorTest.java index 5329683d336..03dbb7d1c71 100644 --- a/src/test/java/org/opentripplanner/framework/collection/CompositeComparatorTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/collection/CompositeComparatorTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.collection; +package org.opentripplanner.utils.collection; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/org/opentripplanner/framework/collection/ListSectionTest.java b/utils/src/test/java/org/opentripplanner/utils/collection/ListSectionTest.java similarity index 91% rename from src/test/java/org/opentripplanner/framework/collection/ListSectionTest.java rename to utils/src/test/java/org/opentripplanner/utils/collection/ListSectionTest.java index 199804e4881..01ce5a2d336 100644 --- a/src/test/java/org/opentripplanner/framework/collection/ListSectionTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/collection/ListSectionTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.collection; +package org.opentripplanner.utils.collection; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/src/test/java/org/opentripplanner/framework/collection/ListUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/collection/ListUtilsTest.java similarity index 90% rename from src/test/java/org/opentripplanner/framework/collection/ListUtilsTest.java rename to utils/src/test/java/org/opentripplanner/utils/collection/ListUtilsTest.java index 33dce1f5574..602182a64b4 100644 --- a/src/test/java/org/opentripplanner/framework/collection/ListUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/collection/ListUtilsTest.java @@ -1,9 +1,9 @@ -package org.opentripplanner.framework.collection; +package org.opentripplanner.utils.collection; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.opentripplanner.framework.collection.ListUtils.first; -import static org.opentripplanner.framework.collection.ListUtils.last; +import static org.opentripplanner.utils.collection.ListUtils.first; +import static org.opentripplanner.utils.collection.ListUtils.last; import java.util.List; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/framework/collection/MapUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/collection/MapUtilsTest.java similarity index 91% rename from src/test/java/org/opentripplanner/framework/collection/MapUtilsTest.java rename to utils/src/test/java/org/opentripplanner/utils/collection/MapUtilsTest.java index 047a8e61d6b..100e56fec03 100644 --- a/src/test/java/org/opentripplanner/framework/collection/MapUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/collection/MapUtilsTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.collection; +package org.opentripplanner.utils.collection; import static java.util.Collections.singleton; import static java.util.Collections.singletonList; @@ -6,7 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.opentripplanner.framework.collection.MapUtils.mapToList; +import static org.opentripplanner.utils.collection.MapUtils.mapToList; import java.util.Collections; import java.util.Map; diff --git a/src/test/java/org/opentripplanner/framework/collection/SetUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/collection/SetUtilsTest.java similarity index 86% rename from src/test/java/org/opentripplanner/framework/collection/SetUtilsTest.java rename to utils/src/test/java/org/opentripplanner/utils/collection/SetUtilsTest.java index 8e55e27e79b..e1c8d84eca3 100644 --- a/src/test/java/org/opentripplanner/framework/collection/SetUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/collection/SetUtilsTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.collection; +package org.opentripplanner.utils.collection; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/org/opentripplanner/framework/lang/ArrayUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/lang/ArrayUtilsTest.java similarity index 75% rename from src/test/java/org/opentripplanner/framework/lang/ArrayUtilsTest.java rename to utils/src/test/java/org/opentripplanner/utils/lang/ArrayUtilsTest.java index 8933555e75c..9d512af5770 100644 --- a/src/test/java/org/opentripplanner/framework/lang/ArrayUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/lang/ArrayUtilsTest.java @@ -1,8 +1,8 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.opentripplanner.framework.lang.ArrayUtils.hasContent; +import static org.opentripplanner.utils.lang.ArrayUtils.hasContent; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/framework/lang/BitSetUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/lang/BitSetUtilsTest.java similarity index 97% rename from src/test/java/org/opentripplanner/framework/lang/BitSetUtilsTest.java rename to utils/src/test/java/org/opentripplanner/utils/lang/BitSetUtilsTest.java index 83da400f69c..6327da849b4 100644 --- a/src/test/java/org/opentripplanner/framework/lang/BitSetUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/lang/BitSetUtilsTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/src/test/java/org/opentripplanner/framework/lang/BoxTest.java b/utils/src/test/java/org/opentripplanner/utils/lang/BoxTest.java similarity index 96% rename from src/test/java/org/opentripplanner/framework/lang/BoxTest.java rename to utils/src/test/java/org/opentripplanner/utils/lang/BoxTest.java index 7e072fd2f5a..b9f9218fe07 100644 --- a/src/test/java/org/opentripplanner/framework/lang/BoxTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/lang/BoxTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/src/test/java/org/opentripplanner/framework/lang/DoubleUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/lang/DoubleUtilsTest.java similarity index 83% rename from src/test/java/org/opentripplanner/framework/lang/DoubleUtilsTest.java rename to utils/src/test/java/org/opentripplanner/utils/lang/DoubleUtilsTest.java index cb3b0e8b1d6..415b5e939b9 100644 --- a/src/test/java/org/opentripplanner/framework/lang/DoubleUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/lang/DoubleUtilsTest.java @@ -1,15 +1,15 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.opentripplanner.framework.lang.DoubleUtils.requireInRange; -import static org.opentripplanner.framework.lang.DoubleUtils.roundTo1Decimal; -import static org.opentripplanner.framework.lang.DoubleUtils.roundTo2Decimals; -import static org.opentripplanner.framework.lang.DoubleUtils.roundTo3Decimals; -import static org.opentripplanner.framework.lang.DoubleUtils.roundTo4Decimals; -import static org.opentripplanner.framework.lang.DoubleUtils.roundToZeroDecimals; +import static org.opentripplanner.utils.lang.DoubleUtils.requireInRange; +import static org.opentripplanner.utils.lang.DoubleUtils.roundTo1Decimal; +import static org.opentripplanner.utils.lang.DoubleUtils.roundTo2Decimals; +import static org.opentripplanner.utils.lang.DoubleUtils.roundTo3Decimals; +import static org.opentripplanner.utils.lang.DoubleUtils.roundTo4Decimals; +import static org.opentripplanner.utils.lang.DoubleUtils.roundToZeroDecimals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/framework/lang/IntBoxTest.java b/utils/src/test/java/org/opentripplanner/utils/lang/IntBoxTest.java similarity index 96% rename from src/test/java/org/opentripplanner/framework/lang/IntBoxTest.java rename to utils/src/test/java/org/opentripplanner/utils/lang/IntBoxTest.java index d2151b4bea7..1dea3cb7d79 100644 --- a/src/test/java/org/opentripplanner/framework/lang/IntBoxTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/lang/IntBoxTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; diff --git a/src/test/java/org/opentripplanner/framework/lang/IntRangeTest.java b/utils/src/test/java/org/opentripplanner/utils/lang/IntRangeTest.java similarity index 98% rename from src/test/java/org/opentripplanner/framework/lang/IntRangeTest.java rename to utils/src/test/java/org/opentripplanner/utils/lang/IntRangeTest.java index da6300b3953..f568cd5df36 100644 --- a/src/test/java/org/opentripplanner/framework/lang/IntRangeTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/lang/IntRangeTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/src/test/java/org/opentripplanner/framework/lang/IntUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/lang/IntUtilsTest.java similarity index 84% rename from src/test/java/org/opentripplanner/framework/lang/IntUtilsTest.java rename to utils/src/test/java/org/opentripplanner/utils/lang/IntUtilsTest.java index 3d5c92c9258..99b32f47f0a 100644 --- a/src/test/java/org/opentripplanner/framework/lang/IntUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/lang/IntUtilsTest.java @@ -1,18 +1,18 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.opentripplanner.framework.lang.IntUtils.concat; -import static org.opentripplanner.framework.lang.IntUtils.intArray; -import static org.opentripplanner.framework.lang.IntUtils.intArrayToString; -import static org.opentripplanner.framework.lang.IntUtils.intToString; -import static org.opentripplanner.framework.lang.IntUtils.requireInRange; -import static org.opentripplanner.framework.lang.IntUtils.requireNotNegative; -import static org.opentripplanner.framework.lang.IntUtils.requireNullOrNotNegative; -import static org.opentripplanner.framework.lang.IntUtils.shiftArray; -import static org.opentripplanner.framework.lang.IntUtils.standardDeviation; +import static org.opentripplanner.utils.lang.IntUtils.concat; +import static org.opentripplanner.utils.lang.IntUtils.intArray; +import static org.opentripplanner.utils.lang.IntUtils.intArrayToString; +import static org.opentripplanner.utils.lang.IntUtils.intToString; +import static org.opentripplanner.utils.lang.IntUtils.requireInRange; +import static org.opentripplanner.utils.lang.IntUtils.requireNotNegative; +import static org.opentripplanner.utils.lang.IntUtils.requireNullOrNotNegative; +import static org.opentripplanner.utils.lang.IntUtils.shiftArray; +import static org.opentripplanner.utils.lang.IntUtils.standardDeviation; import java.util.List; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/framework/lang/MemEfficientArrayBuilderTest.java b/utils/src/test/java/org/opentripplanner/utils/lang/MemEfficientArrayBuilderTest.java similarity index 98% rename from src/test/java/org/opentripplanner/framework/lang/MemEfficientArrayBuilderTest.java rename to utils/src/test/java/org/opentripplanner/utils/lang/MemEfficientArrayBuilderTest.java index 16468868fe7..99297b29f1d 100644 --- a/src/test/java/org/opentripplanner/framework/lang/MemEfficientArrayBuilderTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/lang/MemEfficientArrayBuilderTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import static java.time.DayOfWeek.MONDAY; import static java.time.DayOfWeek.SATURDAY; diff --git a/src/test/java/org/opentripplanner/framework/lang/ObjectUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/lang/ObjectUtilsTest.java similarity index 98% rename from src/test/java/org/opentripplanner/framework/lang/ObjectUtilsTest.java rename to utils/src/test/java/org/opentripplanner/utils/lang/ObjectUtilsTest.java index 274fb3e8700..3f6283543fc 100644 --- a/src/test/java/org/opentripplanner/framework/lang/ObjectUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/lang/ObjectUtilsTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; diff --git a/src/test/java/org/opentripplanner/framework/lang/OtpNumberFormatTest.java b/utils/src/test/java/org/opentripplanner/utils/lang/OtpNumberFormatTest.java similarity index 96% rename from src/test/java/org/opentripplanner/framework/lang/OtpNumberFormatTest.java rename to utils/src/test/java/org/opentripplanner/utils/lang/OtpNumberFormatTest.java index af5d28af94b..b8cfe684692 100644 --- a/src/test/java/org/opentripplanner/framework/lang/OtpNumberFormatTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/lang/OtpNumberFormatTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/org/opentripplanner/framework/lang/StringUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/lang/StringUtilsTest.java similarity index 93% rename from src/test/java/org/opentripplanner/framework/lang/StringUtilsTest.java rename to utils/src/test/java/org/opentripplanner/utils/lang/StringUtilsTest.java index 0e67344b2bb..dda9248468e 100644 --- a/src/test/java/org/opentripplanner/framework/lang/StringUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/lang/StringUtilsTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.lang; +package org.opentripplanner.utils.lang; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; @@ -100,4 +100,10 @@ void containsInvisibleChars(String input) { void noInvisibleChars(String input) { assertFalse(StringUtils.containsInvisibleCharacters(input)); } + + @ParameterizedTest + @ValueSource(strings = { "AAA Bbb", "aAa bbb", "aaa bbb", "aaa bbb", "AAA_BBB" }) + void slugify(String input) { + assertEquals("aaa-bbb", StringUtils.slugify(input)); + } } diff --git a/src/test/java/org/opentripplanner/framework/logging/ProgressTrackerTest.java b/utils/src/test/java/org/opentripplanner/utils/logging/ProgressTrackerTest.java similarity index 97% rename from src/test/java/org/opentripplanner/framework/logging/ProgressTrackerTest.java rename to utils/src/test/java/org/opentripplanner/utils/logging/ProgressTrackerTest.java index fbbc7b9a7a6..c297aac136f 100644 --- a/src/test/java/org/opentripplanner/framework/logging/ProgressTrackerTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/logging/ProgressTrackerTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.logging; +package org.opentripplanner.utils.logging; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/src/test/java/org/opentripplanner/framework/logging/ThrottleTest.java b/utils/src/test/java/org/opentripplanner/utils/logging/ThrottleTest.java similarity index 97% rename from src/test/java/org/opentripplanner/framework/logging/ThrottleTest.java rename to utils/src/test/java/org/opentripplanner/utils/logging/ThrottleTest.java index c9155992daa..eec907588c6 100644 --- a/src/test/java/org/opentripplanner/framework/logging/ThrottleTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/logging/ThrottleTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.logging; +package org.opentripplanner.utils.logging; import java.time.Duration; import java.util.ArrayList; diff --git a/src/test/java/org/opentripplanner/framework/text/CharacterEscapeFormatterTest.java b/utils/src/test/java/org/opentripplanner/utils/text/CharacterEscapeFormatterTest.java similarity index 95% rename from src/test/java/org/opentripplanner/framework/text/CharacterEscapeFormatterTest.java rename to utils/src/test/java/org/opentripplanner/utils/text/CharacterEscapeFormatterTest.java index b33b06babb6..15dc7139f30 100644 --- a/src/test/java/org/opentripplanner/framework/text/CharacterEscapeFormatterTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/text/CharacterEscapeFormatterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.text; +package org.opentripplanner.utils.text; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/src/test/java/org/opentripplanner/framework/text/FileSizeToTextConverterTest.java b/utils/src/test/java/org/opentripplanner/utils/text/FileSizeToTextConverterTest.java similarity index 87% rename from src/test/java/org/opentripplanner/framework/text/FileSizeToTextConverterTest.java rename to utils/src/test/java/org/opentripplanner/utils/text/FileSizeToTextConverterTest.java index 0d91792423b..b860ff3f09d 100644 --- a/src/test/java/org/opentripplanner/framework/text/FileSizeToTextConverterTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/text/FileSizeToTextConverterTest.java @@ -1,7 +1,7 @@ -package org.opentripplanner.framework.text; +package org.opentripplanner.utils.text; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.framework.text.FileSizeToTextConverter.fileSizeToString; +import static org.opentripplanner.utils.text.FileSizeToTextConverter.fileSizeToString; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/framework/text/HexStringTest.java b/utils/src/test/java/org/opentripplanner/utils/text/HexStringTest.java similarity index 94% rename from src/test/java/org/opentripplanner/framework/text/HexStringTest.java rename to utils/src/test/java/org/opentripplanner/utils/text/HexStringTest.java index 2a565857155..7efc4e3fa61 100644 --- a/src/test/java/org/opentripplanner/framework/text/HexStringTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/text/HexStringTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.text; +package org.opentripplanner.utils.text; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/org/opentripplanner/framework/text/MarkdownFormatterTest.java b/utils/src/test/java/org/opentripplanner/utils/text/MarkdownFormatterTest.java similarity index 96% rename from src/test/java/org/opentripplanner/framework/text/MarkdownFormatterTest.java rename to utils/src/test/java/org/opentripplanner/utils/text/MarkdownFormatterTest.java index b31f7fd8a26..602d9e3b6c5 100644 --- a/src/test/java/org/opentripplanner/framework/text/MarkdownFormatterTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/text/MarkdownFormatterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.text; +package org.opentripplanner.utils.text; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/org/opentripplanner/framework/text/TableTest.java b/utils/src/test/java/org/opentripplanner/utils/text/TableTest.java similarity index 90% rename from src/test/java/org/opentripplanner/framework/text/TableTest.java rename to utils/src/test/java/org/opentripplanner/utils/text/TableTest.java index f79a766c80c..98915faebb1 100644 --- a/src/test/java/org/opentripplanner/framework/text/TableTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/text/TableTest.java @@ -1,10 +1,10 @@ -package org.opentripplanner.framework.text; +package org.opentripplanner.utils.text; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.opentripplanner.framework.text.Table.Align.Center; -import static org.opentripplanner.framework.text.Table.Align.Left; -import static org.opentripplanner.framework.text.Table.Align.Right; +import static org.opentripplanner.utils.text.Table.Align.Center; +import static org.opentripplanner.utils.text.Table.Align.Left; +import static org.opentripplanner.utils.text.Table.Align.Right; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/framework/time/CountdownTimerTest.java b/utils/src/test/java/org/opentripplanner/utils/time/CountdownTimerTest.java similarity index 96% rename from src/test/java/org/opentripplanner/framework/time/CountdownTimerTest.java rename to utils/src/test/java/org/opentripplanner/utils/time/CountdownTimerTest.java index 4d5bdd6fe1d..a30be79cbf9 100644 --- a/src/test/java/org/opentripplanner/framework/time/CountdownTimerTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/time/CountdownTimerTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.time; +package org.opentripplanner.utils.time; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/utils/src/test/java/org/opentripplanner/utils/time/DateUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/time/DateUtilsTest.java new file mode 100644 index 00000000000..75621b8fadb --- /dev/null +++ b/utils/src/test/java/org/opentripplanner/utils/time/DateUtilsTest.java @@ -0,0 +1,24 @@ +package org.opentripplanner.utils.time; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import org.junit.jupiter.api.Test; + +public class DateUtilsTest { + + public static final ZoneId UTC = ZoneIds.UTC; + + @Test + public final void testToDate() { + ZonedDateTime date = DateUtils.toZonedDateTime("1970-01-01", "00:00", UTC); + assertEquals("1970-01-01", date.toLocalDate().toString()); + assertEquals(0, date.toEpochSecond()); + + date = DateUtils.toZonedDateTime(null, "00:00", UTC); + assertEquals(LocalDate.now(UTC).toString(), date.toLocalDate().toString()); + assertEquals(0, date.toEpochSecond() % TimeUtils.ONE_DAY_SECONDS); + } +} diff --git a/src/test/java/org/opentripplanner/framework/time/DurationUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/time/DurationUtilsTest.java similarity index 81% rename from src/test/java/org/opentripplanner/framework/time/DurationUtilsTest.java rename to utils/src/test/java/org/opentripplanner/utils/time/DurationUtilsTest.java index 97b8afc52c0..ef2e0f50901 100644 --- a/src/test/java/org/opentripplanner/framework/time/DurationUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/time/DurationUtilsTest.java @@ -1,13 +1,13 @@ -package org.opentripplanner.framework.time; +package org.opentripplanner.utils.time; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.params.provider.Arguments.of; -import static org.opentripplanner.framework.time.DurationUtils.requireNonNegative; -import static org.opentripplanner.framework.time.DurationUtils.requireNonNegativeLong; -import static org.opentripplanner.framework.time.DurationUtils.requireNonNegativeMedium; -import static org.opentripplanner.framework.time.DurationUtils.requireNonNegativeShort; -import static org.opentripplanner.framework.time.DurationUtils.toIntMilliseconds; +import static org.opentripplanner.utils.time.DurationUtils.requireNonNegative; +import static org.opentripplanner.utils.time.DurationUtils.requireNonNegativeMax2days; +import static org.opentripplanner.utils.time.DurationUtils.requireNonNegativeMax2hours; +import static org.opentripplanner.utils.time.DurationUtils.requireNonNegativeMax30minutes; +import static org.opentripplanner.utils.time.DurationUtils.toIntMilliseconds; import java.time.Duration; import java.time.format.DateTimeParseException; @@ -23,6 +23,8 @@ public class DurationUtilsTest { + private final Duration NEG_1s = Duration.ofSeconds(-1); + private final Duration D1s = Duration.ofSeconds(1); private final Duration D3d = Duration.ofDays(3); private final Duration D2h = Duration.ofHours(2); private final Duration D5m = Duration.ofMinutes(5); @@ -127,42 +129,64 @@ public void testRequireNonNegative() { assertThrows(IllegalArgumentException.class, () -> requireNonNegative(Duration.ofSeconds(-1))); } + @Test + public void testRequireNonNegativeAndMaxLimit() { + // Firs make sure legal values are accepted + requireNonNegative(Duration.ZERO, D2h, "test"); + requireNonNegative(D2h.minus(D1s), D2h, "test"); + + // null is not supported + assertThrows(NullPointerException.class, () -> requireNonNegative(null, D2h, "test")); + + // Test max limit + var ex = assertThrows( + IllegalArgumentException.class, + () -> requireNonNegative(D2h, D2h, "test") + ); + assertEquals("Duration test can't be longer or equals too 2h: PT2H", ex.getMessage()); + + // Test non-negative + ex = + assertThrows(IllegalArgumentException.class, () -> requireNonNegative(NEG_1s, D2h, "test")); + assertEquals("Duration test can't be negative: PT-1S", ex.getMessage()); + } + @Test public void testRequireNonNegativeLong() { - assertThrows(NullPointerException.class, () -> requireNonNegativeLong(null, "test")); + assertThrows(NullPointerException.class, () -> requireNonNegativeMax2days(null, "test")); assertThrows( IllegalArgumentException.class, - () -> requireNonNegativeLong(Duration.ofSeconds(-1), "test") + () -> requireNonNegativeMax2days(Duration.ofSeconds(-1), "test") ); assertThrows( IllegalArgumentException.class, - () -> requireNonNegativeLong(Duration.ofDays(3), "test") + () -> requireNonNegativeMax2days(Duration.ofDays(3), "test") ); } @Test public void testRequireNonNegativeMedium() { - assertThrows(NullPointerException.class, () -> requireNonNegativeMedium(null, "test")); + assertThrows(NullPointerException.class, () -> requireNonNegativeMax2hours(null, "test")); assertThrows( IllegalArgumentException.class, - () -> requireNonNegativeMedium(Duration.ofSeconds(-1), "test") + () -> requireNonNegativeMax2hours(Duration.ofSeconds(-1), "test") ); assertThrows( IllegalArgumentException.class, - () -> requireNonNegativeMedium(Duration.ofHours(3), "test") + () -> requireNonNegativeMax2hours(Duration.ofHours(3), "test") ); } @Test public void testRequireNonNegativeShort() { - assertThrows(NullPointerException.class, () -> requireNonNegativeShort(null, "test")); + assertThrows(NullPointerException.class, () -> requireNonNegativeMax30minutes(null, "test")); assertThrows( IllegalArgumentException.class, - () -> requireNonNegativeShort(Duration.ofSeconds(-1), "test") + () -> requireNonNegativeMax30minutes(Duration.ofSeconds(-1), "test") ); assertThrows( IllegalArgumentException.class, - () -> requireNonNegativeShort(Duration.ofMinutes(31), "test") + () -> requireNonNegativeMax30minutes(Duration.ofMinutes(31), "test") ); } diff --git a/src/test/java/org/opentripplanner/framework/time/LocalDateUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/time/LocalDateUtilsTest.java similarity index 94% rename from src/test/java/org/opentripplanner/framework/time/LocalDateUtilsTest.java rename to utils/src/test/java/org/opentripplanner/utils/time/LocalDateUtilsTest.java index fa6a25ab3d7..4a0ae7e37d9 100644 --- a/src/test/java/org/opentripplanner/framework/time/LocalDateUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/time/LocalDateUtilsTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.time; +package org.opentripplanner.utils.time; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/org/opentripplanner/framework/time/OffsetDateTimeParserTest.java b/utils/src/test/java/org/opentripplanner/utils/time/OffsetDateTimeParserTest.java similarity index 96% rename from src/test/java/org/opentripplanner/framework/time/OffsetDateTimeParserTest.java rename to utils/src/test/java/org/opentripplanner/utils/time/OffsetDateTimeParserTest.java index d8944b9a5f0..a114cc96788 100644 --- a/src/test/java/org/opentripplanner/framework/time/OffsetDateTimeParserTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/time/OffsetDateTimeParserTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.time; +package org.opentripplanner.utils.time; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/src/test/java/org/opentripplanner/framework/time/ServiceDateUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/time/ServiceDateUtilsTest.java similarity index 97% rename from src/test/java/org/opentripplanner/framework/time/ServiceDateUtilsTest.java rename to utils/src/test/java/org/opentripplanner/utils/time/ServiceDateUtilsTest.java index 4c22b414537..028b53b064a 100644 --- a/src/test/java/org/opentripplanner/framework/time/ServiceDateUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/time/ServiceDateUtilsTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.time; +package org.opentripplanner.utils.time; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -6,7 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.opentripplanner.framework.time.ServiceDateUtils.asStartOfService; +import static org.opentripplanner.utils.time.ServiceDateUtils.asStartOfService; import java.text.ParseException; import java.time.Duration; @@ -17,7 +17,6 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import org.junit.jupiter.api.Test; -import org.opentripplanner._support.time.ZoneIds; public class ServiceDateUtilsTest { diff --git a/src/test/java/org/opentripplanner/framework/time/TimeUtilsTest.java b/utils/src/test/java/org/opentripplanner/utils/time/TimeUtilsTest.java similarity index 98% rename from src/test/java/org/opentripplanner/framework/time/TimeUtilsTest.java rename to utils/src/test/java/org/opentripplanner/utils/time/TimeUtilsTest.java index c2eb828cc21..d5c0e519742 100644 --- a/src/test/java/org/opentripplanner/framework/time/TimeUtilsTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/time/TimeUtilsTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.time; +package org.opentripplanner.utils.time; import static java.time.ZoneOffset.UTC; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -11,7 +11,6 @@ import java.time.ZonedDateTime; import java.util.Arrays; import org.junit.jupiter.api.Test; -import org.opentripplanner._support.time.ZoneIds; public class TimeUtilsTest { diff --git a/utils/src/test/java/org/opentripplanner/utils/time/ZoneIds.java b/utils/src/test/java/org/opentripplanner/utils/time/ZoneIds.java new file mode 100644 index 00000000000..0e3244dcd36 --- /dev/null +++ b/utils/src/test/java/org/opentripplanner/utils/time/ZoneIds.java @@ -0,0 +1,11 @@ +package org.opentripplanner.utils.time; + +import java.time.ZoneId; + +public class ZoneIds { + + public static final ZoneId UTC = ZoneId.of("UTC"); + public static final ZoneId CET = ZoneId.of("CET"); + public static final ZoneId OSLO = ZoneId.of("Europe/Oslo"); + public static final ZoneId PARIS = ZoneId.of("Europe/Paris"); +} diff --git a/src/test/java/org/opentripplanner/framework/tostring/MultiLineToStringBuilderTest.java b/utils/src/test/java/org/opentripplanner/utils/tostring/MultiLineToStringBuilderTest.java similarity index 96% rename from src/test/java/org/opentripplanner/framework/tostring/MultiLineToStringBuilderTest.java rename to utils/src/test/java/org/opentripplanner/utils/tostring/MultiLineToStringBuilderTest.java index 495a8649cef..55b43517e18 100644 --- a/src/test/java/org/opentripplanner/framework/tostring/MultiLineToStringBuilderTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/tostring/MultiLineToStringBuilderTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.tostring; +package org.opentripplanner.utils.tostring; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/org/opentripplanner/framework/tostring/ToStringBuilderTest.java b/utils/src/test/java/org/opentripplanner/utils/tostring/ToStringBuilderTest.java similarity index 98% rename from src/test/java/org/opentripplanner/framework/tostring/ToStringBuilderTest.java rename to utils/src/test/java/org/opentripplanner/utils/tostring/ToStringBuilderTest.java index 90254c321a1..477f48e7c63 100644 --- a/src/test/java/org/opentripplanner/framework/tostring/ToStringBuilderTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/tostring/ToStringBuilderTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.tostring; +package org.opentripplanner.utils.tostring; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -13,8 +13,8 @@ import java.util.Objects; import java.util.function.Function; import org.junit.jupiter.api.Test; -import org.opentripplanner._support.time.ZoneIds; -import org.opentripplanner.framework.time.TimeUtils; +import org.opentripplanner.utils.time.TimeUtils; +import org.opentripplanner.utils.time.ZoneIds; public class ToStringBuilderTest { diff --git a/src/test/java/org/opentripplanner/framework/tostring/ValueObjectToStringBuilderTest.java b/utils/src/test/java/org/opentripplanner/utils/tostring/ValueObjectToStringBuilderTest.java similarity index 99% rename from src/test/java/org/opentripplanner/framework/tostring/ValueObjectToStringBuilderTest.java rename to utils/src/test/java/org/opentripplanner/utils/tostring/ValueObjectToStringBuilderTest.java index a59a0bf9b90..01a9beac141 100644 --- a/src/test/java/org/opentripplanner/framework/tostring/ValueObjectToStringBuilderTest.java +++ b/utils/src/test/java/org/opentripplanner/utils/tostring/ValueObjectToStringBuilderTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.tostring; +package org.opentripplanner.utils.tostring; import static org.junit.jupiter.api.Assertions.assertEquals;