From ef8d73a166b0e408f826d0dcfa2bb167bc7e986d Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 31 Mar 2022 18:49:58 +0200 Subject: [PATCH] doc: Reformat doc using IntelliJ --- .github/pull_request_template.md | 48 ++- ARCHITECTURE.md | 79 ++--- CONTRIBUTING.md | 158 ++++++--- README.md | 66 +++- docs/Basic-Tutorial.md | 158 +++++++-- docs/Bibliography.md | 181 ++++++---- docs/BuildConfiguration.md | 287 ++++++++++------ docs/Changelog.md | 56 +++- docs/Codestyle.md | 168 +++++----- docs/Configuration.md | 157 +++++---- docs/Deployments.md | 102 ++++-- docs/Developers-Guide.md | 258 ++++++++------- docs/Getting-OTP.md | 110 ++++--- docs/Governance.md | 31 +- docs/History.md | 80 ++++- docs/Interfaces-Data-Sources.md | 35 +- docs/Localization.md | 150 ++++++--- docs/Netex-Norway.md | 76 ++++- docs/OTP2-MigrationGuide.md | 304 ++++++++--------- docs/Preparing-OSM.md | 70 +++- docs/RouterConfiguration.md | 161 +++++---- docs/RoutingModes.md | 76 +++-- docs/SandboxExtension.md | 63 ++-- docs/Security.md | 31 +- docs/Troubleshooting-Routing.md | 165 ++++++---- docs/Version-Comparison.md | 171 +++++++--- docs/Visual-Identity.md | 20 +- docs/examples/Readme.md | 14 +- docs/examples/entur/Readme.md | 34 +- docs/index.md | 71 ++-- docs/sandbox/ActuatorAPI.md | 8 +- docs/sandbox/DataOverlay.md | 56 +++- docs/sandbox/Flex.md | 36 +- docs/sandbox/GoogleCloudStorage.md | 11 +- docs/sandbox/InteractiveOtpMain.md | 11 +- docs/sandbox/LegacyGraphQLApi.md | 15 +- docs/sandbox/MapboxVectorTilesApi.md | 61 ++-- docs/sandbox/ParkAndRideApi.md | 4 +- docs/sandbox/ReportApi.md | 24 +- docs/sandbox/SiriUpdator.md | 25 +- docs/sandbox/SmooveBikeRental.md | 11 +- docs/sandbox/TransmodelApi.md | 63 ++-- docs/sandbox/VehicleParking.md | 36 +- docs/sandbox/VehicleRentalServiceDirectory.md | 16 +- docs/sandbox/VehicleToStopHeuristics.md | 15 +- docs/sandbox/transferanalyzer.md | 10 +- .../org/opentripplanner/ext/flex/README.md | 36 +- .../ext/legacygraphqlapi/generated/README.md | 5 +- .../java/org/opentripplanner/api/package.md | 10 +- .../java/org/opentripplanner/gtfs/package.md | 11 +- .../model/plan/pagecursor/readme.md | 106 +++--- .../java/org/opentripplanner/netex/package.md | 116 +++---- .../routing/algorithm/filterchain/package.md | 16 +- .../algorithm/transferoptimization/package.md | 201 ++++++------ .../standalone/config/package.md | 46 ++- .../opentripplanner/transit/raptor/package.md | 309 ++++++++++-------- .../raptor/moduletests/package-info.md | 6 +- .../transit/raptor/package-info.md | 11 +- .../transit/raptor/speed_test/package.md | 10 +- .../raptor/speedtest/norway/README.md | 10 +- test/ci-performance-test/README.md | 20 +- 61 files changed, 2901 insertions(+), 1794 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 73da17e7a70..ff4c14046fa 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,41 +1,71 @@ ## PR Instructions -When creating a pull request, please follow the format below. For each section, *replace* the guidance text with your own text, keeping the section heading. If you have nothing to say in a particular section, you can completely delete the section including its heading to indicate that you have taken the requested steps. None of these instructions or the guidance text (non-heading text) should be present in the submitted PR. These sections serve as a checklist: when you have replaced or deleted all of them, the PR is considered complete. As of 2021, most regular OTP contributors participate in our twice-weekly conference calls. For all but the simplest and smallest PRs, participation in these discussions is necessary to facilitate the review and merge process. Other developers can ask questions and provide immediate feedback on technical design and code style, and resolve any concerns about long term maintenance and comprehension of new code. + +When creating a pull request, please follow the format below. For each section, *replace* the +guidance text with your own text, keeping the section heading. If you have nothing to say in a +particular section, you can completely delete the section including its heading to indicate that you +have taken the requested steps. None of these instructions or the guidance text (non-heading text) +should be present in the submitted PR. These sections serve as a checklist: when you have replaced +or deleted all of them, the PR is considered complete. As of 2021, most regular OTP contributors +participate in our twice-weekly conference calls. For all but the simplest and smallest PRs, +participation in these discussions is necessary to facilitate the review and merge process. Other +developers can ask questions and provide immediate feedback on technical design and code style, and +resolve any concerns about long term maintenance and comprehension of new code. ### Summary + Explain in one or two sentences what this PR achieves. ### Issue -Link to or create an [issue](https://github.com/opentripplanner/OpenTripPlanner/issues) that describes the relevant feature or bug. -You need not create an issue for small bugfixes and code cleanups, but in that case do describe the problem clearly and completely in the "summary" section above. -In the linked issue (or summary section for smaller PRs) please describe: + +Link to or create an [issue](https://github.com/opentripplanner/OpenTripPlanner/issues) that +describes the relevant feature or bug. You need not create an issue for small bugfixes and code +cleanups, but in that case do describe the problem clearly and completely in the "summary" section +above. In the linked issue (or summary section for smaller PRs) please describe: + - Motivation (problem or need encountered) - How the code works - Technical approach and any design considerations or decisions -Remember that the PR will be reviewed by another developer who may not be familiar with your use cases or the code you're modifying. It generally takes much less effort for the author of a PR to explain the background and technical details than for a reviewer to infer or deduce them. PRs may be closed if they or their linked issues do not contain sufficient information for a reviewer to proceed. +Remember that the PR will be reviewed by another developer who may not be familiar with your use +cases or the code you're modifying. It generally takes much less effort for the author of a PR to +explain the background and technical details than for a reviewer to infer or deduce them. PRs may be +closed if they or their linked issues do not contain sufficient information for a reviewer to +proceed. -Add [GitHub keywords](https://help.github.com/articles/closing-issues-using-keywords/) to this PR's description, for example: +Add [GitHub keywords](https://help.github.com/articles/closing-issues-using-keywords/) to this PR's +description, for example: `closes #45` ### Unit tests + Write a few words on how the new code is tested. + - Were unit tests added/updated? - Was any manual verification done? - Any observations on changes to performance? - Was the code designed so it is unit testable? - Were any tests applied to the smallest appropriate unit? -- Do all tests pass [the continuous integration service](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/docs/Developers-Guide.md#continuous-integration)? +- Do all tests + pass [the continuous integration service](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/docs/Developers-Guide.md#continuous-integration) + ? ### Code style -Have you followed the [suggested code style](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/docs/Codestyle.md)? + +Have you followed +the [suggested code style](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/docs/Codestyle.md) +? ### Documentation + - Have you added documentation in code covering design and rationale behind the code? - Were all non-trivial public classes and methods documented with Javadoc? -- Were any new configuration options added? If so were the tables in the [configuration documentation](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/docs/Configuration.md) updated? +- Were any new configuration options added? If so were the tables in + the [configuration documentation](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/docs/Configuration.md) + updated? ### Changelog + The [changelog file](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/docs/Changelog.md) is generated from the pull-request title, make sure the title describe the feature or issue fixed. To exclude the PR from the changelog add `[changelog skip]` in the title. diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 6f160ab8f7f..b6178f9912f 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -1,37 +1,36 @@ # OTP Architecture -OTP is developed over more than 10 years, and most of the design documentation is in the code -as comments and JavaDoc. Over the years the complexity have increased, and the natural developer -turnover creates a demand for more architecture and design documentation. The new OTP2 -documentation is put together with the source; hopefully making it easier to maintain. Instead of -documenting modules in old style _package-info.java_ files we use _package.md_ files. This document -should serve as an index to all existing top-level documented components. - -This document is far from complete - hopefully it can evolve over time and become a good -introduction to OTP architecture. The OTP project GitHub issues are a good place to look for detailed -discussions on many design decisions. - -Be sure to also read the [developer documentation](docs/Developers-Guide.md). - + +OTP is developed over more than 10 years, and most of the design documentation is in the code as +comments and JavaDoc. Over the years the complexity have increased, and the natural developer +turnover creates a demand for more architecture and design documentation. The new OTP2 documentation +is put together with the source; hopefully making it easier to maintain. Instead of documenting +modules in old style _package-info.java_ files we use _package.md_ files. This document should serve +as an index to all existing top-level documented components. + +This document is far from complete - hopefully it can evolve over time and become a good +introduction to OTP architecture. The OTP project GitHub issues are a good place to look for +detailed discussions on many design decisions. + +Be sure to also read the [developer documentation](docs/Developers-Guide.md). + ## Modules/Components + 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) -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. - +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. ### [REST API](src/main/java/org/opentripplanner/api/package.md) Short introduction to the REST API. - ### [GTFS import module](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) Used to import NeTEx transit data files. @@ -41,35 +40,41 @@ Used to import NeTEx transit data files. #### [Raptor transit routing](src/main/java/org/opentripplanner/transit/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 developer - just to understand how the transit routing works. +Raptor works, the important concepts and the design. It might be worth reading even if you are not a +developer - just to understand how the transit routing works. -The Raptor functionality is quite complex, so we want to isolate it from the remaining code. Therefore, the -raptor component is designed to have as few dependencies as possible. In fact there are _no_ +The Raptor functionality is quite complex, so we want to isolate it from the remaining code. +Therefore, the raptor component is designed to have as few dependencies as possible. In fact there +are _no_ dependencies from Raptor to other parts of OTP code, only to utility classes not found in the JDK. -Also, the code follows a stricter object-oriented design, than most other parts of OTP. The Raptor +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 + +OTP provides transit data to Raptor by implementing the _raptor/api/transit_ model. The [RoutingService](src/main/java/org/opentripplanner/routing/RoutingService.java) -is responsible for mapping from the OTP context to a +is responsible for mapping from the OTP context to a [RaptorRequest](src/main/java/org/opentripplanner/transit/raptor/api/request/RaptorRequest.java) -and then map the result, [Raptor Path](src/main/java/org/opentripplanner/transit/raptor/api/path/Path.java), -back to the OTP internal domain. This might seem like a lot of unnecessary mapping, but -mapping is simple - routing is not. +and then map the +result, [Raptor Path](src/main/java/org/opentripplanner/transit/raptor/api/path/Path.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 with an earlier version of the code to make sure the performance is NOT degraded. +existing Raptor coded should be tested with the +[SpeedTest](src/test/java/org/opentripplanner/transit/raptor/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) -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). + +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) +. #### [Itinerary list filter chain](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), -in order to sort and reduce the number of returned itineraries. It can also be used to decorate the + +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), +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. \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a2f279cb440..fc7a2ff34d5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,69 +1,147 @@ # OpenTripPlanner Contributing Guide -Thank you for your interest in contributing to OpenTripPlanner. This document will give you some pointers on how to contact and coordinate with the OTP development team, as well as a description of the contribution process and expectations. - +Thank you for your interest in contributing to OpenTripPlanner. This document will give you some +pointers on how to contact and coordinate with the OTP development team, as well as a description of +the contribution process and expectations. ## Primary Channels of Communication -If you have any questions about problems you are encountering with code, deployment, documentation, or development coordination, please don't hesitate to post to the OpenTripPlanner discussion groups. These are Google Groups which can be accessed as web forums or as traditional email mailing lists: +If you have any questions about problems you are encountering with code, deployment, documentation, +or development coordination, please don't hesitate to post to the OpenTripPlanner discussion groups. +These are Google Groups which can be accessed as web forums or as traditional email mailing lists: - https://groups.google.com/g/opentripplanner-dev (opentripplanner-dev@googlegroups.com) - https://groups.google.com/g/opentripplanner-users (opentripplanner-users@googlegroups.com) -Any message posted there will be seen by most of the contributors, some of whom work on OTP full time. It will also create a record of the discussion that will be useful to the larger community and often leads to issues being discussed at the twice-weekly development meetings. - -OTP development meetings usually occur twice a week. These meetings are open to anyone who wants to join, even if you simply want to observe the process or ask a few questions. The most effective way to advance pull requests and collaborate is to participate directly in these meetings. The meeting times have been deliberately chosen to allow participation during regular business hours across as many time zones as possible, from the eastern Americas through Europe and Africa to Asia. If these times are not suitable for you, please let us know and we will attempt to schedule a call at a time that suits you. - -Check the specific times on [this calendar](https://calendar.google.com/calendar/u/0/embed?src=ormbltvsqb6adl80ejgudt0glc@group.calendar.google.com) which will be updated to reflect holidays or changes to meeting times. Note that times on this calendar are expressed in the Central European time zone by default. There is also an [iCal link to import this calendar](https://calendar.google.com/calendar/ical/ormbltvsqb6adl80ejgudt0glc@group.calendar.google.com/public/basic.ics) into calendar apps. Check the details of the calendar events for the Google Meet link, which is different on different days of the week. - -Our primary tools for organizing development are Github issues and pull requests. When creating issues and pull requests, please follow the instructions in the template: always specify the version of OTP you are running and provide command lines and configuration files, do not leave remnants of the instructions in your submitted text etc. - +Any message posted there will be seen by most of the contributors, some of whom work on OTP full +time. It will also create a record of the discussion that will be useful to the larger community and +often leads to issues being discussed at the twice-weekly development meetings. + +OTP development meetings usually occur twice a week. These meetings are open to anyone who wants to +join, even if you simply want to observe the process or ask a few questions. The most effective way +to advance pull requests and collaborate is to participate directly in these meetings. The meeting +times have been deliberately chosen to allow participation during regular business hours across as +many time zones as possible, from the eastern Americas through Europe and Africa to Asia. If these +times are not suitable for you, please let us know and we will attempt to schedule a call at a time +that suits you. + +Check the specific times +on [this calendar](https://calendar.google.com/calendar/u/0/embed?src=ormbltvsqb6adl80ejgudt0glc@group.calendar.google.com) +which will be updated to reflect holidays or changes to meeting times. Note that times on this +calendar are expressed in the Central European time zone by default. There is also +an [iCal link to import this calendar](https://calendar.google.com/calendar/ical/ormbltvsqb6adl80ejgudt0glc@group.calendar.google.com/public/basic.ics) +into calendar apps. Check the details of the calendar events for the Google Meet link, which is +different on different days of the week. + +Our primary tools for organizing development are Github issues and pull requests. When creating +issues and pull requests, please follow the instructions in the template: always specify the version +of OTP you are running and provide command lines and configuration files, do not leave remnants of +the instructions in your submitted text etc. ## Contributing Issues and Pull Requests -OpenTripPlanner has been in active development and use for well over a decade and is now relied upon as infrastructure by large organizations and millions of public transit passengers around the world. These organizations have invested a great deal of time, effort, and money in this project, and some have gone all-in supporting and relying on OTP over the long term. Accordingly, when working on OpenTripPlanner 2 we have decided to make code quality and maintainability a top priority, and have built up a culture of active collaboration and code review to support this. At this stage, the project has relatively high expectations on code quality and a desire to maintain a professional and orderly development process. - -We welcome well-documented bug reports as Github Issues, and pull requests sharing your patches and new features. However, for all but the simplest bugfixes and documentation updates, please be aware that pull requests will be subject to review and you will almost certainly be asked to explain use cases, ensure encapsulation and integration with the rest of the system, and provide some assurance that there is an organizational commitment to long term maintenance. - -Most of the contributors to OTP2 are full-time software developers working for organizations with a long term stake in OpenTripPlanner, and are professionally bound to ensure its reliability and efficiency. It is an accepted fact among this team that a large part, perhaps the most important part of software development is careful design and communication with current collaborators and future maintainers of the system. - -You will see a steady stream of pull requests being merged from different organizations. What almost all these have in common is that their authors participated in the weekly meetings, at which they discussed the problem or feature they were addressing, answered questions from the other developers about their design and implementation, and were open to making changes based on the consensus reached at those meetings. If you do not have time to participate in a meeting (or organize a special-purpose call to review code together with other contributors), please understand up front that contributions may stall. - -Even before you start working on a contribution, please feel free to join a call and discuss how you want to solve your problem or implement your feature. In the past, most contributions that were undertaken without any discussion up front required major changes before acceptance. - -We try to reduce the time demands on reviewers by putting more responsibilities on the PR submitter. This does carry a risk of discouraging contributions, but without a "sponsor" organization for a change, the time available to review is the bottleneck in the process. - -In sum: if you are interested in integrating your code into core OTP, a significant amount of the time you invest in OTP will need to be spent on collaboration, discussion, documentation, etc. and you will need to be available for regular meetings. You will need to take this into consideration in your budget and timeline. - +OpenTripPlanner has been in active development and use for well over a decade and is now relied upon +as infrastructure by large organizations and millions of public transit passengers around the world. +These organizations have invested a great deal of time, effort, and money in this project, and some +have gone all-in supporting and relying on OTP over the long term. Accordingly, when working on +OpenTripPlanner 2 we have decided to make code quality and maintainability a top priority, and have +built up a culture of active collaboration and code review to support this. At this stage, the +project has relatively high expectations on code quality and a desire to maintain a professional and +orderly development process. + +We welcome well-documented bug reports as Github Issues, and pull requests sharing your patches and +new features. However, for all but the simplest bugfixes and documentation updates, please be aware +that pull requests will be subject to review and you will almost certainly be asked to explain use +cases, ensure encapsulation and integration with the rest of the system, and provide some assurance +that there is an organizational commitment to long term maintenance. + +Most of the contributors to OTP2 are full-time software developers working for organizations with a +long term stake in OpenTripPlanner, and are professionally bound to ensure its reliability and +efficiency. It is an accepted fact among this team that a large part, perhaps the most important +part of software development is careful design and communication with current collaborators and +future maintainers of the system. + +You will see a steady stream of pull requests being merged from different organizations. What almost +all these have in common is that their authors participated in the weekly meetings, at which they +discussed the problem or feature they were addressing, answered questions from the other developers +about their design and implementation, and were open to making changes based on the consensus +reached at those meetings. If you do not have time to participate in a meeting (or organize a +special-purpose call to review code together with other contributors), please understand up front +that contributions may stall. + +Even before you start working on a contribution, please feel free to join a call and discuss how you +want to solve your problem or implement your feature. In the past, most contributions that were +undertaken without any discussion up front required major changes before acceptance. + +We try to reduce the time demands on reviewers by putting more responsibilities on the PR submitter. +This does carry a risk of discouraging contributions, but without a "sponsor" organization for a +change, the time available to review is the bottleneck in the process. + +In sum: if you are interested in integrating your code into core OTP, a significant amount of the +time you invest in OTP will need to be spent on collaboration, discussion, documentation, etc. and +you will need to be available for regular meetings. You will need to take this into consideration in +your budget and timeline. ## Other ways to share development work -We don't want to discourage innovation and experimentation, and want promising new features to be visible to other users, so we have also created a Sandbox system for fast-track review and inclusion in mainline OTP. Most code for a Sandbox feature must be located in its own package, and any code added to the core of OTP must be in conditional blocks controlled by a feature flag and disabled by default. This greatly simplifies and accelerates the review process, as requirements on the code outside core OTP will be much less stringent. Please see http://docs.opentripplanner.org/en/latest/SandboxExtension/ for more details. - -If you don't have the time to participate in this process, the community is of course still interested in the new ideas and capabilities in your fork of OTP. Please do share them on the groups (mailing lists) where you may create awareness of your work and attract collaborators with more resources. The goal of mainline OTP is not to be everything to everyone, but rather to contain the most solid code relied upon daily by the primary OTP contributor organizations (as well as Sandbox features that have been cleanly isolated from the core system). So in a sense it's encouraged for people to work on special-purpose forks. - +We don't want to discourage innovation and experimentation, and want promising new features to be +visible to other users, so we have also created a Sandbox system for fast-track review and inclusion +in mainline OTP. Most code for a Sandbox feature must be located in its own package, and any code +added to the core of OTP must be in conditional blocks controlled by a feature flag and disabled by +default. This greatly simplifies and accelerates the review process, as requirements on the code +outside core OTP will be much less stringent. Please +see http://docs.opentripplanner.org/en/latest/SandboxExtension/ for more details. + +If you don't have the time to participate in this process, the community is of course still +interested in the new ideas and capabilities in your fork of OTP. Please do share them on the +groups (mailing lists) where you may create awareness of your work and attract collaborators with +more resources. The goal of mainline OTP is not to be everything to everyone, but rather to contain +the most solid code relied upon daily by the primary OTP contributor organizations (as well as +Sandbox features that have been cleanly isolated from the core system). So in a sense it's +encouraged for people to work on special-purpose forks. ## Additional Considerations for Structuring Pull Requests When creating and building on a pull request, please do the following: -- If possible, please discuss your proposed changes in advance before proceeding too far with development. There are often other plans to address the same problem, or at least other points of view and ideas. Coordinating with other OTP developers can avoid a lot of duplicated effort, conflict, and technical debt and make the review process a lot easier. -- Describe in detail the problem you are solving and any major design choices you have made. PR descriptions must clearly state how your changes work. +- If possible, please discuss your proposed changes in advance before proceeding too far with + development. There are often other plans to address the same problem, or at least other points of + view and ideas. Coordinating with other OTP developers can avoid a lot of duplicated effort, + conflict, and technical debt and make the review process a lot easier. +- Describe in detail the problem you are solving and any major design choices you have made. PR + descriptions must clearly state how your changes work. - Break large changes down into a series of smaller logical steps in separate PRs. - Tie such series of PRs together with an "epic issue" that explains the overall plan. - Use Github issue references ("addresses #12" etc.) to connect PRs and issues together. -- Consider squashing and rebasing to make the PR history easier to understand, eliminating extra "noise" commits like accidental changes to organization specific code, abandoned experiments, or reverted configuration changes. +- Consider squashing and rebasing to make the PR history easier to understand, eliminating extra " + noise" commits like accidental changes to organization specific code, abandoned experiments, or + reverted configuration changes. -In turn, in order to prevent OTP2 from turning into a "big-ball-of-mud" (https://en.wikipedia.org/wiki/Big_ball_of_mud) and ensure development does grind to a halt, the maintainers of the project will: +In turn, in order to prevent OTP2 from turning into a " +big-ball-of-mud" (https://en.wikipedia.org/wiki/Big_ball_of_mud) and ensure development does grind +to a halt, the maintainers of the project will: - Keep an eye out for features which are not core, and suggest that they be Sandbox features. -- Ask for example use cases for new functionality to make sure OTP is the right place to implement it (rather than some external component). -- Make sure the implementation avoids duplication and the addition of new layers and is encapsulated, requesting refactoring if necessary. -- Make sure non-functional characteristics (performance and memory usage) are maintained when features are added. - +- Ask for example use cases for new functionality to make sure OTP is the right place to implement + it (rather than some external component). +- Make sure the implementation avoids duplication and the addition of new layers and is + encapsulated, requesting refactoring if necessary. +- Make sure non-functional characteristics (performance and memory usage) are maintained when + features are added. ## OTP2 versus OTP1 -The vast majority of the work done by the core development team is now on OTP2 (the `dev-2.x` branch) as opposed to OTP1 (the `dev-1.x` branch). Please see http://docs.opentripplanner.org/en/latest/Version-Comparison/ for a discussion of the difference between these two branches. At this point, OTP1 is essentially a legacy product that will receive bug and stability fixes to the extent that they can be readily backported from OTP2 or that the author of such patches can invest the effort to join a meeting and answer any questions about the impact and design of their code. - -There is a large base of existing deployments of OTP1, in both trip planning and academic research use. OTP2 is different in many ways from OTP1, and some features that were research prototypes or not actively maintained have been removed. We want to ensure long-term users can continue to rely on these OTP1-specific if needed. Therefore we cannot apply changes to OTP1 which pose any significant risk of introducing new bugs or behavior changes, as this will create additional maintenance or documentation work for which there is no budgeted developer time. +The vast majority of the work done by the core development team is now on OTP2 (the `dev-2.x` +branch) as opposed to OTP1 (the `dev-1.x` branch). Please +see http://docs.opentripplanner.org/en/latest/Version-Comparison/ for a discussion of the difference +between these two branches. At this point, OTP1 is essentially a legacy product that will receive +bug and stability fixes to the extent that they can be readily backported from OTP2 or that the +author of such patches can invest the effort to join a meeting and answer any questions about the +impact and design of their code. + +There is a large base of existing deployments of OTP1, in both trip planning and academic research +use. OTP2 is different in many ways from OTP1, and some features that were research prototypes or +not actively maintained have been removed. We want to ensure long-term users can continue to rely on +these OTP1-specific if needed. Therefore we cannot apply changes to OTP1 which pose any significant +risk of introducing new bugs or behavior changes, as this will create additional maintenance or +documentation work for which there is no budgeted developer time. diff --git a/README.md b/README.md index cbf694a1a65..d6f5005d85d 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,76 @@ ## Overview -OpenTripPlanner (OTP) is an open source multi-modal trip planner, focusing on travel by scheduled public transportation in combination with bicycling, walking, and mobility services including bike share and ride hailing. Its server component runs on any platform with a Java virtual machine (including Linux, Mac, and Windows). It exposes REST and GraphQL APIs that can be accessed by various clients including open source Javascript components and native mobile applications. It builds its representation of the transportation network from open data in open standard file formats (primarily GTFS and OpenStreetMap). It applies real-time updates and alerts with immediate visibility to clients, finding itineraries that account for disruptions and service changes. +OpenTripPlanner (OTP) is an open source multi-modal trip planner, focusing on travel by scheduled +public transportation in combination with bicycling, walking, and mobility services including bike +share and ride hailing. Its server component runs on any platform with a Java virtual machine ( +including Linux, Mac, and Windows). It exposes REST and GraphQL APIs that can be accessed by various +clients including open source Javascript components and native mobile applications. It builds its +representation of the transportation network from open data in open standard file formats (primarily +GTFS and OpenStreetMap). It applies real-time updates and alerts with immediate visibility to +clients, finding itineraries that account for disruptions and service changes. -Note that this branch contains **OpenTripPlanner 2**, the second major version of OTP, which has been under development since Q2 2018. The latest version of OTP is v2.1.0, released in March 2022. - -If you do not want to test or explore this version, please switch to the final 1.x release tag `v1.5.0` or the `dev-1.x` branch for any patches and bugfixes applied to the v1.5.0 release. +Note that this branch contains **OpenTripPlanner 2**, the second major version of OTP, which has +been under development since Q2 2018. The latest version of OTP is v2.1.0, released in March 2022. +If you do not want to test or explore this version, please switch to the final 1.x release +tag `v1.5.0` or the `dev-1.x` branch for any patches and bugfixes applied to the v1.5.0 release. ## Performance Test -[📊 Speed Benchmark](https://otp-performance.leonard.io/) We run the SpeedTest (included in the code) to measure the performance for every PR merged into OTP. The test uses a fixed Norwegian Netex data set and Grafana is used to display the results. Each run is listed under the [GitHub Actions](https://github.com/opentripplanner/OpenTripPlanner/actions/workflows/performance-test.yml). If you need to run the test locally you can [download the NeTex file](https://leonard.io/otp/rb_norway-aggregated-netex-2021-12-11.zip) from the Continuous Integration Pipeline. There is a [text file](test/ci-performance-test/travelSearch-expected-results.csv) with the expected results witch might need to be updated when OTP is changed and the test fails. The OSM data used is the [norway-210101.osm.pbf](https://download.geofabrik.de/europe/norway-210101.osm.pbf) file from Geofabrik OSM extract from January 1st 2021. - +[📊 Speed Benchmark](https://otp-performance.leonard.io/) We run the SpeedTest (included in the +code) to measure the performance for every PR merged into OTP. The test uses a fixed Norwegian Netex +data set and Grafana is used to display the results. Each run is listed under +the [GitHub Actions](https://github.com/opentripplanner/OpenTripPlanner/actions/workflows/performance-test.yml) +. If you need to run the test locally you +can [download the NeTex file](https://leonard.io/otp/rb_norway-aggregated-netex-2021-12-11.zip) from +the Continuous Integration Pipeline. There is +a [text file](test/ci-performance-test/travelSearch-expected-results.csv) with the expected results +witch might need to be updated when OTP is changed and the test fails. The OSM data used is +the [norway-210101.osm.pbf](https://download.geofabrik.de/europe/norway-210101.osm.pbf) file from +Geofabrik OSM extract from January 1st 2021. ## 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 `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. -Additional information and instructions are available in the [main documentation](http://docs.opentripplanner.org/en/dev-2.x/), including a +Additional information and instructions are available in +the [main documentation](http://docs.opentripplanner.org/en/dev-2.x/), including a [quick introduction](http://docs.opentripplanner.org/en/dev-2.x/Basic-Tutorial/). -## Development +## Development [![codecov](https://codecov.io/gh/opentripplanner/OpenTripPlanner/branch/dev-2.x/graph/badge.svg?token=ak4PbIKgZ1)](https://codecov.io/gh/opentripplanner/OpenTripPlanner) -OpenTripPlanner is a collaborative project incorporating code, translation, and documentation from contributors around the world. We welcome new contributions. Further [development guidelines](http://docs.opentripplanner.org/en/latest/Developers-Guide/) can be found in the documentation. +OpenTripPlanner is a collaborative project incorporating code, translation, and documentation from +contributors around the world. We welcome new contributions. +Further [development guidelines](http://docs.opentripplanner.org/en/latest/Developers-Guide/) can be +found in the documentation. ### Development history -The OpenTripPlanner project was launched by Portland, Oregon's transport agency TriMet (http://trimet.org/) in July of 2009. As of this writing in Q3 2020, it has been in development for over ten years. See the main documentation for an overview of [OTP history](http://docs.opentripplanner.org/en/dev-2.x/History/) and a list of [cities and regions using OTP](http://docs.opentripplanner.org/en/dev-2.x/Deployments/) around the world. - +The OpenTripPlanner project was launched by Portland, Oregon's transport agency +TriMet (http://trimet.org/) in July of 2009. As of this writing in Q3 2020, it has been in +development for over ten years. See the main documentation for an overview +of [OTP history](http://docs.opentripplanner.org/en/dev-2.x/History/) and a list +of [cities and regions using OTP](http://docs.opentripplanner.org/en/dev-2.x/Deployments/) around +the world. ## Mailing Lists -The main forums through which the OpenTripPlanner community organizes development and provides mutual assistance are our two Google discussion groups. Changes and extensions to OTP are debated on the [opentripplanner-dev](https://groups.google.com/forum/#!forum/opentripplanner-dev) developers' list. More general questions and announcements of interest to non-developer OTP users should be directed to the [opentripplanner-users](https://groups.google.com/forum/#!forum/opentripplanner-users) list. Other details of [project governance](http://docs.opentripplanner.org/en/dev-2.x/Governance/) can be found in the main documentation. - +The main forums through which the OpenTripPlanner community organizes development and provides +mutual assistance are our two Google discussion groups. Changes and extensions to OTP are debated on +the [opentripplanner-dev](https://groups.google.com/forum/#!forum/opentripplanner-dev) developers' +list. More general questions and announcements of interest to non-developer OTP users should be +directed to +the [opentripplanner-users](https://groups.google.com/forum/#!forum/opentripplanner-users) list. +Other details of [project governance](http://docs.opentripplanner.org/en/dev-2.x/Governance/) can be +found in the main documentation. ## OTP Ecosystem - - [awesome-transit](https://github.com/CUTR-at-USF/awesome-transit) Community list of transit APIs, apps, datasets, research, and software. +- [awesome-transit](https://github.com/CUTR-at-USF/awesome-transit) Community list of transit APIs, + apps, datasets, research, and software. diff --git a/docs/Basic-Tutorial.md b/docs/Basic-Tutorial.md index 36c31f11efc..717fe99a67e 100644 --- a/docs/Basic-Tutorial.md +++ b/docs/Basic-Tutorial.md @@ -1,23 +1,51 @@ # OpenTripPlanner Basic Tutorial -This page should allow you to set up and test your own OTP2 server. If all goes well it should only take a few minutes! +This page should allow you to set up and test your own OTP2 server. If all goes well it should only +take a few minutes! ## Get Java -As a Java program, OTP must be run within a Java virtual machine (JVM), which is provided as part of the Java runtime (JRE) or Java development kit (JDK). OTP2 is compatible with Java 17 or later. We recommend running on Java 17 rather than a later version, as it is a long-term support release. Run `java -version` to check that you have version 17 or newer of the JVM installed. If you do not, you will need to install a recent OpenJDK or Oracle Java package for your operating system. +As a Java program, OTP must be run within a Java virtual machine (JVM), which is provided as part of +the Java runtime (JRE) or Java development kit (JDK). OTP2 is compatible with Java 17 or later. We +recommend running on Java 17 rather than a later version, as it is a long-term support release. +Run `java -version` to check that you have version 17 or newer of the JVM installed. If you do not, +you will need to install a recent OpenJDK or Oracle Java package for your operating system. ## Get OTP -OpenTripPlanner is written in Java and distributed as a single runnable JAR file. This is a "shaded" JAR containing all other libraries needed for OTP to work, and is available from the Maven Central 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 for the 2.1 release](https://repo1.maven.org/maven2/org/opentripplanner/otp/2.1.0/), and download the [file whose name ends with `shaded.jar`](https://repo1.maven.org/maven2/org/opentripplanner/otp/2.1.0/otp-2.1.0-shaded.jar). +OpenTripPlanner is written in Java and distributed as a single runnable JAR file. This is a "shaded" +JAR containing all other libraries needed for OTP to work, and is available from the Maven Central +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 for the 2.1 release](https://repo1.maven.org/maven2/org/opentripplanner/otp/2.1.0/), +and download +the [file whose name ends with `shaded.jar`](https://repo1.maven.org/maven2/org/opentripplanner/otp/2.1.0/otp-2.1.0-shaded.jar) +. -You may also want to get your own copy of the OTP source code and [build a bleeding edge development JAR from scratch](Getting-OTP.md), especially if you plan to do some development yourself. In that case, check out the branch `dev-2.x`. +You may also want to get your own copy of the OTP source code +and [build a bleeding edge development JAR from scratch](Getting-OTP.md), especially if you plan to +do some development yourself. In that case, check out the branch `dev-2.x`. ## Get some data ### GTFS for Transit Schedules and Stops -First you'll need GTFS data to build a transit network. There's an excellent description of the GTFS format [here](http://gtfs.org/). Transport agencies throughout the world provide GTFS schedules to the public. Transitland has a -[registry of feeds](https://transit.land/feed-registry) and [TransitFeeds](http://transitfeeds.com/) also provides an extensive catalog. The best option is often to simply fetch the data directly from a transit operator or agency. If you know of a feed you want to work with, download it and put it in an empty directory you have created for your OTP instance such as `/home/username/otp` on Linux, `/Users/username/otp` on MacOS, or `C:\Users\username\otp` on Windows. For OTP2 to detect a GTFS file, **its name must end in `.zip` and must contain the letters 'gtfs'**. We often use the convention of saving GTFS files with names ending in `.gtfs.zip` which meets both these criteria, reflecting the fact that a GTFS feed is just a ZIP file containing a specific set of files. If you don't have a particular feed in mind, the one for Portland, Oregon's TriMet agency is a good option. It is available at [this URL](http://developer.trimet.org/schedule/gtfs.zip). This is a moderate-sized input of good quality (TriMet initiated OTP development and helped develop the GTFS format). On Linux, this could be done on the command line as follows: +First you'll need GTFS data to build a transit network. There's an excellent description of the GTFS +format [here](http://gtfs.org/). Transport agencies throughout the world provide GTFS schedules to +the public. Transitland has a +[registry of feeds](https://transit.land/feed-registry) and [TransitFeeds](http://transitfeeds.com/) +also provides an extensive catalog. The best option is often to simply fetch the data directly from +a transit operator or agency. If you know of a feed you want to work with, download it and put it in +an empty directory you have created for your OTP instance such as `/home/username/otp` on +Linux, `/Users/username/otp` on MacOS, or `C:\Users\username\otp` on Windows. For OTP2 to detect a +GTFS file, **its name must end in `.zip` and must contain the letters 'gtfs'**. We often use the +convention of saving GTFS files with names ending in `.gtfs.zip` which meets both these criteria, +reflecting the fact that a GTFS feed is just a ZIP file containing a specific set of files. If you +don't have a particular feed in mind, the one for Portland, Oregon's TriMet agency is a good option. +It is available at [this URL](http://developer.trimet.org/schedule/gtfs.zip). This is a +moderate-sized input of good quality (TriMet initiated OTP development and helped develop the GTFS +format). On Linux, this could be done on the command line as follows: $ cd /home/username $ mkdir otp @@ -26,70 +54,129 @@ First you'll need GTFS data to build a transit network. There's an excellent des ### OSM for Streets -You'll also need OpenStreetMap data to build a road network for walking, cycling, and driving. [OpenStreetMap](https://www.openstreetmap.org/) is a global collaborative map database that rivals or surpasses the quality of commercial maps in many locations. Several services extract smaller geographic regions from this database. Interline Technologies maintains a collection of [extracts updated daily for urban areas around the world](https://www.interline.io/osm/extracts/). [Geofabrik](http://download.geofabrik.de/) provides extracts for larger areas like countries or states, from which you can prepare your own smaller bounding-box extracts using [Osmosis](http://wiki.openstreetmap.org/wiki/Osmosis#Extracting_bounding_boxes), [osmconvert](http://wiki.openstreetmap.org/wiki/Osmconvert#Applying_Geographical_Borders), or (our favorite) [Osmium-Tool](https://osmcode.org/osmium-tool/manual.html#creating-geographic-extracts). OSM data can be delivered as XML or in the more compact binary PBF format. OpenTripPlanner consumes only PBF because it's smaller and more efficient. - -Download OSM PBF data for the same geographic region as your GTFS feed, and place this PBF file in the same directory you created for the OSM data. If you are using the TriMet GTFS feed, you could download the [Geofabrik extract for the US state of Oregon](http://download.geofabrik.de/north-america/us/oregon.html), then further trim that to just the [TriMet service area](https://trimet.org/pdfs/taxinfo/trimetdistrictboundary.pdf) using the bounding box switch of one of the above tools. On Linux or MacOS you could do that as follows: +You'll also need OpenStreetMap data to build a road network for walking, cycling, and +driving. [OpenStreetMap](https://www.openstreetmap.org/) is a global collaborative map database that +rivals or surpasses the quality of commercial maps in many locations. Several services extract +smaller geographic regions from this database. Interline Technologies maintains a collection +of [extracts updated daily for urban areas around the world](https://www.interline.io/osm/extracts/) +. [Geofabrik](http://download.geofabrik.de/) provides extracts for larger areas like countries or +states, from which you can prepare your own smaller bounding-box extracts +using [Osmosis](http://wiki.openstreetmap.org/wiki/Osmosis#Extracting_bounding_boxes) +, [osmconvert](http://wiki.openstreetmap.org/wiki/Osmconvert#Applying_Geographical_Borders), or (our +favorite) [Osmium-Tool](https://osmcode.org/osmium-tool/manual.html#creating-geographic-extracts). +OSM data can be delivered as XML or in the more compact binary PBF format. OpenTripPlanner consumes +only PBF because it's smaller and more efficient. + +Download OSM PBF data for the same geographic region as your GTFS feed, and place this PBF file in +the same directory you created for the OSM data. If you are using the TriMet GTFS feed, you could +download +the [Geofabrik extract for the US state of Oregon](http://download.geofabrik.de/north-america/us/oregon.html) +, then further trim that to just +the [TriMet service area](https://trimet.org/pdfs/taxinfo/trimetdistrictboundary.pdf) using the +bounding box switch of one of the above tools. On Linux or MacOS you could do that as follows: $ cd /home/username $ wget http://download.geofabrik.de/north-america/us/oregon-latest.osm.pbf $ osmconvert oregon-latest.osm.pbf -b=-123.043,45.246,-122.276,45.652 --complete-ways -o=portland.pbf $ mv portland.pbf otp -We find [this tool](https://boundingbox.klokantech.com/) useful for determining the geographic coordinates of bounding boxes. The CSV option in that tool produces exactly the format expected by the `osmconvert -b` switch. The `--complete-ways` switch is important to handle roads that cross outside your bounding box. +We find [this tool](https://boundingbox.klokantech.com/) useful for determining the geographic +coordinates of bounding boxes. The CSV option in that tool produces exactly the format expected by +the `osmconvert -b` switch. The `--complete-ways` switch is important to handle roads that cross +outside your bounding box. -If you have extracted a smaller PBF file from a larger region, be sure to put only your extract (not the original larger file) in the directory with your GTFS data. Otherwise OTP will try to load both the original file and the extract in a later step. See the [page on preparing OSM data](Preparing-OSM.md) for additional information and example commands for cropping and filtering OSM data. +If you have extracted a smaller PBF file from a larger region, be sure to put only your extract (not +the original larger file) in the directory with your GTFS data. Otherwise OTP will try to load both +the original file and the extract in a later step. See +the [page on preparing OSM data](Preparing-OSM.md) for additional information and example commands +for cropping and filtering OSM data. ## Starting OTP -A typical command to start OTP looks like `java -Xmx2G -jar otp.shaded.jar `. The - `-Xmx` parameter sets the limit on how much memory OTP is allowed to consume. GTFS and OSM data sets are often very large, and OTP is relatively memory-hungry. You will need at least 1GB of memory when working with the Portland TriMet data set, and several gigabytes for larger inputs. If you have - sufficient memory in your computer, set this to a couple of gigabytes (e.g. `-Xmx2G`). Java uses a [garbage collection](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)) approach to memory management, which requires some "breathing room" to efficiently operate. Without sufficient free memory OTP can grind to a halt. [VisualVM](https://visualvm.github.io) is a good way to inspect Java memory usage, especially with the [VisualGC plugin](https://visualvm.github.io/plugins.html). +A typical command to start OTP looks like `java -Xmx2G -jar otp.shaded.jar `. The +`-Xmx` parameter sets the limit on how much memory OTP is allowed to consume. GTFS and OSM data sets +are often very large, and OTP is relatively memory-hungry. You will need at least 1GB of memory when +working with the Portland TriMet data set, and several gigabytes for larger inputs. If you have +sufficient memory in your computer, set this to a couple of gigabytes (e.g. `-Xmx2G`). Java uses +a [garbage collection](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)) approach +to memory management, which requires some "breathing room" to efficiently operate. Without +sufficient free memory OTP can grind to a halt. [VisualVM](https://visualvm.github.io) is a good way +to inspect Java memory usage, especially with +the [VisualGC plugin](https://visualvm.github.io/plugins.html). ## Building Graphs -There are two main phases to preparing and deploying an OTP server. The first is to analyze the GTFS, OSM and any other inputs (such as elevation data) and build a representation of the transportation network. Following mathematical terminology we call this a ['graph'](http://en.wikipedia.org/wiki/Graph_%28mathematics%29), and refer to this phase as "graph building". The second phase is to start a server that provides trip planning and other API services for this graph. - -It is possible to save the graph to a file on disk after the first phase, then load the graph from the file in the second phase. This allows restarting the server or starting multiple instances of the server without repeating the often time-consuming process of building the graph. It is also possible to split the graph building process into separate OSM and GTFS stages for similar reasons: to allow reusing results from slow processes, such as applying elevation data to streets. These different options are controlled with command line switches, and will be described in more detail below and in other tutorials. +There are two main phases to preparing and deploying an OTP server. The first is to analyze the +GTFS, OSM and any other inputs (such as elevation data) and build a representation of the +transportation network. Following mathematical terminology we call this +a ['graph'](http://en.wikipedia.org/wiki/Graph_%28mathematics%29), and refer to this phase as "graph +building". The second phase is to start a server that provides trip planning and other API services +for this graph. -## Simple One-step Server +It is possible to save the graph to a file on disk after the first phase, then load the graph from +the file in the second phase. This allows restarting the server or starting multiple instances of +the server without repeating the often time-consuming process of building the graph. It is also +possible to split the graph building process into separate OSM and GTFS stages for similar reasons: +to allow reusing results from slow processes, such as applying elevation data to streets. These +different options are controlled with command line switches, and will be described in more detail +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: +## Simple One-step Server +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.1.0-shaded.jar --build --serve /home/username/otp - where `/home/username/otp` should be the directory where you put your configuration and input files. - -If you're using the Portland input data, the graph build operation should take about one minute to complete, and then you'll see a `Grizzly server running` message. At this point you have an OpenTripPlanner server running locally and can open [http://localhost:8080/](http://localhost:8080/) in a web browser. You should be presented with a Javascript client application that will interact with your local OpenTripPlanner instance. + +If you're using the Portland input data, the graph build operation should take about one minute to +complete, and then you'll see a `Grizzly server running` message. At this point you have an +OpenTripPlanner server running locally and can open [http://localhost:8080/](http://localhost:8080/) +in a web browser. You should be presented with a Javascript client application that will interact +with your local OpenTripPlanner instance. This map-based user interface is in fact sending HTTP GET requests to the OTP server running on your local machine. It can be informative to watch the HTTP requests and responses being generated using -the developer tools in your web browser. OTP's built-in web server will run by default on ports -8080 and 8081 for HTTP and HTTPS respectively. If by any chance some other software is already using one or both of those port numbers, you can specify different port numbers with switches like `--port 8801 --securePort 8802`. - +the developer tools in your web browser. OTP's built-in web server will run by default on ports 8080 +and 8081 for HTTP and HTTPS respectively. If by any chance some other software is already using one +or both of those port numbers, you can specify different port numbers with switches +like `--port 8801 --securePort 8802`. ## Saving a Graph -If you want speed up the process of repeatedly starting up a server with the same graph, you can build a graph from street and transit data then save it to a file using the `--build` and `--save` 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: +If you want speed up the process of repeatedly starting up a server with the same graph, you can +build a graph from street and transit data then save it to a file using the `--build` and `--save` +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.1.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: +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.1.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 server. Accordingly, you may want to perform the build on one machine (e.g. a throw-away cloud instance with more memory or compute capacity), then copy the resulting graph file to one or more smaller machines to serve the API. +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 +server. Accordingly, you may want to perform the build on one machine (e.g. a throw-away cloud +instance with more memory or compute capacity), then copy the resulting graph file to one or more +smaller machines to serve the API. ## Layering GTFS onto OSM -Building the street graph (especially with elevation data) can take a long time. It is common for transit data to change more frequently than street data, so it can be convenient to build the street graph once, and then layer transit data on top of the streets to make the final graph. +Building the street graph (especially with elevation data) can take a long time. It is common for +transit data to change more frequently than street data, so it can be convenient to build the street +graph once, and then layer transit data on top of the streets to make the final graph. -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: +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.1.0-shaded.jar --buildStreet . -Then, to build a graph layering transit data on top of the saved street graph (built using the previous command): +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.1.0-shaded.jar --loadStreet --save . @@ -97,13 +184,16 @@ Finally, the server can be started using the `--load` parameter: $ java -Xmx2G -jar otp-2.1.0-shaded.jar --load . - ## Command Line Switches -The flow diagram below summarizes all the command line switches used in the above examples, and how they control which actions are taken when OTP starts up. +The flow diagram below summarizes all the command line switches used in the above examples, and how +they control which actions are taken when OTP starts up. ![Command-Line-Parameter-Flow](images/cli-flow.svg) -You must use at least one of the required parameters: `--load`, `--loadStreet`, `--build`, `--buildStreet`. A _required_ parameter may imply other parameters when the flow allows for no other choice. For example, `--load` implies `--serve`, so `--serve` is not necessary and has no additional effect when used together with `--load`. +You must use at least one of the required parameters: `--load`, `--loadStreet`, `--build` +, `--buildStreet`. A _required_ parameter may imply other parameters when the flow allows for no +other choice. For example, `--load` implies `--serve`, so `--serve` is not necessary and has no +additional effect when used together with `--load`. You can run the OTP .jar file with the `--help` option for a full list of command line parameters. diff --git a/docs/Bibliography.md b/docs/Bibliography.md index d5ef8f2f897..6129f7fb0d2 100644 --- a/docs/Bibliography.md +++ b/docs/Bibliography.md @@ -1,146 +1,185 @@ # Routing Bibliography -This is a list of articles, dissertations, and books that have inspired and informed both the existing OTP routing engine and some ongoing experiments. - -OTP1 uses a single time-dependent (as opposed to time-expanded) graph that contains both street and transit networks. Walk-only and bicycle-only trips are generally planned using the A-star algorithm with a Euclidean heuristic. Walk+Transit or Bike+Transit trips are planned using A-star with the Tung-Chew heuristic (i.e. a graph grown backward from the destination providing a lower bound on aggregate weight) for queue ordering. For speed reasons we are performing single-variable generalized cost optimization, which is not ideal. We should be performing Pareto optimization on at least two variables (generalized cost and time). - -OTP2 splits the search into three segments: access from the origin to transit stops, egress from transit stops to the destination, and transit service connecting the two. For the transit segment, OTP2 uses the Multi-criteria Range Raptor algorithm. For the access and egress searches it uses the same approach as OTP1. Both splitting the search into three parts and use of a table-scanning algorithm like Raptor improve OTP2's performance significantly while increasing result quality by producing true Pareto-optimal sets of results. +This is a list of articles, dissertations, and books that have inspired and informed both the +existing OTP routing engine and some ongoing experiments. + +OTP1 uses a single time-dependent (as opposed to time-expanded) graph that contains both street and +transit networks. Walk-only and bicycle-only trips are generally planned using the A-star algorithm +with a Euclidean heuristic. Walk+Transit or Bike+Transit trips are planned using A-star with the +Tung-Chew heuristic (i.e. a graph grown backward from the destination providing a lower bound on +aggregate weight) for queue ordering. For speed reasons we are performing single-variable +generalized cost optimization, which is not ideal. We should be performing Pareto optimization on at +least two variables (generalized cost and time). + +OTP2 splits the search into three segments: access from the origin to transit stops, egress from +transit stops to the destination, and transit service connecting the two. For the transit segment, +OTP2 uses the Multi-criteria Range Raptor algorithm. For the access and egress searches it uses the +same approach as OTP1. Both splitting the search into three parts and use of a table-scanning +algorithm like Raptor improve OTP2's performance significantly while increasing result quality by +producing true Pareto-optimal sets of results. ## Algorithms used in OTP2 but not OTP1 - Delling, Pajor, Werneck. Round-Based Public Transit Routing (2012) -
This is a tabular approach to routing in public transit networks that does not use an (explicit) graph. It is simpler and can outperform classic graph algorithms. -
http://research.microsoft.com/pubs/156567/raptor_alenex.pdf +
This is a tabular approach to routing in public transit networks that does not use an ( + explicit) graph. It is simpler and can outperform classic graph algorithms. +
http://research.microsoft.com/pubs/156567/raptor_alenex.pdf -- Delling, Dibbelt, and Pajor. Fast and Exact Public Transit Routing with Restricted Pareto Sets (2019) -
Describes the heuristic used in OTP2 to eliminate options early when they are known to become non-optimal before they reach the destination. -
https://epubs.siam.org/doi/pdf/10.1137/1.9781611975499.5 +- Delling, Dibbelt, and Pajor. Fast and Exact Public Transit Routing with Restricted Pareto Sets ( + 2019) +
Describes the heuristic used in OTP2 to eliminate options early when they are known to become + non-optimal before they reach the destination. +
https://epubs.siam.org/doi/pdf/10.1137/1.9781611975499.5 -## Techniques used in or influencing OTP1 and OTP2 +## Techniques used in or influencing OTP1 and OTP2 -### General Background +### General Background - Bast, Hannah. Car or public transport -- two worlds. (2009)
-Explains how car routing is different from schedule-based public transport routing.
-http://www.mpi-inf.mpg.de/~bast/papers/car_or_public_transport.pdf + Explains how car routing is different from schedule-based public transport routing.
+ http://www.mpi-inf.mpg.de/~bast/papers/car_or_public_transport.pdf - Delling, Daniel. Engineering and augmenting route planning algorithms. (2009, dissertation) -
Overview, including time-dependent and Pareto shortest paths. -
http://i11www.ira.uka.de/extra/publications/d-earpa-09.pdf +
Overview, including time-dependent and Pareto shortest paths. +
http://i11www.ira.uka.de/extra/publications/d-earpa-09.pdf - Delling, Sanders, Schultes, and Wagner. Engineering Route-Planning Algorithms. (2009) -
Overview. -
http://i11www.ira.uka.de/extra/publications/dssw-erpa-09.pdf +
Overview. +
http://i11www.ira.uka.de/extra/publications/dssw-erpa-09.pdf ### Path Search Speedup Techniques - Delling and Wagner. Time-Dependent Route Planning. (2009) -
Overview. -
http://i11www.iti.uni-karlsruhe.de/extra/publications/dw-tdrp-09.pdf +
Overview. +
http://i11www.iti.uni-karlsruhe.de/extra/publications/dw-tdrp-09.pdf - Delling and Wagner. Landmark-Based Routing in Dynamic Graphs. (2008) -
http://i11www.ira.uka.de/extra/publications/dw-lbrdg-07.pdf +
http://i11www.ira.uka.de/extra/publications/dw-lbrdg-07.pdf -- Bauer, Delling, Sanders, Schultes, and Wagner. Combining Hierarchical and Goal-Directed -Speed-Up Techniques for Dijkstra’s Algorithm. (2008) -
http://algo2.iti.kit.edu/download/bdsssw-chgds-10.pdf +- Bauer, Delling, Sanders, Schultes, and Wagner. Combining Hierarchical and Goal-Directed Speed-Up + Techniques for Dijkstra’s Algorithm. (2008) +
http://algo2.iti.kit.edu/download/bdsssw-chgds-10.pdf - Bauer and Delling. SHARC: Fast and Robust Unidirectional Routing. (2009) -
**SH** ortcuts + **ARC** flags. Can be combined with ALT. -
http://www.siam.org/proceedings/alenex/2008/alx08_02bauerr.pdf +
**SH** ortcuts + **ARC** flags. Can be combined with ALT. +
http://www.siam.org/proceedings/alenex/2008/alx08_02bauerr.pdf - Delling, Daniel. Time-Dependent SHARC-Routing. (2008) -
http://i11www.iti.uni-karlsruhe.de/extra/publications/d-tdsr-09.pdf +
http://i11www.iti.uni-karlsruhe.de/extra/publications/d-tdsr-09.pdf -- Goldberg, Kaplan, and Werneck. Reach for A∗: Efficient Point-to-Point Shortest Path Algorithms. (2005) -
http://avglab.com/andrew/pub/msr-tr-2005-132.pdf +- Goldberg, Kaplan, and Werneck. Reach for A∗: Efficient Point-to-Point Shortest Path Algorithms. + (2005) +
http://avglab.com/andrew/pub/msr-tr-2005-132.pdf ### Multi-objective Pareto Shortest Paths -- Das and Dennis. Drawbacks of minimizing weighted sums of objectives for Pareto set generation in multicriteria optimization problems. (1997) +- Das and Dennis. Drawbacks of minimizing weighted sums of objectives for Pareto set generation in + multicriteria optimization problems. (1997) -- Müller-Hannemann and Schnee. Finding All Attractive Train Connections by Multi-criteria Pareto Search. (2007) -
Deutsche Bahn information system. Does not account for on-street travel. +- Müller-Hannemann and Schnee. Finding All Attractive Train Connections by Multi-criteria Pareto + Search. (2007) +
Deutsche Bahn information system. Does not account for on-street travel. - Mandow & Pérez de la Cruz. A New Approach to Multiobjective A* Search. (2005) -
NAMOA* -
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.97.8780&rep=rep1&type=pdf +
NAMOA* +
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.97.8780&rep=rep1&type=pdf - Mandow & Pérez de la Cruz. Multiobjective A* search with consistent heuristics. (2008) -
NAMOA* +
NAMOA* -- Machuca, Mandow and Pérez de la Cruz. Evaluation of Heuristic Functions for Bicriterion Shortest Path Problems. (2009) -
Evaluates heuristics from Tung & Chew (1992) versus lexicographical ordering of priority queue. -
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.160.4715&rep=rep1&type=pdf +- Machuca, Mandow and Pérez de la Cruz. Evaluation of Heuristic Functions for Bicriterion Shortest + Path Problems. (2009) +
Evaluates heuristics from Tung & Chew (1992) versus lexicographical ordering of priority + queue. +
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.160.4715&rep=rep1&type=pdf - Perny and Spanjaard. Near Admissible Algorithms for Multiobjective Search. (2009) -
Discusses relaxed Pareto dominance (Epsilon-dominance) and its use in Multi-objective A*. This a scheme for approximating the entire pareto-optimal solution set that allows time and space complexity polynomial in the number of nodes. -
http://www-desir.lip6.fr/publications/pub_1052_1_ECAI08.pdf +
Discusses relaxed Pareto dominance (Epsilon-dominance) and its use in Multi-objective A*. This + a scheme for approximating the entire pareto-optimal solution set that allows time and space + complexity polynomial in the number of nodes. +
http://www-desir.lip6.fr/publications/pub_1052_1_ECAI08.pdf - Tung and Chew. A multicriteria Pareto-optimal path algorithm. (1992) - Delling and Wagner. Pareto Paths with SHARC. (2009) -
http://i11www.iti.uni-karlsruhe.de/extra/publications/dw-pps-09.pdf +
http://i11www.iti.uni-karlsruhe.de/extra/publications/dw-pps-09.pdf ### Resource-constrained Routing -- Dumitrescu & Boland. Improved Preprocessing, Labeling and Scaling Algorithms for the Weight-Constrained Shortest Path Problem. (2003) -
Comparison of scaling and label-setting methods. +- Dumitrescu & Boland. Improved Preprocessing, Labeling and Scaling Algorithms for the + Weight-Constrained Shortest Path Problem. (2003) +
Comparison of scaling and label-setting methods. - Ziegelmann, Mark. Constrained Shortest Paths and Related Problems. (2001, dissertation) -
http://scidok.sulb.uni-saarland.de/volltexte/2004/251/pdf/MarkZiegelmann_ProfDrKurtMehlhorn.pdf +
http://scidok.sulb.uni-saarland.de/volltexte/2004/251/pdf/MarkZiegelmann_ProfDrKurtMehlhorn.pdf ### Contraction and Transfer Patterns -- Geisberger, Robert. Contraction Hierarchies: Faster and Simpler Hierarchical Routing in Road Networks. (2008, dissertation) -
http://algo2.iti.kit.edu/documents/routeplanning/geisberger_dipl.pdf +- Geisberger, Robert. Contraction Hierarchies: Faster and Simpler Hierarchical Routing in Road + Networks. (2008, dissertation) +
http://algo2.iti.kit.edu/documents/routeplanning/geisberger_dipl.pdf - Geisberger, Robert. Contraction of Timetable Networks with Realistic Tranfers (2010) -
Introduces the "Station Model Graph". -
http://algo2.iti.kit.edu/download/time_table_ch.pdf +
Introduces the "Station Model Graph". +
http://algo2.iti.kit.edu/download/time_table_ch.pdf -- Bast, Carlsson, Eigenwillig, Geisberger Harrelson, Raychev, and Viger. Fast Routing in Very Large Public Transportation Networks Using Transfer Patterns. (2010) -
http://ad.informatik.uni-freiburg.de/files/transferpatterns.pdf/at_download/file +- Bast, Carlsson, Eigenwillig, Geisberger Harrelson, Raychev, and Viger. Fast Routing in Very Large + Public Transportation Networks Using Transfer Patterns. (2010) +
http://ad.informatik.uni-freiburg.de/files/transferpatterns.pdf/at_download/file ### Timetable-based routing - Schulz, Frank. Timetable Information and Shortest Paths. (2005, dissertation) -
Excellent reference. -
http://d-nb.info/1001586921/34 +
Excellent reference. +
http://d-nb.info/1001586921/34 ### ALT and Metric Embeddings - Goldberg and Werneck. Computing Point-to-Point Shortest Paths from External Memory. (2005) -
Introduced the ALT algorithm. -
http://www.cs.princeton.edu/courses/archive/spring06/cos423/Handouts/GW05.pdf +
Introduced the ALT algorithm. +
http://www.cs.princeton.edu/courses/archive/spring06/cos423/Handouts/GW05.pdf -- Linial, London, and Rabinovich. The Geometry of Graphs and Some of its Algorithmic Applications. (1995) -
http://pdf.aminer.org/000/798/423/the_geometry_of_graphs_and_some_of_its_algorithmic_applications.pdf +- Linial, London, and Rabinovich. The Geometry of Graphs and Some of its Algorithmic Applications. ( + 1995) +
http://pdf.aminer.org/000/798/423/the_geometry_of_graphs_and_some_of_its_algorithmic_applications.pdf -- Hjaltason and Samet. Contractive Embedding Methods for Similarity Searching in Metric Spaces. (2000) -
http://www.cs.umd.edu/~hjs/pubs/metricpruning.pdf +- Hjaltason and Samet. Contractive Embedding Methods for Similarity Searching in Metric Spaces. ( + 2000) +
http://www.cs.umd.edu/~hjs/pubs/metricpruning.pdf -- Potamias, Bonchi, Castillo, and Gionis. Fast Shortest Path Distance Estimation in Large Networks. (2009) -
Briefly discusses the connection between landmark routing and more general research on metric embeddings. -
http://dcommon.bu.edu/xmlui/bitstream/handle/2144/1727/2009-004-shortest-distance-estimation.pdf +- Potamias, Bonchi, Castillo, and Gionis. Fast Shortest Path Distance Estimation in Large + Networks. (2009) +
Briefly discusses the connection between landmark routing and more general research on metric + embeddings. +
http://dcommon.bu.edu/xmlui/bitstream/handle/2144/1727/2009-004-shortest-distance-estimation.pdf ### Calibration and Implementation Details - Wardman, Mark. Public Transport Values of Time. (2004) -
http://eprints.whiterose.ac.uk/2062/1/ITS37_WP564_uploadable.pdf +
http://eprints.whiterose.ac.uk/2062/1/ITS37_WP564_uploadable.pdf -- A.M. El-Geneidy, K.J. Krizek, M.J. Iacono. Predicting bicycle travel speeds along different facilities using GPS data: a proof of concept model. (2007)
Proceedings of the 86th Annual Meeting of the Transportation Research Board, Compendium of Papers, TRB, Washington, D.C., USA (CD-ROM) +- A.M. El-Geneidy, K.J. Krizek, M.J. Iacono. Predicting bicycle travel speeds along different + facilities using GPS data: a proof of concept model. (2007)
Proceedings of the 86th Annual + Meeting of the Transportation Research Board, Compendium of Papers, TRB, Washington, D.C., USA ( + CD-ROM) - Chen, Chowdhury, Roche, Ramachandran, Tong. Priority Queues and Dijkstra’s Algorithm. -
Summary: Despite better theoretical complexity for Fibonacci heaps, it is often as good or better to use a binary heap as a priority queue when doing path searches. -
http://www.cs.utexas.edu/users/shaikat/papers/TR-07-54.pdf +
Summary: Despite better theoretical complexity for Fibonacci heaps, it is often as good or + better to use a binary heap as a priority queue when doing path searches. +
http://www.cs.utexas.edu/users/shaikat/papers/TR-07-54.pdf ### Post-Dijkstra Public Transit Routing - Dibbelt, Pajor, Strasser, Wagner. Intriguingly Simple and Fast Transit Routing (2013). -
Introduces the Connection Scan Algorithm (CSA). -
http://www.ecompass-project.eu/sites/default/files/ECOMPASS-TR-021.pdf - -- Delling, Katz, and Pajor. Parallel computation of best connections in public transportation networks (2012). -
"In this work, we present a novel algorithm for the one-to-all profile-search problem in public transportation networks. It answers the question for all fastest connections between a given station S and any other station at any time of the day in a single query... two interesting questions arise for time-dependent route planning: compute the best connection for a given departure time and the computation of all best connections during a given time interval (e. g., a whole day). The former is called a time-query, while the latter is called a profile-query." -
http://www.ecompass-project.eu/sites/default/files/ECOMPASS-TR-021.pdf +
Introduces the Connection Scan Algorithm (CSA). +
http://www.ecompass-project.eu/sites/default/files/ECOMPASS-TR-021.pdf + +- Delling, Katz, and Pajor. Parallel computation of best connections in public transportation + networks (2012). +
"In this work, we present a novel algorithm for the one-to-all profile-search problem in + public transportation networks. It answers the question for all fastest connections between a + given station S and any other station at any time of the day in a single query... two interesting + questions arise for time-dependent route planning: compute the best connection for a given + departure time and the computation of all best connections during a given time interval (e. g., a + whole day). The former is called a time-query, while the latter is called a profile-query." +
http://www.ecompass-project.eu/sites/default/files/ECOMPASS-TR-021.pdf diff --git a/docs/BuildConfiguration.md b/docs/BuildConfiguration.md index fc6a6a29f38..0a477418a2f 100644 --- a/docs/BuildConfiguration.md +++ b/docs/BuildConfiguration.md @@ -1,6 +1,8 @@ # Graph Build Configuration -This table lists all the JSON properties that can be defined in a `build-config.json` file. These will be stored in the graph itself, and affect any server that subsequently loads that graph. Sections follow that describe particular settings in more depth. +This table lists all the JSON properties that can be defined in a `build-config.json` file. These +will be stored in the graph itself, and affect any server that subsequently loads that graph. +Sections follow that describe particular settings in more depth. | config key | description | value type | value default | notes | |------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------|-------------------------|-------------------------------------------------------------------------------------------| @@ -39,19 +41,26 @@ This table lists all the JSON properties that can be defined in a `build-config. | `transitServiceEnd` | Limit the import of transit services to the given *end* date. *Inclusive*. Use an absolute date or a period relative to the day the graph is build. | date or period | P3Y | _2022‑12‑31, P1Y6M10D, P12W_ | | `writeCachedElevations` | If true, writes the calculated elevation data. | boolean | false | see [Elevation Data Calculation Optimizations](#elevation-data-calculation-optimizations) | -This list of parameters in defined in the [BuildConfig.java](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/standalone/config/BuildConfig.java). - +This list of parameters in defined in +the [BuildConfig.java](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/standalone/config/BuildConfig.java) +. ## Storage -The storage section of `build-config.json` allows you to override the default behavior of scanning for input files in the [base directory](Configuration.md#Base Directory) and writing output files (such as the graph and error reports) to that same directory. In OTP2 it is now possible to read and write data located outside the local filesystem (including cloud storage services) or at various different locations around the local filesystem. - -If your OTP instance is running on a cloud compute service, you may get significantly faster start-up and graph build times if you use the cloud storage directly instead of copying the files back and forth to cloud server instances. This also simplifies the deployment process. +The storage section of `build-config.json` allows you to override the default behavior of scanning +for input files in the [base directory](Configuration.md#Base Directory) and writing output files ( +such as the graph and error reports) to that same directory. In OTP2 it is now possible to read and +write data located outside the local filesystem (including cloud storage services) or at various +different locations around the local filesystem. +If your OTP instance is running on a cloud compute service, you may get significantly faster +start-up and graph build times if you use the cloud storage directly instead of copying the files +back and forth to cloud server instances. This also simplifies the deployment process. ### Specifying Data Sources -Here is a summary of the configuration keys that can be nested inside the`storage` property of the build-config JSON to specify input and output data sources: +Here is a summary of the configuration keys that can be nested inside the`storage` property of the +build-config JSON to specify input and output data sources: | config key | description | value type | value default | |-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|---------------| @@ -80,9 +89,9 @@ For example, this configuration could be used to load GTFS and OSM inputs from G The Google Storage system will inherit the permissions of the server it's running on within Google Cloud. It is also possible to supply credentials in this configuration file (see example below). -Note that when files are specified with URIs in this configuration, the file types do not need to -be inferred from the file names, so these GTFS files can have any names - there is no requirement -that they have the letters "gtfs" in them. +Note that when files are specified with URIs in this configuration, the file types do not need to be +inferred from the file names, so these GTFS files can have any names - there is no requirement that +they have the letters "gtfs" in them. The default behavior of scanning the base directory for inputs is overridden independently for each file type. So in the above configuration, GTFS and OSM will be loaded from Google Cloud Storage, but @@ -90,10 +99,10 @@ OTP2 will still scan the base directory for all other types such as DEM files. S array for a particular file type will ensure that no inputs of that type are loaded, including by local directory scanning. -See the comments in the source code of class [StorageConfig.java](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/standalone/config/StorageConfig.java) +See the comments in the source code of +class [StorageConfig.java](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/standalone/config/StorageConfig.java) for an up-to-date detailed description of each config parameter. - ### Local Filename Patterns When scanning the base directory for inputs, each file's name is checked against patterns to detect @@ -114,7 +123,6 @@ seeking within files to guess what they are. Therefore, like all other file type detected from a filename pattern. It is not sufficient to look for the `.zip` extension because Netex data is also often supplied in a ZIP file. - ### Storage example ```JSON @@ -133,20 +141,33 @@ Netex data is also often supplied in a ZIP file. } ``` - ## Limit the transit service period -The properties `transitServiceStart` and `transitServiceEnd` can be used to limit the service dates. This affects both GTFS service calendars and dates. The service calendar is reduced and dates outside the period are dropped. OTP2 will compute a transit schedule for every day for which it can find at least one trip running. On the other hand, OTP will waste resources if a service end date is *unbounded* or very large (`9999-12-31`). To avoid this, limit the OTP service period. Also, if you provide a service with multiple feeds they may have different service end dates. To avoid inconsistent results, the period can be limited, so all feeds have data for the entire period. The default is to use a period of 1 year before, and 3 years after the day the graph is built. Limiting the period will *not* improve the search performance, but OTP will build faster and load faster in most cases. - -The `transitServiceStart` and `transitServiceEnd` parameters are set using an absolute date like `2020-12-31` or a period like `P1Y6M5D` relative to the graph build date. Negative periods is used to specify dates in the past. The period is computed using the system time-zone, not the feed time-zone. Also, remember that the service day might be more than 24 hours. So be sure to include enough slack to account for the this. Setting the limits too wide have very little impact and is in general better than trying to be exact. The period and date format follow the ISO 8601 standard. - +The properties `transitServiceStart` and `transitServiceEnd` can be used to limit the service dates. +This affects both GTFS service calendars and dates. The service calendar is reduced and dates +outside the period are dropped. OTP2 will compute a transit schedule for every day for which it can +find at least one trip running. On the other hand, OTP will waste resources if a service end date +is *unbounded* or very large (`9999-12-31`). To avoid this, limit the OTP service period. Also, if +you provide a service with multiple feeds they may have different service end dates. To avoid +inconsistent results, the period can be limited, so all feeds have data for the entire period. The +default is to use a period of 1 year before, and 3 years after the day the graph is built. Limiting +the period will *not* improve the search performance, but OTP will build faster and load faster in +most cases. + +The `transitServiceStart` and `transitServiceEnd` parameters are set using an absolute date +like `2020-12-31` or a period like `P1Y6M5D` relative to the graph build date. Negative periods is +used to specify dates in the past. The period is computed using the system time-zone, not the feed +time-zone. Also, remember that the service day might be more than 24 hours. So be sure to include +enough slack to account for the this. Setting the limits too wide have very little impact and is in +general better than trying to be exact. The period and date format follow the ISO 8601 standard. ## Reaching a subway platform -The ride locations for some modes of transport such as subways and airplanes can be slow to reach from the street. -When planning a trip, we need to allow additional time to reach these locations to properly inform the passenger. For -example, this helps avoid suggesting short bus rides between two subway rides as a way to improve travel time. You can -specify how long it takes to reach a subway platform +The ride locations for some modes of transport such as subways and airplanes can be slow to reach +from the street. When planning a trip, we need to allow additional time to reach these locations to +properly inform the passenger. For example, this helps avoid suggesting short bus rides between two +subway rides as a way to improve travel time. You can specify how long it takes to reach a subway +platform ```JSON // build-config.json @@ -155,30 +176,35 @@ specify how long it takes to reach a subway platform } ``` -Stops in GTFS do not necessarily serve a single transit mode, but in practice this is usually the case. This additional -access time will be added to any stop that is visited by trips on subway routes (GTFS route_type = 1). +Stops in GTFS do not necessarily serve a single transit mode, but in practice this is usually the +case. This additional access time will be added to any stop that is visited by trips on subway +routes (GTFS route_type = 1). -This setting does not generalize well to airplanes because you often need much longer to check in to a flight (2-3 hours -for international flights) than to alight and exit the airport (perhaps 1 hour). Therefore there is currently no -per-mode access time, it is subway-specific. +This setting does not generalize well to airplanes because you often need much longer to check in to +a flight (2-3 hours for international flights) than to alight and exit the airport (perhaps 1 hour). +Therefore there is currently no per-mode access time, it is subway-specific. ## Transferring within stations -Subway systems tend to exist in their own layer of the city separate from the surface, though there are exceptions where -tracks lie right below the street and transfers happen via the surface. In systems where the subway is quite deep -and transfers happen via tunnels, the time required for an in-station transfer is often less than that for a -surface transfer. A proposal was made to provide detailed station pathways in GTFS but it is not in common use. - -One way to resolve this problem is by ensuring that the GTFS feed codes each platform as a separate stop, then -micro-mapping stations in OSM. When OSM data contains a detailed description of walkways, stairs, and platforms within -a station, GTFS stops can be linked to the nearest platform and transfers will happen via the OSM ways, which should -yield very realistic transfer time expectations. This works particularly well in above-ground train stations where -the layering of non-intersecting ways is less prevalent. Here's an example in the Netherlands: - -View Larger Map -When such micro-mapping data is not available, we need to rely on information from GTFS including how stops are grouped -into stations and a table of transfer timings where available. During the graph build, OTP can create preferential -connections between each pair of stops in the same station to favor in-station transfers: +Subway systems tend to exist in their own layer of the city separate from the surface, though there +are exceptions where tracks lie right below the street and transfers happen via the surface. In +systems where the subway is quite deep and transfers happen via tunnels, the time required for an +in-station transfer is often less than that for a surface transfer. A proposal was made to provide +detailed station pathways in GTFS but it is not in common use. + +One way to resolve this problem is by ensuring that the GTFS feed codes each platform as a separate +stop, then micro-mapping stations in OSM. When OSM data contains a detailed description of walkways, +stairs, and platforms within a station, GTFS stops can be linked to the nearest platform and +transfers will happen via the OSM ways, which should yield very realistic transfer time +expectations. This works particularly well in above-ground train stations where the layering of +non-intersecting ways is less prevalent. Here's an example in the Netherlands: + + +View Larger Map +When such micro-mapping data is not available, we need to rely on information from GTFS including +how stops are grouped into stations and a table of transfer timings where available. During the +graph build, OTP can create preferential connections between each pair of stops in the same station +to favor in-station transfers: ```JSON // build-config.json @@ -187,14 +213,15 @@ connections between each pair of stops in the same station to favor in-station t } ``` -Note that this method is at odds with micro-mapping and might make some transfers artificially short. - +Note that this method is at odds with micro-mapping and might make some transfers artificially +short. ## Elevation data -OpenTripPlanner can "drape" the OSM street network over a digital elevation model (DEM). -This allows OTP to draw an elevation profile for the on-street portion of itineraries, and helps provide better -routing for bicyclists. It even helps avoid hills for walking itineraries. DEMs are usually supplied as rasters +OpenTripPlanner can "drape" the OSM street network over a digital elevation model (DEM). This allows +OTP to draw an elevation profile for the on-street portion of itineraries, and helps provide better +routing for bicyclists. It even helps avoid hills for walking itineraries. DEMs are usually supplied +as rasters (regular grids of numbers) stored in image formats such as GeoTIFF. ### U.S. National Elevation Dataset @@ -202,11 +229,12 @@ routing for bicyclists. It even helps avoid hills for walking itineraries. DEMs In the United States, a high resolution [National Elevation Dataset](http://ned.usgs.gov/) is available for the entire territory. It used to be possible for OTP to download NED tiles on the fly from a rather complex USGS SOAP service. This process was somewhat unreliable and would greatly slow -down the graph building process. In any case the service has since been replaced. But the USGS -would also deliver the whole dataset in bulk if you [sent them a hard drive](https://web.archive.org/web/20150811051917/http://ned.usgs.gov:80/faq.html#DATA). We did this many years back and uploaded -the entire data set to Amazon AWS S3. OpenTripPlanner contains another module that can automatically -fetch data in this format from any Amazon S3 copy of the bulk data. You can configure it as follows -in `build-config.json`: +down the graph building process. In any case the service has since been replaced. But the USGS would +also deliver the whole dataset in bulk if +you [sent them a hard drive](https://web.archive.org/web/20150811051917/http://ned.usgs.gov:80/faq.html#DATA) +. We did this many years back and uploaded the entire data set to Amazon AWS S3. OpenTripPlanner +contains another module that can automatically fetch data in this format from any Amazon S3 copy of +the bulk data. You can configure it as follows in `build-config.json`: ```JSON // router-config.json @@ -227,26 +255,25 @@ Once the tiles are downloaded for a particular geographic area, OTP will keep th for the next graph build operation. You should add the `--cache ` command line parameter to specify your NED tile cache location. - ### Geoid Difference Some elevation data sets are relative to mean sea level. At a global scale sea level is represented -as a surface called the geoid, which is irregular in shape due to local gravitational anomalies. -On the other hand, GPS elevations are reported relative to the WGS84 spheroid, a perfectly smooth -mathematical surface approximating the geoid. -In cases where the two elevation definitions are mixed, it may be necessary to adjust elevation -values to avoid confusing users with things like negative elevation values in places clearly above -sea level. See [issue #2301](https://github.com/opentripplanner/OpenTripPlanner/issues/2301) +as a surface called the geoid, which is irregular in shape due to local gravitational anomalies. On +the other hand, GPS elevations are reported relative to the WGS84 spheroid, a perfectly smooth +mathematical surface approximating the geoid. In cases where the two elevation definitions are +mixed, it may be necessary to adjust elevation values to avoid confusing users with things like +negative elevation values in places clearly above sea level. +See [issue #2301](https://github.com/opentripplanner/OpenTripPlanner/issues/2301) for detailed discussion of this. -OTP allows you to adjust the elevation values reported in API responses in two ways. -The first way 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) 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: +OTP allows you to adjust the elevation values reported in API responses in two ways. The first way +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) +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: ```JSON // router-config.json @@ -257,13 +284,13 @@ to set a default request value in the `router-config.json` file as follows: } ``` -The second way is to precompute these geoid difference values at a more granular level and store -all elevations internally relative to the geoid (sea level). Elevations returned in the API -responses will then not need to be adjusted to match end users' intuitive understanding of elevation. -In order to speed up calculations, these geoid difference values are calculated and cached using only -2 significant digits of GPS coordinates. This is more than enough detail for most regions of the -world and should result in less than one meter of vertical error even in areas that have the largest -geoid irregularities. To enable this, include the following in the `build-config.json` file: +The second way is to precompute these geoid difference values at a more granular level and store all +elevations internally relative to the geoid (sea level). Elevations returned in the API responses +will then not need to be adjusted to match end users' intuitive understanding of elevation. In order +to speed up calculations, these geoid difference values are calculated and cached using only 2 +significant digits of GPS coordinates. This is more than enough detail for most regions of the world +and should result in less than one meter of vertical error even in areas that have the largest geoid +irregularities. To enable this, include the following in the `build-config.json` file: ```JSON // build-config.json @@ -272,34 +299,43 @@ geoid irregularities. To enable this, include the following in the `build-config } ``` -If the geoid difference values are precomputed, be careful to not set the routing resource value of `geoidElevation` to true in order to avoid having the graph-wide geoid added again to all elevation values in the relevant street edges in responses. +If the geoid difference values are precomputed, be careful to not set the routing resource value +of `geoidElevation` to true in order to avoid having the graph-wide geoid added again to all +elevation values in the relevant street edges in responses. ### Other raster elevation data -For other parts of the world you will need a GeoTIFF file containing the elevation data. These are often available from -national geographic surveys, or you can always fall back on the worldwide -[Space Shuttle Radar Topography Mission](http://www2.jpl.nasa.gov/srtm/) (SRTM) data. This not particularly high resolution +For other parts of the world you will need a GeoTIFF file containing the elevation data. These are +often available from national geographic surveys, or you can always fall back on the worldwide +[Space Shuttle Radar Topography Mission](http://www2.jpl.nasa.gov/srtm/) (SRTM) data. This not +particularly high resolution (roughly 30 meters horizontally) but it can give acceptable results. -Simply place the elevation data file in the directory with the other graph builder inputs, alongside the GTFS and OSM data. -Make sure the file has a `.tiff` or `.tif` extension, and the graph builder should detect its presence and apply -the elevation data to the streets. +Simply place the elevation data file in the directory with the other graph builder inputs, alongside +the GTFS and OSM data. Make sure the file has a `.tiff` or `.tif` extension, and the graph builder +should detect its presence and apply the elevation data to the streets. -OTP should automatically handle DEM GeoTIFFs in most common projections. You may want to check for elevation-related -error messages during the graph build process to make sure OTP has properly discovered the projection. If you are using -a DEM in unprojected coordinates make sure that the axis order is (longitude, latitude) rather than -(latitude, longitude). Unfortunately there is no reliable standard for WGS84 axis order, so OTP uses the same axis -order as the above-mentioned SRTM data, which is also the default for the popular Proj4 library. +OTP should automatically handle DEM GeoTIFFs in most common projections. You may want to check for +elevation-related error messages during the graph build process to make sure OTP has properly +discovered the projection. If you are using a DEM in unprojected coordinates make sure that the axis +order is (longitude, latitude) rather than +(latitude, longitude). Unfortunately there is no reliable standard for WGS84 axis order, so OTP uses +the same axis order as the above-mentioned SRTM data, which is also the default for the popular +Proj4 library. -DEM files(USGS DEM) is not supported by OTP, but can be converted to GeoTIFF with tools like [GDAL](http://www.gdal.org/). -Use `gdal_merge.py -o merged.tiff *.dem` to merge a set of `dem` files into one `tif` file. +DEM files(USGS DEM) is not supported by OTP, but can be converted to GeoTIFF with tools +like [GDAL](http://www.gdal.org/). Use `gdal_merge.py -o merged.tiff *.dem` to merge a set of `dem` +files into one `tif` file. -See Interline [PlanetUtils](https://github.com/interline-io/planetutils) for a set of scripts to download, merge, and resample [Mapzen/Amazon Terrain Tiles](https://registry.opendata.aws/terrain-tiles/). +See Interline [PlanetUtils](https://github.com/interline-io/planetutils) for a set of scripts to +download, merge, and +resample [Mapzen/Amazon Terrain Tiles](https://registry.opendata.aws/terrain-tiles/). ### Elevation unit conversion -By default, OTP expects the elevation data to use metres. However, by setting `elevationUnitMultiplier` in `build-config.json`, -it is possible to define a multiplier that converts the elevation values from some other unit to metres. +By default, OTP expects the elevation data to use metres. However, by +setting `elevationUnitMultiplier` in `build-config.json`, it is possible to define a multiplier that +converts the elevation values from some other unit to metres. ```JSON // build-config.json @@ -311,11 +347,17 @@ it is possible to define a multiplier that converts the elevation values from so ### Elevation Data Calculation Optimizations -Calculating elevations on all StreetEdges can take a dramatically long time. In a very large graph build for multiple Northeast US states, the time it took to download the elevation data and calculate all of the elevations took 5,509 seconds (roughly 1.5 hours). +Calculating elevations on all StreetEdges can take a dramatically long time. In a very large graph +build for multiple Northeast US states, the time it took to download the elevation data and +calculate all of the elevations took 5,509 seconds (roughly 1.5 hours). -If you are using cloud computing for your OTP instances, it is recommended to create prebuilt images that contain the elevation data you need. This will save time because all of the data won't need to be downloaded. +If you are using cloud computing for your OTP instances, it is recommended to create prebuilt images +that contain the elevation data you need. This will save time because all of the data won't need to +be downloaded. -However, the bulk of the time will still be spent calculating elevations for all of the street edges. Therefore, a further optimization can be done to calculate and save the elevation data during a graph build and then save it for future use. +However, the bulk of the time will still be spent calculating elevations for all of the street +edges. Therefore, a further optimization can be done to calculate and save the elevation data during +a graph build and then save it for future use. #### Reusing elevation data from previous builds @@ -328,15 +370,31 @@ In order to write out the precalculated elevation data, add this to your `build- } ``` -After building the graph, a file called `cached_elevations.obj` will be written to the cache directory. By default, this file is not written during graph builds. There is also a graph build parameter called `readCachedElevations` which is set to `true` by default. - -In graph builds, the elevation module will attempt to read the `cached_elevations.obj` file from the cache directory. The cache directory defaults to `/var/otp/cache`, but this can be overriden via the CLI argument `--cache `. For the same graph build for multiple Northeast US states, the time it took with using this predownloaded and precalculated data became 543.7 seconds (roughly 9 minutes). - -The cached data is a lookup table where the coordinate sequences of respective street edges are used as keys for calculated data. It is assumed that all of the other input data except for the OpenStreetMap data remains the same between graph builds. Therefore, if the underlying elevation data is changed, or different configuration values for `elevationUnitMultiplier` or `includeEllipsoidToGeoidDifference` are used, then this data becomes invalid and all elevation data should be recalculated. Over time, various edits to OpenStreetMap will cause this cached data to become stale and not include new OSM ways. Therefore, periodic update of this cached data is recommended. +After building the graph, a file called `cached_elevations.obj` will be written to the cache +directory. By default, this file is not written during graph builds. There is also a graph build +parameter called `readCachedElevations` which is set to `true` by default. + +In graph builds, the elevation module will attempt to read the `cached_elevations.obj` file from the +cache directory. The cache directory defaults to `/var/otp/cache`, but this can be overriden via the +CLI argument `--cache `. For the same graph build for multiple Northeast US states, the +time it took with using this predownloaded and precalculated data became 543.7 seconds (roughly 9 +minutes). + +The cached data is a lookup table where the coordinate sequences of respective street edges are used +as keys for calculated data. It is assumed that all of the other input data except for the +OpenStreetMap data remains the same between graph builds. Therefore, if the underlying elevation +data is changed, or different configuration values for `elevationUnitMultiplier` +or `includeEllipsoidToGeoidDifference` are used, then this data becomes invalid and all elevation +data should be recalculated. Over time, various edits to OpenStreetMap will cause this cached data +to become stale and not include new OSM ways. Therefore, periodic update of this cached data is +recommended. #### Configuring multi-threading during elevation calculations -For unknown reasons that seem to depend on data and machine settings, it might be faster to use a single processor. For this reason, multi-threading of elevation calculations is only done if `multiThreadElevationCalculations` is set to true. To enable multi-threading in the elevation module, add the following to the `build-config.json` file: +For unknown reasons that seem to depend on data and machine settings, it might be faster to use a +single processor. For this reason, multi-threading of elevation calculations is only done +if `multiThreadElevationCalculations` is set to true. To enable multi-threading in the elevation +module, add the following to the `build-config.json` file: ```JSON // build-config.json @@ -361,7 +419,9 @@ vehicle-rental) by defining a `combinationStrategy` parameter, and a list of sub "fares": "seattle" } ``` + Or this alternative form that could allow additional configuration + ```JSON // build-config.json { @@ -396,6 +456,7 @@ Or this alternative form that could allow additional configuration ``` Turning the fare service _off_, this will ignore any fare data in the provided GTFS data. + ```JSON // build-config.json { @@ -403,12 +464,12 @@ Turning the fare service _off_, this will ignore any fare data in the provided G } ``` - The current list of custom fare type is: - `vehicle-rental-time-based` - accepting the following parameters: - `currency` - the ISO 4217 currency code to use, such as `"EUR"` or `"USD"`, - - `prices` - a list of {time, price}. The resulting cost is the smallest cost where the elapsed time of vehicle rental is lower than the defined time. + - `prices` - a list of {time, price}. The resulting cost is the smallest cost where the elapsed + time of vehicle rental is lower than the defined time. - `san-francisco` (no parameters) - `new-york` (no parameters) - `seattle` (no parameters) @@ -420,12 +481,17 @@ The current list of `combinationStrategy` is: ## OSM / OpenStreetMap configuration -It is possible to adjust how OSM data is interpreted by OpenTripPlanner when building the road part of the routing graph. +It is possible to adjust how OSM data is interpreted by OpenTripPlanner when building the road part +of the routing graph. ### Way property sets -OSM tags have different meanings in different countries, and how the roads in a particular country or region are tagged affects routing. As an example are roads tagged with `highway=trunk (mainly) walkable in Norway, but forbidden in some other countries. This might lead to OTP being unable to snap stops to these roads, or by giving you poor routing results for walking and biking. -You can adjust which road types that are accessible by foot, car & bicycle as well as speed limits, suitability for biking and walking. +OSM tags have different meanings in different countries, and how the roads in a particular country +or region are tagged affects routing. As an example are roads tagged with `highway=trunk (mainly) +walkable in Norway, but forbidden in some other countries. This might lead to OTP being unable to +snap stops to these roads, or by giving you poor routing results for walking and biking. You can +adjust which road types that are accessible by foot, car & bicycle as well as speed limits, +suitability for biking and walking. There are currently following wayPropertySets defined; @@ -434,7 +500,11 @@ There are currently following wayPropertySets defined; - `norway` which is adjusted to rules and speeds in Norway - `uk` which is adjusted to rules and speed in the UK -To add your own custom property set have a look at `org.opentripplanner.graph_builder.module.osm.NorwayWayPropertySet` and `org.opentripplanner.graph_builder.module.osm.DefaultWayPropertySet`. If you choose to mainly rely on the default rules, make sure you add your own rules first before applying the default ones. The mechanism is that for any two identical tags, OTP will use the first one. +To add your own custom property set have a look +at `org.opentripplanner.graph_builder.module.osm.NorwayWayPropertySet` +and `org.opentripplanner.graph_builder.module.osm.DefaultWayPropertySet`. If you choose to mainly +rely on the default rules, make sure you add your own rules first before applying the default ones. +The mechanism is that for any two identical tags, OTP will use the first one. ```JSON // build-config.json @@ -443,11 +513,10 @@ To add your own custom property set have a look at `org.opentripplanner.graph_bu } ``` - ### Custom naming -You can define a custom naming scheme for elements drawn from OSM by defining an `osmNaming` field in `build-config.json`, -such as: +You can define a custom naming scheme for elements drawn from OSM by defining an `osmNaming` field +in `build-config.json`, such as: ```JSON // build-config.json diff --git a/docs/Changelog.md b/docs/Changelog.md index 4c4d25437c7..5090520c450 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -1,10 +1,11 @@ # Changelog -The changelog list 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. +The changelog list 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.2.0 (in progress) + - Optimize merging of trip patterns on dates [#3925](https://github.com/opentripplanner/OpenTripPlanner/pull/3925) - Fix default value for transit alerts [#3934](https://github.com/opentripplanner/OpenTripPlanner/pull/3934) - Add the visualizer to the interactive launcher [#3932](https://github.com/opentripplanner/OpenTripPlanner/pull/3932) @@ -25,7 +26,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Don't try to repair trips with negative dwell or driving times, drop them instead [#4019](https://github.com/opentripplanner/OpenTripPlanner/pull/4019) - Add support for NeTex DatedServiceJourneys [#3889](https://github.com/opentripplanner/OpenTripPlanner/pull/3889) - Add support for SKIPPED stop time updates in SCHEDULED update handling [#3960](https://github.com/opentripplanner/OpenTripPlanner/pull/3960) -- New Norwegian way properties profile [#3728](https://github.com/opentripplanner/OpenTripPlanner/pull/3728) +- New Norwegian way properties profile [#3728](https://github.com/opentripplanner/OpenTripPlanner/pull/3728) - Elevation handling improvements [#4033](https://github.com/opentripplanner/OpenTripPlanner/pull/4033) - NeTEx mapping of WheelchairBoarding from ServiceJourney to Trip [#4043](https://github.com/opentripplanner/OpenTripPlanner/pull/4043) - Always parse Netex flexible lines [#4049](https://github.com/opentripplanner/OpenTripPlanner/pull/4049) @@ -33,10 +34,11 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Add Geocoder API for debug client searches [#4068](https://github.com/opentripplanner/OpenTripPlanner/pull/4068) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) - ## 2.1.0 (2022-03-17) + ### Notable Changes + - GBFS 2.2 is supported including "form factors" (bike, scooter, car) and floating vehicles (with no fixed station) - Constrained Transfers (Netex interchanges / GTFS `transfers.txt`) - Transfers for bicycle and wheelchair users distinct from walking paths @@ -49,7 +51,9 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Response times should be roughly stable since 2.0. Performance much improved over OTP1 for long searches, may be somewhat slower for short searches. Extremely depdendent on data set used, so test on your specific data. - System integration tests for ongoing performance measurement + ### Detailed changes by Pull Request + - Fix NullPointerException when a RealTime update do not match an existing TripPattern [#3284](https://github.com/opentripplanner/OpenTripPlanner/issues/3284) - Support for versioning the configuration files [#3282](https://github.com/opentripplanner/OpenTripPlanner/issues/3282) - Prioritize "direct" routes over transfers in group-filters [#3309](https://github.com/opentripplanner/OpenTripPlanner/issues/3309) @@ -187,7 +191,7 @@ See the [OTP2 Migration Guide](OTP2-MigrationGuide.md) on changes to the REST AP - Remove extra Djikstra implementations - Remove redundant LineStrings in order to save memory [#2795](https://github.com/opentripplanner/OpenTripPlanner/issues/2795) - NeTEx import support [#2769](https://github.com/opentripplanner/OpenTripPlanner/issues/2769) -- New Transit search algorithm, Raptor, replaces the AStar for all transit searches. +- New Transit search algorithm, Raptor, replaces the AStar for all transit searches. - Added NeTEx notices [#2824](https://github.com/opentripplanner/OpenTripPlanner/issues/2824) - Make transfers and access/egress use effectiveWalkDistance to take slopes into account [#2857](https://github.com/opentripplanner/OpenTripPlanner/issues/2857) - Add MultiModalStation and GroupOfStations to OTP model and added these to the NeTEx import [#2813](https://github.com/opentripplanner/OpenTripPlanner/issues/2813) @@ -260,7 +264,6 @@ See the [OTP2 Migration Guide](OTP2-MigrationGuide.md) on changes to the REST AP - Improve documentation for `mode` routing parameter [#2809](https://github.com/opentripplanner/OpenTripPlanner/issues/2809) - Switched to single license file, removing all OTP and OBA file license headers - ## 1.3 (2018-08-03) - Fix stop linking to only one edge of platform [#2472](https://github.com/opentripplanner/OpenTripPlanner/issues/2472) @@ -286,7 +289,6 @@ See the [OTP2 Migration Guide](OTP2-MigrationGuide.md) on changes to the REST AP - Docs: Update leadership committee listing following Boston Summit - Docs: Update OTP logo (Thanks Kate Chanba!) - ## 1.2 (2017-09-18) - Add support for consuming GBFS bike-rental availability feeds. [#2458](https://github.com/opentripplanner/OpenTripPlanner/issues/2458) @@ -313,7 +315,6 @@ See the [OTP2 Migration Guide](OTP2-MigrationGuide.md) on changes to the REST AP - Add updater for urbaninfrastructure city bikes [#2448](https://github.com/opentripplanner/OpenTripPlanner/issues/2448) - Miscellaneous documentation updates - ## 1.1 (2017-03-16) - Deploy to Sonatype OSSRH and Maven Central @@ -376,7 +377,6 @@ See the [OTP2 Migration Guide](OTP2-MigrationGuide.md) on changes to the REST AP - Switch to only use the new SimpleStreetLinker, even for search start and end points. Completely removed old linker classes. Changes for proper handling of wheelchairs and bicycles at start and end points. - Properly handle null timetableSnapshots when there is no real-time data. - ## 0.20 (2016-06-10) - Re-enabled Enunciate, which works properly with OTP now. This means we have auto-generated API docs. @@ -405,10 +405,13 @@ See the [OTP2 Migration Guide](OTP2-MigrationGuide.md) on changes to the REST AP - Handle embeded router configuration for POSTed graphs and zips for building. - Simplified router-config handling. - Properly lazy-initialize profile routing stopClusters. Added stop clusters to the Index API. -- Completely removed the ill-advised path parser system, which was too clever for its own good. +- Completely removed the ill-advised path parser system, which was too clever for its own good. - Sort itineraries by total travel time rather than in-transit time. - Rental bikes: allow loading generic KML. -- Removed the experimental TransportNetwork classes, which shared no code with the rest of OTP and were duplicated in the R5 project. There are still some elements that can be cleaned out when only R5 is used by Conveyal's analysis system. The broker code in OTP is now able to start up R5 workers for Analyst. +- Removed the experimental TransportNetwork classes, which shared no code with the rest of OTP and + were duplicated in the R5 project. There are still some elements that can be cleaned out when only + R5 is used by Conveyal's analysis system. The broker code in OTP is now able to start up R5 + workers for Analyst. - Use the Conveyal fork of the OBA GTFS loader, so that we can add our own extensions to GTFS. - Updated docs to offer Conveyal Maven repo as a place to get prebuilt OTP. @@ -468,7 +471,8 @@ See the [OTP2 Migration Guide](OTP2-MigrationGuide.md) on changes to the REST AP ## 0.14.0 (2015-03-28) - JSON configuration of graph building and routers -- Began moving documentation (including this changelog) into the OTP repo and rewriting it page by page. It is built statically from Markdown using mkdocs and published on readthedocs. +- Began moving documentation (including this changelog) into the OTP repo and rewriting it page by + page. It is built statically from Markdown using mkdocs and published on readthedocs. - Street edge lists and bike rental station IDs in profile routing results (allows better rendering) - Improved correctness of profile routing - Qualified modes including rented bikes work in profile routing @@ -488,7 +492,8 @@ See the [OTP2 Migration Guide](OTP2-MigrationGuide.md) on changes to the REST AP - All client Javascript librariess are now pulled from a CDN - Dutch BAG and French BANO geocoders - Bus to street matching improvements -- Complete MapDB based GTFS and OSM loader libraries (will become separate projects, not yet connected to OTP graph builder) +- Complete MapDB based GTFS and OSM loader libraries (will become separate projects, not yet + connected to OTP graph builder) - API documentation generation working again - Disable some time consuming graph building steps by default - Finnish and Swedish translations @@ -497,7 +502,7 @@ See the [OTP2 Migration Guide](OTP2-MigrationGuide.md) on changes to the REST AP - Stairs reluctance is much higher when carrying a bike - Graph visualizer routing progress animates when a search is triggered via the web API - Assume WGS84 (spherical distance calculations) everywhere -- Removed custom motor vehicle (which was unmaintained and not documented) +- Removed custom motor vehicle (which was unmaintained and not documented) - Ability to poll for bike rental locations only once at startup - Stoptimes are fetched for a specific service day in index API - Bicycle triangle support in profile routing @@ -505,8 +510,11 @@ See the [OTP2 Migration Guide](OTP2-MigrationGuide.md) on changes to the REST AP - Command line option to output OTP's version ## 0.13.0 (2014-12-05) + - Detect apparent errors in GTFS interlining -- Long distance mode: use a pure weight-based state comparison, and use trip-banning retrying logic to get multiple paths. This compromises correctness somewhat but brings search times back within reason for large regional graphs. Also, we create significantly less SimpleTransfers. +- Long distance mode: use a pure weight-based state comparison, and use trip-banning retrying logic + to get multiple paths. This compromises correctness somewhat but brings search times back within + reason for large regional graphs. Also, we create significantly less SimpleTransfers. - Progress on GTFS reading and writing library (not yet used by OTP). - Bug fixes for tiny street edges, time zones. - Deployment of artifacts to maven.conveyal.com via S3. @@ -517,6 +525,7 @@ See the [OTP2 Migration Guide](OTP2-MigrationGuide.md) on changes to the REST AP - Fixed 'unconnected areas' infinite loop [#1605](https://github.com/opentripplanner/OpenTripPlanner/issues/1605) ## 0.12.0 (2014-11-11) + - Graph building from zipball of data sent over the wire - OTP-specific GTFS loader library with error checking and recovery - Bike and car park and ride improvements @@ -541,15 +550,21 @@ See the [OTP2 Migration Guide](OTP2-MigrationGuide.md) on changes to the REST AP - basic Lucene-based built-in geocoder ## 0.11.0 (2014-03-24) + - Built-in HTTP server layer, making it possible to distribute OTP as a standalone JAR - "Long-distance" mode for large graphs, including bidirectional goal direction heuristic. - Simplified Maven project structure with less submodules - GTFS-RT trip update support, including streaming incremental data, which directly affects route optimization ## 0.10.0 (2014-03-18) -This release was made to consolidate all the development that had occurred with a 0.9.x-SNAPSHOT Maven version. The changes were very significant and it was not appropriate to tag them as a minor bugfix release after the 0.9 tag. Though this release was performed at the same time as 0.11.0, it represents a much earlier stage in the development of OTP. + +This release was made to consolidate all the development that had occurred with a 0.9.x-SNAPSHOT +Maven version. The changes were very significant and it was not appropriate to tag them as a minor +bugfix release after the 0.9 tag. Though this release was performed at the same time as 0.11.0, it +represents a much earlier stage in the development of OTP. ## 0.7.0 (2012-04-29) + - Bike rental support (thanks Laurent Grégoire) - Realtime bike rental availability feed support - Updated to new version of One Bus Away GTFS/CSV, fixing timezone and string interning issues (thanks Brian Ferris) @@ -559,11 +574,13 @@ This release was made to consolidate all the development that had occurred with - Significant (10-20%) speedup by moving a field into StateData (thanks Laurent Grégoire) ## 0.6.0 (2012-04-25) + - area routing - more lenient parsing of times - new directions icon set with SVG sources (thanks Laurent G) ## 0.5.4 (2012-04-06) + - catch 0 divisors in NED builder, preventing NaN propagation to edge lengths - avoid repeated insertion of edges into edge lists, which are now threadsafe edge sets - identity equality for edges @@ -582,6 +599,7 @@ This release was made to consolidate all the development that had occurred with - allow loading a base graph into graphbuilder instead of starting from scratch ## 0.5.3 (2012-03-23) + - GTFS loader now loads feeds one-at-a-time, allowing per-feed configuration - half-written graph files are now deleted on graph build error - DST issue OTP-side fixes, tests adjusted to use timezones @@ -595,17 +613,20 @@ This release was made to consolidate all the development that had occurred with - complete Dutch translation ## 0.5.2 (2012-03-20) + - hop speed/distance checks, duplicate shape point filtering, etc. ## 0.5.1 (2012-03-16) + - more transit index features - default agencyIDs now determined on a per-feed basis - fixed fare overflow problem - fixed bug in loop road turn conversion - additional graphbuilder warnings and annotations -- fixed a batch of bugs found by fixbugs +- fixed a batch of bugs found by fixbugs ## 0.5.0 (2012-03-09) + - stop codes, zones, and agency names in planner responses - encapsulation of edge list modifications - expanded edge and vertex type hierarchy @@ -623,4 +644,5 @@ This release was made to consolidate all the development that had occurred with - and of course, lots of bugfixes ## 0.4.4 (2012-02-06) + Release in anticipation of upcoming merges. diff --git a/docs/Codestyle.md b/docs/Codestyle.md index 392f76f4a75..f0a248f7fd8 100644 --- a/docs/Codestyle.md +++ b/docs/Codestyle.md @@ -2,29 +2,26 @@ 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 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. - -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. +[Prettier Java](https://github.com/jhipster/prettier-java) as is. Maven is setup 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. +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. ### How to run Prittier with Maven - Format all code is done in the validate phase (run before test, package, install) ``` % mvn test ``` + To skip the prettier formating use profile `prettierSkip`: ``` @@ -37,17 +34,14 @@ The check for formatting errors use profile `prettierCheck`: % mvn test -P prettierSkip ``` -The check is run by the CI server and will fail the build if the code is -incorrectly formatted. +The check is run by the CI server and will fail the build if the code is incorrectly formatted. ### IntellJ and Code Style Formatting -If you use IntelliJ, the code-style is automatically imported when you first -import the project. If you have set a custom code-style in your settings (as we -used in v2.1.0 of OTP), then you should 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. - +If you use IntelliJ, the code-style is automatically imported when you first import the project. If +you have set a custom code-style in your settings (as we used in v2.1.0 of OTP), then you should +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. #### Install File Watchers Plugin in IntelliJ @@ -55,15 +49,12 @@ Then select **Project** in the _Scheme drop down. 2. Search for "File Watchers" in Marketplace 3. Run _Install_ - ##### Configure File Watcher -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 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. > *Name:* Format files with Prettier @@ -71,84 +62,85 @@ your shell and run it instead. > *File type:* Java > > *Scope:* Project Files -> +> > *Program:* mvn -> +> > *Arguments:* prettier:write -Dprettier.inputGlobs=$FilePathRelativeToProjectRoot$ > > *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 feel free to share it. +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 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. + +Some of the classes in OTP have a lot of fields and methods. Keeping members sorted reduce the 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. - 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´ - +1. Getter and Setter methods are kept together +2. Overridden methods are kept together +3. Dependent methods are sorted in a 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: -- 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) - - Invariants that hold if the preconditions are met - - Concurrency - - Is method thread-safe - - Usage constraints for multi-threaded use + +- 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) + - Invariants that hold if the preconditions are met + - Concurrency + - Is 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 - + - 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 + ## JavaScript - -As of #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");` - * Include a class comment. For example, - + +As of #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");` +* Include a class comment. For example, + ```javascript /** * Configure Class @@ -162,6 +154,6 @@ As of #206, we follow [Crockford's JavaScript code conventions](http://javascrip * @class */ ``` - -*Note: There is still a lot of code following other style conventions, but please adhere to + +*Note: There is still a lot of code following other style conventions, but please adhere to consistent style when you write new code, and help clean up and reformat code as you refactor.* diff --git a/docs/Configuration.md b/docs/Configuration.md index 724fad14e42..967edd5ec93 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -1,12 +1,14 @@ # Configuring OpenTripPlanner -_Note: if you are familiar with OTP1 configuration and are migrating to OTP2, please read the +_Note: if you are familiar with OTP1 configuration and are migrating to OTP2, please read the [OTP2 Migration Guide](OTP2-MigrationGuide.md) to learn what has changed._ - ## Base Directory -On the OTP2 command line you must always specify a single directory after all the switches. This tells OTP2 where to look for any configuration files. By default OTP will also scan this directory for input files to build a graph (GTFS, OSM, elevation, and base street graphs) or the `graph.obj` file to load when starting a server. +On the OTP2 command line you must always specify a single directory after all the switches. This +tells OTP2 where to look for any configuration files. By default OTP will also scan this directory +for input files to build a graph (GTFS, OSM, elevation, and base street graphs) or the `graph.obj` +file to load when starting a server. A typical OTP2 directory for a New York City graph might include the following: @@ -22,25 +24,38 @@ port-authority-of-new-york-new-jersey.gtfs.zip graph.obj ``` -You could have more than one of these directories if you are building separate graphs for separate regions. Each one should contain one or more GTFS feeds, a PBF OpenStreetMap file, some JSON configuration files, and any output files such as `graph.obj`. For convenience, especially if you work with only one graph at a time, you may want to place your OTP2 JAR file in this same directory. Note that file types are detected through a case-insensitive combination of file extension and words within the file name. GTFS file names must end in `.zip` and contain the letters `gtfs`, and OSM files must end in `.pbf`. +You could have more than one of these directories if you are building separate graphs for separate +regions. Each one should contain one or more GTFS feeds, a PBF OpenStreetMap file, some JSON +configuration files, and any output files such as `graph.obj`. For convenience, especially if you +work with only one graph at a time, you may want to place your OTP2 JAR file in this same directory. +Note that file types are detected through a case-insensitive combination of file extension and words +within the file name. GTFS file names must end in `.zip` and contain the letters `gtfs`, and OSM +files must end in `.pbf`. It is also possible to provide a list of input files in the configuration, which will override the -default behavior of scanning the base directory for input files. Scanning is overridden -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. +default behavior of scanning the base directory for input files. Scanning is overridden +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 -OTP is configured via three 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. +OTP is configured via three 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. -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` contains simple switches that enable or disable system-wide features. +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` +contains simple switches that enable or disable system-wide features. ## Configuration types -The OTP configuration files use the JSON file format. OTP allows comments and unquoted field names -in the JSON configuration files to be more human-friendly. OTP supports all the basic JSON types: -nested objects `{...}`, arrays `[]`, numbers `789.0` and boolean `true` or `false`. In addition to -these basic types some configuration parameters are parsed with some restrictions. In the +The OTP configuration files use the JSON file format. OTP allows comments and unquoted field names +in the JSON configuration files to be more human-friendly. OTP supports all the basic JSON types: +nested objects `{...}`, arrays `[]`, numbers `789.0` and boolean `true` or `false`. In addition to +these basic types some configuration parameters are parsed with some restrictions. In the documentation below we will refer to the following types: | Type | Description | Examples | @@ -65,12 +80,11 @@ documentation below we will refer to the following types: ## System environment and project information substitution -OTP support injecting system environment variables and project information parameters into the +OTP support injecting system environment variables and project information parameters into the configuration. A pattern like `${VAR_NAME}` in a configuration file is substituted with an environment variable with name `VAR_NAME`. The substitution is done BEFORE the JSON is parsed, so -both json keys and values is subject to substitution. This is useful if you want OTPs version -number to be part of the _graph-file-name_, or you want to inject credentials in a cloud based -deployment. +both json keys and values is subject to substitution. This is useful if you want OTPs version number +to be part of the _graph-file-name_, or you want to inject credentials in a cloud based deployment. ```JSON { @@ -80,67 +94,65 @@ deployment. } } ``` + In the example above the environment variable `GCS_SERVICE_CREDENTIALS` on the local machine where OTP is deployed is injected into the config. Also, the OTP serialization version id is injected. The project information variables available are: - - `maven.version` - - `maven.version.short` - - `maven.version.major` - - `maven.version.minor` - - `maven.version.patch` - - `maven.version.qualifier` - - `git.branch` - - `git.commit` - - `git.commit.timestamp` - - `graph.file.header` - - `otp.serialization.version.id` - - -## Config version - -All three configuration files have an optional `configVersion` property. The property can be used -to version the configuration in a deployment pipeline. The `configVersion` is not used by OTP in -any way, but is logged at startup and is available as part of the _server-info_ data in the REST -API. The intended usage is to be able to check which version of the configuration the graph was -build with and which version the router uses. In an deployment with many OTP instances it can be -useful to ask an instance about the version, instead of tracking the deployment pipline backwards -to find the version used. How you inject a version into the configuration file is up to you, but -you can do it in your build-pipline, at deployment time or use system environment variable -substituton. - +- `maven.version` +- `maven.version.short` +- `maven.version.major` +- `maven.version.minor` +- `maven.version.patch` +- `maven.version.qualifier` +- `git.branch` +- `git.commit` +- `git.commit.timestamp` +- `graph.file.header` +- `otp.serialization.version.id` + +## Config version + +All three configuration files have an optional `configVersion` property. The property can be used to +version the configuration in a deployment pipeline. The `configVersion` is not used by OTP in any +way, but is logged at startup and is available as part of the _server-info_ data in the REST API. +The intended usage is to be able to check which version of the configuration the graph was build +with and which version the router uses. In an deployment with many OTP instances it can be useful to +ask an instance about the version, instead of tracking the deployment pipline backwards to find the +version used. How you inject a version into the configuration file is up to you, but you can do it +in your build-pipline, at deployment time or use system environment variable substituton. ## OTP Serialization version id and _Graph.obj_ file header - + OTP has a _OTP Serialization Version Id_ maintained in the pom.xml_ file. OTP store the id in the -serialized _Graph.obj_ file header, allowing OTP the check for compatibility issues when loading -the graph. The header info is available to configuration substitution: - - - `${graph.file.header}` Will expand to: `OpenTripPlannerGraph;0000007;` - - `${otp.serialization.version.id}` Will expand to: `7` - -The intended usage is to be able to have a graph build pipeline which "knows" which graph -that matches OTP planner instances. For example, you may build new graphs for every OTP -serialization version id in use by the planning OPT instances you have deploied and plan to deploy. -This way you can roll forward and backward new OTP instances without worring about building new -graphs. - -There are various ways to access this information. To get the `Graph.obj` serialization version id +serialized _Graph.obj_ file header, allowing OTP the check for compatibility issues when loading the +graph. The header info is available to configuration substitution: + +- `${graph.file.header}` Will expand to: `OpenTripPlannerGraph;0000007;` +- `${otp.serialization.version.id}` Will expand to: `7` + +The intended usage is to be able to have a graph build pipeline which "knows" which graph that +matches OTP planner instances. For example, you may build new graphs for every OTP serialization +version id in use by the planning OPT instances you have deploied and plan to deploy. This way you +can roll forward and backward new OTP instances without worring about building new graphs. + +There are various ways to access this information. To get the `Graph.obj` serialization version id you can run the following bash command: - - `head -c 29 Graph.obj ==> OpenTripPlannerGraph;0000007;` (file header) - - `head -c 28 Graph.obj | tail -c 7 ==> 0000007` (version id) - -The Maven _pom.xml_, the _META-INF/MANIFEST.MF_, the OTP command line(`--serVerId`), log start-up -messages and all OTP APIs can be used to get the OTP Serialization Version Id. +- `head -c 29 Graph.obj ==> OpenTripPlannerGraph;0000007;` (file header) +- `head -c 28 Graph.obj | tail -c 7 ==> 0000007` (version id) + +The Maven _pom.xml_, the _META-INF/MANIFEST.MF_, the OTP command line(`--serVerId`), log start-up +messages and all OTP APIs can be used to get the OTP Serialization Version Id. ## Include file directive -It is possible to inject the contents of another file into a configuration file. This makes it -possible to keep parts of the configuration in separate files. To include the contents of a file, use -`${includeFile:FILE_NAME}`. The `FILE_NAME` must be the name of a file in the configuration -directory. Relative paths are not supported. +It is possible to inject the contents of another file into a configuration file. This makes it +possible to keep parts of the configuration in separate files. To include the contents of a file, +use +`${includeFile:FILE_NAME}`. The `FILE_NAME` must be the name of a file in the configuration +directory. Relative paths are not supported.

To allow both files (the configuration file and the injected file) to be valid JSON files, a special case is supported. If the include file directive is quoted, then the quotes are removed, if the @@ -164,7 +176,9 @@ Here is an example including variable substitution, assuming version 2.1.0 of OT "streetGraph": "street-graph-v${maven.version}.obj" } ``` + The result will look like this: + ```JSON { "storage" : { @@ -173,16 +187,16 @@ The result will look like this: } ``` - # System-wide Configuration Using the file `otp-config.json` you can enable or disable different APIs and experimental -[Sandbox Extensions](SandboxExtension.md). By default, all supported APIs are enabled and all +[Sandbox Extensions](SandboxExtension.md). By default, all supported APIs are enabled and all sandbox features are disabled. So for most OTP2 use cases it is not necessary to create this file. -Features that can be toggled in this file are generally only affect the routing phase of OTP2 -usage, but for consistency all such "feature flags", even those that would affect graph building, -are managed in this one file. See the [OTPFeature](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/util/OTPFeature.java) -Java class for an enumeration of all available features and their default settings. Here is an +Features that can be toggled in this file are generally only affect the routing phase of OTP2 usage, +but for consistency all such "feature flags", even those that would affect graph building, are +managed in this one file. See +the [OTPFeature](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/util/OTPFeature.java) +Java class for an enumeration of all available features and their default settings. Here is an example: ```JSON @@ -196,6 +210,7 @@ example: ``` ## OTP Features + Here is a list of all features which can be toggled on/off. | Feature | Description | Enabled by default | Sandbox | diff --git a/docs/Deployments.md b/docs/Deployments.md index 6525a64dfd8..39225704d78 100644 --- a/docs/Deployments.md +++ b/docs/Deployments.md @@ -4,32 +4,88 @@ The following are known deployments of OTP in a government- or agency-sponsored production capacity: -* **Norway (nationwide)** Since November 2017, the national integrated ticketing agency Entur has prodvided a [national journey planner](https://en-tur.no/) which consumes schedule data in the EU standard NeTEx format with SIRI realtime updates. Entur has contributed greatly to the OTP2 effort and primarily uses OTP2 in production, handling peak loads in excess of 20 requests per second. -* **Oslo, Norway** Ruter provides a [journey planner for the Oslo region](https://ruter.no/). It has been in production since January 2016 and serves around 200,000 users per day. -* **Finland (nationwide)** The [Helsinki Regional Transport Authority](https://www.reittiopas.fi/), the [Finnish Transport Agency](https://opas.matka.fi/), and other [Finnish cities](https://waltti.fi/?lang=en) have collaborated to create [Digitransit](https://digitransit.fi/en/), providing OTP-based trip planners, APIs, open data, Docker containers and open source code. Each member organisation runs its own instance of a shared codebase and deployment environment. Their source code is available [on Github](https://github.com/HSLdevcom/), including a [new custom UI](https://github.com/HSLdevcom/digitransit-ui). This system also has a strong real-time component. -* **Finland Intercity** The Finnish intercity coach service [Matkahuolto](https://en.wikipedia.org/wiki/Matkahuolto) has [developed a trip planner in partnership with Kyyti](https://www.kyyti.com/matkahuoltos-new-app-brings-real-travel-chains-within-the-reach-of-citizens-in-addition-to-coach-travel-hsl-tickets-are-also-available/). -* **Leipzig, Germany** As of summer 2020 [Leipzig Move](https://leipzig-move.de/) has been using OpenTripPlanner. -* **Portland, Oregon** TriMet is the agency that originally started the OpenTripPlanner project. Their [Regional Trip Planner](http://ride.trimet.org) is based on OTP and provides about 40,000 trip plans on a typical weekday. -* **New York State** The State Department of Transportation's [transit trip planner](https://511ny.org/#TransitRegion-1) provides itineraries for public transit systems throughout the state in a single unified OTP instance. +* **Norway (nationwide)** Since November 2017, the national integrated ticketing agency Entur has + prodvided a [national journey planner](https://en-tur.no/) which consumes schedule data in the EU + standard NeTEx format with SIRI realtime updates. Entur has contributed greatly to the OTP2 effort + and primarily uses OTP2 in production, handling peak loads in excess of 20 requests per second. +* **Oslo, Norway** Ruter provides a [journey planner for the Oslo region](https://ruter.no/). It has + been in production since January 2016 and serves around 200,000 users per day. +* **Finland (nationwide)** The [Helsinki Regional Transport Authority](https://www.reittiopas.fi/), + the [Finnish Transport Agency](https://opas.matka.fi/), and + other [Finnish cities](https://waltti.fi/?lang=en) have collaborated to + create [Digitransit](https://digitransit.fi/en/), providing OTP-based trip planners, APIs, open + data, Docker containers and open source code. Each member organisation runs its own instance of a + shared codebase and deployment environment. Their source code is + available [on Github](https://github.com/HSLdevcom/), including + a [new custom UI](https://github.com/HSLdevcom/digitransit-ui). This system also has a strong + real-time component. +* **Finland Intercity** The Finnish intercity coach + service [Matkahuolto](https://en.wikipedia.org/wiki/Matkahuolto) + has [developed a trip planner in partnership with Kyyti](https://www.kyyti.com/matkahuoltos-new-app-brings-real-travel-chains-within-the-reach-of-citizens-in-addition-to-coach-travel-hsl-tickets-are-also-available/) + . +* **Leipzig, Germany** As of summer 2020 [Leipzig Move](https://leipzig-move.de/) has been using + OpenTripPlanner. +* **Portland, Oregon** TriMet is the agency that originally started the OpenTripPlanner project. + Their [Regional Trip Planner](http://ride.trimet.org) is based on OTP and provides about 40,000 + trip plans on a typical weekday. +* **New York State** The State Department of + Transportation's [transit trip planner](https://511ny.org/#TransitRegion-1) provides itineraries + for public transit systems throughout the state in a single unified OTP instance. * **Los Angeles, California** The new [metro.net trip planner](https://www.metro.net/). -* **Atlanta, Georgia** The Metropolitan Atlanta Rapid Transit Authority's (MARTA) [trip planner](http://itsmarta.com/planatrip.aspx) and the Atlanta region's transit information hub [atltransit.org](https://atltransit.org/) both use OTP to power their website trip planners. -* **Boston, Massachusetts** The [Massachusetts Bay Transportation Authority trip planner](https://www.mbta.com/trip-planner). -* **Seattle, Washington** The [Sound Transit Trip Planner](https://www.soundtransit.org/tripplanner) is based on OTP. OTP also powers the trip planning feature of the [OneBusAway native apps](http://onebusaway.org/) in the Puget Sound region. Technical details are [here](https://github.com/OneBusAway/onebusaway-android/blob/master/SYSTEM_ARCHITECTURE.md#add-trip-planning-andor-bike-share-optional). -* **Tampa, Florida** Hillsoborough Area Regional Transit uses an OpenTripPlanner server to power the trip planning feature of the [OneBusAway native apps](http://onebusaway.org/) in their region. Technical details are [here](https://github.com/OneBusAway/onebusaway-android/blob/master/SYSTEM_ARCHITECTURE.md#add-trip-planning-andor-bike-share-optional). -* [**Piemonte Region, Italy**](https://map.muoversinpiemonte.it/#planner) and the [**City of Torino**](https://www.muoversiatorino.it/) built on OpenTripPlanner by [5T](http://www.5t.torino.it/). -* [**Valencia, Spain**](http://www.emtvalencia.es/geoportal/?lang=en_otp) from the Municipal Transport Company of Valencia S.A.U. -* [**Grenoble, France**](http://www.metromobilite.fr/) from SMTC, Grenoble Alpes métropole, l'État Français, the Rhône-alpes region, the Isère council and the City of Grenoble. -* **Rennes, France** where the STAR network provides an OTP client for [iOS](https://itunes.apple.com/us/app/starbusmetro/id899970416?mt=8), [Android](https://play.google.com/store/apps/details?id=com.bookbeo.starbusmetro), Windows Phone et Web. -* **Alençon, France** integrated urban and school bus network [planner from Réunir Alençon](https://altobus.com/mon-itineraire/). -* [**Poznań, Poland**](http://ztm.poznan.pl/#planner) from Urban Transport Authority of Poznań (ZTM Poznan). -* **Trento Province, Italy** - [ViaggiaTrento](https://play.google.com/store/apps/details?id=eu.trentorise.smartcampus.viaggiatrento) and [ViaggiaRovereto](https://play.google.com/store/apps/details?id=eu.trentorise.smartcampus.viaggiarovereto) - were implemented as part of the [SmartCampus Project](http://www.smartcampuslab.it), a research project founded by [TrentoRise](http://trentorise.eu), [UNITN](http://www.unitn.it), and [FBK](http://www.fbk.eu). -* **University of South Florida** (Tampa, Florida). The [USF Maps App](https://maps.usf.edu/) is a responsive web application for that helps university students, staff, and visitors find their way around the campus using multiple modes of transportation, including the USF Bull Runner campus shuttle, Share-A-Bull bike share, and pedestrian pathways. Open-sourced [on Github](https://github.com/CUTR-at-USF/usf-mobullity). +* **Atlanta, Georgia** The Metropolitan Atlanta Rapid Transit Authority's ( + MARTA) [trip planner](http://itsmarta.com/planatrip.aspx) and the Atlanta region's transit + information hub [atltransit.org](https://atltransit.org/) both use OTP to power their website trip + planners. +* **Boston, Massachusetts** + The [Massachusetts Bay Transportation Authority trip planner](https://www.mbta.com/trip-planner). +* **Seattle, Washington** The [Sound Transit Trip Planner](https://www.soundtransit.org/tripplanner) + is based on OTP. OTP also powers the trip planning feature of + the [OneBusAway native apps](http://onebusaway.org/) in the Puget Sound region. Technical details + are [here](https://github.com/OneBusAway/onebusaway-android/blob/master/SYSTEM_ARCHITECTURE.md#add-trip-planning-andor-bike-share-optional) + . +* **Tampa, Florida** Hillsoborough Area Regional Transit uses an OpenTripPlanner server to power the + trip planning feature of the [OneBusAway native apps](http://onebusaway.org/) in their region. + Technical details + are [here](https://github.com/OneBusAway/onebusaway-android/blob/master/SYSTEM_ARCHITECTURE.md#add-trip-planning-andor-bike-share-optional) + . +* [**Piemonte Region, Italy**](https://map.muoversinpiemonte.it/#planner) and the [**City of + Torino**](https://www.muoversiatorino.it/) built on OpenTripPlanner + by [5T](http://www.5t.torino.it/). +* [**Valencia, Spain**](http://www.emtvalencia.es/geoportal/?lang=en_otp) from the Municipal + Transport Company of Valencia S.A.U. +* [**Grenoble, France**](http://www.metromobilite.fr/) from SMTC, Grenoble Alpes métropole, l'État + Français, the Rhône-alpes region, the Isère council and the City of Grenoble. +* **Rennes, France** where the STAR network provides an OTP client + for [iOS](https://itunes.apple.com/us/app/starbusmetro/id899970416?mt=8) + , [Android](https://play.google.com/store/apps/details?id=com.bookbeo.starbusmetro), Windows Phone + et Web. +* **Alençon, France** integrated urban and school bus + network [planner from Réunir Alençon](https://altobus.com/mon-itineraire/). +* [**Poznań, Poland**](http://ztm.poznan.pl/#planner) from Urban Transport Authority of Poznań (ZTM + Poznan). +* **Trento Province, Italy** + - [ViaggiaTrento](https://play.google.com/store/apps/details?id=eu.trentorise.smartcampus.viaggiatrento) + and [ViaggiaRovereto](https://play.google.com/store/apps/details?id=eu.trentorise.smartcampus.viaggiarovereto) + were implemented as part of the [SmartCampus Project](http://www.smartcampuslab.it), a research + project founded by [TrentoRise](http://trentorise.eu), [UNITN](http://www.unitn.it), + and [FBK](http://www.fbk.eu). +* **University of South Florida** (Tampa, Florida). The [USF Maps App](https://maps.usf.edu/) is a + responsive web application for that helps university students, staff, and visitors find their way + around the campus using multiple modes of transportation, including the USF Bull Runner campus + shuttle, Share-A-Bull bike share, and pedestrian pathways. + Open-sourced [on Github](https://github.com/CUTR-at-USF/usf-mobullity). ## Independent Production -The following OTP-based services are presented as production-quality deployments, but are not backed by an official transportation authority or government. OTP is also known to be used on the back end of several popular multi-city mobile trip planning applications. +The following OTP-based services are presented as production-quality deployments, but are not backed +by an official transportation authority or government. OTP is also known to be used on the back end +of several popular multi-city mobile trip planning applications. -* **The Netherlands (nationwide)** [Plannerstack Foundation](http://www.plannerstack.org/) provides national scale trip planning APIs using OTP and other open source trip planners, based on [OpenOV's extremely detailed open data](http://gtfs.openov.nl/) including minutely real-time updates for every vehicle in the country. -* [OTP Android](https://play.google.com/store/apps/details?id=edu.usf.cutr.opentripplanner.android) by CUTR-USF and Vreixo González can find itineraries on many different OTP servers via a service discovery mechanism. +* **The Netherlands (nationwide)** [Plannerstack Foundation](http://www.plannerstack.org/) provides + national scale trip planning APIs using OTP and other open source trip planners, based + on [OpenOV's extremely detailed open data](http://gtfs.openov.nl/) including minutely real-time + updates for every vehicle in the country. +* [OTP Android](https://play.google.com/store/apps/details?id=edu.usf.cutr.opentripplanner.android) + by CUTR-USF and Vreixo González can find itineraries on many different OTP servers via a service + discovery mechanism. * [**ViviBus Bologna**](http://www.vivibus.it/) Bologna, Italy. diff --git a/docs/Developers-Guide.md b/docs/Developers-Guide.md index 28208265833..c942f4fd75d 100644 --- a/docs/Developers-Guide.md +++ b/docs/Developers-Guide.md @@ -1,103 +1,123 @@ # Developers Guide ## Quick setup + _A Quick guide to setting up the OpenTripPlanner project._ -You need Git, Maven and Java(JDK) and an IDE installed on your computer. You IDE might have JDK and +You need Git, Maven and Java(JDK) and an IDE installed on your computer. You IDE might have JDK and Maven embedded, if so you may skip step 3. 1. Clone OpenTripPlanner from GitHub. -2. Checkout the desired branch `git checkout dev-2.x` +2. Checkout the desired branch `git checkout dev-2.x` 3. Run `maven package`- this will download all dependencies, build the project and run tests. 4. Open the project in your IDE. 5. Import the _intellij-code-style.xml_ (IntelliJ IDE). - ## Working on OTP in an IDE -Most people writing or modifying OTP code use an Integrated Development Environment (IDE). Some of -the most popular IDEs for Java development are [IntelliJ IDEA](https://www.jetbrains.com/idea/), -[Eclipse](http://eclipse.org), and [NetBeans](https://netbeans.org). All three of these environments -are good for working on OTP. IntelliJ is used by most OTP developers, and the only IDE we support -with a code style formatter. You may choose another IDE, but Maven and Git integration is a -plus since OTP is under Git version control and build with Maven. +Most people writing or modifying OTP code use an Integrated Development Environment (IDE). Some of +the most popular IDEs for Java development are [IntelliJ IDEA](https://www.jetbrains.com/idea/), +[Eclipse](http://eclipse.org), and [NetBeans](https://netbeans.org). All three of these environments +are good for working on OTP. IntelliJ is used by most OTP developers, and the only IDE we support +with a code style formatter. You may choose another IDE, but Maven and Git integration is a plus +since OTP is under Git version control and build with Maven. -Many of the Core OTP developers use IntelliJ IDEA. It is an excellent IDE, and in my experience is -quicker and more stable than the competition. IntelliJ IDEA is a commercial product, but there is an +Many of the Core OTP developers use IntelliJ IDEA. It is an excellent IDE, and in my experience is +quicker and more stable than the competition. IntelliJ IDEA is a commercial product, but there is an open source "community edition" that is completely sufficient for working on OTP. -Rather than using the version control support in my IDE, I usually find it more straightforward to clone the OTP GitHub -repository manually (on the command line or using some other Git interface tool), then import the resulting local OTP -repository into my IDE as a Maven project. The IDE should then take care of fetching all the libraries OTP depends on, -based on the Maven project description (POM file) in the base of the OTP repository. This step can take a long time because -it involves downloading a lot of JAR files. +Rather than using the version control support in my IDE, I usually find it more straightforward to +clone the OTP GitHub repository manually (on the command line or using some other Git interface +tool), then import the resulting local OTP repository into my IDE as a Maven project. The IDE should +then take care of fetching all the libraries OTP depends on, based on the Maven project +description (POM file) in the base of the OTP repository. This step can take a long time because it +involves downloading a lot of JAR files. -When running your local copy of the OTP source within an IDE, all command line switches and +When running your local copy of the OTP source within an IDE, all command line switches and configuration options will be identical to the ones used when running the OTP JAR from the command -line (as described in the [OpenTripPlanner Basic Tutorial](Basic-Tutorial.md) and -[configuration reference](Configuration.md)). The only difference is that you need to manually -specify the main class. When you run a JAR from the command line, the JVM automatically knows which -class contains the entry point into the program (the `main` function), but in IDEs you must create +line (as described in the [OpenTripPlanner Basic Tutorial](Basic-Tutorial.md) and +[configuration reference](Configuration.md)). The only difference is that you need to manually +specify the main class. When you run a JAR from the command line, the JVM automatically knows which +class contains the entry point into the program (the `main` function), but in IDEs you must create a "run configuration". -Both IntelliJ and Eclipse have "run" menus, from which you can select an option to edit the run configurations. -You want to create a configuration for a Java Application, specifying the main class -`org.opentripplanner.standalone.OTPMain`. Unlike on the command line, the arguments to the JVM and to the main class -you are running are specified separately. In the field for the VM options you'll want to put your maximum memory -parameter (`-Xmx2G`, or whatever limit you want to place on JVM memory usage). The rest of the parameters to OTP itself -will go in a different field with a name like "program arguments". - +Both IntelliJ and Eclipse have "run" menus, from which you can select an option to edit the run +configurations. You want to create a configuration for a Java Application, specifying the main class +`org.opentripplanner.standalone.OTPMain`. Unlike on the command line, the arguments to the JVM and +to the main class you are running are specified separately. In the field for the VM options you'll +want to put your maximum memory parameter (`-Xmx2G`, or whatever limit you want to place on JVM +memory usage). The rest of the parameters to OTP itself will go in a different field with a name +like "program arguments". ## Contributing to the project OpenTripPlanner is a community based open source project, and we welcome all who wish to contribute. There are several ways to get involved: - * Join the [developer mailing list](http://groups.google.com/group/opentripplanner-dev) +* Join the [developer mailing list](http://groups.google.com/group/opentripplanner-dev) - * Fix typos and improve the documentation within the `/docs` directory of the project (details below). +* Fix typos and improve the documentation within the `/docs` directory of the project (details + below). - * [File a bug or new feature request](http://github.com/openplans/OpenTripPlanner/issues/new). +* [File a bug or new feature request](http://github.com/openplans/OpenTripPlanner/issues/new). - * Submit patches. If you're not yet a committer, please provide patches as pull requests citing the relevant issue. - Even when you do have push access to the repository, pull requests are a good way to get feedback on changes. +* Submit patches. If you're not yet a committer, please provide patches as pull requests citing the + relevant issue. Even when you do have push access to the repository, pull requests are a good way + to get feedback on changes. ### Branches and Branch Protection -As of January 2019, we have begun work on OTP 2.x and are using a Git branching model derived from [Gitflow](https://nvie.com/posts/a-successful-git-branching-model/). All development will occur on the `dev-1.x` and `dev-2.x` branches. Only release commits setting the Maven artifact version to a non-snapshot number should be pushed to the `master` branch of OTP. All other changes to master should result from fast-forward merges of a Github pull request from the `dev-1.x` branch. In turn, all changes to `dev-1.x` should result from a fast-forward merge of a Github pull request for a single feature, fix, or other change. These pull requests are subject to code review. We require two pull request approvals from OTP leadership committee members or designated code reviewers from two different organizations. We also have validation rules ensuring that the code compiles and all tests pass before pull requests can be merged. - -The `dev-2.x` branch is managed similarly to `dev-1.x` but because it's rapidly changing experimental code worked on by relatively few people, we require only one pull request approval from a different organization than the author. Merges will not occur into `master` from `dev-2.x` until that branch is sufficiently advanced and receives approval from the OTP project leadership committee. +As of January 2019, we have begun work on OTP 2.x and are using a Git branching model derived +from [Gitflow](https://nvie.com/posts/a-successful-git-branching-model/). All development will occur +on the `dev-1.x` and `dev-2.x` branches. Only release commits setting the Maven artifact version to +a non-snapshot number should be pushed to the `master` branch of OTP. All other changes to master +should result from fast-forward merges of a Github pull request from the `dev-1.x` branch. In turn, +all changes to `dev-1.x` should result from a fast-forward merge of a Github pull request for a +single feature, fix, or other change. These pull requests are subject to code review. We require two +pull request approvals from OTP leadership committee members or designated code reviewers from two +different organizations. We also have validation rules ensuring that the code compiles and all tests +pass before pull requests can be merged. + +The `dev-2.x` branch is managed similarly to `dev-1.x` but because it's rapidly changing +experimental code worked on by relatively few people, we require only one pull request approval from +a different organization than the author. Merges will not occur into `master` from `dev-2.x` until +that branch is sufficiently advanced and receives approval from the OTP project leadership +committee. ### Issues and commits -All commits should reference a specific issue number (this was formally decided in issue #175). -For example, `Simplify module X configuration #9999`. -If no ticket exists for the feature or bug your code implements or fixes, -you should [create a new ticket](http://github.com/openplans/OpenTripPlanner/issues/new) prior to checking in, or -ideally even prior to your development work since this provides a place to carry out implementation discussions (in the comments). - -GitHub will automatically update issues when commits are merged in: if your commit message includes the text -` fixes #123 `, it will automatically append your message as a comment on the isse and close it. -If you simply mention ` #123 ` in your message, your message will be appended to the issue but it will remain open. -Many other expressions exist to close issues via commit messages. See [the GitHub help page on this topic](https://help.github.com/articles/closing-issues-via-commit-messages/). +All commits should reference a specific issue number (this was formally decided in issue #175). For +example, `Simplify module X configuration #9999`. If no ticket exists for the feature or bug your +code implements or fixes, you +should [create a new ticket](http://github.com/openplans/OpenTripPlanner/issues/new) prior to +checking in, or ideally even prior to your development work since this provides a place to carry out +implementation discussions (in the comments). + +GitHub will automatically update issues when commits are merged in: if your commit message includes +the text +` fixes #123 `, it will automatically append your message as a comment on the isse and close it. If +you simply mention ` #123 ` in your message, your message will be appended to the issue but it will +remain open. Many other expressions exist to close issues via commit messages. +See [the GitHub help page on this topic](https://help.github.com/articles/closing-issues-via-commit-messages/) +. ### Unit tests using real OSM data -Sometimes it is useful to build a graph from actual OSM or GTFS data. Since building these graphs -in a test can be quite slow they will be accepted in pull requests only if they conform to certain +Sometimes it is useful to build a graph from actual OSM or GTFS data. Since building these graphs in +a test can be quite slow they will be accepted in pull requests only if they conform to certain standards: -1. Use the smallest possible regional extract - the OSM file should not contain more than a few hundred ways. - Use `osmium-extract` to cut down a larger OSM file into a tiny subset of it. - -2. Strip out any unneeded information by using the `osmium filter-tags` as describe in [Preparing OSM](Preparing-OSM.md) +1. Use the smallest possible regional extract - the OSM file should not contain more than a few + hundred ways. Use `osmium-extract` to cut down a larger OSM file into a tiny subset of it. +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 +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 +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 @@ -115,15 +135,15 @@ The updated files may be committed after checking that the changes in the files ### Documentation -OTP documentation is included directly in the OpenTripPlanner repository. -This allows version control to be applied to documentation as well as program source code. -All pull requests that change how OTP is used or configured should include changes to the -documentation alongside code modifications. +OTP documentation is included directly in the OpenTripPlanner repository. This allows version +control to be applied to documentation as well as program source code. All pull requests that change +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 project. On every push to the master branch the documentation will be rebuilt and deployed as -static pages to our subdomain of [ReadTheDocs](http://opentripplanner.readthedocs.org/). MkDocs is -a Python program and should run on any major platform. See http://www.mkdocs.org/ for information on +The documentation files are in Markdown format and are in the `/docs` directory under the root of +the project. On every push to the master branch the documentation will be rebuilt and deployed as +static pages to our subdomain of [ReadTheDocs](http://opentripplanner.readthedocs.org/). MkDocs is a +Python program and should run on any major platform. See http://www.mkdocs.org/ for information on how to install it and how to generate a live local preview of the documentation while you're working on writing it. @@ -142,7 +162,6 @@ For example, for v2.1.0: http://dev.opentripplanner.org/apidoc/2.1.0/index.html - ### Debug layers Adding new renderer is very easy. You just need to create new class (preferably in @@ -153,17 +172,20 @@ label of edge/vertex and color can be set. And both return `true` if edge/vertex and `false` otherwise. `getName` function should return short descriptive name of the class and will be shown in layer chooser. -For examples how to write renderers you can look into example renderers which are all in `org.opentripplanner.inspector` package. +For examples how to write renderers you can look into example renderers which are all +in `org.opentripplanner.inspector` package. After your class is written you only need to add it to TileRenderManager: + ```java //This is how Wheelchair renderer is added renderers.put("wheelchair", new EdgeVertexTileRenderer(new WheelchairEdgeRenderer())); ``` + `wheelchair` is internal layer key and should consist of a-zA-Z and -. By default all the tiles have cache headers to cache them for one hour. This can become problematic - if you are changing renderers a lot. To disable this change `GraphInspectorTileResource`: +if you are changing renderers a lot. To disable this change `GraphInspectorTileResource`: ```java //This lines @@ -176,63 +198,61 @@ CacheControl cc = new CacheControl(); cc.setNoCache(true); ``` - ### Date format -Please use only ISO 8601 date format (YYYY-MM-DD) in documentation, comments, and throughout the -project. This avoids the ambiguity that can result from differing local interpretations of date +Please use only ISO 8601 date format (YYYY-MM-DD) in documentation, comments, and throughout the +project. This avoids the ambiguity that can result from differing local interpretations of date formats like 02/01/12. - ## Code style The OTP code style is described on a separate [style guide page](Codestyle.md). - ## Continuous Integration -The OpenTripPlanner project uses the [Travis CI continuous integration system](https://travis-ci.org/opentripplanner/OpenTripPlanner). Any time a change -is pushed to the main OpenTripPlanner repository on GitHub, this server will compile and test the new code, providing feedback on the stability of the build. - +The OpenTripPlanner project uses +the [Travis CI continuous integration system](https://travis-ci.org/opentripplanner/OpenTripPlanner) +. Any time a change is pushed to the main OpenTripPlanner repository on GitHub, this server will +compile and test the new code, providing feedback on the stability of the build. ### Changelog workflow The [changelog file](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/docs/Changelog.md) is generated from the pull-request(PR) _title_ using the -[changelog workflow](https://github.com/opentripplanner/OpenTripPlanner/actions/workflows/automatic-changelog.yml). -The workflow runs after the PR is merged, and it changes, commits and pushes the _Changelog.md_. A +[changelog workflow](https://github.com/opentripplanner/OpenTripPlanner/actions/workflows/automatic-changelog.yml) +. The workflow runs after the PR is merged, and it changes, commits and pushes the _Changelog.md_. A secret _personal access token_ is used to bypass the "Require PR with 2 approvals" rule. To exclude a PR from the changelog add `[changelog skip]` in the PR title. - #### How-to update the CHANGELOG_TOKEN -The `CHANGELOG_TOKEN` is used by the changelog workflow. It contains a Personal Access Token. The token must be generated by a Repository Owner and have the following rights (_Settings / Developer settings / Personal access tokens_): +The `CHANGELOG_TOKEN` is used by the changelog workflow. It contains a Personal Access Token. The +token must be generated by a Repository Owner and have the following rights (_Settings / Developer +settings / Personal access tokens_): ![Skjermbilde 2021-11-18 kl 12 08 27](https://user-images.githubusercontent.com/5525340/142404549-c0bf2aba-608b-4feb-a114-6e4992c57073.png) - ## Release Process -This section serves as a checklist for the person performing releases. Note that much of this mimics -the actions taken by the Maven release plugin. Based on past experience, the Maven release plugin can -fail at various points in the process leaving the repo in a confusing state. Taking each action -manually is more tedious, but keeps eyes on each step and is less prone to failure. Releases are +This section serves as a checklist for the person performing releases. Note that much of this mimics +the actions taken by the Maven release plugin. Based on past experience, the Maven release plugin +can fail at various points in the process leaving the repo in a confusing state. Taking each action +manually is more tedious, but keeps eyes on each step and is less prone to failure. Releases are performed off the master branch, and are tagged with git annotated tags. -OpenTripPlanner is currently configured such that builds including releases upload JAR files to +OpenTripPlanner is currently configured such that builds including releases upload JAR files to GitHub Packages. This is not the most convenient place for end users to find and download the files. Therefore we also attach a stand-alone "shaded" JAR to the GitHub tag/release page, and have historically also uploaded Maven artifacts to Maven Central including compiled and source code JARs -as well as the "shaded" JAR containing all dependencies, allowing stand-alone usage. This release -process is handled by the Sonatype Nexus Staging plugin, which is no longer configured in the -OpenTripPlanner POM. This step currently requires making a few significant manual modifications to +as well as the "shaded" JAR containing all dependencies, allowing stand-alone usage. This release +process is handled by the Sonatype Nexus Staging plugin, which is no longer configured in the +OpenTripPlanner POM. This step currently requires making a few significant manual modifications to the POM. -We no longer trigger deployment of artifacts to Maven Central or deployment of REST API -documentation to AWS automatically in our build scripts (GitHub Actions). These steps are prone to -failure and require storing a lot of infrequently used secret information in the repo and -environment variables on GitHub. Our releases are currently not very frequent so we just carry out +We no longer trigger deployment of artifacts to Maven Central or deployment of REST API +documentation to AWS automatically in our build scripts (GitHub Actions). These steps are prone to +failure and require storing a lot of infrequently used secret information in the repo and +environment variables on GitHub. Our releases are currently not very frequent so we just carry out these steps manually by following the checklist. * Check that your local copy of the dev branch is up to date with no uncommitted changes @@ -243,51 +263,62 @@ these steps manually by following the checklist. * Verify that all dependencies in the POM are non-SNAPSHOT versions (e.g. with `grep`) * Update `docs/Changelog.md` * Lines should have been added or updated as each pull request was merged - * If you suspect any changes are not reflected in the Changelog, review the commit log and add any missing items + * If you suspect any changes are not reflected in the Changelog, review the commit log and add + any missing items * Update the header at the top of the list from `x.y.z-SNAPSHOT` to just `x.y.z (current date)` * Check in any changes, and push to Github -* Check [on GH Actions](https://github.com/opentripplanner/OpenTripPlanner/actions/workflows/) that the build is currently passing +* Check [on GH Actions](https://github.com/opentripplanner/OpenTripPlanner/actions/workflows/) that + the build is currently passing * Switch to the HEAD of master branch, and ensure it's up to date with no uncommitted changes * `git checkout master` * `git status` * `git clean -df` * `git pull` * Merge the dev branch into master - * `git merge dev-2.x` + * `git merge dev-2.x` * Bump the SNAPSHOT version in the POM to the release version - * Edit version in POM, removing SNAPSHOT and increasing version numbers as needed (following semantic versioning) + * Edit version in POM, removing SNAPSHOT and increasing version numbers as needed (following + semantic versioning) * `git add pom.xml` * `git commit -m "prepare release x.y.z"` * Run a test build of the release locally, without deploying it * `mvn clean install site` - * The `install` goal will sign the Maven artifacts so you need the GPG signing certificate set up - * You can also use the `package` goal instead of the `install` goal to avoid signing if you don't have the GPG certificate installed. + * The `install` goal will sign the Maven artifacts so you need the GPG signing certificate set + up + * You can also use the `package` goal instead of the `install` goal to avoid signing if you + don't have the GPG certificate installed. * All tests should pass - * This build will also create Enunciate API docs and Javadoc with the correct non-snapshot version number + * This build will also create Enunciate API docs and Javadoc with the correct non-snapshot + version number * Deploy the documentation to AWS S3 - * You have to do this right after the test release build to ensure the right version number in the docs + * You have to do this right after the test release build to ensure the right version number in + the docs * You will need AWSCLI tools (`sudo pip install -U awscli`) * You will need AWS credentials with write access to the bucket `s3://dev.opentripplanner.org` * `aws s3 cp --recursive target/site/apidocs s3://dev.opentripplanner.org/javadoc/x.y.z --acl public-read` * `aws s3 cp --recursive target/site/enunciate/apidocs s3://dev.opentripplanner.org/apidoc/x.y.z --acl public-read` - * Check that docs are readable and show the correct version via the [development documentation landing page](http://dev.opentripplanner.org). + * Check that docs are readable and show the correct version via + the [development documentation landing page](http://dev.opentripplanner.org). * Finally, if everything looks good, tag and push this release to make it official * `git tag -a vX.Y.Z -m "release X.Y.Z"` * `git push origin vX.Y.Z` * `git push origin master` - * Note that **only one** commit may have a particular non-snapshot version in the POM (this is the commit that - should be tagged as the release) - * Go to the [GitHub tags page](https://github.com/opentripplanner/OpenTripPlanner/tags) and use + * Note that **only one** commit may have a particular non-snapshot version in the POM (this is + the commit that should be tagged as the release) + * Go to the [GitHub tags page](https://github.com/opentripplanner/OpenTripPlanner/tags) and use the `...` button to mark the new tag as a release. * Give the release a name like `v2.1.0 (March 2022)` * Optionally add a very condensed version of the changelog in the description box, with only the 5-10 most significant changes that might affect someone's choice to upgrade. * Attach the JAR files produced in `/target` to the GitHub release page you just created. * Check that the push triggered an Actions build and that it was uploaded to GHPR. - * Currently, pushing the tag does not trigger deployment of release Maven artifacts, only GHPR JARs. + * Currently, pushing the tag does not trigger deployment of release Maven artifacts, only GHPR + JARs. * Deploy the build artifacts to Maven Central and GitHub and Maven Central - * This step can get complicated and requires you to have the GPG keys and Maven repo credentials set up. - * Apply the changes recorded in https://github.com/opentripplanner/OpenTripPlanner/tree/signed-deploy-to-central + * This step can get complicated and requires you to have the GPG keys and Maven repo credentials + set up. + * Apply the changes recorded + in https://github.com/opentripplanner/OpenTripPlanner/tree/signed-deploy-to-central * While still on the tag commit, run `mvn deploy`. * Set up next development iteration * Add a new section header to `docs/Changelog.md` like `x.y+1.0-SNAPSHOT (in progress)` @@ -297,14 +328,16 @@ these steps manually by following the checklist. * `git push` * Check that Maven artifact appears on Maven Central * [Directory listing of OTP releases on Maven Central](https://repo1.maven.org/maven2/org/opentripplanner/otp/) - * It may take a while (half an hour) for releases to show up in the central repo after Travis uploads the artifacts + * It may take a while (half an hour) for releases to show up in the central repo after Travis + uploads the artifacts * Merge master back into dev (to sync up the Maven artifact version from the POM) * `git checkout dev-2.x` * `git merge master` * `git push` * Make sure the main documentation is built * For some reason it doesn't always build automatically - * Go to [builds of docs.opentripplanner.org](http://readthedocs.org/projects/opentripplanner/builds/) + * Go + to [builds of docs.opentripplanner.org](http://readthedocs.org/projects/opentripplanner/builds/) * Click "build version: latest" * Email the OTP dev and users mailing lists * Mention the new version number. @@ -312,20 +345,19 @@ these steps manually by following the checklist. * Provide links to the artifacts directory on Maven Central. * Trigger build of latest OTP documentation on Readthedocs. - ### Artifact Signing -Maven release artifacts must be digitally signed to prove their origin. This is a safeguard against +Maven release artifacts must be digitally signed to prove their origin. This is a safeguard against compromised code from a malicious third party being disguised as a trusted library. -The OTP artifact signing key was created by Conveyal. We export only that signing subkey, with our +The OTP artifact signing key was created by Conveyal. We export only that signing subkey, with our company's main key blanked out. Therefore, even if someone managed to acquire the decrypted key file and the associated GPG passphrase, they would not have the main key. We could deactivate the signing key and create a new one, without the main key being compromised. When modified for Maven Central deployment, OpenTripPlanner's POM is set up to sign artifacts in the -verify phase, which means signing will happen for the `install` and `deploy` targets, but not the -`package` target. When performing a local test build, if you do `mvn clean install site` it will -test the signing process. If you do not have the certificate installed, you can instead do +verify phase, which means signing will happen for the `install` and `deploy` targets, but not the +`package` target. When performing a local test build, if you do `mvn clean install site` it will +test the signing process. If you do not have the certificate installed, you can instead do `mvn clean package site` to bypass signing, but this provides less certainty that everything is set up correctly for the CI-driven final release. diff --git a/docs/Getting-OTP.md b/docs/Getting-OTP.md index 8c4726242e0..6e92d1516da 100644 --- a/docs/Getting-OTP.md +++ b/docs/Getting-OTP.md @@ -2,17 +2,29 @@ ## Pre-built JARs -OpenTripPlanner is distributed as a single stand-alone runnable JAR file. We create a tag and release page on GitHub for each release version, and also deploy them to the Maven Central repository. You can go to the [release pages on GitHub](https://github.com/opentripplanner/OpenTripPlanner/releases) 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.1.0-SNAPSHOT` refer to development builds _before_ the release version `v2.1.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 build OTP every time a change is made. You can find the JARs resulting from those builds in the [Github Packages repository](https://github.com/opentripplanner/OpenTripPlanner/packages/562174). It can be harder to find the specific version you're looking for here, so we recommend using the release pages or Maven Central as described above. +OpenTripPlanner is distributed as a single stand-alone runnable JAR file. We create a tag and +release page on GitHub for each release version, and also deploy them to the Maven Central +repository. You can go to +the [release pages on GitHub](https://github.com/opentripplanner/OpenTripPlanner/releases) +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.1.0-SNAPSHOT` refer to development builds _ +before_ the release version `v2.1.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 +build OTP every time a change is made. You can find the JARs resulting from those builds in +the [Github Packages repository](https://github.com/opentripplanner/OpenTripPlanner/packages/562174) +. It can be harder to find the specific version you're looking for here, so we recommend using the +release pages or Maven Central as described above. ## Building from Source -You may also choose to build OTP from its source code. If you will be modifying OTP you will need to know how to rebuild - it (though your IDE may take care of this build cycle for you). If you have the right software installed, - building OTP locally from its source code is not particularly difficult. You should only need the following software: +You may also choose to build OTP from its source code. If you will be modifying OTP you will need to +know how to rebuild it (though your IDE may take care of this build cycle for you). If you have the +right software installed, building OTP locally from its source code is not particularly difficult. +You should only need the following software: - Git, a version control system @@ -20,9 +32,11 @@ You may also choose to build OTP from its source code. If you will be modifying - Maven, a build and dependency management system -You will also need a reliable internet connection so Maven can fetch all of OTP's dependencies (the libraries it uses). +You will also need a reliable internet connection so Maven can fetch all of OTP's dependencies (the +libraries it uses). -Once you have these packages installed, create and/or switch to the directory where you will keep your Git repositories and make a local copy of the OTP source code: +Once you have these packages installed, create and/or switch to the directory where you will keep +your Git repositories and make a local copy of the OTP source code: ```shell mkdir git @@ -36,8 +50,9 @@ Then change to the newly cloned OpenTripPlanner repository directory and start a cd OpenTripPlanner mvn clean package ``` -Maven should then be able to download all the libraries and other dependencies necessary to compile OTP. -If all goes well you should see a success message like the following: + +Maven should then be able to download all the libraries and other dependencies necessary to compile +OTP. If all goes well you should see a success message like the following: ``` [INFO] ------------------------------------------------------------------------ @@ -49,22 +64,24 @@ 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. - -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 including "package", - which bundles the compiled program into a single JAR file for distribution. - -If you have just cloned OTP you will be working with the default "master" branch, where most active development occurs. - This is not the most stable or deployment-ready code available. To avoid newly minted bugs or undocumented behavior, - you can use Git to check out a specific release (tag or branch) of OTP to work with. The Maven build also includes - many time-consuming integration tests. When working with a stable release of OTP, - you may want to turn them off by adding the switch: `-DskipTests`. +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. + +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 +including "package", which bundles the compiled program into a single JAR file for distribution. + +If you have just cloned OTP you will be working with the default "master" branch, where most active +development occurs. This is not the most stable or deployment-ready code available. To avoid newly +minted bugs or undocumented behavior, you can use Git to check out a specific release (tag or +branch) of OTP to work with. The Maven build also includes many time-consuming integration tests. +When working with a stable release of OTP, you may want to turn them off by adding the +switch: `-DskipTests`. For example, you could do the following: @@ -75,24 +92,29 @@ git clean -df mvn clean package -DskipTests ``` -Please note that the build process creates two distinct versions of the OTP JAR file. The one ending in `-shaded.jar` -is much bigger because it contains copies of all the external libraries that OTP uses. -It serves as a stand-alone runnable distribution of OTP. The one with a version number but without the word `shaded` -contains only OTP itself, without any external dependencies. This JAR is useful when OTP is included as a component in -some other project, where we want the dependency management system to gather all the external libraries automatically. - +Please note that the build process creates two distinct versions of the OTP JAR file. The one ending +in `-shaded.jar` +is much bigger because it contains copies of all the external libraries that OTP uses. It serves as +a stand-alone runnable distribution of OTP. The one with a version number but without the +word `shaded` +contains only OTP itself, without any external dependencies. This JAR is useful when OTP is included +as a component in some other project, where we want the dependency management system to gather all +the external libraries automatically. ## Maven Repository -OpenTripPlanner is a Maven project. Maven is a combined build and dependency management system: it fetches -all the external libraries that OTP uses, runs all the commands to compile the OTP source code into runnable form, -performs tests, and can then deploy the final "artifact" (the runnable JAR file) to the Maven repository, from which it -can be automatically included in other Java projects. +OpenTripPlanner is a Maven project. Maven is a combined build and dependency management system: it +fetches all the external libraries that OTP uses, runs all the commands to compile the OTP source +code into runnable form, performs tests, and can then deploy the final "artifact" (the runnable JAR +file) to the Maven repository, from which it can be automatically included in other Java projects. -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.1.0 will be found at `https://repo1.maven.org/maven2/org/opentripplanner/otp/2.1.0/otp-2.1.0-shaded.jar`. +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.1.0 will be found +at `https://repo1.maven.org/maven2/org/opentripplanner/otp/2.1.0/otp-2.1.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`: +To make use of OTP in another Maven project, you must specify it as a dependency in that +project's `pom.xml`: ```XML @@ -102,7 +124,11 @@ To make use of OTP in another Maven project, you must specify it as a dependency ``` -After each successful build, the [Travis continuous integration system](https://travis-ci.org/opentripplanner/OpenTripPlanner) deploys the final OTP "artifact" (the runnable JAR) to our Maven repository as a "SNAPSHOT" build. This means that a Maven project depending on OTP as a library can always fetch the latest work in progress by specifying a snapshot artifact: +After each successful build, +the [Travis continuous integration system](https://travis-ci.org/opentripplanner/OpenTripPlanner) +deploys the final OTP "artifact" (the runnable JAR) to our Maven repository as a "SNAPSHOT" build. +This means that a Maven project depending on OTP as a library can always fetch the latest work in +progress by specifying a snapshot artifact: ```XML diff --git a/docs/Governance.md b/docs/Governance.md index 952253838ea..89626f7a59f 100644 --- a/docs/Governance.md +++ b/docs/Governance.md @@ -1,8 +1,9 @@ # Project Governance -OpenTripPlanner is a member project of the [Software Freedom Conservancy](https://sfconservancy.org/members/current/). -Development of OpenTripPlanner is managed by a Project Leadership Committee (PLC) which makes decisions by simple majority vote. -The current members of this committee are (in alphabetical order): +OpenTripPlanner is a member project of +the [Software Freedom Conservancy](https://sfconservancy.org/members/current/). Development of +OpenTripPlanner is managed by a Project Leadership Committee (PLC) which makes decisions by simple +majority vote. The current members of this committee are (in alphabetical order): | Name | Affiliation | |-------------------|--------------------------------------------------------------| @@ -18,16 +19,18 @@ The current members of this committee are (in alphabetical order): | Frank Purcell | [TriMet](https://trimet.org/) (Portland, Oregon) | | David Turner | ex-[OpenPlans](https://www.openplans.org/) | -The PLC holds a quarterly video conference on the first Tuesday of June, September, December, and March. -An agenda is prepared as a collaborative document in advance of each quarterly meeting. -These meetings are held at 8AM US Pacific time to accommodate members in the US Pacific, US Eastern, and Central European time zones. +The PLC holds a quarterly video conference on the first Tuesday of June, September, December, and +March. An agenda is prepared as a collaborative document in advance of each quarterly meeting. These +meetings are held at 8AM US Pacific time to accommodate members in the US Pacific, US Eastern, and +Central European time zones. -We take care to avoid a governance system that is too conceptual or process-heavy. -The main goal is to have regular agenda-driven meetings that yield clear decisions and action items assigned to specific people. -The committee should ideally be composed of active, professional contributors to the OpenTripPlanner project, -including representatives of organizations that host official public deployments of OTP. +We take care to avoid a governance system that is too conceptual or process-heavy. The main goal is +to have regular agenda-driven meetings that yield clear decisions and action items assigned to +specific people. The committee should ideally be composed of active, professional contributors to +the OpenTripPlanner project, including representatives of organizations that host official public +deployments of OTP. -We enfore a policy on the review and merging of new changes to the OTP system, -guided by a roadmap maintained by the committee. -All changes must be reviewed and approved by at least two people from two different organizations. -The list of approved reviewers is the PLC Github group, visible here https://github.com/orgs/opentripplanner/teams/plc/members +We enfore a policy on the review and merging of new changes to the OTP system, guided by a roadmap +maintained by the committee. All changes must be reviewed and approved by at least two people from +two different organizations. The list of approved reviewers is the PLC Github group, visible +here https://github.com/orgs/opentripplanner/teams/plc/members diff --git a/docs/History.md b/docs/History.md index 6ec8b7b90b6..e51519c1520 100644 --- a/docs/History.md +++ b/docs/History.md @@ -2,25 +2,83 @@ ## OpenTripPlanner 1 -OpenTripPlanner was seeded by Portland, Oregon's transit agency [TriMet](http://trimet.org/) with a [Regional Travel Options grant](http://www.oregonmetro.gov/tools-partners/grants-and-resources/travel-options-grants) and opened with a [3-day Kick-Off Workshop](https://github.com/opentripplanner/OpenTripPlanner/wiki/kick-off-workshop) in July of 2009 bringing together transit agencies and the authors of the major open source transit passenger information software of the day: David Emory of FivePoints, Brian Ferris of [OneBusAway](https://github.com/OneBusAway/onebusaway/wiki), and Brandon Martin-Anderson of [Graphserver](http://graphserver.github.io/graphserver/). From 2009 through 2012, development was coordinated by New York nonprofit [OpenPlans](http://openplans.org/). In 2011 a second workshop was held to mark the end of the first phase of development. TriMet's 2009-2011 [OTP Final Report](https://raw.githubusercontent.com/wiki/opentripplanner/OpenTripPlanner/History/2011-07-OTP-Workshop/OTP%202009-2011%20RTO%20Grant%20Final%20Report.pdf) summarizes progress at that point. +OpenTripPlanner was seeded by Portland, Oregon's transit agency [TriMet](http://trimet.org/) with +a [Regional Travel Options grant](http://www.oregonmetro.gov/tools-partners/grants-and-resources/travel-options-grants) +and opened with +a [3-day Kick-Off Workshop](https://github.com/opentripplanner/OpenTripPlanner/wiki/kick-off-workshop) +in July of 2009 bringing together transit agencies and the authors of the major open source transit +passenger information software of the day: David Emory of FivePoints, Brian Ferris +of [OneBusAway](https://github.com/OneBusAway/onebusaway/wiki), and Brandon Martin-Anderson +of [Graphserver](http://graphserver.github.io/graphserver/). From 2009 through 2012, development was +coordinated by New York nonprofit [OpenPlans](http://openplans.org/). In 2011 a second workshop was +held to mark the end of the first phase of development. TriMet's +2009-2011 [OTP Final Report](https://raw.githubusercontent.com/wiki/opentripplanner/OpenTripPlanner/History/2011-07-OTP-Workshop/OTP%202009-2011%20RTO%20Grant%20Final%20Report.pdf) +summarizes progress at that point. -The project has since grown to encompass a global community of users and developers. By early 2013, OpenTripPlanner had become the primary trip planning software used by TriMet in the [Portland regional trip planner](http://ride.trimet.org/) and was backing several popular mobile applications. Public-facing OpenTripPlanner instances were available in at least ten countries throughout the world. At this point the OpenPlans transportation software team became the independent consultancy [Conveyal](http://www.conveyal.com/). The original OpenTripPlanner development team from OpenPlans still actively participates in programming, design, and community coordination via the mailing list and their roles on the OTP [Project Leadership Committee](Governance.md). +The project has since grown to encompass a global community of users and developers. By early 2013, +OpenTripPlanner had become the primary trip planning software used by TriMet in +the [Portland regional trip planner](http://ride.trimet.org/) and was backing several popular mobile +applications. Public-facing OpenTripPlanner instances were available in at least ten countries +throughout the world. At this point the OpenPlans transportation software team became the +independent consultancy [Conveyal](http://www.conveyal.com/). The original OpenTripPlanner +development team from OpenPlans still actively participates in programming, design, and community +coordination via the mailing list and their roles on the +OTP [Project Leadership Committee](Governance.md). -In summer of 2013, the OpenTripPlanner project was accepted for membership in the [Software Freedom Conservancy (SFC)](http://sfconservancy.org/). SFC handles the legal and financial details common to many open source projects. +In summer of 2013, the OpenTripPlanner project was accepted for membership in +the [Software Freedom Conservancy (SFC)](http://sfconservancy.org/). SFC handles the legal and +financial details common to many open source projects. -In 2013-2014 OpenTripPlanner was a focal point in the Dutch Transport Ministry's Beter Benutten Multimodale Reisinformatie (Better Utilization: Multimodal Travel Information) project which encouraged investment in trip planning platforms and services. [Five companies worked together](https://www.ovmagazine.nl/nieuws/vijf-nieuwe-actuele-ov-routeplanners-zijn-af) to improve OpenTripPlanner performance in large regional transport networks and add support for streaming real-time data, making itineraries reflect service modifications and delays only seconds after vehicles report their positions. Another consortium embarked on a full rewrite of the trip planning core called [RRRR (or R4)](https://github.com/bliksemlabs/rrrr), a proof of concept validating extremely efficient routing techniques and serving as an early prototype for OTP2. +In 2013-2014 OpenTripPlanner was a focal point in the Dutch Transport Ministry's Beter Benutten +Multimodale Reisinformatie (Better Utilization: Multimodal Travel Information) project which +encouraged investment in trip planning platforms and +services. [Five companies worked together](https://www.ovmagazine.nl/nieuws/vijf-nieuwe-actuele-ov-routeplanners-zijn-af) +to improve OpenTripPlanner performance in large regional transport networks and add support for +streaming real-time data, making itineraries reflect service modifications and delays only seconds +after vehicles report their positions. Another consortium embarked on a full rewrite of the trip +planning core called [RRRR (or R4)](https://github.com/bliksemlabs/rrrr), a proof of concept +validating extremely efficient routing techniques and serving as an early prototype for OTP2. -In the fall of 2014, Arlington, Virginia launched a new commute planning site for the Washington, DC metropolitan area, depending on OpenTripPlanner to weigh the costs and benefits of various travel options. In 2015 the New York State department of transportation's 511 transit trip planner began using OTP to provide itineraries for public transit systems throughout the state from a single unified OTP instance. Starting in early 2016, the regional transport authorities of Helsinki, Finland (HSL) and Oslo, Norway (Ruter) began using a completely open source passenger information system based on OpenTripPlanner. National-scale OpenTripPlanner instances were also created in Finland and Norway. - -After seven years of hard work and almost 10,000 commits from over 100 contributors around the world, OTP version 1.0 was released on 9 September 2016. +In the fall of 2014, Arlington, Virginia launched a new commute planning site for the Washington, DC +metropolitan area, depending on OpenTripPlanner to weigh the costs and benefits of various travel +options. In 2015 the New York State department of transportation's 511 transit trip planner began +using OTP to provide itineraries for public transit systems throughout the state from a single +unified OTP instance. Starting in early 2016, the regional transport authorities of Helsinki, +Finland (HSL) and Oslo, Norway (Ruter) began using a completely open source passenger information +system based on OpenTripPlanner. National-scale OpenTripPlanner instances were also created in +Finland and Norway. +After seven years of hard work and almost 10,000 commits from over 100 contributors around the +world, OTP version 1.0 was released on 9 September 2016. ## OpenTripPlanner 2 -The OTP community has a long history with round-based routing algorithms. FivePoints, one of the predecessor projects to OTP, used a round-based method several years before the now-familiar Raptor algorithm was published in [an influential paper](https://www.microsoft.com/en-us/research/wp-content/uploads/2012/01/raptor_alenex.pdf). OpenPlans carried out experiments with routing innovations like Raptor and contraction hierarchies as they emerged in the academic literature. Research and development work on OTP scalability has focused on round-based tabular approaches since the MMRI pre-commercial procurement projects of 2013-2014. Conveyal built its high-performance transportation network analysis system around its [R5 router](https://github.com/conveyal/r5). So in strategy discussions, the expected technical direction was clear. +The OTP community has a long history with round-based routing algorithms. FivePoints, one of the +predecessor projects to OTP, used a round-based method several years before the now-familiar Raptor +algorithm was published +in [an influential paper](https://www.microsoft.com/en-us/research/wp-content/uploads/2012/01/raptor_alenex.pdf) +. OpenPlans carried out experiments with routing innovations like Raptor and contraction hierarchies +as they emerged in the academic literature. Research and development work on OTP scalability has +focused on round-based tabular approaches since the MMRI pre-commercial procurement projects of +2013-2014. Conveyal built its high-performance transportation network analysis system around +its [R5 router](https://github.com/conveyal/r5). So in strategy discussions, the expected technical +direction was clear. -In the second quarter of 2018, Ruter and Entur took the lead on finally integrating a new round-based transit routing engine inspired by R5 into OTP. They also began adding support for importing EU-standard Netex data, making it possible for passenger information services in Europe to achieve regulatory compliance with a fully open source software stack. In June 2018, at the first OTP international summit hosted by Cambridge Systematics in Boston, the project leadership committee officially approved this roadmap toward OTP2. +In the second quarter of 2018, Ruter and Entur took the lead on finally integrating a new +round-based transit routing engine inspired by R5 into OTP. They also began adding support for +importing EU-standard Netex data, making it possible for passenger information services in Europe to +achieve regulatory compliance with a fully open source software stack. In June 2018, at the first +OTP international summit hosted by Cambridge Systematics in Boston, the project leadership committee +officially approved this roadmap toward OTP2. -In April of 2019, the second OTP international summit was hosted by Entur in Oslo. Encouraged by the crowd of participants from across the Nordic countries and North America, work on OTP2 continued unabated through 2019, 2020, and 2021 with twice-weekly videoconferences bringing together software developers from across the world. Videos of the full [April 2019 OTP summit](https://www.youtube.com/watch?v=QZdpP73zuX0) and the [October 2019 OTP webinar](https://www.youtube.com/watch?v=_2d68s_U4Tc) are available. +In April of 2019, the second OTP international summit was hosted by Entur in Oslo. Encouraged by the +crowd of participants from across the Nordic countries and North America, work on OTP2 continued +unabated through 2019, 2020, and 2021 with twice-weekly videoconferences bringing together software +developers from across the world. Videos of the +full [April 2019 OTP summit](https://www.youtube.com/watch?v=QZdpP73zuX0) and +the [October 2019 OTP webinar](https://www.youtube.com/watch?v=_2d68s_U4Tc) are available. -OTP2 went into feature freeze in September 2020, and the 2.0 release occurred at the end of November 2020. OTP2 is now seeing production use for a subset of requests in several national-scale trip planners. The project leadership committee is exploring the creation of an OTP1 working group to ensure follow-up maintenance of the final version of OTP1. +OTP2 went into feature freeze in September 2020, and the 2.0 release occurred at the end of November +2020. OTP2 is now seeing production use for a subset of requests in several national-scale trip +planners. The project leadership committee is exploring the creation of an OTP1 working group to +ensure follow-up maintenance of the final version of OTP1. diff --git a/docs/Interfaces-Data-Sources.md b/docs/Interfaces-Data-Sources.md index d64e06d6f63..f8e64cbaacd 100644 --- a/docs/Interfaces-Data-Sources.md +++ b/docs/Interfaces-Data-Sources.md @@ -1,28 +1,45 @@ # OTP Interfaces (APIs) and Data Sources - ## Input Formats -At the core of OpenTripPlanner is a library of Java code that finds efficient paths through multi-modal transportation networks built from [OpenStreetMap](http://wiki.openstreetmap.org/wiki/Main_Page) and [GTFS](https://developers.google.com/transit/gtfs/) data. It can also receive GTFS-RT (realtime) data... +At the core of OpenTripPlanner is a library of Java code that finds efficient paths through +multi-modal transportation networks built +from [OpenStreetMap](http://wiki.openstreetmap.org/wiki/Main_Page) +and [GTFS](https://developers.google.com/transit/gtfs/) data. It can also receive GTFS-RT (realtime) +data... -In addition to GTFS, OTP2 can also load data in the Nordic Profile of Netex, the EU-standard transit data interchange format. The upcoming EU-wide profile was heavily influenced by the Nordic Profile and uses the same schema, so eventual support for the full the EU profile is a possibility. +In addition to GTFS, OTP2 can also load data in the Nordic Profile of Netex, the EU-standard transit +data interchange format. The upcoming EU-wide profile was heavily influenced by the Nordic Profile +and uses the same schema, so eventual support for the full the EU profile is a possibility. -GTFS and Netex data are converted into OTP's own internal model which is a superset of both. It is therefore possible to mix Netex and GTFS data, and potentially even data from other sources. +GTFS and Netex data are converted into OTP's own internal model which is a superset of both. It is +therefore possible to mix Netex and GTFS data, and potentially even data from other sources. ## Interfaces to Services (APIs) Several different services are built upon this routing library, and expose APIs: -The **OTP Routing API** is a [RESTful](https://en.wikipedia.org/wiki/Representational_state_transfer) web service that responds to journey planning requests with itineraries in a JSON or XML representation. You can combine this API with OTP's standard Javascript front end to provide users with trip planning functionality in a familiar map interface, or write your own applications that talk directly to the API. +The **OTP Routing API** is +a [RESTful](https://en.wikipedia.org/wiki/Representational_state_transfer) web service that responds +to journey planning requests with itineraries in a JSON or XML representation. You can combine this +API with OTP's standard Javascript front end to provide users with trip planning functionality in a +familiar map interface, or write your own applications that talk directly to the API. -The **OTP Transit Index API** is another [RESTful](https://en.wikipedia.org/wiki/Representational_state_transfer) web service that provides information derived from the input GTFS feed(s). Examples include routes serving a particular stop, upcoming vehicles at a particular stop, upcoming stops on a given trip, etc. More complex transit data requests can be formulated using a GraphQL API. +The **OTP Transit Index API** is +another [RESTful](https://en.wikipedia.org/wiki/Representational_state_transfer) web service that +provides information derived from the input GTFS feed(s). Examples include routes serving a +particular stop, upcoming vehicles at a particular stop, upcoming stops on a given trip, etc. More +complex transit data requests can be formulated using a GraphQL API. ## Sandbox APIs Additional experimental APIs are provided by [sandbox extensions](SandboxExtension.md): -The [Actuator API](sandbox/ActuatorAPI.md) provides endpoints for checking the health status of the OTP instance. It can be useful when running OTP in a container. +The [Actuator API](sandbox/ActuatorAPI.md) provides endpoints for checking the health status of the +OTP instance. It can be useful when running OTP in a container. -The [Transmodel GraphQL API](sandbox/TransmodelApi.md) is the Transmodel API (version 3) used at Entur in production(Sep, 2020). +The [Transmodel GraphQL API](sandbox/TransmodelApi.md) is the Transmodel API (version 3) used at +Entur in production(Sep, 2020). -The [HSL Legacy GraphQL API](sandbox/LegacyGraphQLApi.md) is the HSL's GraphQL API used by the Digitransit project. +The [HSL Legacy GraphQL API](sandbox/LegacyGraphQLApi.md) is the HSL's GraphQL API used by the +Digitransit project. diff --git a/docs/Localization.md b/docs/Localization.md index 57508b0fe20..ca7dbb277c1 100644 --- a/docs/Localization.md +++ b/docs/Localization.md @@ -1,17 +1,20 @@ - # 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. +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. +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 +- [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. @@ -23,24 +26,33 @@ Three types of files are used in the OTP localization process: - `.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. +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: +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). +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. +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: +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 @@ -48,11 +60,13 @@ When you add strings to the source code, if you think that translators might not 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. +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 @@ -62,19 +76,23 @@ html += '
  • ' + _tr('Board') + ': ' + leg.from.name + ' (' + leg.from.st //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()}) + '

    '; +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())+'

    '; +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; - + 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; +html += " " + otp.util.Itin.distanceString(leg.distance) + pgettext("direction", " to ") + leg.to.name; ``` @@ -85,63 +103,91 @@ html += " "+otp.util.Itin.distanceString(leg.distance)+ pgettext("direction", " 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. +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). +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. +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/). +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) +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. +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. +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. +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. +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 `opentripplanner-dev` mailing list stating what language you want to translate, and someone will make you a corresponding `.po` file. +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 `opentripplanner-dev` mailing list 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`. +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: +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). +- 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. + +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: @@ -152,18 +198,32 @@ Then take the following steps: #### 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. +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 +- [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. +- [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. +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. +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/docs/Netex-Norway.md b/docs/Netex-Norway.md index 5700aaa7409..e9fc3b8a219 100644 --- a/docs/Netex-Norway.md +++ b/docs/Netex-Norway.md @@ -2,19 +2,36 @@ ## 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. +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. +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, @@ -39,23 +56,40 @@ The `build-config.json` for a Norwegian graph using Netex data looks like this: } ``` -Note the special section specifying how to find Netex XML files within the single ZIP archive you downloaded. +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: +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. +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. + +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 Realtime Data -Another important feature in OTP2 is the ability to use [SIRI realtime 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 realtime 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. +Another important feature in OTP2 is the ability to +use [SIRI realtime 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 realtime 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 { @@ -90,14 +124,20 @@ Another important feature in OTP2 is the ability to use [SIRI realtime data](htt } ``` -The first three updaters fetch three different kinds of SIRI data: +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. +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. +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 realtime data into a format suitable for use by OTP2's new Raptor router. Without this updater the realtime data will be received and cataloged, but not visible to the router. +The final updater regularly performs a copy of the realtime data into a format suitable for use by +OTP2's new Raptor router. Without this updater the realtime data will be received and cataloged, but +not visible to the router. diff --git a/docs/OTP2-MigrationGuide.md b/docs/OTP2-MigrationGuide.md index 9ed23b3409e..2b155087383 100644 --- a/docs/OTP2-MigrationGuide.md +++ b/docs/OTP2-MigrationGuide.md @@ -2,48 +2,54 @@ ## Command Line -The OTP2 command line parameters are different than in OTP1. Use the `--help` option to get the -current documentation, and look at [Basic Tutorial - Starting OTP](Basic-Tutorial.md#starting-otp) -for examples. The possibility to build the graph in 2 steps (streets then transit) is new in OTP2. -OTP2 does not support routing on more than one separate transportation network with a single +The OTP2 command line parameters are different than in OTP1. Use the `--help` option to get the +current documentation, and look at [Basic Tutorial - Starting OTP](Basic-Tutorial.md#starting-otp) +for examples. The possibility to build the graph in 2 steps (streets then transit) is new in OTP2. +OTP2 does not support routing on more than one separate transportation network with a single server (referred to as multiple "routers" in OTP1). - ## File Loading -OTP1 reads and writes all files on the local filesystem, and no other _data-source_ is supported. -In OTP2 we support accessing cloud storage. So far support for Google Cloud Storage has been added -and we plan to add support for AWS S3 as well. Config files (_otp-config.json, build-config.json, -router-config.json_) must be read from the local file system, while other files can be read/written +OTP1 reads and writes all files on the local filesystem, and no other _data-source_ is supported. In +OTP2 we support accessing cloud storage. So far support for Google Cloud Storage has been added and +we plan to add support for AWS S3 as well. Config files (_otp-config.json, build-config.json, +router-config.json_) must be read from the local file system, while other files can be read/written from either the local filesystem or cloud storage. OTP2 supports mixing any supported data sources. -OTP1 loads input data files (_DEM, OSM, GTFS, NeTEx_) based on the suffix (file extension). But for -GTFS files OTP1 also opens the zip-file and looks for _stops.txt_. OTP2 identifies GTFS files by the -name only: it will detect any zip-file or directory that contains "gtfs" as part of the name. All -file types in OTP2 are resolved by matching the name with a regexp pattern. You can configure the -patterns in the _build-config.json_ if the defaults do not suit you. - -OTP2 does not support multiple routers (separate named networks to route on), but you can load as -many GTFS and/or NeTEx feeds as you want into a single routable network in a single instance of OTP2. +OTP1 loads input data files (_DEM, OSM, GTFS, NeTEx_) based on the suffix (file extension). But for +GTFS files OTP1 also opens the zip-file and looks for _stops.txt_. OTP2 identifies GTFS files by the +name only: it will detect any zip-file or directory that contains "gtfs" as part of the name. All +file types in OTP2 are resolved by matching the name with a regexp pattern. You can configure the +patterns in the _build-config.json_ if the defaults do not suit you. +OTP2 does not support multiple routers (separate named networks to route on), but you can load as +many GTFS and/or NeTEx feeds as you want into a single routable network in a single instance of +OTP2. ## Build Config + OTP will log all unrecognized parameters when starting up. Make sure to investigate all log events of this type: + ``` 16:18:46.911 WARN (NodeAdapter.java:413) Unexpected config parameter: 'fetchElevationUS:false' in 'build-config.json'. Is the spelling correct? ``` #### New parameters + - `configVersion` Optional parameter which can be used to version the build config file. Since v2.1 - `dataOverlay` Config for the DataOverlay Sandbox module. Since v2.1 -- `maxAreaNodes` Visibility calculations will not be done for areas with more nodes than this limit. Since v2.1 -- `maxJourneyDuration` This limits the patterns we consider in the transit search. See [RoutingRequest](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/routing/api/request/RoutingRequest.java). Since v2.1 +- `maxAreaNodes` Visibility calculations will not be done for areas with more nodes than this limit. + Since v2.1 +- `maxJourneyDuration` This limits the patterns we consider in the transit search. + See [RoutingRequest](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/routing/api/request/RoutingRequest.java) + . Since v2.1 - `maxStopToShapeSnapDistance` Used for mapping route geometry shapes. Since v2.1 - `transferRequests` Pre-calculate transfers. Since v2.1 -- `transitServiceStart` Limit the import of transit services to the given *start* date. Default: `-P1Y`. Since v2.0 -- `transitServiceEnd` Limit the import of transit services to the given *end* date. *Inclusive*. Default: `P3Y`. Since v2.0 - +- `transitServiceStart` Limit the import of transit services to the given *start* date. + Default: `-P1Y`. Since v2.0 +- `transitServiceEnd` Limit the import of transit services to the given *end* date. *Inclusive*. + Default: `P3Y`. Since v2.0 #### Parameters whose names were changed @@ -53,7 +59,6 @@ of this type: - `maxHtmlAnnotationsPerFile` to `maxDataImportIssuesPerFile`. Since v2.0 - `maxTransferDistance` to `maxTransferDurationSeconds`. Since v2.1 - #### These parameters are no longer supported - `fetchElevationUS`. Since v2.1 @@ -63,134 +68,130 @@ of this type: - `stopClusterMode`. Since v2.0 - `useTransfersTxt`. Since v2.1 - - OTP2 records the "parentStation" relationship between stops and stations in its internal transit - model, based on the GTFS and/or NeTEx input. This enables OTP to search from all stop in a station - _without_ walking/waiting when the request from/to input field is a station id. There is no way to - automatically infer this parent station relationship based on geographic proximity in OTP2. - - Transfers in OTP2 are generated based on the stop location and the OSM data or GTFS Pathways. In - future versions of OTP2 we also want to support generating simple transfers based on - "line-of-sight" if no pathways or OSM data exist. See issue - [#3204](https://github.com/opentripplanner/OpenTripPlanner/issues/3204). - - Cleaning and patching input data is NOT a core feature of OTP, but anyone is welcome to implement - a sandbox plugin to patch data. So, if any of the features above are needed they can be ported - from OTP1 into an OTP2 sandbox feature. - - +OTP2 records the "parentStation" relationship between stops and stations in its internal transit +model, based on the GTFS and/or NeTEx input. This enables OTP to search from all stop in a station +_without_ walking/waiting when the request from/to input field is a station id. There is no way to +automatically infer this parent station relationship based on geographic proximity in OTP2. + +Transfers in OTP2 are generated based on the stop location and the OSM data or GTFS Pathways. In +future versions of OTP2 we also want to support generating simple transfers based on +"line-of-sight" if no pathways or OSM data exist. See issue +[#3204](https://github.com/opentripplanner/OpenTripPlanner/issues/3204). + +Cleaning and patching input data is NOT a core feature of OTP, but anyone is welcome to implement a +sandbox plugin to patch data. So, if any of the features above are needed they can be ported from +OTP1 into an OTP2 sandbox feature. + ## Router Config -See the [Router Configuration](RouterConfiguration) for a description of the -new and existing routing parameters. +See the [Router Configuration](RouterConfiguration) for a description of the new and existing +routing parameters. #### New parameters - `flex` Add configuration for flex services (sandbox feature). Since v2.1 - `configVersion` Optional parameter which can be used to version the build config file. Since v2.1 -- `streetRoutingTimeout` Maximum time limit for street route queries. Replace the old `timeout`. Since v2.0 +- `streetRoutingTimeout` Maximum time limit for street route queries. Replace the old `timeout`. + Since v2.0 - `transit` A set of parameters to tune the Raptor transit router. Since v2.0, changed in v2.1 -- `itineraryFilters` Configure itinerary filters that may modify itineraries, sort them, and - filter away less preferable results. Since v2.0, changed in v2.1 +- `itineraryFilters` Configure itinerary filters that may modify itineraries, sort them, and filter + away less preferable results. Since v2.0, changed in v2.1 - `transferOptimization` Configure the new transfer optimization feature. Since 2.1 - #### These parameters are no longer supported - - `timeout` Replaced by `streetRoutingTimeout`. Since v2.0 - - `timeouts` OTP1 searches the graph many times. OTP2 finds multiple results in a single search so there is no longer a need for this parameter. Since v2.0 - - `boardTimes` is replaced by `request` parameter `boardSlack` and `boardSlackForMode`. Since v2.0 - - `alightTimes` is replaced by `request` parameter `alightSlack` and `alightSlackForMode`. Since v2.0 - - -## REST API +- `timeout` Replaced by `streetRoutingTimeout`. Since v2.0 +- `timeouts` OTP1 searches the graph many times. OTP2 finds multiple results in a single search so + there is no longer a need for this parameter. Since v2.0 +- `boardTimes` is replaced by `request` parameter `boardSlack` and `boardSlackForMode`. Since v2.0 +- `alightTimes` is replaced by `request` parameter `alightSlack` and `alightSlackForMode`. Since + v2.0 -### Trip Planning +## REST API -Support for XML as a request/response format is removed. The only supported format is JSON. -Some of these parameters may only be available as `defaultRequest` configuration parameters. +### Trip Planning +Support for XML as a request/response format is removed. The only supported format is JSON. Some of +these parameters may only be available as `defaultRequest` configuration parameters. #### Query parameter changes -A lot of the query parameters in the REST API are ignored/deprecated, see the [RoutingRequest](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/routing/api/request/RoutingRequest.java) - and the [RoutingResource](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/api/common/RoutingResource.java) - class for the documentation on what is now supported in OTP2. - - +A lot of the query parameters in the REST API are ignored/deprecated, see +the [RoutingRequest](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/routing/api/request/RoutingRequest.java) +and +the [RoutingResource](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/api/common/RoutingResource.java) +class for the documentation on what is now supported in OTP2. + #### Parameters missing in OTP2 but intended to be reintroduced -- `startingTransitTripId` - ability to plan a trip from on board a vehicle -- `intermediatePlaces` - ability to specify intermediate destinations along the route. It is not - certain when this will be implemented. +- `startingTransitTripId` - ability to plan a trip from on board a vehicle +- `intermediatePlaces` - ability to specify intermediate destinations along the route. It is not + certain when this will be implemented. - `nonpreferredTransferCost`, `(un)preferredRoutes`, `(un)preferredAgencies` - these help diversify - or customize the trips and operators visible in results. Due to the new transit routing - algorithm, Entur plans to completely rewrite these features, accounting for market-neutrality - requirements and showing relevant trips and operators in local vs. intercity trips. - - - Some features in OTP1 will not be present upon launch in OTP2, and they are proposed to be removed - permanently from OTP2, but may require some development to support valid important cases: - + or customize the trips and operators visible in results. Due to the new transit routing algorithm, + Entur plans to completely rewrite these features, accounting for market-neutrality requirements + and showing relevant trips and operators in local vs. intercity trips. + +Some features in OTP1 will not be present upon launch in OTP2, and they are proposed to be removed +permanently from OTP2, but may require some development to support valid important cases: + - `maxWalkDistance`, `maxTransferWalkDistance`, & `maxWait` - these parameters impose hard limits - and are no longer the preferred way to reduce the amount of walking or waiting in returned - itineraries. In OTP2 the goal is to control this with `walkReluctance` and `waitReluctance`. - Internally some limits on walking and waiting do still exist, but they are set quite high so - trips with long walking or waiting times are still considered. Note that unlike in OTP1, if you - do set your own max walk or wait time on an API request, it will apply to both transit searches - and non-transit searches. -- `maxHours` & `useRequestedDateTimeInMaxHours` - This is replaced by `searchWindow`, which - limits the arrival or departure window of the trip -- `worstTime` - This factor returns the “worst” trip in a depart after/arrive by search, i.e. - the latest or earliest trip available. It is not a priority for current OTP2 users but could - be added as a filter. -- `waitAtBeginningFactor` - No longer necessary to weight the initial wait differently based on - the the Range Raptor search algorithm, which no longer prefers a departure at one valid time - over another. Filtering could be implemented on top of Raptor to show certain departure times - before others. + and are no longer the preferred way to reduce the amount of walking or waiting in returned + itineraries. In OTP2 the goal is to control this with `walkReluctance` and `waitReluctance`. + Internally some limits on walking and waiting do still exist, but they are set quite high so trips + with long walking or waiting times are still considered. Note that unlike in OTP1, if you do set + your own max walk or wait time on an API request, it will apply to both transit searches and + non-transit searches. +- `maxHours` & `useRequestedDateTimeInMaxHours` - This is replaced by `searchWindow`, which limits + the arrival or departure window of the trip +- `worstTime` - This factor returns the “worst” trip in a depart after/arrive by search, i.e. the + latest or earliest trip available. It is not a priority for current OTP2 users but could be added + as a filter. +- `waitAtBeginningFactor` - No longer necessary to weight the initial wait differently based on the + the Range Raptor search algorithm, which no longer prefers a departure at one valid time over + another. Filtering could be implemented on top of Raptor to show certain departure times before + others. - `pathComparator` - The ability to set a sort order based on departure or arrival should be the - domain of the API rather than the search. + domain of the API rather than the search. - `startingTransitStopId` - this is redundant, as the same thing can be achieved with fromPlace - `onlyTransitTrips` - it is now possible to specify access, egress, transit and direct modes - separately, making this parameter unnecessary. - + separately, making this parameter unnecessary. #### Parameters that have changed -- `numItineraries` The parameter is no longer used to terminate the request when the - numItineraries is found, instead the new `searchWindow` parameter should be used to limit the - search. In OTP2 it crops the list of itineraries AFTER the search is complete. This parameter - is a post search filter function. The best option is to configure this on the server side and - not use it as a client side input parameter. A side effect from reducing the result is that - OTP2 cannot guarantee to find all pareto-optimal itineraries when paging. Also, a large - search-window and a small `numItineraries` waste computer CPU calculation time. Consider - tuning the `searchWindow` instead of setting this to a small value. Since 2.0 -- `modes` The REST API is unchanged, but is mapped into a new structure in the RoutingRequest. - This means not all combinations of non-transit modes that was available in OTP1 is available in - OTP2. Since 2.0 +- `numItineraries` The parameter is no longer used to terminate the request when the numItineraries + is found, instead the new `searchWindow` parameter should be used to limit the search. In OTP2 it + crops the list of itineraries AFTER the search is complete. This parameter is a post search filter + function. The best option is to configure this on the server side and not use it as a client side + input parameter. A side effect from reducing the result is that OTP2 cannot guarantee to find all + pareto-optimal itineraries when paging. Also, a large search-window and a small `numItineraries` + waste computer CPU calculation time. Consider tuning the `searchWindow` instead of setting this to + a small value. Since 2.0 +- `modes` The REST API is unchanged, but is mapped into a new structure in the RoutingRequest. This + means not all combinations of non-transit modes that was available in OTP1 is available in OTP2. + Since 2.0 - `preferredAgencies`, `unpreferredAgencies`, `bannedAgencies` and `whiteListedAgencies` use - feed-scoped ids. If you are using the ids directly from the Index API, no changes are needed. - Since 2.0 + feed-scoped ids. If you are using the ids directly from the Index API, no changes are needed. + Since 2.0 - `maxTransferDistance`, replaced by `maxTransferDurationSeconds` Since 2.1 - `bannedTrips` no longer allows specifying stop indices, but only allows banning complete trips. - Since 2.2 - - + Since 2.2 #### New parameters in OTP2 - `alightSlackByMode` How much time alighting a vehicle takes for each given mode. Since 2.0 - `allowedVehicleRentalNetworks` and `bannedVehicleRentalNetworks`. Since 2.1 -- `bikeReluctance`, `bikeWalkingReluctance`, `bikeWalkingSpeed`, `carReluctance`, and `walkingBike` Add explicit bike / bike-walking / car / walk reluctance. Since 2.1 +- `bikeReluctance`, `bikeWalkingReluctance`, `bikeWalkingSpeed`, `carReluctance`, and `walkingBike` + Add explicit bike / bike-walking / car / walk reluctance. Since 2.1 - `boardSlackByMode` How much time ride a vehicle takes for each given mode. Since 2.0 -- `carPickupCost` and `carPickupTime`. Add a cost/time for CarPickup changes when a pickup or drop off takes place. Since 2.1 +- `carPickupCost` and `carPickupTime`. Add a cost/time for CarPickup changes when a pickup or drop + off takes place. Since 2.1 - `maxAccessEgressDurationSecondsForMode` Limit access/egress per street mode. Since 2.0 - `parkAndRideDurationRatio` Filter for park and ride with long walk. Since 2.1 - `requiredVehicleParkingTags` and `bannedVehicleParkingTags`. Since 2.1 - `searchWindow` Limit the departure window or arrival window for the routing search. Since 2.0 - `stairsTimeFactor` Add a penalty to the time it takes to walk up and down stairs. Since 2.1 - #### These parameters are no longer supported - `maxHours` Since 2.1 @@ -199,71 +200,71 @@ A lot of the query parameters in the REST API are ignored/deprecated, see the [R - `driveOnRight` You can specify the driving direction in your way property set. Since 2.1 - `bannedTrips` Not supported in 2.0 and 2.1 - #### Paging - In OTP1 most clients provided a way to break results into pages by looking at the trips returned - and issuing another request, supplying something like the `last-depature-time` + 1 minute to the - next request. This yields another batch of trips to show to the user. In OTP2 the recommended way - to do this is to use the new `TripPlan metadata` returned by the router call. - -In OTP 2.0 the server returned a set of parameters(`searchWindowUsed`, `nextDateTime`, and `prevDateTime`), but in OTP 2.1 we have switched to a token-based approach to paging. In the response there is a next/previous cursor. Duplicate the request and set the new `pageCursor` to go the next/previous page. +In OTP1 most clients provided a way to break results into pages by looking at the trips returned and +issuing another request, supplying something like the `last-depature-time` + 1 minute to the next +request. This yields another batch of trips to show to the user. In OTP2 the recommended way to do +this is to use the new `TripPlan metadata` returned by the router call. +In OTP 2.0 the server returned a set of parameters(`searchWindowUsed`, `nextDateTime`, +and `prevDateTime`), but in OTP 2.1 we have switched to a token-based approach to paging. In the +response there is a next/previous cursor. Duplicate the request and set the new `pageCursor` to go +the next/previous page. #### Response changes - - `agencyId` in the `leg` is now feed-scoped and similarly to other ids, is prefixed with `:` - - `debugOutput` in `TripPlan` has changed due to the different algorithms used in OTP version 1.x and 2.x. - - The `totalTime` is left as is, `directStreetRouterTime`, `transitRouterTime`, `filteringTime` - and `renderingTime` are new fields. - - `effectiveEndDate` is added to the `Alert`s - +- `agencyId` in the `leg` is now feed-scoped and similarly to other ids, is prefixed + with `:` +- `debugOutput` in `TripPlan` has changed due to the different algorithms used in OTP version 1.x + and 2.x. +- The `totalTime` is left as is, `directStreetRouterTime`, `transitRouterTime`, `filteringTime` + and `renderingTime` are new fields. +- `effectiveEndDate` is added to the `Alert`s ### Changes to the Index API - - Error handling is improved, this is now consistently applied and uses build in framework support. - - The HTTP 400 and 404 response now contains a detailed error message in plain text targeted - developers to help understanding why the 400 or 404 was returned. - - `Route` - - Deprecated 'routeBikesAllowed' field removed. - - `sortOrder` will be empty (missing) when empty, NOT -999 as before. - - To access or references `TripPattern` use `tripPatternId`, not `code`. In OTP1 the +- Error handling is improved, this is now consistently applied and uses build in framework support. +- The HTTP 400 and 404 response now contains a detailed error message in plain text targeted + developers to help understanding why the 400 or 404 was returned. +- `Route` +- Deprecated 'routeBikesAllowed' field removed. +- `sortOrder` will be empty (missing) when empty, NOT -999 as before. +- To access or references `TripPattern` use `tripPatternId`, not `code`. In OTP1 the `code` was used. The code was the same as the id without the feedId prefix. The `code` - is removed from OTP2. Clients may not be affected by this change, unless they toke advantage - of the semantics in the old `code`. - - The `mode` field is added to `Route`, it should probebly replace the `type`(unchanged). The - `RouteShort` is not chencged - it has the `mode` field. - - `Pattern` (or `TripPattern`) - - The semantics of the `id` should NOT be used to access other related entities like `Route`, - the `routeId` is added to `TripPatternShort` to allow navigation to Route. - - `Trip` + is removed from OTP2. Clients may not be affected by this change, unless they toke advantage of + the semantics in the old `code`. +- The `mode` field is added to `Route`, it should probebly replace the `type`(unchanged). The + `RouteShort` is not chencged - it has the `mode` field. +- `Pattern` (or `TripPattern`) + - The semantics of the `id` should NOT be used to access other related entities like `Route`, + the `routeId` is added to `TripPatternShort` to allow navigation to Route. +- `Trip` - The deprecated `tripBikesAllowed` is removed. - The `routeId` replace `route`. The route is no longer part of the trip. To obtain the Route object call the Index API with the routeId. - - `Stop` +- `Stop` - The new `stationId` is a feed-scoped-id to the parent station. It should be used instead of the deprecated ~~parentStation~~. - - `StopShort` +- `StopShort` - The new `stationId` is a feed-scoped-id to the parent station. It should be used instead of the deprecated ~~cluster~~. - - `Agency` +- `Agency` - The `id` is now feed-scoped and similarly to other ids, is prefixed with `:` - - `Alert` - - `effectiveEndDate` is added to show the end time of the alert validity. - +- `Alert` + - `effectiveEndDate` is added to show the end time of the alert validity. ### ServerInfo The returned data structure is changed and more info is available. +### AlertPatcher -### AlertPatcher - -The AlertPatcher, which was under the `/patch` path, is removed. In order to update alerts, please -use a GTFS-RT Service Alert updater instead. An example of a simple service for producing static +The AlertPatcher, which was under the `/patch` path, is removed. In order to update alerts, please +use a GTFS-RT Service Alert updater instead. An example of a simple service for producing static GTFS-RT Service Alert feed from JSON is [manual-gtfsrt](https://github.com/pailakka/manual-gtfsrt). -Querying for alerts has been moved under the index API, where `/alerts` can be appended to stop, +Querying for alerts has been moved under the index API, where `/alerts` can be appended to stop, route, trip and pattern. ### Analyst @@ -276,8 +277,11 @@ The scripting API endpoint has been removed. ### Updaters -- Floating bikes have been disabled by default in the GbfsBikeRentalDataSource unless explicitly -turned on via OTPFeature. +- Floating bikes have been disabled by default in the GbfsBikeRentalDataSource unless explicitly + turned on via OTPFeature. - Allow http headers to be configured for bike rental updaters -- The following bike updaters have been removed: *b-cycle*, *bicimad*, *bixi*, *city-bikes*, and *citi-bike-nyc*, *jcdecaux*, *keolis-rennes*, *kml*, *next-bike*, *ov-fiets*, *sf-bay-area*, *share-bike*, *smoove*, *uip-bike*, and *vcub*. Use the standard *gtfs* updater instead, or reintroduce your custom updater as a Sandbox module. +- The following bike updaters have been removed: *b-cycle*, *bicimad*, *bixi*, *city-bikes*, and * + citi-bike-nyc*, *jcdecaux*, *keolis-rennes*, *kml*, *next-bike*, *ov-fiets*, *sf-bay-area*, * + share-bike*, *smoove*, *uip-bike*, and *vcub*. Use the standard *gtfs* updater instead, or + reintroduce your custom updater as a Sandbox module. diff --git a/docs/Preparing-OSM.md b/docs/Preparing-OSM.md index a6167a4d036..4a446d983ba 100644 --- a/docs/Preparing-OSM.md +++ b/docs/Preparing-OSM.md @@ -1,23 +1,57 @@ ### Cropping OSM data -Services producing automated extracts of OSM data like [Geofabrik](http://download.geofabrik.de) or [Interline Extracts](https://www.interline.io/osm/extracts/) are limited to predefined areas. You'll often need to download an extract for a country or region larger than your true analysis area, then cut it down to size. - -Excessively large OSM data can lead to significant increases in computation time and complexity, both while building the graph and handling trip planning requests. You may want to crop the OSM data if they cover an area significantly larger than your transit network. Several command line tools are able to perform these cropping operations: [Osmosis](https://wiki.openstreetmap.org/wiki/Osmosis) is a multi-platform Java tool that works on Windows, Linux, and MacOS but is relatively slow, [OSMConvert](https://wiki.openstreetmap.org/wiki/Osmconvert) is a fast tool pre-built for Windows and Linux and available on MacOS and Linux distributions as part of `osmctools` package. [Osmium-Tool](https://wiki.openstreetmap.org/wiki/Osmium) is a personal favorite that is extremely fast but only straightforward to install on Linux and MacOS platforms. Below are some example crop commands for these different tools: - -**Osmosis:** `osmosis --rb input.osm.pbf --bounding-box left=4.34 right=5.84 bottom=43.10 top=43.97 --wb cropped.osm.pbf` - -**OsmConvert:** `osmconvert input.osm.pbf -b=-77.255859375,38.77764022307335,-76.81365966796875,39.02345139405933 --complete-ways -o=cropped.osm.pbf` - -**Osmium:** `osmium extract --strategy complete_ways --bbox 2.25,48.81,2.42,48.91 input.osm.pbf -o cropped.osm.pbf` - -The latter two commands expect bounding boxes to be specified in the format `min_lon,min_lat,max_lon,max_lat`. We frequently find bounding boxes using the convenient [Klokantech bounding box tool](https://boundingbox.klokantech.com/). Selecting the "CSV" format in the lower left will give exactly the format expected by these tools. +Services producing automated extracts of OSM data like [Geofabrik](http://download.geofabrik.de) +or [Interline Extracts](https://www.interline.io/osm/extracts/) are limited to predefined areas. +You'll often need to download an extract for a country or region larger than your true analysis +area, then cut it down to size. + +Excessively large OSM data can lead to significant increases in computation time and complexity, +both while building the graph and handling trip planning requests. You may want to crop the OSM data +if they cover an area significantly larger than your transit network. Several command line tools are +able to perform these cropping operations: [Osmosis](https://wiki.openstreetmap.org/wiki/Osmosis) is +a multi-platform Java tool that works on Windows, Linux, and MacOS but is relatively +slow, [OSMConvert](https://wiki.openstreetmap.org/wiki/Osmconvert) is a fast tool pre-built for +Windows and Linux and available on MacOS and Linux distributions as part of `osmctools` +package. [Osmium-Tool](https://wiki.openstreetmap.org/wiki/Osmium) is a personal favorite that is +extremely fast but only straightforward to install on Linux and MacOS platforms. Below are some +example crop commands for these different tools: + +** +Osmosis:** `osmosis --rb input.osm.pbf --bounding-box left=4.34 right=5.84 bottom=43.10 top=43.97 --wb cropped.osm.pbf` + +** +OsmConvert:** `osmconvert input.osm.pbf -b=-77.255859375,38.77764022307335,-76.81365966796875,39.02345139405933 --complete-ways -o=cropped.osm.pbf` + +** +Osmium:** `osmium extract --strategy complete_ways --bbox 2.25,48.81,2.42,48.91 input.osm.pbf -o cropped.osm.pbf` + +The latter two commands expect bounding boxes to be specified in the +format `min_lon,min_lat,max_lon,max_lat`. We frequently find bounding boxes using the +convenient [Klokantech bounding box tool](https://boundingbox.klokantech.com/). Selecting the "CSV" +format in the lower left will give exactly the format expected by these tools. ### Filtering OSM data -The OSM database contains a lot of other data besides the roads, paths, and public transportation platform data we need for accessibility analysis. As of this writing, according to [TagInfo](https://taginfo.openstreetmap.org/) 59% of the ways in OSM are buildings, and only 23% are roads or paths. Buildings frequently have more complex shapes than roads, and objects like waterways or political boundaries can be very large in size. It has been jokingly said that OSM should be renamed "OpenBuildingMap" rather than "OpenStreetMap". - -Removing unneeded data will reduce file sizes, facilitating copying or moving files around and reducing the size of project backups and archives. It may also speed up the processing stage where the OSM data is converted into a routable street network. Several command line tools exist to filter OSM data. Command line tools for this purpose include [Osmosis](https://wiki.openstreetmap.org/wiki/Osmosis) and [Osmium-Tool](https://osmcode.org/osmium-tool/). Osmium-Tool is extremely fast but is only straightforward to install on Linux and MacOS platforms. Osmosis is often slower at filtering but will also work on Windows as it's a multi-platform Java application. OSMFilter cannot work with PBF format files so we rarely use it. Below are some example commands for retaining only OSM data useful for accessibility analysis. Here are some example commands: - -**Osmosis:** `osmosis --rb input.osm.pbf --tf reject-ways building=* --tf reject-ways waterway=* --tf reject-ways landuse=* --tf reject-ways natural=* --used-node --wb filtered.osm.pbf` - -**Osmium-Tool:** `osmium tags-filter input.osm.pbf w/highway w/public_transport=platform w/railway=platform w/park_ride=yes r/type=restriction r/type=route -o filtered.osm.pbf -f pbf,add_metadata=false` +The OSM database contains a lot of other data besides the roads, paths, and public transportation +platform data we need for accessibility analysis. As of this writing, according +to [TagInfo](https://taginfo.openstreetmap.org/) 59% of the ways in OSM are buildings, and only 23% +are roads or paths. Buildings frequently have more complex shapes than roads, and objects like +waterways or political boundaries can be very large in size. It has been jokingly said that OSM +should be renamed "OpenBuildingMap" rather than "OpenStreetMap". + +Removing unneeded data will reduce file sizes, facilitating copying or moving files around and +reducing the size of project backups and archives. It may also speed up the processing stage where +the OSM data is converted into a routable street network. Several command line tools exist to filter +OSM data. Command line tools for this purpose +include [Osmosis](https://wiki.openstreetmap.org/wiki/Osmosis) +and [Osmium-Tool](https://osmcode.org/osmium-tool/). Osmium-Tool is extremely fast but is only +straightforward to install on Linux and MacOS platforms. Osmosis is often slower at filtering but +will also work on Windows as it's a multi-platform Java application. OSMFilter cannot work with PBF +format files so we rarely use it. Below are some example commands for retaining only OSM data useful +for accessibility analysis. Here are some example commands: + +** +Osmosis:** `osmosis --rb input.osm.pbf --tf reject-ways building=* --tf reject-ways waterway=* --tf reject-ways landuse=* --tf reject-ways natural=* --used-node --wb filtered.osm.pbf` + +** +Osmium-Tool:** `osmium tags-filter input.osm.pbf w/highway w/public_transport=platform w/railway=platform w/park_ride=yes r/type=restriction r/type=route -o filtered.osm.pbf -f pbf,add_metadata=false` diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index a91065e0c88..3467c01839c 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -14,12 +14,14 @@ These options can be applied by the OTP server without rebuilding the graph. ## Routing defaults -There are many trip planning options used in the OTP web API, and more exist -internally that are not exposed via the API. You may want to change the default value for some of these parameters, -i.e. the value which will be applied unless it is overridden in a web API request. - -A full list of them can be found in the [RoutingRequest](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/routing/api/request/RoutingRequest.java). -Any public field or setter method in this class can be given a default value using the routingDefaults section of +There are many trip planning options used in the OTP web API, and more exist internally that are not +exposed via the API. You may want to change the default value for some of these parameters, i.e. the +value which will be applied unless it is overridden in a web API request. + +A full list of them can be found in +the [RoutingRequest](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/routing/api/request/RoutingRequest.java) +. Any public field or setter method in this class can be given a default value using the +routingDefaults section of `router-config.json` as follows: ```JSON @@ -33,17 +35,24 @@ Any public field or setter method in this class can be given a default value usi } ``` - ### Tuning transfer optimization -The main purpose of transfer optimization is to handle cases where it is possible to transfer between two routes at more than one point (pair of stops). The transfer optimization ensures that transfers occur at the best possible location. By post-processing all paths returned by the router, OTP can apply sophisticated calculations that are too slow or not algorithmically valid within Raptor. Transfers are optimized before the paths are passed to the itinerary-filter-chain. +The main purpose of transfer optimization is to handle cases where it is possible to transfer +between two routes at more than one point (pair of stops). The transfer optimization ensures that +transfers occur at the best possible location. By post-processing all paths returned by the router, +OTP can apply sophisticated calculations that are too slow or not algorithmically valid within +Raptor. Transfers are optimized before the paths are passed to the itinerary-filter-chain. -For a detailed description of the design and the optimization calculations see the [design documentation](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/package.md) (dev-2.x latest). +For a detailed description of the design and the optimization calculations see +the [design documentation](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/package.md) ( +dev-2.x latest). #### Transfer optimization configuration To toggle transfer optimization on or off use the OTPFeature `OptimizeTransfers` (default is on). -You should leave this on unless there is a critical issue with it. The OTPFeature `GuaranteedTransfers` will toggle on and off the priority optimization (part of OptimizeTransfers). +You should leave this on unless there is a critical issue with it. The +OTPFeature `GuaranteedTransfers` will toggle on and off the priority optimization (part of +OptimizeTransfers). The optimized transfer service will try to, in order: @@ -74,10 +83,13 @@ option or "back-travel", then try to increase the `minSafeWaitTimeFactor`, } } ``` -See the [TransferOptimizationParameters](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/TransferOptimizationParameters.java) (dev-2.x latest) for a description of these parameters. +See +the [TransferOptimizationParameters](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/api/TransferOptimizationParameters.java) ( +dev-2.x latest) for a description of these parameters. ### Tuning itinerary filtering + Nested inside `routingDefaults { itineraryFilters{...} }` in `router-config.json`. The purpose of the itinerary filter chain is to post process the result returned by the routing @@ -110,9 +122,9 @@ The group-by-filter work by grouping itineraries together and then reducing the itineraries in each group, keeping the itinerary/itineraries with the best itinerary _generalized-cost_. The group-by function first pick all transit legs that account for more than N% of the itinerary based on distance traveled. This become the group-key. Two keys are the same if all -legs in one of the keys also exist in the other. Note, one key may have a lager set of legs than -the other, but they can still be the same. When comparing two legs we compare the `tripId` and make -sure the legs overlap in place and time. Two legs are the same if both legs ride at least a common +legs in one of the keys also exist in the other. Note, one key may have a lager set of legs than the +other, but they can still be the same. When comparing two legs we compare the `tripId` and make sure +the legs overlap in place and time. Two legs are the same if both legs ride at least a common subsection of the same trip. The `keepOne` filter will keep ONE itinerary in each group. The `keepThree` keeps 3 itineraries for each group. @@ -121,21 +133,21 @@ This parameter filters out itineraries, where the legs that are not common for a itineraries have a much higher cost, than the lowest in the group. By default, it filters out itineraries that are at least double in cost for the non-grouped legs. - ### Drive-to-transit routing defaults -When using the "park and ride" or "kiss and ride" modes (drive to transit), the initial driving time to reach a transit -stop or park and ride facility is constrained. You can set a drive time limit in seconds by adding a line like -`maxPreTransitTime = 1200` to the routingDefaults section. If the limit is too high on a very large street graph, routing -performance may suffer. - +When using the "park and ride" or "kiss and ride" modes (drive to transit), the initial driving time +to reach a transit stop or park and ride facility is constrained. You can set a drive time limit in +seconds by adding a line like +`maxPreTransitTime = 1200` to the routingDefaults section. If the limit is too high on a very large +street graph, routing performance may suffer. ## Boarding and alighting times -Sometimes there is a need to configure a longer ride or alighting times for specific modes, such as airplanes or ferries, -where the check-in process needs to be done in good time before ride. The ride time is added to the time when going -from the stop (offboard) vertex to the onboard vertex, and the alight time is added vice versa. The times are configured as -seconds needed for the ride and alighting processes in `router-config.json` as follows: +Sometimes there is a need to configure a longer ride or alighting times for specific modes, such as +airplanes or ferries, where the check-in process needs to be done in good time before ride. The ride +time is added to the time when going from the stop (offboard) vertex to the onboard vertex, and the +alight time is added vice versa. The times are configured as seconds needed for the ride and +alighting processes in `router-config.json` as follows: ```JSON // router-config.json @@ -169,12 +181,13 @@ search-window. To set the street routing timeout use the following config: } ``` -This specifies a timeout in (optionally fractional) seconds. The search abort after this many seconds and any paths found are returned to the client. +This specifies a timeout in (optionally fractional) seconds. The search abort after this many +seconds and any paths found are returned to the client. -##maxAccessEgressDurationSecondsForMode +## maxAccessEgressDurationSecondsForMode -Override the settings in maxAccessEgressDurationSeconds for specific street modes. This is done because -some street modes searches are much more resource intensive than others. +Override the settings in maxAccessEgressDurationSeconds for specific street modes. This is done +because some street modes searches are much more resource intensive than others. ```JSON // router-config.json @@ -188,9 +201,10 @@ other access/egress modes. ## Logging incoming requests -You can log some characteristics of trip planning requests in a file for later analysis. Some transit agencies and -operators find this information useful for identifying existing or unmet transportation demand. Logging will be -performed only if you specify a log file name in the router config: +You can log some characteristics of trip planning requests in a file for later analysis. Some +transit agencies and operators find this information useful for identifying existing or unmet +transportation demand. Logging will be performed only if you specify a log file name in the router +config: ```JSON // router-config.json @@ -213,13 +227,16 @@ The fields separated by whitespace are (in order): 6. Origin latitude and longitude 7. Destination latitude and longitude -Finally, for each itinerary returned to the user, there is a travel duration in seconds and the number of transit vehicles used in that itinerary. - +Finally, for each itinerary returned to the user, there is a travel duration in seconds and the +number of transit vehicles used in that itinerary. ## Tuning transit routing + Nested inside `transit {...}` in `router-config.json`. -Some of these parameters for tuning transit routing is only available through configuration and cannot be set in the routing request. These parameters work together with the default routing request and the actual routing request. +Some of these parameters for tuning transit routing is only available through configuration and +cannot be set in the routing request. These parameters work together with the default routing +request and the actual routing request. | config key | description | value type | value default | |--------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|-------------------------------------------| @@ -233,6 +250,7 @@ Some of these parameters for tuning transit routing is only available through co | `pagingSearchWindowAdjustments` | The provided array of durations is used to increase the search-window for the next/previous page when the current page return few options. If ZERO results 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 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. | duration[] | `["4h", "2h", "1h", "30m", "20m", "10m"]` | ### Tuning transit routing - Dynamic search window + Nested inside `transit : { dynamicSearchWindow : { ... } }` in `router-config.json`. | config key | description | value type | value default | @@ -244,9 +262,12 @@ Nested inside `transit : { dynamicSearchWindow : { ... } }` in `router-config.js | `stepMinutes` | The search window is rounded of to the closest multiplication of N minutes. If N=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. | int | `10` | ### Tuning transit routing - Stop transfer cost + Nested inside `transit : { stopTransferCost : { ... } }` in `router-config.json`. -This _cost_ is in addition to other costs like `boardCost` and indirect cost from waiting (board-/alight-/transfer slack). You should account for this when you tune the routing search parameters. +This _cost_ is in addition to other costs like `boardCost` and indirect cost from waiting ( +board-/alight-/transfer slack). You should account for this when you tune the routing search +parameters. If not set the `stopTransferCost` is ignored. This is only available for NeTEx imported Stops. @@ -259,10 +280,11 @@ The cost is a scalar, but is equivalent to the felt cost of riding a transit tri | `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 `stopTransferCost` is listed.** - +Use values in a range from `0` to `100 000`. **All key/value pairs are required if +the `stopTransferCost` is listed.** ### Transit example + ```JSON // router-config.json { @@ -290,43 +312,51 @@ Use values in a range from `0` to `100 000`. **All key/value pairs are required ## Real-time data -GTFS feeds contain *schedule* data that is is published by an agency or operator in advance. The feed does not account -for unexpected service changes or traffic disruptions that occur from day to day. Thus, this kind of data is also -referred to as 'static' data or 'theoretical' arrival and departure times. +GTFS feeds contain *schedule* data that is is published by an agency or operator in advance. The +feed does not account for unexpected service changes or traffic disruptions that occur from day to +day. Thus, this kind of data is also referred to as 'static' data or 'theoretical' arrival and +departure times. ### GTFS-Realtime -The [GTFS-RT spec](https://developers.google.com/transit/gtfs-realtime/) complements GTFS with three additional kinds of -feeds. In contrast to the base GTFS schedule feed, they provide *real-time* updates (*'dynamic'* data) and are are -updated from minute to minute. +The [GTFS-RT spec](https://developers.google.com/transit/gtfs-realtime/) complements GTFS with three +additional kinds of feeds. In contrast to the base GTFS schedule feed, they provide *real-time* +updates (*'dynamic'* data) and are are updated from minute to minute. -- **Alerts** are text messages attached to GTFS objects, informing riders of disruptions and changes. +- **Alerts** are text messages attached to GTFS objects, informing riders of disruptions and + changes. -- **TripUpdates** report on the status of scheduled trips as they happen, providing observed and predicted arrival and - departure times for the remainder of the trip. +- **TripUpdates** report on the status of scheduled trips as they happen, providing observed and + predicted arrival and departure times for the remainder of the trip. -- **VehiclePositions** give the location of some or all vehicles currently in service, in terms of geographic coordinates - or position relative to their scheduled stops. +- **VehiclePositions** give the location of some or all vehicles currently in service, in terms of + geographic coordinates or position relative to their scheduled stops. ### Vehicle rental systems using GBFS -Besides GTFS-RT transit data, OTP can also fetch real-time data about vehicle rental networks including the number -of bikes and free parking spaces at each station. We support vehicle rental systems from using GBFS feed format. +Besides GTFS-RT transit data, OTP can also fetch real-time data about vehicle rental networks +including the number of bikes and free parking spaces at each station. We support vehicle rental +systems from using GBFS feed format. ### Vehicle parking (sandbox feature) -Vehicle parking options and configuration is documented in its [sandbox documentation](sandbox/VehicleParking.md). +Vehicle parking options and configuration is documented in +its [sandbox documentation](sandbox/VehicleParking.md). ### Configuring real-time updaters -Real-time data can be provided using either a pull or push system. In a pull configuration, the GTFS-RT consumer polls the -real-time provider over HTTP. That is to say, OTP fetches a file from a web server every few minutes. In the push -configuration, the consumer opens a persistent connection to the GTFS-RT provider, which then sends incremental updates -immediately as they become available. OTP can use both approaches. The [OneBusAway GTFS-realtime exporter project](https://github.com/OneBusAway/onebusaway-gtfs-realtime-exporter) provides this kind of streaming, incremental updates over a websocket rather than a single large file. +Real-time data can be provided using either a pull or push system. In a pull configuration, the +GTFS-RT consumer polls the real-time provider over HTTP. That is to say, OTP fetches a file from a +web server every few minutes. In the push configuration, the consumer opens a persistent connection +to the GTFS-RT provider, which then sends incremental updates immediately as they become available. +OTP can use both approaches. +The [OneBusAway GTFS-realtime exporter project](https://github.com/OneBusAway/onebusaway-gtfs-realtime-exporter) +provides this kind of streaming, incremental updates over a websocket rather than a single large +file. -Real-time data sources are configured in `router-config.json`. The `updaters` section is an array of JSON objects, each -of which has a `type` field and other configuration fields specific to that type. Common to all updater entries that -connect to a network resource is the `url` field. +Real-time data sources are configured in `router-config.json`. The `updaters` section is an array of +JSON objects, each of which has a `type` field and other configuration fields specific to that type. +Common to all updater entries that connect to a network resource is the `url` field. ```JSON // router-config.json @@ -392,9 +422,12 @@ connect to a network resource is the `url` field. #### GBFS Configuration -[GBFS](https://github.com/NABSA/gbfs) is used for a variety of shared mobility services, with partial support for both v1 and v2.2 ([list of known GBFS feeds](https://github.com/NABSA/gbfs/blob/master/systems.csv)). +[GBFS](https://github.com/NABSA/gbfs) is used for a variety of shared mobility services, with +partial support for both v1 and +v2.2 ([list of known GBFS feeds](https://github.com/NABSA/gbfs/blob/master/systems.csv)). -To add a GBFS feed to the router add one entry in the `updater` field of `router-config.json` in the format: +To add a GBFS feed to the router add one entry in the `updater` field of `router-config.json` in the +format: ```JSON // router-config.json @@ -431,7 +464,8 @@ For this to be possible three things need to be configured: #### Vehicle Rental Service Directory configuration (sandbox feature) -To configure and url for the [VehicleRentalServiceDirectory](sandbox/VehicleRentalServiceDirectory.md). +To configure and url for +the [VehicleRentalServiceDirectory](sandbox/VehicleRentalServiceDirectory.md). ```JSON // router-config.json @@ -444,4 +478,7 @@ To configure and url for the [VehicleRentalServiceDirectory](sandbox/VehicleRent # Configure using command-line arguments -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). +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) +. diff --git a/docs/RoutingModes.md b/docs/RoutingModes.md index 4a4c5dbd84e..e5f29724fb5 100644 --- a/docs/RoutingModes.md +++ b/docs/RoutingModes.md @@ -1,16 +1,17 @@ ## Routing modes -TODO OTP2 - Where in the documentation does this belong? This is currently not part of the menu or - - any linked to by any of the other documents. +TODO OTP2 - Where in the documentation does this belong? This is currently not part of the menu or - +any linked to by any of the other documents. +The routing request parameter `mode` determines which transport modalities should be considered when +calculating the list of routes. -The routing request parameter `mode` determines which transport modalities should be considered when calculating the list -of routes. +Some modes (mostly bicycle and car) also have optional qualifiers `RENT` and `PARK` to specify if +vehicles are to be parked at a station or rented. In theory this can also apply to other modes but +makes sense only in select cases which are listed below. -Some modes (mostly bicycle and car) also have optional qualifiers `RENT` and `PARK` to specify if vehicles are to be parked at a station or rented. In theory -this can also apply to other modes but makes sense only in select cases which are listed below. - -Whether a transport mode is available highly depends on the input feeds (GTFS, OSM, bike sharing feeds) and the graph building options supplied to OTP. +Whether a transport mode is available highly depends on the input feeds (GTFS, OSM, bike sharing +feeds) and the graph building options supplied to OTP. The complete list of modes are: @@ -18,37 +19,46 @@ The complete list of modes are: - `TRANSIT`: General catch-all for all public transport modes. -- `BICYCLE`: Cycling for the entirety of the route or taking a bicycle onto the public transport and cycling from the arrival station to the destination. - -- `BICYCLE_RENT`: Taking a rented, shared-mobility bike for part or the entirety of the route. +- `BICYCLE`: Cycling for the entirety of the route or taking a bicycle onto the public transport and + cycling from the arrival station to the destination. - _Prerequisite:_ Vehicle positions need to be added to OTP from dynamic data feeds. +- `BICYCLE_RENT`: Taking a rented, shared-mobility bike for part or the entirety of the route. - For dynamic bike positions configure an input feed. See [Configuring real-time updaters](RouterConfiguration.md#Configuring real-time updaters). + _Prerequisite:_ Vehicle positions need to be added to OTP from dynamic data feeds. -- `BICYCLE_PARK`: Leaving the bicycle at the departure station and walking from the arrival station to the destination. + For dynamic bike positions configure an input feed. + See [Configuring real-time updaters](RouterConfiguration.md#Configuring real-time updaters). - This mode needs to be combined with at least one transit mode (or `TRANSIT`) otherwise it behaves like an ordinary bicycle journey. +- `BICYCLE_PARK`: Leaving the bicycle at the departure station and walking from the arrival station + to the destination. - _Prerequisite:_ Bicycle parking stations present in the OSM file and visible to OTP by enabling the property `staticBikeParkAndRide` during graph build. + This mode needs to be combined with at least one transit mode (or `TRANSIT`) otherwise it behaves + like an ordinary bicycle journey. -- `CAR`: Driving your own car the entirety of the route. + _Prerequisite:_ Bicycle parking stations present in the OSM file and visible to OTP by enabling + the property `staticBikeParkAndRide` during graph build. - If this is combined with `TRANSIT` it will return routes with a - [Kiss & Ride](https://en.wikipedia.org/wiki/Park_and_ride#Kiss_and_ride_/_kiss_and_fly) component. This means that the car is not parked in a permanent - parking area but rather the passenger is dropped off (for example, at an airport) and the driver continues driving the car away from the drop off - location. +- `CAR`: Driving your own car the entirety of the route. -- `CAR_PARK`: Driving a car to the park-and-ride facilities near a station and taking public transport. + If this is combined with `TRANSIT` it will return routes with a + [Kiss & Ride](https://en.wikipedia.org/wiki/Park_and_ride#Kiss_and_ride_/_kiss_and_fly) component. + This means that the car is not parked in a permanent parking area but rather the passenger is + dropped off (for example, at an airport) and the driver continues driving the car away from the + drop off location. - This mode needs to be combined with at least one transit mode (or `TRANSIT`) otherwise it behaves like an ordinary car journey. +- `CAR_PARK`: Driving a car to the park-and-ride facilities near a station and taking public + transport. - _Prerequisite:_ Park-and-ride areas near the station need to be present in the OSM input file. + This mode needs to be combined with at least one transit mode (or `TRANSIT`) otherwise it behaves + like an ordinary car journey. + _Prerequisite:_ Park-and-ride areas near the station need to be present in the OSM input file. -The following modes are 1-to-1 mappings from the [GTFS `route_type`](https://developers.google.com/transit/gtfs/reference/#routestxt): +The following modes are 1-to-1 mappings from +the [GTFS `route_type`](https://developers.google.com/transit/gtfs/reference/#routestxt): -- `TRAM`: Tram, streetcar, or light rail. Used for any light rail or street-level system within a metropolitan area. +- `TRAM`: Tram, streetcar, or light rail. Used for any light rail or street-level system within a + metropolitan area. - `SUBWAY`: Subway or metro. Used for any underground rail system within a metropolitan area. @@ -60,15 +70,19 @@ The following modes are 1-to-1 mappings from the [GTFS `route_type`](https://dev - `CABLE_CAR`: Cable car. Used for street-level cable cars where the cable runs beneath the car. -- `GONDOLA`: Gondola or suspended cable car. Typically used for aerial cable cars where the car is suspended from the cable. +- `GONDOLA`: Gondola or suspended cable car. Typically used for aerial cable cars where the car is + suspended from the cable. -- `FUNICULAR`: Funicular. Used for any rail system that moves on steep inclines with a cable traction system. +- `FUNICULAR`: Funicular. Used for any rail system that moves on steep inclines with a cable + traction system. -Lastly, this mode is part of the [Extended GTFS route types](https://developers.google.com/transit/gtfs/reference/extended-route-types): +Lastly, this mode is part of +the [Extended GTFS route types](https://developers.google.com/transit/gtfs/reference/extended-route-types): - `AIRPLANE`: Taking an airplane. -Note that there are conceptual overlaps between `TRAM`, `SUBWAY` and `RAIL` and some transport providers categorize their routes differently to others. -In other words, what is considered a `SUBWAY` in one city might be of type `RAIL` in another. Study your input GTFS feed carefully to +Note that there are conceptual overlaps between `TRAM`, `SUBWAY` and `RAIL` and some transport +providers categorize their routes differently to others. In other words, what is considered +a `SUBWAY` in one city might be of type `RAIL` in another. Study your input GTFS feed carefully to find out the appropriate mapping in your region. diff --git a/docs/SandboxExtension.md b/docs/SandboxExtension.md index 1b7260868c1..0855bda04b1 100644 --- a/docs/SandboxExtension.md +++ b/docs/SandboxExtension.md @@ -1,13 +1,13 @@ # OTP Sandbox Extensions -- The sandbox is a place to test and implement new "experimental" features. +- The sandbox is a place to test and implement new "experimental" features. - This should not be used for bug fixes and smaller changes. - Consider forking if the feature is valuable to one deployment only. - ## Available extensions -Here is a list of features implemented as OTP Sandbox Extensions. The Sandbox extensions are -provided "as is". + +Here is a list of features implemented as OTP Sandbox Extensions. The Sandbox extensions are +provided "as is". - [Google Cloud Storage](sandbox/GoogleCloudStorage.md) - Enable Google Cloud Storage as a OTP Data Source - [Actuator API](sandbox/ActuatorAPI.md) - API used to check the health status of the OTP instance. @@ -29,11 +29,11 @@ nearby stops generated by routing via OSM data. ## Terminology -**Main/core** -- All OTP code and additional files, NOT part of the sandbox. +**Main/core** -- All OTP code and additional files, NOT part of the sandbox. (`docs`, `src/main`, `src/test` and so on) -**Extensions** -- All features implemented in the OTP Sandbox, provided with no guarantees. -(`src/ext`, `src/ext-test`) +**Extensions** -- All features implemented in the OTP Sandbox, provided with no guarantees. +(`src/ext`, `src/ext-test`) ## Sandbox Goals @@ -41,47 +41,48 @@ nearby stops generated by routing via OSM data. - Allow experimental code to evolve (in a Sandbox) - Encourage refactoring and creation of extension points in the main code. - Increase visibility and cooperation of development of new features. -- Feature toggle - - Sandbox features should use the _OTPFeature_ to enable the code. Sandbox features are by - default off. To toggle features on/off se the [configuration documentation](Configuration.md). +- Feature toggle + - Sandbox features should use the _OTPFeature_ to enable the code. Sandbox features are by + default off. To toggle features on/off se the [configuration documentation](Configuration.md). ## Contract + - Give your feature a name: `` -- A new feature is isolated from the rest of the code by putting it in the directory `src/ext`. - Java code should have package prefix `org.opentripplanner.ext.`. Unit tests - should be added in the test directory: `src/ext-test` -- To integrate the new feature into OTP you may have to create new extension points in the - main/core code. Changes to the core OTP are subject to normal a review process. +- A new feature is isolated from the rest of the code by putting it in the directory `src/ext`. Java + code should have package prefix `org.opentripplanner.ext.`. Unit tests should be + added in the test directory: `src/ext-test` +- To integrate the new feature into OTP you may have to create new extension points in the main/core + code. Changes to the core OTP are subject to normal a review process. - Create a readme file (`docs/sandbox/.md` package including: - Extension Name - - Contact info + - Contact info - Change log - Documentation of the feature (optional) -- List your extension in the [Available extensions](#Available extensions) section and in the +- List your extension in the [Available extensions](#Available extensions) section and in the [mydocs config file](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/mkdocs.yml). -- Use feature toggling to enable a feature at runtime. The feature must be disabled by default. - A feature is toggled _on_ using the config files. -- Only code modifying the main code(`src/main`, not `src/ext`) is reviewed. The current coding +- Use feature toggling to enable a feature at runtime. The feature must be disabled by default. A + feature is toggled _on_ using the config files. +- Only code modifying the main code(`src/main`, not `src/ext`) is reviewed. The current coding standard apply to the extension code as well - but the code is not necessarily reviewed. -- There are no grantees - the authors of an extension can change its API any time they want. -- Anyone can request the feature to be merged into the main code. An approval from the PLC and a - new review is then required. The reviewers may request any changes, including API changes. +- There are no grantees - the authors of an extension can change its API any time they want. +- Anyone can request the feature to be merged into the main code. An approval from the PLC and a new + review is then required. The reviewers may request any changes, including API changes. - If an extension is taken into the core/main OTP code, any API included may change, no BACKWARD compatibility is guaranteed. I.e. the reviewers may require changes before it is merged. - The feature submitters is responsible for maintaining and testing the extension code, but do not - need to provide any guarantees or support. If the extension is merged into the main code the + need to provide any guarantees or support. If the extension is merged into the main code the author will in fact need to provide support and maintenance. - When someone at a later point in time want to change the main code the only thing they are responsible for - with regard to the extension code - is: - - that it compiles. - - that the unit tests run. If a test is not easy to fix, it can be tagged with @Ignore. If ignored - it would be polite to notify the author. -- Changes to the main OTP API that cannot be toggled _in_ must be clearly marked/tagged as part of + - that it compiles. + - that the unit tests run. If a test is not easy to fix, it can be tagged with @Ignore. If + ignored it would be polite to notify the author. +- Changes to the main OTP API that cannot be toggled _in_ must be clearly marked/tagged as part of an experimental feature and documented - This code is subject to review. -- If a feature is old and not maintained it can be removed 1 month after notifying the submitter +- If a feature is old and not maintained it can be removed 1 month after notifying the submitter (using contact info in README file). -- Introducing new dependencies needs approval. They are NOT approved if they are likely to be a - maintenance challenge (many transitive dependencies or potential conflicts with other +- Introducing new dependencies needs approval. They are NOT approved if they are likely to be a + maintenance challenge (many transitive dependencies or potential conflicts with other versions/libraries). diff --git a/docs/Security.md b/docs/Security.md index 6b656fe4504..a17a5a7dbda 100644 --- a/docs/Security.md +++ b/docs/Security.md @@ -1,20 +1,37 @@ # Security -OTP's built-in Grizzly web server is configured to accept HTTPS connections on port 8081 by default, but the HTTPS listener needs an encryption key to establish a connection. The key is placed in a "keystore", a format specific to Java server environments. +OTP's built-in Grizzly web server is configured to accept HTTPS connections on port 8081 by default, +but the HTTPS listener needs an encryption key to establish a connection. The key is placed in a " +keystore", a format specific to Java server environments. -## Creating a keystore +## Creating a keystore -By default, OTP will look for the keystore at `/var/otp/keystore`. To generate a self-signed key for testing, use the command: +By default, OTP will look for the keystore at `/var/otp/keystore`. To generate a self-signed key for +testing, use the command: keytool -genkey -keystore /var/otp/keystore -alias OTPServerKey -The alias of the key is arbitrary, but it's best to supply one that indicates the purpose of the key to override the default. `keytool` will ask you a series of questions about you and your organization; again, any values will do when creating this self-signed test key. `keytool` will also ask you for a password to protect your keystore and key. This password will eventually be configurable, but for now it is hard-coded into the OTP server, so you must set the keystore and key passwords both to `opentrip`. - -Of course with a self-signed key, most clients will (rightfully) refuse to connect without special permission from the user. You'll need to add a security exception to most web browsers, or add the `--insecure` switch when using CURL. You could theoretically buy and install a "real" trusted SSL/TLS certificate it in the keystore using `keytool -gencert`, but since none of the functionality protected by this encryption is public-facing a self-signed key should be sufficient for most use cases. All connections to these API methods should be from trusted parties who can verify the validity of the key with you directly as needed. +The alias of the key is arbitrary, but it's best to supply one that indicates the purpose of the key +to override the default. `keytool` will ask you a series of questions about you and your +organization; again, any values will do when creating this self-signed test key. `keytool` will also +ask you for a password to protect your keystore and key. This password will eventually be +configurable, but for now it is hard-coded into the OTP server, so you must set the keystore and key +passwords both to `opentrip`. + +Of course with a self-signed key, most clients will (rightfully) refuse to connect without special +permission from the user. You'll need to add a security exception to most web browsers, or add +the `--insecure` switch when using CURL. You could theoretically buy and install a "real" trusted +SSL/TLS certificate it in the keystore using `keytool -gencert`, but since none of the functionality +protected by this encryption is public-facing a self-signed key should be sufficient for most use +cases. All connections to these API methods should be from trusted parties who can verify the +validity of the key with you directly as needed. ## Testing -Once you have created a key, start up the OTP server and test that HTTPS access and authentication are possible. You should also be able to fetch any OTP resources over HTTPS. For example, you could simply open `https://localhost:8081/index.html` in a browser, or open a raw TLS connection using `openssl s_client -connect localhost:8081`, then issue the request `GET index.html HTTP/1.1`. +Once you have created a key, start up the OTP server and test that HTTPS access and authentication +are possible. You should also be able to fetch any OTP resources over HTTPS. For example, you could +simply open `https://localhost:8081/index.html` in a browser, or open a raw TLS connection +using `openssl s_client -connect localhost:8081`, then issue the request `GET index.html HTTP/1.1`. ## Other diff --git a/docs/Troubleshooting-Routing.md b/docs/Troubleshooting-Routing.md index e9370655b58..299794d1ab3 100644 --- a/docs/Troubleshooting-Routing.md +++ b/docs/Troubleshooting-Routing.md @@ -2,10 +2,10 @@ ## Graph Builder Data Import Issues -When you build a graph, OTP may encounter clearly incorrect or ambiguous data, or may detect less -severe, but potentially problematic situations in the input data. Such problems should result in a -"Data Import Issue" being generated. These issues are logged the the `DATA_IMPORT_ISSUES` console -logger, depending on your need you might turn this logger on/off. At the end of the graph build +When you build a graph, OTP may encounter clearly incorrect or ambiguous data, or may detect less +severe, but potentially problematic situations in the input data. Such problems should result in a +"Data Import Issue" being generated. These issues are logged the the `DATA_IMPORT_ISSUES` console +logger, depending on your need you might turn this logger on/off. At the end of the graph build process, OTP prints a summary of all the issues, like the following: ``` @@ -21,162 +21,185 @@ process, OTP prints a summary of all the issues, like the following: 11:35:57.519 INFO (Graph.java:976) NoFutureDates - 1 ``` -The full set of issues can be written out to an HTML report for closer inspection. To enable the -creation of these (potentially voluminous) HTML reports, add `"dataImportReport" : true` to your +The full set of issues can be written out to an HTML report for closer inspection. To enable the +creation of these (potentially voluminous) HTML reports, add `"dataImportReport" : true` to your graph builder JSON configuration. -If the graph is saved to a file, these issues are saved with it and can be examined later. -Currently the only tool for doing this is the "Graph Visualizer", which is not particularly well -maintained and is intended for use by software developers familiar with OTP who can patch up the -code as needed. - +If the graph is saved to a file, these issues are saved with it and can be examined later. Currently +the only tool for doing this is the "Graph Visualizer", which is not particularly well maintained +and is intended for use by software developers familiar with OTP who can patch up the code as +needed. ## Debug layers OpenTripplanner has option to ease debugging problems with graph. Older option is graph visualizer. -Which you can enable with `--visualize` parameter instead of `--server` when starting OTP. -There you can see whole graph. You can click on edges and vertices and see the metadata. It is - useful to see if street has expected options. And if connections are where they are expected. +Which you can enable with `--visualize` parameter instead of `--server` when starting OTP. There you +can see whole graph. You can click on edges and vertices and see the metadata. It is useful to see +if street has expected options. And if connections are where they are expected. + +It can be hard to use on large graphs since, whole graph is displayed at once. And it can be hard to +search for specific streets since only street graph is shown without the rest of information. -It can be hard to use on large graphs since, whole graph is displayed at once. And it can be hard - to search for specific streets since only street graph is shown without the rest of information. - -Another option is to use debug layers, which shows extra layers on top of the normal [debug UI map](http://localhost:8080). -If you want to see them you need to open the map layer selector on the top left hand side and choose -the requested layer. +Another option is to use debug layers, which shows extra layers on top of the +normal [debug UI map](http://localhost:8080). If you want to see them you need to open the map layer +selector on the top left hand side and choose the requested layer. Currently you can choose between: -- Wheelchair access (which colors street edges red if they don't allow wheelchair or green otherwise) -- [Bicycle safety](Troubleshooting-Routing.md#Bicycle-safety-factor) (colors street edges based on how good are for cycling [smaller is better]) +- Wheelchair access (which colors street edges red if they don't allow wheelchair or green + otherwise) +- [Bicycle safety](Troubleshooting-Routing.md#Bicycle-safety-factor) (colors street edges based on + how good are for cycling [smaller is better]) - Traversal permissions (colors street edges based on what types of transit modes are allowed to - travel on them (Pedestrian, cycling, car are currently supported)) Traversal permissions layer also - draws links from transit stops/vehicle rentals and P+R to graph. And also draws transit stops, vehicle rentals - and P+R vertices with different color. -- No thru traffic - streets are colored if the edge has thru traffic restrictions (car and bicycle = `red`, car only = `orange`, bicycle only = `blue`, and no-restriction = `light gray`) + travel on them (Pedestrian, cycling, car are currently supported)) Traversal permissions layer + also draws links from transit stops/vehicle rentals and P+R to graph. And also draws transit + stops, vehicle rentals and P+R vertices with different color. +- No thru traffic - streets are colored if the edge has thru traffic restrictions (car and bicycle + = `red`, car only = `orange`, bicycle only = `blue`, and no-restriction = `light gray`) ### Interpretation Traversal permissions layer -A sample traversal permissions layer looks like the following +A sample traversal permissions layer looks like the following ![screen shot 2015-06-26 at 11 45 22](https://cloud.githubusercontent.com/assets/4493762/8374829/df05c438-1bf8-11e5-8ead-c1dea41af122.png) * Yellow lines is the link between a stop and the street graph. * Grey lines are streets one can travel with the mode walk, bike, or car * Green lines are paths one can travel with the mode walk only * Red lines are streets one can travel with the mode car only -* Grey dots vertices where edges are connected. If two edges are crossing w/o a vertice at the intersection point, users will not be able to go from one street to the other. But this can be valid in case of over/under pass for -example. If it's an error, it's usually caused by improperly connected OSM data (a shared OSM node is required). +* Grey dots vertices where edges are connected. If two edges are crossing w/o a vertice at the + intersection point, users will not be able to go from one street to the other. But this can be + valid in case of over/under pass for example. If it's an error, it's usually caused by improperly + connected OSM data (a shared OSM node is required). ## OpenStreetMap Data ### Tags affecting permissions and bicycle safety -OTP has a very flexible system for deciding when a street is to be allowed by pedestrians, bicycles or cars. +OTP has a very flexible system for deciding when a street is to be allowed by pedestrians, bicycles +or cars. -To configure the which settings to use for your location, please use the [osmWayPropertySet config attribute](BuildConfiguration.md#Way-property-sets). +To configure the which settings to use for your location, please use +the [osmWayPropertySet config attribute](BuildConfiguration.md#Way-property-sets). -In the following section we will discuss the default case, which will be used if the property is not set. +In the following section we will discuss the default case, which will be used if the property is not +set. ### Default settings -Access tags (such as bicycle/foot = yes/no/designated) can be used to override default graph-building parameters. +Access tags (such as bicycle/foot = yes/no/designated) can be used to override default +graph-building parameters. -As a default, foot and bicycle traffic is ''not'' allowed on `highway=trunk`, `highway=trunk_link`, `highway=motorway`, `highway=motorway_link`, or `highway=construction`. +As a default, foot and bicycle traffic is ''not'' allowed on `highway=trunk`, `highway=trunk_link` +, `highway=motorway`, `highway=motorway_link`, or `highway=construction`. -Both *are* allowed on `highway=pedestrian`, `highway=cycleway`, and `highway=footway`. +Both *are* allowed on `highway=pedestrian`, `highway=cycleway`, and `highway=footway`. -Finally, bicycles are *not* allowed on *highway=footway* when any of the following tags appear on a footway: `footway=sidewalk`, `public_transport=platform`, or `railway=platform`. +Finally, bicycles are *not* allowed on *highway=footway* when any of the following tags appear on a +footway: `footway=sidewalk`, `public_transport=platform`, or `railway=platform`. -Other access tags (such as `access=no` and `access=private` affect routing as well, and can be overridden similarly. While `access=no` prohibits all traffic, `access=private` disallows through traffic. +Other access tags (such as `access=no` and `access=private` affect routing as well, and can be +overridden similarly. While `access=no` prohibits all traffic, `access=private` disallows through +traffic. ### Bicycle safety factor -Bicycle routing is even more configurable than the other traverse modes: during graph build a so-called bicycle safety score is -computed for each street. You can think of this score as a penalty for traversing this way so the lower the score the better. +Bicycle routing is even more configurable than the other traverse modes: during graph build a +so-called bicycle safety score is computed for each street. You can think of this score as a penalty +for traversing this way so the lower the score the better. -For example if a way is tagged with `surface=sand` it receives a safety score of 100 which means that it's 100 times worse to -cycle on when compared to a way which has a safety score of 1. +For example if a way is tagged with `surface=sand` it receives a safety score of 100 which means +that it's 100 times worse to cycle on when compared to a way which has a safety score of 1. How this is calculated depends on two things -- the incline of the way (not read from OSM but from the [separately configured elevation data](Configuration.md#Elevation data)) +- the incline of the way (not read from OSM but from + the [separately configured elevation data](Configuration.md#Elevation data)) - its OSM tags - -At request time you can then use the `triangleFactors` to decide how important bicycle safety -is compared to shorter distances and flatness. -Each `WayPropertySet` contains rules for a given set of tag matchers that influence the bicycle safety score. For example, a rule looks like this: +At request time you can then use the `triangleFactors` to decide how important bicycle safety is +compared to shorter distances and flatness. + +Each `WayPropertySet` contains rules for a given set of tag matchers that influence the bicycle +safety score. For example, a rule looks like this: ```java props.setProperties("highway=track", StreetTraversalPermission.ALL, 1.3, 1.3); ``` -This means that an OSM way with the tag `highway=track` is traversable by all modes (pedestrian, bicycle, car) and that -its bicycle safety score when you traverse in order of the way is `1.3` and also `1.3` when going the other way +This means that an OSM way with the tag `highway=track` is traversable by all modes (pedestrian, +bicycle, car) and that its bicycle safety score when you traverse in order of the way is `1.3` and +also `1.3` when going the other way (smaller means more cycle-friendly). -If there is a more specific matcher like `highway=track;bicycle=no` and it matches a given OSM way, +If there is a more specific matcher like `highway=track;bicycle=no` and it matches a given OSM way, it is chosen instead and its settings applied. -The score can be any positive number but the range (as of writing this) goes from `0.6` for bike lanes -to `100` for ways that consist of sand. To figure out a good value for your set of tags you should -read the bicycle safety report (see below) or the source code of your `WayPropertySetSource` to get -a feeling for how much certain tags are penalised or rewarded. +The score can be any positive number but the range (as of writing this) goes from `0.6` for bike +lanes to `100` for ways that consist of sand. To figure out a good value for your set of tags you +should read the bicycle safety report (see below) or the source code of your `WayPropertySetSource` +to get a feeling for how much certain tags are penalised or rewarded. There are also so-called mixins. These are applied on top of the most specific matchers and a single -OSM way can match many mixins. The mixins' safety values are multiplied with the value of the base -(non-mixin) match. -A mixin looks like this (note the `true` at the end): +OSM way can match many mixins. The mixins' safety values are multiplied with the value of the base +(non-mixin) match. A mixin looks like this (note the `true` at the end): ```java 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) +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) 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 an overview. -There is however an OTP feature to get an HTML viewer with a search feature that lets you browse through the rules. +There are a lot of rules for which tags results in a specific safety score so it's not easy to get +an overview. There is however an OTP feature to get an HTML viewer with a search feature that lets +you browse through the rules. ![Bicycle safety report](images/bicycle-safety-report.png) To enable it activate the [Report API sandbox feature](sandbox/ReportApi.md). -To view the output of the bicycle safety calculation on a map, check the [debug layers](Troubleshooting-Routing.md#Debug-layers). +To view the output of the bicycle safety calculation on a map, check +the [debug layers](Troubleshooting-Routing.md#Debug-layers). ### Railway Platforms -OTP users in Helsinki have documented their best practices for coding railway platforms in OpenStreetMap. These guidelines are available [in the OSM Wiki.](https://wiki.openstreetmap.org/wiki/Digitransit#Editing_railway_platforms) +OTP users in Helsinki have documented their best practices for coding railway platforms in +OpenStreetMap. These guidelines are +available [in the OSM Wiki.](https://wiki.openstreetmap.org/wiki/Digitransit#Editing_railway_platforms) ## Debug logging -OTP use [logback](http://logback.qos.ch/) and [slj4j](http://www.slf4j.org/) as a logging framework. Logging is configured in the _logback.xml_ file inside the OTP jar file. See these frameworks for more documentation on log configuration. +OTP use [logback](http://logback.qos.ch/) and [slj4j](http://www.slf4j.org/) as a logging framework. +Logging is configured in the _logback.xml_ file inside the OTP jar file. See these frameworks for +more documentation on log configuration. -For developers, starting OTP using the `InteractiveOtpMain` is an easy way to configure -debug logging. +For developers, starting OTP using the `InteractiveOtpMain` is an easy way to configure debug +logging. Some useful loggers + - `TRANSFERS_EXPORT` Dump transfers to _transfers-debug.csv_ file. - `DATA_IMPORT_ISSUES` Write issues to debug lag as well as to the issue report. -- `REQ_LOG` Router request log. Enable with `requestLogFile` config parameter in build config. +- `REQ_LOG` Router request log. Enable with `requestLogFile` config parameter in build config. - `org.opentripplanner.transit.raptor.RaptorService` Debug Raptor request and response - ### Transit search -The Raptor implementation support instrumentation of ACCEPT, REJECT, and DROP events for stop-arrivals and trip boardings. Use the SpeedTest to pass in a set of stops and/or a specific path to debug. This is useful when debugging why you do (not) get a particular result. +The Raptor implementation support instrumentation of ACCEPT, REJECT, and DROP events for +stop-arrivals and trip boardings. Use the SpeedTest to pass in a set of stops and/or a specific path +to debug. This is useful when debugging why you do (not) get a particular result. ### GTFS Transfers.txt and NeTEx Interchange import -Transfers may have effects on the routing which may be difficult to predict. OTP can dump all -imported transfers to file - _transfers-debug.csv_. This may help verify the result of the import -or find special test cases. To turn on the export enable the slf4j logger: +Transfers may have effects on the routing which may be difficult to predict. OTP can dump all +imported transfers to file - _transfers-debug.csv_. This may help verify the result of the import or +find special test cases. To turn on the export enable the slf4j logger: ``` ``` - ### Further information * [General information](https://github.com/opentripplanner/OpenTripPlanner/wiki/GraphBuilder#graph-concepts) diff --git a/docs/Version-Comparison.md b/docs/Version-Comparison.md index 76a1ebcf4ad..a3d8d510ead 100644 --- a/docs/Version-Comparison.md +++ b/docs/Version-Comparison.md @@ -2,30 +2,70 @@ ## Summary -OpenTripPlanner has been under development since 2009, leading up to a 1.0 release in 2016. Research and development on higher performance routing has been ongoing since 2013-2014, and work on the second major release referred to as OTP2 officially began in 2018. As of Q3 2020, a release candidate of OTP2 is available and in limited production use. This page explains key differences between the two versions (referred to as OTP1 and OTP2) to help you decide which one to use. - -OTP1 has existed for over a decade and is in widespread use. It aims to do many things for many people: it provides passenger-facing itinerary services over APIs, but also serves as a network analysis toolkit for urban planning and research. Though OTP1 is widely used and gets the job done, its transit routing approach is obsolete. We have long recognized that more resource-efficient approaches were possible. Reasonable response times and scaling to larger data sets have been achieved through a series of complex incremental interventions that became difficult to maintain. OTP1 has also accumulated large amounts of experimental code and specialized tools, which can be useful in a research or consulting setting but complicate long-term maintenance. - -OTP2 is brand new and still in testing, though based on code and ideas in heavy use for over five years. It offers much better performance in larger transportation networks and geographic areas, and a wider variety of alternative itineraries. OTP2's public transit routing component has been completely rewritten, and is now distinct from bike, walk, and motor vehicle routing. Non-transit routing remains identical to OTP1, benefiting from years of adaptations to nuances of OpenStreetMap data and end-user walking and biking preferences. Unlike OTP1, OTP2 is completely focused on passenger-facing itinerary services. The innovations in OTP2 have already been applied to planning, research, and analysis work for several years through Conveyal's R5 project, which informed and inspired the OTP2 transit routing system. - -OTP2 will not supersede OTP1 immediately for all use cases. In some situations there are legitimate reasons to continue using OTP1, or even for new OpenTripPlanner users to adopt OTP1 instead of OTP2. As development work continues over 2021 and additional 2.x releases are made, we expect this gap to close and OTP2 (in combination with other projects) may eventually fully replace OTP1, but this process is expected to take a few years. - +OpenTripPlanner has been under development since 2009, leading up to a 1.0 release in 2016. Research +and development on higher performance routing has been ongoing since 2013-2014, and work on the +second major release referred to as OTP2 officially began in 2018. As of Q3 2020, a release +candidate of OTP2 is available and in limited production use. This page explains key differences +between the two versions (referred to as OTP1 and OTP2) to help you decide which one to use. + +OTP1 has existed for over a decade and is in widespread use. It aims to do many things for many +people: it provides passenger-facing itinerary services over APIs, but also serves as a network +analysis toolkit for urban planning and research. Though OTP1 is widely used and gets the job done, +its transit routing approach is obsolete. We have long recognized that more resource-efficient +approaches were possible. Reasonable response times and scaling to larger data sets have been +achieved through a series of complex incremental interventions that became difficult to maintain. +OTP1 has also accumulated large amounts of experimental code and specialized tools, which can be +useful in a research or consulting setting but complicate long-term maintenance. + +OTP2 is brand new and still in testing, though based on code and ideas in heavy use for over five +years. It offers much better performance in larger transportation networks and geographic areas, and +a wider variety of alternative itineraries. OTP2's public transit routing component has been +completely rewritten, and is now distinct from bike, walk, and motor vehicle routing. Non-transit +routing remains identical to OTP1, benefiting from years of adaptations to nuances of OpenStreetMap +data and end-user walking and biking preferences. Unlike OTP1, OTP2 is completely focused on +passenger-facing itinerary services. The innovations in OTP2 have already been applied to planning, +research, and analysis work for several years through Conveyal's R5 project, which informed and +inspired the OTP2 transit routing system. + +OTP2 will not supersede OTP1 immediately for all use cases. In some situations there are legitimate +reasons to continue using OTP1, or even for new OpenTripPlanner users to adopt OTP1 instead of OTP2. +As development work continues over 2021 and additional 2.x releases are made, we expect this gap to +close and OTP2 (in combination with other projects) may eventually fully replace OTP1, but this +process is expected to take a few years. ## OTP2 Use Cases -The benefits of OTP2 will be most evident in large or dense networks spanning multiple cities: entire countries (Netherlands, Switzerland, Norway), US states, metropolitan regions and cross-border conurbations (e.g. NYC metro area). Although the scale of trip planners is sometimes limited by the geographic extent of administrative structures (national rail or bus operators or ticketing agencies), OTP2 should be capable of handling even larger networks, and we do for example regularly test on a unified Nordic trip planner in hopes that such systems will materialize over time as more territories adopt OTP. - -OTP2 development has been driven by adoption of open source routing software in Northern Europe. Importantly for deployments in Europe, OTP2 introduces support for EU-standard Netex and SIRI data sources in addition to GTFS. The Nordic profile of Netex understood by OTP2 uses the same schema as the EU profile, and generalization to the EU profile should be feasible once it is standardized. +The benefits of OTP2 will be most evident in large or dense networks spanning multiple cities: +entire countries (Netherlands, Switzerland, Norway), US states, metropolitan regions and +cross-border conurbations (e.g. NYC metro area). Although the scale of trip planners is sometimes +limited by the geographic extent of administrative structures (national rail or bus operators or +ticketing agencies), OTP2 should be capable of handling even larger networks, and we do for example +regularly test on a unified Nordic trip planner in hopes that such systems will materialize over +time as more territories adopt OTP. +OTP2 development has been driven by adoption of open source routing software in Northern Europe. +Importantly for deployments in Europe, OTP2 introduces support for EU-standard Netex and SIRI data +sources in addition to GTFS. The Nordic profile of Netex understood by OTP2 uses the same schema as +the EU profile, and generalization to the EU profile should be feasible once it is standardized. ## Choosing between OTP1 and OTP2 -Much development effort has gone into OTP2, and most OTP development effort will continue to focus on OTP2 after its release. OTP2 is much more efficient than OTP1 for certain common use cases, providing faster responses for a larger number of simultaneous users over larger geographic areas and more complex transportation networks. - -However, this does not mean that all users of OpenTripPlanner should switch to OTP2, or that all new users will want to start with OTP2. As of fall 2020, OTP1 remains much more widely used than OTP2, and most importantly OTP2 has a smaller feature set than OTP1. That is to say, OTP2 can do less things than OTP1, but it does them much more efficiently and tries to cover the most common use cases for large-scale OTP deployments. +Much development effort has gone into OTP2, and most OTP development effort will continue to focus +on OTP2 after its release. OTP2 is much more efficient than OTP1 for certain common use cases, +providing faster responses for a larger number of simultaneous users over larger geographic areas +and more complex transportation networks. -When in doubt, new users are advised to try out OTP2 and switch to OTP1 if they need features that are not available in OTP2. If some feature you need is missing from OTP2, you can also create a new issue or comment on an existing one on GitHub, letting us know why it is important to you. New features can be added to the OTP2 if there is sufficient demand and development resources to maintain them. +However, this does not mean that all users of OpenTripPlanner should switch to OTP2, or that all new +users will want to start with OTP2. As of fall 2020, OTP1 remains much more widely used than OTP2, +and most importantly OTP2 has a smaller feature set than OTP1. That is to say, OTP2 can do less +things than OTP1, but it does them much more efficiently and tries to cover the most common use +cases for large-scale OTP deployments. +When in doubt, new users are advised to try out OTP2 and switch to OTP1 if they need features that +are not available in OTP2. If some feature you need is missing from OTP2, you can also create a new +issue or comment on an existing one on GitHub, letting us know why it is important to you. New +features can be added to the OTP2 if there is sufficient demand and development resources to +maintain them. ## High-level feature comparison @@ -54,65 +94,108 @@ When in doubt, new users are advised to try out OTP2 and switch to OTP1 if they | Transfer Priority | yes | yes | | REST API format | XML, JSON | JSON only | - ## Commentary on OTP1 features removed from OTP2 -OTP2 brings significant improvements in speed and scalability, but does not retain all features of OTP1. We have chosen to prioritize long-term maintainability, so only those features that are "owned" by a team of professional developers will be carried over to OTP2. +OTP2 brings significant improvements in speed and scalability, but does not retain all features of +OTP1. We have chosen to prioritize long-term maintainability, so only those features that are " +owned" by a team of professional developers will be carried over to OTP2. -Features that have been removed to simplify the code base and improve maintainability may be removed permanently. Other missing features are still priorities for the organization leading OTP2 development (Entur) but have not yet been adapted to the new transit routing system, and will be added in upcoming releases. Some features have been removed to reflect separation of concerns: following principles of modular design they should be handled outside OTP, or are already covered by other projects where they are more actively developed. +Features that have been removed to simplify the code base and improve maintainability may be removed +permanently. Other missing features are still priorities for the organization leading OTP2 +development (Entur) but have not yet been adapted to the new transit routing system, and will be +added in upcoming releases. Some features have been removed to reflect separation of concerns: +following principles of modular design they should be handled outside OTP, or are already covered by +other projects where they are more actively developed. ### Analysis -Many OpenTripPlanner contributors have been primarily interested in transportation and urban planning use cases. We consider these use cases quite important. This has been a major area of application for OpenTripPlanner and has helped popularize cumulative opportunities accessibility metrics. For example, the University of Minnesota Accessibility Observatory used OpenTripPlanner for [Access Across America](http://access.umn.edu/research/america/). Nonetheless, the analysis code in OTP1 is essentially an unmaintained and unsupported early prototype for later projects, specifically Conveyal's R5 (and the Conveyal Analysis system built upon it). OTP1 seems to have gained popularity for analysis uses due to the existence of documentation and an active user community, but has significant technical shortcomings. One of these is simply speed: OTP1 can be orders of magnitude slower (and more memory-intensive) than the approaches exemplified in R5. The other is the requirement to search at a single specific time. Travel times and especially wait times on scheduled transit vary greatly depending on when you depart. Accounting for variation over a time window requires repeated independent searches at each possible departure time, which is very inefficient. R5 is highly optimized to capture variations in travel time across time windows and account for uncertainty in waiting times on frequency-based routes. - -Due to its similarity to the R5 approach, OTP2's transit router would not have these same problems. Nonetheless, we have decided not to port the -OTP1 analysis features over to OTP2 since it would broaden the focus away from passenger information and draw finite attention away from existing projects like R5 and Conveyal Analysis. - -Accordingly, we have made an effort to clean up and augment OTP1 analysis documentation for researchers who will continue to need it. -It should remain possible for people to continue using OTP1 if they prefer. -If you would instead like to apply the innovations present in OTP2, we recommend looking into R5 or Conveyal Analysis. - +Many OpenTripPlanner contributors have been primarily interested in transportation and urban +planning use cases. We consider these use cases quite important. This has been a major area of +application for OpenTripPlanner and has helped popularize cumulative opportunities accessibility +metrics. For example, the University of Minnesota Accessibility Observatory used OpenTripPlanner +for [Access Across America](http://access.umn.edu/research/america/). Nonetheless, the analysis code +in OTP1 is essentially an unmaintained and unsupported early prototype for later projects, +specifically Conveyal's R5 (and the Conveyal Analysis system built upon it). OTP1 seems to have +gained popularity for analysis uses due to the existence of documentation and an active user +community, but has significant technical shortcomings. One of these is simply speed: OTP1 can be +orders of magnitude slower (and more memory-intensive) than the approaches exemplified in R5. The +other is the requirement to search at a single specific time. Travel times and especially wait times +on scheduled transit vary greatly depending on when you depart. Accounting for variation over a time +window requires repeated independent searches at each possible departure time, which is very +inefficient. R5 is highly optimized to capture variations in travel time across time windows and +account for uncertainty in waiting times on frequency-based routes. + +Due to its similarity to the R5 approach, OTP2's transit router would not have these same problems. +Nonetheless, we have decided not to port the OTP1 analysis features over to OTP2 since it would +broaden the focus away from passenger information and draw finite attention away from existing +projects like R5 and Conveyal Analysis. + +Accordingly, we have made an effort to clean up and augment OTP1 analysis documentation for +researchers who will continue to need it. It should remain possible for people to continue using +OTP1 if they prefer. If you would instead like to apply the innovations present in OTP2, we +recommend looking into R5 or Conveyal Analysis. ### Routers API and Hot Reloading -Via it's Routers API, OTP1 allows loading data and serving APIs for multiple separate geographic areas. This is functionally equivalent to running more than one OTP server with separate data sets. This system also allows reloading transportation network data when it changes, or even pushing new data over a network connection. +Via it's Routers API, OTP1 allows loading data and serving APIs for multiple separate geographic +areas. This is functionally equivalent to running more than one OTP server with separate data sets. +This system also allows reloading transportation network data when it changes, or even pushing new +data over a network connection. -These were all adaptations to the very different IT environment that existed earlier in OTP history. These days, containerization and on-demand cloud servers have become ubiquitous, and most users solve these problems in totally different ways - by provisioning and starting up entirely new virtual servers, then switching a load balancer over to those new servers. Because the Routers API is complex and exposes potentially damaging functionality over the network, it has been removed from OTP2 to simplify the code base and make it easier to reason about security. +These were all adaptations to the very different IT environment that existed earlier in OTP history. +These days, containerization and on-demand cloud servers have become ubiquitous, and most users +solve these problems in totally different ways - by provisioning and starting up entirely new +virtual servers, then switching a load balancer over to those new servers. Because the Routers API +is complex and exposes potentially damaging functionality over the network, it has been removed from +OTP2 to simplify the code base and make it easier to reason about security. ### Routing request parameters -Less parameters are available on the OTP2 REST API than in OTP1. Often there is no practical loss of functionality, just a different way of expressing things due to the new routing algorithms. A summary of parameters that have been removed and their replacements can be found in the migration guide [OTP2-MigrationGuide](OTP2-MigrationGuide.md). - +Less parameters are available on the OTP2 REST API than in OTP1. Often there is no practical loss of +functionality, just a different way of expressing things due to the new routing algorithms. A +summary of parameters that have been removed and their replacements can be found in the migration +guide [OTP2-MigrationGuide](OTP2-MigrationGuide.md). ## OTP Trip planning and Transit index APIs -OTP1 have two APIs for trip planning, the REST API and an obsolete GraphQL API(early version of -the Digitransit GraphQL API). OTP2 still support the REST API and it is very similar in functionality -compared with the OTP1 version. In the future we would like to create a new official OTP API using -GraphQL replacing the REST API. We will probably support the REST API for a long time to allow +OTP1 have two APIs for trip planning, the REST API and an obsolete GraphQL API(early version of the +Digitransit GraphQL API). OTP2 still support the REST API and it is very similar in functionality +compared with the OTP1 version. In the future we would like to create a new official OTP API using +GraphQL replacing the REST API. We will probably support the REST API for a long time to allow everyone to migrate to the new GraphQL API. Today, OTP2 comes with two Sandbox extension APIs: -- [HSL Legacy GraphQL API](sandbox/LegacyGraphQLApi.md) - HSL's GraphQL API used by the Digitransit project. +- [HSL Legacy GraphQL API](sandbox/LegacyGraphQLApi.md) - HSL's GraphQL API used by the Digitransit + project. - [Transmodel API](sandbox/TransmodelApi.md) - Entur´s Transmodel API The plan is to merge the two APIs above, clean it up and make it the new official API. The HSL API -uses GTFS terminology, while the Entur API is Transmodel(NeTEx) based. Both APIs are similar in +uses GTFS terminology, while the Entur API is Transmodel(NeTEx) based. Both APIs are similar in semantics/structure and provide the same functionality. The plan is to merge these to APIs into one new official OTP2 API. We will then deprecate the REST API, Transmodel API and the HSL API. The new -API will be available in a GTFS and a Transmodel "translated" version. - +API will be available in a GTFS and a Transmodel "translated" version. ## Additional characteristics added in OTP2 -**Sandbox Extensions** OTP2's Sandbox system allows for plugins, proprietary extensions, and experimental feature development with less overhead. It forces OTP2 to become more extensible, while reducing process overhead when developing non-core features. +**Sandbox Extensions** OTP2's Sandbox system allows for plugins, proprietary extensions, and +experimental feature development with less overhead. It forces OTP2 to become more extensible, while +reducing process overhead when developing non-core features. -**Cloud support** In OTP1 all data access (config, input data, and graph output) is by direct access to the local filesystem. The only exception is elevation data, which can be loaded from AWS S3 as well. In OTP2, all data access is through an abstraction layer. This can be configured to support individual local files, zip files, and Google Cloud Storage. The new data access treats directories and zip files as “equal”, and this functionality is used to read the contents of GTFS and NeTEx archives. Other data sources can be supported by writing plugins. Entur has written a plugin for AWS S3 which has not been merged. If requested they can provide this code for AWS S3. +**Cloud support** In OTP1 all data access (config, input data, and graph output) is by direct access +to the local filesystem. The only exception is elevation data, which can be loaded from AWS S3 as +well. In OTP2, all data access is through an abstraction layer. This can be configured to support +individual local files, zip files, and Google Cloud Storage. The new data access treats directories +and zip files as “equal”, and this functionality is used to read the contents of GTFS and NeTEx +archives. Other data sources can be supported by writing plugins. Entur has written a plugin for AWS +S3 which has not been merged. If requested they can provide this code for AWS S3. -**Library upgrades** We have adapted OTP2 to run on Java 11+ and moved to newer versions of some dependencies such as GraphQL and One Bus Away. +**Library upgrades** We have adapted OTP2 to run on Java 11+ and moved to newer versions of some +dependencies such as GraphQL and One Bus Away. -**Bugfixes** At least bug issues have been resolved in OTP2. Critical fixes have been backported to OTP1. See https://github.com/issues?q=is%3Aclosed+is%3Aissue+label%3AOTP2+label%3Abug +**Bugfixes** At least bug issues have been resolved in OTP2. Critical fixes have been backported to +OTP1. See https://github.com/issues?q=is%3Aclosed+is%3Aissue+label%3AOTP2+label%3Abug ## Other features removed from OTP2 -**AlertPatch** GTFS-RT Service Alerts will no longer affect routing (e.g. cancel trips). A GTFS-RT Trip Updates feed should be used for this purpose. +**AlertPatch** GTFS-RT Service Alerts will no longer affect routing (e.g. cancel trips). A GTFS-RT +Trip Updates feed should be used for this purpose. diff --git a/docs/Visual-Identity.md b/docs/Visual-Identity.md index ed5db807347..c32fec1d94c 100644 --- a/docs/Visual-Identity.md +++ b/docs/Visual-Identity.md @@ -1,10 +1,11 @@ -#OpenTripPlanner Visual Identity +# OpenTripPlanner Visual Identity This is the OpenTripPlanner logo in scalable vector format, with knockout transparency: ![OTP Logo](images/otp-logo.svg) -Here is a link to this SVG logo as a [downloadable file](images/otp-logo.svg). This is the raw SVG XML source code: +Here is a link to this SVG logo as a [downloadable file](images/otp-logo.svg). This is the raw SVG +XML source code: ``` @@ -22,10 +23,19 @@ Here is a link to this SVG logo as a [downloadable file](images/otp-logo.svg). T ``` -This concept behind this logo design was "infinite roads". Besides the clear references to movement and wayfinding through a transportation network, it (somewhat subliminally) contains the letters O T and P. This design is more geometric and austere than our previous logo, which makes it readily recognizable in a crowd of small app icons, bookmarks, or favicons. It also channels the high modern logos and 1970s supergraphics that were the visual style of public transport for a generation. +This concept behind this logo design was "infinite roads". Besides the clear references to movement +and wayfinding through a transportation network, it (somewhat subliminally) contains the letters O T +and P. This design is more geometric and austere than our previous logo, which makes it readily +recognizable in a crowd of small app icons, bookmarks, or favicons. It also channels the high modern +logos and 1970s supergraphics that were the visual style of public transport for a generation. The color of the logo in the RGB colorspace is `#2179BF`. -The name of the OpenTripPlanner project is written in CamelCase: capital letters at the beginning of each word, with no spaces between the words. For the logotype we do not strictly adhere to a standard typeface. The OTP website just uses the CSS declarations `font: 30pt helvetica, sans-serif; font-weight: bold;`. +The name of the OpenTripPlanner project is written in CamelCase: capital letters at the beginning of +each word, with no spaces between the words. For the logotype we do not strictly adhere to a +standard typeface. The OTP website just uses the CSS +declarations `font: 30pt helvetica, sans-serif; font-weight: bold;`. -The OpenTripPlanner logo was created by Brooklyn-based cartographer and graphic designer [Kate Chanba](https://kchanba.com/), who has also done extensive work on transit system maps. +The OpenTripPlanner logo was created by Brooklyn-based cartographer and graphic +designer [Kate Chanba](https://kchanba.com/), who has also done extensive work on transit system +maps. diff --git a/docs/examples/Readme.md b/docs/examples/Readme.md index 783c6d1797d..0ebb9e79e2c 100644 --- a/docs/examples/Readme.md +++ b/docs/examples/Readme.md @@ -1,18 +1,22 @@ # Example configurations -When setting up OTP it is often useful to have some examples to look at. If you have an example to share just add it here. - +When setting up OTP it is often useful to have some examples to look at. If you have an example to +share just add it here. ## Examples + | Name | Organisation | Description | |-------|---------------|------------------------------------------------| | entur | Entur, Norway | Deployment Configuration with NeTEX input data | -## Support -The examples are provided "as is" - they may get outdated over time or miss information, and it is left to the provider, not the PLC, to include whatever the provider find useful. +## Support +The examples are provided "as is" - they may get outdated over time or miss information, and it is +left to the provider, not the PLC, to include whatever the provider find useful. ## How to share an example -Anyone who want can add their example here as long as it is OTP "related". Just create a normal pull-request to add it. + +Anyone who want can add their example here as long as it is OTP "related". Just create a normal +pull-request to add it. diff --git a/docs/examples/entur/Readme.md b/docs/examples/entur/Readme.md index 4da3d43ce0b..3a97db748ef 100644 --- a/docs/examples/entur/Readme.md +++ b/docs/examples/entur/Readme.md @@ -1,23 +1,39 @@ # Entur Deployment Configuration -This is a snapshot of Enturs deployment configuration. At Entur we run OTP in the cloud, so some of the provided config will not work outside Enturs cluster, but it is provided "as is" for others to replicate if they want. + +This is a snapshot of Enturs deployment configuration. At Entur we run OTP in the cloud, so some of +the provided config will not work outside Enturs cluster, but it is provided "as is" for others to +replicate if they want. ## Config files -See the config files provided. The `updaters` section of the `router-config.json` is provided, but is not working. Remove it if you want to run OTP. It is provided for others as an example on how to configure the SIRI updaters. The same goes for the `storage` section in the `build-config.json`, remove it run OTP locally. -The ``, `` and `` are placeholders you need to change. +See the config files provided. The `updaters` section of the `router-config.json` is provided, but +is not working. Remove it if you want to run OTP. It is provided for others as an example on how to +configure the SIRI updaters. The same goes for the `storage` section in the `build-config.json`, +remove it run OTP locally. +The ``, `` and `` are placeholders you need to change. ## Data input files -At Entur we run OTP with the latest NeTEx data we have. You may download it from here: +At Entur we run OTP with the latest NeTEx data we have. You may download it from here: https://developer.entur.org/stops-and-timetable-data -We use the [Entire Norway](https://storage.googleapis.com/marduk-production/outbound/netex/rb_norway-aggregated-netex.zip) file. +We use +the [Entire Norway](https://storage.googleapis.com/marduk-production/outbound/netex/rb_norway-aggregated-netex.zip) +file. + +In the past the file did not contain the stops, so they needed to be downloaded separably (Entire +Norway (Current stops) - Latest valid version of all country stops) and inserted into the +Netex-file. Unpack the stops zipfile, rename the stops file to `_stops.xml`. Unpack the netex file +and move the `_stops.xml` into the netex directory. Copy the netex directory and config files into +the same directory and start OTP with it as the base directory. -In the past the file did not contain the stops, so they needed to be downloaded separably (Entire Norway (Current stops) - Latest valid version of all country stops) and inserted into the Netex-file. Unpack the stops zipfile, rename the stops file to `_stops.xml`. Unpack the netex file and move the `_stops.xml` into the netex directory. Copy the netex directory and config files into the same directory and start OTP with it as the base directory. - -We also build with elevation data, which is not available on the internet without transformation. Send us a request, and we will find a way to share it. +We also build with elevation data, which is not available on the internet without transformation. +Send us a request, and we will find a way to share it. -We download the OSM data file [norway-latest.osm.pbf](https://download.geofabrik.de/europe/norway.html) every night and build a street-graph with OSM and elevation data. We also use some custom OSM files for areas outside Norway, but they in most cases insignificant. If requested, we can provide them. +We download the OSM data +file [norway-latest.osm.pbf](https://download.geofabrik.de/europe/norway.html) every night and build +a street-graph with OSM and elevation data. We also use some custom OSM files for areas outside +Norway, but they in most cases insignificant. If requested, we can provide them. \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 8e6bfa4e8e7..90e5f8f2dee 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,39 +1,72 @@ ![OTP Logo](images/otp-logo.svg) -# OpenTripPlanner 2 -**OpenTripPlanner** (OTP) is an open source multi-modal trip planner, focusing on travel by scheduled public transportation in combination with bicycling, walking, and mobility services including bike share and ride hailing. Its server component runs on any platform with a Java virtual machine (including Linux, Mac, and Windows). It exposes REST and GraphQL APIs that can be accessed by various clients including open source Javascript components and native mobile applications. It builds its representation of the transportation network from open data in open standard file formats (primarily GTFS and OpenStreetMap). It applies real-time updates and alerts with immediate visibility to clients, finding itineraries that account for disruptions and service changes. OTP is released under the [LGPL license](https://opensource.org/licenses/LGPL-3.0). As of 2020, the codebase has been in active development for over ten years, and is relied upon by transportation authorities and travel planning applications in [deployments](Deployments.md) around the world. +# OpenTripPlanner 2 -You are currently reading the documentation for **OpenTripPlanner 2**, the second major version of OTP. +**OpenTripPlanner** (OTP) is an open source multi-modal trip planner, focusing on travel by +scheduled public transportation in combination with bicycling, walking, and mobility services +including bike share and ride hailing. Its server component runs on any platform with a Java virtual +machine (including Linux, Mac, and Windows). It exposes REST and GraphQL APIs that can be accessed +by various clients including open source Javascript components and native mobile applications. It +builds its representation of the transportation network from open data in open standard file +formats (primarily GTFS and OpenStreetMap). It applies real-time updates and alerts with immediate +visibility to clients, finding itineraries that account for disruptions and service changes. OTP is +released under the [LGPL license](https://opensource.org/licenses/LGPL-3.0). As of 2020, the +codebase has been in active development for over ten years, and is relied upon by transportation +authorities and travel planning applications in [deployments](Deployments.md) around the world. +You are currently reading the documentation for **OpenTripPlanner 2**, the second major version of +OTP. # Versions of this documentation -Several versions of this documentation are built and published automatically for different branches of OTP. Each of these has a different stable URL, and you may switch between these versions using the selector in the lower right of the published documentation. +Several versions of this documentation are built and published automatically for different branches +of OTP. Each of these has a different stable URL, and you may switch between these versions using +the selector in the lower right of the published documentation. - - [Latest](http://docs.opentripplanner.org/en/latest) - Version 2.1 (the git master branch) - - [v2.0.0](http://docs.opentripplanner.org/en/v2.0.0) - Version 2.0 - - [v1.5.0](http://docs.opentripplanner.org/en/v1.5.0) - Stable 1.x release - - [dev-2.x](http://docs.opentripplanner.org/en/dev-2.x) - OTP 2 active development - - [dev-1.x](http://docs.opentripplanner.org/en/dev-1.x) - OTP 1 active development +- [Latest](http://docs.opentripplanner.org/en/latest) - Version 2.1 (the git master branch) +- [v2.0.0](http://docs.opentripplanner.org/en/v2.0.0) - Version 2.0 +- [v1.5.0](http://docs.opentripplanner.org/en/v1.5.0) - Stable 1.x release +- [dev-2.x](http://docs.opentripplanner.org/en/dev-2.x) - OTP 2 active development +- [dev-1.x](http://docs.opentripplanner.org/en/dev-1.x) - OTP 1 active development # Audience -The end users of OTP are the millions of people who rely on it to help plan their daily travel, often without even knowing they are using OTP. As an infrastructure component, installation and configuration of OTP tends to be somewhat technical and essentially invisible to those end users. This documentation is indended for people who wish to perform such deployments of OTP without necessarily diving into the internal details of the software. +The end users of OTP are the millions of people who rely on it to help plan their daily travel, +often without even knowing they are using OTP. As an infrastructure component, installation and +configuration of OTP tends to be somewhat technical and essentially invisible to those end users. +This documentation is indended for people who wish to perform such deployments of OTP without +necessarily diving into the internal details of the software. + +For members of the OTP community interested in software development, additional documentation +detailing algorithms, data structures etc. is available as markdown files within the source code +packages. It can be read in your IDE or when browsing the source tree on Github. See +[OTP Architecture](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/ARCHITECTURE.md). -For members of the OTP community interested in software development, additional documentation detailing algorithms, data structures etc. is available as markdown files within the source code packages. It can be read in your IDE or when browsing the source tree on Github. See -[OTP Architecture](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/ARCHITECTURE.md). - # Quick Start -We encourage you to read the introductory sections of this documentation to familiarize yourself with OpenTripPlanner use cases and configuration. But if you want to get started right away running your own OTP instance, the best place to start is the [Basic Tutorial](Basic-Tutorial.md) page. + +We encourage you to read the introductory sections of this documentation to familiarize yourself +with OpenTripPlanner use cases and configuration. But if you want to get started right away running +your own OTP instance, the best place to start is the [Basic Tutorial](Basic-Tutorial.md) page. # Contact Info -Send questions and comments to the [user mailing list](http://groups.google.com/group/opentripplanner-users). -Discuss internal development details on the [dev mailing list](http://groups.google.com/group/opentripplanner-dev). -File bug reports via the Github [issue tracker](https://github.com/openplans/OpenTripPlanner/issues). Note that the issue tracker is not intended for support questions or discussions. Please post them to one of the mailing lists instead. +Send questions and comments to +the [user mailing list](http://groups.google.com/group/opentripplanner-users). Discuss internal +development details on the [dev mailing list](http://groups.google.com/group/opentripplanner-dev). +File bug reports via the Github [issue tracker](https://github.com/openplans/OpenTripPlanner/issues) +. Note that the issue tracker is not intended for support questions or discussions. Please post them +to one of the mailing lists instead. # Financial and In-Kind Support -OpenTripPlanner is a member project of Software Freedom Conservancy, a 501(c)(3) organization incorporated in New York, and donations made to it are fully tax-deductible to the extent permitted by law. Donations can be made by credit card, wire transfer or paper check. Please contact for instructions. +OpenTripPlanner is a member project of Software Freedom Conservancy, a 501(c)(3) organization +incorporated in New York, and donations made to it are fully tax-deductible to the extent permitted +by law. Donations can be made by credit card, wire transfer or paper check. Please +contact for instructions. -OTP development is primarily carried out by full-time software engineers employed by transportation authorities and consultancies. Even with funding, it can be difficult to engage staff who have the specialized skill set required. Therefore, one of the best ways to support OTP is to allocate software development staff at your organization with transportation domain knowledge to participate in weekly development meetings and contribute to this effort. This also builds connections between organizations favoring open source collaboration. \ No newline at end of file +OTP development is primarily carried out by full-time software engineers employed by transportation +authorities and consultancies. Even with funding, it can be difficult to engage staff who have the +specialized skill set required. Therefore, one of the best ways to support OTP is to allocate +software development staff at your organization with transportation domain knowledge to participate +in weekly development meetings and contribute to this effort. This also builds connections between +organizations favoring open source collaboration. \ No newline at end of file diff --git a/docs/sandbox/ActuatorAPI.md b/docs/sandbox/ActuatorAPI.md index 3421f0184ef..d61d99f256c 100644 --- a/docs/sandbox/ActuatorAPI.md +++ b/docs/sandbox/ActuatorAPI.md @@ -1,14 +1,17 @@ # Actuator API ## Contact Info + - Entur, Norway ## Changelog + - Initial implementation of readiness endpoint (November 2019) - Prometheus metrics added using Micrometer (October 2021) - GraphQL metrics added to prometheus export (November 2021) ## Documentation + This provides endpoints for checking the health status of the OTP instance. It can be useful when running OTP in a container. @@ -19,8 +22,8 @@ actuator API standard. #### /health -The health endpoints returns an 200 OK status code once the graph is loaded and all updaters are ready. -Otherwise, a 404 NOT FOUND is returned. +The health endpoints returns an 200 OK status code once the graph is loaded and all updaters are +ready. Otherwise, a 404 NOT FOUND is returned. #### /prometheus @@ -30,4 +33,5 @@ Also, GraphQL timing metrics are exported under `graphql.timer.query` and `graph if the GraphQL endpoints are enabled. ### Configuration + To enable this you need to add the feature `ActuatorAPI`. diff --git a/docs/sandbox/DataOverlay.md b/docs/sandbox/DataOverlay.md index 63a273022cc..5effff75380 100644 --- a/docs/sandbox/DataOverlay.md +++ b/docs/sandbox/DataOverlay.md @@ -1,8 +1,12 @@ # Data Overlay -Use grid data in NetCDF format to populate the graph. Also provides custom route endpoint parameters for the data "penalty" and "threshold". This allows route planning to be based on the custom data calculated penalties. Data examples: air quality, environmental, and other data types that are tied to certain geographical locations. +Use grid data in NetCDF format to populate the graph. Also provides custom route endpoint parameters +for the data "penalty" and "threshold". This allows route planning to be based on the custom data +calculated penalties. Data examples: air quality, environmental, and other data types that are tied +to certain geographical locations. ## Contact Info + Developed and maintained by Metatavu OY, Finland. Developers: @@ -11,25 +15,33 @@ Developers: Simeon Platonov - simeon.platonov@metatavu.fi\ Daniil Smirnov - daniil.smirnov@metatavu.fi -In case of any questions please contact any of the people above by emails. We would like to continue developing and improving this feature and would love to hear any ideas from the community. +In case of any questions please contact any of the people above by emails. We would like to continue +developing and improving this feature and would love to hear any ideas from the community. Company email: info@metatavu.fi ## Changelog -- Initial version (December 2021) +- Initial version (December 2021) ## Documentation -We have been working with OTP since version 1 mainly for producing the Air Quality affected routing for the city of Helsinki, Finland. That project required us to modify the original OTP quite a lot so we didn't propose our efforts for the community. +We have been working with OTP since version 1 mainly for producing the Air Quality affected routing +for the city of Helsinki, Finland. That project required us to modify the original OTP quite a lot +so we didn't propose our efforts for the community. -With the OTP2 release we decided to create a dedicated layer on top of OTP2 which not only leaves the initial structure of the OpenTripPlanner intact, but also brings some additional features for those, who actually need them. This layer's main feature is populating the graph with a grid data (i.e air quality, temperature, humidity, pressure, wind speed and direction, and e.t.c). For this to work two files are required: the actual data file (i.e in NetCDF format) and a .json settings file which describes the contents of the data file. Please refer to the diagram for more information. +With the OTP2 release we decided to create a dedicated layer on top of OTP2 which not only leaves +the initial structure of the OpenTripPlanner intact, but also brings some additional features for +those, who actually need them. This layer's main feature is populating the graph with a grid data ( +i.e air quality, temperature, humidity, pressure, wind speed and direction, and e.t.c). For this to +work two files are required: the actual data file (i.e in NetCDF format) and a .json settings file +which describes the contents of the data file. Please refer to the diagram for more information. It is a sandbox feature. Please see the configuration part for setup instructions and examples. -### Configuration +### Configuration Enable the feature by including it to the ```otp-config.json```: @@ -38,20 +50,29 @@ Enable the feature by including it to the ```otp-config.json```: { "otpFeatures": { "DataOverlay" : true } } ``` -Plugin configuration should explain the NetCDF data file and request parameters that use the data file. +Plugin configuration should explain the NetCDF data file and request parameters that use the data +file. + * _fileName_ points to the data file -* _latitudeVariable_, _longitudeVariable_ and _timeVariable_ should be equal to the corresponding variable names of the data file +* _latitudeVariable_, _longitudeVariable_ and _timeVariable_ should be equal to the corresponding + variable names of the data file * _timeFormat_ options: MS_EPOCH, SECONDS, HOURS * _indexVariables_ contain a list of variables of data file that will affect the routing. - * _name_ can have any value and exists to act as a reference for _requestPatameters_ (see below) - * _displayName_ is a variable name in human-readable form that should make it more understandable - * _variable_ is the actual name of the variable from data file -* _requestParameters_ contains the list of REST request parameters that affects the cost calculation. - * _name_ should be chosen from the list of enums: org.opentripplanner.ext.dataoverlay.api.ParameterName - * _variable_ should correspond to the _name_ of one of the entries from _indexVariables_ list and explain which data field this parameter corresponds to - * _formula_ should use the keywords VALUE and THRESHOLD and describe the way the penalty is calculated. Note: if the result of the formula is negative it is ignored. + * _name_ can have any value and exists to act as a reference for _requestPatameters_ (see below) + * _displayName_ is a variable name in human-readable form that should make it more + understandable + * _variable_ is the actual name of the variable from data file +* _requestParameters_ contains the list of REST request parameters that affects the cost + calculation. + * _name_ should be chosen from the list of enums: + org.opentripplanner.ext.dataoverlay.api.ParameterName + * _variable_ should correspond to the _name_ of one of the entries from _indexVariables_ list + and explain which data field this parameter corresponds to + * _formula_ should use the keywords VALUE and THRESHOLD and describe the way the penalty is + calculated. Note: if the result of the formula is negative it is ignored. Example of build-config.json that includes the dataOverlay plugin configuration: + ```json // build-config.json { @@ -91,7 +112,10 @@ Example of build-config.json that includes the dataOverlay plugin configuration: } ``` -Default values for Data overlay plugin can also be included in router-config instead of being sent with each request. If any Data overlay parameters are passed in user query, all the default values from router-config are ignored. +Default values for Data overlay plugin can also be included in router-config instead of being sent +with each request. If any Data overlay parameters are passed in user query, all the default values +from router-config are ignored. + ```json // router-config.json { diff --git a/docs/sandbox/Flex.md b/docs/sandbox/Flex.md index d7ec181f6b5..93c3ed9e98a 100644 --- a/docs/sandbox/Flex.md +++ b/docs/sandbox/Flex.md @@ -6,22 +6,30 @@ - Entur, Norway - Hannes Junnila - ## Changelog ### OTP 2.1 + - Initial implementation of Flexible transit routing -- Use one-to-many search in order to make the performance of the StreetFlexPathCalculator acceptable. (April 2021) -- Also link transit stops used by flex trips to the closest car traversable edge. This allows flex street routing all the way to the stop. (April 2021) -- Fix performance issues with the StreetFlexPathCalculator [#3460](https://github.com/opentripplanner/OpenTripPlanner/pull/3460) -- Improve performance of flex access/egress routing [#3661](https://github.com/opentripplanner/OpenTripPlanner/pull/3661) -- Allow getting on and off at the same flex stop time [#3720](https://github.com/opentripplanner/OpenTripPlanner/pull/3720) -- Calculate fare for flex routes [#3743](https://github.com/opentripplanner/OpenTripPlanner/pull/3743) +- Use one-to-many search in order to make the performance of the StreetFlexPathCalculator + acceptable. (April 2021) +- Also link transit stops used by flex trips to the closest car traversable edge. This allows flex + street routing all the way to the stop. (April 2021) +- Fix performance issues with the + StreetFlexPathCalculator [#3460](https://github.com/opentripplanner/OpenTripPlanner/pull/3460) +- Improve performance of flex access/egress + routing [#3661](https://github.com/opentripplanner/OpenTripPlanner/pull/3661) +- Allow getting on and off at the same flex stop + time [#3720](https://github.com/opentripplanner/OpenTripPlanner/pull/3720) +- Calculate fare for flex + routes [#3743](https://github.com/opentripplanner/OpenTripPlanner/pull/3743) ## Documentation -To enable this turn on `FlexRouting` as a feature in `otp-config.json`. -The GTFS feeds should conform to the [GTFS-Flex v2.1 draft](https://github.com/MobilityData/gtfs-flex/blob/master/spec/reference.md) +To enable this turn on `FlexRouting` as a feature in `otp-config.json`. + +The GTFS feeds should conform to +the [GTFS-Flex v2.1 draft](https://github.com/MobilityData/gtfs-flex/blob/master/spec/reference.md) ## Configuration @@ -42,11 +50,11 @@ configuration, add the following to `router-config.json`. Default: 300 -How long should a passenger be allowed to walk after getting out of a flex vehicle and transferring -to a flex or transit one. +How long should a passenger be allowed to walk after getting out of a flex vehicle and transferring +to a flex or transit one. -This was mainly introduced to improve performance which is also the reason for not using the existing -value with the same name: fixed schedule transfers are computed during the graph build but flex -ones are calculated at request time and are more sensitive to slowdown. +This was mainly introduced to improve performance which is also the reason for not using the +existing value with the same name: fixed schedule transfers are computed during the graph build but +flex ones are calculated at request time and are more sensitive to slowdown. A lower value means that the routing is faster. diff --git a/docs/sandbox/GoogleCloudStorage.md b/docs/sandbox/GoogleCloudStorage.md index bf736e2ed49..36215c0535c 100644 --- a/docs/sandbox/GoogleCloudStorage.md +++ b/docs/sandbox/GoogleCloudStorage.md @@ -1,21 +1,24 @@ -# Google Cloud Storage - Using GCS Bucket as a OTP Data Source +# Google Cloud Storage - Using GCS Bucket as a OTP Data Source ## Contact Info - Thomas Gran, Entur, Norway - ## Changelog ### OTP 2.0 + - Initial implementation to access Google Cloud Storage (read and write). (December 2019) ## Documentation -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 [`StorageConfig`](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/standalone/config/StorageConfig.java) on how to configure artifacts. - +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 [`StorageConfig`](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/main/java/org/opentripplanner/standalone/config/StorageConfig.java) +on how to configure artifacts. Example (build-config.json): + ```json { "storage" : { diff --git a/docs/sandbox/InteractiveOtpMain.md b/docs/sandbox/InteractiveOtpMain.md index 6b7397e16b0..5d93aa40b01 100644 --- a/docs/sandbox/InteractiveOtpMain.md +++ b/docs/sandbox/InteractiveOtpMain.md @@ -1,17 +1,18 @@ # Interactive OTP Launcher -A GUI popup window to which help you to start OTP Main interactively. +A GUI popup window to which help you to start OTP Main interactively. ## Contact Info -- Thomas Gran, Norway +- Thomas Gran, Norway ## Changelog -- Initial version (October 2020) +- Initial version (October 2020) ## Documentation -This is a simple GUI to help launch OTP Main. It is useful if you frequently launch OTP with -data set and/or configuration. The `InteractiveOtpMain` search for all OTP data configurations + +This is a simple GUI to help launch OTP Main. It is useful if you frequently launch OTP with data +set and/or configuration. The `InteractiveOtpMain` search for all OTP data configurations directories available and help the user configure and start OTP. diff --git a/docs/sandbox/LegacyGraphQLApi.md b/docs/sandbox/LegacyGraphQLApi.md index 67862d0216b..ea4769cc44e 100644 --- a/docs/sandbox/LegacyGraphQLApi.md +++ b/docs/sandbox/LegacyGraphQLApi.md @@ -1,10 +1,12 @@ # HSL Legacy GraphQL API - OTP Sandbox Extension ## Contact Info + - Digitransit team, HSL, Helsinki, Finland - Kyyti, Helsinki, Finland ## Changelog + - Initial version of Legacy Graph QL API (September 2020) - Added ids parameter to bikeRentalStations query (May 2021, https://github.com/opentripplanner/OpenTripPlanner/pull/3450) - Added capacity and allowOverloading fields to bike rental stations (not yet properly implemented) (May 2021, https://github.com/opentripplanner/OpenTripPlanner/pull/3450) @@ -26,8 +28,7 @@ ## Documentation This is a copy of HSL's GraphQL API used by the Digitransit project. The API is used to run OTP2 - together with the [digitransit-ui](https://github.com/HSLdevcom/digitransit-ui). - +together with the [digitransit-ui](https://github.com/HSLdevcom/digitransit-ui). The GraphQL endpoints are available at: @@ -44,14 +45,16 @@ curl --request POST \ --data '{"query":"query stops {\n stops {\n gtfsId\n name\n }\n}\n","operationName":"stops"}' ``` -### OTP2 Official GraphQL API (Not available) +### OTP2 Official GraphQL API (Not available) + We **plan** to make a new offical OTP2 API, replacing the REST API. The plan is to base the new API -on this API and the [Legacy GraphQL Api](LegacyGraphQLApi.md). The new API will most likely have 2 -"translations": A GTFS version and a Transmodel version, we will try to keep the semantics the same. +on this API and the [Legacy GraphQL Api](LegacyGraphQLApi.md). The new API will most likely have 2 +"translations": A GTFS version and a Transmodel version, we will try to keep the semantics the same. ### Configuration + To enable this you need to add the feature `SandboxAPILegacyGraphQLApi`. - + ``` // otp-config.json { diff --git a/docs/sandbox/MapboxVectorTilesApi.md b/docs/sandbox/MapboxVectorTilesApi.md index a5653b3531c..e6e82b7eb15 100644 --- a/docs/sandbox/MapboxVectorTilesApi.md +++ b/docs/sandbox/MapboxVectorTilesApi.md @@ -1,29 +1,35 @@ # Mapbox Vector Tiles API ## Contact Info + - HSL, Finland - Kyyti Group Oy, Finland - Hannes Junnila - ## Changelog + - 2020-07-09: Initial version of Mapbox vector tiles API - 2021-05-12: Make expansion factor configurable - 2021-09-07: Rename `BikeRental` to `VehicleRental` -- 2021-10-13: Correctly serialize the vehicle rental name [#3648](https://github.com/opentripplanner/OpenTripPlanner/pull/3648) +- 2021-10-13: Correctly serialize the vehicle rental + name [#3648](https://github.com/opentripplanner/OpenTripPlanner/pull/3648) - 2022-01-03: Add support for VehicleParking entities ## Documentation -This API produces [Mapbox vector tiles](https://docs.mapbox.com/vector-tiles/reference/), which are used by eg. [Digitransit-ui](https://github.com/HSLdevcom/digitransit-ui) to show information about public transit entities on the map. +This API produces [Mapbox vector tiles](https://docs.mapbox.com/vector-tiles/reference/), which are +used by eg. [Digitransit-ui](https://github.com/HSLdevcom/digitransit-ui) to show information about +public transit entities on the map. -The tiles can be fetched from `/otp/routers/{routerId}/vectorTiles/{layers}/{z}/{x}/{y}.pbf`, where `layers` is a comma separated list of layer names from the configuration. +The tiles can be fetched from `/otp/routers/{routerId}/vectorTiles/{layers}/{z}/{x}/{y}.pbf`, +where `layers` is a comma separated list of layer names from the configuration. ### Configuration + To enable this you need to add the feature `SandboxAPIMapboxVectorTilesApi` in `otp-config.json`. The feature must be configured in `router-config.json` as follows - + ``` { "vectorTileLayers": [ @@ -67,34 +73,45 @@ The feature must be configured in `router-config.json` as follows For each layer, the configuration includes: - - `name` which is used in the url to fetch tiles, and as the layer name in the vector tiles. - - `type` which tells the type of the layer. Currently `Stop`, `Station`, `VehicleRental` and `VehicleParking` are supported. - - `mapper` which describes the mapper converting the properties from the OTP model entities to the vector tile properties. Currently `Digitransit` is supported for all layer types. - - `minZoom` and `maxZoom` which describe the zoom levels the layer is active for. - - `cacheMaxSeconds` which sets the cache header in the response. The lowest value of the layers included is selected. - - `expansionFactor` 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. +- `name` which is used in the url to fetch tiles, and as the layer name in the vector tiles. +- `type` which tells the type of the layer. Currently `Stop`, `Station`, `VehicleRental` + and `VehicleParking` are supported. +- `mapper` which describes the mapper converting the properties from the OTP model entities to the + vector tile properties. Currently `Digitransit` is supported for all layer types. +- `minZoom` and `maxZoom` which describe the zoom levels the layer is active for. +- `cacheMaxSeconds` which sets the cache header in the response. The lowest value of the layers + included is selected. +- `expansionFactor` 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. ### Extending -If more generic layers are created for this API, it should be moved out from the sandbox, into the core code, with potentially leaving specific property mappers in place. +If more generic layers are created for this API, it should be moved out from the sandbox, into the +core code, with potentially leaving specific property mappers in place. #### Creating a new layer -In order to create a new type of layer, you need to create a new class extending `LayerBuilder`. -You need to implement two methods, `List getGeometries(Envelope query)`, which returns a list of geometries, with an object of type `T` as their userData in the geometry, and `double getExpansionFactor()`, which describes how much information outside the tile bounds should be included. -This layer then needs to be added into `VectorTilesResource.layers`, with a new `LayerType` enum as the key, and the class constructor as the value. +In order to create a new type of layer, you need to create a new class extending `LayerBuilder`. +You need to implement two methods, `List getGeometries(Envelope query)`, which returns a +list of geometries, with an object of type `T` as their userData in the geometry, +and `double getExpansionFactor()`, which describes how much information outside the tile bounds +should be included. This layer then needs to be added into `VectorTilesResource.layers`, with a +new `LayerType` enum as the key, and the class constructor as the value. A new mapper needs to be added every time a new layer is added. See below for information. #### Creating a new mapper -The mapping contains information of what data to include in the vector tiles. The mappers are defined per layer. +The mapping contains information of what data to include in the vector tiles. The mappers are +defined per layer. -In order to create a new mapper for a layer, you need to create a new class extending `PropertyMapper`. -In that class, you need to implement the method `Collection> map(T input)`. -The type T is dependent on the layer for which you implement the mapper for. -It needs to return a list of attributes, as key-value pairs which will be written into the vector tile. +In order to create a new mapper for a layer, you need to create a new class +extending `PropertyMapper`. In that class, you need to implement the +method `Collection> map(T input)`. The type T is dependent on the layer for which +you implement the mapper for. It needs to return a list of attributes, as key-value pairs which will +be written into the vector tile. -The mapper needs to be added to the `mappers` map in the layer, with a new `MapperType` enum as the key, and a function to create the mapper, with a `Graph` object as a parameter, as the value. +The mapper needs to be added to the `mappers` map in the layer, with a new `MapperType` enum as the +key, and a function to create the mapper, with a `Graph` object as a parameter, as the value. diff --git a/docs/sandbox/ParkAndRideApi.md b/docs/sandbox/ParkAndRideApi.md index 558a3a76499..acd80085537 100644 --- a/docs/sandbox/ParkAndRideApi.md +++ b/docs/sandbox/ParkAndRideApi.md @@ -1,6 +1,7 @@ # Park and Ride API ## Contact Info + - Evan Siroky, IBI Group, USA ## Changelog @@ -9,4 +10,5 @@ ## Documentation -This adds a new API endpoint for fetching Park and Rides included in the current graph. It is possible to search using a bounding box and/or proximity of Park and Rides to nearby transit stops. \ No newline at end of file +This adds a new API endpoint for fetching Park and Rides included in the current graph. It is +possible to search using a bounding box and/or proximity of Park and Rides to nearby transit stops. \ No newline at end of file diff --git a/docs/sandbox/ReportApi.md b/docs/sandbox/ReportApi.md index abe0673eaf3..2b1447c8906 100644 --- a/docs/sandbox/ReportApi.md +++ b/docs/sandbox/ReportApi.md @@ -6,29 +6,31 @@ programs, the report can be changed at any time - without any notice. Feel free to add more reports and to add your organization to the contact info list. - ## Contact Info + - Entur, Norway - [Leonard Ehrenfried](https://leonard.io), Germany, [mail@leonard.io](mailto:mail@leonard.io) - ## Changelog - 2021-05-19: Initial version of the report API. Support listing all transfers as a CSV text file. -- 2021-07-19: Add report that exports the bicycle safety factors as CSV and an interactive HTML table view. +- 2021-07-19: Add report that exports the bicycle safety factors as CSV and an interactive HTML + table view. ## Documentation This module mounts an endpoint for generating reports under `otp/report`. Available reports: - - [/otp/report/transfers.csv](http://localhost:8080/otp/report/transfers.csv) - - [/otp/report/bicycle-safety.html](http://localhost:8080/otp/report/bicycle-safety.html): Interactive viewer of the rules that determine how bicycle safety factors are calculated. - - [/otp/report/bicycle-safety.csv](http://localhost:8080/otp/report/bicycle-safety.csv): Raw CSV data for the bicycle safety report. - - [Norwegian version](http://localhost:8080/otp/report/bicycle-safety.csv?osmWayPropertySet=norway) - - [German version](http://localhost:8080/otp/report/bicycle-safety.csv?osmWayPropertySet=germany) - - [UK version](http://localhost:8080/otp/report/bicycle-safety.csv?osmWayPropertySet=uk) - - [Finnish version](http://localhost:8080/otp/report/bicycle-safety.csv?osmWayPropertySet=finland) - +- [/otp/report/transfers.csv](http://localhost:8080/otp/report/transfers.csv) +- [/otp/report/bicycle-safety.html](http://localhost:8080/otp/report/bicycle-safety.html): + Interactive viewer of the rules that determine how bicycle safety factors are calculated. +- [/otp/report/bicycle-safety.csv](http://localhost:8080/otp/report/bicycle-safety.csv): Raw CSV + data for the bicycle safety report. + - [Norwegian version](http://localhost:8080/otp/report/bicycle-safety.csv?osmWayPropertySet=norway) + - [German version](http://localhost:8080/otp/report/bicycle-safety.csv?osmWayPropertySet=germany) + - [UK version](http://localhost:8080/otp/report/bicycle-safety.csv?osmWayPropertySet=uk) + - [Finnish version](http://localhost:8080/otp/report/bicycle-safety.csv?osmWayPropertySet=finland) + ### Configuration The report API is turned _off_ by default. To turn it on enable the `ReportApi` feature. diff --git a/docs/sandbox/SiriUpdator.md b/docs/sandbox/SiriUpdator.md index 506e4db2d78..e1abd763d36 100644 --- a/docs/sandbox/SiriUpdator.md +++ b/docs/sandbox/SiriUpdator.md @@ -1,24 +1,31 @@ # Siri Updator -Support for consuming SIRI ET, SX and ET messages. The updator is developed to support the Norwegian SIRI profile which is a subset of the SIRI specification. + +Support for consuming SIRI ET, SX and ET messages. The updator is developed to support the Norwegian +SIRI profile which is a subset of the SIRI specification. ## Contact Info -- Lasse Tyrihjell, Entur, Norway +- Lasse Tyrihjell, Entur, Norway ## Changelog -- Initial version of SIRI updator (October 2019) -- Include situations with no or no handled entity selectors with Unknown EntitySelector (December 2021, https://github.com/opentripplanner/OpenTripPlanner/pull/3780) +- Initial version of SIRI updator (October 2019) +- Include situations with no or no handled entity selectors with Unknown EntitySelector (December + 2021, https://github.com/opentripplanner/OpenTripPlanner/pull/3780) ## Documentation -This updator consumes SIRI Real Time Information. It is developed by entur and support the Nordic -Profile for SIRI. It should be possible to develop it further to support a broader set of the -SIRI specification. -For more documentation goto the [Entur Real-Time Data](https://developer.entur.org/pages-real-time-intro) documentation and the [Norwegian SIRI profile](https://enturas.atlassian.net/wiki/spaces/PUBLIC/pages/637370420/Norwegian+SIRI+profile). +This updator consumes SIRI Real Time Information. It is developed by entur and support the Nordic +Profile for SIRI. It should be possible to develop it further to support a broader set of the SIRI +specification. + +For more documentation goto +the [Entur Real-Time Data](https://developer.entur.org/pages-real-time-intro) documentation and +the [Norwegian SIRI profile](https://enturas.atlassian.net/wiki/spaces/PUBLIC/pages/637370420/Norwegian+SIRI+profile) +. - ### Configuration + To enable the SIRI updator you need to add it to the updators section of the `router-config.json`. ``` diff --git a/docs/sandbox/SmooveBikeRental.md b/docs/sandbox/SmooveBikeRental.md index e00e7d0e382..f325eca514c 100644 --- a/docs/sandbox/SmooveBikeRental.md +++ b/docs/sandbox/SmooveBikeRental.md @@ -1,18 +1,24 @@ # HSL Smoove Bike Rental Updater Support - OTP Sandbox Extension ## Contact Info + - Digitransit team, HSL, Helsinki, Finland ## Changelog + - Move this functonality into a sandbox -- Add allowOverloading through updater config to the stations and isRenting, isReturning and capacity from the data to stations (October 2021, https://github.com/opentripplanner/OpenTripPlanner/pull/3632) +- Add allowOverloading through updater config to the stations and isRenting, isReturning and + capacity from the data to stations (October + 2021, https://github.com/opentripplanner/OpenTripPlanner/pull/3632) ## Documentation + TODO ### Configuration An example updater configuration: + ``` { "type": "bike-rental", @@ -26,4 +32,5 @@ An example updater configuration: `network` (optional) allows defining custom network id -`allowOverloading` (optional) defines if the stations in the network allow overloading (ignoring available spaces) +`allowOverloading` (optional) defines if the stations in the network allow overloading (ignoring +available spaces) diff --git a/docs/sandbox/TransmodelApi.md b/docs/sandbox/TransmodelApi.md index 4baaa7b7e18..415b17743f1 100644 --- a/docs/sandbox/TransmodelApi.md +++ b/docs/sandbox/TransmodelApi.md @@ -4,47 +4,60 @@ - Entur, Norway - ## Changelog - Initial version of Transmodel Graph QL API (September 2019) - Added support for multimodal StopPlaces (November 2019) - Fix bug querying stopPlaces [#3591](https://github.com/opentripplanner/OpenTripPlanner/pull/3591) - Fix the field bikesAllowed [#3586](https://github.com/opentripplanner/OpenTripPlanner/pull/3586) -- Add triangle factors for bicycle routing [#3585](https://github.com/opentripplanner/OpenTripPlanner/pull/3585) +- Add triangle factors for bicycle + routing [#3585](https://github.com/opentripplanner/OpenTripPlanner/pull/3585) - Fix correct type for BookingArrangementType#latestBookingDay -- Fix NPE in BookingArrangementType data fetchers [#3649](https://github.com/opentripplanner/OpenTripPlanner/pull/3649) -- Add BookingInfo to TimetabledPassingTime and EstimatedCall [#3666](https://github.com/opentripplanner/OpenTripPlanner/pull/3666) -- Use correct capitalization for GraphQL fields [#3707](https://github.com/opentripplanner/OpenTripPlanner/pull/3707) -- Allow filtering by a list of ids [#3738](https://github.com/opentripplanner/OpenTripPlanner/pull/3738) -- Don't filter out stops who don't have multimodal parents in the nearest query [#3752](https://github.com/opentripplanner/OpenTripPlanner/pull/3752) -- Restore ability to filter by private code [#3764](https://github.com/opentripplanner/OpenTripPlanner/pull/3764) -- Narrow down non-null types type [#3803](https://github.com/opentripplanner/OpenTripPlanner/pull/3803) -- Fix issue with fetching parent StopPlaces in nearest query in Transmodel API [#3807](https://github.com/opentripplanner/OpenTripPlanner/pull/3807) -- Fix invalid cast in situations resolver for line type [#3810](https://github.com/opentripplanner/OpenTripPlanner/pull/3810) -- Deduce enum for bookWhen in Transmodel API [#3854](https://github.com/opentripplanner/OpenTripPlanner/pull/3854) -- Fix coercion of default parameter for maximumDistance in nearest [#3846](https://github.com/opentripplanner/OpenTripPlanner/pull/3846) -- Expose stopPositionInPattern on EstimatedCall [#3846](https://github.com/opentripplanner/OpenTripPlanner/pull/3846) -- Allow selecting first or last quays in a ServiceJourney [#3846](https://github.com/opentripplanner/OpenTripPlanner/pull/3846) +- Fix NPE in BookingArrangementType data + fetchers [#3649](https://github.com/opentripplanner/OpenTripPlanner/pull/3649) +- Add BookingInfo to TimetabledPassingTime and + EstimatedCall [#3666](https://github.com/opentripplanner/OpenTripPlanner/pull/3666) +- Use correct capitalization for GraphQL + fields [#3707](https://github.com/opentripplanner/OpenTripPlanner/pull/3707) +- Allow filtering by a list of + ids [#3738](https://github.com/opentripplanner/OpenTripPlanner/pull/3738) +- Don't filter out stops who don't have multimodal parents in the nearest + query [#3752](https://github.com/opentripplanner/OpenTripPlanner/pull/3752) +- Restore ability to filter by private + code [#3764](https://github.com/opentripplanner/OpenTripPlanner/pull/3764) +- Narrow down non-null types + type [#3803](https://github.com/opentripplanner/OpenTripPlanner/pull/3803) +- Fix issue with fetching parent StopPlaces in nearest query in Transmodel + API [#3807](https://github.com/opentripplanner/OpenTripPlanner/pull/3807) +- Fix invalid cast in situations resolver for line + type [#3810](https://github.com/opentripplanner/OpenTripPlanner/pull/3810) +- Deduce enum for bookWhen in Transmodel + API [#3854](https://github.com/opentripplanner/OpenTripPlanner/pull/3854) +- Fix coercion of default parameter for maximumDistance in + nearest [#3846](https://github.com/opentripplanner/OpenTripPlanner/pull/3846) +- Expose stopPositionInPattern on + EstimatedCall [#3846](https://github.com/opentripplanner/OpenTripPlanner/pull/3846) +- Allow selecting first or last quays in a + ServiceJourney [#3846](https://github.com/opentripplanner/OpenTripPlanner/pull/3846) ## Documentation -This is the official Entur OTP2 API. The terminology is based on the Transmodel(NeTEx) with some -limitations/simplification. It provides both a routing API (trip query) and index API for transit -data. +This is the official Entur OTP2 API. The terminology is based on the Transmodel(NeTEx) with some +limitations/simplification. It provides both a routing API (trip query) and index API for transit +data. Entur provide a [GraphQL explorer](https://api.entur.io/graphql-explorer) where you may browse the GraphQL schema and try your own queries. -After enabling this feature (see below), the endpoint is available at: `http://localhost:8080/otp/routers/default/transmodel/index/graphql` - -### OTP2 Official GraphQL API (Not available) +After enabling this feature (see below), the endpoint is available +at: `http://localhost:8080/otp/routers/default/transmodel/index/graphql` + +### OTP2 Official GraphQL API (Not available) We **plan** to make a new offical OTP2 API, replacing the REST API. The plan is to base the new API -on this API and the [Legacy GraphQL Api](LegacyGraphQLApi.md). The new API will most likely have 2 -"translations": A GTFS version and a Transmodel version, we will try to keep the semantics the same. - - +on this API and the [Legacy GraphQL Api](LegacyGraphQLApi.md). The new API will most likely have 2 +"translations": A GTFS version and a Transmodel version, we will try to keep the semantics the same. + ### Configuration To enable this you need to add the feature `SandboxAPITransmodelApi`. diff --git a/docs/sandbox/VehicleParking.md b/docs/sandbox/VehicleParking.md index 4581ad01dc6..999d392935f 100644 --- a/docs/sandbox/VehicleParking.md +++ b/docs/sandbox/VehicleParking.md @@ -1,29 +1,37 @@ # Vehicle Parking Updaters - OTP Sandbox Extension ## Contact Info + - For HSL Park and Ride updater: Digitransit team, HSL, Helsinki, Finland ## Changelog -- Create initial sandbox implementation (January 2022, https://github.com/opentripplanner/OpenTripPlanner/pull/3796) + +- Create initial sandbox implementation (January + 2022, https://github.com/opentripplanner/OpenTripPlanner/pull/3796) ## Documentation -This sandbox contains vehicle parking updaters. Unlike for some other sandbox features, -this is not enabled/disabled through `otp-config.json` but from `router-config.json` updaters. + +This sandbox contains vehicle parking updaters. Unlike for some other sandbox features, this is not +enabled/disabled through `otp-config.json` but from `router-config.json` updaters. Currently contains the following updaters: + - HSL Park and Ride (https://p.hsl.fi/docs/index.html) - ParkAPI (https://github.com/offenesdresden/ParkAPI) - KML (Keyhole Markup language) placemark parks. Use name as bike park name and point coordinates. ### Configuration -These sandboxed vehicle parking updaters can be enabled by editing the `updaters` section -in the `router-config.json` according to the following examples. + +These sandboxed vehicle parking updaters can be enabled by editing the `updaters` section in +the `router-config.json` according to the following examples. All updaters have the following parameters in common: + - `type`: this needs to be `"vehicle-parking"` - `feedId`: this is used as a "prefix" for park ids, entrance ids and sometimes also for tags. To use HSL park updater: + ``` { "type": "vehicle-parking", @@ -35,16 +43,18 @@ All updaters have the following parameters in common: "utilizationsUrl": "https://p.hsl.fi/api/v1/utilizations.json?limit=-1" } ``` + - `sourceType`: needs to be `"hsl-park"` - `facilitiesUrl`: URL that contains the basic information for the parks -- `facilitiesFrequencySec`: how often should the basic information for parks be refetched. -Should be more than `utilizationsFrequencySec` and if it's <= 0, parks are only fetched once. Default `600`. +- `facilitiesFrequencySec`: how often should the basic information for parks be refetched. Should be + more than `utilizationsFrequencySec` and if it's <= 0, parks are only fetched once. Default `600`. - `utilizationsUrl`: URL that contains realtime updates to parks -- `utilizationsFrequencySec`: how often should the basic information for parks be refetched. -Should be less than `facilitiesFrequencySec` and if it's < 0, -realtime information is never refetched. Default `3600`. +- `utilizationsFrequencySec`: how often should the basic information for parks be refetched. Should + be less than `facilitiesFrequencySec` and if it's < 0, realtime information is never refetched. + Default `3600`. To use KML park updater: + ``` { "type": "vehicle-parking", @@ -56,6 +66,7 @@ realtime information is never refetched. Default `3600`. "zip": true } ``` + - `sourceType`: needs to be `"kml"` - `url`: URL that contains the park data in KML format - `frequencySec`: how often park data is refetched. Default `60`. @@ -63,6 +74,7 @@ realtime information is never refetched. Default `3600`. - `zip`: Tells if the data is zipped or not. To use ParkAPI updater: + ``` { "type": "vehicle-parking", @@ -74,7 +86,9 @@ realtime information is never refetched. Default `3600`. "tags": ["source:parkapi"] } ``` -- `sourceType`: needs to be `"park-api"` if car parks are fetched, `"bicycle-park-api"` if bicycle parks. + +- `sourceType`: needs to be `"park-api"` if car parks are fetched, `"bicycle-park-api"` if bicycle + parks. - `url`: URL that contains the park data in KML format - `frequencySec`: how often park data is refetched. Default `60`. - `headers`: Use these headers for requests diff --git a/docs/sandbox/VehicleRentalServiceDirectory.md b/docs/sandbox/VehicleRentalServiceDirectory.md index 3fbdaf30ade..666fb525c98 100644 --- a/docs/sandbox/VehicleRentalServiceDirectory.md +++ b/docs/sandbox/VehicleRentalServiceDirectory.md @@ -1,14 +1,24 @@ # Vehicle Rental Service Directory API support. ## Contact Info + - Gard Mellemstrand, Entur, Norway ## Changelog + - Initial implementation of bike share updater API support -- Make json tag names configurable [#3447](https://github.com/opentripplanner/OpenTripPlanner/pull/3447) +- Make json tag names + configurable [#3447](https://github.com/opentripplanner/OpenTripPlanner/pull/3447) ## Documentation -This adds support for the GBFS service directory endpoint component located at https://github.com/entur/lahmu. OTP use the service directory to lookup and connect to all GBFS endpoints registered in the directory. This simplify the management of the GBFS enpoints, since multiple services/components like OTP can connect to the directory and get the necessary configuration from it. + +This adds support for the GBFS service directory endpoint component located +at https://github.com/entur/lahmu. OTP use the service directory to lookup and connect to all GBFS +endpoints registered in the directory. This simplify the management of the GBFS enpoints, since +multiple services/components like OTP can connect to the directory and get the necessary +configuration from it. ### Configuration -To enable this you need to specify a url for the `vehicleRentalServiceDirectory` in the `router-config.json` + +To enable this you need to specify a url for the `vehicleRentalServiceDirectory` in +the `router-config.json` diff --git a/docs/sandbox/VehicleToStopHeuristics.md b/docs/sandbox/VehicleToStopHeuristics.md index e5744ae5f35..3197bbdca9d 100644 --- a/docs/sandbox/VehicleToStopHeuristics.md +++ b/docs/sandbox/VehicleToStopHeuristics.md @@ -6,7 +6,8 @@ ## Changelog -- Create initial implementation [#3906](https://github.com/opentripplanner/OpenTripPlanner/pull/3906) +- Create initial + implementation [#3906](https://github.com/opentripplanner/OpenTripPlanner/pull/3906) ## Documentation @@ -29,7 +30,7 @@ maximum, but we want it to scale with the density of well-connected stops. ### Vehicle-to-stop heuristic -In order to improve the Park+Ride and Bike+Ride results we reduced the number of candidate stops +In order to improve the Park+Ride and Bike+Ride results we reduced the number of candidate stops with the following heuristic: 1. When a stop is encountered check which routes depart from it @@ -42,8 +43,8 @@ The code for this is located in `VehicleToStopSkipEdgeStrategy.java`. ### Bicycle-on-transit heuristic This heuristic works slightly differently in that it doesn't assign a score but simply stops the -access search when a certain number of routes were encountered that allow you to take your bike -onto transit. +access search when a certain number of routes were encountered that allow you to take your bike onto +transit. The code for this is located in `BikeToStopSkipEdgeStrategy.java`. @@ -70,5 +71,7 @@ These are some the goals for the future: - make the scores that are assigned for routes of a certain mode configurable in JSON - pre-calculate stop importance scores during the graph build -If you want to help making this feature more flexible, please contact [Leonard Ehrenfried](mailto:mail@leonard.io) -or use the regular channels of communication outlined in [CONTRIBUTING.md](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/CONTRIBUTING.md#primary-channels-of-communication) \ No newline at end of file +If you want to help making this feature more flexible, please +contact [Leonard Ehrenfried](mailto:mail@leonard.io) +or use the regular channels of communication outlined +in [CONTRIBUTING.md](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/CONTRIBUTING.md#primary-channels-of-communication) \ No newline at end of file diff --git a/docs/sandbox/transferanalyzer.md b/docs/sandbox/transferanalyzer.md index e5e5c1c3c91..edc1a2579ea 100644 --- a/docs/sandbox/transferanalyzer.md +++ b/docs/sandbox/transferanalyzer.md @@ -1,6 +1,7 @@ # Direct transfer analyzer module ## Contact Info + - Gard Mellemstrand, Entur, Norway ## Changelog @@ -11,7 +12,10 @@ ### Documentation -Module used for analyzing the transfers between nearby stops generated by routing via OSM data. It generates lists of both unusually long and unroutable transfers. These lists can typically be used to improve the quality of OSM data for transfer purposes. +Module used for analyzing the transfers between nearby stops generated by routing via OSM data. It +generates lists of both unusually long and unroutable transfers. These lists can typically be used +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) class \ No newline at end of file +See javadoc in +[DirectTransferAnalyzer](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/src/ext/java/org/opentripplanner/ext/transferanalyzer/DirectTransferAnalyzer.java) +class \ No newline at end of file diff --git a/src/ext/java/org/opentripplanner/ext/flex/README.md b/src/ext/java/org/opentripplanner/ext/flex/README.md index 4a6245e1666..8f099279450 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/README.md +++ b/src/ext/java/org/opentripplanner/ext/flex/README.md @@ -1,34 +1,46 @@ # Flexible transit routing -This package contains a router, which produces access and egress legs for the RAPTOR algorithm, as well as flex-only itineraries +This package contains a router, which produces access and egress legs for the RAPTOR algorithm, as +well as flex-only itineraries -The data format is based on the [GTFS-Flex v2.1 draft](https://github.com/MobilityData/gtfs-flex/blob/master/spec/reference.md). +The data format is based on +the [GTFS-Flex v2.1 draft](https://github.com/MobilityData/gtfs-flex/blob/master/spec/reference.md). ## Algorithm ![Flex routing diagram](Flex.svg) The algorithm runs in two phases. - -1. Flex access/egress templates are generated from the places reachable by the access/egress mode. The templates contain information about how to reach the flex service and the service itself. -1. From these templates, flex accesses are generated by alighting at all places after the boarding. If the alighting is not at a stop, transfers are generated to all stops reachable by walking distance. For egresses the flow is the opposite. -These accesses and egresses can then be fed to the RAPTOR algorithm similar to how the street accesses and egresses are. +1. Flex access/egress templates are generated from the places reachable by the access/egress mode. + The templates contain information about how to reach the flex service and the service itself. +1. From these templates, flex accesses are generated by alighting at all places after the boarding. + If the alighting is not at a stop, transfers are generated to all stops reachable by walking + distance. For egresses the flow is the opposite. + +These accesses and egresses can then be fed to the RAPTOR algorithm similar to how the street +accesses and egresses are. ### FlexTrip -As there is a wide variety of flexible transit services, the business logic for each type exists in separate classes. -To add a new type of service it should be simple to add a new class extending the FlexTrip class, with the required methods. +As there is a wide variety of flexible transit services, the business logic for each type exists in +separate classes. To add a new type of service it should be simple to add a new class extending the +FlexTrip class, with the required methods. #### UnscheduledTrip -This type of trip consists of one or two service areas, with a set operating window. The trip is possible at any time within the set window, and the class can represent multiple potential trips. +This type of trip consists of one or two service areas, with a set operating window. The trip is +possible at any time within the set window, and the class can represent multiple potential trips. #### ScheduledDeviatedTrip -A scheduled deviated trip represents a single trip, which operates not only via stops, but also via locations, which can be either areas or lines, and groups of locations and stops. -As the trip has a set order of stops, and usually includes at least one timed stop, the driving times are calculated from the schedules, providing the beginning of the window for boarding and the end of the window for alighting at the flexible locations, in order to make sure that the trips are possible. +A scheduled deviated trip represents a single trip, which operates not only via stops, but also via +locations, which can be either areas or lines, and groups of locations and stops. As the trip has a +set order of stops, and usually includes at least one timed stop, the driving times are calculated +from the schedules, providing the beginning of the window for boarding and the end of the window for +alighting at the flexible locations, in order to make sure that the trips are possible. #### ContinuousStopsTrip -A continuous stops trip is a trip which serves regular stops, and where boarding and alighting are possible also between at least one pair of stops. +A continuous stops trip is a trip which serves regular stops, and where boarding and alighting are +possible also between at least one pair of stops. diff --git a/src/ext/java/org/opentripplanner/ext/legacygraphqlapi/generated/README.md b/src/ext/java/org/opentripplanner/ext/legacygraphqlapi/generated/README.md index e7ae2824642..e5b8b8fc8c4 100644 --- a/src/ext/java/org/opentripplanner/ext/legacygraphqlapi/generated/README.md +++ b/src/ext/java/org/opentripplanner/ext/legacygraphqlapi/generated/README.md @@ -6,15 +6,18 @@ ## Running -***NOTE, there are some errors in the generated LegacyGraphQLTypes.java that need to be manually fixed related to use of enums*** +***NOTE, there are some errors in the generated LegacyGraphQLTypes.java that need to be manually +fixed related to use of enums*** The files can be generated using the following snippet + ``` yarn install yarn generate ``` ***TODO fix this as it currently does not run and uses wrong version of @graphql-codegen/java*** + ``` npx -p @graphql-codegen/add -p @graphql-codegen/cli -p @graphql-codegen/java -p @graphql-codegen/java-resolvers -p graphql graphql-codegen -c graphql-codegen.yml ``` diff --git a/src/main/java/org/opentripplanner/api/package.md b/src/main/java/org/opentripplanner/api/package.md index 5ae0846982e..5498b2e4c47 100644 --- a/src/main/java/org/opentripplanner/api/package.md +++ b/src/main/java/org/opentripplanner/api/package.md @@ -1,8 +1,8 @@ # OTP REST API -This package contains the code which exposes OpenTripPlanner services to the outside world as a -REST API. This includes Jersey REST resource classes (in the "resource" subpackage, picked up by -Jersey's package scanning process), and the classes modeling the structure of the response (in -the "model" subpackage). We provide OTP with the REST API as a embedded standalone Grizzly-based -command-line server. +This package contains the code which exposes OpenTripPlanner services to the outside world as a REST +API. This includes Jersey REST resource classes (in the "resource" subpackage, picked up by Jersey's +package scanning process), and the classes modeling the structure of the response (in the "model" +subpackage). We provide OTP with the REST API as a embedded standalone Grizzly-based command-line +server. diff --git a/src/main/java/org/opentripplanner/gtfs/package.md b/src/main/java/org/opentripplanner/gtfs/package.md index c2a3afd742d..017c6001baa 100644 --- a/src/main/java/org/opentripplanner/gtfs/package.md +++ b/src/main/java/org/opentripplanner/gtfs/package.md @@ -1,7 +1,6 @@ -This package contains a GTFS loader library. -It is made to be as tolerant as possible of errors in the input, because a large proportion of GTFS feeds contain -errors, and we want to be able to report all of those errors rather than bailing out the first time we hit an -exception or missing field. +This package contains a GTFS loader library. It is made to be as tolerant as possible of errors in +the input, because a large proportion of GTFS feeds contain errors, and we want to be able to report +all of those errors rather than bailing out the first time we hit an exception or missing field. -This package is currently in the OpenTripPlanner repository to avoid dependency mismatches during development, but should -be written such that it functions as an independent library. +This package is currently in the OpenTripPlanner repository to avoid dependency mismatches during +development, but should be written such that it functions as an independent library. diff --git a/src/main/java/org/opentripplanner/model/plan/pagecursor/readme.md b/src/main/java/org/opentripplanner/model/plan/pagecursor/readme.md index 9346ee8d29e..d0707a93a0b 100644 --- a/src/main/java/org/opentripplanner/model/plan/pagecursor/readme.md +++ b/src/main/java/org/opentripplanner/model/plan/pagecursor/readme.md @@ -1,81 +1,79 @@ # Page Cursor Design -There are a few corner cases which complicates the paging. Below we have tried to document these -cases and at the same time illustrate how we have solved the different cases. There are also a few -cases which are not handled by the current implementation and we try to document those as well. + +There are a few corner cases which complicates the paging. Below we have tried to document these +cases and at the same time illustrate how we have solved the different cases. There are also a few +cases which are not handled by the current implementation and we try to document those as well. Each case is given a name and the name is referenced in code and unit tests. -We start with the most common "normal" case, and step into more complicated cases below. In the -discussion of each case we "build" on top of the previous ones - we try not to repeat the same -discussions - so read the cases in chronological order and make sure you understand each case -before moving on to the next. +We start with the most common "normal" case, and step into more complicated cases below. In the +discussion of each case we "build" on top of the previous ones - we try not to repeat the same +discussions - so read the cases in chronological order and make sure you understand each case before +moving on to the next. ## Terminology - - **search-window (sw)** The search window is the minutes Raptor iterate 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 page cursors. - - **earliest-departure-time (edt)** The search-window start with the earliest-depature-time, which - is the first possible time any itinerary may start. **edt'** is the calculated value for the - new cursor. - - **latest-arrival-time (lat)** The latest time an itinerary can arrive to get accepted. The - latest-arrival-time is only used in _arrive-by_ search. **lat'** is the calculated value for the - new cursor. - - **next page >>** The trip search constructed to retrieve itineraries BEFORE the original search. - - **<< 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 - from the beginning or end of the list depending on the page cursor type (next/previous) and the - sort order(arrival/departure time). - - -## Sort by arrival time (depart after) +- **search-window (sw)** The search window is the minutes Raptor iterate 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 + page cursors. +- **earliest-departure-time (edt)** The search-window start with the earliest-depature-time, which + is the first possible time any itinerary may start. **edt'** is the calculated value for the new + cursor. +- **latest-arrival-time (lat)** The latest time an itinerary can arrive to get accepted. The + latest-arrival-time is only used in _arrive-by_ search. **lat'** is the calculated value for the + new cursor. +- **next page >>** The trip search constructed to retrieve itineraries BEFORE the original search. +- **<< 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 + from the beginning or end of the list depending on the page cursor type (next/previous) and the + sort order(arrival/departure time). + +## Sort by arrival time (depart after) The next 4 cases are all **depart after** trip routing requests. A _sort-by-arrival-time_ request must have a _search-window(sw)_ and a _earliest-arrival-time_, but no _latest-arrival-time_. - ### sort-by-arrival -This is the most common case, where itineraries returned are sorted by the arrival time with the -earliest arrival first. The regular depart after search with all itineraries departing inside the +This is the most common case, where itineraries returned are sorted by the arrival time with the +earliest arrival first. The regular depart after search with all itineraries departing inside the search-window matches this case. The list of itineraries is _not_ cropped in the ItineraryFilter. ![sort-by-arrival](images/sort-by-arrival.svg) -This case is straight forward to implement, the only thing to remember here is that the +This case is straight forward to implement, the only thing to remember here is that the _previous-page_ must reverse the itinerary-filtering: `crop itineraries at START of list`. ### sort-by-arrival & crop-search-window ![sort-by-arrival-crop-sw](images/sort-by-arrival-crop-sw.svg) - - 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 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`. ### sort-by-arrival, crop-search-window & original-prev-page ![sort-by-arrival-time-crop-sw-prev-page](images/sort-by-arrival-crop-sw-prev-page.svg) This is the most complicated case of the _sort-by-arrival_ search. It combines all cases above. - - The `Next page >>` is not shown since it is the same as in [sort-by-arrival](#sort-by-arrival). - - For `<< Previous page` we need to adjust the `edt'` and the `lat'` using the first removed - itinerary. +- The `Next page >>` is not shown since it is the same as in [sort-by-arrival](#sort-by-arrival). +- For `<< Previous page` we need to adjust the `edt'` and the `lat'` using the first removed + itinerary. ## Sort by departure time (arrive by) -The next 4 cases are all **arrive by** trip routing requests. A _sort-by-departure-time_ is sorted -with the latest departure first (descending). The request must have a _search-window(sw)_ and -a _latest-arrival-time_. It is not possible to set the _earliest-departure-time_ in the request, -but we put it in the _pageCursor_ to avoid a new calculation for it in the next page/request. +The next 4 cases are all **arrive by** trip routing requests. A _sort-by-departure-time_ is sorted +with the latest departure first (descending). The request must have a _search-window(sw)_ and a _ +latest-arrival-time_. It is not possible to set the _earliest-departure-time_ in the request, but we +put it in the _pageCursor_ to avoid a new calculation for it in the next page/request. ### sort-by-departure @@ -84,17 +82,16 @@ but we put it in the _pageCursor_ to avoid a new calculation for it in the next This is the basic `sort-by-departure` (arrive-by search) without removing itineraries in the `ItineraryFilterChain`. - - The `<< Previous page` is straight forward to implement and any removal of itineraries in the - `ItineraryFilterChain` will follow the same logic that the `Original Search`. Note! the - `latest-arrival-time` is kept the same as in the `Original Search`. - - The `Next page >>` is a bit problematic, but a rare use-case. +- The `<< Previous page` is straight forward to implement and any removal of itineraries in the + `ItineraryFilterChain` will follow the same logic that the `Original Search`. Note! the + `latest-arrival-time` is kept the same as in the `Original Search`. +- The `Next page >>` is a bit problematic, but a rare use-case. - Itineraries which start in the original search-window, but arrive AFTER the `latest-arrival-time` are not be found. Hopefully these cases are rare. - - The sort order and filtering is reversed in the `ItineraryFilterChain` + - The sort order and filtering is reversed in the `ItineraryFilterChain` (`crop itineraries at START of list`). - The `latest-arrival-time` can not be computed and is dropped. - ### sort-by-departure & crop-search-window ![sort-by-departure-crop-sw](images/sort-by-departure-crop-sw.svg) @@ -106,12 +103,11 @@ if it departs AFTER the `remoed itinerary` and arrive before - hopefully this is The `Next page >>` is the same as the basic case [sort-by-departure](#sort-by-departure). - ### sort-by-departure, crop-search-window & original-next-page ![sort-by-departure-crop-sw-next-page](images/sort-by-departure-crop-sw-next-page.svg) - - The `<< Previous page` work the same as [sort-by-departure](#sort-by-departure) - - The `Next page >>` need to be adjusted by setting the `edt'` to the `removed itinerary` - departure time. +- The `<< Previous page` work the same as [sort-by-departure](#sort-by-departure) +- The `Next page >>` need to be adjusted by setting the `edt'` to the `removed itinerary` + departure time. - We might have duplicate results, and we might lose some optimal results. diff --git a/src/main/java/org/opentripplanner/netex/package.md b/src/main/java/org/opentripplanner/netex/package.md index 1c6f05d12ac..5127b24ac31 100644 --- a/src/main/java/org/opentripplanner/netex/package.md +++ b/src/main/java/org/opentripplanner/netex/package.md @@ -1,118 +1,118 @@ # NeTEx -NeTEx is a European standard for exchanging Transit data. OTP can import NeTEx into its internal +NeTEx is a European standard for exchanging Transit data. OTP can import NeTEx into its internal model. The XML parser support the entire NeTEx specification and is not limited to a specific profile, but not every part of it is mapped into OTP. Only a small subset of the entities are supported. When loading NeTEx data OTP should print warnings for all NeTEx data types not loaded. -OTP is tested with data from Entur which uses the [Nordic NeTEx profile](https://enturas.atlassian.net/wiki/spaces/PUBLIC/pages/728891481/Nordic+NeTEx+Profile). If you find that some part of your import is not -imported/supported by OTP you will need to add support for it in this model. NeTEx is huge, and -ONLY data relevant for travel planning should be imported. +OTP is tested with data from Entur which uses +the [Nordic NeTEx profile](https://enturas.atlassian.net/wiki/spaces/PUBLIC/pages/728891481/Nordic+NeTEx+Profile) +. If you find that some part of your import is not imported/supported by OTP you will need to add +support for it in this model. NeTEx is huge, and ONLY data relevant for travel planning should be +imported. OTP assume the data is valid and as a main rule the data is not washed or improved inside OTP. Poor -data quality should be fixed BEFORE loading the data into OTP. OTP will try to _ignores_ invalid -data, allowing the rest to be imported. - +data quality should be fixed BEFORE loading the data into OTP. OTP will try to _ignores_ invalid +data, allowing the rest to be imported. ## Design Goals - Import Transit data from NeTEx xml-files - Handle large input file sets (10 GB) -- Allow some data to be shared and group other data together is an isolated scope -- Support for reading data fast, multi-threaded (the design support this, but not implemented jet) -- Warn or report issues on poor data, but keep building a graph so one "bad" line do not block the +- Allow some data to be shared and group other data together is an isolated scope +- Support for reading data fast, multi-threaded (the design support this, but not implemented jet) +- Warn or report issues on poor data, but keep building a graph so one "bad" line do not block the entire import. - The import should put any restrictions on the order of XML types in the files. If ServiceJourney - comes before Authority in the xml file - that should be ok. The file-hierarchy is an optional - way to group and scope data. - - + comes before Authority in the xml file - that should be ok. The file-hierarchy is an optional way + to group and scope data. + ## Design -The 2 main classes are the [`NetexModule`](NetexModule.java) and the [`NetexBundle`](NetexBundle.java). -The `NetexModule` is a `GraphBuilderModule` and responsible for building all bundles, while a bundle -is responsible for importing a Netex bundle, normally a zip-file with a Netex data set. You may -start OTP with as many bundles as you like, and you may mix GTFS and NeTEx bundles in the same build. +The 2 main classes are the [`NetexModule`](NetexModule.java) and +the [`NetexBundle`](NetexBundle.java). The `NetexModule` is a `GraphBuilderModule` and responsible +for building all bundles, while a bundle is responsible for importing a Netex bundle, normally a +zip-file with a Netex data set. You may start OTP with as many bundles as you like, and you may mix +GTFS and NeTEx bundles in the same build. ![Design overview](images/DegignOverview.png) -The Netex files are _xml-files_ and one data set can be more than 5 GB in size. There is no fixed -relationship between file names and content like it is in GTFS, where for example `stops.txt` -contains all stops. Instead, OTP import Netex data based one a file hierarchy. - +The Netex files are _xml-files_ and one data set can be more than 5 GB in size. There is no fixed +relationship between file names and content like it is in GTFS, where for example `stops.txt` +contains all stops. Instead, OTP import Netex data based one a file hierarchy. ### Netex File Bundle -As seen above the _netex-file-bundle_ is organized in a hierarchy. This is done to support -loading large data set, and to avoid keeping XML DOM entities in memory. Also, the hierarchy -prevent references from different files at the same level to reference each other. The hierarchy -allow OTP to go through the steps of parsing xml data into Netex POJOs, validating the relationships -and mapping these POJOs into OTPs internal data model for *each set/group of files*. +As seen above the _netex-file-bundle_ is organized in a hierarchy. This is done to support loading +large data set, and to avoid keeping XML DOM entities in memory. Also, the hierarchy prevent +references from different files at the same level to reference each other. The hierarchy allow OTP +to go through the steps of parsing xml data into Netex POJOs, validating the relationships and +mapping these POJOs into OTPs internal data model for *each set/group of files*. The general rule is that entities referencing other entities, should be in the same file or placed -at a lover level in the hierarchy, so the referenced object already exist when mapping an entity. -There are exception to this. For example trip-to-trip interchanges. +at a lover level in the hierarchy, so the referenced object already exist when mapping an entity. +There are exception to this. For example trip-to-trip interchanges. -The shared data si available during the entire mapping process. Then _group data_ is kept in memory +The shared data si available during the entire mapping process. Then _group data_ is kept in memory for the duration of _parsing_ and _mapping_ each group. Data in one group is not visible to another group. - -Within each group there is also _shared-group-data_ and _group-files_ (leaf-files). -- Entities in _group-files_ can reference other entities in the same file and entities in the +Within each group there is also _shared-group-data_ and _group-files_ (leaf-files). + +- Entities in _group-files_ can reference other entities in the same file and entities in the _shared-group-files_ and in the global _shared-files_, but not entities in other _group-files_. -- Entities in _shared-group-files_ can reference other entities in the same file and entities in - the same group of _shared-group-files_ and in the global _shared-files_, but not entities in any - _group-files_. -- Entities in global _shared-files_ can reference other entities in the same file and entities in +- Entities in _shared-group-files_ can reference other entities in the same file and entities in the + same group of _shared-group-files_ and in the global _shared-files_, but not entities in any + _group-files_. +- Entities in global _shared-files_ can reference other entities in the same file and entities in other global _shared-files_. -✅ Note! You can configure how your data files are grouped into the 3 levels above using regular +✅ Note! You can configure how your data files are grouped into the 3 levels above using regular expressions in the _build-config.json_. - ### Load entities, validate and map into the OTP model For each level in the hierarchy and each group of files OTP perform the same steps: - 1. Load XML entities (NeTEx XML DOM POJOs). See [`NetexDataSourceHierarchy`](loader/NetexDataSourceHierarchy.java) - 1. Parse xml file and insert XML POJOs into the index. See [`NetexXmlParser`](loader/NetexXmlParser.java) - 1. Validate relationships. See [`Validator`](validation/Validator.java) - 1. Map XML entities to OPT internal model. See [`NetexMapper`](mapping/NetexMapper.java) +1. Load XML entities (NeTEx XML DOM POJOs). + See [`NetexDataSourceHierarchy`](loader/NetexDataSourceHierarchy.java) +1. Parse xml file and insert XML POJOs into the index. + See [`NetexXmlParser`](loader/NetexXmlParser.java) +1. Validate relationships. See [`Validator`](validation/Validator.java) +1. Map XML entities to OPT internal model. See [`NetexMapper`](mapping/NetexMapper.java) -OTP load entities into a hierarchical [`NetexEntityDataIndex`](index/NetexEntityDataIndex.java) +OTP load entities into a hierarchical [`NetexEntityDataIndex`](index/NetexEntityDataIndex.java) before validating and mapping each entity. Entities may appear in any order in the _xml-files_. So, doing the validation in a separate step ensure all entities is available when doing the validation. -If an entity or a required relation is missing the validator should remove the invalid entity. -This make the mapping easier, because the mapper can assume all required data and entities exist. +If an entity or a required relation is missing the validator should remove the invalid entity. This +make the mapping easier, because the mapper can assume all required data and entities exist. ![Collaboration diagram](images/Colaboration.png) -Here is an outline of the process including the file-hierarchy traversal and the steps at each +Here is an outline of the process including the file-hierarchy traversal and the steps at each level: 1. Load _shared-data-files_ into _index_. -1. Validate loaded entities +1. Validate loaded entities 1. Map _shared-data-entries_ 1. For each group: 1. Load _group-shared-files_ into index - 1. Validate loaded entities + 1. Validate loaded entities 1. Map _group-shared-entries_ 1. For each leaf group-file file: 1. Load _group-file_ into index - 1. Validate loaded entities + 1. Validate loaded entities 1. Map _group-entries_ 1. Clear leaf data from index 1. Remove group data from index -The [`NetexBundele`](NetexBundle.java) repeat the exact same steps for each group/set of files. -To emulate navigation in the hierarchy both the [`NetexEntityDataIndex`](index/NetexEntityIndex.java) -and the [`NetexMapper`](mapping/NetexMapper.java) persist data in a "Stack" like structure. The -`NetexBundle` call the `push()` and `pop()` on the index and the mapper to enter and exit each -file set at a given level. Entities loaded at a given level is in the local scope, while -entities loaded at a higher level is in the global scope. The index has methods to access both -local and global scoped entities, but it is only possible to add entities at the local scope. - +The [`NetexBundele`](NetexBundle.java) repeat the exact same steps for each group/set of files. To +emulate navigation in the hierarchy both the [`NetexEntityDataIndex`](index/NetexEntityIndex.java) +and the [`NetexMapper`](mapping/NetexMapper.java) persist data in a "Stack" like structure. The +`NetexBundle` call the `push()` and `pop()` on the index and the mapper to enter and exit each file +set at a given level. Entities loaded at a given level is in the local scope, while entities loaded +at a higher level is in the global scope. The index has methods to access both local and global +scoped entities, but it is only possible to add entities at the local scope. ## Package dependencies diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md index faa807cc9f9..7630f96b2df 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md @@ -1,10 +1,10 @@ # ItineraryListFilterChain ItineraryListFilterChain is a mechanism for post-processing itinerary results. It contains a list of -Each of which contains different business logic for a different operation. They not only remove +Each of which contains different business logic for a different operation. They not only remove itineraries, but can be also used for sorting, decorating or even adding new itineraries. The filter -chain is also responsible for creating routing errors, if no itineraries remain after filtering. -Itineraries are flagged for deletion, but not actually deleted when debugging is turned on. When +chain is also responsible for creating routing errors, if no itineraries remain after filtering. +Itineraries are flagged for deletion, but not actually deleted when debugging is turned on. When debugging is off, the chain actually removes those itineraries that were flagged for deletion. ![Architecture diagram](ItineraryListFilterChain.svg) @@ -15,11 +15,11 @@ can appear multiple times. ## DeletionFlaggingFilter DeletionFlaggingFilter is responsible for flagging itineraries for deletion. It does not remove any -itineraries directly, but uses `Itinerary#flagForDeletion(SystemNotice)` for this. A -DeletionFlaggingFilter is instantiated with a ItineraryDeletionFlagger, which contains the business -logic for selecting the itineraries for flagging. You can use `skipAlreadyFlaggedItineraries()` for -selecting if the filter should skip already flagged itineraries to the flagger. This is useful to -disable, in case already removed itineraries are useful in comparing whether other itineraries +itineraries directly, but uses `Itinerary#flagForDeletion(SystemNotice)` for this. A +DeletionFlaggingFilter is instantiated with a ItineraryDeletionFlagger, which contains the business +logic for selecting the itineraries for flagging. You can use `skipAlreadyFlaggedItineraries()` for +selecting if the filter should skip already flagged itineraries to the flagger. This is useful to +disable, in case already removed itineraries are useful in comparing whether other itineraries should be flagged for removal. ## SortingFilter diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/package.md b/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/package.md index 06bcb89abf7..b869be4c2ec 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/package.md +++ b/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/package.md @@ -1,99 +1,102 @@ # Transfers / Interchanges -OTP2 handles transfers differently than OTP1. In OTP1, transfers were optimized by applying a cost -for each transfer edge during the search. In OTP2, finding the best transfers is done partially during -routing and then improved in a post-processing step. It is easier to understand how you should tune -OTP2 if you understand this process. When optimizing transfers we first find the best paths -(sequences of trips), then identify the best stops to transfer between subsequent trips in each of +OTP2 handles transfers differently than OTP1. In OTP1, transfers were optimized by applying a cost +for each transfer edge during the search. In OTP2, finding the best transfers is done partially +during routing and then improved in a post-processing step. It is easier to understand how you +should tune OTP2 if you understand this process. When optimizing transfers we first find the best +paths +(sequences of trips), then identify the best stops to transfer between subsequent trips in each of those paths (the post-processing). ## Supported Input Data -- OTP supports [GTFS Transfers.txt](https://gtfs.org/reference/static#transferstxt) and the Google - extention with [Trip to Trip transfers](https://developers.google.com/transit/gtfs/reference/gtfs-extensions#TripToTripTransfers). -- OTP supports [NeTEx Interchanges](https://enturas.atlassian.net/wiki/spaces/PUBLIC/pages/728760393/timetable#Interchange.1) as specified in the Nordic profile. - +- OTP supports [GTFS Transfers.txt](https://gtfs.org/reference/static#transferstxt) and the Google + extention + with [Trip to Trip transfers](https://developers.google.com/transit/gtfs/reference/gtfs-extensions#TripToTripTransfers) + . +- OTP + supports [NeTEx Interchanges](https://enturas.atlassian.net/wiki/spaces/PUBLIC/pages/728760393/timetable#Interchange.1) + as specified in the Nordic profile. ## Goals - 1. Prefer paths with fewer transfers over many transfers. - 2. Prefer some locations (stop pairs) over others. - 3. Support `StaySeated` and `Guaranteed` transfers. - 4. Choose the transfer with the highest priority: `Preferred` over `Recommended` over `Allowed`. - 5. Support for transfer specificity, [Specificity of a transfer](https://developers.google.com/transit/gtfs/reference/gtfs-extensions#specificity-of-a-transfer). - 6. Prevent transfers between stops and/or trips/routes. GTFS Transfers `transfer_type = 3` and - Netex Transfer `priority = -1(not allowed)`. - 7. Find the best place to transfer between two transit trips in a path. Normally we want to - maximize the "wait-time"/"extra-time" to allow the traveler to have as much time to do the - transfer as possible. +1. Prefer paths with fewer transfers over many transfers. +2. Prefer some locations (stop pairs) over others. +3. Support `StaySeated` and `Guaranteed` transfers. +4. Choose the transfer with the highest priority: `Preferred` over `Recommended` over `Allowed`. +5. Support for transfer + specificity, [Specificity of a transfer](https://developers.google.com/transit/gtfs/reference/gtfs-extensions#specificity-of-a-transfer) + . +6. Prevent transfers between stops and/or trips/routes. GTFS Transfers `transfer_type = 3` and Netex + Transfer `priority = -1(not allowed)`. +7. Find the best place to transfer between two transit trips in a path. Normally we want to maximize + the "wait-time"/"extra-time" to allow the traveler to have as much time to do the transfer as + possible. 1. Maximize the wait-time - 2. For a journey with more than one transfer we want to distribute the wait-time, if possible. + 2. For a journey with more than one transfer we want to distribute the wait-time, if possible. For a path with 2 transfers it is better to have 4 minutes extra for each transfer than having 30 seconds for one and 7m30s for the other. 3. For a transfer between two trips we want to find the right balance, between - extra-transfer-time and the path generalized-cost(like the cost of walking and riding a - bus). + extra-transfer-time and the path generalized-cost(like the cost of walking and riding a bus). - ## Not Supported (jet) - - Using GTFS transfers.txt it is possible to set the `min_transfer_time` with `transfer_type = 2`. - See issue [#3369](https://github.com/opentripplanner/OpenTripPlanner/issues/3369) - - The NeTEx Interchange MaximumWaitTime is ignored. - - Transfer not-allowed at location. - See issue [#3505](https://github.com/opentripplanner/OpenTripPlanner/issues/3505). - - Support for Trip matching when only Route is specified in transfers.txt. - See issue [#3429](https://github.com/opentripplanner/OpenTripPlanner/issues/3429) +- Using GTFS transfers.txt it is possible to set the `min_transfer_time` with `transfer_type = 2`. + See issue [#3369](https://github.com/opentripplanner/OpenTripPlanner/issues/3369) +- The NeTEx Interchange MaximumWaitTime is ignored. +- Transfer not-allowed at location. See + issue [#3505](https://github.com/opentripplanner/OpenTripPlanner/issues/3505). +- Support for Trip matching when only Route is specified in transfers.txt. See + issue [#3429](https://github.com/opentripplanner/OpenTripPlanner/issues/3429) ## Implementation OTP finds the best transfers in 2 steps: - 1. As part of the routing. The routing engine (Raptor) applies generalized-cost and - number-of-transfers as criteria during the routing. In addition, Raptor supports overriding - regular transfers with constrained transfers. +1. As part of the routing. The routing engine (Raptor) applies generalized-cost and + number-of-transfers as criteria during the routing. In addition, Raptor supports overriding + regular transfers with constrained transfers. 1. Goal 1 is achieved by having `number-of-transfers` as a Raptor criterion. - 2. Goal 2 is achieved by giving some stops a lower _visiting-cost_ according to the + 2. Goal 2 is achieved by giving some stops a lower _visiting-cost_ according to the `StopTransferPriority`. - 3. Goal 3 and 6 is achieved by allowing constrained transfers to override regular transfers. An - optional `RaptorTransferConstraintsProvider` is injected into Raptor which Raptor calls to - get guaranteed transfers. This service is also responsible for rejecting a transfer(TODO). - 2. Optimize transfers: Goal 4, 5, and 7 are achieved by post-processing paths. Paths from the - routing search are revised, optimizing the stop at which transfers happen between each pair of - transit rides (trips). This step does NOT compare different paths returned by the router - (Raptor), but instead finds all possible transfer locations for a given path, and the different - alternatives to transfer between each pair of trips within the path. This is an outline of the - process: + 3. Goal 3 and 6 is achieved by allowing constrained transfers to override regular transfers. An + optional `RaptorTransferConstraintsProvider` is injected into Raptor which Raptor calls to + get guaranteed transfers. This service is also responsible for rejecting a transfer(TODO). +2. Optimize transfers: Goal 4, 5, and 7 are achieved by post-processing paths. Paths from the + routing search are revised, optimizing the stop at which transfers happen between each pair of + transit rides (trips). This step does NOT compare different paths returned by the router + (Raptor), but instead finds all possible transfer locations for a given path, and the different + alternatives to transfer between each pair of trips within the path. This is an outline of the + process: 1. For each path find all possible permutations of transfers. - 2. Filter paths based on priority including `StaySeated=100`, `Guaranteed=10`, `Preferred=2`, - `Recommended=1`, `Allowed=0` and `NotAllowed=-1000`. Each path is given a combined score, - and the set of the paths with the lowest score is returned (more than one path might have - the same score). + 2. Filter paths based on priority including `StaySeated=100`, `Guaranteed=10`, `Preferred=2`, + `Recommended=1`, `Allowed=0` and `NotAllowed=-1000`. Each path is given a combined score, and + the set of the paths with the lowest score is returned (more than one path might have the + same score). 3. Another filter which breaks ties based on an "optimize-transfer-cost" function. - 4. Because the number of permutations grow exponentially with the number of transfers, - each filter above is applied for each sub-path starting from the end of the path. This - keep the number of options down, close to O(N), where N is the number of transfers. - + 4. Because the number of permutations grow exponentially with the number of transfers, each + filter above is applied for each sub-path starting from the end of the path. This keep the + number of options down, close to O(N), where N is the number of transfers. ## Design - Optimize transfers -The `OptimizeTranferService` is the entry point and delegates to the "domain" services in -the `services` package. The result of the optimization process is an `OptimizedPath` found in the +The `OptimizeTranferService` is the entry point and delegates to the "domain" services in +the `services` package. The result of the optimization process is an `OptimizedPath` found in the `api` package. The optimization process first uses the `TransferGenerator` to find all possible transfer points between each trip in a path. Then the `OptimizePathService` constructs all possible -paths starting at the "tail" with the egress-leg, and adds legs until the path is constructed. -To avoid exploring too many paths, the optimization filters the result of each step, reducing the -set of optimal tails. The `MinCostFilterChain` is used to filter each equivalent set of paths and +paths starting at the "tail" with the egress-leg, and adds legs until the path is constructed. To +avoid exploring too many paths, the optimization filters the result of each step, reducing the set +of optimal tails. The `MinCostFilterChain` is used to filter each equivalent set of paths and the `TransitPathLegSelector` finds the best tail for each transfer used to generate a new path-tail. Here is an outline of the calls: ![Transfer-Optimization-Object-Collaboration](TransferOptimizationObjCol.svg) - -### Packages +### Packages Package `org.opentripplanner.routing.algorithm.transferoptimization` has the following subpackages: + - `api` classes used outside the transfer-optimization. - `configure` creates and wires up the the module. - `model` simple internal model classes used by the services. @@ -102,34 +105,34 @@ Package `org.opentripplanner.routing.algorithm.transferoptimization` has the fol ### Important classes The `TransferOptimizationServiceConfigurator` is responsible for creating and wiring up the module. -The configuration `TransferOptimizationParameters` is used to configure classes and inject the -right versions of each class. For example, the min-cost-filter-chain is created with the -appropriate filters to perform the filtering according to the configuration. +The configuration `TransferOptimizationParameters` is used to configure classes and inject the right +versions of each class. For example, the min-cost-filter-chain is created with the appropriate +filters to perform the filtering according to the configuration. -The `OptimizeTransferService` is the entry point of the service and responsible for delegating -the sub-tasks to the internal domain services. It is also responsible for the life-cycle, mainly +The `OptimizeTransferService` is the entry point of the service and responsible for delegating the +sub-tasks to the internal domain services. It is also responsible for the life-cycle, mainly injecting 'setMinSafeTransferTime' before the calculation starts. The `OptimizePathService` finds the best optimized path using the other domain services. -The `TransferGenerator` is responsible for finding all possible transfer options and decorating each +The `TransferGenerator` is responsible for finding all possible transfer options and decorating each transfer with information that the other services will use later to do their job. The additional information added to each transfer is: + - Constrained transfer information including priority, guaranteed, stay-seated and so on - The various cost described in `TransferOptimized`: - - `transfer-priority-cost` - - `wait-time-optimized-cost` or `generalized-cost` - - `break-tie-cost` - + - `transfer-priority-cost` + - `wait-time-optimized-cost` or `generalized-cost` + - `break-tie-cost` + The `wait-time-optimized-cost` is described in [detail below](#the-optimize-transfer-cost-function). -The `TransitPathLegSelector` uses the filter-chain to prune the results already found before -combining them with new transfer-points and a new transit-path-leg. +The `TransitPathLegSelector` uses the filter-chain to prune the results already found before +combining them with new transfer-points and a new transit-path-leg. The domain `OptimizedPathTail` is used to store the intermediate results. It decorates the `PathLeg` from Raptor with `TransferOptimized` costs. - ### The Optimize-transfer-cost Function The optimize-transfer-cost function is used select between alternative transfers for a @@ -139,45 +142,49 @@ The optimize-transfer-cost function is used select between alternative transfers 2. Distribute the wait-time between transfers 3. Balance the wait-time cost and the generalized-cost -To compare two paths we need a cost function that account for the differences in the existing cost, +To compare two paths we need a cost function that account for the differences in the existing cost, except the wait-time cost, and add a new inverse cost for the extra-time: ``` F(t) = path.generalized-cost - total-wait-time * waitReluctance + ∑ f(t) ``` + The `∑ f(t)` is the sum over the new wait-time-cost-function `f(t)` where `t` is the wait-time for each transfer in the path. We have created a function with two parts: -- a linear decreasing component with a factor `a`. This should be adjusted to balance with the + +- a linear decreasing component with a factor `a`. This should be adjusted to balance with the components of the path `generalized-cost`. -- an inverse logarithmic function which have a high cost for short wait-times. - This function is relative to the calculated `min-safe-transfer-time`. +- an inverse logarithmic function which have a high cost for short wait-times. This function is + relative to the calculated `min-safe-transfer-time`. The `f(t)` is constructed so only 2 parameters are needed to tune it. Let: - - `t0` be the `min-safe-transfer-time`. This is defined as 6.67% of the total transit-time - including board- and alight-slack across all paths found in the search. We want the `f(t)` to - be relative to the travel-time, and fairly stable over time, independent of day of week. So, - by excluding wait time we get an ok estimate for the journey travel duration. - +- `t0` be the `min-safe-transfer-time`. This is defined as 6.67% of the total transit-time including + board- and alight-slack across all paths found in the search. We want the `f(t)` to be relative to + the travel-time, and fairly stable over time, independent of day of week. So, by excluding wait + time we get an ok estimate for the journey travel duration. + Then the parameters used and available for configuration is: - - `a` the `inverse-wait-reluctance`. This factor is an inverse `waitReluctance`. For example, - if it is set to 1, a wait-time of 10 seconds give a _reduction_ in cost of 10 cost points - - the same as riding a bus for 10 seconds. - - `n` the `min-safe-wait-time-factor`. This defines the maximum cost for the logarithmic function - relative to the `min-safe-transfer-time` when wait time goes towards zero(0). - -The `f(t)` is created so: - - - `f(0) = (n+1) * t0` - - `f(t0) = t0 - a * t0`, so if `a=1` then `f(t0)=0`. - -Note that since we are comparing paths where the only difference is the transfers, the effect of -the function `f(t)` lies in the delta between the cost of transfer A for alternative 1 and the cost -of transfer B for alternative 2. + +- `a` the `inverse-wait-reluctance`. This factor is an inverse `waitReluctance`. For example, if it + is set to 1, a wait-time of 10 seconds give a _reduction_ in cost of 10 cost points - the same as + riding a bus for 10 seconds. +- `n` the `min-safe-wait-time-factor`. This defines the maximum cost for the logarithmic function + relative to the `min-safe-transfer-time` when wait time goes towards zero(0). + +The `f(t)` is created so: + +- `f(0) = (n+1) * t0` +- `f(t0) = t0 - a * t0`, so if `a=1` then `f(t0)=0`. + +Note that since we are comparing paths where the only difference is the transfers, the effect of the +function `f(t)` lies in the delta between the cost of transfer A for alternative 1 and the cost of +transfer B for alternative 2. The function is: + ``` (n+1) * t0 f(t) = ----------------------- - a * t @@ -186,11 +193,11 @@ f(t) = ----------------------- - a * t where the constant `C = (e - 1.0)/t0`. -Here is a plot with three examples with different values for `n` and `a` which illustrate how the -function look like when the linear, and the logarithmic part is present or not. The blue line have +Here is a plot with three examples with different values for `n` and `a` which illustrate how the +function look like when the linear, and the logarithmic part is present or not. The blue line have only the logarithmic part(n=4, a=0), the purple line is a combination (n=2, a=0.5), and the yellow line have the linear path only(n=0, a=1). The minimum-safe-transfer-time is set to 600s or 10 -minutes in this case. Notice that the blue line gots from `f(0)=(n+1) * t0` to `f(t0)=t0` with +minutes in this case. Notice that the blue line gots from `f(0)=(n+1) * t0` to `f(t0)=t0` with delta `n * t0`. The purple line goes from `f(0)=t0` to `f(t0)=0` with delta `-t0`. ![Optimize-MinSafe-Transfer-Cost](OptimizeMinSafeTransferCost.png) diff --git a/src/main/java/org/opentripplanner/standalone/config/package.md b/src/main/java/org/opentripplanner/standalone/config/package.md index c55782cf04f..c8ad3dca26d 100644 --- a/src/main/java/org/opentripplanner/standalone/config/package.md +++ b/src/main/java/org/opentripplanner/standalone/config/package.md @@ -2,11 +2,11 @@ This document explains the configuration design. - ## Design Goals The design goals are: -- Load and validate the configuration early, before loading the graph or creating any + +- Load and validate the configuration early, before loading the graph or creating any components/modules. This ensures fast feedback and early termination of the server if the configuration is not valid. - Ignore unknown parameters, just print a warning message in the log. This will make the process of @@ -23,20 +23,18 @@ The design goals are: (interface or POJO) injected into the Sandbox module itself, should be declared in the Sandbox module. - ## Implementation -For historic reasons the configuration loader uses jackson and parses the config into a JSON node -tree. Java objects are mapped explicit by wrapping each `JsonNode` in a `NodeAdapter`. The -`NodeAdapter` decorates the `JsonNode` to provide type-safe getters for rich basic types like -`Enum`, `List`(type-safe), `Map`(type-safe), `LocalDateTime`, `URI` and so on. It also helps with -validation and providing a list of unused parameters. - +For historic reasons the configuration loader uses jackson and parses the config into a JSON node +tree. Java objects are mapped explicit by wrapping each `JsonNode` in a `NodeAdapter`. The +`NodeAdapter` decorates the `JsonNode` to provide type-safe getters for rich basic types like +`Enum`, `List`(type-safe), `Map`(type-safe), `LocalDateTime`, `URI` and so on. It also helps with +validation and providing a list of unused parameters. ### Config Injection -Each OTP module in need for configuration should declare needs and document each parameter -using JavaDoc. It can be done using an interface or a simple plain-old-java-object(POJO): +Each OTP module in need for configuration should declare needs and document each parameter using +JavaDoc. It can be done using an interface or a simple plain-old-java-object(POJO): ``` /** */ @@ -67,24 +65,24 @@ public class { } ``` -In the `org.opentripplanner.standalone.config` package there will be a class called -`ModuleNnnnConfig` that either extends the interface above or instantiates the POJO. The -config class should map from JSON using the `NodeAdapter` into itself(extending the interface) +In the `org.opentripplanner.standalone.config` package there will be a class called +`ModuleNnnnConfig` that either extends the interface above or instantiates the POJO. The config +class should map from JSON using the `NodeAdapter` into itself(extending the interface) or into the POJO. -The 2 approaches are almost identical, but the interface is a bit more "pure" with respect to the +The 2 approaches are almost identical, but the interface is a bit more "pure" with respect to the responsibilities, while the POJO approach saves a few lines of code. - ## Examples -Before you start implementing or injecting config into your new code, take a look at -`TransitRoutingConfig` or `RouterConfig#mapRoutingRequest(...)` for good examples. +Before you start implementing or injecting config into your new code, take a look at +`TransitRoutingConfig` or `RouterConfig#mapRoutingRequest(...)` for good examples. -The root configuration classes `BuildConfig`, `OtpConfig` and `RouterConfig` are **NOT** good examples, -they are not defined in the modules they are used, and they do parse their own config. This creates -cyclic dependencies between the configuration loading and the modules using it. There is an issue -to (Merge otp-config, router-config and build-config)[https://github.com/opentripplanner/OpenTripPlanner/issues/3020]. -When doing this issue, we should move the above classes to the appropriate packages, possibly -splitting them by their usage. Than parsing and instantiating them should be done in the +The root configuration classes `BuildConfig`, `OtpConfig` and `RouterConfig` are **NOT** good +examples, they are not defined in the modules they are used, and they do parse their own config. +This creates cyclic dependencies between the configuration loading and the modules using it. There +is an issue to (Merge otp-config, router-config and +build-config)[https://github.com/opentripplanner/OpenTripPlanner/issues/3020]. When doing this +issue, we should move the above classes to the appropriate packages, possibly splitting them by +their usage. Than parsing and instantiating them should be done in the `org.opentripplanner.standalone.config` package. diff --git a/src/main/java/org/opentripplanner/transit/raptor/package.md b/src/main/java/org/opentripplanner/transit/raptor/package.md index 9addc4c084c..feb4ad80ee5 100644 --- a/src/main/java/org/opentripplanner/transit/raptor/package.md +++ b/src/main/java/org/opentripplanner/transit/raptor/package.md @@ -1,102 +1,113 @@ # Goal - Why replace AStar with Raptor? -We want to make the transit routing in OTP faster and at the same time better by changing from the -existing A* (AStar) to a Raptor based algorithm. We want to keep all existing features or replace +We want to make the transit routing in OTP faster and at the same time better by changing from the +existing A* (AStar) to a Raptor based algorithm. We want to keep all existing features or replace them with something at least as good. Some of the benefits are: - faster travel search (our goal is at least 10 times faster) -- more and better variation in the result. We want true support for multi-criteria search (arrival -time, transfers, travel duration, operator, weight/cost ...) +- more and better variation in the result. We want true support for multi-criteria search (arrival + time, transfers, travel duration, operator, weight/cost ...) -Changing the algorithm also mean that we will create a new data structure representing transit -service which is optimized for Raptor. The existing routing graph will be used for the _non_ +Changing the algorithm also mean that we will create a new data structure representing transit +service which is optimized for Raptor. The existing routing graph will be used for the _non_ transit search, but transit data will be removed from that existing graph. # Terminology -The *Raptor* algorithm is described in [a paper](https://www.microsoft.com/en-us/research/wp-content/uploads/2012/01/raptor_alenex.pdf) -by Microsoft from 2012. We plan to use the _Range Raptor_ with _Multi-criteria pareto-optimal_ search. + +The *Raptor* algorithm is described +in [a paper](https://www.microsoft.com/en-us/research/wp-content/uploads/2012/01/raptor_alenex.pdf) +by Microsoft from 2012. We plan to use the _Range Raptor_ with _Multi-criteria pareto-optimal_ +search. ## Raptor -Raptor is a graph algorithm that works in _rounds_. The search starts from a list of access stops -and arrival times (initial _stop-arrivals_). Then for each _route_ serving these stops the best -trip is explored. Each _trip_ will take you to a new set of _stops_ with new _stop-arrivals_. -Then transfers from all stops reached are used to further reach new stops. This process is repeated, -each iteration of transit and transfers is called a _round_. For every _round_ a new list of -_stop-arrivals_ are found. This new list of _stop-arrivals_ are used as input for the next round. -The algorithm will terminate by itself (when all reachable stops are visited), or can be stopped when -you have the desired results. The reason this is much faster than the current OTP A* is that there -is no need to maintain a priority queue of edges to explore. For each stop we keep the best -_stop arrival_ which has a link to the previous _stop-arrival_ so we can compute the _path_ when -the search is complete. The algorithm also operates largely on contiguous lists of numbers, with -adjacency in memory (rather than explicit edge objects) implying reachability of one stop from + +Raptor is a graph algorithm that works in _rounds_. The search starts from a list of access stops +and arrival times (initial _stop-arrivals_). Then for each _route_ serving these stops the best trip +is explored. Each _trip_ will take you to a new set of _stops_ with new _stop-arrivals_. Then +transfers from all stops reached are used to further reach new stops. This process is repeated, each +iteration of transit and transfers is called a _round_. For every _round_ a new list of +_stop-arrivals_ are found. This new list of _stop-arrivals_ are used as input for the next round. +The algorithm will terminate by itself (when all reachable stops are visited), or can be stopped +when you have the desired results. The reason this is much faster than the current OTP A* is that +there is no need to maintain a priority queue of edges to explore. For each stop we keep the best +_stop arrival_ which has a link to the previous _stop-arrival_ so we can compute the _path_ when the +search is complete. The algorithm also operates largely on contiguous lists of numbers, with +adjacency in memory (rather than explicit edge objects) implying reachability of one stop from another. This avoids a lot of pointer-chasing and better exploits processor cache and prefetching. Raptor is part of a family of newer algorithms that account for typical processor architecture rather than just theoretical asymptotic complexity. ## Range Raptor (RR) -_The code for this is found in the `org.opentripplanner.transit.raptor.rangeraptor.standard` -package._ - -_Range Raptor_ finds results for many different departure times by iterating over a range of minutes. -Let say you want to travel from A to B sometime -between 12:00 and 13:00. Then _Range Raptor_ start at 13:00, and for each minute it runs the search -again: 12:59, 12:58 ... until 12:00. At each minute it retains and builds upon the results from the -previous iteration. This combination of backward iteration and reuse of results makes range raptor -much more efficient than a series of independent searches at single departure times. Finding results -for a whole range of time only degrades overall performance by a small percentage (relative to a single -Raptor search). -This also make sure that we find the "best" trip with the combination of latest departure time -and earliest arrival time, with all legs "packed" towards the beginning of the trip. Raptor -grantees finding the best trip in that period with departure time _after_ 12:00 o'clock and leaving -no later than 13:00. The "optimal trip" guarantee is only valid for the _search-time-window_; There -might be a trip leaving after 13:00 that is faster than the trips found. - -## Multi-criteria Range Raptor (McRR) -_The code for this is found in the `org.opentripplanner.transit.raptor.rangeraptor.multicriteria` -package._ - -Raptor gives us the optimal trips considering all trade-offs between _arrival time_ and _number of -transfers_. _Range Raptor_ also gives us the shortest travel duration (within its search-window). -The OTP McRangeRaptor adds another criterion: `generalized-cost`, which is a function of -`travel-time`, `waiting-time`, `walking-distance`, `transfers` and so on. McRR search will return + +_The code for this is found in the `org.opentripplanner.transit.raptor.rangeraptor.standard` +package._ + +_Range Raptor_ finds results for many different departure times by iterating over a range of +minutes. Let say you want to travel from A to B sometime between 12:00 and 13:00. Then _Range +Raptor_ start at 13:00, and for each minute it runs the search again: 12:59, 12:58 ... until 12:00. +At each minute it retains and builds upon the results from the previous iteration. This combination +of backward iteration and reuse of results makes range raptor much more efficient than a series of +independent searches at single departure times. Finding results for a whole range of time only +degrades overall performance by a small percentage (relative to a single Raptor search). This also +make sure that we find the "best" trip with the combination of latest departure time and earliest +arrival time, with all legs "packed" towards the beginning of the trip. Raptor grantees finding the +best trip in that period with departure time _after_ 12:00 o'clock and leaving no later than 13:00. +The "optimal trip" guarantee is only valid for the _search-time-window_; There might be a trip +leaving after 13:00 that is faster than the trips found. + +## Multi-criteria Range Raptor (McRR) + +_The code for this is found in the `org.opentripplanner.transit.raptor.rangeraptor.multicriteria` +package._ + +Raptor gives us the optimal trips considering all trade-offs between _arrival time_ and _number of +transfers_. _Range Raptor_ also gives us the shortest travel duration (within its search-window). +The OTP McRangeRaptor adds another criterion: `generalized-cost`, which is a function of +`travel-time`, `waiting-time`, `walking-distance`, `transfers` and so on. McRR search will return a *pareto-optimal* set of paths which simultaneously optimize at least these criteria: + - arrival time (seconds) - number of transfers (scalar) - travel duration (seconds) - generalized cost (scalar) (a function of anything other than the above criteria) -We will also experiment with separating other criteria out from the _cost_, such as +We will also experiment with separating other criteria out from the _cost_, such as _walkingDistance_ or _operator_. The goal is to make this configurable so each deployment may tune this to their needs. Due to performance reasons it might not be 100% dynamic. Because plain _Raptor_ is much faster than _multi-criteria_ Raptor we will provide an option (request parameter) to run both _RR_ and _McRR_. We use a _single iteration Rator_ search as a heuristic optimization, establishing travel time bounds that then feed into McRR. In a benchmark -test(SpeedTest), RR may take 80ms while the McRR with the same configuration typically takes 400ms. -If we add _walking distance_ as an extra criteria the average time increase to 1000ms. These times -are examples to give you an idea of the exponential growth of adding criteria to Raptor search. +test(SpeedTest), RR may take 80ms while the McRR with the same configuration typically takes 400ms. +If we add _walking distance_ as an extra criteria the average time increase to 1000ms. These times +are examples to give you an idea of the exponential growth of adding criteria to Raptor search. + +## Paths and Itineraries -## Paths and Itineraries In this context, Path and Itineraries are almost the same. We use *Path* to talk about the minimal -set of data returned by Raptor. Those paths are decorated with information from the transit-layer -and used to create the itineraries, which are returned from the routing code (to the end user). +set of data returned by Raptor. Those paths are decorated with information from the transit-layer +and used to create the itineraries, which are returned from the routing code (to the end user). ## Pareto optimal/efficiency set -All paths that are considered *pareto optimal* for a set of criteria are returned by McRR. This -can be a large set (like 500 paths), so a filter-chain will be applied to the set of itineraries. -The idea here is to have a configurable filter-chain with decorating, mapping, sorting and -filtering capabilities. + +All paths that are considered *pareto optimal* for a set of criteria are returned by McRR. This can +be a large set (like 500 paths), so a filter-chain will be applied to the set of itineraries. The +idea here is to have a configurable filter-chain with decorating, mapping, sorting and filtering +capabilities. ### Pareto-set explained -See [Wikipedia](https://en.wikipedia.org/wiki/Pareto_efficiency) A pareto-set of paths/itineraries + +See [Wikipedia](https://en.wikipedia.org/wiki/Pareto_efficiency) A pareto-set of paths/itineraries is a set where all elements are better than (usually less than) than all other elements in the set -for at least one criterion. Given a set `{ [9,2], [5,6], [3, 8] }` then `[7, 4]` would be accepted -into the set. This is because 7 < 9 (comparing the 1st criterion of element 1), while 4 < 6 and 8 -(comparing with the 2nd criterion of elements 2 and 3). `[6,7]` would not make it into the set +for at least one criterion. Given a set `{ [9,2], [5,6], [3, 8] }` then `[7, 4]` would be accepted +into the set. This is because 7 < 9 (comparing the 1st criterion of element 1), while 4 < 6 and 8 +(comparing with the 2nd criterion of elements 2 and 3). `[6,7]` would not make it into the set because the existing element `[5,6]` is better than the new element for both criteria. # Features + ## Algorithm implementation + - Algorithms - Raptor (Range Raptor with one iteration) - Range Raptor @@ -106,130 +117,142 @@ because the existing element `[5,6]` is better than the new element for both cri - Travel duration - Generalized Cost - Dynamic search-window - + ## Filters -Filtering on stops was implemented and tested with heuristics. We tested removing all stops which -could not be part of an optimal path, but this did not have a significant performance impact. If -Routes, Trips or Stops can be filtered it is probably better to do it in the transit layer, not in + +Filtering on stops was implemented and tested with heuristics. We tested removing all stops which +could not be part of an optimal path, but this did not have a significant performance impact. If +Routes, Trips or Stops can be filtered it is probably better to do it in the transit layer, not in Raptor. Hence; We have removed the stop filter (c96d1af0). ## Debugging Raptor - accepted, rejected and dropped paths + The Raptor code has build in support for debugging a routing request. A normal travel search follow -millions of paths and at each stop each path is ACCEPTED, REJECTED and/or eventually DROPPED. +millions of paths and at each stop each path is ACCEPTED, REJECTED and/or eventually DROPPED. Logging these events make it possible to find out why a path is not making it into the final result. Use the Raptor request to specify a set-of-stops or a path to enable the debugger. You also need to -pass in listeners to the debugger. In the test code there is an implementation of the Logger/Event +pass in listeners to the debugger. In the test code there is an implementation of the Logger/Event listener which logs to the console standard error, `TestDebugLogger`. The `SpeedTest` or the module -tests are the easiest way to debug a search. The debugger design support using it from the OTP -APIs, but there is no implementation for this. +tests are the easiest way to debug a search. The debugger design support using it from the OTP APIs, +but there is no implementation for this. ### Debugging implementation notes -The debugger instrument the existing code for the given stops determined by the -[`DebugRequest`](api/request/DebugRequest.java). If no debug listeners exist, then no debugging -code is injected or run; hence the performance overhead under normal execution is minimal. The -main Raptor logic will post events to the [DebugHandler](rangeraptor/view/DebugHandler.java) + +The debugger instrument the existing code for the given stops determined by the +[`DebugRequest`](api/request/DebugRequest.java). If no debug listeners exist, then no debugging code +is injected or run; hence the performance overhead under normal execution is minimal. The main +Raptor logic will post events to the [DebugHandler](rangeraptor/view/DebugHandler.java) interface. There are one handler implementation for each event type(stop arrival, pattern ride, and path), all created by the [DebugHandlerFactory](rangeraptor/debug/DebugHandlerFactory.java). The -handler implementations are called _Adapters_ because they take the internal Raptor event and +handler implementations are called _Adapters_ because they take the internal Raptor event and convert it and passes it to the listeners passed in using the Raptor debug request. - # Design -The Raptor implementation is implemented as a Java library with its own API and has a single point -of access the`RaptorService`. -- It is self contained and has no dependencies on any other library or code inside OTP (except a -few utility functions). -- It is modular, with several pluggable components. The wiring is done in separate assembly classes -(configure classes). + +The Raptor implementation is implemented as a Java library with its own API and has a single point +of access the`RaptorService`. + +- It is self contained and has no dependencies on any other library or code inside OTP (except a few + utility functions). +- It is modular, with several pluggable components. The wiring is done in separate assembly classes + (configure classes). - To provide Transit data for the algorithm you need to implement a _data provider_. ## Optimizations -As the search progresses, many branches can be pruned if we can establish some bounds on the solution set. -- A limit on `maxAdditionalNumberOfTransfers` not `maxNumberOfTransfers`. We want to change this to -be relative to the trip with fewest transfers. -- A limit on *destination pareto-set* (not just travel time to destination). -Applying this limit the first time (not every time) we arrive at a stop might give the best performance. -- Use _R_ or _RR_ as a "heuristic optimization", possibly bi-directional, computing a set of -stops/routes that can be used as a filter for the _McRR_. _RR_ is super fast, more than 10x faster -than McRR with 4 criteria. + +As the search progresses, many branches can be pruned if we can establish some bounds on the +solution set. + +- A limit on `maxAdditionalNumberOfTransfers` not `maxNumberOfTransfers`. We want to change this to + be relative to the trip with fewest transfers. +- A limit on *destination pareto-set* (not just travel time to destination). Applying this limit the + first time (not every time) we arrive at a stop might give the best performance. +- Use _R_ or _RR_ as a "heuristic optimization", possibly bi-directional, computing a set of + stops/routes that can be used as a filter for the _McRR_. _RR_ is super fast, more than 10x faster + than McRR with 4 criteria. ## Understanding the search (range-raptor algorithm implementation) -The `RangeRaptorWorker` and the `RoutingStrategy` together implement the _range-raptor_ algorithm. + +The `RangeRaptorWorker` and the `RoutingStrategy` together implement the _range-raptor_ algorithm. There are three `RoutingStrategy` implementations: + 1. The `ArrivalTimeRoutingStrategy` is the standard Range Raptor implementation. It supports both _forward_ and _reverse_ search and is used to find the path with the best _arrival-time_. -2. The `MinTravelDurationRoutingStrategy` is the same as the standard, but optimize on +2. The `MinTravelDurationRoutingStrategy` is the same as the standard, but optimize on travel-duration, eliminating _wait-time_ (except board and alight slack). It supports both - _forward_ and _reverse_ search, but only one Range Raptor iteration (no search window). - The main usage for this is to compute heuristics used to improve the performance in the - multi-criteria search. It is used to compute various heuristics, like + _forward_ and _reverse_ search, but only one Range Raptor iteration (no search window). The main + usage for this is to compute heuristics used to improve the performance in the multi-criteria + search. It is used to compute various heuristics, like _minimum-number-of-transfers_, _minimum-travel-time_ and _earliest-possible-arrival-time_. 3. The `McTransitWorker` is the _Multi-Criteria Range Raptor_ implementation. It does **not** support _reverse_ search - so far there has not been a need for it. - -The Range Raptor Search supports both _Forward_ and _Reverse_ search. In the diagram below, the same -journey is shown using the _forward_ and _reverse_ search. The two trips have the exact same -legs, but the calculated times are slightly different. Note! If you remove or time-shift -the _Wait_ parts you will get the exact same result. + +The Range Raptor Search supports both _Forward_ and _Reverse_ search. In the diagram below, the same +journey is shown using the _forward_ and _reverse_ search. The two trips have the exact same legs, +but the calculated times are slightly different. Note! If you remove or time-shift the _Wait_ parts +you will get the exact same result. ![Raptor Time Line](RaptorTimeLine.svg) Some important notes on the diagram above: -- The _Stop Arrival_ (or _Stop Arrival Time_) is the decisions points of the algorithm. This is -were a path is ACCEPTED, REJECTED or DROPPED, based on the existing _Stop Arrival State_. The -`Stop Arrival 1` and `Stop Arrival 1'` represent the same _stop arrival_ at **stop 1** for the -same path, but at times are different. A _Forward Raptor Search_ will _time-shift_ the trip to the -left, while a _Reverse Raptor Search_ wil time-shift the trip to the right. -- The _Transfer (walk)_ is calculated by Raptor only if you need to walk from one stop to another. -If a transfer between two routes takes place at the same location/stop, then Raptor uses the -calculated transit arrival, instead of calculating a new transit arrival. In the diagram you can -remove the transit arrow and `Stop Arrival 3` and `2'`. The _Stop Arrival 2_ and _Stop Arrival 3'_ -then represent the same stop arrival at the same stop. -- There is no important timing point between the _transfer-slack_ and the _board-slack_, so the -order does not matter. In the algorithm the _transfer-slack_ is eliminated and it is left to the -internal Raptor `SlackProvider` to include the _transfer-slack_ in the _bord-slack_(forward search) -or in the _alight_slack_(reverse-search). -- It might look odd that the _board-slack_ comes before the _wait_ part, but this is just a small -trick to be able to calculate the _earliest-board-time_. Remember that the parts between 2 -_stop-arrivals_ can technically be swapped around without any effect on the algorithm. Of cause -the result paths need to be adjusted to reflect this. +- The _Stop Arrival_ (or _Stop Arrival Time_) is the decisions points of the algorithm. This is were + a path is ACCEPTED, REJECTED or DROPPED, based on the existing _Stop Arrival State_. The + `Stop Arrival 1` and `Stop Arrival 1'` represent the same _stop arrival_ at **stop 1** for the + same path, but at times are different. A _Forward Raptor Search_ will _time-shift_ the trip to the + left, while a _Reverse Raptor Search_ wil time-shift the trip to the right. +- The _Transfer (walk)_ is calculated by Raptor only if you need to walk from one stop to another. + If a transfer between two routes takes place at the same location/stop, then Raptor uses the + calculated transit arrival, instead of calculating a new transit arrival. In the diagram you can + remove the transit arrow and `Stop Arrival 3` and `2'`. The _Stop Arrival 2_ and _Stop Arrival 3'_ + then represent the same stop arrival at the same stop. +- There is no important timing point between the _transfer-slack_ and the _board-slack_, so the + order does not matter. In the algorithm the _transfer-slack_ is eliminated and it is left to the + internal Raptor `SlackProvider` to include the _transfer-slack_ in the _bord-slack_(forward + search) + or in the _alight_slack_(reverse-search). +- It might look odd that the _board-slack_ comes before the _wait_ part, but this is just a small + trick to be able to calculate the _earliest-board-time_. Remember that the parts between 2 + _stop-arrivals_ can technically be swapped around without any effect on the algorithm. Of cause + the result paths need to be adjusted to reflect this. - The path(itinerary) mapping process should swap the parts between to _stop-arrivals_ into an -intuitive order seen from a user perspective, this may include time-shifting access or egress. + intuitive order seen from a user perspective, this may include time-shifting access or egress. - The _wait_ after the access and before the egress leg should be removed by the itinerary mapper. -- In a _reverse-search_ the `Worker` code is the same - the exact same algorithm implementation is -used. To be able to do this, a special _reverse_ `TransitCalculator`, `SlackProvider` and -`TripScheduleSearch` is injected into the `RaptorWorker`. The terminology in the diagram above is -the terminology used in the algorithm (`worker`). For example the _board-time_ and _alight-time_ -is swapped, compared with the `RaptorTripSchedule` in the _transit-layer_. - - So be aware that the `ReverseSearchTransitCalculator` have some awkward variable names - - depending on the point-of-view. - - The `TripScheduleAlightSearch` search the _alight-times_ and return it as a _board-time_. +- In a _reverse-search_ the `Worker` code is the same - the exact same algorithm implementation is + used. To be able to do this, a special _reverse_ `TransitCalculator`, `SlackProvider` and + `TripScheduleSearch` is injected into the `RaptorWorker`. The terminology in the diagram above is + the terminology used in the algorithm (`worker`). For example the _board-time_ and _alight-time_ + is swapped, compared with the `RaptorTripSchedule` in the _transit-layer_. + - So be aware that the `ReverseSearchTransitCalculator` have some awkward variable names - + depending on the point-of-view. + - The `TripScheduleAlightSearch` search the _alight-times_ and return it as a _board-time_. ### The transfer-slack is added to the board-slack, why? -The _transfer-slack_ is incorporated into the _board-slack_, instead of being applied to the -transfer for the following reasons: -- It is valid to do so. The Raptor algorithm branching happens at _stop-arrivals_ where the arrivals - are compared. Therefore it is important that the comparison is fare. You can arrive at a stop by - access/transfer or transit. So, because the _transfer-slack_ is constant we can safely remove it - from transfer-arrivals at a particular stop and add it to all transit-legs leaving from the same - stop. - - This is useful, because we do not have zero distance transfer-stop-arrivals in the state. - (The transit-arrival is used in the next round). - - This also allow using the stop-arrival(transit only) to continue onto the _egress-leg_ - - without any _transfer-slack_ added. -- It does not have any effect on the performance. Adding a constant to the dynamically calculated - _board-slack_ does not have any significant influence on the performance. +The _transfer-slack_ is incorporated into the _board-slack_, instead of being applied to the +transfer for the following reasons: + +- It is valid to do so. The Raptor algorithm branching happens at _stop-arrivals_ where the arrivals + are compared. Therefore it is important that the comparison is fare. You can arrive at a stop by + access/transfer or transit. So, because the _transfer-slack_ is constant we can safely remove it + from transfer-arrivals at a particular stop and add it to all transit-legs leaving from the same + stop. + - This is useful, because we do not have zero distance transfer-stop-arrivals in the state. + (The transit-arrival is used in the next round). + - This also allow using the stop-arrival(transit only) to continue onto the _egress-leg_ - + without any _transfer-slack_ added. +- It does not have any effect on the performance. Adding a constant to the dynamically calculated + _board-slack_ does not have any significant influence on the performance. # Testing There are 4 main ways Raptor is tested: + - UnitTest - The Raptor is written in an object-oriented way, partly to allow good unit testing. -- Module tests - Together with the unit tests there is a package(`moduletests`). This is a list - of "unit tests" on the [`RaptorService`](RaptorService.java). Each test testing one feature or +- Module tests - Together with the unit tests there is a package(`moduletests`). This is a list of " + unit tests" on the [`RaptorService`](RaptorService.java). Each test testing one feature or use-case. -- The `SpeedTest` is used to track Raptor performance. This test must be run manually and used the +- The `SpeedTest` is used to track Raptor performance. This test must be run manually and used the transit data model in OTP. -- Various manual tests - With the module tests in palce we should try to minimize the need of - other high level testing. +- Various manual tests - With the module tests in palce we should try to minimize the need of other + high level testing. diff --git a/src/test/java/org/opentripplanner/transit/raptor/moduletests/package-info.md b/src/test/java/org/opentripplanner/transit/raptor/moduletests/package-info.md index d4a71ed5de9..c7979176ab1 100644 --- a/src/test/java/org/opentripplanner/transit/raptor/moduletests/package-info.md +++ b/src/test/java/org/opentripplanner/transit/raptor/moduletests/package-info.md @@ -1,9 +1,9 @@ # Module tests -This package contains functional tests for the Raptor module(`RaptorService`) as a black box. Each +This package contains functional tests for the Raptor module(`RaptorService`) as a black box. Each test class should focus on testing ONE feature or scenario. Each test class should contain a small -test data set made with the _feature-under-test_ in mind. This make the tests focused, small and -easier to maintain. +test data set made with the _feature-under-test_ in mind. This make the tests focused, small and +easier to maintain. Each test class should document the _feature-under-test_ in the class java-doc. diff --git a/src/test/java/org/opentripplanner/transit/raptor/package-info.md b/src/test/java/org/opentripplanner/transit/raptor/package-info.md index 2b38e05bf0a..6d9d1e4550a 100644 --- a/src/test/java/org/opentripplanner/transit/raptor/package-info.md +++ b/src/test/java/org/opentripplanner/transit/raptor/package-info.md @@ -2,11 +2,12 @@ This package contains: - - `_shared` Shared test data including a transit model mock-up classes and utilities to help unit test Raptor. This package does NOT contain any tests. - - `moduletests` Functional _acceptance-tests_ organized by a feature, scenario or use-case. The - tests in this package are testing the Raptor module as a black box using the _transit - model mock-up_ found in the `_shared` package. - - Other _packages_ matching raptor sub-modules contains unit-tests. +- `_shared` Shared test data including a transit model mock-up classes and utilities to help unit + test Raptor. This package does NOT contain any tests. +- `moduletests` Functional _acceptance-tests_ organized by a feature, scenario or use-case. The + tests in this package are testing the Raptor module as a black box using the _transit model + mock-up_ found in the `_shared` package. +- Other _packages_ matching raptor sub-modules contains unit-tests. diff --git a/src/test/java/org/opentripplanner/transit/raptor/speed_test/package.md b/src/test/java/org/opentripplanner/transit/raptor/speed_test/package.md index be2061533db..552754bd3c5 100644 --- a/src/test/java/org/opentripplanner/transit/raptor/speed_test/package.md +++ b/src/test/java/org/opentripplanner/transit/raptor/speed_test/package.md @@ -7,13 +7,14 @@ When changing the core logic of Raptor this test can be used to detect changes i performance. To run the SpeedTest use the {@code --help} option to se the documentation. There is not much -documentation on this tool, hopefully with time, we will add more doc and maybe automate part of +documentation on this tool, hopefully with time, we will add more doc and maybe automate part of this test. Example input files and setup is included in the resource test folder: - - {@code test/ci-performance-test/}. -## Running +- {@code test/ci-performance-test/}. + +## Running ``` mvn compiler:testCompile exec:java -Dexec.mainClass="org.opentripplanner.transit.raptor.speed_test.SpeedTest" -Dexec.classpathScope=test -Dexec.args="--dir=test/ci-performance-test/ -p md -n 4" @@ -21,4 +22,5 @@ mvn compiler:testCompile exec:java -Dexec.mainClass="org.opentripplanner.transit ## CI -The test is run after every merge to master. Its Github Actions workflow is defined in [performance-test.yml](../../../../../../../../.github/workflows/performance-test.yml). \ No newline at end of file +The test is run after every merge to master. Its Github Actions workflow is defined +in [performance-test.yml](../../../../../../../../.github/workflows/performance-test.yml). \ No newline at end of file diff --git a/src/test/resources/raptor/speedtest/norway/README.md b/src/test/resources/raptor/speedtest/norway/README.md index e9dfc03cef4..eafa49cb828 100644 --- a/src/test/resources/raptor/speedtest/norway/README.md +++ b/src/test/resources/raptor/speedtest/norway/README.md @@ -1,12 +1,12 @@ - #### Download GTFS data: - - https://storage.googleapis.com/marduk-production/outbound/gtfs/rb_norway-aggregated-gtfs.zip +- https://storage.googleapis.com/marduk-production/outbound/gtfs/rb_norway-aggregated-gtfs.zip If the link above do not work you should be able to find it on the ENTUR web: - - - https://www.entur.org/ + +- https://www.entur.org/ #### Configure the test - - Set the testDate in the speed-test-config.json + +- Set the testDate in the speed-test-config.json diff --git a/test/ci-performance-test/README.md b/test/ci-performance-test/README.md index 6694d201133..0e22ba954ce 100644 --- a/test/ci-performance-test/README.md +++ b/test/ci-performance-test/README.md @@ -1,17 +1,17 @@ +#### Data files -#### Data files -We use a static set of data files in the CI perfomance test, so the results are comparable. We will periodically -update these. This will of cause change the benchmark results from time to time. - - - [Norwegian NeTEx data](https://leonard.io/otp/rb_norway-aggregated-netex-2021-12-11.zip) - - [Norway OSM data](https://download.geofabrik.de/europe/norway-210101.osm.pbf) +We use a static set of data files in the CI perfomance test, so the results are comparable. We will +periodically update these. This will of cause change the benchmark results from time to time. +- [Norwegian NeTEx data](https://leonard.io/otp/rb_norway-aggregated-netex-2021-12-11.zip) +- [Norway OSM data](https://download.geofabrik.de/europe/norway-210101.osm.pbf) If the link above do not work you should be able to find it on the ENTUR web: - - - https://www.entur.org/ + +- https://www.entur.org/ #### Configure the test - - Pick a valid "testDate" for your data set and set it in the speed-test-config.json. - - Make sure build-config "transitServiceStart" and "transitServiceEnd" include the "testDate". + +- Pick a valid "testDate" for your data set and set it in the speed-test-config.json. +- Make sure build-config "transitServiceStart" and "transitServiceEnd" include the "testDate".