diff --git a/en/dev-2.x/Changelog/index.html b/en/dev-2.x/Changelog/index.html index b725a8ca..17db3bf0 100644 --- a/en/dev-2.x/Changelog/index.html +++ b/en/dev-2.x/Changelog/index.html @@ -2575,7 +2575,8 @@

2.7.0-SNAPSHOT (under development)

  • add stopPositionInPattern in Stoptime in GTFS GraphQL API #6204
  • Fix parsing of wheelchair accessible parking, add wheelchair debug layer #6229
  • Add previousLegs into GTFS GraphQL API #6142
  • -
  • Fix stop index filtering on ServiceJourney Transmodel GraphQL API #6251 +
  • Fix stop index filtering on ServiceJourney Transmodel GraphQL API #6251
  • +
  • Fix rental searches when destination is in a no-drop-off zone #6233
  • 2.6.0 (2024-09-18)

    diff --git a/en/dev-2.x/search/search_index.json b/en/dev-2.x/search/search_index.json index c612b85e..bc4eaf7d 100644 --- a/en/dev-2.x/search/search_index.json +++ b/en/dev-2.x/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Home","text":""},{"location":"#opentripplanner-2","title":"OpenTripPlanner 2","text":"

    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 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. 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 around the world.

    You are currently reading the documentation for OpenTripPlanner 2, the second major version of OTP.

    "},{"location":"#versions-of-this-documentation","title":"Versions of this documentation","text":"

    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 upper left of the published documentation.

    Releases

    Snapshot

    "},{"location":"#audience","title":"Audience","text":"

    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 intended 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.

    "},{"location":"#quick-start","title":"Quick Start","text":"

    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 page.

    "},{"location":"#getting-help","title":"Getting help","text":"

    The fastest way to get help is to use our Gitter chat room where most of the core developers are. Bug reports may be filed via the Github issue tracker. The issue tracker is not intended for support questions or discussions. Please use the chat for this purpose. The OpenTripPlanner mailing list is treated as a legacy communications channel and used almost exclusively for project announcements. Again, please direct development and support discussions to the Gitter chat.

    "},{"location":"#financial-and-in-kind-support","title":"Financial and In-Kind Support","text":"

    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 accounting@sfconservancy.org 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.

    "},{"location":"Accessibility/","title":"Accessibility","text":""},{"location":"Accessibility/#preamble","title":"Preamble","text":"

    In this document and in OTP, the term \"accessibility\" is used with its most common meaning: design of products, devices, services, vehicles, or environments to ensure they are usable by people with disabilities. If you have reached this page looking for cumulative opportunities accessibility indicators (access to opportunities metrics) please see the Analysis page.

    While accessibility is a complex subject, at this point GTFS and Netex mostly represent it very simply as a yes/no possibility of wheelchair use. While OTP developers hope to broaden the scope and nuance of accessibility support in OTP, the lack of detailed data from data producers currently limits implementation and discussion in this document to this binary \"wheelchair accessible\" definition.

    "},{"location":"Accessibility/#unknown-data","title":"Unknown data","text":"

    Many agencies have the same problem: data on wheelchair-accessibility is, if it exists at all, patchy. If you only included trips and stops that are explicitly set to be wheelchair-accessible rather than unknown, it would be hard to get any result at all. For this reason OTP allows you to configure which sort of unknown information should be taken into account.

    "},{"location":"Accessibility/#configuration","title":"Configuration","text":"

    If you want to allow trips and stops of unknown wheelchair-accessibility then add the following to router-config.json:

    {\n  \"routingDefaults\": {\n    \"wheelchairAccessibility\": {\n      \"trip\": {\n        \"onlyConsiderAccessible\": false,\n        \"unknownCost\": 600,\n        \"inaccessibleCost\": 3600\n      },\n      \"stop\": {\n        \"onlyConsiderAccessible\": false,\n        \"unknownCost\": 600,\n        \"inaccessibleCost\": 3600\n      },\n      \"elevator\": {\n        \"onlyConsiderAccessible\": false\n      },\n      \"inaccessibleStreetReluctance\": 25,\n      \"maxSlope\": 0.08333,\n      \"slopeExceededReluctance\": 50,\n      \"stairsReluctance\": 25\n    }\n  },\n  \"updaters\": []\n}\n

    The parameters for stop, trip and elevator mean the following:

    name default onlyConsiderAccessible Whether to exclude unknown accessibility and inaccessible stops/trips/elevators in the search. true unknownCost The cost to add if an entity has unknown wheelchair accessibility 600 inaccessibleCost The cost to add if an entity is known to be inaccessible 3600

    Note: Unless your accessibility data coverage is complete you will receive much better results by setting onlyConsiderAccessible=false, because otherwise you receive barely any results.

    Other parameters are:

    "},{"location":"Accessibility/#accessible-transfers","title":"Accessible transfers","text":"

    By default OTP only pre-calculates transfers between stops for able-bodied walkers. If they have no obstacles wheelchair users can use them, too, but there won't be guaranteed to be one.

    If you want OTP to also pre-generate wheelchair-accessible transfers use the following configuration in build-config.json:

    {\n  \"transferRequests\": [\n    {\n      \"modes\": \"WALK\"\n    },\n    {\n      \"modes\": \"WALK\",\n      \"wheelchairAccessibility\": {\n        \"enabled\": true\n      }\n    }\n  ]\n}\n

    This results in OTP calculating an accessible transfer if the default one is found to be inaccessible to wheelchair users.

    "},{"location":"Accessibility/#example","title":"Example","text":"

    A full configuration example is available at /docs/examples

    "},{"location":"Analysis/","title":"Travel Time Analysis","text":""},{"location":"Analysis/#background","title":"Background","text":"

    Since the beginning of the project, many OTP contributors and users have been primarily interested in research, spatial analysis, and urban planning use cases. They have prototyped many ideas within or on top of the OTP codebase, including one-to-many searches producing travel time grids, isochrones, and access-to-opportunities indicators (see Terminology Note below). This has historically been a major area of application for OpenTripPlanner and has helped popularize cumulative opportunities metrics in urban planning. For example, the University of Minnesota Accessibility Observatory used OpenTripPlanner for Access Across America.

    Although we consider these use cases quite important, most work of this kind has long since shifted to separate projects focused on urban planning and analytics. As of version 2, OTP has chosen to focus entirely on passenger information rather than analytics.

    "},{"location":"Analysis/#travel-time-analysis-in-otp1","title":"Travel Time Analysis in OTP1","text":"

    Much of the analysis code present in the v1.x legacy branch of OTP is essentially an unmaintained and unsupported early prototype for later projects, specifically 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 used 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.

    "},{"location":"Analysis/#travel-time-analysis-in-otp2","title":"Travel Time Analysis in OTP2","text":"

    OTP2's new transit router is quite similar to R5 (indeed it was directly influenced by R5) and would not face the same technical problems. Nonetheless, we have decided not to port the OTP1 analysis features over to OTP2 since it would broaden the scope of OTP2 away from passenger information and draw the finite amount of available attention and resources away from existing open source analytics tools. If you would like to apply the routing innovations present in OTP2 in analytics situations, we recommend taking a look at projects like R5 or the R and Python language wrappers for it created by the community.

    "},{"location":"Analysis/#terminology-note","title":"Terminology Note","text":"

    In OpenTripPlanner, we usually use the term \"accessibility\" with its most common meaning: design of products, devices, services, vehicles, or environments to ensure they are usable by people with disabilities. The term \"accessibility\" has a completely separate, unrelated definition in the fields of spatial analysis, urban transportation planning, and associated social sciences, where it refers to quantitative indicators of how well-connected a particular location is to people or opportunities. OTP has been widely used in research and planning settings for the calculation of such indicators. Although this meaning of the term dates back many decades, it is less well known and has become a source of confusion, so the academic and planning communities are gradually shifting to the expression \"access to opportunities\", often shortened to \"access\".

    "},{"location":"Basic-Tutorial/","title":"OpenTripPlanner Basic Tutorial","text":"

    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!

    "},{"location":"Basic-Tutorial/#get-java","title":"Get Java","text":"

    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 21 or later. We recommend running on Java 21 rather than a later version, as it is a long-term support release. Run java -version to check that you have version 21 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.

    "},{"location":"Basic-Tutorial/#get-otp","title":"Get OTP","text":"

    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, navigate to the directory of releases, and download the file with shaded.jar suffix .

    You may also want to get your own copy of the OTP source code and build a bleeding edge development JAR from scratch, especially if you plan to do some development yourself. In that case, check out the branch dev-2.x.

    "},{"location":"Basic-Tutorial/#get-some-data","title":"Get some data","text":""},{"location":"Basic-Tutorial/#gtfs-for-transit-schedules-and-stops","title":"GTFS for Transit Schedules and Stops","text":"

    First you'll need GTFS data to build a transit network. There's an excellent description of the GTFS format here. Transport agencies throughout the world provide GTFS schedules to the public. Transitland has a registry of feeds and TransitFeeds 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. 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\n$ mkdir otp\n$ cd otp\n$ wget \"http://developer.trimet.org/schedule/gtfs.zip\" -O trimet.gtfs.zip\n
    "},{"location":"Basic-Tutorial/#osm-for-streets","title":"OSM for Streets","text":"

    You'll also need OpenStreetMap data to build a road network for walking, cycling, and driving. OpenStreetMap 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 . Geofabrik provides extracts for larger areas like countries or states, from which you can prepare your own smaller bounding-box extracts using Osmosis , osmconvert, or (our favorite) Osmium-Tool. There is also Protomaps which can create custom extracts for any region of the world with an easy to use drag and drop interface. OSM data can be delivered as XML or in the more compact binary PBF format. OpenTripPlanner consumes only PBF because it's smaller and more efficient.

    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 , then further trim that to just the TriMet service area using the bounding box switch of one of the above tools. On Linux or MacOS you could do that as follows:

    $ cd /home/username\n$ wget http://download.geofabrik.de/north-america/us/oregon-latest.osm.pbf\n$ osmconvert oregon-latest.osm.pbf -b=-123.043,45.246,-122.276,45.652 --complete-ways -o=portland.pbf\n$ mv portland.pbf otp\n

    We find this tool 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 for additional information and example commands for cropping and filtering OSM data.

    "},{"location":"Basic-Tutorial/#starting-otp","title":"Starting OTP","text":"

    A typical command to start OTP looks like java -Xmx2G -jar otp.shaded.jar <options>. 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. Here is more information about the system requirements. If you have sufficient memory in your computer, set this to a couple of gigabytes (e.g. -Xmx2G). Java uses a garbage collection approach to memory management, which requires some \"breathing room\" to efficiently operate. Without sufficient free memory OTP can grind to a halt. VisualVM is a good way to inspect Java memory usage, especially with the VisualGC plugin.

    "},{"location":"Basic-Tutorial/#building-graphs","title":"Building Graphs","text":"

    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', 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.

    "},{"location":"Basic-Tutorial/#simple-one-step-server","title":"Simple One-step Server","text":"

    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.6.0-shaded.jar --build --serve /home/username/otp\n

    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/ 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 port 8080. If by any chance some other software is already using that port number, you can specify a different port number with a switch --port 8801.

    "},{"location":"Basic-Tutorial/#saving-a-graph","title":"Saving a Graph","text":"

    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.6.0-shaded.jar --build --save .\n

    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.6.0-shaded.jar --load .\n

    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.

    "},{"location":"Basic-Tutorial/#layering-gtfs-onto-osm","title":"Layering GTFS onto OSM","text":"

    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:

    $ java -Xmx2G -jar otp-2.6.0-shaded.jar --buildStreet .\n

    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.6.0-shaded.jar --loadStreet --save .\n

    Finally, the server can be started using the --load parameter:

    $ java -Xmx2G -jar otp-2.6.0-shaded.jar --load .\n
    "},{"location":"Basic-Tutorial/#command-line-switches","title":"Command Line Switches","text":"

    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.

    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.

    "},{"location":"Basic-Tutorial/#exploring-the-api","title":"Exploring the API","text":"

    If you want to learn how to use OTP's API's, check out the GraphQL tutorial.

    "},{"location":"Bibliography/","title":"Routing Bibliography","text":"

    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.

    "},{"location":"Bibliography/#algorithms-used-in-otp2-but-not-otp1","title":"Algorithms used in OTP2 but not OTP1","text":""},{"location":"Bibliography/#techniques-used-in-or-influencing-otp1-and-otp2","title":"Techniques used in or influencing OTP1 and OTP2","text":""},{"location":"Bibliography/#general-background","title":"General Background","text":""},{"location":"Bibliography/#path-search-speedup-techniques","title":"Path Search Speedup Techniques","text":""},{"location":"Bibliography/#multi-objective-pareto-shortest-paths","title":"Multi-objective Pareto Shortest Paths","text":""},{"location":"Bibliography/#resource-constrained-routing","title":"Resource-constrained Routing","text":""},{"location":"Bibliography/#contraction-and-transfer-patterns","title":"Contraction and Transfer Patterns","text":""},{"location":"Bibliography/#timetable-based-routing","title":"Timetable-based routing","text":""},{"location":"Bibliography/#alt-and-metric-embeddings","title":"ALT and Metric Embeddings","text":""},{"location":"Bibliography/#calibration-and-implementation-details","title":"Calibration and Implementation Details","text":""},{"location":"Bibliography/#post-dijkstra-public-transit-routing","title":"Post-Dijkstra Public Transit Routing","text":""},{"location":"BoardingLocations/","title":"Boarding locations","text":"

    It is often the case that the coordinates of stops are relatively far away from where the passengers are expected to the wait for the vehicle.

    A good example of this is Buckhead subway station in Atlanta.

    There the coordinates of the stop in GTFS are located near Peachtree Road so OTP would instruct passengers to wait on the street rather than walking down the stairs to the platform.

    "},{"location":"BoardingLocations/#osm-tagging","title":"OSM tagging","text":"

    We can correct the waiting location for the passenger by adding some tags to OSM which help OTP decide to correct the location. In general, you should familiarise yourself with the OSM wiki page on public transport.

    You can add cross-references to a stop's id or code on all OSM entities (nodes, ways, relations) which have one of the following tag combinations:

    "},{"location":"BoardingLocations/#notes","title":"Notes","text":""},{"location":"BoardingLocations/#cross-referencing","title":"Cross-referencing","text":"

    In order to tell OTP how to link up the OSM entities to the stops you need to add a ref tag whose value is the stop's id or code.

    However, tagging conventions vary from location to location so other tags can be configured, too.

    For example, there is a country-wide stop reference system in Germany called IFOPT and therefore if you want to use it to match stops (example platform), add the following to build-config.json:

    {\n  \"boardingLocationTags\": [\"ref\", \"ref:IFOPT\"]\n}\n
    "},{"location":"BoardingLocations/#multiple-stops-on-the-same-platform","title":"Multiple stops on the same platform","text":"

    Some stations have a middle platform with a stop on either side of it. In such a case, you can simply add two or more references separated by a semicolon, as seen in this example.

    "},{"location":"BoardingLocations/#related-chat-threads","title":"Related chat threads","text":""},{"location":"BuildConfiguration/","title":"Build","text":""},{"location":"BuildConfiguration/#graph-build-configuration","title":"Graph Build Configuration","text":"

    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.

    "},{"location":"BuildConfiguration/#parameters-overview","title":"Parameters Overview","text":"Config Parameter Type Summary Req./Opt. Default Value Since areaVisibility boolean Perform visibility calculations. Optional false 1.5 buildReportDir uri URI to the directory where the graph build report should be written to. Optional 2.0 configVersion string Deployment version of the build-config.json. Optional 2.1 dataImportReport boolean Generate nice HTML report of Graph errors/warnings Optional false 2.0 distanceBetweenElevationSamples double The distance between elevation samples in meters. Optional 10.0 2.0 embedRouterConfig boolean Embed the Router config in the graph, which allows it to be sent to a server fully configured over the wire. Optional true 2.0 graph uri URI to the graph object file for reading and writing. Optional 2.0 gsCredentials string Local file system path to Google Cloud Platform service accounts credentials file. Optional 2.0 includeEllipsoidToGeoidDifference boolean Include the Ellipsoid to Geoid difference in the calculations of every point along every StreetWithElevationEdge. Optional false 2.0 maxAreaNodes integer Visibility calculations for an area will not be done if there are more nodes than this limit. Optional 150 2.1 maxDataImportIssuesPerFile integer When to split the import report. Optional 1000 2.0 maxElevationPropagationMeters integer The maximum distance to propagate elevation to vertices which have no elevation. Optional 2000 1.5 maxStopToShapeSnapDistance double Maximum distance between route shapes and their stops. Optional 150.0 2.1 maxTransferDuration duration Transfers up to this duration with the default walk speed value will be pre-calculated and included in the Graph. Optional \"PT30M\" 2.1 multiThreadElevationCalculations boolean Configuring multi-threading during elevation calculations. Optional false 2.0 osmCacheDataInMem boolean If OSM data should be cached in memory during processing. Optional false 2.0 osmNaming enum A custom OSM namer to use. Optional \"default\" 1.5 platformEntriesLinking boolean Link unconnected entries to public transport platforms. Optional false 2.0 readCachedElevations boolean Whether to read cached elevation data. Optional true 2.0 staticBikeParkAndRide boolean Whether we should create bike P+R stations from OSM data. Optional false 1.5 staticParkAndRide boolean Whether we should create car P+R stations from OSM data. Optional true 1.5 stopConsolidationFile uri Name of the CSV-formatted file in the build directory which contains the configuration for stop consolidation. Optional 2.5 streetGraph uri URI to the street graph object file for reading and writing. Optional 2.0 subwayAccessTime double Minutes necessary to reach stops served by trips on routes of route_type=1 (subway) from the street. Optional 2.0 1.5 transitModelTimeZone time-zone Time zone for the graph. Optional 2.2 transitServiceEnd duration Limit the import of transit services to the given end date. Optional \"P3Y\" 2.0 transitServiceStart duration Limit the import of transit services to the given START date. Optional \"-P1Y\" 2.0 writeCachedElevations boolean Reusing elevation data from previous builds Optional false 2.0 boardingLocationTags string[] What OSM tags should be looked on for the source of matching stops to platforms and stops. Optional 2.2 dataOverlay object Config for the DataOverlay Sandbox module Optional 2.2 dem object[] Specify parameters for DEM extracts. Optional 2.2 elevationUnitMultiplier double Specify a multiplier to convert elevation units from source to meters. Overrides the value specified in demDefaults. Optional 1.0 2.3 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0source uri The unique URI pointing to the data file. Required 2.2 demDefaults object Default properties for DEM extracts. Optional 2.3 elevationUnitMultiplier double Specify a multiplier to convert elevation units from source to meters. Optional 1.0 2.3 elevationBucket object Used to download NED elevation tiles from the given AWS S3 bucket. Optional na emissions object Emissions configuration. Optional 2.5 fares object Fare configuration. Optional 2.0 gtfsDefaults object The gtfsDefaults section allows you to specify default properties for GTFS files. Optional 2.3 \u00a0\u00a0\u00a0blockBasedInterlining boolean Whether to create stay-seated transfers in between two trips with the same block id. Optional true 2.3 discardMinTransferTimes boolean Should minimum transfer times in GTFS files be discarded. Optional false 2.3 \u00a0\u00a0\u00a0maxInterlineDistance integer Maximal distance between stops in meters that will connect consecutive trips that are made with same vehicle. Optional 200 2.3 \u00a0\u00a0\u00a0removeRepeatedStops boolean Should consecutive identical stops be merged into one stop time entry. Optional true 2.3 stationTransferPreference enum Should there be some preference or aversion for transfers at stops that are part of a station. Optional \"allowed\" 2.3 islandPruning object Settings for fixing street graph connectivity errors Optional 2.3 adaptivePruningDistance integer Search distance for analyzing islands in pruning. Optional 250 2.3 adaptivePruningFactor double Defines how much pruning thresholds grow maximally by distance. Optional 50.0 2.3 islandWithStopsMaxSize integer When a graph island with stops in it should be pruned. Optional 2 2.3 islandWithoutStopsMaxSize integer When a graph island without stops should be pruned. Optional 10 2.3 localFileNamePatterns object Patterns for matching OTP file types in the base directory Optional 2.0 dem regexp Pattern for matching elevation DEM files. Optional \"(?i)\\.tiff?$\" 2.0 gtfs regexp Patterns for matching GTFS zip-files or directories. Optional \"(?i)gtfs\" 2.0 netex regexp Patterns for matching NeTEx zip files or directories. Optional \"(?i)netex\" 2.0 osm regexp Pattern for matching Open Street Map input files. Optional \"(?i)(\\.pbf\u00a6\\.osm\u00a6\\.osm\\.xml)$\" 2.0 netexDefaults object The netexDefaults section allows you to specify default properties for NeTEx files. Optional 2.2 \u00a0\u00a0\u00a0feedId string This field is used to identify the specific NeTEx feed. It is used instead of the feed_id field in GTFS file feed_info.txt. Optional \"NETEX\" 2.2 groupFilePattern regexp Pattern for matching group NeTEx files. Optional \"(\\w{3})-.*\\.xml\" 2.0 \u00a0\u00a0\u00a0ignoreFareFrame boolean Ignore contents of the FareFrame Optional false 2.3 ignoreFilePattern regexp Pattern for matching ignored files in a NeTEx bundle. Optional \"$^\" 2.0 \u00a0\u00a0\u00a0ignoreParking boolean Ignore Parking elements. Optional true 2.6 \u00a0\u00a0\u00a0noTransfersOnIsolatedStops boolean Whether we should allow transfers to and from StopPlaces marked with LimitedUse.ISOLATED Optional false 2.2 sharedFilePattern regexp Pattern for matching shared NeTEx files in a NeTEx bundle. Optional \"shared-data\\.xml\" 2.0 sharedGroupFilePattern regexp Pattern for matching shared group NeTEx files in a NeTEx bundle. Optional \"(\\w{3})-.*-shared\\.xml\" 2.0 ferryIdsNotAllowedForBicycle string[] List ferries which do not allow bikes. Optional 2.0 osm object[] Configure properties for a given OpenStreetMap feed. Optional 2.2 osmTagMapping enum The named set of mapping rules applied when parsing OSM tags. Overrides the value specified in osmDefaults. Optional \"default\" 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0source uri The unique URI pointing to the data file. Required 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0timeZone time-zone The timezone used to resolve opening hours in OSM data. Overrides the value specified in osmDefaults. Optional 2.2 osmDefaults object Default properties for OpenStreetMap feeds. Optional 2.2 osmTagMapping enum The named set of mapping rules applied when parsing OSM tags. Optional \"default\" 2.2 \u00a0\u00a0\u00a0timeZone time-zone The timezone used to resolve opening hours in OSM data. Optional 2.2 transferRequests object[] Routing requests to use for pre-calculating stop-to-stop transfers. Optional 2.1 transitFeeds object[] Scan for transit data files Optional 2.2 \u00a0\u00a0\u00a0{ object } object Nested object in array. The object type is determined by the parameters. Optional 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type = \"gtfs\" enum The feed input format. Required 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0blockBasedInterlining boolean Whether to create stay-seated transfers in between two trips with the same block id. Overrides the value specified in gtfsDefaults. Optional true 2.3 discardMinTransferTimes boolean Should minimum transfer times in GTFS files be discarded. Overrides the value specified in gtfsDefaults. Optional false 2.3 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0feedId string The unique ID for this feed. This overrides any feed ID defined within the feed itself. Optional 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0maxInterlineDistance integer Maximal distance between stops in meters that will connect consecutive trips that are made with same vehicle. Overrides the value specified in gtfsDefaults. Optional 200 2.3 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0removeRepeatedStops boolean Should consecutive identical stops be merged into one stop time entry. Overrides the value specified in gtfsDefaults. Optional true 2.3 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0source uri The unique URI pointing to the data file. Required 2.2 stationTransferPreference enum Should there be some preference or aversion for transfers at stops that are part of a station. Overrides the value specified in gtfsDefaults. Optional \"allowed\" 2.3 \u00a0\u00a0\u00a0{ object } object Nested object in array. The object type is determined by the parameters. Optional 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type = \"netex\" enum The feed input format. Required 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0feedId string This field is used to identify the specific NeTEx feed. It is used instead of the feed_id field in GTFS file feed_info.txt. Required 2.2 groupFilePattern regexp Pattern for matching group NeTEx files. Optional \"(\\w{3})-.*\\.xml\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ignoreFareFrame boolean Ignore contents of the FareFrame Optional false 2.3 ignoreFilePattern regexp Pattern for matching ignored files in a NeTEx bundle. Optional \"$^\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ignoreParking boolean Ignore Parking elements. Optional true 2.6 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0noTransfersOnIsolatedStops boolean Whether we should allow transfers to and from StopPlaces marked with LimitedUse.ISOLATED Optional false 2.2 sharedFilePattern regexp Pattern for matching shared NeTEx files in a NeTEx bundle. Optional \"shared-data\\.xml\" 2.0 sharedGroupFilePattern regexp Pattern for matching shared group NeTEx files in a NeTEx bundle. Optional \"(\\w{3})-.*-shared\\.xml\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0source uri The unique URI pointing to the data file. Required 2.2 ferryIdsNotAllowedForBicycle string[] List ferries which do not allow bikes. Optional 2.0 transitRouteToStationCentroid feed-scoped-id[] List stations that should route to centroid. Optional 2.7"},{"location":"BuildConfiguration/#specifying-uris","title":"Specifying URIs","text":"

    As a general rule, references to data files are specified as absolute URIs and must start with the protocol name.

    Example

    Local files: \"file:///Users/kelvin/otp/streetGraph.obj\" HTTPS resources: \"https://download.geofabrik.de/europe/norway-latest.osm.pbf\" Google Cloud Storage files: \"gs://otp-test-bucket/a/b/graph.obj\"

    Alternatively if a relative URI can be provided, it is interpreted as a path relative to the base directory.

    Example

    File relative to the base directory (inside the base directory): streetGraph.obj File relative to the base directory (outside the base directory): ../street-graphs/streetGraph.obj

    "},{"location":"BuildConfiguration/#example-with-multiple-data-sources","title":"Example With Multiple Data Sources","text":"

    For example, this configuration could be used to load GTFS and OSM inputs from Google Cloud Storage:

    // build-config.json\n{\n  \"osm\": [\n    {\n      \"source\": \"gs://bucket-name/streets.pbf\"\n    }\n  ],\n  \"transitFeeds\": [\n    {\n      \"type\": \"netex\",\n      \"source\": \"gs://bucket-name/transit1.zip\"\n    },\n    {\n      \"type\": \"gtfs\",\n      \"source\": \"gs://bucket-name/transit2.zip\"\n    }\n  ]\n}\n

    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.

    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 OTP2 will still scan the base directory for all other types such as DEM files. Supplying an empty array for a particular file type will ensure that no inputs of that type are loaded, including by local directory scanning.

    "},{"location":"BuildConfiguration/#limit-transit-service-period","title":"Limit the transit service period","text":"

    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.

    Example

    // build-config.json\n{\n  // Include 3 months of history\n  \"transitServiceStart\" : \"-P3M\",\n  // Include 1 year 6 month and 5 days of scheduled data in the future \n  \"transitServiceEnd\" : \"P1Y6M5D\"\n}\n
    "},{"location":"BuildConfiguration/#openstreetmaposm-configuration","title":"OpenStreetMap(OSM) configuration","text":"

    It is possible to adjust how OSM data is interpreted by OpenTripPlanner when building the road part of the routing graph.

    "},{"location":"BuildConfiguration/#osm-tag-mapping","title":"OSM tag mapping","text":"

    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 roads tagged with `highway=trunk are (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. It's possible to define \"safety\" values for cycling and walking which are used in routing.

    To add your own OSM tag mapping have a look at org.opentripplanner.graph_builder.module.osm.tagmapping.NorwayTagMapper and org.opentripplanner.graph_builder.module.osm.tagmapping.DefaultMapper as examples. 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.

    // build-config.json\n{\n  \"osm\": [\n    {\n      \"source\": \"gs://marduk-dev/osm/oslo_norway.osm-160816.pbf\",\n      \"osmTagMapping\": \"norway\"\n    }\n  ]\n}\n
    "},{"location":"BuildConfiguration/#elevation-data","title":"Elevation data","text":"

    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.

    "},{"location":"BuildConfiguration/#geoid-difference","title":"Geoid Difference","text":"

    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 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 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:

    // router-config.json\n{\n    \"routingDefaults\": {\n        \"geoidElevation\": true   \n    }\n}\n

    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:

    // build-config.json\n{\n  \"includeEllipsoidToGeoidDifference\": true\n}\n

    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.

    "},{"location":"BuildConfiguration/#other-raster-elevation-data","title":"Other raster elevation data","text":"

    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 (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.

    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. Use gdal_merge.py -o merged.tiff *.dem to merge a set of dem files into one tif file.

    See Interline PlanetUtils for a set of scripts to download, merge, and resample Mapzen/Amazon Terrain Tiles.

    "},{"location":"BuildConfiguration/#elevation-unit-conversion","title":"Elevation unit conversion","text":"

    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.

    // build-config.json\n{\n  \"dem\": [\n    {\n      \"source\": \"gs://otp-test-bucket/a/b/northpole.dem.tif\",\n      // Correct conversion multiplier when source data uses decimetres instead of metres\n      \"elevationUnitMultiplier\": 0.1\n    }\n  ]\n}\n
    "},{"location":"BuildConfiguration/#elevation-data-calculation-optimizations","title":"Elevation Data Calculation Optimizations","text":"

    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 the elevations took 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 the data won't need to be downloaded.

    However, the bulk of the time will still be spent calculating elevations for 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.

    "},{"location":"BuildConfiguration/#reusing-elevation-data-from-previous-builds","title":"Reusing elevation data from previous builds","text":"

    In order to write out the precalculated elevation data, add this to your build-config.json file:

    // build-config.json\n{  \n  \"writeCachedElevations\": true\n}\n
    See writeCachedElevations for details.

    "},{"location":"BuildConfiguration/#parameter-details","title":"Parameter Details","text":""},{"location":"BuildConfiguration/#areaVisibility","title":"areaVisibility","text":"

    Since version: 1.5 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /

    Perform visibility calculations.

    If this is true OTP attempts to calculate a path straight through an OSM area using the shortest way rather than around the edge of it. (These calculations can be time consuming).

    "},{"location":"BuildConfiguration/#buildReportDir","title":"buildReportDir","text":"

    Since version: 2.0 \u2219 Type: uri \u2219 Cardinality: Optional Path: /

    URI to the directory where the graph build report should be written to.

    The html report is written into this directory. If the directory exist, any existing files are deleted. If it does not exist, it is created.

    "},{"location":"BuildConfiguration/#configVersion","title":"configVersion","text":"

    Since version: 2.1 \u2219 Type: string \u2219 Cardinality: Optional Path: /

    Deployment version of the build-config.json.

    The config-version is a parameter which each OTP deployment may set to be able to query the OTP server and verify that it uses the correct version of the config. The version should be injected into the config in the (continuous) deployment pipeline. How this is done, is up to the deployment.

    The config-version has no effect on OTP, and is provided as is on the API. There is no syntax or format check on the version and it can be any string.

    Be aware that OTP uses the config embedded in the loaded graph if no new config is provided.

    "},{"location":"BuildConfiguration/#dataImportReport","title":"dataImportReport","text":"

    Since version: 2.0 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /

    Generate nice HTML report of Graph errors/warnings

    The reports are stored in the same location as the graph.

    "},{"location":"BuildConfiguration/#distanceBetweenElevationSamples","title":"distanceBetweenElevationSamples","text":"

    Since version: 2.0 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 10.0 Path: /

    The distance between elevation samples in meters.

    The default is the approximate resolution of 1/3 arc-second NED data. This should not be smaller than the horizontal resolution of the height data used.

    "},{"location":"BuildConfiguration/#graph","title":"graph","text":"

    Since version: 2.0 \u2219 Type: uri \u2219 Cardinality: Optional Path: /

    URI to the graph object file for reading and writing.

    The file is created or overwritten if OTP saves the graph to the file.

    "},{"location":"BuildConfiguration/#gsCredentials","title":"gsCredentials","text":"

    Since version: 2.0 \u2219 Type: string \u2219 Cardinality: Optional Path: /

    Local file system path to Google Cloud Platform service accounts credentials file.

    The credentials is used to access GCS urls. When using GCS from outside of Google Cloud you need to provide a path the the service credentials. Environment variables in the path are resolved.

    This is a path to a file on the local file system, not an URI.

    "},{"location":"BuildConfiguration/#includeEllipsoidToGeoidDifference","title":"includeEllipsoidToGeoidDifference","text":"

    Since version: 2.0 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /

    Include the Ellipsoid to Geoid difference in the calculations of every point along every StreetWithElevationEdge.

    When set to true (it is false by default), the elevation module will include the Ellipsoid to Geoid difference in the calculations of every point along every StreetWithElevationEdge in the graph.

    NOTE: if this is set to true for graph building, make sure to not set the value of RoutingResource#geoidElevation to true otherwise OTP will add this geoid value again to all of the elevation values in the street edges.

    "},{"location":"BuildConfiguration/#maxDataImportIssuesPerFile","title":"maxDataImportIssuesPerFile","text":"

    Since version: 2.0 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 1000 Path: /

    When to split the import report.

    If the number of issues is larger then maxDataImportIssuesPerFile, then the files will be split in multiple files. Since browsers have problems opening large HTML files.

    "},{"location":"BuildConfiguration/#maxStopToShapeSnapDistance","title":"maxStopToShapeSnapDistance","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 150.0 Path: /

    Maximum distance between route shapes and their stops.

    This field is used for mapping routes geometry shapes. It determines max distance between shape points and their stop sequence. If mapper cannot find any stops within this radius it will default to simple stop-to-stop geometry instead.

    "},{"location":"BuildConfiguration/#multiThreadElevationCalculations","title":"multiThreadElevationCalculations","text":"

    Since version: 2.0 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /

    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. If multi-threading is activated, parallel streams will be used to calculate the elevations.

    "},{"location":"BuildConfiguration/#osmCacheDataInMem","title":"osmCacheDataInMem","text":"

    Since version: 2.0 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /

    If OSM data should be cached in memory during processing.

    When loading OSM data, the input is streamed 3 times - one phase for processing RELATIONS, one for WAYS and last one for NODES. Instead of reading the data source 3 times it might be faster to cache the entire osm file im memory. The trade off is of course that OTP might use more memory while loading osm data. You can use this parameter to choose what is best for your deployment depending on your infrastructure. Set the parameter to true to cache the data, and to false to read the stream from the source each time.

    "},{"location":"BuildConfiguration/#osmNaming","title":"osmNaming","text":"

    Since version: 1.5 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"default\" Path: / Enum values: default | portland | sidewalks

    A custom OSM namer to use.

    "},{"location":"BuildConfiguration/#readCachedElevations","title":"readCachedElevations","text":"

    Since version: 2.0 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: true Path: /

    Whether to read cached elevation data.

    When set to true, the elevation module will attempt to read this file in order to reuse calculations of elevation data for various coordinate sequences instead of recalculating them all over again.

    "},{"location":"BuildConfiguration/#streetGraph","title":"streetGraph","text":"

    Since version: 2.0 \u2219 Type: uri \u2219 Cardinality: Optional Path: /

    URI to the street graph object file for reading and writing.

    The file is created or overwritten if OTP saves the graph to the file

    "},{"location":"BuildConfiguration/#subwayAccessTime","title":"subwayAccessTime","text":"

    Since version: 1.5 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 2.0 Path: /

    Minutes necessary to reach stops served by trips on routes of route_type=1 (subway) from the street.

    Note! The preferred way to do this is to update the OSM data. See In-station navigation.

    The ride locations for some modes of transport such as subways 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.

    This setting does not generalize to other modes like airplanes because you often need much longer time to check in to a flight (2-3 hours for international flights) than to alight and exit the airport (perhaps 1 hour). Use boardSlackForMode and alightSlackForMode for this.

    "},{"location":"BuildConfiguration/#transitModelTimeZone","title":"transitModelTimeZone","text":"

    Since version: 2.2 \u2219 Type: time-zone \u2219 Cardinality: Optional Path: /

    Time zone for the graph.

    This is used to store the timetables in the transit model, and to interpret times in incoming requests.

    "},{"location":"BuildConfiguration/#transitServiceEnd","title":"transitServiceEnd","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"P3Y\" Path: /

    Limit the import of transit services to the given end date.

    See Limit the transit service period for an introduction.

    The date is inclusive. If set, any transit service on a day AFTER the given date is dropped and will not be part of the graph. Use an absolute date or a period relative to the date the graph is build(BUILD_DAY).

    Use an empty string to make it unbounded.

    "},{"location":"BuildConfiguration/#transitServiceStart","title":"transitServiceStart","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"-P1Y\" Path: /

    Limit the import of transit services to the given START date.

    See Limit the transit service period for an introduction.

    The date is inclusive. If set, any transit service on a day BEFORE the given date is dropped and will not be part of the graph. Use an absolute date or a period relative to the date the graph is build(BUILD_DAY).

    Use an empty string to make unbounded.

    "},{"location":"BuildConfiguration/#writeCachedElevations","title":"writeCachedElevations","text":"

    Since version: 2.0 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /

    Reusing elevation data from previous builds

    When set to true, the elevation module will create a file cache for calculated elevation data. Subsequent graph builds can reuse the data in this file.

    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 overridden via the CLI argument --cache <directory>. For the same graph build for multiple Northeast US states, the time it took with using this pre-downloaded and precalculated data became 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.

    "},{"location":"BuildConfiguration/#boardingLocationTags","title":"boardingLocationTags","text":"

    Since version: 2.2 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /

    What OSM tags should be looked on for the source of matching stops to platforms and stops.

    Detailed documentation

    "},{"location":"BuildConfiguration/#dem","title":"dem","text":"

    Since version: 2.2 \u2219 Type: object[] \u2219 Cardinality: Optional Path: /

    Specify parameters for DEM extracts.

    The dem section allows you to override the default behavior of scanning for elevation files in the base directory. You can specify data located outside the local filesystem (including cloud storage services) or at various different locations around the local filesystem.

    If not specified OTP will fall back to auto-detection based on the directory provided on the command line.

    "},{"location":"BuildConfiguration/#dem_0_elevationUnitMultiplier","title":"elevationUnitMultiplier","text":"

    Since version: 2.3 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 1.0 Path: /dem/[0]

    Specify a multiplier to convert elevation units from source to meters. Overrides the value specified in demDefaults.

    Unit conversion multiplier for elevation values. No conversion needed if the elevation values are defined in meters in the source data. If, for example, decimetres are used in the source data, this should be set to 0.1.

    "},{"location":"BuildConfiguration/#demDefaults_elevationUnitMultiplier","title":"elevationUnitMultiplier","text":"

    Since version: 2.3 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 1.0 Path: /demDefaults

    Specify a multiplier to convert elevation units from source to meters.

    Unit conversion multiplier for elevation values. No conversion needed if the elevation values are defined in meters in the source data. If, for example, decimetres are used in the source data, this should be set to 0.1.

    "},{"location":"BuildConfiguration/#elevationBucket","title":"elevationBucket","text":"

    Since version: na \u2219 Type: object \u2219 Cardinality: Optional Path: /

    Used to download NED elevation tiles from the given AWS S3 bucket.

    In the United States, a high resolution National Elevation Dataset 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. 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.

    This ned13 bucket is still available on S3 under a \"requester pays\" policy. As long as you specify valid AWS account credentials you should be able to download tiles, and any bandwidth costs will be billed to your AWS account.

    Once the tiles are downloaded for a particular geographic area, OTP will keep them in local cache for the next graph build operation. You should add the --cache <directory> command line parameter to specify your NED tile cache location.

    "},{"location":"BuildConfiguration/#gd_discardMinTransferTimes","title":"discardMinTransferTimes","text":"

    Since version: 2.3 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /gtfsDefaults

    Should minimum transfer times in GTFS files be discarded.

    This is useful eg. when the minimum transfer time is only set for ticketing purposes, but we want to calculate the transfers always from OSM data.

    "},{"location":"BuildConfiguration/#gd_stationTransferPreference","title":"stationTransferPreference","text":"

    Since version: 2.3 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"allowed\" Path: /gtfsDefaults Enum values: preferred | recommended | allowed | discouraged

    Should there be some preference or aversion for transfers at stops that are part of a station.

    This parameter sets the generic level of preference. What is the actual cost can be changed with the stopBoardAlightDuringTransferCost parameter in the router configuration.

    "},{"location":"BuildConfiguration/#islandPruning_adaptivePruningDistance","title":"adaptivePruningDistance","text":"

    Since version: 2.3 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 250 Path: /islandPruning

    Search distance for analyzing islands in pruning.

    The distance after which disconnected sub graph is considered as real island in pruning heuristics.

    "},{"location":"BuildConfiguration/#islandPruning_adaptivePruningFactor","title":"adaptivePruningFactor","text":"

    Since version: 2.3 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 50.0 Path: /islandPruning

    Defines how much pruning thresholds grow maximally by distance.

    Expands the pruning thresholds as the distance of an island from the rest of the graph gets smaller. Even fairly large disconnected sub graphs should be removed if they are badly entangled with other graph.

    "},{"location":"BuildConfiguration/#islandPruning_islandWithStopsMaxSize","title":"islandWithStopsMaxSize","text":"

    Since version: 2.3 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 2 Path: /islandPruning

    When a graph island with stops in it should be pruned.

    This field indicates the pruning threshold for islands with stops. Any such island under this edge count will be pruned.

    "},{"location":"BuildConfiguration/#islandPruning_islandWithoutStopsMaxSize","title":"islandWithoutStopsMaxSize","text":"

    Since version: 2.3 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 10 Path: /islandPruning

    When a graph island without stops should be pruned.

    This field indicates the pruning threshold for islands without stops. Any such island under this edge count will be pruned.

    "},{"location":"BuildConfiguration/#localFileNamePatterns","title":"localFileNamePatterns","text":"

    Since version: 2.0 \u2219 Type: object \u2219 Cardinality: Optional Path: /

    Patterns for matching OTP file types in the base directory

    When scanning the base directory for inputs, each file's name is checked against patterns to detect what kind of file it is.

    OTP1 used to peek inside ZIP files and read the CSV tables to guess if a ZIP was indeed GTFS. Now that we support remote input files (cloud storage or arbitrary URLs) not all data sources allow seeking within files to guess what they are. Therefore, like all other file types GTFS is now 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.

    "},{"location":"BuildConfiguration/#lfp_dem","title":"dem","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(?i)\\.tiff?$\" Path: /localFileNamePatterns

    Pattern for matching elevation DEM files.

    If the filename contains the given pattern it is considered a match. Any legal Java Regular expression is allowed.

    "},{"location":"BuildConfiguration/#lfp_gtfs","title":"gtfs","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(?i)gtfs\" Path: /localFileNamePatterns

    Patterns for matching GTFS zip-files or directories.

    If the filename contains the given pattern it is considered a match. Any legal Java Regular expression is allowed.

    "},{"location":"BuildConfiguration/#lfp_netex","title":"netex","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(?i)netex\" Path: /localFileNamePatterns

    Patterns for matching NeTEx zip files or directories.

    If the filename contains the given pattern it is considered a match. Any legal Java Regular expression is allowed.

    "},{"location":"BuildConfiguration/#lfp_osm","title":"osm","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(?i)(\\.pbf|\\.osm|\\.osm\\.xml)$\" Path: /localFileNamePatterns

    Pattern for matching Open Street Map input files.

    If the filename contains the given pattern it is considered a match. Any legal Java Regular expression is allowed.

    "},{"location":"BuildConfiguration/#nd_groupFilePattern","title":"groupFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(\\w{3})-.*\\.xml\" Path: /netexDefaults

    Pattern for matching group NeTEx files.

    This field is used to match group files in the module file(zip file entries). group files are loaded right the after shared group files are loaded. Files are grouped together by the first group pattern in the regular expression. The pattern \"(\\w{3})-.*\\.xml\" matches \"RUT-Line-208-Hagalia-Nevlunghavn.xml\" with group \"RUT\".

    "},{"location":"BuildConfiguration/#nd_ignoreFilePattern","title":"ignoreFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"$^\" Path: /netexDefaults

    Pattern for matching ignored files in a NeTEx bundle.

    This field is used to exclude matching files in the module file(zip file entries). The ignored files are not loaded.

    "},{"location":"BuildConfiguration/#nd_sharedFilePattern","title":"sharedFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"shared-data\\.xml\" Path: /netexDefaults

    Pattern for matching shared NeTEx files in a NeTEx bundle.

    This field is used to match shared files(zip file entries) in the module file. Shared files are loaded first. Then the rest of the files are grouped and loaded.

    The pattern \"shared-data.xml\" matches \"shared-data.xml\"

    File names are matched in the following order - and treated accordingly to the first match:

    "},{"location":"BuildConfiguration/#nd_sharedGroupFilePattern","title":"sharedGroupFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(\\w{3})-.*-shared\\.xml\" Path: /netexDefaults

    Pattern for matching shared group NeTEx files in a NeTEx bundle.

    This field is used to match shared group files in the module file(zip file entries). Typically this is used to group all files from one agency together.

    Shared group files are loaded after shared files, but before the matching group files. Each group of files are loaded as a unit, followed by next group.

    Files are grouped together by the first group pattern in the regular expression.

    The pattern \"(\\w{3})-.*-shared\\.xml\" matches \"RUT-shared.xml\" with group \"RUT\".

    "},{"location":"BuildConfiguration/#nd_ferryIdsNotAllowedForBicycle","title":"ferryIdsNotAllowedForBicycle","text":"

    Since version: 2.0 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /netexDefaults

    List ferries which do not allow bikes.

    Bicycles are allowed on most ferries however the Nordic profile doesn't contain a place where bicycle conveyance can be defined.

    For this reason we allow bicycles on ferries by default and allow to override the rare case where this is not the case.

    "},{"location":"BuildConfiguration/#osm","title":"osm","text":"

    Since version: 2.2 \u2219 Type: object[] \u2219 Cardinality: Optional Path: /

    Configure properties for a given OpenStreetMap feed.

    The osm section of build-config.json allows you to override the default behavior of scanning for OpenStreetMap files in the base directory. You can specify data located outside the local filesystem (including cloud storage services) or at various different locations around the local filesystem.

    "},{"location":"BuildConfiguration/#osm_0_osmTagMapping","title":"osmTagMapping","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"default\" Path: /osm/[0] Enum values: default | norway | uk | finland | germany | hamburg | atlanta | houston | portland | constant-speed-finland

    The named set of mapping rules applied when parsing OSM tags. Overrides the value specified in osmDefaults.

    "},{"location":"BuildConfiguration/#od_osmTagMapping","title":"osmTagMapping","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"default\" Path: /osmDefaults Enum values: default | norway | uk | finland | germany | hamburg | atlanta | houston | portland | constant-speed-finland

    The named set of mapping rules applied when parsing OSM tags.

    "},{"location":"BuildConfiguration/#transitFeeds","title":"transitFeeds","text":"

    Since version: 2.2 \u2219 Type: object[] \u2219 Cardinality: Optional Path: /

    Scan for transit data files

    The transitFeeds section of build-config.json allows you to override the default behavior of scanning for transit data files in the base directory. You can specify data located outside the local filesystem (including cloud storage services) or at various different locations around the local filesystem.

    When a feed of a particular type (netex or gtfs) is specified in the transitFeeds section, auto-scanning in the base directory for this feed type will be disabled.

    "},{"location":"BuildConfiguration/#tf_0_discardMinTransferTimes","title":"discardMinTransferTimes","text":"

    Since version: 2.3 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /transitFeeds/[0]

    Should minimum transfer times in GTFS files be discarded. Overrides the value specified in gtfsDefaults.

    This is useful eg. when the minimum transfer time is only set for ticketing purposes, but we want to calculate the transfers always from OSM data.

    "},{"location":"BuildConfiguration/#tf_0_stationTransferPreference","title":"stationTransferPreference","text":"

    Since version: 2.3 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"allowed\" Path: /transitFeeds/[0] Enum values: preferred | recommended | allowed | discouraged

    Should there be some preference or aversion for transfers at stops that are part of a station. Overrides the value specified in gtfsDefaults.

    This parameter sets the generic level of preference. What is the actual cost can be changed with the stopBoardAlightDuringTransferCost parameter in the router configuration.

    "},{"location":"BuildConfiguration/#tf_1_groupFilePattern","title":"groupFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(\\w{3})-.*\\.xml\" Path: /transitFeeds/[1]

    Pattern for matching group NeTEx files.

    This field is used to match group files in the module file(zip file entries). group files are loaded right the after shared group files are loaded. Files are grouped together by the first group pattern in the regular expression. The pattern \"(\\w{3})-.*\\.xml\" matches \"RUT-Line-208-Hagalia-Nevlunghavn.xml\" with group \"RUT\".

    "},{"location":"BuildConfiguration/#tf_1_ignoreFilePattern","title":"ignoreFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"$^\" Path: /transitFeeds/[1]

    Pattern for matching ignored files in a NeTEx bundle.

    This field is used to exclude matching files in the module file(zip file entries). The ignored files are not loaded.

    "},{"location":"BuildConfiguration/#tf_1_sharedFilePattern","title":"sharedFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"shared-data\\.xml\" Path: /transitFeeds/[1]

    Pattern for matching shared NeTEx files in a NeTEx bundle.

    This field is used to match shared files(zip file entries) in the module file. Shared files are loaded first. Then the rest of the files are grouped and loaded.

    The pattern \"shared-data.xml\" matches \"shared-data.xml\"

    File names are matched in the following order - and treated accordingly to the first match:

    "},{"location":"BuildConfiguration/#tf_1_sharedGroupFilePattern","title":"sharedGroupFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(\\w{3})-.*-shared\\.xml\" Path: /transitFeeds/[1]

    Pattern for matching shared group NeTEx files in a NeTEx bundle.

    This field is used to match shared group files in the module file(zip file entries). Typically this is used to group all files from one agency together.

    Shared group files are loaded after shared files, but before the matching group files. Each group of files are loaded as a unit, followed by next group.

    Files are grouped together by the first group pattern in the regular expression.

    The pattern \"(\\w{3})-.*-shared\\.xml\" matches \"RUT-shared.xml\" with group \"RUT\".

    "},{"location":"BuildConfiguration/#tf_1_ferryIdsNotAllowedForBicycle","title":"ferryIdsNotAllowedForBicycle","text":"

    Since version: 2.0 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /transitFeeds/[1]

    List ferries which do not allow bikes.

    Bicycles are allowed on most ferries however the Nordic profile doesn't contain a place where bicycle conveyance can be defined.

    For this reason we allow bicycles on ferries by default and allow to override the rare case where this is not the case.

    "},{"location":"BuildConfiguration/#transitRouteToStationCentroid","title":"transitRouteToStationCentroid","text":"

    Since version: 2.7 \u2219 Type: feed-scoped-id[] \u2219 Cardinality: Optional Path: /

    List stations that should route to centroid.

    This field contains a list of station ids for which street legs will start/end at the station centroid instead of the child stops.

    When searching from/to a station the default behaviour is to route from/to any of the stations child stops. This can cause strange results for stations that have stops spread over a large area.

    For some stations you might instead wish to use the centroid of the station as the origin/destination. In this case the centroid will be used both for direct street search and for access/egress street search where the station is used as the start/end of the access/egress. But transit that starts/ends at the station will work as usual without any additional street leg from/to the centroid.

    "},{"location":"BuildConfiguration/#build-config-example","title":"Build Config Example","text":"
    // build-config.json\n{\n  \"transitServiceStart\" : \"-P3M\",\n  \"transitServiceEnd\" : \"P1Y\",\n  \"osmCacheDataInMem\" : true,\n  \"localFileNamePatterns\" : {\n    \"osm\" : \"(i?)\\\\.osm\\\\.pbf$\",\n    \"dem\" : \"(i?)\\\\.dem\\\\.tiff?$\",\n    \"gtfs\" : \"(?i)gtfs\",\n    \"netex\" : \"(?i)netex\"\n  },\n  \"osmDefaults\" : {\n    \"timeZone\" : \"Europe/Rome\",\n    \"osmTagMapping\" : \"default\"\n  },\n  \"osm\" : [\n    {\n      \"source\" : \"gs://my-bucket/otp-work-dir/norway.osm.pbf\",\n      \"timeZone\" : \"Europe/Oslo\",\n      \"osmTagMapping\" : \"norway\"\n    }\n  ],\n  \"demDefaults\" : {\n    \"elevationUnitMultiplier\" : 1.0\n  },\n  \"dem\" : [\n    {\n      \"source\" : \"gs://my-bucket/otp-work-dir/norway.dem.tiff\",\n      \"elevationUnitMultiplier\" : 2.5\n    }\n  ],\n  \"netexDefaults\" : {\n    \"feedId\" : \"EN\",\n    \"sharedFilePattern\" : \"_stops.xml\",\n    \"sharedGroupFilePattern\" : \"_(\\\\w{3})_shared_data.xml\",\n    \"groupFilePattern\" : \"(\\\\w{3})_.*\\\\.xml\",\n    \"ignoreFilePattern\" : \"(temp|tmp)\",\n    \"ferryIdsNotAllowedForBicycle\" : [\n      \"RUT:B107\",\n      \"RUT:B209\"\n    ]\n  },\n  \"gtfsDefaults\" : {\n    \"stationTransferPreference\" : \"recommended\",\n    \"removeRepeatedStops\" : true,\n    \"discardMinTransferTimes\" : false,\n    \"blockBasedInterlining\" : true,\n    \"maxInterlineDistance\" : 200\n  },\n  \"islandPruning\" : {\n    \"islandWithStopsMaxSize\" : 2,\n    \"islandWithoutStopsMaxSize\" : 10,\n    \"adaptivePruningFactor\" : 50.0,\n    \"adaptivePruningDistance\" : 250\n  },\n  \"transitFeeds\" : [\n    {\n      \"type\" : \"gtfs\",\n      \"feedId\" : \"SE\",\n      \"source\" : \"https://skanetrafiken.se/download/sweden.gtfs.zip\"\n    },\n    {\n      \"type\" : \"netex\",\n      \"feedId\" : \"NO\",\n      \"source\" : \"gs://BUCKET/OTP_GCS_WORK_DIR/norway-netex.obj\",\n      \"sharedFilePattern\" : \"_stops.xml\",\n      \"sharedGroupFilePattern\" : \"_(\\\\w{3})_shared_data.xml\",\n      \"groupFilePattern\" : \"(\\\\w{3})_.*\\\\.xml\",\n      \"ignoreFilePattern\" : \"(temp|tmp)\"\n    }\n  ],\n  \"transferRequests\" : [\n    {\n      \"modes\" : \"WALK\"\n    },\n    {\n      \"modes\" : \"WALK\",\n      \"wheelchairAccessibility\" : {\n        \"enabled\" : true\n      }\n    }\n  ],\n  \"stopConsolidationFile\" : \"consolidated-stops.csv\",\n  \"emissions\" : {\n    \"carAvgCo2PerKm\" : 170,\n    \"carAvgOccupancy\" : 1.3\n  }\n}\n
    "},{"location":"Changelog/","title":"Changelog","text":"

    The changelog lists most feature changes between each release. The list is automatically created based on merged pull requests. Search GitHub issues and pull requests for smaller issues.

    "},{"location":"Changelog/#270-snapshot-under-development","title":"2.7.0-SNAPSHOT (under development)","text":""},{"location":"Changelog/#260-2024-09-18","title":"2.6.0 (2024-09-18)","text":""},{"location":"Changelog/#notable-changes","title":"Notable Changes","text":""},{"location":"Changelog/#detailed-changes-by-pull-request","title":"Detailed changes by Pull Request","text":""},{"location":"Changelog/#250-2024-03-13","title":"2.5.0 (2024-03-13)","text":""},{"location":"Changelog/#notable-changes_1","title":"Notable Changes","text":""},{"location":"Changelog/#detailed-changes-by-pull-request_1","title":"Detailed changes by Pull Request","text":""},{"location":"Changelog/#240-2023-09-13","title":"2.4.0 (2023-09-13)","text":""},{"location":"Changelog/#notable-changes_2","title":"Notable Changes","text":""},{"location":"Changelog/#detailed-changes-by-pull-request_2","title":"Detailed changes by Pull Request","text":""},{"location":"Changelog/#230-2023-04-24","title":"2.3.0 (2023-04-24)","text":""},{"location":"Changelog/#notable-changes_3","title":"Notable Changes","text":""},{"location":"Changelog/#detailed-changes-by-pull-request_3","title":"Detailed changes by Pull Request","text":""},{"location":"Changelog/#220-2022-11-01","title":"2.2.0 (2022-11-01)","text":""},{"location":"Changelog/#notable-changes_4","title":"Notable Changes","text":""},{"location":"Changelog/#detailed-changes-by-pull-request_4","title":"Detailed changes by Pull Request","text":""},{"location":"Changelog/#210-2022-03-17","title":"2.1.0 (2022-03-17)","text":""},{"location":"Changelog/#notable-changes_5","title":"Notable Changes","text":""},{"location":"Changelog/#detailed-changes-by-pull-request_5","title":"Detailed changes by Pull Request","text":""},{"location":"Changelog/#200-2020-11-27","title":"2.0.0 (2020-11-27)","text":""},{"location":"Changelog/#ported-over-from-14-and-15","title":"Ported over from 1.4 and 1.5","text":""},{"location":"Changelog/#13-2018-08-03","title":"1.3 (2018-08-03)","text":""},{"location":"Changelog/#12-2017-09-18","title":"1.2 (2017-09-18)","text":""},{"location":"Changelog/#11-2017-03-16","title":"1.1 (2017-03-16)","text":""},{"location":"Changelog/#10-2016-09-09","title":"1.0 (2016-09-09)","text":""},{"location":"Changelog/#020-2016-06-10","title":"0.20 (2016-06-10)","text":""},{"location":"Changelog/#0190-2016-05-25","title":"0.19.0 (2016-05-25)","text":""},{"location":"Changelog/#0180-2015-05-29","title":"0.18.0 (2015-05-29)","text":""},{"location":"Changelog/#0170-2015-05-14","title":"0.17.0 (2015-05-14)","text":""},{"location":"Changelog/#0160-2015-05-07","title":"0.16.0 (2015-05-07)","text":""},{"location":"Changelog/#0150-2015-04-14","title":"0.15.0 (2015-04-14)","text":""},{"location":"Changelog/#0140-2015-03-28","title":"0.14.0 (2015-03-28)","text":""},{"location":"Changelog/#0130-2014-12-05","title":"0.13.0 (2014-12-05)","text":""},{"location":"Changelog/#0121-2014-11-17","title":"0.12.1 (2014-11-17)","text":""},{"location":"Changelog/#0120-2014-11-11","title":"0.12.0 (2014-11-11)","text":""},{"location":"Changelog/#0110-2014-03-24","title":"0.11.0 (2014-03-24)","text":""},{"location":"Changelog/#0100-2014-03-18","title":"0.10.0 (2014-03-18)","text":"

    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.

    "},{"location":"Changelog/#070-2012-04-29","title":"0.7.0 (2012-04-29)","text":""},{"location":"Changelog/#060-2012-04-25","title":"0.6.0 (2012-04-25)","text":""},{"location":"Changelog/#054-2012-04-06","title":"0.5.4 (2012-04-06)","text":""},{"location":"Changelog/#053-2012-03-23","title":"0.5.3 (2012-03-23)","text":""},{"location":"Changelog/#052-2012-03-20","title":"0.5.2 (2012-03-20)","text":""},{"location":"Changelog/#051-2012-03-16","title":"0.5.1 (2012-03-16)","text":""},{"location":"Changelog/#050-2012-03-09","title":"0.5.0 (2012-03-09)","text":""},{"location":"Changelog/#044-2012-02-06","title":"0.4.4 (2012-02-06)","text":"

    Release in anticipation of upcoming merges.

    "},{"location":"Configuration/","title":"Introduction","text":""},{"location":"Configuration/#configuring-opentripplanner","title":"Configuring OpenTripPlanner","text":""},{"location":"Configuration/#base-directory","title":"Base Directory","text":"

    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:

    otp-config.json\nbuild-config.json\nrouter-config.json\nnew-york-city-no-buildings.osm.pbf\nnyc-elevation.tiff\nlong-island-rail-road.gtfs.zip\nmta-new-york-city-transit.gtfs.zip\nport-authority-of-new-york-new-jersey.gtfs.zip\ngraph.obj\n

    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 for further details.

    "},{"location":"Configuration/#three-scopes-of-configuration","title":"Three Scopes of Configuration","text":"

    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.

    "},{"location":"Configuration/#configuration-types","title":"Configuration types","text":"

    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 boolean This is the Boolean JSON type true, false string This is the String JSON type. \"This is a string!\" double A decimal floating point number. 64 bit. 3.15 integer A decimal integer number. 32 bit. 1, -7, 2100 long A decimal integer number. 64 bit. -1234567890 enum A fixed set of string literals. \"RAIL\", \"BUS\" enum-map List of key/value pairs, where the key is a enum and the value can be any given type. { \"RAIL: 1.2, \"BUS\": 2.3 } enum-set List of enum string values [ \"RAIL\", \"TRAM\" ] locale Language[\\_country[\\_variant]]. A Locale object represents a specific geographical, political, or cultural region. For more information see the Java Locale. \"en_US\", \"nn_NO\" date Local date. The format is YYYY-MM-DD (ISO-8601). \"2020-09-21\" date-or-period A local date, or a period relative to today. The local date has the format YYYY-MM-DD and the period has the format PnYnMnD or -PnYnMnD where n is a integer number. \"P1Y\", \"-P3M2D\", \"P1D\" duration A duration is a amount of time. The format is PnDTnHnMnS or nDnHnMnS where n is a integer number. The D(days), H(hours), M(minutes) and S(seconds) are not case sensitive. \"3h\", \"2m\", \"1d5h2m3s\", \"-P2dT-1s\" regexp A regular expression pattern used to match a sting. \"$^\", \"gtfs\", \"\\w{3})-.*\\.xml\" uri An URI path to a resource like a file or a URL. Relative URIs are resolved relative to the OTP base path. \"http://foo.bar/\", \"file:///Users/jon/local/file\", \"graph.obj\" time-zone Time-Zone ID \"UTC\", \"Europe/Paris\", \"-05:00\" feed-scoped-id FeedScopedId \"NO:1001\", \"1:101\" cost-linear-function A cost-linear-function used to calculate a cost from another cost or time/duration. Given a function of time: f(t) = a + b * t then a is the constant time part, b is the time-coefficient, and t is the variable. If a=0s and b=0.0, then the cost is always 0(zero). Examples: 0s + 2.5t, 10m + 0t and 1h5m59s + 9.9t The constant must be 0 or a positive number or duration. The unit is seconds unless specified using the duration format. A duration is automatically converted to a cost. The coefficient must be in range: [0.0, 100.0] time-penalty A time-penalty is used to add a penalty to the duration/arrival-time/departure-time for a path. It will be invisible to the end user, but used during the routing when comparing stop-arrival/paths. Given a function of time: f(t) = a + b * t then a is the constant time part, b is the time-coefficient, and t is the variable. If a=0s and b=0.0, then the cost is always 0(zero). Examples: 0s + 2.5t, 10m + 0 x and 1h5m59s + 9.9t The constant must be 0 or a positive number(seconds) or a duration. The coefficient must be in range: [0.0, 100.0] map List of key/value pairs, where the key is a string and the value can be any given type. { \"one\": 1.2, \"two\": 2.3 } object Config object containing nested elements \"walk\": { \"speed\": 1.3, \"reluctance\": 5 } array Config object containing an array/list of elements \"array\": [ 1, 2, 3 ]"},{"location":"Configuration/#system-environment-and-project-information-substitution","title":"System environment and project information substitution","text":"

    OTP supports 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 are 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.

    {\n    \"gsCredentials\": \"${GCS_SERVICE_CREDENTIALS}\",\n    \"graph\": \"file:///var/otp/graph-${otp.serialization.version.id}.obj\"\n}\n

    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:

    "},{"location":"Configuration/#config-version","title":"Config version","text":"

    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 pipeline 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-pipeline, at deployment time or use system environment variable substitution.

    "},{"location":"Configuration/#otp-serialization-version-id-and-graphobj-file-header","title":"OTP Serialization version id and Graph.obj file header","text":"

    OTP has a OTP Serialization Version Id maintained in the pom.xml_ file. OTP stores the id in the serialized Graph.obj file header, allowing OTP to check for compatibility issues when loading the graph. The header info is available to configuration substitution:

    The intended usage is to be able to have a graph build pipeline that \"knows\" the matching graph and OTP planner instance. For example, you may build new graphs for every OTP serialization version id in use by the planning OTP instances you have deployed and plan to deploy. This way you can roll forward and backward new OTP instances without worrying 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:

    The Maven pom.xml, the META-INF/MANIFEST.MF, the OTP command line(--serializationVersionId), log start-up messages and all OTP APIs can be used to get the OTP Serialization Version Id.

    "},{"location":"Configuration/#include-file-directive","title":"Include file directive","text":"

    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 text inserted is valid JSON (starts with { and ends with }).

    Variable substitution is performed on configuration file after the include file directive; Hence variable substitution is also performed on the text in the injected file.

    Here is an example including variable substitution, assuming version 2.6.0 of OTP:

    // build-config.json\n{\n  \"transitFeeds\" : \"${includeFile:transit.json}\"\n} \n
    // transit.json\n[\n  {\n  \"source\": \"netex-v${maven.version.short}.obj\"\n}\n]\n

    The result will look like this:

    {\n      \"transitFeeds\": [\n        {\n          \"source\": \"netex-v2.6.0.obj\"\n        }\n      ]\n} \n
    "},{"location":"Configuration/#system-wide-configuration","title":"System-wide Configuration","text":"

    Using the file otp-config.json you can enable or disable different APIs and experimental Sandbox Extensions. 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.

    "},{"location":"Configuration/#otp-features","title":"OTP Features","text":"

    Here is a list of all features which can be toggled on/off and their default values.

    Feature Description Enabled by default Sandbox APIBikeRental Enable the bike rental endpoint. \u2713\ufe0f APIServerInfo Enable the server info endpoint. \u2713\ufe0f APIUpdaterStatus Enable endpoint for graph updaters status. \u2713\ufe0f ConsiderPatternsForDirectTransfers Enable limiting transfers so that there is only a single transfer to each pattern. \u2713\ufe0f DebugUi Enable the debug GraphQL client and web UI and located at the root of the web server as well as the debug map tiles it uses. Be aware that the map tiles are not a stable API and can change without notice. Use the vector tiles feature if you want a stable map tiles API. \u2713\ufe0f ExtraTransferLegOnSameStop Should there be a transfer leg when transferring on the very same stop. Note that for in-seat/interlined transfers no transfer leg will be generated. FloatingBike Enable floating bike routing. \u2713\ufe0f GtfsGraphQlApi Enable the GTFS GraphQL API. \u2713\ufe0f GtfsGraphQlApiRentalStationFuzzyMatching Does vehicleRentalStation query also allow ids that are not feed scoped. MinimumTransferTimeIsDefinitive If the minimum transfer time is a lower bound (default) or the definitive time for the transfer. Set this to true if you want to set a transfer time lower than what OTP derives from OSM data. OptimizeTransfers OTP will inspect all itineraries found and optimize where (which stops) the transfer will happen. Waiting time, priority and guaranteed transfers are taken into account. \u2713\ufe0f ParallelRouting Enable performing parts of the trip planning in parallel. TransferConstraints Enforce transfers to happen according to the transfers.txt (GTFS) and Interchanges (NeTEx). Turning this off will increase the routing performance a little. \u2713\ufe0f TransmodelGraphQlApi Enable the Transmodel (NeTEx) GraphQL API. \u2713\ufe0f \u2713\ufe0f ActuatorAPI Endpoint for actuators (service health status). \u2713\ufe0f AsyncGraphQLFetchers Whether the @async annotation in the GraphQL schema should lead to the fetch being executed asynchronously. This allows batch or alias queries to run in parallel at the cost of consuming extra threads. Co2Emissions Enable the emissions sandbox module. \u2713\ufe0f DataOverlay Enable usage of data overlay when calculating costs for the street network. \u2713\ufe0f FaresV2 Enable import of GTFS-Fares v2 data. \u2713\ufe0f FlexRouting Enable FLEX routing. \u2713\ufe0f GoogleCloudStorage Enable Google Cloud Storage integration. \u2713\ufe0f LegacyRestApi Enable legacy REST API. This API will be removed in the future. \u2713\ufe0f MultiCriteriaGroupMaxFilter Keep the best itinerary with respect to each criteria used in the transit-routing search. For example the itinerary with the lowest cost, fewest transfers, and each unique transit-group (transit-group-priority) is kept, even if the max-limit is exceeded. This is turned off by default for now, until this feature is well tested. RealtimeResolver When routing with ignoreRealtimeUpdates=true, add an extra step which populates results with real-time data \u2713\ufe0f ReportApi Enable the report API. \u2713\ufe0f RestAPIPassInDefaultConfigAsJson Enable a default RouteRequest to be passed in as JSON on the REST API - FOR DEBUGGING ONLY! SandboxAPIGeocoder Enable the Geocoder API. \u2713\ufe0f SandboxAPIMapboxVectorTilesApi Enable Mapbox vector tiles API. \u2713\ufe0f SandboxAPIParkAndRideApi Enable park-and-ride endpoint. \u2713\ufe0f Sorlandsbanen Include train S\u00f8rlandsbanen in results when searching in south of Norway. Only relevant in Norway. \u2713\ufe0f TransferAnalyzer Analyze transfers during graph build. \u2713\ufe0f

    Example

    // otp-config.json\n{\n    \"otpFeatures\" : {\n        \"APIBikeRental\" : false,\n        \"ActuatorAPI\" : true\n    }\n}\n
    "},{"location":"Configuration/#jvm-configuration","title":"JVM configuration","text":"

    This section contains general recommendations for tuning the JVM in a production environment. It focuses mainly on garbage collection configuration and memory settings. See Garbage Collector Tuning for general information on garbage collection. See Large Pages in Java and Transparent Huge Pages for general information on large memory pages.

    "},{"location":"Configuration/#otp-server","title":"OTP server","text":"

    The OTP server processes concurrent routing requests in real time. The main optimization goal for the OTP server is minimizing response time.

    "},{"location":"Configuration/#garbage-collector","title":"Garbage collector","text":""},{"location":"Configuration/#memory-settings","title":"Memory settings","text":""},{"location":"Configuration/#graph-builder","title":"Graph Builder","text":"

    The Graph Builder is the non-interactive mode used to build street graphs and transit graphs. The main optimization goal for the Graph Builder is minimizing total build time.

    "},{"location":"Configuration/#garbage-collector_1","title":"Garbage collector","text":""},{"location":"Configuration/#memory-settings_1","title":"Memory settings","text":""},{"location":"Container-Image/","title":"Container image","text":"

    The CI pipeline deploys container images for runtimes like Docker, Kubernetes or Podman to Dockerhub.

    The image assumes you use a volume to mount the input data (GTFS/NeTex, OSM) and config files into /var/opentripplanner/. When serving a graph it's also expected to be in this directory. If a logback extensions file needs to be used, it should be mounted to the root location /logback-include-extensions.xml instead of the /var/opentripplanner/ directory.

    "},{"location":"Container-Image/#quick-start","title":"Quick start","text":"

    Let's use the image to build a graph in Berlin.

    # create directory for data and config\nmkdir berlin\n# download OSM\ncurl -L https://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf -o berlin/osm.pbf  \n# download GTFS\ncurl -L https://vbb.de/vbbgtfs -o berlin/vbb-gtfs.zip\n# build graph and save it onto the host system via the volume\ndocker run --rm \\\n    -e JAVA_TOOL_OPTIONS='-Xmx8g' \\\n    -v \"$(pwd)/berlin:/var/opentripplanner\" \\\n    docker.io/opentripplanner/opentripplanner:latest --build --save\n# load and serve graph\ndocker run -it --rm -p 8080:8080 \\\n    -e JAVA_TOOL_OPTIONS='-Xmx8g' \\\n    -v \"$(pwd)/berlin:/var/opentripplanner\" \\\n    docker.io/opentripplanner/opentripplanner:latest --load --serve\n

    Now open http://localhost:8080 to see your running OTP instance.

    "},{"location":"Container-Image/#additional-notes","title":"Additional notes","text":"

    Make sure to include the word \"gtfs\" when naming the gtfs files that you want to use for OTP. Otherwise, graph build will fail.

    If you want to set JVM options you can use the environment variable JAVA_TOOL_OPTIONS, so a full example to add to your docker command is -e JAVA_TOOL_OPTIONS='-Xmx4g'.

    "},{"location":"Data-Sources/","title":"Data Sources","text":""},{"location":"Data-Sources/#input-formats","title":"Input Formats","text":"

    At the core of OpenTripPlanner is a library of Java code that finds efficient paths through multi-modal transportation networks built from OpenStreetMap, GTFS/GTFS RT and GBFS.

    In addition to GTFS, OTP 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 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.

    "},{"location":"Deployments/","title":"OpenTripPlanner Deployments Worldwide","text":""},{"location":"Deployments/#official-production","title":"Official Production","text":"

    The following are known deployments of OTP in a government- or agency-sponsored production capacity:

    "},{"location":"Deployments/#independent-production","title":"Independent Production","text":"

    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.

    "},{"location":"Developers-Guide/","title":"Developers Guide","text":""},{"location":"Developers-Guide/#quick-setup","title":"Quick setup","text":"

    A Quick guide to setting up the OpenTripPlanner project.

    You need Git, Maven and Java(JDK) and an IDE installed on your computer. Your 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
    3. Run mvn package- this will download all dependencies, build the project and run tests.
    4. Open the project in your IDE.
    "},{"location":"Developers-Guide/#working-on-otp-in-an-ide","title":"Working on OTP in an IDE","text":"

    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, Eclipse, and NetBeans. 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 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.

    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 and configuration reference). 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\".

    "},{"location":"Developers-Guide/#contributing-to-the-project","title":"Contributing to the project","text":"

    OpenTripPlanner is a community based open source project, and we welcome all who wish to contribute. There are several ways to get involved:

    "},{"location":"Developers-Guide/#branches-and-branch-protection","title":"Branches and Branch Protection","text":"

    As of August 2022, we work on OTP 2.x and are using a Git branching model derived from Gitflow. All development will occur on the dev-2.x branch. 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-2.x branch. In turn, all changes to dev-2.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 developers part of the OTP Review Team. These developers act on behalf of the leadership committee members. The reviewers should be 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-1.x exist for patching OTP version 1.x, but with few people to do the reviews, very few PRs are accepted. We recommend getting in touch with the community before you spend time on making a PR.

    "},{"location":"Developers-Guide/#issues","title":"Issues","text":"

    If no ticket exists for the feature or bug your code implements or fixes, you should create a new ticket 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). The created issue should be referenced in a pull request. For really minor and uncontroversial pull requests, it is ok to not create an issue.

    "},{"location":"Developers-Guide/#unit-tests-using-real-osm-data","title":"Unit tests using real OSM data","text":"

    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

    "},{"location":"Developers-Guide/#itinerary-and-api-snapshot-tests","title":"Itinerary and API Snapshot Tests","text":"

    To test the itinerary generation, and the API there are snapshot test which save the result of the requests as *.snap JSON-like files. These are stored in git so that it is possible to compare to the expected result when running the tests.

    If the snapshots need to be recreated than running mvn clean -Pclean-test-snapshots will remove the existing *.snap files so that the next time the tests are run the snapshots will be recreated. The updated files may be committed after checking that the changes in the files are expected.

    "},{"location":"Developers-Guide/#documentation","title":"Documentation","text":"

    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 /doc/user directory under the root of the project. On every push to the dev-2.x branch the documentation will be rebuilt and deployed as static pages to our subdomain of Github Pages. 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 writing it.

    In short:

    $ pip install -r doc/user/requirements.txt\n$ mkdocs serve\n

    The OTP GTFS GraphQL API documentation is available online at

    https://docs.opentripplanner.org/api/dev-2.x/graphql-gtfs/

    You can also use the interactive GraphQL API client that is built into every instance at

    http://localhost:8080/graphiql

    "},{"location":"Developers-Guide/#debug-layers","title":"Debug layers","text":"

    Adding new renderer is very easy. You just need to create new class (preferably in org.opentripplanner.inspector package) which implements EdgeVertexRenderer. It is best if class name ends with Rendered. To implement this interface you need to write three functions renderEdge, renderVertex and getName. Both render functions accepts EdgeVisualAttributes object in which label of edge/vertex and color can be set. And both return true if edge/vertex should be rendered 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.

    After your class is written you only need to add it to TileRenderManager:

    //This is how Wheelchair renderer is added\nrenderers.put(\"wheelchair\", new EdgeVertexTileRenderer(new WheelchairEdgeRenderer()));\n

    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:

    //This lines\nCacheControl cc = new CacheControl();\ncc.setMaxAge(3600);\ncc.setNoCache(false);\n\n//to this:\nCacheControl cc = new CacheControl();\ncc.setNoCache(true);\n
    "},{"location":"Developers-Guide/#date-format","title":"Date format","text":"

    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.

    "},{"location":"Developers-Guide/#code-conventions-and-architecture","title":"Code conventions and architecture","text":"

    The development and architecture documentation are only available on GitHub, not in the user project documentation (https://www.opentripplanner.org/). These documents contain relative links to code, so they are a bit easier to maintain that way. The primary audience is also active OTP developers that have the code checked out locally.

    "},{"location":"Developers-Guide/#continuous-integration","title":"Continuous Integration","text":"

    The OpenTripPlanner project uses the Github actions continuous integration system . Any time a change is pushed to the main OpenTripPlanner repository on GitHub or to an open pull request, Github actions will compile and test the new code, providing feedback on the stability of the build.

    "},{"location":"Developers-Guide/#changelog-workflow","title":"Changelog workflow","text":"

    The changelog file is generated from the pull-request(PR) title using the changelog workflow . 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 the label skip changelog to the PR.

    "},{"location":"Developers-Guide/#how-to-update-the-changelog_token","title":"How-to update the CHANGELOG_TOKEN","text":"

    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):

    "},{"location":"Developers-Guide/#release-process","title":"Release Process","text":"

    New releases can be found on GitHub. 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 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 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 these steps manually by following the checklist. We aim to make a release every 6 months.

    Use the Release Checklist to perform the release.

    "},{"location":"Frontends/","title":"Frontends (User Interfaces) for OpenTripPlanner","text":""},{"location":"Frontends/#introduction","title":"Introduction","text":"

    OpenTripPlanner is a client-server system. A backend service written in Java is accessed over an API by some client software, which is generally embedded in a web page or a mobile app. When OpenTripPlanner developers refer to OpenTripPlanner or OTP, they often specifically mean the Java backend service. But for this service to be useful to end users who want to plan their journeys, you will typically also want to deploy a user interface as well as a few other components providing mapping capabilities and address lookup functionality.

    For the purposes of this document and in many OpenTripPlanner development discussions, the terms frontend, UI, and client will be used interchangeably. In reality many kinds of clients are possible, not all of them being user interfaces (UIs). The OpenTripPlanner API may be called by various scripts and microservices, potentially all within what would traditionally be called a \"backend\" with no user interface at all. For example, updates to trip plans could be requested, summarized and sent as text messages over a mobile network. But in this documentation page, we are exclusively talking about graphical user interfaces, usually written in Javascript for execution and display in web browsers.

    "},{"location":"Frontends/#two-kinds-of-frontends","title":"Two Kinds of Frontends","text":"

    Broadly speaking there are two kinds of frontends for OTP: debug frontends and production frontends.

    Debug frontends are included in the main OpenTripPlanner repository, and are intended to work \"out of the box\" with little to no configuration. They are served by OTP itself or a simple local web server, or set up such that a single deployment is usable by anyone via a content delivery network (CDN). The primary purpose of debug frontends is to allow OTP developers (as well as people evaluating OpenTripPlanner for their organization) to observe, test, and debug an OTP instance they're working on. Debug frontends will expose some internal details of OTP operation such as graph nodes and edges, traversal permissions, or transit data entity identifiers. Their primary role is as a development and deployment tool.

    On the other hand, production frontends are intended to be a component of larger public-facing deployments of OTP, with a more polished appearance and user experience. They generally do not work \"out of the box\", and require a significant amount of configuration and coordination with external components such as map tile servers and geocoders. They are designed to be components of a large professionally maintained and managed OTP deployment, and present a simpler view of OpenTripPlanner options and results to a non-technical audience of end users.

    "},{"location":"Frontends/#debug-frontends","title":"Debug Frontends","text":"

    The main OpenTripPlanner repository currently contains two debug web frontends:

    The new debug client is a React/TypeScript Single Page App (SPA) that can be served locally or accessed over a content delivery network (CDN). Unlike the original debug client, it connects to the OTP Java backend via the GraphQL API using the Transmodel vocabulary. By default, it is available at the root URL (http://localhost:8080/ in local operation).

    The classic debug client is a jQuery and Backbone based UI whose history can be traced back over a decade to the first days of the OTP project. It connects to the OTP Java backend via a REST API using the GTFS vocabulary. Historically this was the default OTP interface available at the root URL. It is still available, but has been moved to http://localhost:8080/classic-debug/ .

    There is a third piece of software that might qualify as an OTP client: a Java Swing application making use of the Processing visualization library, located in the GraphVisualizer class. While it would not be accurate to call this a \"native\" desktop application (as it's cross-platform Java) it is not a web app. This very developer-centric UI is also over a decade old and has been very sparsely maintained, but continues to exist because it can visualize the progress of searches through the street network, providing some insight into the internals of the routing algorithms that are not otherwise visible.

    "},{"location":"Frontends/#working-with-debug-frontends","title":"Working with Debug Frontends","text":"

    While the two debug frontends are enabled by default as of this writing, they may not be in the future, and you may wish to disable them if you've chosen to use a different frontend. Also, to get full use of the existing debug frontends you may want to enable OTP's built-in simple testing geocoder which performs fuzzy searches for transit stops by name, supplying their coordinates to the routing engine. Without it, you will be limited to origins and destinations selected on a map or specified in terms of latitude and longitude coordinates. The debug frontend and the geocoder can be toggled in otp-config.json:

    // otp-config.json\n{\n  \"otpFeatures\": {\n    \"DebugUi\": true,\n    \"SandboxAPIGeocoder\": true\n  }\n}\n
    "},{"location":"Frontends/#production-frontends","title":"Production Frontends","text":"

    Many different production OTP frontends exist. Any number of agencies and consultancies may have built new frontends, whether in Javascript or as native mobile apps, without the OpenTripPlanner development team even being aware of them.

    That said, there are two main Javascript-based web user interfaces that are generally recommended by members of the OTP development team who also work on professional, public-facing OpenTripPlanner deployments:

    Digitransit is an open-source public transportation project, originally created in Finland to replace existing nationwide and regional journey planning solutions in 2014. Digitransit has since been used around the world in other projects, for example in Germany. It is a joint project of Helsinki Regional Transport Authority (HSL), Fintraffic, and Waltti Solutions.

    Arcadis IBI has for several years actively developed, deployed, and maintained instances of the React-based OTP UI, systematically contributing their improvements back to the original repositories under the OpenTripPlanner organization:

    Both major frontend projects mentioned above support internationalization and have several translations already available.

    "},{"location":"Frontends/#deploying-a-production-frontend","title":"Deploying a Production Frontend","text":"

    Deploying a full OpenTripPlanner-based system including a web UI can be quite complex, as there are many \"moving parts\". Such a system needs to remain responsive and function smoothly under load that varies wildly from one time of day to another, constantly refresh input data, and meet customer expectations in recognizing addresses and names of landmarks etc. Because deployment and management of such a system demands long term commitment by a professional team with sufficient experience and knowledge about the component parts, the major production frontend projects do not really aim to work \"out of the box\". There's a working assumption that they'll be actively customized for any large regional deployment.

    Unfortunately this creates a bit of a barrier for organizations evaluating such components. Please don't hesitate to join the OpenTripPlanner Gitter chat and ask if you need any information on this subject. Several organizations that manage multiple large OTP deployments are active there and will be happy to engage with you.

    While you are welcome to stand up an instance of one of these UIs for testing or evaluation, and there has been some effort to make this more straightforward especially on the Arcadis IBI projects, it is still strongly recommended to collaborate with a specialist. The process of tailoring a deployment to a specific region and deployment environment is estimated to take at least several full days even for an experienced professional, and while it may start off looking deceptively simple, can rapidly grow into a seemingly never-ending project for those who are not aware of the pitfalls. The goal here is not by any means to discourage you from using or learning about any of these projects, but to set expectations that the process will be much smoother if you work with someone who's done it before. Be aware that both of these systems rely on multiple additional backend services other than the OTP Java backend. To get either one working, you will need to configure a source of map tiles and a geocoder that translates geographic names to latitude and longitude coordinates, among other components.

    That said, as of this writing (early 2024) it may now be possible to get a minimal, non-production test deployment of OTP-React-Redux working with only a few adjustments to the example configuration file. See the README and example-config.yml in the OTP-RR repo.

    "},{"location":"Frontends/#historical-background","title":"Historical Background","text":"

    The history of the more widely used OpenTripPlanner interfaces is roughly as follows:

    "},{"location":"Getting-OTP/","title":"Getting OpenTripPlanner","text":""},{"location":"Getting-OTP/#pre-built-jars","title":"Pre-built JARs","text":"

    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 or the OTP directory at Maven Central, 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.6.0-SNAPSHOT refer to development builds _ before_ the release version v2.6.0. The existence of a build vX.Y.Z-SNAPSHOT does not mean that vX.Y.Z has been released yet.

    We use the Github Actions CI system to build OTP every time a change is made. You can find the JARs resulting from those builds in the Github Packages repository . 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.

    "},{"location":"Getting-OTP/#building-from-source","title":"Building from Source","text":"

    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 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:

    mkdir git\ncd git\ngit clone git@github.com:opentripplanner/OpenTripPlanner.git\n

    Then change to the newly cloned OpenTripPlanner repository directory and start a build:

    cd OpenTripPlanner\nmvn clean package\n

    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] ------------------------------------------------------------------------\n[INFO] BUILD SUCCESS\n[INFO] ------------------------------------------------------------------------\n[INFO] Total time: 42.164s\n[INFO] Finished at: Tue Feb 18 19:35:48 CET 2014\n[INFO] Final Memory: 88M/695M\n[INFO] ------------------------------------------------------------------------\n

    This build process should produce a JAR file called otp-x.y.z-shaded.jar in the application/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:

    cd OpenTripPlanner\ngit checkout v2.6.0\ngit clean -df\nmvn clean package -DskipTests\n

    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.

    "},{"location":"Getting-OTP/#maven-repository","title":"Maven Repository","text":"

    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.6.0 will be found at https://repo1.maven.org/maven2/org/opentripplanner/otp/2.6.0/otp-2.6.0-shaded.jar.

    To make use of OTP in another Maven project, you must specify it as a dependency in that project's pom.xml:

    <dependency>\n  <groupId>org.opentripplanner</groupId>\n  <artifactId>otp</artifactId>\n  <version>2.6.0</version>\n</dependency>\n
    "},{"location":"Governance/","title":"Project Governance","text":"

    OpenTripPlanner is a member project of the Software Freedom Conservancy. 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 Sean Barbeau University of South Florida Sheldon Brown Cambridge Systematics Andrew Byrd Conveyal Thomas Craig CALACT ITS4US Drew Dara-Abrams Interline David Emory IBI Group Thomas Gran Entur (Norway) Tuukka Hastrup Transpordiamet (Estonia) Joel Lappalainan Digitransit (Finland) Frank Purcell TriMet (Portland, Oregon) David Turner ex-OpenPlans Anders Varmy Skanetrafiken Leonard Ehrenfried Independent contractor

    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 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

    "},{"location":"History/","title":"OpenTripPlanner Project History","text":""},{"location":"History/#opentripplanner-1","title":"OpenTripPlanner 1","text":"

    OpenTripPlanner was seeded by Portland, Oregon's transit agency TriMet with a Regional Travel Options grant and opened with a 3-day 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, and Brandon Martin-Anderson of Graphserver. From 2009 through 2012, development was coordinated by New York nonprofit OpenPlans. In 2011 a second workshop was held to mark the end of the first phase of development. TriMet's 2009-2011 OTP Final Report 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 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. 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.

    In summer of 2013, the OpenTripPlanner project was accepted for membership in the Software Freedom Conservancy (SFC). 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 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), 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.

    "},{"location":"History/#opentripplanner-2","title":"OpenTripPlanner 2","text":"

    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 . 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. 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 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 and the October 2019 OTP webinar 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.

    "},{"location":"In-Station-Navigation/","title":"In-station navigation","text":"

    OTP offers a variety of ways to produce precise walking instructions for walking inside a station or between transit stops.

    "},{"location":"In-Station-Navigation/#osm-generated-navigation","title":"OSM generated navigation","text":"

    In the most common case, the walking instructions for reaching a transit stop are generated from the available OSM data. For this reason it is important that the coordinate of the stop is as close as possible to where the passenger is expected to wait for the vehicle, not where the vehicle will stop.

    It is therefore a good idea to place the stop coordinates at a bus shelter or railway platform rather than at the middle of the road or the railway tracks.

    Of course you also want the data in OSM as precise as possible: data for railway platforms, stairs, tunnels and other infrastructure help OTP to generate good walking instructions.

    "},{"location":"In-Station-Navigation/#example-exiting-a-railway-platform","title":"Example: exiting a railway platform","text":"

    The train arrives in a railway station in Stuttgart (green line), the passenger alights and is instructed (grey line) to walk along the platform, up the stairs and across a bridge to continue to their final destination.

    "},{"location":"In-Station-Navigation/#boarding-locations","title":"Boarding locations","text":"

    If your stop coordinates are not very well-placed, OTP may direct passengers to the wrong waiting location or offer incorrect transfer paths and time. As this a common problem and stop coordinates can be hard to change due to upstream systems, OTP offers a way to derive the waiting coordinates from OSM data.

    Even if your stop coordinates are good, some stations are underground and to get correct walking instructions it's required to use this feature so that correct instructions for using entrances and stairs are generated.

    "},{"location":"In-Station-Navigation/#example-walking-downstairs-to-underground-stations","title":"Example: walking downstairs to underground stations","text":"

    This shows an underground subway station in Stuttgart which can only be reached by using entrances at either end walking down to the platform via a series of stairs and walkways. OTP can only generate these detailed instructions because the platform has a tag ref:IFOPT which identifies it in the German national stop register.

    "},{"location":"In-Station-Navigation/#gtfs-pathways","title":"GTFS pathways","text":"

    If your GTFS input file contains pathways this will override the OSM-generated instructions. It is therefore important that the pathways contain as much precision as possible.

    One advantage that pathways offer is the possibility to add information like \"follow signs for X\" which OTP adds to the textual turn-by-turn instructions.

    "},{"location":"In-Station-Navigation/#example-transferring-at-sudkreuz","title":"Example: Transferring at S\u00fcdkreuz","text":"

    Here the pathways don't offer a lot of precision: In a railway hub in Berlin there are suboptimal instructions on how to move from one platform to another because the pathways only contain rudimentary information about how to move inside the station. (The red lines represent train lines with the grey line showing the walking path.)

    "},{"location":"In-Station-Navigation/#transfers","title":"Transfers","text":"

    The above precedence rules of

    also apply when computing transfers from one stop to another.

    "},{"location":"In-Station-Navigation/#example-transferring-from-tram-to-rail-at-oslo-central","title":"Example: transferring from tram to rail at Oslo Central","text":"

    Here the passenger arrives in a local tram (blue line) near the main station in Oslo. They are instructed (grey line) to walk into the station right onto the correct platform and leave on a long-distance train (red line).

    "},{"location":"In-Station-Navigation/#example-transferring-between-platforms-at-oslo-central","title":"Example: transferring between platforms at Oslo Central","text":"

    This example instructs the passenger to get off a train, then walking down the stairs and via a tunnel to another platform.

    "},{"location":"In-Station-Navigation/#transfer-time","title":"Transfer time","text":"

    The routing engine calculates the time to move from one stop to another by how long it thinks the walking takes based on the navigation instructions outlined above. So, if OTP thinks that it takes 5 minutes to walk from platform 1 to platform 8, then the routing algorithm will not suggest a transit connection that departs less than 5 minutes after arriving at platform 1.

    However, how fast the passenger is assumed to walk is controllable through the walk speed parameter. This can be configured per installation or passed as an API call parameter.

    The parameters alightSlack, transferSlack and boardSlack also allow you to define extra buffer time for transferring.

    GTFS minimum transfer times are also supported but generally not advised. It is preferable to micromap your stations and improve the stop coordinates rather than force specific transfer times by adding this data.

    "},{"location":"In-Station-Navigation/#common-data-errors","title":"Common data errors","text":""},{"location":"IslandPruning/","title":"Street graph pruning","text":"

    A street graph created from OpenStreetMap data has sections which cannot be reached with some or all traverse modes. For example, true geographic islands are usually disconnected from the main graph. The street network of such islands should be kept so that routing within the island or continuing from a ferry stop on it works as expected. Even a tiny street network connected to a ferry stop improves routing to an island a lot, because coordinate based itinerary searches find something to project onto.

    Removing a small subgraph from an island causes poor routing. A ferry stop on the island links directly to mainland.

    Disconnected parts can also represent a strictly forbidden area, such as connections within an industrial unit, roads of a military base or another region which cannot and should not be accessed when using door to door routing of a public transit journey planner. Existence of such graph sections is harmful, because start and end points of an itinerary search request may accidentally get projected to such a private pathway. As a result, a user does not receive any itineraries and gets no explanation for the routing problem.

    In most cases, connectivity problems are caused by incorrect modeling of OSM data. The number of such errors is usually very large, and the problem cannot be solved by simply fixing OSM data as soon as errors are detected - the OSM street network in Finland contains over 10 000 detected walk connectivity issues! An algorithmic solution is needed to address a problem of such magnitude.

    A typical error: bus platforms are not connected to the street network at all

    A simple and efficient solution is to detect harmful disconnected parts and remove them from the street graph. Routing then uses the properly connected part of the graph and finds itineraries. As a side effect, the start point of an itinerary search which departs from the removed graph projects at the border of it, which usually is good enough. Transfers may include strange teleportation and unexpected walking, as public transit stops may link to somewhat remote streets, but at least transfers will work.

    A disconnected railway platform breaks routing. Traveler is guided to take a round trip around the country although there is one hour direct train connection.

    "},{"location":"IslandPruning/#access-restriction-islands","title":"Access restriction islands","text":"

    One common reason for OSM connectivity problems is access tagging. It is perfectly OK to tag a front yard of a private residence using access=private or access=destination tags, so that strangers are not guided to travel through the private area. Routing will still use the private streets if a trip starts or ends there - only pass through traversal gets prohibited. However, sometimes OSM contributors try to block the traffic by tagging only entrance segments of streets leading to a restricted area. Unfortunately this totally prevents access to the interior part of the network, because OTP interprets it as pass through traffic. Pruning handles such problems by converting streets behind an access restriction to have the same access properties.

    Some regular (gray colored) streets are blocked behind access restricted (red colored) connections. Walk routing to them fails because it would be considered as pass through traffic. The image on the right shows that pruning added walk nothrough restriction to those streets, and routing works again.

    "},{"location":"IslandPruning/#pruning-algorithm","title":"Pruning algorithm","text":"

    Pruning analyses the three traverse modes - walk, bike and car - separately. For example, a resting area by a motorway may include some walking paths, but the only way to get there is to use a car. Therefore, it represents a disconnected 'island' when considering the walk mode. Pruning does not erase disconnected graph geometry as long as it can be reached using any of the traverse modes. Instead, pruning removes traversal permission for each disconnected mode from the island.

    Pruning uses four parameters and some heuristics to decide if a disconnected sub graph is a real island to be retained, or a harmful data error:

    Pruning thresholds are increased adaptively so that if the distance between an examined sub graph and the other graph is zero, the threshold is multiplied by a full adaptivePruningFactor value. The idea is that if a sub graph is closely entangled with another graph, it is likely to be a harmful modeling error, not a remote place like a true geographic island. If the distance is more than adaptivePruningDistance, the actual nominal threshold values will be used. So, adaptiveness prunes much larger disconnected graphs in places where they have potential to cause routing errors.

    Adaptive pruning can be disabled by setting adaptivePruningFactor to 1. Constant pruning thresholds will then be applied.

    Pruning also examines the transport modes of graph islands with stops. If land transportation modes are not found (only ferry or no modes at all), the graph is retained. Unknown mode is accepted for island status, because ferry lines often operate only during warm seasons.

    "},{"location":"IslandPruning/#some-examples","title":"Some examples","text":"

    A disconnected small graph should be preserved, if it is located on a real island.

    A street section has tags which prevent traversal on it, and OTP has removed it from the graph. Some isolated streets remain left, and a public transit stop gets linked to them. Routing cannot use the stop unless traveler is leaving from or going to the small isolated sub graph. Isolated streets cannot be reached by walking either. After pruning, the stop is projected to the main graph. Transfers at the stop work fine. Itineraries can guide traveler quite close to the removed streets.

    The platform structure of a bus station is disconnected from the other graph. Most bus traffic of a medium size city becomes unusable. Despite of the complexity of the sub graph (54 edges and 21 stops), it must be removed in pruning, so that stops get linked to reachable and well connected streets.

    "},{"location":"IslandPruning/#issue-reports","title":"Issue reports","text":"

    Pruning creates a GraphIsland issue every time it prunes a sub graph. Issues may show up as duplicates, because pruning is run for each traverse mode.

    A PrunedStopIsland issue is added for every pruned graph island which has stops linked to it. Such islands are particularly harmful, because they are places where public transit transfers take place and hence are frequently used. Pruned stop island issues should be studied frequently and underlying OSM errors fixed, especially if the island has many stops and edges (i.e it is most likely a public transit station, see station island example above).

    "},{"location":"Logging/","title":"Logging","text":"

    OTP uses logback and slj4j 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.

    Some loggers useful for debugging.

    "},{"location":"Logging/#format","title":"Format","text":"

    By default, OTP logs in plain text to the console. However, it is possible to also log in JSON format.

    To enable it, set the Java property otp.logging.format to one of these values:

    "},{"location":"Logging/#complete-example","title":"Complete example","text":"
    java -Dotp.logging.format=json -jar otp.jar --load --serve data\n
    "},{"location":"Logging/#further-customization","title":"Further customization","text":"

    If you want to customize the exact log output even further you can use your own logback configuration by starting OTP with the following parameter:

    java -Dlogback.configurationFile=/path/to/logback.xml -jar otp.jar --load --serve data\n

    For example, Entur has their own custom log format configured as follows:

    <!-- Entur's custom log format  -->\n<appender name=\"entur\" class=\"ch.qos.logback.core.ConsoleAppender\">\n  <encoder class=\"net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder\">\n     <providers>\n        <!-- provides the timestamp <timestamp/> -->\n        <!-- provides the version <version/> -->\n        <!-- provides the fields in the configured pattern -->\n        <pattern>\n           <!-- the pattern that defines what to include -->\n           <pattern>\n           {\n             \"serviceContext\": {\n               \"service\": \"otp2\"\n             },\n             \"message\": \"%message\\n%ex{full}\",\n             \"severity\": \"%level\",\n             \"reportLocation\": {\n               \"filePath\": \"%logger\",\n               \"lineNumber\": \"%line\",\n               \"functionName\": \"%method\"\n              }\n            }\n            </pattern>\n        </pattern>\n     </providers>\n  </encoder>\n</appender>\n
    "},{"location":"Migrating-Configuration/","title":"Migrating between versions/builds","text":"

    While OTP's GraphQL APIs are very, very stable even across versions, the JSON configuration schema is not. Changes to it are relatively frequent and you can see all PRs that change it with the Github tag 'config change'.

    "},{"location":"Migrating-Configuration/#migrating-the-json-configuration","title":"Migrating the JSON configuration","text":"

    OTP validates the configuration and prints warnings during startup. This means that when you migrate to a newer version, you should carefully inspect the logs. If you see messages like

    (NodeAdapter.java:170) Unexpected config parameter: 'routingDefaults.stairsReluctance:1.65' in 'router-config.json'\n

    this means there are properties in your configuration that are unknown to OTP and therefore likely to be a configuration error, perhaps because the schema was changed. In such a case you should consult the feature, router or build configuration documentation to find out what the new schema looks like.

    By default, OTP starts up even if unknown configuration parameters exist. This supports forward and backwards migration of config parameters independent if the OTP version. This allows the configuration to follow the lifecycle of the environment and still be able to roll back OTP. Combined with the config parameter substitution it also allows using the same configuration in different environments. Tip! Rolling out the configuration before rolling out a new version of OTP, ensure you that you are safe and can roll back later.

    An example: you change the location of the graphs, a critical error occurs afterwards and you need to roll back. Any member of the dev-ops team should then be confident that they can roll back without risk - even if the environment changed since the last OTP version was rolled out.

    "},{"location":"Migrating-Configuration/#aborting-on-invalid-configuration","title":"Aborting on invalid configuration","text":"

    If you want OTP to abort the startup when encountering unknown configuration parameters, you can add the flag --abortOnUnknownConfig to your regular OTP CLI commands.

    This should of course be used wisely as it can also accidentally make your production instances refuse to start up. For some deployments this is a good solution - especially if the config substitution feature is used to inject environment specific information. Using this feature in the graph-build phase is less risky, than in the OTP serve phase.

    "},{"location":"Netex-Tutorial/","title":"NeTEx & SIRI tutorial","text":"

    One important new feature of OTP2 is the ability to load NeTEx and SIRI data. NeTEx is a European specification for transit data exchange, comparable in purpose to GTFS but broader in scope.

    First of all, you need to download a bundled jar of OTP.

    Secondly, you will use the Norwegian NeTEx file as well as the Norwegian OSM data, but OTP can download the NeTEx one for you.

    "},{"location":"Netex-Tutorial/#configuring-the-build","title":"Configuring the build","text":"

    Create a working directory and place the OTP jar file in it and call it otp.jar.

    Since we download the OSM data from a free source, we don't want to put undue stress on the server. Therefore we download it before building the graph, not during.

    curl https://download.geofabrik.de/europe/norway-latest.osm.pbf -o norway.osm.pbf\n

    Now create a file called build-config.json in the same folder and fill it with the following content:

    // build-config.json\n{\n  \"transitFeeds\" : [\n    {\n      \"type\" : \"netex\",\n      \"feedId\" : \"NO\",\n      \"source\" : \"https://storage.googleapis.com/marduk-production/outbound/netex/rb_norway-aggregated-netex.zip\",\n      \"sharedFilePattern\" : \"_stops.xml\",\n      \"sharedGroupFilePattern\" : \"_(\\\\w{3})(_flexible)?_shared_data.xml\",\n      \"groupFilePattern\" : \"(\\\\w{3})_.*\\\\.xml\"\n    }\n  ],\n  \"osm\" : [\n    {\n      \"source\" : \"norway.osm.pbf\",\n      \"osmTagMapping\" : \"norway\",\n      \"timeZone\" : \"Europe/Oslo\"\n    }\n  ],\n  \"osmCacheDataInMem\" : true\n}\n

    Note the special section specifying how to find NeTEx XML files within the single ZIP archive that OTP downloads.

    Now you can instruct OTP to build a graph from this configuration file:

    java -Xmx16G -jar otp.jar --build --save .

    This should produce a file graph.obj in the same directory as your build-config.json.

    Building the Norway graph requires downloading about 250MB of input data so stay patient at the beginning particularly on a slow internet connection. The actual build takes approximately 10 minutes (without elevation data, as is configured above), and can be done within 16GB of heap memory (JVM switch -Xmx16G). The Graph file it produces is about 1.1 GB. The server will take about 30 seconds to load this graph and start up, and will consume about 6GB of heap memory under light use.

    You can then start up an OTP server with a command like this:

    java -Xmx6G -jar otp.jar --load .

    Once the server is started up, go to http://localhost:8080 in a browser to try out your server using OTP's built in testing web client. Try some long trips like Oslo to Bergen and see if you can get long distance trains and flights as alternatives. You might need to increase the walking limit above its very low default value.

    "},{"location":"Netex-Tutorial/#adding-siri-real-time-data","title":"Adding SIRI real time Data","text":"

    Another important feature in OTP version 2 is the ability to use SIRI real-time data. Within the EU data standards, SIRI is analogous to GTFS-RT: a way to apply real-time updates on top of schedule data. While technically a distinct specification from NeTEx, both NeTEx and SIRI use the Transmodel vocabulary, allowing SIRI messages to reference entities in NeTEx schedule data. Like GTFS-RT, SIRI is consumed by OTP2 using \"graph updaters\" which are configured in the router-config.json file, which is placed in the same directory as the graph.obj file and loaded at server startup.

    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"siri-sx-updater\",\n      \"frequency\" : \"1m\",\n      \"url\" : \"https://api.entur.io/realtime/v1/services\",\n      \"feedId\" : \"NO\",\n      \"blockReadinessUntilInitialized\" : true\n    },\n    {\n      \"type\" : \"siri-et-updater\",\n      \"frequency\" : \"1m\",\n      \"previewInterval\" : \"1h30m\",\n      \"url\" : \"https://api.entur.io/realtime/v1/services\",\n      \"feedId\" : \"NO\",\n      \"blockReadinessUntilInitialized\" : true\n    }\n  ]\n}\n

    After saving the file in the working directory, restart OTP.

    The updaters fetch two different kinds of SIRI data:

    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.

    "},{"location":"Preparing-OSM/","title":"Preparing OSM Data","text":""},{"location":"Preparing-OSM/#cropping-osm-data","title":"Cropping OSM data","text":"

    Services producing automated extracts of OSM data like Geofabrik or Interline 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 is a multi-platform Java tool that works on Windows, Linux, and MacOS but is relatively slow, 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 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. Selecting the \"CSV\" format in the lower left will give exactly the format expected by these tools.

    "},{"location":"Preparing-OSM/#filtering-osm-data","title":"Filtering OSM data","text":"

    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 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 and 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 wa/public_transport=platform wa/railway=platform w/park_ride=yes r/type=restriction r/type=route -o filtered.osm.pbf -f pbf,add_metadata=false

    "},{"location":"Presentations/","title":"Presentations related to OpenTripPlanner","text":""},{"location":"Presentations/#presentations-in-english","title":"Presentations in English","text":""},{"location":"Presentations/#presentations-in-german","title":"Presentations in German","text":""},{"location":"Presentations/#case-studies-and-reports","title":"Case studies and reports","text":""},{"location":"Product-Overview/","title":"Product Overview","text":""},{"location":"Product-Overview/#opentripplanner-project","title":"OpenTripPlanner project","text":"

    OpenTripPlanner is a group of open source software applications that help individuals and organizations calculate and deliver multimodal trip plans based on a combination of open-standard data sources. These include public transit services and schedules (GTFS and NeTEx) and OpenStreetMap (OSM), as well as sources describing bicycle sharing or rental, ride hailing, and other services (e.g. GBFS).

    A community of dozens of individuals and organizations work on OpenTripPlanner collaboratively to improve multimodal trip planning best practices and to make it easier for public transit agencies and public transit riders to publish and access information about transit services.

    OpenTripPlanner deployments are locally managed in many different ways by many different types of organizations. OpenTripPlanner consistently and dependably delivers multimodal trip plans to millions of riders every day in dozens of countries around the globe. The project is actively maintained by the community, with more than 50 commits most weeks during 2022, and 20 different developers having made 50 or more commits during the life of the project.

    "},{"location":"Product-Overview/#what-exactly-is-otp","title":"What exactly is OTP?","text":"

    The most commonly used OpenTripPlanner component is a server-side Java application that is primarily designed to interpret and combine map, transit service, and other mobility data sets, providing API endpoints that receive user origins and destinations and return trip plans to other applications along with vector map tiles, stop departures, and other rider information.

    In other words, OTP is a backend application that can work with other frontend user interfaces. OTP works with your website, mobile app, physical signage or other applications in order to provide relevant customer information and meaningful trip plans to riders.

    There's no official OTP user interface, although the OpenTripPlanner ecosystem includes several user interface projects (for example Digitransit and OTP-react-redux). How your OTP deployment looks is entirely up to you.

    "},{"location":"Product-Overview/#what-otp-can-do-for-you","title":"What OTP can do for you","text":""},{"location":"Product-Overview/#transit-agencies","title":"Transit agencies","text":"

    Transit agencies can use OTP as a backend for their public website/app trip planner or internal trip planner for their customer service team.

    "},{"location":"Product-Overview/#regions-countries-and-private-entities","title":"Regions, countries, and private entities","text":"

    Regional, provincial, or national governments, or any private entity, can set up a trip planner including multiple transit agencies.

    "},{"location":"Product-Overview/#researchers","title":"Researchers","text":"

    While historically, OpenTripPlanner has often been used by researchers for the programmatic calculation of large numbers of trip plans, this is no longer an intended use case of OTP. You are welcome to use OTP for any purpose, but you may also find applications like r5 to be more appropriate for these purposes.

    "},{"location":"Product-Overview/#talk-to-an-expert-about-otp","title":"Talk to an expert about OTP","text":"

    Everyone interested in OTP is welcome to post questions on the Gitter chat or OpenTripPlanner-users group.

    If you\u2019re looking for a conversation with an individual from a similar organizational type, you can make that request and include some info about your organization on the forum linked above and a member of the OTP community will connect with you.

    "},{"location":"ReleaseChecklist/","title":"Release Checklist","text":"

    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.

    "},{"location":"ReleaseChecklist/#artifact-signing","title":"Artifact Signing","text":"

    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 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 mvn clean package site to bypass signing, but this provides less certainty that everything is set up correctly for the CI-driven final release.

    "},{"location":"Roadmap/","title":"Roadmap","text":"

    The OTP community uses a GitHub-hosted Roadmap to document all long-term feature requests for OpenTripPlanner. Unlike typical OTP Issues, the Roadmap outlines quarterly and yearly product-focused goals the community intends to propose for OTP, rather than short-term bug fixes or feature requests.

    Twice a year, product owners (POs) and developers will review and clean up the issues at the PO meetings. Product owner (PO) meetings are open to everyone interested in OTP and are held on the first Tuesday of each month at 7 AM US Pacific / 10 AM US Eastern / 4PM CET. To join, please consult this calender. For other questions, please contact members in the Gitter chat or the user mailing list.

    To create an issue on the OTP Roadmap, follow these steps:

    1. Navigate to the OpenTripPlanner GitHub.
    2. Select the \"Projects\" tab.
    3. Choose the \"Roadmap\" project.
    4. To add an issue, click \"Add item\" under the \"Wish list\" column.
    5. Click the \"+\" icon, then \"Create a new issue.\"
    6. Select the \"Roadmap Epic\" type by clicking \"Choose.\"
    7. Complete the required fields:

    Then, click \"Create.\"

    This is what your completed Roadmap Issue should like:

    Discussions about the Issue within the corresponding Gitter chat are encouraged, along with participation in the OTP product owner (PO) or developer meetings.

    "},{"location":"RouteRequest/","title":"Route Request","text":""},{"location":"RouteRequest/#route-request","title":"Route Request","text":"

    The RouteRequest is the type for the routingDefaults in router-config.json and in the transferRequests in build-config.json.

    Config Parameter Type Summary Req./Opt. Default Value Since alightSlack duration The time safety margin when alighting from a vehicle. Optional \"PT0S\" 2.0 arriveBy boolean Whether the trip should depart or arrive at the specified date and time. Optional false 2.0 boardSlack duration The time safety margin when boarding a vehicle. Optional \"PT0S\" 2.0 drivingDirection enum The driving direction to use in the intersection traversal calculation Optional \"right\" 2.2 elevatorBoardCost integer What is the cost of boarding a elevator? Optional 90 2.0 elevatorBoardTime integer How long does it take to get on an elevator, on average. Optional 90 2.0 elevatorHopCost integer What is the cost of travelling one floor on an elevator? Optional 20 2.0 elevatorHopTime integer How long does it take to advance one floor on an elevator? Optional 20 2.0 geoidElevation boolean If true, the Graph's ellipsoidToGeoidDifference is applied to all elevations returned by this query. Optional false 2.0 ignoreRealtimeUpdates boolean When true, real-time updates are ignored during this search. Optional false 2.0 intersectionTraversalModel enum The model that computes the costs of turns. Optional \"simple\" 2.2 locale locale TODO Optional \"en_US\" 2.0 maxDirectStreetDuration duration This is the maximum duration for a direct street search for each mode. Optional \"PT4H\" 2.1 maxJourneyDuration duration The expected maximum time a journey can last across all possible journeys for the current deployment. Optional \"PT24H\" 2.1 modes string The set of access/egress/direct/transit modes to be used for the route search. Optional \"TRANSIT,WALK\" 2.0 nonpreferredTransferPenalty integer Penalty (in seconds) for using a non-preferred transfer. Optional 180 2.0 numItineraries integer The maximum number of itineraries to return. Optional 50 2.0 otherThanPreferredRoutesPenalty integer Penalty added for using every route that is not preferred if user set any route as preferred. Optional 300 2.0 relaxTransitGroupPriority string The relax function for transit-group-priority Optional \"0s + 1.00 t\" 2.5 relaxTransitSearchGeneralizedCostAtDestination double Whether non-optimal transit paths at the destination should be returned Optional 2.3 searchWindow duration The duration of the search-window. Optional 2.0 streetRoutingTimeout duration The maximum time a street routing request is allowed to take before returning the results. Optional \"PT5S\" 2.2 transferPenalty integer An additional penalty added to boardings after the first. Optional 0 2.0 transferSlack duration The extra time needed to make a safe transfer. Optional \"PT2M\" 2.0 turnReluctance double Multiplicative factor on expected turning time. Optional 1.0 2.0 unpreferredCost cost-linear-function A cost function used to calculate penalty for an unpreferred route. Optional \"0s + 1.00 t\" 2.2 waitReluctance double How much worse is waiting for a transit vehicle than being on a transit vehicle, as a multiplier. Optional 1.0 2.0 accessEgress object Parameters for access and egress routing. Optional 2.4 maxDuration duration This is the maximum duration for access/egress for street searches. Optional \"PT45M\" 2.1 maxStopCount integer Maximal number of stops collected in access/egress routing Optional 500 2.4 maxDurationForMode enum map of duration Limit access/egress per street mode. Optional 2.1 penalty enum map of object Penalty for access/egress by street mode. Optional 2.4 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0FLEXIBLE object NA Optional 2.4 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0costFactor double A factor multiplied with the time-penalty to get the cost-penalty. Optional 0.0 2.4 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0timePenalty time-penalty Penalty added to the time of a path/leg. Optional \"0s + 0.00 t\" 2.4 alightSlackForMode enum map of duration How much extra time should be given when alighting a vehicle for each given mode. Optional 2.0 bicycle object Bicycle preferences. Optional 2.5 boardCost integer Prevents unnecessary transfers by adding a cost for boarding a transit vehicle. Optional 600 2.0 optimization enum The set of characteristics that the user wants to optimize for. Optional \"safe-streets\" 2.0 \u00a0\u00a0\u00a0reluctance double A multiplier for how bad cycling is, compared to being in transit for equal lengths of time. Optional 2.0 2.0 \u00a0\u00a0\u00a0speed double Max bicycle speed along streets, in meters per second Optional 5.0 2.0 \u00a0\u00a0\u00a0parking object Preferences for parking a vehicle. Optional 2.5 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cost integer Cost to park a vehicle. Optional 120 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0time duration Time to park a vehicle. Optional \"PT1M\" 2.0 unpreferredVehicleParkingTagCost integer What cost to add if a parking facility doesn't contain a preferred tag. Optional 300 2.3 bannedVehicleParkingTags string[] Tags with which a vehicle parking will not be used. If empty, no tags are banned. Optional 2.1 preferredVehicleParkingTags string[] Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. Optional 2.3 requiredVehicleParkingTags string[] Tags without which a vehicle parking will not be used. If empty, no tags are required. Optional 2.1 \u00a0\u00a0\u00a0rental object Vehicle rental options Optional 2.3 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0allowKeepingAtDestination boolean If a vehicle should be allowed to be kept at the end of a station-based rental. Optional false 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dropOffCost integer Cost to drop-off a rented vehicle. Optional 30 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dropOffTime duration Time to drop-off a rented vehicle. Optional \"PT30S\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0keepingAtDestinationCost integer The cost of arriving at the destination with the rented vehicle, to discourage doing so. Optional 0 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pickupCost integer Cost to rent a vehicle. Optional 120 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pickupTime duration Time to rent a vehicle. Optional \"PT1M\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0useAvailabilityInformation boolean Whether or not vehicle rental availability information will be used to plan vehicle rental trips. Optional false 2.0 allowedNetworks string[] The vehicle rental networks which may be used. If empty all networks may be used. Optional 2.1 bannedNetworks string[] The vehicle rental networks which may not be used. If empty, no networks are banned. Optional 2.1 triangle object Triangle optimization criteria. Optional 2.5 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0flatness double Relative importance of flat terrain (range 0-1). Optional 0.0 2.0 safety double Relative importance of safety (range 0-1). Optional 0.0 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0time double Relative importance of duration of travel (range 0-1). Optional 0.0 2.0 \u00a0\u00a0\u00a0walk object Preferences for walking a vehicle. Optional 2.5 mountDismountCost integer The cost of hopping on or off a vehicle. Optional 0 2.0 mountDismountTime duration The time it takes the user to hop on or off a vehicle. Optional \"PT0S\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0reluctance double A multiplier for how bad walking with a vehicle is, compared to being in transit for equal lengths of time. Optional 5.0 2.1 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0speed double The user's vehicle walking speed in meters/second. Defaults to approximately 3 MPH. Optional 1.33 2.1 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0stairsReluctance double How bad is it to walk the vehicle up/down a flight of stairs compared to taking a detour. Optional 10.0 2.3 boardSlackForMode enum map of duration How much extra time should be given when boarding a vehicle for each given mode. Optional 2.0 car object Car preferences. Optional 2.5 \u00a0\u00a0\u00a0accelerationSpeed double The acceleration speed of an automobile, in meters per second per second. Optional 2.9 2.0 \u00a0\u00a0\u00a0decelerationSpeed double The deceleration speed of an automobile, in meters per second per second. Optional 2.9 2.0 \u00a0\u00a0\u00a0pickupCost integer Add a cost for car pickup changes when a pickup or drop off takes place Optional 120 2.1 \u00a0\u00a0\u00a0pickupTime duration Add a time for car pickup changes when a pickup or drop off takes place Optional \"PT1M\" 2.1 \u00a0\u00a0\u00a0reluctance double A multiplier for how bad driving is, compared to being in transit for equal lengths of time. Optional 2.0 2.0 \u00a0\u00a0\u00a0parking object Preferences for parking a vehicle. Optional 2.5 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cost integer Cost to park a vehicle. Optional 120 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0time duration Time to park a vehicle. Optional \"PT1M\" 2.0 unpreferredVehicleParkingTagCost integer What cost to add if a parking facility doesn't contain a preferred tag. Optional 300 2.3 bannedVehicleParkingTags string[] Tags with which a vehicle parking will not be used. If empty, no tags are banned. Optional 2.1 preferredVehicleParkingTags string[] Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. Optional 2.3 requiredVehicleParkingTags string[] Tags without which a vehicle parking will not be used. If empty, no tags are required. Optional 2.1 \u00a0\u00a0\u00a0rental object Vehicle rental options Optional 2.3 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0allowKeepingAtDestination boolean If a vehicle should be allowed to be kept at the end of a station-based rental. Optional false 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dropOffCost integer Cost to drop-off a rented vehicle. Optional 30 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dropOffTime duration Time to drop-off a rented vehicle. Optional \"PT30S\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0keepingAtDestinationCost integer The cost of arriving at the destination with the rented vehicle, to discourage doing so. Optional 0 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pickupCost integer Cost to rent a vehicle. Optional 120 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pickupTime duration Time to rent a vehicle. Optional \"PT1M\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0useAvailabilityInformation boolean Whether or not vehicle rental availability information will be used to plan vehicle rental trips. Optional false 2.0 allowedNetworks string[] The vehicle rental networks which may be used. If empty all networks may be used. Optional 2.1 bannedNetworks string[] The vehicle rental networks which may not be used. If empty, no networks are banned. Optional 2.1 itineraryFilters object Configure itinerary filters that may modify itineraries, sort them, and filter away less preferable results. Optional 2.0 accessibilityScore boolean An experimental feature contributed by IBI which adds a sandbox accessibility score between 0 and 1 for each leg and itinerary. Optional false 2.2 bikeRentalDistanceRatio double Filter routes that consist of bike-rental and walking by the minimum fraction of the bike-rental leg using distance. Optional 0.0 2.1 debug enum Enable this to attach a system notice to itineraries instead of removing them. This is very convenient when tuning the itinerary-filter-chain. Optional \"off\" 2.0 filterDirectFlexBySearchWindow boolean Filter direct flex results by the search window. The search-window is not used during flex routing, but we use one end to align it with transit results. Optional true 2.7 filterItinerariesWithSameFirstOrLastTrip boolean If more than one itinerary begins or ends with same trip, filter out one of those itineraries so that only one remains. Optional false 2.2 \u00a0\u00a0\u00a0groupSimilarityKeepOne double Pick ONE itinerary from each group after putting itineraries that are 85% similar together. Optional 0.85 2.1 \u00a0\u00a0\u00a0groupSimilarityKeepThree double Reduce the number of itineraries to three itineraries by reducing each group of itineraries grouped by 68% similarity. Optional 0.68 2.1 groupedOtherThanSameLegsMaxCostMultiplier double Filter grouped itineraries, where the non-grouped legs are more expensive than in the lowest cost one. Optional 2.0 2.1 minBikeParkingDistance double Filter out bike park+ride results that have fewer meters of cycling than this value. Optional 0.0 2.3 nonTransitGeneralizedCostLimit cost-linear-function The function define a max-limit for generalized-cost for non-transit itineraries. Optional \"1h + 2.0 t\" 2.1 parkAndRideDurationRatio double Filter P+R routes that consist of driving and walking by the minimum fraction of the driving using of time. Optional 0.0 2.1 removeItinerariesWithSameRoutesAndStops boolean Set to true if you want to list only the first itinerary which goes through the same stops and routes. Optional false 2.2 removeTransitWithHigherCostThanBestOnStreetOnly cost-linear-function Limit function for generalized-cost computed from street-only itineries applied to transit itineraries. Optional \"1m + 1.30 t\" 2.4 transitGeneralizedCostLimit object A relative limit for the generalized-cost for transit itineraries. Optional 2.1 costLimitFunction cost-linear-function The base function used by the filter. Optional \"15m + 1.50 t\" 2.2 intervalRelaxFactor double How much the filter should be relaxed for itineraries that do not overlap in time. Optional 0.4 2.2 maxDirectStreetDurationForMode enum map of duration Limit direct route duration per street mode. Optional 2.2 scooter object Scooter preferences. Optional 2.5 optimization enum The set of characteristics that the user wants to optimize for. Optional \"safe-streets\" 2.0 \u00a0\u00a0\u00a0reluctance double A multiplier for how bad scooter travel is, compared to being in transit for equal lengths of time. Optional 2.0 2.0 \u00a0\u00a0\u00a0speed double Max scooter speed along streets, in meters per second Optional 5.0 2.0 \u00a0\u00a0\u00a0rental object Vehicle rental options Optional 2.3 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0allowKeepingAtDestination boolean If a vehicle should be allowed to be kept at the end of a station-based rental. Optional false 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dropOffCost integer Cost to drop-off a rented vehicle. Optional 30 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dropOffTime duration Time to drop-off a rented vehicle. Optional \"PT30S\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0keepingAtDestinationCost integer The cost of arriving at the destination with the rented vehicle, to discourage doing so. Optional 0 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pickupCost integer Cost to rent a vehicle. Optional 120 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pickupTime duration Time to rent a vehicle. Optional \"PT1M\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0useAvailabilityInformation boolean Whether or not vehicle rental availability information will be used to plan vehicle rental trips. Optional false 2.0 allowedNetworks string[] The vehicle rental networks which may be used. If empty all networks may be used. Optional 2.1 bannedNetworks string[] The vehicle rental networks which may not be used. If empty, no networks are banned. Optional 2.1 triangle object Triangle optimization criteria. Optional 2.5 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0flatness double Relative importance of flat terrain (range 0-1). Optional 0.0 2.0 safety double Relative importance of safety (range 0-1). Optional 0.0 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0time double Relative importance of duration of travel (range 0-1). Optional 0.0 2.0 transferOptimization object Optimize where a transfer between to trip happens. Optional 2.1 backTravelWaitTimeFactor double To reduce back-travel we favor waiting, this reduces the cost of waiting. Optional 1.0 2.1 extraStopBoardAlightCostsFactor double Add an extra board- and alight-cost for prioritized stops. Optional 0.0 2.1 minSafeWaitTimeFactor double Used to set a maximum wait-time cost, base on min-safe-transfer-time. Optional 5.0 2.1 optimizeTransferWaitTime boolean This enables the transfer wait time optimization. Optional true 2.1 transitGroupPriority object Group transit patterns and give each group a mutual advantage in the Raptor search. Optional 2.5 transitReluctanceForMode enum map of double Transit reluctance for a given transport mode Optional 2.1 unpreferred object Parameters listing authorities or lines that preferably should not be used in trip patters. Optional 2.2 agencies feed-scoped-id[] The ids of the agencies that incur an extra cost when being used. Format: FeedId:AgencyId Optional 2.2 routes feed-scoped-id[] The ids of the routes that incur an extra cost when being used. Format: FeedId:RouteId Optional 2.2 walk object Walking preferences. Optional 2.5 \u00a0\u00a0\u00a0boardCost integer Prevents unnecessary transfers by adding a cost for boarding a vehicle. This is the cost that is used when boarding while walking. Optional 600 2.0 \u00a0\u00a0\u00a0escalatorReluctance double A multiplier for how bad being in an escalator is compared to being in transit for equal lengths of time Optional 1.5 2.4 reluctance double A multiplier for how bad walking is, compared to being in transit for equal lengths of time. Optional 2.0 2.0 safetyFactor double Factor for how much the walk safety is considered in routing. Optional 1.0 2.2 \u00a0\u00a0\u00a0speed double The user's walking speed in meters/second. Optional 1.33 2.0 \u00a0\u00a0\u00a0stairsReluctance double Used instead of walkReluctance for stairs. Optional 2.0 2.0 stairsTimeFactor double How much more time does it take to walk a flight of stairs compared to walking a similar horizontal length. Optional 3.0 2.1 wheelchairAccessibility object See Wheelchair Accessibility Optional 2.2 \u00a0\u00a0\u00a0enabled boolean Enable wheelchair accessibility. Optional false 2.0 \u00a0\u00a0\u00a0inaccessibleStreetReluctance double The factor to multiply the cost of traversing a street edge that is not wheelchair-accessible. Optional 25.0 2.2 maxSlope double The maximum slope as a fraction of 1. Optional 0.083 2.0 slopeExceededReluctance double How much streets with high slope should be avoided. Optional 1.0 2.2 stairsReluctance double How much stairs should be avoided. Optional 100.0 2.2 \u00a0\u00a0\u00a0elevator object Configuration for when to use inaccessible elevators. Optional 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0inaccessibleCost integer The cost to add when traversing an entity which is know to be inaccessible. Optional 3600 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onlyConsiderAccessible boolean Whether to only use this entity if it is explicitly marked as wheelchair accessible. Optional false 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0unknownCost integer The cost to add when traversing an entity with unknown accessibility information. Optional 20 2.2 \u00a0\u00a0\u00a0stop object Configuration for when to use inaccessible stops. Optional 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0inaccessibleCost integer The cost to add when traversing an entity which is know to be inaccessible. Optional 3600 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onlyConsiderAccessible boolean Whether to only use this entity if it is explicitly marked as wheelchair accessible. Optional true 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0unknownCost integer The cost to add when traversing an entity with unknown accessibility information. Optional 600 2.2 \u00a0\u00a0\u00a0trip object Configuration for when to use inaccessible trips. Optional 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0inaccessibleCost integer The cost to add when traversing an entity which is know to be inaccessible. Optional 3600 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onlyConsiderAccessible boolean Whether to only use this entity if it is explicitly marked as wheelchair accessible. Optional true 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0unknownCost integer The cost to add when traversing an entity with unknown accessibility information. Optional 600 2.2"},{"location":"RouteRequest/#parameter-details","title":"Parameter Details","text":""},{"location":"RouteRequest/#rd_alightSlack","title":"alightSlack","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT0S\" Path: /routingDefaults

    The time safety margin when alighting from a vehicle.

    This time slack is added to arrival time of the vehicle before any transfer or onward travel.

    This time slack helps model potential delays or procedures a passenger experiences during the process of passing through the alighting location. This parameter is intended to be set by agencies not individual users. For specific modes, like airplane and subway, that need more time than others, this is also configurable per mode with alightSlackForMode. A related parameter (transferSlack) exists to help avoid missed connections when there are minor schedule variations.

    "},{"location":"RouteRequest/#rd_boardSlack","title":"boardSlack","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT0S\" Path: /routingDefaults

    The time safety margin when boarding a vehicle.

    The board slack is added to the passenger's arrival time at a stop, before evaluating which vehicles can be boarded.

    This time slack helps model potential delays or procedures a passenger experiences during the process of passing through the boarding location, as well as some minor schedule variation. This parameter is intended to be set by agencies not individual users.

    Agencies can use this parameter to ensure that the trip planner does not instruct passengers to arrive at the last second. This slack is added at every boarding including the first vehicle and transfers except for in-seat transfers and guaranteed transfers.

    For specific modes, like airplane and subway, that need more time than others, this is also configurable per mode with boardSlackForMode.

    A related parameter (transferSlack) also helps avoid missed connections when there are minor schedule variations.

    "},{"location":"RouteRequest/#rd_drivingDirection","title":"drivingDirection","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"right\" Path: /routingDefaults Enum values: right | left

    The driving direction to use in the intersection traversal calculation

    "},{"location":"RouteRequest/#rd_intersectionTraversalModel","title":"intersectionTraversalModel","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"simple\" Path: /routingDefaults Enum values: simple | constant

    The model that computes the costs of turns.

    "},{"location":"RouteRequest/#rd_maxDirectStreetDuration","title":"maxDirectStreetDuration","text":"

    Since version: 2.1 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT4H\" Path: /routingDefaults

    This is the maximum duration for a direct street search for each mode.

    This is a performance limit and should therefore be set high. Results close to the limit are not guaranteed to be optimal. Use itinerary-filters to limit what is presented to the client. The duration can be set per mode(maxDirectStreetDurationForMode), because some street modes searches are much more resource intensive than others. A default value is applied if the mode specific value does not exist.\"

    "},{"location":"RouteRequest/#rd_maxJourneyDuration","title":"maxJourneyDuration","text":"

    Since version: 2.1 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT24H\" Path: /routingDefaults

    The expected maximum time a journey can last across all possible journeys for the current deployment.

    Normally you would just do an estimate and add enough slack, so you are sure that there is no journeys that falls outside this window. The parameter is used find all possible dates for the journey and then search only the services which run on those dates. The duration must include access, egress, wait-time and transit time for the whole journey. It should also take low frequency days/periods like holidays into account. In other words, pick the two points within your area that has the worst connection and then try to travel on the worst possible day, and find the maximum journey duration. Using a value that is too high has the effect of including more patterns in the search, hence, making it a bit slower. Recommended values would be from 12 hours(small town/city), 1 day (region) to 2 days (country like Norway).\"

    "},{"location":"RouteRequest/#rd_otherThanPreferredRoutesPenalty","title":"otherThanPreferredRoutesPenalty","text":"

    Since version: 2.0 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 300 Path: /routingDefaults

    Penalty added for using every route that is not preferred if user set any route as preferred.

    We return number of seconds that we are willing to wait for preferred route.

    "},{"location":"RouteRequest/#rd_relaxTransitGroupPriority","title":"relaxTransitGroupPriority","text":"

    Since version: 2.5 \u2219 Type: string \u2219 Cardinality: Optional \u2219 Default value: \"0s + 1.00 t\" Path: /routingDefaults

    The relax function for transit-group-priority

    A path is considered optimal if the generalized-cost is less than the generalized-cost of another path. If this parameter is set, the comparison is relaxed further if they belong to different transit groups.

    "},{"location":"RouteRequest/#rd_relaxTransitSearchGeneralizedCostAtDestination","title":"relaxTransitSearchGeneralizedCostAtDestination","text":"

    Since version: 2.3 \u2219 Type: double \u2219 Cardinality: Optional Path: /routingDefaults

    Whether non-optimal transit paths at the destination should be returned

    Let c be the existing minimum pareto optimal generalized cost to beat. Then a trip with cost c' is accepted if the following is true: c' < Math.round(c * relaxRaptorCostCriteria).

    The parameter is optional. If not set a normal comparison is performed.

    Values equals or less than zero is not allowed. Values greater than 2.0 are not supported, due to performance reasons.

    "},{"location":"RouteRequest/#rd_searchWindow","title":"searchWindow","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional Path: /routingDefaults

    The duration of the search-window.

    This is the time/duration in seconds from the earliest-departure-time(EDT) to the latest-departure-time(LDT). In case of a reverse search it will be the time from earliest to latest arrival time (LAT - EAT).

    All optimal travels that depart within the search window is guaranteed to be found.

    This is sometimes referred to as the Range Raptor Search Window - but could be used in a none Transit search as well; Hence this is named search-window and not raptor-search-window.

    This is normally dynamically calculated by the server. Use null to unset, and zero to do one Raptor iteration. The value is dynamically assigned a suitable value, if not set. In a small to medium size operation you may use a fixed value, like 60 minutes. If you have a mixture of high frequency cities routes and infrequent long distant journeys, the best option is normally to use the dynamic auto assignment. If not provided the value is resolved depending on the other input parameters, available transit options and realtime changes.

    There is no need to set this when going to the next/previous page. The OTP Server will increase/decrease the search-window when paging to match the requested number of itineraries.

    "},{"location":"RouteRequest/#rd_streetRoutingTimeout","title":"streetRoutingTimeout","text":"

    Since version: 2.2 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT5S\" Path: /routingDefaults

    The maximum time a street routing request is allowed to take before returning the results.

    The street search(AStar) aborts after this duration and any paths found are returned to the client. The street part of the routing may take a long time if searching very long distances. You can set the street routing timeout to avoid tying up server resources on pointless searches and ensure that your users receive a timely response. You can also limit the max duration. There are is also a 'apiProcessingTimeout'. Make sure the street timeout is less than the 'apiProcessingTimeout'.

    "},{"location":"RouteRequest/#rd_transferPenalty","title":"transferPenalty","text":"

    Since version: 2.0 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 0 Path: /routingDefaults

    An additional penalty added to boardings after the first.

    The value is in OTP's internal weight units, which are roughly equivalent to seconds. Set this to a high value to discourage transfers. Of course, transfers that save significant time or walking will still be taken.

    "},{"location":"RouteRequest/#rd_transferSlack","title":"transferSlack","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT2M\" Path: /routingDefaults

    The extra time needed to make a safe transfer.

    The extra buffer time/safety margin added to transfers to make sure the connection is safe, time wise. We recommend allowing the end-user to set this, and use board-/alight-slack to enforce agency policies. This time is in addition to how long it might take to walk, board and alight.

    It is useful for passengers on long distance travel, and people with mobility issues, but can be set close to zero for everyday commuters and short distance searches in high-frequency transit areas.

    "},{"location":"RouteRequest/#rd_unpreferredCost","title":"unpreferredCost","text":"

    Since version: 2.2 \u2219 Type: cost-linear-function \u2219 Cardinality: Optional \u2219 Default value: \"0s + 1.00 t\" Path: /routingDefaults

    A cost function used to calculate penalty for an unpreferred route.

    Function should return number of seconds that we are willing to wait for preferred route or for an unpreferred agency's departure. For example: 5m + 2.0 t

    "},{"location":"RouteRequest/#rd_accessEgress_maxDuration","title":"maxDuration","text":"

    Since version: 2.1 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT45M\" Path: /routingDefaults/accessEgress

    This is the maximum duration for access/egress for street searches.

    This is a performance limit and should therefore be set high. Results close to the limit are not guaranteed to be optimal. Use itinerary-filters to limit what is presented to the client. The duration can be set per mode(maxDurationForMode), because some street modes searches are much more resource intensive than others. A default value is applied if the mode specific value does not exist.

    "},{"location":"RouteRequest/#rd_accessEgress_maxStopCount","title":"maxStopCount","text":"

    Since version: 2.4 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 500 Path: /routingDefaults/accessEgress

    Maximal number of stops collected in access/egress routing

    Safety limit to prevent access to and egress from too many stops.

    "},{"location":"RouteRequest/#rd_accessEgress_maxDurationForMode","title":"maxDurationForMode","text":"

    Since version: 2.1 \u2219 Type: enum map of duration \u2219 Cardinality: Optional Path: /routingDefaults/accessEgress Enum keys: not-set | walk | bike | bike-to-park | bike-rental | scooter-rental | car | car-to-park | car-pickup | car-rental | car-hailing | flexible

    Limit access/egress per street mode.

    Override the settings in maxDuration for specific street modes. This is done because some street modes searches are much more resource intensive than others.

    "},{"location":"RouteRequest/#rd_accessEgress_penalty","title":"penalty","text":"

    Since version: 2.4 \u2219 Type: enum map of object \u2219 Cardinality: Optional Path: /routingDefaults/accessEgress Enum keys: not-set | walk | bike | bike-to-park | bike-rental | scooter-rental | car | car-to-park | car-pickup | car-rental | car-hailing | flexible

    Penalty for access/egress by street mode.

    Use this to add a time and cost penalty to an access/egress legs for a given street mode. This will favour other street-modes and transit. This has a performance penalty, since the search-window is increased with the same amount as the maximum penalty for the access legs used. In other cases where the access(CAR) is faster than transit the performance will be better.

    The default values are

    Example: \"car-to-park\" : { \"timePenalty\": \"10m + 1.5t\", \"costFactor\": 2.5 }

    Time penalty

    The timePenalty is used to add a penalty to the access/egress duration/time. The time including the penalty is used in the algorithm when comparing paths, but the actual duration is used when presented to the end user.

    Cost factor

    The costFactor is used to add an additional cost to the leg\u00b4s generalized-cost. The time-penalty is multiplied with the cost-factor. A cost-factor of zero, gives no extra cost, while 1.0 will add the same amount to both time and cost.

    "},{"location":"RouteRequest/#rd_alightSlackForMode","title":"alightSlackForMode","text":"

    Since version: 2.0 \u2219 Type: enum map of duration \u2219 Cardinality: Optional Path: /routingDefaults Enum keys: rail | coach | subway | bus | tram | ferry | airplane | cable-car | gondola | funicular | trolleybus | monorail | carpool | taxi

    How much extra time should be given when alighting a vehicle for each given mode.

    Sometimes there is a need to configure a longer alighting times for specific modes, such as airplanes or ferries.

    "},{"location":"RouteRequest/#rd_bicycle_boardCost","title":"boardCost","text":"

    Since version: 2.0 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 600 Path: /routingDefaults/bicycle

    Prevents unnecessary transfers by adding a cost for boarding a transit vehicle.

    This is the cost that is used when boarding while cycling. This is usually higher that walkBoardCost.

    "},{"location":"RouteRequest/#rd_bicycle_optimization","title":"optimization","text":"

    Since version: 2.0 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"safe-streets\" Path: /routingDefaults/bicycle Enum values: shortest-duration | safe-streets | flat-streets | safest-streets | triangle

    The set of characteristics that the user wants to optimize for.

    If the triangle optimization is used, it's enough to just define the triangle parameters

    "},{"location":"RouteRequest/#rd_bicycle_parking_unpreferredVehicleParkingTagCost","title":"unpreferredVehicleParkingTagCost","text":"

    Since version: 2.3 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 300 Path: /routingDefaults/bicycle/parking

    What cost to add if a parking facility doesn't contain a preferred tag.

    See preferredVehicleParkingTags.

    "},{"location":"RouteRequest/#rd_bicycle_parking_bannedVehicleParkingTags","title":"bannedVehicleParkingTags","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/bicycle/parking

    Tags with which a vehicle parking will not be used. If empty, no tags are banned.

    Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed).

    "},{"location":"RouteRequest/#rd_bicycle_parking_preferredVehicleParkingTags","title":"preferredVehicleParkingTags","text":"

    Since version: 2.3 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/bicycle/parking

    Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised.

    Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed).

    "},{"location":"RouteRequest/#rd_bicycle_parking_requiredVehicleParkingTags","title":"requiredVehicleParkingTags","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/bicycle/parking

    Tags without which a vehicle parking will not be used. If empty, no tags are required.

    Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed).

    "},{"location":"RouteRequest/#rd_bicycle_rental_allowedNetworks","title":"allowedNetworks","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/bicycle/rental

    The vehicle rental networks which may be used. If empty all networks may be used.

    "},{"location":"RouteRequest/#rd_bicycle_rental_bannedNetworks","title":"bannedNetworks","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/bicycle/rental

    The vehicle rental networks which may not be used. If empty, no networks are banned.

    "},{"location":"RouteRequest/#rd_bicycle_triangle","title":"triangle","text":"

    Since version: 2.5 \u2219 Type: object \u2219 Cardinality: Optional Path: /routingDefaults/bicycle

    Triangle optimization criteria.

    Optimization type doesn't need to be defined if these values are defined.

    "},{"location":"RouteRequest/#rd_bicycle_triangle_safety","title":"safety","text":"

    Since version: 2.0 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.0 Path: /routingDefaults/bicycle/triangle

    Relative importance of safety (range 0-1).

    This factor can also include other concerns such as convenience and general cyclist preferences by taking into account road surface etc.

    "},{"location":"RouteRequest/#rd_bicycle_walk_mountDismountCost","title":"mountDismountCost","text":"

    Since version: 2.0 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 0 Path: /routingDefaults/bicycle/walk

    The cost of hopping on or off a vehicle.

    There are different parameters for the cost of renting or parking a vehicle and this is not meant for controlling the cost of those events.

    "},{"location":"RouteRequest/#rd_bicycle_walk_mountDismountTime","title":"mountDismountTime","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT0S\" Path: /routingDefaults/bicycle/walk

    The time it takes the user to hop on or off a vehicle.

    Time it takes to rent or park a vehicle have their own parameters and this is not meant for controlling the duration of those events.

    "},{"location":"RouteRequest/#rd_boardSlackForMode","title":"boardSlackForMode","text":"

    Since version: 2.0 \u2219 Type: enum map of duration \u2219 Cardinality: Optional Path: /routingDefaults Enum keys: rail | coach | subway | bus | tram | ferry | airplane | cable-car | gondola | funicular | trolleybus | monorail | carpool | taxi

    How much extra time should be given when boarding a vehicle for each given mode.

    Sometimes there is a need to configure a board times for specific modes, such as airplanes or ferries, where the check-in process needs to be done in good time before ride.

    "},{"location":"RouteRequest/#rd_car_parking_unpreferredVehicleParkingTagCost","title":"unpreferredVehicleParkingTagCost","text":"

    Since version: 2.3 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 300 Path: /routingDefaults/car/parking

    What cost to add if a parking facility doesn't contain a preferred tag.

    See preferredVehicleParkingTags.

    "},{"location":"RouteRequest/#rd_car_parking_bannedVehicleParkingTags","title":"bannedVehicleParkingTags","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/car/parking

    Tags with which a vehicle parking will not be used. If empty, no tags are banned.

    Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed).

    "},{"location":"RouteRequest/#rd_car_parking_preferredVehicleParkingTags","title":"preferredVehicleParkingTags","text":"

    Since version: 2.3 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/car/parking

    Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised.

    Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed).

    "},{"location":"RouteRequest/#rd_car_parking_requiredVehicleParkingTags","title":"requiredVehicleParkingTags","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/car/parking

    Tags without which a vehicle parking will not be used. If empty, no tags are required.

    Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed).

    "},{"location":"RouteRequest/#rd_car_rental_allowedNetworks","title":"allowedNetworks","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/car/rental

    The vehicle rental networks which may be used. If empty all networks may be used.

    "},{"location":"RouteRequest/#rd_car_rental_bannedNetworks","title":"bannedNetworks","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/car/rental

    The vehicle rental networks which may not be used. If empty, no networks are banned.

    "},{"location":"RouteRequest/#rd_itineraryFilters","title":"itineraryFilters","text":"

    Since version: 2.0 \u2219 Type: object \u2219 Cardinality: Optional Path: /routingDefaults

    Configure itinerary filters that may modify itineraries, sort them, and filter away less preferable results.

    The purpose of the itinerary filter chain is to post process the result returned by the routing search. The filters may modify itineraries, sort them, and filter away less preferable results.

    OTP2 may produce numerous pareto-optimal results when using time, number-of-transfers and generalized-cost as criteria. Use the parameters listed here to reduce/filter the itineraries return by the search engine before returning the results to client. There is also a few mandatory non-configurable filters removing none optimal results. You may see these filters pop-up in the filter debugging.

    "},{"location":"RouteRequest/#group-by-similarity-filters","title":"Group by similarity filters","text":"

    The group-by-filter is a bit complex, but should be simple to use. Set debug=true and experiment with searchWindow and the three group-by parameters(groupSimilarityKeepOne, groupSimilarityKeepThree and groupedOtherThanSameLegsMaxCostMultiplier).

    The group-by-filter work by grouping itineraries together and then reducing the number of 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 larger 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.

    The grouped itineraries can be further reduced by using groupedOtherThanSameLegsMaxCostMultiplier. This parameter filters out itineraries, where the legs that are not common for all the grouped 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.

    "},{"location":"RouteRequest/#rd_if_accessibilityScore","title":"accessibilityScore","text":"

    Since version: 2.2 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /routingDefaults/itineraryFilters

    An experimental feature contributed by IBI which adds a sandbox accessibility score between 0 and 1 for each leg and itinerary.

    This can be used by frontend developers to implement a simple traffic light UI.

    "},{"location":"RouteRequest/#rd_if_bikeRentalDistanceRatio","title":"bikeRentalDistanceRatio","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.0 Path: /routingDefaults/itineraryFilters

    Filter routes that consist of bike-rental and walking by the minimum fraction of the bike-rental leg using distance.

    This filters out results that consist of a long walk plus a relatively short bike rental leg. A value of 0.3 means that a minimum of 30% of the total distance must be spent on the bike in order for the result to be included.

    "},{"location":"RouteRequest/#rd_if_debug","title":"debug","text":"

    Since version: 2.0 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"off\" Path: /routingDefaults/itineraryFilters Enum values: off | list-all | limit-to-search-window | limit-to-num-of-itineraries

    Enable this to attach a system notice to itineraries instead of removing them. This is very convenient when tuning the itinerary-filter-chain.

    "},{"location":"RouteRequest/#rd_if_filterDirectFlexBySearchWindow","title":"filterDirectFlexBySearchWindow","text":"

    Since version: 2.7 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: true Path: /routingDefaults/itineraryFilters

    Filter direct flex results by the search window. The search-window is not used during flex routing, but we use one end to align it with transit results.

    When direct flex is mixed with a transit search in the same request, then the direct flex results are filtered by the search window of the transit results.

    Depart-at searches are filtered by latest-arrival-time and arrive-by searches are filtered by earliest-departure-time.

    Use this configuration to turn this feature off.

    "},{"location":"RouteRequest/#rd_if_filterItinerariesWithSameFirstOrLastTrip","title":"filterItinerariesWithSameFirstOrLastTrip","text":"

    Since version: 2.2 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /routingDefaults/itineraryFilters

    If more than one itinerary begins or ends with same trip, filter out one of those itineraries so that only one remains.

    Trips are considered equal if they have same id and same service day. Non-transit legs are skipped during comparison. Before filtering, trips are sorted by their generalized cost. The algorithm loops through the list from top to bottom. If an itinerary matches from any other itinerary from above, it is removed from list.

    "},{"location":"RouteRequest/#rd_if_groupedOtherThanSameLegsMaxCostMultiplier","title":"groupedOtherThanSameLegsMaxCostMultiplier","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 2.0 Path: /routingDefaults/itineraryFilters

    Filter grouped itineraries, where the non-grouped legs are more expensive than in the lowest cost one.

    Of the itineraries grouped to maximum of three itineraries, how much worse can the non-grouped legs be compared to the lowest cost. 2.0 means that they can be double the cost, and any itineraries having a higher cost will be filtered.

    "},{"location":"RouteRequest/#rd_if_minBikeParkingDistance","title":"minBikeParkingDistance","text":"

    Since version: 2.3 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.0 Path: /routingDefaults/itineraryFilters

    Filter out bike park+ride results that have fewer meters of cycling than this value.

    Useful if you want to exclude those routes which have only a few meters of cycling before parking the bike and taking public transport.

    "},{"location":"RouteRequest/#rd_if_nonTransitGeneralizedCostLimit","title":"nonTransitGeneralizedCostLimit","text":"

    Since version: 2.1 \u2219 Type: cost-linear-function \u2219 Cardinality: Optional \u2219 Default value: \"1h + 2.0 t\" Path: /routingDefaults/itineraryFilters

    The function define a max-limit for generalized-cost for non-transit itineraries.

    The max-limit is applied to itineraries with no transit legs, however all itineraries (including those with transit legs) are considered when calculating the minimum cost. The smallest generalized-cost value is used as input to the function. The function is used to calculate a max-limit. The max-limit is then used to filter non-transit itineraries by generalized-cost. Itineraries with a cost higher than the max-limit are dropped from the result set.

    For example if the function is f(x) = 30m + 2.0 x and the smallest cost is 30m = 1800s, then all non-transit itineraries with a cost larger than 1800 + 2 * 5000 = 11 800 are dropped.

    "},{"location":"RouteRequest/#rd_if_parkAndRideDurationRatio","title":"parkAndRideDurationRatio","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.0 Path: /routingDefaults/itineraryFilters

    Filter P+R routes that consist of driving and walking by the minimum fraction of the driving using of time.

    This filters out results that consist of driving plus a very long walk leg at the end. A value of 0.3 means that a minimum of 30% of the total time must be spent in the car in order for the result to be included. However, if there is only a single result, it is never filtered.

    "},{"location":"RouteRequest/#rd_if_removeItinerariesWithSameRoutesAndStops","title":"removeItinerariesWithSameRoutesAndStops","text":"

    Since version: 2.2 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /routingDefaults/itineraryFilters

    Set to true if you want to list only the first itinerary which goes through the same stops and routes.

    Itineraries visiting the same set of stops and riding the exact same routes, departing later are removed from the result.

    "},{"location":"RouteRequest/#rd_if_removeTransitWithHigherCostThanBestOnStreetOnly","title":"removeTransitWithHigherCostThanBestOnStreetOnly","text":"

    Since version: 2.4 \u2219 Type: cost-linear-function \u2219 Cardinality: Optional \u2219 Default value: \"1m + 1.30 t\" Path: /routingDefaults/itineraryFilters

    Limit function for generalized-cost computed from street-only itineries applied to transit itineraries.

    The max-limit is applied to itineraries with transit legs, and only itineraries without transit legs are considered when calculating the minimum cost. The smallest generalized-cost value is used as input to the function. The function is used to calculate a max-limit. The max-limit is then used to filter transit itineraries by generalized-cost. Itineraries with a cost higher than the max-limit are dropped from the result set. Walking is handled with a different logic: if a transit itinerary has higher cost than a plain walk itinerary, it will be removed even if the cost limit function would keep it.

    "},{"location":"RouteRequest/#rd_if_transitGeneralizedCostLimit","title":"transitGeneralizedCostLimit","text":"

    Since version: 2.1 \u2219 Type: object \u2219 Cardinality: Optional Path: /routingDefaults/itineraryFilters

    A relative limit for the generalized-cost for transit itineraries.

    The filter compares all itineraries against every other itinerary. If the generalized-cost plus a transitGeneralizedCostLimit is higher than the other generalized-cost, then the itinerary is dropped. The transitGeneralizedCostLimit is calculated using the costLimitFunction plus a relative cost for the distance in time between the itineraries. The relative cost is the intervalRelaxFactor multiplied with the interval in seconds. To set the costLimitFunction to be 1 hour plus 2 times cost use: 3600 + 2.0 x. To set an absolute value(3000s) use: 3000 + 0x

    "},{"location":"RouteRequest/#rd_if_transitGeneralizedCostLimit_costLimitFunction","title":"costLimitFunction","text":"

    Since version: 2.2 \u2219 Type: cost-linear-function \u2219 Cardinality: Optional \u2219 Default value: \"15m + 1.50 t\" Path: /routingDefaults/itineraryFilters/transitGeneralizedCostLimit

    The base function used by the filter.

    This function calculates the threshold for the filter, when the itineraries have exactly the same arrival and departure times.

    "},{"location":"RouteRequest/#rd_if_transitGeneralizedCostLimit_intervalRelaxFactor","title":"intervalRelaxFactor","text":"

    Since version: 2.2 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.4 Path: /routingDefaults/itineraryFilters/transitGeneralizedCostLimit

    How much the filter should be relaxed for itineraries that do not overlap in time.

    This value is used to increase the filter threshold for itineraries further away in time, compared to those, that have exactly the same arrival and departure times.

    The unit is cost unit per second of time difference.

    "},{"location":"RouteRequest/#rd_maxDirectStreetDurationForMode","title":"maxDirectStreetDurationForMode","text":"

    Since version: 2.2 \u2219 Type: enum map of duration \u2219 Cardinality: Optional Path: /routingDefaults Enum keys: not-set | walk | bike | bike-to-park | bike-rental | scooter-rental | car | car-to-park | car-pickup | car-rental | car-hailing | flexible

    Limit direct route duration per street mode.

    Override the settings in maxDirectStreetDuration for specific street modes. This is done because some street modes searches are much more resource intensive than others.

    "},{"location":"RouteRequest/#rd_scooter_optimization","title":"optimization","text":"

    Since version: 2.0 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"safe-streets\" Path: /routingDefaults/scooter Enum values: shortest-duration | safe-streets | flat-streets | safest-streets | triangle

    The set of characteristics that the user wants to optimize for.

    If the triangle optimization is used, it's enough to just define the triangle parameters

    "},{"location":"RouteRequest/#rd_scooter_rental_allowedNetworks","title":"allowedNetworks","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/scooter/rental

    The vehicle rental networks which may be used. If empty all networks may be used.

    "},{"location":"RouteRequest/#rd_scooter_rental_bannedNetworks","title":"bannedNetworks","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/scooter/rental

    The vehicle rental networks which may not be used. If empty, no networks are banned.

    "},{"location":"RouteRequest/#rd_scooter_triangle","title":"triangle","text":"

    Since version: 2.5 \u2219 Type: object \u2219 Cardinality: Optional Path: /routingDefaults/scooter

    Triangle optimization criteria.

    Optimization type doesn't need to be defined if these values are defined.

    "},{"location":"RouteRequest/#rd_scooter_triangle_safety","title":"safety","text":"

    Since version: 2.0 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.0 Path: /routingDefaults/scooter/triangle

    Relative importance of safety (range 0-1).

    This factor can also include other concerns such as convenience and general cyclist preferences by taking into account road surface etc.

    "},{"location":"RouteRequest/#rd_transferOptimization","title":"transferOptimization","text":"

    Since version: 2.1 \u2219 Type: object \u2219 Cardinality: Optional Path: /routingDefaults

    Optimize where a transfer between to trip happens.

    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 is done after the Raptor search and before the paths are passed to the itinerary-filter-chain.

    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).

    The optimized transfer service will try to, in order:

    1. Use transfer priority. This includes stay-seated and guaranteed transfers.
    2. Use the transfers with the best distribution of the wait-time, and avoid very short transfers.
    3. Avoid back-travel
    4. Boost stop-priority to select preferred and recommended stops.

    If two paths have the same transfer priority level, then we break the tie by looking at waiting times. The goal is to maximize the wait-time for each stop, avoiding situations where there is little time available to make the transfer. This is balanced with the generalized-cost. The cost is adjusted with a new cost for wait-time (optimized-wait-time-cost).

    The defaults should work fine, but if you have results with short wait-times dominating a better option or \"back-travel\", then try to increase the minSafeWaitTimeFactor, backTravelWaitTimeFactor and/or extraStopBoardAlightCostsFactor.

    For details on the logic/design see transfer optimization package documentation.

    "},{"location":"RouteRequest/#rd_to_backTravelWaitTimeFactor","title":"backTravelWaitTimeFactor","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 1.0 Path: /routingDefaults/transferOptimization

    To reduce back-travel we favor waiting, this reduces the cost of waiting.

    The wait time is used to prevent back-travel, the backTravelWaitTimeFactor is multiplied with the wait-time and subtracted from the optimized-transfer-cost.

    "},{"location":"RouteRequest/#rd_to_extraStopBoardAlightCostsFactor","title":"extraStopBoardAlightCostsFactor","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.0 Path: /routingDefaults/transferOptimization

    Add an extra board- and alight-cost for prioritized stops.

    A stopBoardAlightTransferCosts is added to the generalized-cost during routing. But this cost cannot be too high, because that would add extra cost to the transfer, and favor other alternative paths. But, when optimizing transfers, we do not have to take other paths into consideration and can boost the stop-priority-cost to allow transfers to take place at a preferred stop. The cost added during routing is already added to the generalized-cost used as a base in the optimized transfer calculation. By setting this parameter to 0, no extra cost is added, by setting it to 1.0 the stop-cost is doubled. Stop priority is only supported by the NeTEx import, not GTFS.

    "},{"location":"RouteRequest/#rd_to_minSafeWaitTimeFactor","title":"minSafeWaitTimeFactor","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 5.0 Path: /routingDefaults/transferOptimization

    Used to set a maximum wait-time cost, base on min-safe-transfer-time.

    This defines the maximum cost for the logarithmic function relative to the min-safe-transfer-time (t0) when wait time goes towards zero(0). f(0) = n * t0

    "},{"location":"RouteRequest/#rd_to_optimizeTransferWaitTime","title":"optimizeTransferWaitTime","text":"

    Since version: 2.1 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: true Path: /routingDefaults/transferOptimization

    This enables the transfer wait time optimization.

    If not enabled generalizedCost function is used to pick the optimal transfer point.

    "},{"location":"RouteRequest/#rd_transitGroupPriority","title":"transitGroupPriority","text":"

    Since version: 2.5 \u2219 Type: object \u2219 Cardinality: Optional Path: /routingDefaults

    Group transit patterns and give each group a mutual advantage in the Raptor search.

    Use this to separate transit patterns into groups. Each group will be given a group-id. A path (multiple legs) will then have a set of group-ids based on the group-id from each leg. Hence, two paths with a different set of group-ids will BOTH be optimal unless the cost is worse than the relaxation specified in the relaxTransitGroupPriority parameter. This is only available in the TransmodelAPI for now.

    Unmatched patterns are put in the BASE priority-group.

    THIS IS STILL AN EXPERIMENTAL FEATURE - IT MAY CHANGE WITHOUT ANY NOTICE!

    "},{"location":"RouteRequest/#rd_transitReluctanceForMode","title":"transitReluctanceForMode","text":"

    Since version: 2.1 \u2219 Type: enum map of double \u2219 Cardinality: Optional Path: /routingDefaults Enum keys: rail | coach | subway | bus | tram | ferry | airplane | cable-car | gondola | funicular | trolleybus | monorail | carpool | taxi

    Transit reluctance for a given transport mode

    "},{"location":"RouteRequest/#rd_unpreferred","title":"unpreferred","text":"

    Since version: 2.2 \u2219 Type: object \u2219 Cardinality: Optional Path: /routingDefaults

    Parameters listing authorities or lines that preferably should not be used in trip patters.

    A cost is applied to boarding nonpreferred authorities or routes.

    The routing engine will add extra penalty - on the unpreferred routes and/or agencies using a cost function. The cost function (unpreferredCost) is defined as a linear function of the form A + B x, where A is a fixed cost (in seconds) and B is reluctance multiplier for transit leg travel time x (in seconds).

    "},{"location":"RouteRequest/#rd_unpreferred_agencies","title":"agencies","text":"

    Since version: 2.2 \u2219 Type: feed-scoped-id[] \u2219 Cardinality: Optional Path: /routingDefaults/unpreferred

    The ids of the agencies that incur an extra cost when being used. Format: FeedId:AgencyId

    How much cost is added is configured in unpreferredCost.

    "},{"location":"RouteRequest/#rd_unpreferred_routes","title":"routes","text":"

    Since version: 2.2 \u2219 Type: feed-scoped-id[] \u2219 Cardinality: Optional Path: /routingDefaults/unpreferred

    The ids of the routes that incur an extra cost when being used. Format: FeedId:RouteId

    How much cost is added is configured in unpreferredCost.

    "},{"location":"RouteRequest/#rd_walk_reluctance","title":"reluctance","text":"

    Since version: 2.0 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 2.0 Path: /routingDefaults/walk

    A multiplier for how bad walking is, compared to being in transit for equal lengths of time.

    Empirically, values between 2 and 4 seem to correspond well to the concept of not wanting to walk too much without asking for totally ridiculous itineraries, but this observation should in no way be taken as scientific or definitive. Your mileage may vary. See https://github.com/opentripplanner/OpenTripPlanner/issues/4090 for impact on performance with high values.

    "},{"location":"RouteRequest/#rd_walk_safetyFactor","title":"safetyFactor","text":"

    Since version: 2.2 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 1.0 Path: /routingDefaults/walk

    Factor for how much the walk safety is considered in routing.

    Value should be between 0 and 1. If the value is set to be 0, safety is ignored.

    "},{"location":"RouteRequest/#rd_walk_stairsTimeFactor","title":"stairsTimeFactor","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 3.0 Path: /routingDefaults/walk

    How much more time does it take to walk a flight of stairs compared to walking a similar horizontal length.

    Default value is based on: Fujiyama, T., & Tyler, N. (2010). Predicting the walking speed of pedestrians on stairs. Transportation Planning and Technology, 33(2), 177\u2013202.

    "},{"location":"RouteRequest/#rd_wheelchairAccessibility_maxSlope","title":"maxSlope","text":"

    Since version: 2.0 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.083 Path: /routingDefaults/wheelchairAccessibility

    The maximum slope as a fraction of 1.

    9 percent would be 0.09

    "},{"location":"RouteRequest/#rd_wheelchairAccessibility_slopeExceededReluctance","title":"slopeExceededReluctance","text":"

    Since version: 2.2 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 1.0 Path: /routingDefaults/wheelchairAccessibility

    How much streets with high slope should be avoided.

    What factor should be given to street edges, which are over the max slope. The penalty is not static but scales with how much you exceed the maximum slope. Set to negative to disable routing on too steep edges.

    "},{"location":"RouteRequest/#rd_wheelchairAccessibility_stairsReluctance","title":"stairsReluctance","text":"

    Since version: 2.2 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 100.0 Path: /routingDefaults/wheelchairAccessibility

    How much stairs should be avoided.

    Stairs are not completely excluded for wheelchair users but severely punished. This value determines how much they are punished. This should be a very high value as you want to only include stairs as a last result.

    "},{"location":"RouteRequest/#config-example","title":"Config Example","text":"
    // router-config.json\n{\n  \"routingDefaults\" : {\n    \"numItineraries\" : 12,\n    \"transferPenalty\" : 0,\n    \"turnReluctance\" : 1.0,\n    \"elevatorBoardTime\" : 90,\n    \"elevatorBoardCost\" : 90,\n    \"elevatorHopTime\" : 20,\n    \"elevatorHopCost\" : 20,\n    \"bicycle\" : {\n      \"speed\" : 5,\n      \"reluctance\" : 5.0,\n      \"boardCost\" : 600,\n      \"walk\" : {\n        \"reluctance\" : 10.0,\n        \"stairsReluctance\" : 150.0\n      },\n      \"rental\" : {\n        \"pickupCost\" : 120,\n        \"dropOffTime\" : \"30s\",\n        \"dropOffCost\" : 30\n      },\n      \"parking\" : {\n        \"time\" : \"1m\",\n        \"cost\" : 120\n      },\n      \"triangle\" : {\n        \"safety\" : 0.4,\n        \"flatness\" : 0.3,\n        \"time\" : 0.3\n      }\n    },\n    \"car\" : {\n      \"reluctance\" : 10,\n      \"decelerationSpeed\" : 2.9,\n      \"accelerationSpeed\" : 2.9,\n      \"rental\" : {\n        \"pickupCost\" : 120,\n        \"dropOffTime\" : \"30s\",\n        \"dropOffCost\" : 30\n      },\n      \"parking\" : {\n        \"time\" : \"5m\",\n        \"cost\" : 600\n      }\n    },\n    \"scooter\" : {\n      \"speed\" : 5,\n      \"reluctance\" : 5.0,\n      \"rental\" : {\n        \"pickupCost\" : 120,\n        \"dropOffTime\" : \"30s\",\n        \"dropOffCost\" : 30\n      },\n      \"triangle\" : {\n        \"safety\" : 0.4,\n        \"flatness\" : 0.3,\n        \"time\" : 0.3\n      }\n    },\n    \"walk\" : {\n      \"speed\" : 1.3,\n      \"reluctance\" : 4.0,\n      \"stairsReluctance\" : 1.65,\n      \"boardCost\" : 600,\n      \"escalatorReluctance\" : 1.5\n    },\n    \"waitReluctance\" : 1.0,\n    \"otherThanPreferredRoutesPenalty\" : 300,\n    \"transferSlack\" : \"2m\",\n    \"boardSlackForMode\" : {\n      \"AIRPLANE\" : \"35m\"\n    },\n    \"alightSlackForMode\" : {\n      \"AIRPLANE\" : \"15m\"\n    },\n    \"transitReluctanceForMode\" : {\n      \"RAIL\" : 0.85\n    },\n    \"accessEgress\" : {\n      \"maxDuration\" : \"45m\",\n      \"maxDurationForMode\" : {\n        \"BIKE_RENTAL\" : \"20m\"\n      },\n      \"maxStopCount\" : 500,\n      \"penalty\" : {\n        \"FLEXIBLE\" : {\n          \"timePenalty\" : \"2m + 1.1t\",\n          \"costFactor\" : 1.7\n        }\n      }\n    },\n    \"itineraryFilters\" : {\n      \"transitGeneralizedCostLimit\" : {\n        \"costLimitFunction\" : \"15m + 1.5 x\",\n        \"intervalRelaxFactor\" : 0.4\n      },\n      \"nonTransitGeneralizedCostLimit\" : \"400 + 1.5x\",\n      \"removeTransitWithHigherCostThanBestOnStreetOnly\" : \"60 + 1.3x\",\n      \"bikeRentalDistanceRatio\" : 0.3,\n      \"accessibilityScore\" : true,\n      \"minBikeParkingDistance\" : 300,\n      \"debug\" : \"limit-to-search-window\"\n    },\n    \"ignoreRealtimeUpdates\" : false,\n    \"geoidElevation\" : false,\n    \"maxJourneyDuration\" : \"36h\",\n    \"unpreferred\" : {\n      \"agencies\" : [\n        \"HSL:123\"\n      ],\n      \"routes\" : [\n        \"HSL:456\"\n      ]\n    },\n    \"unpreferredCost\" : \"10m + 2.0 x\",\n    \"streetRoutingTimeout\" : \"5s\",\n    \"transferOptimization\" : {\n      \"optimizeTransferWaitTime\" : true,\n      \"minSafeWaitTimeFactor\" : 5.0,\n      \"backTravelWaitTimeFactor\" : 1.0,\n      \"extraStopBoardAlightCostsFactor\" : 8.0\n    },\n    \"wheelchairAccessibility\" : {\n      \"trip\" : {\n        \"onlyConsiderAccessible\" : false,\n        \"unknownCost\" : 600,\n        \"inaccessibleCost\" : 3600\n      },\n      \"stop\" : {\n        \"onlyConsiderAccessible\" : false,\n        \"unknownCost\" : 600,\n        \"inaccessibleCost\" : 3600\n      },\n      \"elevator\" : {\n        \"onlyConsiderAccessible\" : false,\n        \"unknownCost\" : 20,\n        \"inaccessibleCost\" : 3600\n      },\n      \"inaccessibleStreetReluctance\" : 25,\n      \"maxSlope\" : 0.083,\n      \"slopeExceededReluctance\" : 1,\n      \"stairsReluctance\" : 100\n    }\n  }\n}\n
    "},{"location":"RouterConfiguration/","title":"Router","text":""},{"location":"RouterConfiguration/#router-configuration","title":"Router configuration","text":"

    This section covers all options that can be set for each router using the router-config.json file. These options can be applied by the OTP server without rebuilding the graph.

    "},{"location":"RouterConfiguration/#configure-using-command-line-arguments","title":"Configure using command-line arguments","text":"

    Certain settings can be provided on the command line, when starting OpenTripPlanner. See the CommandLineParameters class for a full list of arguments .

    "},{"location":"RouterConfiguration/#routing-defaults","title":"Routing defaults","text":"

    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 RouteRequest.

    "},{"location":"RouterConfiguration/#parameter-summary","title":"Parameter Summary","text":"Config Parameter Type Summary Req./Opt. Default Value Since configVersion string Deployment version of the router-config.json. Optional 2.1 flex object Configuration for flex routing. Optional 2.1 rideHailingServices object[] Configuration for interfaces to external ride hailing services like Uber. Optional 2.3 routingDefaults object The default parameters for the routing query. Optional 2.0 server object Configuration for router server. Optional 2.4 apiProcessingTimeout duration Maximum processing time for an API request Optional \"PT-1S\" 2.4 traceParameters object[] Trace OTP request using HTTP request/response parameter(s) combined with logging. Optional 2.4 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0generateIdIfMissing boolean If true a unique value is generated if no http request header is provided, or the value is missing. Optional false 2.4 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0httpRequestHeader string The header-key to use when fetching the trace parameter value Optional 2.4 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0httpResponseHeader string The header-key to use when saving the value back into the http response Optional 2.4 logKey string The log event key used. Optional 2.4 timetableUpdates object Global configuration for timetable updaters. Optional 2.2 maxSnapshotFrequency duration How long a snapshot should be cached. Optional \"PT1S\" 2.2 \u00a0\u00a0\u00a0purgeExpiredData boolean Should expired real-time data be purged from the graph. Apply to GTFS-RT and Siri updates. Optional true 2.2 transit object Configuration for transit searches with RAPTOR. Optional na iterationDepartureStepInSeconds integer Step for departure times between each RangeRaptor iterations. Optional 60 na maxNumberOfTransfers integer This parameter is used to allocate enough memory space for Raptor. Optional 12 na maxSearchWindow duration Upper limit of the request parameter searchWindow. Optional \"PT24H\" 2.4 scheduledTripBinarySearchThreshold integer This threshold is used to determine when to perform a binary trip schedule search. Optional 50 na searchThreadPoolSize integer Split a travel search in smaller jobs and run them in parallel to improve performance. Optional 0 na transferCacheMaxSize integer The maximum number of distinct transfers parameters to cache pre-calculated transfers for. Optional 25 na dynamicSearchWindow object The dynamic search window coefficients used to calculate the EDT, LAT and SW. Optional 2.1 maxWindow duration Upper limit for the search-window calculation. Optional \"PT3H\" 2.2 minTransitTimeCoefficient double The coefficient to multiply with minTransitTime. Optional 0.5 2.1 minWaitTimeCoefficient double The coefficient to multiply with minWaitTime. Optional 0.5 2.1 minWindow duration The constant minimum duration for a raptor-search-window. Optional \"PT40M\" 2.2 stepMinutes integer Used to set the steps the search-window is rounded to. Optional 10 2.1 pagingSearchWindowAdjustments duration[] The provided array of durations is used to increase the search-window for the next/previous page. Optional na stopBoardAlightDuringTransferCost enum map of integer Costs for boarding and alighting during transfers at stops with a given transfer priority. Optional 2.0 transferCacheRequests object[] Routing requests to use for pre-filling the stop-to-stop transfer cache. Optional 2.3 transmodelApi object Configuration for the Transmodel GraphQL API. Optional 2.1 hideFeedId boolean Hide the FeedId in all API output, and add it to input. Optional false na maxNumberOfResultFields integer The maximum number of fields in a GraphQL result Optional 1000000 2.6 tracingHeaderTags string[] Used to group requests when monitoring OTP. Optional na updaters object[] Configuration for the updaters that import various types of data into OTP. Optional 1.5 vectorTiles object Vector tile configuration Optional na vehicleRentalServiceDirectory object Configuration for the vehicle rental service directory. Optional 2.0"},{"location":"RouterConfiguration/#parameter-details","title":"Parameter Details","text":""},{"location":"RouterConfiguration/#configVersion","title":"configVersion","text":"

    Since version: 2.1 \u2219 Type: string \u2219 Cardinality: Optional Path: /

    Deployment version of the router-config.json.

    The config-version is a parameter which each OTP deployment may set to be able to query the OTP server and verify that it uses the correct version of the config. The version should be injected into the config in the (continuous) deployment pipeline. How this is done, is up to the deployment.

    The config-version has no effect on OTP, and is provided as is on the API. There is no syntax or format check on the version and it can be any string.

    Be aware that OTP uses the config embedded in the loaded graph if no new config is provided.

    "},{"location":"RouterConfiguration/#server","title":"server","text":"

    Since version: 2.4 \u2219 Type: object \u2219 Cardinality: Optional Path: /

    Configuration for router server.

    These parameters are used to configure the router server. Many parameters are specific to a domain, these are set in the routing request.

    "},{"location":"RouterConfiguration/#server_apiProcessingTimeout","title":"apiProcessingTimeout","text":"

    Since version: 2.4 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT-1S\" Path: /server

    Maximum processing time for an API request

    This timeout limits the server-side processing time for a given API request. This does not include network latency nor waiting time in the HTTP server thread pool. The default value is -1s(no timeout). The timeout is applied to all APIs (REST, Transmodel & GTFS GraphQL). The timeout is not enforced when the parallel routing OTP feature is in use.

    "},{"location":"RouterConfiguration/#server_traceParameters","title":"traceParameters","text":"

    Since version: 2.4 \u2219 Type: object[] \u2219 Cardinality: Optional Path: /server

    Trace OTP request using HTTP request/response parameter(s) combined with logging.

    OTP supports tracing user requests across log events and \"outside\" services. OTP can insert http-request-header parameters into all associated log events and into the http response. If the value is not present in the request, a unique value can be generated. The OTP generated value is a 6 characters long base 36[0-9a-z] character string.

    Use-case Correlation-ID

    A common use-case in a service oriented environment is to use a correlation-id to identify all log messages across multiple (micro-)services from the same user. This is done by setting the \"X-Correlation-ID\" http header in the http facade/gateway. Use the \"traceParameters\" to configure OTP to pick up the correlation id, insert it into the logs and return it. See the example below on how-to configure the \"server.traceParameters\" instance.

    "},{"location":"RouterConfiguration/#server_traceParameters_0_logKey","title":"logKey","text":"

    Since version: 2.4 \u2219 Type: string \u2219 Cardinality: Optional Path: /server/traceParameters/[0]

    The log event key used.

    OTP stores the key/value pair in the log MDC(Mapped Diagnostic Context). To use it you normally include the key in the log pattern like this: %X{LOG-KEY}. See your log framework for details. Only log4j and logback support this.

    "},{"location":"RouterConfiguration/#timetableUpdates_maxSnapshotFrequency","title":"maxSnapshotFrequency","text":"

    Since version: 2.2 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT1S\" Path: /timetableUpdates

    How long a snapshot should be cached.

    If a timetable snapshot is requested less than this number of milliseconds after the previous snapshot, then return the same instance. Throttles the potentially resource-consuming task of duplicating a TripPattern \u2192 Timetable map and indexing the new Timetables. Applies to GTFS-RT and Siri updates.

    "},{"location":"RouterConfiguration/#transit","title":"transit","text":"

    Since version: na \u2219 Type: object \u2219 Cardinality: Optional Path: /

    Configuration for transit searches with RAPTOR.

    Some of these parameters for tuning transit routing are 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.

    "},{"location":"RouterConfiguration/#transit_iterationDepartureStepInSeconds","title":"iterationDepartureStepInSeconds","text":"

    Since version: na \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 60 Path: /transit

    Step for departure times between each RangeRaptor iterations.

    This is a performance optimization parameter. A transit network usually uses minute resolution for the timetables, so to match that, set this variable to 60 seconds. Setting it to less than 60 will not give better result, but degrade performance. Setting it to 120 seconds will improve performance, but you might get a slack of 60 seconds somewhere in the result.

    "},{"location":"RouterConfiguration/#transit_maxNumberOfTransfers","title":"maxNumberOfTransfers","text":"

    Since version: na \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 12 Path: /transit

    This parameter is used to allocate enough memory space for Raptor.

    Set it to the maximum number of transfers for any given itinerary expected to be found within the entire transit network. The memory overhead of setting this higher than the maximum number of transfers is very little so it is better to set it too high than to low.

    "},{"location":"RouterConfiguration/#transit_maxSearchWindow","title":"maxSearchWindow","text":"

    Since version: 2.4 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT24H\" Path: /transit

    Upper limit of the request parameter searchWindow.

    Maximum search window that can be set through the searchWindow API parameter. Due to the way timetable data are collected before a Raptor trip search, using a search window larger than 24 hours may lead to inconsistent search results. Limiting the search window prevents also potential performance issues. The recommended maximum value is 24 hours. This parameter does not restrict the maximum duration of a dynamic search window (use the parameter transit.dynamicSearchWindow.maxWindow to specify such a restriction).

    "},{"location":"RouterConfiguration/#transit_scheduledTripBinarySearchThreshold","title":"scheduledTripBinarySearchThreshold","text":"

    Since version: na \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 50 Path: /transit

    This threshold is used to determine when to perform a binary trip schedule search.

    This reduce the number of trips departure time lookups and comparisons. When testing with data from Entur and all of Norway as a Graph, the optimal value was about 50. If you calculate the departure time every time or want to fine tune the performance, changing this may improve the performance a few percents.

    "},{"location":"RouterConfiguration/#transit_searchThreadPoolSize","title":"searchThreadPoolSize","text":"

    Since version: na \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 0 Path: /transit

    Split a travel search in smaller jobs and run them in parallel to improve performance.

    Use this parameter to set the total number of executable threads available across all searches. Multiple searches can run in parallel - this parameter has no effect with regard to that. If 0, no extra threads are started and the search is done in one thread.

    "},{"location":"RouterConfiguration/#transit_transferCacheMaxSize","title":"transferCacheMaxSize","text":"

    Since version: na \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 25 Path: /transit

    The maximum number of distinct transfers parameters to cache pre-calculated transfers for.

    If too low, requests may be slower. If too high, more memory may be used then required.

    "},{"location":"RouterConfiguration/#transit_dynamicSearchWindow","title":"dynamicSearchWindow","text":"

    Since version: 2.1 \u2219 Type: object \u2219 Cardinality: Optional Path: /transit

    The dynamic search window coefficients used to calculate the EDT, LAT and SW.

    The dynamic search window coefficients is used to calculate EDT(earliest-departure-time), LAT(latest-arrival-time) and SW(raptor-search-window) request parameters using heuristics. The heuristics perform a Raptor search (one-iteration) to find a trip which we use to find a lower bound for the travel duration time - the \"minTransitTime\". The heuristic search is used for other purposes too, and is very fast.

    At least the EDT or the LAT must be passed into Raptor to perform a Range Raptor search. If unknown/missing the parameters(EDT, LAT, DW) are dynamically calculated. The dynamic coefficients affect the performance and should be tuned to match the deployment.

    The request parameters are calculated like this:

        DW  = round_N(C + T * minTransitTime + W * minWaitTime)\n    LAT = EDT + DW + minTransitTime\n    EDT = LAT - (DW + minTransitTime)\n

    The round_N(...) method rounds the input to the closest multiplication of N.

    The 3 coefficients above are:

    In addition there is an upper bound on the calculation of the search window: maxWindow.

    "},{"location":"RouterConfiguration/#transit_dynamicSearchWindow_maxWindow","title":"maxWindow","text":"

    Since version: 2.2 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT3H\" Path: /transit/dynamicSearchWindow

    Upper limit for the search-window calculation.

    Long search windows consume a lot of resources and may take a long time. Use this parameter to tune the desired maximum search time.

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

    "},{"location":"RouterConfiguration/#transit_dynamicSearchWindow_minTransitTimeCoefficient","title":"minTransitTimeCoefficient","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.5 Path: /transit/dynamicSearchWindow

    The coefficient to multiply with minTransitTime.

    Use a value between 0.0 and 3.0. Using 0.0 will eliminate the minTransitTime from the dynamic raptor-search-window calculation.

    "},{"location":"RouterConfiguration/#transit_dynamicSearchWindow_minWaitTimeCoefficient","title":"minWaitTimeCoefficient","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.5 Path: /transit/dynamicSearchWindow

    The coefficient to multiply with minWaitTime.

    Use a value between 0.0 and 1.0. Using 0.0 will eliminate the minWaitTime from the dynamic raptor-search-window calculation.

    "},{"location":"RouterConfiguration/#transit_dynamicSearchWindow_minWindow","title":"minWindow","text":"

    Since version: 2.2 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT40M\" Path: /transit/dynamicSearchWindow

    The constant minimum duration for a raptor-search-window.

    Use a value between 20 and 180 minutes in a normal deployment.

    "},{"location":"RouterConfiguration/#transit_dynamicSearchWindow_stepMinutes","title":"stepMinutes","text":"

    Since version: 2.1 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 10 Path: /transit/dynamicSearchWindow

    Used to set the steps the search-window is rounded to.

    The search window is rounded off to the closest multiplication of stepMinutes. If stepMinutes = 10 minutes, the search-window can be 10, 20, 30 ... minutes. It the computed search-window is 5 minutes and 17 seconds it will be rounded up to 10 minutes.

    Use a value between 1 and 60. This should be less than the min-raptor-search-window coefficient.

    "},{"location":"RouterConfiguration/#transit_pagingSearchWindowAdjustments","title":"pagingSearchWindowAdjustments","text":"

    Since version: na \u2219 Type: duration[] \u2219 Cardinality: Optional Path: /transit

    The provided array of durations is used to increase the search-window for the next/previous page.

    The search window is expanded when the current page return few options. If ZERO result is returned the first duration in the list is used, if ONE result is returned then the second duration is used and so on. The duration is added to the existing search-window and inserted into the next and previous page cursor. See JavaDoc for TransitTuningParameters#pagingSearchWindowAdjustments\" + for more info.\"

    "},{"location":"RouterConfiguration/#transit_stopBoardAlightDuringTransferCost","title":"stopBoardAlightDuringTransferCost","text":"

    Since version: 2.0 \u2219 Type: enum map of integer \u2219 Cardinality: Optional Path: /transit Enum keys: preferred | recommended | allowed | discouraged

    Costs for boarding and alighting during transfers at stops with a given transfer priority.

    This cost is applied both to boarding and alighting at stops during transfers. All stops have a transfer cost priority set, the default is allowed. The stopBoardAlightDuringTransferCost parameter is optional, but if listed all values must be set.

    When a transfer occurs at the same stop, the cost will be applied twice since the cost is both for boarding and alighting,

    If not set the stopBoardAlightDuringTransferCost is ignored. This is only available for NeTEx imported Stops.

    The cost is a scalar, but is equivalent to the felt cost of riding a transit trip for 1 second.

    Config key Description Type discouraged Use a very high cost like 72 000 to eliminate transfers at the stop if not the only option. int allowed Allowed, but not recommended. Use something like 150. int 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 stopBoardAlightDuringTransferCost is listed.

    "},{"location":"RouterConfiguration/#transit_transferCacheRequests","title":"transferCacheRequests","text":"

    Since version: 2.3 \u2219 Type: object[] \u2219 Cardinality: Optional Path: /transit \u2219 See: RouteRequest.md

    Routing requests to use for pre-filling the stop-to-stop transfer cache.

    If not set, the default behavior is to cache stop-to-stop transfers using the default route request (routingDefaults). Use this to change the default or specify more than one RouteRequest.

    Example

    // router-config.json\n{\n  \"transit\": {\n    \"transferCacheRequests\": [\n      { \"modes\": \"WALK\"                                                     },\n      { \"modes\": \"WALK\",    \"wheelchairAccessibility\": { \"enabled\": true  } }\n    ]\n  }\n}\n
    "},{"location":"RouterConfiguration/#transmodelApi_hideFeedId","title":"hideFeedId","text":"

    Since version: na \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /transmodelApi

    Hide the FeedId in all API output, and add it to input.

    Only turn this feature on if you have unique ids across all feeds, without the feedId prefix.

    "},{"location":"RouterConfiguration/#transmodelApi_maxNumberOfResultFields","title":"maxNumberOfResultFields","text":"

    Since version: 2.6 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 1000000 Path: /transmodelApi

    The maximum number of fields in a GraphQL result

    Enforce rate limiting based on query complexity; Queries that return too much data are cancelled.

    "},{"location":"RouterConfiguration/#transmodelApi_tracingHeaderTags","title":"tracingHeaderTags","text":"

    Since version: na \u2219 Type: string[] \u2219 Cardinality: Optional Path: /transmodelApi

    Used to group requests when monitoring OTP.

    "},{"location":"RouterConfiguration/#router-config-example","title":"Router Config Example","text":"
    // router-config.json\n{\n  \"configVersion\" : \"v2.4.0-EN000121\",\n  \"server\" : {\n    \"apiProcessingTimeout\" : \"7s\",\n    \"traceParameters\" : [\n      {\n        \"httpRequestHeader\" : \"X-Correlation-ID\",\n        \"httpResponseHeader\" : \"X-Correlation-ID\",\n        \"logKey\" : \"correlationId\",\n        \"generateIdIfMissing\" : true\n      }\n    ]\n  },\n  \"routingDefaults\" : {\n    \"numItineraries\" : 12,\n    \"transferPenalty\" : 0,\n    \"turnReluctance\" : 1.0,\n    \"elevatorBoardTime\" : 90,\n    \"elevatorBoardCost\" : 90,\n    \"elevatorHopTime\" : 20,\n    \"elevatorHopCost\" : 20,\n    \"bicycle\" : {\n      \"speed\" : 5,\n      \"reluctance\" : 5.0,\n      \"boardCost\" : 600,\n      \"walk\" : {\n        \"reluctance\" : 10.0,\n        \"stairsReluctance\" : 150.0\n      },\n      \"rental\" : {\n        \"pickupCost\" : 120,\n        \"dropOffTime\" : \"30s\",\n        \"dropOffCost\" : 30\n      },\n      \"parking\" : {\n        \"time\" : \"1m\",\n        \"cost\" : 120\n      },\n      \"triangle\" : {\n        \"safety\" : 0.4,\n        \"flatness\" : 0.3,\n        \"time\" : 0.3\n      }\n    },\n    \"car\" : {\n      \"reluctance\" : 10,\n      \"decelerationSpeed\" : 2.9,\n      \"accelerationSpeed\" : 2.9,\n      \"rental\" : {\n        \"pickupCost\" : 120,\n        \"dropOffTime\" : \"30s\",\n        \"dropOffCost\" : 30\n      },\n      \"parking\" : {\n        \"time\" : \"5m\",\n        \"cost\" : 600\n      }\n    },\n    \"scooter\" : {\n      \"speed\" : 5,\n      \"reluctance\" : 5.0,\n      \"rental\" : {\n        \"pickupCost\" : 120,\n        \"dropOffTime\" : \"30s\",\n        \"dropOffCost\" : 30\n      },\n      \"triangle\" : {\n        \"safety\" : 0.4,\n        \"flatness\" : 0.3,\n        \"time\" : 0.3\n      }\n    },\n    \"walk\" : {\n      \"speed\" : 1.3,\n      \"reluctance\" : 4.0,\n      \"stairsReluctance\" : 1.65,\n      \"boardCost\" : 600,\n      \"escalatorReluctance\" : 1.5\n    },\n    \"waitReluctance\" : 1.0,\n    \"otherThanPreferredRoutesPenalty\" : 300,\n    \"transferSlack\" : \"2m\",\n    \"boardSlackForMode\" : {\n      \"AIRPLANE\" : \"35m\"\n    },\n    \"alightSlackForMode\" : {\n      \"AIRPLANE\" : \"15m\"\n    },\n    \"transitReluctanceForMode\" : {\n      \"RAIL\" : 0.85\n    },\n    \"accessEgress\" : {\n      \"maxDuration\" : \"45m\",\n      \"maxDurationForMode\" : {\n        \"BIKE_RENTAL\" : \"20m\"\n      },\n      \"maxStopCount\" : 500,\n      \"penalty\" : {\n        \"FLEXIBLE\" : {\n          \"timePenalty\" : \"2m + 1.1t\",\n          \"costFactor\" : 1.7\n        }\n      }\n    },\n    \"itineraryFilters\" : {\n      \"transitGeneralizedCostLimit\" : {\n        \"costLimitFunction\" : \"15m + 1.5 x\",\n        \"intervalRelaxFactor\" : 0.4\n      },\n      \"nonTransitGeneralizedCostLimit\" : \"400 + 1.5x\",\n      \"removeTransitWithHigherCostThanBestOnStreetOnly\" : \"60 + 1.3x\",\n      \"bikeRentalDistanceRatio\" : 0.3,\n      \"accessibilityScore\" : true,\n      \"minBikeParkingDistance\" : 300,\n      \"debug\" : \"limit-to-search-window\"\n    },\n    \"ignoreRealtimeUpdates\" : false,\n    \"geoidElevation\" : false,\n    \"maxJourneyDuration\" : \"36h\",\n    \"unpreferred\" : {\n      \"agencies\" : [\n        \"HSL:123\"\n      ],\n      \"routes\" : [\n        \"HSL:456\"\n      ]\n    },\n    \"unpreferredCost\" : \"10m + 2.0 x\",\n    \"streetRoutingTimeout\" : \"5s\",\n    \"transferOptimization\" : {\n      \"optimizeTransferWaitTime\" : true,\n      \"minSafeWaitTimeFactor\" : 5.0,\n      \"backTravelWaitTimeFactor\" : 1.0,\n      \"extraStopBoardAlightCostsFactor\" : 8.0\n    },\n    \"wheelchairAccessibility\" : {\n      \"trip\" : {\n        \"onlyConsiderAccessible\" : false,\n        \"unknownCost\" : 600,\n        \"inaccessibleCost\" : 3600\n      },\n      \"stop\" : {\n        \"onlyConsiderAccessible\" : false,\n        \"unknownCost\" : 600,\n        \"inaccessibleCost\" : 3600\n      },\n      \"elevator\" : {\n        \"onlyConsiderAccessible\" : false,\n        \"unknownCost\" : 20,\n        \"inaccessibleCost\" : 3600\n      },\n      \"inaccessibleStreetReluctance\" : 25,\n      \"maxSlope\" : 0.083,\n      \"slopeExceededReluctance\" : 1,\n      \"stairsReluctance\" : 100\n    }\n  },\n  \"flex\" : {\n    \"maxTransferDuration\" : \"5m\",\n    \"maxFlexTripDuration\" : \"45m\",\n    \"maxAccessWalkDuration\" : \"15m\",\n    \"maxEgressWalkDuration\" : \"15m\"\n  },\n  \"transit\" : {\n    \"maxNumberOfTransfers\" : 12,\n    \"dynamicSearchWindow\" : {\n      \"minTransitTimeCoefficient\" : 0.5,\n      \"minWaitTimeCoefficient\" : 0.5,\n      \"minWindow\" : \"1h\",\n      \"maxWindow\" : \"5h\"\n    },\n    \"stopBoardAlightDuringTransferCost\" : {\n      \"DISCOURAGED\" : 1500,\n      \"ALLOWED\" : 75,\n      \"RECOMMENDED\" : 30,\n      \"PREFERRED\" : 0\n    },\n    \"transferCacheRequests\" : [\n      {\n        \"modes\" : \"WALK\"\n      },\n      {\n        \"modes\" : \"WALK\",\n        \"wheelchairAccessibility\" : {\n          \"enabled\" : true\n        }\n      }\n    ]\n  },\n  \"vehicleRentalServiceDirectory\" : {\n    \"url\" : \"https://entur.no/bikeRentalServiceDirectory\",\n    \"sourcesName\" : \"systems\",\n    \"updaterUrlName\" : \"url\",\n    \"updaterNetworkName\" : \"id\",\n    \"headers\" : {\n      \"ET-Client-Name\" : \"MY_ORG_CLIENT_NAME\"\n    }\n  },\n  \"transmodelApi\" : {\n    \"hideFeedId\" : true\n  },\n  \"vectorTiles\" : {\n    \"basePath\" : \"/otp_ct/vectorTiles\",\n    \"layers\" : [\n      {\n        \"name\" : \"stops\",\n        \"type\" : \"Stop\",\n        \"mapper\" : \"Digitransit\",\n        \"maxZoom\" : 20,\n        \"minZoom\" : 14,\n        \"cacheMaxSeconds\" : 600\n      },\n      {\n        \"name\" : \"areaStops\",\n        \"type\" : \"AreaStop\",\n        \"mapper\" : \"OTPRR\",\n        \"maxZoom\" : 20,\n        \"minZoom\" : 14,\n        \"cacheMaxSeconds\" : 600\n      },\n      {\n        \"name\" : \"stations\",\n        \"type\" : \"Station\",\n        \"mapper\" : \"Digitransit\",\n        \"maxZoom\" : 20,\n        \"minZoom\" : 12,\n        \"cacheMaxSeconds\" : 600\n      },\n      {\n        \"name\" : \"rentalPlaces\",\n        \"type\" : \"VehicleRental\",\n        \"mapper\" : \"Digitransit\",\n        \"maxZoom\" : 20,\n        \"minZoom\" : 14,\n        \"cacheMaxSeconds\" : 60,\n        \"expansionFactor\" : 0.25\n      },\n      {\n        \"name\" : \"rentalVehicle\",\n        \"type\" : \"VehicleRentalVehicle\",\n        \"mapper\" : \"Digitransit\",\n        \"maxZoom\" : 20,\n        \"minZoom\" : 14,\n        \"cacheMaxSeconds\" : 60\n      },\n      {\n        \"name\" : \"rentalStation\",\n        \"type\" : \"VehicleRentalStation\",\n        \"mapper\" : \"Digitransit\",\n        \"maxZoom\" : 20,\n        \"minZoom\" : 14,\n        \"cacheMaxSeconds\" : 600\n      },\n      {\n        \"name\" : \"vehicleParking\",\n        \"type\" : \"VehicleParking\",\n        \"mapper\" : \"Digitransit\",\n        \"maxZoom\" : 20,\n        \"minZoom\" : 14,\n        \"cacheMaxSeconds\" : 60,\n        \"expansionFactor\" : 0.25\n      }\n    ]\n  },\n  \"timetableUpdates\" : {\n    \"purgeExpiredData\" : false,\n    \"maxSnapshotFrequency\" : \"2s\"\n  },\n  \"updaters\" : [\n    {\n      \"type\" : \"real-time-alerts\",\n      \"frequency\" : \"30s\",\n      \"url\" : \"http://developer.trimet.org/ws/V1/FeedSpecAlerts/appID/0123456789ABCDEF\",\n      \"feedId\" : \"TriMet\",\n      \"headers\" : {\n        \"Some-Header\" : \"A-Value\"\n      }\n    },\n    {\n      \"type\" : \"vehicle-rental\",\n      \"network\" : \"socialbicycles_coast\",\n      \"sourceType\" : \"gbfs\",\n      \"language\" : \"en\",\n      \"frequency\" : \"1m\",\n      \"allowKeepingRentedVehicleAtDestination\" : false,\n      \"geofencingZones\" : false,\n      \"url\" : \"http://coast.socialbicycles.com/opendata/gbfs.json\",\n      \"headers\" : {\n        \"Auth\" : \"<any-token>\",\n        \"<key>\" : \"<value>\"\n      }\n    },\n    {\n      \"type\" : \"vehicle-parking\",\n      \"sourceType\" : \"hsl-park\",\n      \"feedId\" : \"hslpark\",\n      \"timeZone\" : \"Europe/Helsinki\",\n      \"facilitiesFrequencySec\" : 3600,\n      \"facilitiesUrl\" : \"https://p.hsl.fi/api/v1/facilities.json?limit=-1\",\n      \"utilizationsFrequencySec\" : 600,\n      \"utilizationsUrl\" : \"https://p.hsl.fi/api/v1/utilizations.json?limit=-1\",\n      \"hubsUrl\" : \"https://p.hsl.fi/api/v1/hubs.json?limit=-1\"\n    },\n    {\n      \"type\" : \"vehicle-parking\",\n      \"sourceType\" : \"park-api\",\n      \"feedId\" : \"parkapi\",\n      \"timeZone\" : \"Europe/Berlin\",\n      \"frequency\" : \"10m\",\n      \"url\" : \"https://foo.bar\",\n      \"headers\" : {\n        \"Cache-Control\" : \"max-age=604800\"\n      },\n      \"tags\" : [\n        \"source:parkapi\"\n      ]\n    },\n    {\n      \"type\" : \"vehicle-parking\",\n      \"feedId\" : \"bikely\",\n      \"sourceType\" : \"bikely\",\n      \"url\" : \"https://api.safebikely.com/api/v1/s/locations\",\n      \"headers\" : {\n        \"X-Bikely-Token\" : \"${BIKELY_TOKEN}\",\n        \"Authorization\" : \"${BIKELY_AUTHORIZATION}\"\n      }\n    },\n    {\n      \"type\" : \"stop-time-updater\",\n      \"frequency\" : \"1m\",\n      \"backwardsDelayPropagationType\" : \"REQUIRED_NO_DATA\",\n      \"url\" : \"http://developer.trimet.org/ws/V1/TripUpdate/appID/0123456789ABCDEF\",\n      \"feedId\" : \"TriMet\",\n      \"headers\" : {\n        \"Authorization\" : \"A-Token\"\n      }\n    },\n    {\n      \"type\" : \"mqtt-gtfs-rt-updater\",\n      \"url\" : \"tcp://pred.rt.hsl.fi\",\n      \"topic\" : \"gtfsrt/v2/fi/hsl/tu\",\n      \"feedId\" : \"HSL\",\n      \"fuzzyTripMatching\" : true\n    },\n    {\n      \"type\" : \"vehicle-positions\",\n      \"url\" : \"https://s3.amazonaws.com/kcm-alerts-realtime-prod/vehiclepositions.pb\",\n      \"feedId\" : \"1\",\n      \"frequency\" : \"1m\",\n      \"headers\" : {\n        \"Header-Name\" : \"Header-Value\"\n      },\n      \"fuzzyTripMatching\" : false,\n      \"features\" : [\n        \"position\"\n      ]\n    },\n    {\n      \"type\" : \"siri-et-updater\",\n      \"url\" : \"https://example.com/some/path\",\n      \"feedId\" : \"feed_id\",\n      \"timeout\" : \"30s\",\n      \"headers\" : {\n        \"Authorization\" : \"Some-Token\"\n      }\n    },\n    {\n      \"type\" : \"siri-sx-updater\",\n      \"url\" : \"https://example.com/some/path\",\n      \"feedId\" : \"feed_id\",\n      \"timeout\" : \"30s\",\n      \"headers\" : {\n        \"Key\" : \"Value\"\n      }\n    },\n    {\n      \"type\" : \"siri-azure-sx-updater\",\n      \"topic\" : \"some_topic\",\n      \"servicebus-url\" : \"service_bus_url\",\n      \"feedId\" : \"feed_id\",\n      \"customMidnight\" : 4,\n      \"history\" : {\n        \"url\" : \"endpoint_url\",\n        \"fromDateTime\" : \"-P1D\",\n        \"toDateTime\" : \"P1D\",\n        \"timeout\" : 300000\n      }\n    },\n    {\n      \"type\" : \"siri-azure-et-updater\",\n      \"topic\" : \"some_topic\",\n      \"authenticationType\" : \"SharedAccessKey\",\n      \"fullyQualifiedNamespace\" : \"fully_qualified_namespace\",\n      \"servicebus-url\" : \"service_bus_url\",\n      \"feedId\" : \"feed_id\",\n      \"customMidnight\" : 4,\n      \"history\" : {\n        \"url\" : \"endpoint_url\",\n        \"fromDateTime\" : \"-P1D\",\n        \"timeout\" : 300000\n      }\n    },\n    {\n      \"type\" : \"siri-et-google-pubsub-updater\",\n      \"feedId\" : \"feed_id\",\n      \"reconnectPeriod\" : \"5s\",\n      \"initialGetDataTimeout\" : \"1m20s\",\n      \"topicProjectName\" : \"google_pubsub_topic_project_name\",\n      \"subscriptionProjectName\" : \"google_pubsub_subscription_project_name\",\n      \"topicName\" : \"estimated_timetables\",\n      \"dataInitializationUrl\" : \"https://example.com/some/path\",\n      \"fuzzyTripMatching\" : true\n    },\n    {\n      \"type\" : \"vehicle-parking\",\n      \"feedId\" : \"bikeep\",\n      \"sourceType\" : \"bikeep\",\n      \"url\" : \"https://services.bikeep.com/location/v1/public-areas/no-baia-mobility/locations\"\n    },\n    {\n      \"type\" : \"vehicle-parking\",\n      \"feedId\" : \"parking\",\n      \"sourceType\" : \"siri-fm\",\n      \"url\" : \"https://transmodel.api.opendatahub.com/siri-lite/fm/parking\"\n    }\n  ],\n  \"rideHailingServices\" : [\n    {\n      \"type\" : \"uber-car-hailing\",\n      \"clientId\" : \"secret-id\",\n      \"clientSecret\" : \"very-secret\",\n      \"wheelchairAccessibleProductId\" : \"545de0c4-659f-49c6-be65-0d5e448dffd5\",\n      \"bannedProductIds\" : [\n        \"1196d0dd-423b-4a81-a1d8-615367d3a365\",\n        \"f58761e5-8dd5-4940-a472-872f1236c596\"\n      ]\n    }\n  ]\n}\n
    "},{"location":"RoutingModes/","title":"Routing modes","text":"

    This page is intended as an exhaustive listing of what OTP's routing engine is capable of and therefore documents internal names. Since OTP has multiple APIs where each works slightly differently, please consult your API documentation on how to select the appropriate mode.

    "},{"location":"RoutingModes/#Street modes","title":"Street modes","text":"

    Routing modes on streets, including walking, biking, driving, and car-sharing.

    "},{"location":"RoutingModes/#BIKE","title":"BIKE","text":"

    Cycling for the entirety of the route or taking a bicycle onto the public transport and cycling from the arrival station to the destination.

    Taking a bicycle onto transit is only possible if information about the permission to do so is supplied in the source data. In GTFS this field is called bikesAllowed.

    "},{"location":"RoutingModes/#BIKE_RENTAL","title":"BIKE_RENTAL","text":"

    Taking a rented, shared-mobility bike for part or the entirety of the route.

    Prerequisite: Vehicle or station locations need to be added to OTP from dynamic data feeds. See Configuring GBFS on how to add one.

    "},{"location":"RoutingModes/#BIKE_TO_PARK","title":"BIKE_TO_PARK","text":"

    Leaving the bicycle at the departure station and walking from the arrival station to the destination. This mode needs to be combined with at least one transit mode otherwise it behaves like an ordinary bicycle journey.

    Prerequisite: Bicycle parking stations present in the OSM file and visible to OTP by enabling the property staticBikeParkAndRide during graph build.

    "},{"location":"RoutingModes/#CAR","title":"CAR","text":"

    Driving your own car the entirety of the route. This can be combined with transit, where will return routes with a Kiss & Ride 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.

    "},{"location":"RoutingModes/#CAR_HAILING","title":"CAR_HAILING","text":"

    Using a car hailing app like Uber or Lyft to get to a train station or all the way to the destination.

    See the sandbox documentation on how to configure it.

    "},{"location":"RoutingModes/#CAR_PICKUP","title":"CAR_PICKUP","text":"

    Walking to a pickup point along the road, driving to a drop-off point along the road, and walking the rest of the way. This can include various taxi-services or kiss & ride.

    "},{"location":"RoutingModes/#CAR_RENTAL","title":"CAR_RENTAL","text":"

    Walk to a car rental point, drive to a car rental drop-off point and walk the rest of the way. This can include car rental at fixed locations or free-floating services.

    Prerequisite: Vehicle or station locations need to be added to OTP from dynamic data feeds. See Configuring GBFS on how to add one.

    "},{"location":"RoutingModes/#CAR_TO_PARK","title":"CAR_TO_PARK","text":"

    Driving a car to the park-and-ride facilities near a station and taking publictransport. This mode needs to be combined with at least one transit mode otherwise, it behaves like an ordinary car journey. Prerequisite: Park-and-ride areas near the stations need to be present in the OSM input file.

    "},{"location":"RoutingModes/#FLEXIBLE","title":"FLEXIBLE","text":"

    Encompasses all types of on-demand and flexible transportation for example GTFS Flex or NeTEx Flexible Stop Places.

    "},{"location":"RoutingModes/#SCOOTER_RENTAL","title":"SCOOTER_RENTAL","text":"

    Walking to a scooter rental point, riding a scooter to a scooter rental drop-off point, and walking the rest of the way. This can include scooter rental at fixed locations or free-floating services.

    Prerequisite: Vehicle or station locations need to be added to OTP from dynamic data feeds. See Configuring GBFS on how to add one.

    "},{"location":"RoutingModes/#WALK","title":"WALK","text":"

    Walking some or all of the way of the route.

    "},{"location":"RoutingModes/#Transit modes","title":"Transit modes","text":"

    Routing modes for transit, including rail, bus, ferry, etc. Equivalent to GTFS route_type or to NeTEx TransportMode.

    "},{"location":"RoutingModes/#AIRPLANE","title":"AIRPLANE","text":"

    Taking an airplane

    "},{"location":"RoutingModes/#BUS","title":"BUS","text":"

    Used for short- and long-distance bus routes.

    "},{"location":"RoutingModes/#CABLE_CAR","title":"CABLE_CAR","text":"

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

    "},{"location":"RoutingModes/#CARPOOL","title":"CARPOOL","text":"

    Private car trips shared with others.

    This is currently not specified in GTFS so we use the mode type values 1550-1560 which are in the range of private taxis.

    "},{"location":"RoutingModes/#COACH","title":"COACH","text":"

    Used for long-distance bus routes.

    "},{"location":"RoutingModes/#FERRY","title":"FERRY","text":"

    Used for short- and long-distance boat service.

    "},{"location":"RoutingModes/#FUNICULAR","title":"FUNICULAR","text":"

    Used for any rail system that moves on steep inclines with a cable traction system.

    "},{"location":"RoutingModes/#GONDOLA","title":"GONDOLA","text":"

    Gondola or suspended cable car. Typically used for aerial cable cars where the car is suspended from the cable.

    "},{"location":"RoutingModes/#MONORAIL","title":"MONORAIL","text":"

    Used for any rail system that runs on a single rail.

    "},{"location":"RoutingModes/#RAIL","title":"RAIL","text":"

    Used for intercity or long-distance travel.

    "},{"location":"RoutingModes/#SUBWAY","title":"SUBWAY","text":"

    Subway or Metro, used for any underground rail system within a metropolitan area.

    "},{"location":"RoutingModes/#TAXI","title":"TAXI","text":"

    Using a taxi service

    "},{"location":"RoutingModes/#TRAM","title":"TRAM","text":"

    Tram, streetcar or light rail. Used for any light rail or street level system within a metropolitan area.

    "},{"location":"RoutingModes/#TROLLEYBUS","title":"TROLLEYBUS","text":"

    Used for trolleybus systems which draw power from overhead wires using poles on the roof of the vehicle.

    "},{"location":"SandboxExtension/","title":"OTP Sandbox Extensions","text":""},{"location":"SandboxExtension/#terminology","title":"Terminology","text":"

    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)

    "},{"location":"SandboxExtension/#sandbox-goals","title":"Sandbox Goals","text":""},{"location":"SandboxExtension/#contract","title":"Contract","text":""},{"location":"StopAreas/","title":"Stop Areas","text":"

    Public transit stations and stops can be modeled using a relation tagged with public_transport=stop_area. Description of such relations can be found from this OSM wiki page.

    OpenTripPlanner detects such relations and applies some special logic to them. Nodes, which are linked to street network, and are located within platform areas, are interpreted as connection points from the street network to the platform. OTP automatically links such points with the platform geometry in order to improve walk routing.

    For example, an elevator or stairs can connect a normal street to a railway platform above it. There is no need to add an explicit edge, which connects the entrance point with the actual geometry of the platform.

    An example: Huopalahti railway station in Helsinki

    "},{"location":"StopAreas/#instructions","title":"Instructions","text":""},{"location":"System-Requirements/","title":"System Requirements and Suggestions","text":""},{"location":"System-Requirements/#system-requirements","title":"System requirements","text":""},{"location":"System-Requirements/#memory","title":"Memory","text":"

    OTP is relatively memory-hungry as it includes all the required data in memory. How much memory is required to build the graph for OTP, or to run the OTP server, depends on the used data sets (is OSM, elevation and/or transit data included?), on the size of the covered geographical area and the density of the transit and street network. The required memory can vary from less than one GB to more than 100 GB. For example, including all available data for Finland takes a bit over 10 GB but for Germany it requires 95 GB.

    "},{"location":"System-Requirements/#processor","title":"Processor","text":"

    Single thread performance is an important factor for OTP's performance. Additionally, OTP benefits from larger CPU cache as reading from memory can be a bottleneck.

    OTP's performance scales with the number of available CPU cores. OTP processes each request in a separate thread and usually one request doesn't utilize more than one thread, but with some requests and configurations, it's possible that multiple threads are used in parallel for a small part of a request or to process multiple queries within one request. How much parallel processing we utilize in requests might change in the future. Real-time updates also run in a separate thread. Therefore, to have a good performance, it makes sense to have multiple cores available. How OTP uses parallel processing also depends on the available cores (<= 2 cores vs >2 cores) in some cases. Therefore, load testing should be done against a machine that doesn't differ too much from production machines.

    Entur and the Digitransit project have found that the 3rd generation AMD processors have a slightly better performance for OTP2 than the Intel 3rd generation CPUs (and especially better than the 2nd generation CPUs).

    "},{"location":"System-Requirements/#suggested-vm-types-in-cloud-service-providers","title":"Suggested VM types in cloud service providers","text":""},{"location":"System-Requirements/#azure","title":"Azure","text":"

    For Azure, the Digitransit project did benchmarking of the available virtual machines types for OTP 2.3 in early 2023 and found that the D2as \u2013 D96as v5 family had the best performance of the reasonable priced virtual machines types. These machines use the 3rd generation AMD EPYCTM 7763v (Milan) processor. The 3rd generation Intel machines had a slightly worse performance and a slightly higher cost. Digitransit chose to use the D8as v5 machine as it had enough memory for running OTP in Finland and a reasonable number of vCPUs.

    "},{"location":"System-Requirements/#google-cloud","title":"Google Cloud","text":"

    Entur uses a scalable fleet of instances of type c2d-standard-8.

    "},{"location":"Troubleshooting-Routing/","title":"Troubleshooting Routing","text":""},{"location":"Troubleshooting-Routing/#graph-builder-data-import-issues","title":"Graph Builder Data Import Issues","text":"

    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:

     11:35:57.515 INFO (Graph.java:970) Summary (number of each type of issues):\n 11:35:57.518 INFO (Graph.java:976)     TurnRestrictionBad - 560\n 11:35:57.518 INFO (Graph.java:976)     TurnRestrictionException - 15\n 11:35:57.518 INFO (Graph.java:976)     StopLinkedTooFar - 22\n 11:35:57.518 INFO (Graph.java:976)     HopSpeedSlow - 22\n 11:35:57.518 INFO (Graph.java:976)     Graphwide - 1\n 11:35:57.518 INFO (Graph.java:976)     GraphConnectivity - 407\n 11:35:57.519 INFO (Graph.java:976)     ParkAndRideUnlinked - 1\n 11:35:57.519 INFO (Graph.java:976)     StopNotLinkedForTransfers - 31\n 11:35:57.519 INFO (Graph.java:976)     NoFutureDates - 1\n

    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.

    "},{"location":"Troubleshooting-Routing/#debug-layers","title":"Debug layers","text":"

    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.

    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. 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:

    "},{"location":"Troubleshooting-Routing/#interpretation-traversal-permissions-layer","title":"Interpretation Traversal permissions layer","text":"

    A sample traversal permissions layer looks like the following

    "},{"location":"Troubleshooting-Routing/#openstreetmap-data","title":"OpenStreetMap Data","text":""},{"location":"Troubleshooting-Routing/#tags-affecting-permissions-and-bicycle-safety","title":"Tags affecting permissions and bicycle safety","text":"

    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 osmTagMapping config attribute.

    In the following section we will discuss the default case, which will be used if the property is not set.

    "},{"location":"Troubleshooting-Routing/#default-settings","title":"Default settings","text":"

    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.

    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.

    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.

    "},{"location":"Troubleshooting-Routing/#bicycle-safety-factor","title":"Bicycle safety factor","text":"

    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.

    How this is calculated depends on two things

    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:

    props.setProperties(\"highway=track\", StreetTraversalPermission.ALL, 1.3, 1.3);\n

    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, 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 OsmTagMapper 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):

    props.setProperties(\"surface=mud\", StreetTraversalPermission.ALL, 1.5, 1.5, true);\n

    The Javadoc of 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.

    To enable it activate the Report API sandbox feature.

    To view the output of the bicycle safety calculation on a map, check the debug layers.

    "},{"location":"Troubleshooting-Routing/#railway-platforms","title":"Railway Platforms","text":"

    OTP users in Helsinki have documented their best practices for coding railway platforms in OpenStreetMap. These guidelines are available in the OSM Wiki.

    "},{"location":"Troubleshooting-Routing/#transit-search","title":"Transit search","text":"

    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.

    Read the logging page for more information.

    "},{"location":"Troubleshooting-Routing/#gtfs-transferstxt-and-netex-interchange-import","title":"GTFS Transfers.txt and NeTEx Interchange import","text":"

    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:

      <logger name=\"TRANSFERS_EXPORT\" level=\"info\" />\n
    "},{"location":"Troubleshooting-Routing/#further-information","title":"Further information","text":""},{"location":"UpdaterConfig/","title":"Realtime Updaters","text":""},{"location":"UpdaterConfig/#updater-configuration","title":"Updater configuration","text":"

    This section covers options that can be set in the updaters section of router-config.json. See the parameter summary and examples in the router configuration documentation

    Real-time data are those that are not added to OTP during the graph build phase but during runtime.

    Real-time data sources are configured in the updaters section is an array of JSON objects, each of which has a type field and other configuration fields specific to that type.

    "},{"location":"UpdaterConfig/#gtfs-realtime","title":"GTFS-Realtime","text":"

    GTFS feeds contain schedule data that 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 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 updated from minute to minute.

    "},{"location":"UpdaterConfig/#alerts","title":"Alerts","text":"

    Alerts are text messages attached to GTFS objects, informing riders of disruptions and changes. The information is downloaded in a single HTTP request and polled regularly.

    Config Parameter Type Summary Req./Opt. Default Value Since type = \"real-time-alerts\" enum The type of the updater. Required 1.5 earlyStartSec integer How long before the posted start of an event it should be displayed to users Optional 0 1.5 feedId string The id of the feed to apply the alerts to. Required 1.5 frequency duration How often the URL should be fetched. Optional \"PT1M\" 1.5 fuzzyTripMatching boolean Whether to match trips fuzzily. Optional false 1.5 url string URL to fetch the GTFS-RT feed from. Required 1.5 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.3"},{"location":"UpdaterConfig/#parameter-details","title":"Parameter details","text":""},{"location":"UpdaterConfig/#u_0_headers","title":"headers","text":"

    Since version: 2.3 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[0]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"UpdaterConfig/#example-configuration","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"real-time-alerts\",\n      \"frequency\" : \"30s\",\n      \"url\" : \"http://developer.trimet.org/ws/V1/FeedSpecAlerts/appID/0123456789ABCDEF\",\n      \"feedId\" : \"TriMet\",\n      \"headers\" : {\n        \"Some-Header\" : \"A-Value\"\n      }\n    }\n  ]\n}\n
    "},{"location":"UpdaterConfig/#tripupdates-via-https","title":"TripUpdates via HTTP(S)","text":"

    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. The information is downloaded in a single HTTP request and polled regularly.

    Config Parameter Type Summary Req./Opt. Default Value Since type = \"stop-time-updater\" enum The type of the updater. Required 1.5 backwardsDelayPropagationType enum How backwards propagation should be handled. Optional \"required-no-data\" 2.2 feedId string Which feed the updates apply to. Required 1.5 frequency duration How often the data should be downloaded. Optional \"PT1M\" 1.5 fuzzyTripMatching boolean If the trips should be matched fuzzily. Optional false 1.5 url string The URL of the GTFS-RT resource. Required 1.5 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.3"},{"location":"UpdaterConfig/#parameter-details_1","title":"Parameter details","text":""},{"location":"UpdaterConfig/#u__5__backwardsDelayPropagationType","title":"backwardsDelayPropagationType","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"required-no-data\" Path: /updaters/[5] Enum values: required-no-data | required | always

    How backwards propagation should be handled.

    REQUIRED_NO_DATA: Default value. Only propagates delays backwards when it is required to ensure that the times are increasing, and it sets the NO_DATA flag on the stops so these automatically updated times are not exposed through APIs.

    REQUIRED: Only propagates delays backwards when it is required to ensure that the times are increasing. The updated times are exposed through APIs.

    ALWAYS Propagates delays backwards on stops with no estimates regardless if it's required or not. The updated times are exposed through APIs.

    "},{"location":"UpdaterConfig/#u__5__url","title":"url","text":"

    Since version: 1.5 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[5]

    The URL of the GTFS-RT resource.

    file: URLs are also supported if you want to read a file from the local disk.

    "},{"location":"UpdaterConfig/#u__5__headers","title":"headers","text":"

    Since version: 2.3 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[5]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"UpdaterConfig/#example-configuration_1","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"stop-time-updater\",\n      \"frequency\" : \"1m\",\n      \"backwardsDelayPropagationType\" : \"REQUIRED_NO_DATA\",\n      \"url\" : \"http://developer.trimet.org/ws/V1/TripUpdate/appID/0123456789ABCDEF\",\n      \"feedId\" : \"TriMet\",\n      \"headers\" : {\n        \"Authorization\" : \"A-Token\"\n      }\n    }\n  ]\n}\n
    "},{"location":"UpdaterConfig/#streaming-tripupdates-via-mqtt","title":"Streaming TripUpdates via MQTT","text":"

    This updater connects to an MQTT broker and processes TripUpdates in a streaming fashion. This means that they will be applied individually in near-realtime rather than in batches at a certain interval.

    This system powers the realtime updates in Helsinki and more information can be found on Github.

    Config Parameter Type Summary Req./Opt. Default Value Since type = \"mqtt-gtfs-rt-updater\" enum The type of the updater. Required 1.5 backwardsDelayPropagationType enum How backwards propagation should be handled. Optional \"required-no-data\" 2.2 feedId string The feed id to apply the updates to. Required 2.0 fuzzyTripMatching boolean Whether to match trips fuzzily. Optional false 2.0 qos integer QOS level. Optional 0 2.0 topic string The topic to subscribe to. Required 2.0 url string URL of the MQTT broker. Required 2.0"},{"location":"UpdaterConfig/#parameter-details_2","title":"Parameter details","text":""},{"location":"UpdaterConfig/#u__6__backwardsDelayPropagationType","title":"backwardsDelayPropagationType","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"required-no-data\" Path: /updaters/[6] Enum values: required-no-data | required | always

    How backwards propagation should be handled.

    REQUIRED_NO_DATA: Default value. Only propagates delays backwards when it is required to ensure that the times are increasing, and it sets the NO_DATA flag on the stops so these automatically updated times are not exposed through APIs.

    REQUIRED: Only propagates delays backwards when it is required to ensure that the times are increasing. The updated times are exposed through APIs.

    ALWAYS: Propagates delays backwards on stops with no estimates regardless if it's required or not. The updated times are exposed through APIs.

    "},{"location":"UpdaterConfig/#example-configuration_2","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"mqtt-gtfs-rt-updater\",\n      \"url\" : \"tcp://pred.rt.hsl.fi\",\n      \"topic\" : \"gtfsrt/v2/fi/hsl/tu\",\n      \"feedId\" : \"HSL\",\n      \"fuzzyTripMatching\" : true\n    }\n  ]\n}\n
    "},{"location":"UpdaterConfig/#vehicle-positions","title":"Vehicle Positions","text":"

    VehiclePositions give the location of some or all vehicles currently in service, in terms of geographic coordinates or position relative to their scheduled stops. The information is downloaded in a single HTTP request and polled regularly.

    Config Parameter Type Summary Req./Opt. Default Value Since type = \"vehicle-positions\" enum The type of the updater. Required 1.5 feedId string Feed ID to which the update should be applied. Required 2.2 frequency duration How often the positions should be updated. Optional \"PT1M\" 2.2 fuzzyTripMatching boolean Whether to match trips fuzzily. Optional false 2.5 url uri The URL of GTFS-RT protobuf HTTP resource to download the positions from. Required 2.2 features enum set Which features of GTFS RT vehicle positions should be loaded into OTP. Optional 2.5 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.3"},{"location":"UpdaterConfig/#parameter-details_3","title":"Parameter details","text":""},{"location":"UpdaterConfig/#u__7__features","title":"features","text":"

    Since version: 2.5 \u2219 Type: enum set \u2219 Cardinality: Optional Path: /updaters/[7] Enum values: position | stop-position | occupancy

    Which features of GTFS RT vehicle positions should be loaded into OTP.

    "},{"location":"UpdaterConfig/#u__7__headers","title":"headers","text":"

    Since version: 2.3 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[7]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"UpdaterConfig/#example-configuration_3","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"vehicle-positions\",\n      \"url\" : \"https://s3.amazonaws.com/kcm-alerts-realtime-prod/vehiclepositions.pb\",\n      \"feedId\" : \"1\",\n      \"frequency\" : \"1m\",\n      \"headers\" : {\n        \"Header-Name\" : \"Header-Value\"\n      },\n      \"fuzzyTripMatching\" : false,\n      \"features\" : [\n        \"position\"\n      ]\n    }\n  ]\n}\n
    "},{"location":"UpdaterConfig/#gbfs-vehicle-rental-systems","title":"GBFS vehicle rental systems","text":"

    Besides GTFS-RT transit data, OTP can also fetch real-time data about vehicle rental networks including the number of vehicles and free parking spaces at each station. We support vehicle rental systems that use the GBFS standard.

    GBFS can be used for a variety of shared mobility services, with partial support for both v1 and v2.2 (list of known GBFS feeds). OTP supports the following GBFS form factors:

    Config Parameter Type Summary Req./Opt. Default Value Since type = \"vehicle-rental\" enum The type of the updater. Required 1.5 allowKeepingRentedVehicleAtDestination boolean If a vehicle should be allowed to be kept at the end of a station-based rental. Optional false 2.1 frequency duration How often the data should be updated. Optional \"PT1M\" 1.5 geofencingZones boolean Compute rental restrictions based on GBFS 2.2 geofencing zones. Optional false 2.3 language string TODO Optional 2.1 network string The name of the network to override the one derived from the source data. Optional 1.5 overloadingAllowed boolean Allow leaving vehicles at a station even though there are no free slots. Optional false 2.2 sourceType enum What source of vehicle rental updater to use. Required 1.5 url string The URL to download the data from. Required 1.5 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 1.5"},{"location":"UpdaterConfig/#parameter-details_4","title":"Parameter details","text":""},{"location":"UpdaterConfig/#u_1_allowKeepingRentedVehicleAtDestination","title":"allowKeepingRentedVehicleAtDestination","text":"

    Since version: 2.1 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /updaters/[1]

    If a vehicle should be allowed to be kept at the end of a station-based rental.

    In some cases it may be useful to not drop off the rented vehicle before arriving at the destination. This is useful if vehicles may only be rented for round trips, or the destination is an intermediate place.

    For this to be possible three things need to be configured:

    "},{"location":"UpdaterConfig/#u_1_geofencingZones","title":"geofencingZones","text":"

    Since version: 2.3 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /updaters/[1]

    Compute rental restrictions based on GBFS 2.2 geofencing zones.

    This feature is somewhat experimental and therefore turned off by default for the following reasons:

    "},{"location":"UpdaterConfig/#u_1_network","title":"network","text":"

    Since version: 1.5 \u2219 Type: string \u2219 Cardinality: Optional Path: /updaters/[1]

    The name of the network to override the one derived from the source data.

    GBFS feeds must include a system_id which will be used as the default network. These ids are sometimes not helpful so setting this property will override it.

    "},{"location":"UpdaterConfig/#u_1_sourceType","title":"sourceType","text":"

    Since version: 1.5 \u2219 Type: enum \u2219 Cardinality: Required Path: /updaters/[1] Enum values: gbfs | smoove

    What source of vehicle rental updater to use.

    "},{"location":"UpdaterConfig/#u_1_headers","title":"headers","text":"

    Since version: 1.5 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[1]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"UpdaterConfig/#example-configuration_4","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"vehicle-rental\",\n      \"network\" : \"socialbicycles_coast\",\n      \"sourceType\" : \"gbfs\",\n      \"language\" : \"en\",\n      \"frequency\" : \"1m\",\n      \"allowKeepingRentedVehicleAtDestination\" : false,\n      \"geofencingZones\" : false,\n      \"url\" : \"http://coast.socialbicycles.com/opendata/gbfs.json\",\n      \"headers\" : {\n        \"Auth\" : \"<any-token>\",\n        \"<key>\" : \"<value>\"\n      }\n    }\n  ]\n}\n
    "},{"location":"UpdaterConfig/#other-updaters-in-sandboxes","title":"Other updaters in sandboxes","text":""},{"location":"Version-Comparison/","title":"Comparing OTP2 and OTP1","text":""},{"location":"Version-Comparison/#summary","title":"Summary","text":"

    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 2023, OTP2 is the only version to receive regular updates and OTP1 is considered legacy and unsupported. This page explains key differences between the two versions (referred to as OTP1 and OTP2).

    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 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 very similar 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.

    "},{"location":"Version-Comparison/#otp2-use-cases","title":"OTP2 Use Cases","text":"

    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.

    "},{"location":"Version-Comparison/#high-level-feature-comparison","title":"High-level feature comparison","text":"Feature OTP1 OTP2 OSM street data yes yes GTFS transit data yes yes Netex transit data no yes(Nordic profile) GTFS-Realtime yes(streaming, polling, incremental) yes(streaming, polling, incremental) SIRI Realtime no yes Elevation data TIFF and NED TIFF and NED One-to-many routing, isochrones and scripting yes no Isochrones yes yes Java version 8+ 21+ Multiple regions per server yes no Hot reloading of graphs yes no Street (OSM) routing algorithm Generalized cost A* Generalized cost A* Transit routing algorithm Generalized cost A* Multi-criteria range-RAPTOR Search segmentation Single search through access, transit, egress Access/egress separate from transit search Goal direction Upper bound search backward from destination, over streets and transit, interleaved with forward search Upper bound search backward from destination on transit only, before forward search begins Alternative itineraries \"Trip banning\", N lowest generalized costs True Pareto-optimal results Departure/arrival time Single departure or arrival time only Every minute in a window up to several days long API Paging no yes Timetable View no yes Plugin Sandbox Extensions no yes (See extensions) Data storage local, S3 (elevation only) extensible with local, ZIP,and Google Cloud plugins, S3 available Transfer Priority yes yes"},{"location":"Version-Comparison/#commentary-on-otp1-features-removed-from-otp2","title":"Commentary on OTP1 features removed from OTP2","text":"

    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.

    Some features have been removed to simplify the code base and improve maintainability. Others 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.

    "},{"location":"Version-Comparison/#analysis","title":"Analysis","text":"

    From the beginning of the project, many OTP contributors and users have used OTP in research, analysis, and planning applications. They have prototyped many ideas within the OTP codebase, including one-to-many searches producing travel time grids, isochrones, and access-to-opportunities metrics. While some of these features may still be available as optional \"sandbox\" features in OTP2, they are unsupported and may be removed in the near future.

    Most work of this kind moved over separate projects focused on urban planning and analytics. As of version 2, OTP has chosen to focus entirely on passenger information rather than analytics applications. See the Analysis page for more details.

    "},{"location":"Version-Comparison/#routers-api-and-hot-reloading","title":"Routers API and Hot Reloading","text":"

    Via its 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.

    "},{"location":"Version-Comparison/#routing-request-parameters","title":"Routing request parameters","text":"

    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

    "},{"location":"Version-Comparison/#otp-trip-planning-and-transit-index-apis","title":"OTP Trip planning and Transit index APIs","text":"

    OTP1 had two APIs for trip planning, the REST API and an GraphQL API (early version of the GTFS GraphQL API). This API has been formalised and is now, together with the Transmodel GraphQL API, the only supported way of sending requests to the OTP routing engine.

    Details of those two APIs are available at the following pages:

    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 semantics and structure, and provide the same functionality.

    "},{"location":"Version-Comparison/#additional-characteristics-added-in-otp2","title":"Additional characteristics added in OTP2","text":"

    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 \u201cequal\u201d, 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.

    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

    "},{"location":"Version-Comparison/#other-features-removed-from-otp2","title":"Other features removed from OTP2","text":"

    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.

    "},{"location":"Version-Comparison/#migration-guide","title":"Migration guide","text":"

    The development community has maintained a migration guide from version 1.5.0 up to 2.2.0 when it was no longer feasible to document every change as version 2 was considered the only supported one. The document can be found in the documentation of version 2.2.0.

    "},{"location":"Visual-Identity/","title":"OpenTripPlanner Visual Identity","text":"

    This is the OpenTripPlanner logo in scalable vector format, with knockout transparency:

    Here is a link to this SVG logo as a downloadable file. This is the raw SVG XML source code:

    <?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" \n    x=\"0px\" y=\"0px\" width=\"512px\" height=\"512px\" viewBox=\"0 0 125.333 125.334\" xml:space=\"preserve\">\n<path fill=\"#2179BF\" d=\"M62.668,0C33.83,0,9.559,19.483,2.258,46l72.681-0.003c4.729-0.011,8.555-3.837,8.561-8.568\n    c-0.006-4.729-3.831-8.555-8.561-8.559c-4.731,0.004-8.557,3.83-8.564,8.559v4.592h-13.7v-4.592\n    c0-12.294,9.962-22.261,22.265-22.263c12.298,0.002,22.262,9.969,22.266,22.263c-0.003,12.3-9.968,22.264-22.266,22.271H0.074\n    C0.028,60.684,0,61.671,0,62.666c0,34.611,28.057,62.668,62.668,62.668c34.609,0,62.665-28.057,62.665-62.668\n    C125.333,28.057,97.277,0,62.668,0 M92.222,85.667v-3.473v-4.86l-47.058,0.003c-4.729,0.011-8.556,3.837-8.561,8.568\n    c0.005,4.728,3.831,8.555,8.561,8.559c4.731-0.004,8.558-3.831,8.565-8.559v-4.592h13.699v4.592\n    c0,12.294-9.961,22.261-22.265,22.263c-12.298-0.002-22.26-9.969-22.264-22.263c0.002-12.3,9.966-22.264,22.264-22.271h47.058V56.12\n    l21.712,14.775L92.222,85.667z\"/>\n</svg>\n

    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 OpenTripPlanner logo was created by Brooklyn-based cartographer and graphic designer Kate Chanba, who has also done extensive work on transit system maps.

    "},{"location":"apis/Apis/","title":"APIs","text":"

    Several services are built upon OTP's routing and transit data indexing engines. They expose these APIs:

    The GTFS GraphQL API has been used by the Digitransit and otp-react-redux projects as a general purpose routing and transit data API in production for many years. If your input data is mostly GTFS then this is probably the best choice as it uses the same vocabulary.

    The Transmodel GraphQL API is used at Entur in production since 2020. Like the GTFS GraphQL API it is also a general purpose API. If your input data is mostly NeTeX then you might want to investigate this API as it uses the Transmodel vocabulary to describe its entities.

    The Vector tiles API is a special purpose API for displaying entities on a vector map.

    The Actuator API provides endpoints for checking the health status of the OTP instance and reading live application metrics.

    The Geocoder API allows you to geocode stop names and codes.

    "},{"location":"apis/Apis/#legacy-apis-to-be-removed","title":"Legacy APIs (to be removed)","text":"

    The OTP REST API used to power many apps and frontends. For years it was the only way to access OTP programmatically.

    Over time it has been replaced by the GraphQL APIs and is now disabled by default and will eventually be removed completely. It's therefore not recommended to use it.

    "},{"location":"apis/GTFS-GraphQL-API/","title":"GTFS GraphQL API","text":"

    The GTFS GraphQL API is a general purpose API which was created for the Digitransit project and is used heavily by digitransit-ui.

    otp-react-redux has also migrated to this API in 2023.

    There is also a Java client available which makes it easy to use this API in a Java application.

    "},{"location":"apis/GTFS-GraphQL-API/#urls","title":"URLs","text":""},{"location":"apis/GTFS-GraphQL-API/#built-in-api-client","title":"Built-in API client","text":"

    A browser based GraphQL API client is available at http://localhost:8080/graphiql

    curl example

    A complete example that fetches the list of all stops from OTP is:

    curl --request POST \\\n  --url http://localhost:8080/otp/gtfs/v1 \\\n  --header 'Content-Type: application/json' \\\n  --header 'OTPTimeout: 180000' \\\n  --data '{\"query\":\"query stops {\\n  stops {\\n    gtfsId\\n    name\\n  }\\n}\\n\",\"operationName\":\"stops\"}'\n
    "},{"location":"apis/GTFS-GraphQL-API/#configuration","title":"Configuration","text":"

    The API is enabled by default.

    If you want to disable it, do it in otp-config.json:

    // otp-config.json\n{\n  \"otpFeatures\" : {\n    \"GtfsGraphQlApi\": false\n  }\n}\n
    "},{"location":"apis/GraphQL-Tutorial/","title":"GraphQL Tutorial","text":""},{"location":"apis/GraphQL-Tutorial/#graphql-tutorial","title":"GraphQL tutorial","text":"

    This document will give you a quick start tutorial on how to get started with OTP's GraphQL APIs. For this tutorial we will be using the GTFS GraphQL API as this is the most commonly used one.

    First of all, make sure that you've loaded street and transit data into your instance by following the basic tutorial

    "},{"location":"apis/GraphQL-Tutorial/#visual-graphql-api-client","title":"Visual GraphQL API client","text":"

    OTP has a built-in API client to help you build queries and view documentation. After having started OTP, visit http://localhost:8080/graphiql to open it.

    It should look like this:

    "},{"location":"apis/GraphQL-Tutorial/#sending-your-first-query","title":"Sending your first query","text":"

    For our first query we want to get the list of routes loaded into OTP. Therefore paste the following GraphQL query in the left hand panel of the page:

    {\n  routes {\n    longName\n    shortName\n    gtfsId\n    agency {\n      gtfsId\n      name\n    }\n    mode\n  }\n}\n

    After pressing the \"Execute query\" button you should see the result of the query on the right hand side panel.

    Now would be a good time to explore the auto-complete capabilities of the tool by moving the cursor into the query panel and hitting Ctrl-Space to see what other query parameters are possible.

    The explorer also has documentation built into it. If you hover your pointer over a property on the left hand side you can see its documentation.

    "},{"location":"apis/GraphQL-Tutorial/#a-more-advanced-query","title":"A more advanced query","text":"

    Most people want to get routing results out of OTP, so lets see the query for this:

    {\n  planConnection(\n    origin: {\n      # these coordinates are in Portland, change this to YOUR origin\n      location: { coordinate: { latitude: 45.5552, longitude: -122.6534 } }\n    }\n    destination: {\n      # these coordinates are in Portland, change this to YOUR destination\n      location: { coordinate: { latitude: 45.4908, longitude: -122.5519 } }\n    }\n    # use the correct date and time of your request\n    dateTime: { earliestDeparture: \"2023-06-13T14:30-07:00\" }\n    # choose the transport modes you need\n    modes: {\n      direct: [WALK]\n      transit: { transit: [{ mode: BUS }, { mode: RAIL }] }\n    }\n  ) {\n    edges {\n      node {\n        start\n        end\n        legs {\n          mode\n          from {\n            name\n            lat\n            lon\n            departure {\n              scheduledTime\n              estimated {\n                time\n                delay\n              }\n            }\n          }\n          to {\n            name\n            lat\n            lon\n            arrival {\n              scheduledTime\n              estimated {\n                time\n                delay\n              }\n            }\n          }\n          route {\n            gtfsId\n            longName\n            shortName\n          }\n          legGeometry {\n            points\n          }\n        }\n      }\n    }\n  }\n}\n

    Again, please use the autocomplete and documentation viewers to figure out what each input parameter and property means.

    More examples for a variety of queries can also be found in the test code.

    "},{"location":"apis/TransmodelApi/","title":"Transmodel GraphQL API","text":""},{"location":"apis/TransmodelApi/#contact-info","title":"Contact Info","text":""},{"location":"apis/TransmodelApi/#documentation","title":"Documentation","text":"

    This is the official OTP2 API for Transmodel (NeTEx). 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 provides a GraphQL explorer where you may browse the GraphQL schema and try your own queries.

    When running OTP locally the endpoint is available at: http://localhost:8080/otp/transmodel/v3

    Note! Versions v1 and v2 do not exist in the main OTP git repository, but in the Entur fork from which this code originates from.

    "},{"location":"apis/TransmodelApi/#configuration","title":"Configuration","text":"

    To turn this API off, add the feature TransmodelGraphQlApi : false in otp-config.json.

    "},{"location":"apis/TransmodelApi/#changelog-old","title":"Changelog - old","text":"

    The Transmodel API is now part of the main OTP supported APIs. New changes in the changelog will be added to the main change log, and NOT here (2023-12-13).

    "},{"location":"examples/Readme/","title":"Example configurations","text":"

    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.

    "},{"location":"examples/Readme/#examples","title":"Examples","text":"Name Organisation Description entur Entur, Norway Deployment Configuration with NeTEX input data ibi IBI Group, USA Allow routing for wheelchair users even if accessibility data is incomplete skanetrafiken Sk\u00e5netrafiken, Sweden, Sk\u00e5ne Deployment Configuration with combination of NeTEx and GTFS input data"},{"location":"examples/Readme/#support","title":"Support","text":"

    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.

    "},{"location":"examples/Readme/#how-to-share-an-example","title":"How to share an example","text":"

    Anyone who want can add their example here as long as it is OTP \"related\". Just create a normal pull-request to add it.

    "},{"location":"examples/entur/Readme/","title":"Entur Deployment Configuration","text":"

    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.

    "},{"location":"examples/entur/Readme/#config-files","title":"Config files","text":"

    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 <host>, <OperatorNameSpace> and ${GCS_BUCKET} are placeholders you need to change.

    "},{"location":"examples/entur/Readme/#data-input-files","title":"Data input files","text":"

    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 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.

    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 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.

    "},{"location":"examples/skanetrafiken/Readme/","title":"Sk\u00e5netrafiken Deployment Configuration","text":"

    This is a snapshot of Sk\u00e5netrafiken deployment configuration. At Sk\u00e5netrafiken we deploy our OTP instances as microservices to a Kubernetes cluster. Some parts of the config are missing due to confidentiality.

    "},{"location":"examples/skanetrafiken/Readme/#data-input-files","title":"Data input files","text":""},{"location":"examples/skanetrafiken/Readme/#netex","title":"NeTEx","text":"

    NeTEx is used for transport data inside Sweden. Each night the system automatically builds new file based on data from SQL database. At the moment those files are not accessible through any public endpoint.

    "},{"location":"examples/skanetrafiken/Readme/#gtfs","title":"GTFS","text":"

    GTFS data is used for traffic inside Denmark. GTFS for danish public transport can be downloaded here. There is some processing applied to the original data so that unnecessary trips are filtered out and ID structure for journeys and stop point / stop places matches with the NeTEx. The modified GTFS is not accessible through any public endpoint either.

    "},{"location":"examples/skanetrafiken/Readme/#osm","title":"OSM","text":"

    Two different OSM files are used:

    "},{"location":"examples/skanetrafiken/Readme/#sweden","title":"Sweden","text":"

    OSM data is downloaded from http://download.geofabrik.de/europe/sweden-latest.osm.pbf. To reduced graph size, only data for southern part of Sweden is used.

    "},{"location":"examples/skanetrafiken/Readme/#denmark","title":"Denmark","text":"

    OSM data is downloaded from http://download.geofabrik.de/europe/denmark-latest.osm.pbf. To reduce graph size, only data for northern part of Denmark is used.

    "},{"location":"examples/skanetrafiken/Readme/#real-time","title":"Real-time","text":"

    The Azure Service Bus is used to propagate SIRI SX and ET real-time messages to OTP. This is solved through Siri Azure updaters that Sk\u00e5netrafiken had implemented in OTP. There are separate updaters for SIRI SX and ET. Those updaters are used to provide data for Swedish traffic (NeTEx). Right now, there is no connection to any real-time source for danish traffic (GTFS data).

    Except for receiving messages from Service Bus there are two endpoints through which historical ET and SX messages can be downloaded at OTP startup. The updater will first create new subscription on ServiceBus topic and then send request to the history endpoint. It can take some time get a response from the endpoint, so the timeout is set quite high. Once OTP is done with processing of history messages the updater will start querying messages from the subscription.

    Once the updaters are done with processing of history messages they will change their status to primed, and the system will start channeling request to this OTP instance. This ensures that no real-time message is omitted and all OTP instance that ran in the cluster does have exact same real-time data. Thi means that no matter which instance the client is hitting it will always get the same search results.

    "},{"location":"examples/skanetrafiken/Readme/#history-endpoint-contract","title":"History endpoint contract","text":"

    See the updaters section of router-config.json file provided in this folder. This is an example configuration for the updaters. The history configuration is optional. It can be skipped so that OTP does not fetch any historical messages on startup.

    There are two separate endpoints for respectively SX and ET. They are basic GET endpoints with following query parameters:

    parameters format fromDateTime ISO 8601 toDateTime ISO 8601

    Those two parameters are used to define time boundaries for the messages.

    Both endpoints generate XML response which is an SIRI object containing SX or ET messages. Messages are formatted according to Siri Nordic Profile. Since in SIRI ET standard each messages contains all necessary data, Sk\u00e5netrafikens implementation of the endpoint returns only the last message for each DatedServiceJourney ID (sending multiple messages would be pointless since they will override each other). The messages are processed in the same order as they came in (in the list) so it would still work to include multiple messages on same DatedServiceJourney as long as they are sorted in correct order and the newest message is the last one in the list.

    "},{"location":"examples/skanetrafiken/Readme/#matching-on-stop-arrival-times","title":"Matching on stop arrival-times","text":"

    Normally ET messages are matched with corresponding trips based on ServiceJourney or DatedServiceJourney id from the message. In case OTP was not able to find corresponding trip additional search will be performed based on arrival-times/stop-patterns from the ET message. This feature turned off by default but can be activated by adding fuzzyTripMatching property to updater configuration.

    "},{"location":"examples/skanetrafiken/Readme/#federatedidentity","title":"FederatedIdentity","text":"

    It is also possible to connect to Service Bus through FederatedIdentity. Change authenticationType to FederatedIdentity and provide fullyQualifiedNamespace in router-config.

    "},{"location":"features-explained/Netex-Siri-Compatibility/","title":"NeTEx and SIRI compatibility","text":"

    NeTEx and SIRI are two European public transport data specifications that are comparable to GTFS and GTFS-RT but have a broader scope. Support for both was added by Entur in OTP version 2 and you can find examples of those in their examples repo.

    "},{"location":"features-explained/Netex-Siri-Compatibility/#profiles","title":"Profiles","text":""},{"location":"features-explained/Netex-Siri-Compatibility/#nordic-profile","title":"Nordic profile","text":"

    Different countries are currently using different incompatible \"profiles\" of NeTEx, but an effort is underway to converge on a single European standard profile. This is based in large part on the Nordic profile used by Entur.

    The Nordic profile is the only profile that has been thoroughly tested in production in OTP and is used in Norway, Finland and Sweden.

    "},{"location":"features-explained/Netex-Siri-Compatibility/#epip","title":"EPIP","text":"

    The European Passenger Information Profile is an attempt to unify other country profiles and support in OTP is adequate, but it is difficult to tell how much of EPIP is supported since it is a very large profile. The current status of the support is tracked on Github.

    Sometimes it is difficult to tell if a file conforms to EPIP so to find out, you can run the following commands:

    git clone git@github.com:NeTEx-CEN/NeTEx-Profile-EPIP.git\nxmllint --noout --schema NeTEx-Profile-EPIP/NeTEx_publication_EPIP.xsd your-filename.xml\n
    "},{"location":"features-explained/Netex-Siri-Compatibility/#other-profiles","title":"Other profiles","text":"

    It is the goal of the community to support both the Nordic profile and EPIP. If you have another profile, we encourage to get in touch with the community to find a way forward.

    "},{"location":"osm/Finland/","title":"OSM tag mapping","text":"

    This page is intended to give an overview of which OpenStreetMap(OSM) tags OTP uses to evaluate its walking and bicycling instructions. If a tag is not part of the documentation on this page then this tag mapper (profile) does not use it.

    The exception are access permissions and wheelchair accessibility tags like

    These are identical for all mappers and not separately listed on this page.

    "},{"location":"osm/Finland/#way-properties","title":"Way properties","text":"

    Way properties set a way's permission and optionally influences its walk and bicycle safety factors.

    These factors determine how desirable an OSM way is when routing for cyclists and pedestrians. Lower safety values make an OSM way more desirable and higher values less desirable.

    specifier permission bike safety walk safety highway=living_street ALL 0.9 highway=unclassified ALL highway=road ALL highway=byway ALL 1.3 highway=track ALL 1.3 highway=service ALL 1.1 highway=residential ALL 0.98 highway=residential_link ALL 0.98 highway=tertiary ALL highway=tertiary_link ALL highway=secondary ALL 1.5 highway=secondary_link ALL 1.5 highway=primary ALL 2.06 highway=primary_link ALL 2.06 highway=trunk_link ALL 2.06 highway=trunk ALL 7.47 highway=trunk; tunnel=yes CAR 7.47 motorroad=yes CAR 7.47 present(highway); informal=yes NONE highway=service; access=private NONE highway=trail NONE present(highway); seasonal=winter NONE present(highway); ice_road=yes NONE present(highway); winter_road=yes NONE highway=footway PEDESTRIAN footway=sidewalk; highway=footway PEDESTRIAN highway=cycleway; segregated=yes PEDESTRIAN_AND_BICYCLE 0.6 1.1 highway=footway; bridge=yes PEDESTRIAN highway=footway; tunnel=yes PEDESTRIAN highway=cycleway; bridge=yes PEDESTRIAN_AND_BICYCLE 0.6 highway=cycleway; tunnel=yes PEDESTRIAN_AND_BICYCLE 0.6 highway=footway; footway=crossing; crossing=traffic_signals PEDESTRIAN 1.1 highway=footway; footway=crossing PEDESTRIAN 1.2 highway=cycleway; cycleway=crossing; segregated=yes; crossing=traffic_signals PEDESTRIAN_AND_BICYCLE 0.8 1.1 highway=cycleway; footway=crossing; segregated=yes; crossing=traffic_signals PEDESTRIAN 0.8 1.1 highway=cycleway; cycleway=crossing; segregated=yes PEDESTRIAN_AND_BICYCLE 1.2 1.2 highway=cycleway; footway=crossing; segregated=yes PEDESTRIAN 1.2 1.2 highway=cycleway; cycleway=crossing; crossing=traffic_signals PEDESTRIAN_AND_BICYCLE 0.8 1.15 highway=cycleway; footway=crossing; crossing=traffic_signals PEDESTRIAN_AND_BICYCLE 0.8 1.15 highway=cycleway; cycleway=crossing PEDESTRIAN_AND_BICYCLE 1.2 1.25 highway=cycleway; footway=crossing PEDESTRIAN_AND_BICYCLE 1.2 1.25 highway=cycleway; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.6 highway=service; tunnel=yes; access=destination NONE highway=service; access=destination ALL 1.1 mtb:scale=3 NONE mtb:scale=4 NONE mtb:scale=5 NONE mtb:scale=6 NONE highway=corridor PEDESTRIAN highway=steps PEDESTRIAN highway=crossing PEDESTRIAN highway=platform PEDESTRIAN public_transport=platform PEDESTRIAN railway=platform PEDESTRIAN footway=sidewalk; highway=footway PEDESTRIAN mtb:scale=1 PEDESTRIAN mtb:scale=2 PEDESTRIAN mtb:scale=0 PEDESTRIAN_AND_BICYCLE highway=cycleway PEDESTRIAN_AND_BICYCLE 0.6 highway=path PEDESTRIAN_AND_BICYCLE 0.75 highway=pedestrian PEDESTRIAN_AND_BICYCLE 0.9 highway=footway PEDESTRIAN_AND_BICYCLE 1.1 highway=bridleway PEDESTRIAN_AND_BICYCLE 1.3 highway=living_street ALL 0.9 highway=unclassified ALL highway=road ALL highway=byway ALL 1.3 highway=track ALL 1.3 highway=service ALL 1.1 highway=residential ALL 0.98 highway=residential_link ALL 0.98 highway=tertiary ALL highway=tertiary_link ALL highway=secondary ALL 1.5 highway=secondary_link ALL 1.5 highway=primary ALL 2.06 highway=primary_link ALL 2.06 highway=trunk_link CAR 2.06 highway=motorway_link CAR 2.06 highway=trunk CAR 7.47 highway=motorway CAR 8.0 present(highway); cycleway=lane PEDESTRIAN_AND_BICYCLE 0.87 highway=service; cycleway=lane ALL 0.77 highway=residential; cycleway=lane ALL 0.77 highway=residential_link; cycleway=lane ALL 0.77 highway=tertiary; cycleway=lane ALL 0.87 highway=tertiary_link; cycleway=lane ALL 0.87 highway=secondary; cycleway=lane ALL 0.96 highway=secondary_link; cycleway=lane ALL 0.96 highway=primary; cycleway=lane ALL 1.15 highway=primary_link; cycleway=lane ALL 1.15 highway=trunk; cycleway=lane BICYCLE_AND_CAR 1.5 highway=trunk_link; cycleway=lane BICYCLE_AND_CAR 1.15 highway=motorway; cycleway=lane BICYCLE_AND_CAR 2.0 highway=motorway_link; cycleway=lane BICYCLE_AND_CAR 1.15 present(highway); cycleway=share_busway PEDESTRIAN_AND_BICYCLE 0.92 highway=service; cycleway=share_busway ALL 0.85 highway=residential; cycleway=share_busway ALL 0.85 highway=residential_link; cycleway=share_busway ALL 0.85 highway=tertiary; cycleway=share_busway ALL 0.92 highway=tertiary_link; cycleway=share_busway ALL 0.92 highway=secondary; cycleway=share_busway ALL 0.99 highway=secondary_link; cycleway=share_busway ALL 0.99 highway=primary; cycleway=share_busway ALL 1.25 highway=primary_link; cycleway=share_busway ALL 1.25 highway=trunk; cycleway=share_busway BICYCLE_AND_CAR 1.75 highway=trunk_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 highway=motorway; cycleway=share_busway BICYCLE_AND_CAR 2.5 highway=motorway_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 present(highway); cycleway=opposite_lane PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.87 highway=service; cycleway=opposite_lane ALL forward: 1.1 back: 0.77 highway=residential; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=residential_link; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=tertiary; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=tertiary_link; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=secondary; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=secondary_link; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=primary; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=primary_link; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=trunk; cycleway=opposite_lane BICYCLE_AND_CAR forward: 7.47 back: 1.5 highway=trunk_link; cycleway=opposite_lane BICYCLE_AND_CAR forward: 2.06 back: 1.15 present(highway); cycleway=track PEDESTRIAN_AND_BICYCLE 0.75 highway=service; cycleway=track ALL 0.65 highway=residential; cycleway=track ALL 0.65 highway=residential_link; cycleway=track ALL 0.65 highway=tertiary; cycleway=track ALL 0.75 highway=tertiary_link; cycleway=track ALL 0.75 highway=secondary; cycleway=track ALL 0.8 highway=secondary_link; cycleway=track ALL 0.8 highway=primary; cycleway=track ALL 0.85 highway=primary_link; cycleway=track ALL 0.85 highway=trunk; cycleway=track BICYCLE_AND_CAR 0.95 highway=trunk_link; cycleway=track BICYCLE_AND_CAR 0.85 present(highway); cycleway=opposite_track PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.75 highway=service; cycleway=opposite_track ALL forward: 1.1 back: 0.65 highway=residential; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=residential_link; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=tertiary; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=tertiary_link; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=secondary; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=secondary_link; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=primary; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=primary_link; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=trunk; cycleway=opposite_track BICYCLE_AND_CAR forward: 7.47 back: 0.95 highway=trunk_link; cycleway=opposite_track BICYCLE_AND_CAR forward: 2.06 back: 0.85 present(highway); cycleway=shared_lane PEDESTRIAN_AND_BICYCLE 0.77 highway=service; cycleway=shared_lane ALL 0.73 highway=residential; cycleway=shared_lane ALL 0.77 highway=residential_link; cycleway=shared_lane ALL 0.77 highway=tertiary; cycleway=shared_lane ALL 0.83 highway=tertiary_link; cycleway=shared_lane ALL 0.83 highway=secondary; cycleway=shared_lane ALL 1.25 highway=secondary_link; cycleway=shared_lane ALL 1.25 highway=primary; cycleway=shared_lane ALL 1.75 highway=primary_link; cycleway=shared_lane ALL 1.75 present(highway); cycleway=opposite PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 1.4 highway=service; cycleway=opposite ALL 1.1 highway=residential; cycleway=opposite ALL 0.98 highway=residential_link; cycleway=opposite ALL 0.98 highway=tertiary; cycleway=opposite ALL highway=tertiary_link; cycleway=opposite ALL highway=secondary; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=secondary_link; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=primary; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=primary_link; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=path; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.6 highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 highway=footway; bicycle=yes; area=yes PEDESTRIAN_AND_BICYCLE 0.9 highway=pedestrian; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 footway=sidewalk; highway=footway; bicycle=yes PEDESTRIAN_AND_BICYCLE 2.5 footway=sidewalk; highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=footway; footway=crossing PEDESTRIAN_AND_BICYCLE 2.5 highway=footway; footway=crossing; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=track; bicycle=yes PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.99 highway=track; bicycle=yes; present(surface) PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated; present(surface) PEDESTRIAN_AND_BICYCLE 0.99 highway=track; present(surface) PEDESTRIAN_AND_BICYCLE 1.3 present(highway); bicycle=designated ALL 0.97 highway=service; bicycle=designated ALL 0.84 highway=residential; bicycle=designated ALL 0.95 highway=unclassified; bicycle=designated ALL 0.95 highway=residential_link; bicycle=designated ALL 0.95 highway=tertiary; bicycle=designated ALL 0.97 highway=tertiary_link; bicycle=designated ALL 0.97 highway=secondary; bicycle=designated ALL 1.46 highway=secondary_link; bicycle=designated ALL 1.46 highway=primary; bicycle=designated ALL 2.0 highway=primary_link; bicycle=designated ALL 2.0 highway=trunk; bicycle=designated BICYCLE_AND_CAR 7.25 highway=trunk_link; bicycle=designated BICYCLE_AND_CAR 2.0 highway=motorway; bicycle=designated BICYCLE_AND_CAR 7.76 highway=motorway_link; bicycle=designated BICYCLE_AND_CAR 2.0"},{"location":"osm/Finland/#safety-mixins","title":"Safety mixins","text":"

    Mixins are selectors that have only an effect on the bicycle and walk safety factors but not on the permission of an OSM way. Their safety values are multiplied with the base values from the selected way properties. Multiple mixins can apply to the same way and their effects compound.

    matcher bicycle safety walk safety bicycle=use_sidepath 5.0 lcn=yes\u00a6rcn=yes\u00a6ncn=yes\u00a6bicycle_road=yes\u00a6cyclestreet=yes 0.7 surface=unpaved 1.18 surface=compacted 1.18 surface=wood 1.18 surface=cobblestone 1.3 surface=sett 1.3 surface=unhewn_cobblestone 1.5 surface=grass_paver 1.3 surface=pebblestone 1.3 surface=metal 1.3 surface=ground 1.5 surface=dirt 1.5 surface=earth 1.5 surface=grass 1.5 surface=mud 1.5 surface=woodchip 1.5 surface=gravel 1.5 surface=artifical_turf 1.5 surface=sand 100.0 foot=discouraged 3.0 bicycle=discouraged 3.0 foot=use_sidepath 5.0 bicycle=use_sidepath 5.0"},{"location":"osm/Germany/","title":"OSM tag mapping","text":"

    This page is intended to give an overview of which OpenStreetMap(OSM) tags OTP uses to evaluate its walking and bicycling instructions. If a tag is not part of the documentation on this page then this tag mapper (profile) does not use it.

    The exception are access permissions and wheelchair accessibility tags like

    These are identical for all mappers and not separately listed on this page.

    "},{"location":"osm/Germany/#way-properties","title":"Way properties","text":"

    Way properties set a way's permission and optionally influences its walk and bicycle safety factors.

    These factors determine how desirable an OSM way is when routing for cyclists and pedestrians. Lower safety values make an OSM way more desirable and higher values less desirable.

    specifier permission bike safety walk safety highway=track PEDESTRIAN_AND_BICYCLE highway=track; present(surface) PEDESTRIAN_AND_BICYCLE highway=residential; junction=roundabout ALL 0.98 present(highway); junction=roundabout BICYCLE_AND_CAR highway=pedestrian PEDESTRIAN highway=residential; maxspeed=30 ALL 0.9 highway=footway; bicycle=yes PEDESTRIAN_AND_BICYCLE 0.8 footway=sidewalk; highway=footway; bicycle=yes PEDESTRIAN_AND_BICYCLE 1.2 highway=unclassified; cycleway=lane ALL 0.87 mtb:scale=3 NONE mtb:scale=4 NONE mtb:scale=5 NONE mtb:scale=6 NONE highway=corridor PEDESTRIAN highway=steps PEDESTRIAN highway=crossing PEDESTRIAN highway=platform PEDESTRIAN public_transport=platform PEDESTRIAN railway=platform PEDESTRIAN footway=sidewalk; highway=footway PEDESTRIAN mtb:scale=1 PEDESTRIAN mtb:scale=2 PEDESTRIAN mtb:scale=0 PEDESTRIAN_AND_BICYCLE highway=cycleway PEDESTRIAN_AND_BICYCLE 0.6 highway=path PEDESTRIAN_AND_BICYCLE 0.75 highway=pedestrian PEDESTRIAN_AND_BICYCLE 0.9 highway=footway PEDESTRIAN_AND_BICYCLE 1.1 highway=bridleway PEDESTRIAN_AND_BICYCLE 1.3 highway=living_street ALL 0.9 highway=unclassified ALL highway=road ALL highway=byway ALL 1.3 highway=track ALL 1.3 highway=service ALL 1.1 highway=residential ALL 0.98 highway=residential_link ALL 0.98 highway=tertiary ALL highway=tertiary_link ALL highway=secondary ALL 1.5 highway=secondary_link ALL 1.5 highway=primary ALL 2.06 highway=primary_link ALL 2.06 highway=trunk_link CAR 2.06 highway=motorway_link CAR 2.06 highway=trunk CAR 7.47 highway=motorway CAR 8.0 present(highway); cycleway=lane PEDESTRIAN_AND_BICYCLE 0.87 highway=service; cycleway=lane ALL 0.77 highway=residential; cycleway=lane ALL 0.77 highway=residential_link; cycleway=lane ALL 0.77 highway=tertiary; cycleway=lane ALL 0.87 highway=tertiary_link; cycleway=lane ALL 0.87 highway=secondary; cycleway=lane ALL 0.96 highway=secondary_link; cycleway=lane ALL 0.96 highway=primary; cycleway=lane ALL 1.15 highway=primary_link; cycleway=lane ALL 1.15 highway=trunk; cycleway=lane BICYCLE_AND_CAR 1.5 highway=trunk_link; cycleway=lane BICYCLE_AND_CAR 1.15 highway=motorway; cycleway=lane BICYCLE_AND_CAR 2.0 highway=motorway_link; cycleway=lane BICYCLE_AND_CAR 1.15 present(highway); cycleway=share_busway PEDESTRIAN_AND_BICYCLE 0.92 highway=service; cycleway=share_busway ALL 0.85 highway=residential; cycleway=share_busway ALL 0.85 highway=residential_link; cycleway=share_busway ALL 0.85 highway=tertiary; cycleway=share_busway ALL 0.92 highway=tertiary_link; cycleway=share_busway ALL 0.92 highway=secondary; cycleway=share_busway ALL 0.99 highway=secondary_link; cycleway=share_busway ALL 0.99 highway=primary; cycleway=share_busway ALL 1.25 highway=primary_link; cycleway=share_busway ALL 1.25 highway=trunk; cycleway=share_busway BICYCLE_AND_CAR 1.75 highway=trunk_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 highway=motorway; cycleway=share_busway BICYCLE_AND_CAR 2.5 highway=motorway_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 present(highway); cycleway=opposite_lane PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.87 highway=service; cycleway=opposite_lane ALL forward: 1.1 back: 0.77 highway=residential; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=residential_link; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=tertiary; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=tertiary_link; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=secondary; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=secondary_link; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=primary; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=primary_link; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=trunk; cycleway=opposite_lane BICYCLE_AND_CAR forward: 7.47 back: 1.5 highway=trunk_link; cycleway=opposite_lane BICYCLE_AND_CAR forward: 2.06 back: 1.15 present(highway); cycleway=track PEDESTRIAN_AND_BICYCLE 0.75 highway=service; cycleway=track ALL 0.65 highway=residential; cycleway=track ALL 0.65 highway=residential_link; cycleway=track ALL 0.65 highway=tertiary; cycleway=track ALL 0.75 highway=tertiary_link; cycleway=track ALL 0.75 highway=secondary; cycleway=track ALL 0.8 highway=secondary_link; cycleway=track ALL 0.8 highway=primary; cycleway=track ALL 0.85 highway=primary_link; cycleway=track ALL 0.85 highway=trunk; cycleway=track BICYCLE_AND_CAR 0.95 highway=trunk_link; cycleway=track BICYCLE_AND_CAR 0.85 present(highway); cycleway=opposite_track PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.75 highway=service; cycleway=opposite_track ALL forward: 1.1 back: 0.65 highway=residential; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=residential_link; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=tertiary; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=tertiary_link; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=secondary; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=secondary_link; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=primary; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=primary_link; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=trunk; cycleway=opposite_track BICYCLE_AND_CAR forward: 7.47 back: 0.95 highway=trunk_link; cycleway=opposite_track BICYCLE_AND_CAR forward: 2.06 back: 0.85 present(highway); cycleway=shared_lane PEDESTRIAN_AND_BICYCLE 0.77 highway=service; cycleway=shared_lane ALL 0.73 highway=residential; cycleway=shared_lane ALL 0.77 highway=residential_link; cycleway=shared_lane ALL 0.77 highway=tertiary; cycleway=shared_lane ALL 0.83 highway=tertiary_link; cycleway=shared_lane ALL 0.83 highway=secondary; cycleway=shared_lane ALL 1.25 highway=secondary_link; cycleway=shared_lane ALL 1.25 highway=primary; cycleway=shared_lane ALL 1.75 highway=primary_link; cycleway=shared_lane ALL 1.75 present(highway); cycleway=opposite PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 1.4 highway=service; cycleway=opposite ALL 1.1 highway=residential; cycleway=opposite ALL 0.98 highway=residential_link; cycleway=opposite ALL 0.98 highway=tertiary; cycleway=opposite ALL highway=tertiary_link; cycleway=opposite ALL highway=secondary; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=secondary_link; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=primary; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=primary_link; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=path; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.6 highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 highway=footway; bicycle=yes; area=yes PEDESTRIAN_AND_BICYCLE 0.9 highway=pedestrian; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 footway=sidewalk; highway=footway; bicycle=yes PEDESTRIAN_AND_BICYCLE 2.5 footway=sidewalk; highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=footway; footway=crossing PEDESTRIAN_AND_BICYCLE 2.5 highway=footway; footway=crossing; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=track; bicycle=yes PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.99 highway=track; bicycle=yes; present(surface) PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated; present(surface) PEDESTRIAN_AND_BICYCLE 0.99 highway=track; present(surface) PEDESTRIAN_AND_BICYCLE 1.3 present(highway); bicycle=designated ALL 0.97 highway=service; bicycle=designated ALL 0.84 highway=residential; bicycle=designated ALL 0.95 highway=unclassified; bicycle=designated ALL 0.95 highway=residential_link; bicycle=designated ALL 0.95 highway=tertiary; bicycle=designated ALL 0.97 highway=tertiary_link; bicycle=designated ALL 0.97 highway=secondary; bicycle=designated ALL 1.46 highway=secondary_link; bicycle=designated ALL 1.46 highway=primary; bicycle=designated ALL 2.0 highway=primary_link; bicycle=designated ALL 2.0 highway=trunk; bicycle=designated BICYCLE_AND_CAR 7.25 highway=trunk_link; bicycle=designated BICYCLE_AND_CAR 2.0 highway=motorway; bicycle=designated BICYCLE_AND_CAR 7.76 highway=motorway_link; bicycle=designated BICYCLE_AND_CAR 2.0"},{"location":"osm/Germany/#safety-mixins","title":"Safety mixins","text":"

    Mixins are selectors that have only an effect on the bicycle and walk safety factors but not on the permission of an OSM way. Their safety values are multiplied with the base values from the selected way properties. Multiple mixins can apply to the same way and their effects compound.

    matcher bicycle safety walk safety highway=tertiary 1.2 maxspeed=70 1.5 maxspeed=80 2.0 maxspeed=90 3.0 maxspeed=100 5.0 tracktype=grade1 tracktype=grade2 1.1 tracktype=grade3 1.15 tracktype=grade4 1.3 tracktype=grade5 1.5 lit=no 1.05 lcn=yes\u00a6rcn=yes\u00a6ncn=yes\u00a6bicycle_road=yes\u00a6cyclestreet=yes 0.7 surface=unpaved 1.18 surface=compacted 1.18 surface=wood 1.18 surface=cobblestone 1.3 surface=sett 1.3 surface=unhewn_cobblestone 1.5 surface=grass_paver 1.3 surface=pebblestone 1.3 surface=metal 1.3 surface=ground 1.5 surface=dirt 1.5 surface=earth 1.5 surface=grass 1.5 surface=mud 1.5 surface=woodchip 1.5 surface=gravel 1.5 surface=artifical_turf 1.5 surface=sand 100.0 foot=discouraged 3.0 bicycle=discouraged 3.0 foot=use_sidepath 5.0 bicycle=use_sidepath 5.0"},{"location":"osm/Norway/","title":"OSM tag mapping","text":"

    This page is intended to give an overview of which OpenStreetMap(OSM) tags OTP uses to evaluate its walking and bicycling instructions. If a tag is not part of the documentation on this page then this tag mapper (profile) does not use it.

    The exception are access permissions and wheelchair accessibility tags like

    These are identical for all mappers and not separately listed on this page.

    "},{"location":"osm/Norway/#way-properties","title":"Way properties","text":"

    Way properties set a way's permission and optionally influences its walk and bicycle safety factors.

    These factors determine how desirable an OSM way is when routing for cyclists and pedestrians. Lower safety values make an OSM way more desirable and higher values less desirable.

    specifier permission bike safety walk safety highway one of [motorway, motorway_link] CAR highway one of [trunk, trunk_link, primary, primary_link]; motorroad=yes CAR highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link, unclassified, residential] ALL cycleway=track; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link, unclassified, residential] ALL cycleway=lane; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link] ALL 1.27 cycleway=lane; maxspeed < 50; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link] ALL 1.1 cycleway=lane; highway one of [unclassified, residential] ALL 1.1 highway=service ALL highway=service; service=parking_aisle ALL 2.5 highway=service; service=drive-through ALL 2.5 highway=living_street ALL 1.83 highway=pedestrian PEDESTRIAN_AND_BICYCLE 1.2 highway=busway PEDESTRIAN_AND_BICYCLE 2.37 1.9 highway=service; bus one of [yes, designated] PEDESTRIAN_AND_BICYCLE 2.37 1.9 highway=footway PEDESTRIAN_AND_BICYCLE 1.42 highway=cycleway PEDESTRIAN_AND_BICYCLE 1.05 1.4 highway=cycleway; lanes > 1 PEDESTRIAN_AND_BICYCLE 1.4 highway=cycleway; oneway=yes PEDESTRIAN_AND_BICYCLE 1.4 highway=cycleway; sidewalk one of [yes, left, right, both] PEDESTRIAN_AND_BICYCLE 1.05 highway=cycleway; lanes > 1; sidewalk one of [yes, left, right, both] PEDESTRIAN_AND_BICYCLE highway=cycleway; oneway=yes; sidewalk one of [yes, left, right, both] PEDESTRIAN_AND_BICYCLE highway=cycleway; foot=designated; segregated=no PEDESTRIAN_AND_BICYCLE 1.05 1.15 highway=path; foot=designated; bicycle=designated; segregated=no PEDESTRIAN_AND_BICYCLE 1.05 1.15 highway=cycleway; foot=designated; segregated=yes PEDESTRIAN_AND_BICYCLE 1.05 highway=path; foot=designated; bicycle=designated; segregated=yes PEDESTRIAN_AND_BICYCLE 1.05 highway=cycleway; foot=designated; segregated=yes; lanes > 1 PEDESTRIAN_AND_BICYCLE highway=cycleway; foot=designated; present(segregated); motor_vehicle=destination PEDESTRIAN_AND_BICYCLE 1.57 highway=path; foot=designated; bicycle=designated; present(segregated); motor_vehicle=destination PEDESTRIAN_AND_BICYCLE 1.57 highway=footway; footway=sidewalk PEDESTRIAN_AND_BICYCLE 1.93 1.1 highway=footway; footway=crossing PEDESTRIAN_AND_BICYCLE 2.33 1.35 highway=cycleway; cycleway=crossing PEDESTRIAN_AND_BICYCLE 2.33 1.35 highway=track PEDESTRIAN_AND_BICYCLE highway=bridleway PEDESTRIAN_AND_BICYCLE highway=path PEDESTRIAN_AND_BICYCLE highway=steps PEDESTRIAN highway=corridor PEDESTRIAN highway=footway; indoor=yes PEDESTRIAN highway=platform PEDESTRIAN public_transport=platform PEDESTRIAN trail_visibility one of [bad, low, poor, horrible, no]; highway=path NONE sac_scale one of [demanding_mountain_hiking, alpine_hiking, demanding_alpine_hiking, difficult_alpine_hiking]; highway one of [path, steps] NONE smoothness one of [horrible, very_horrible]; highway one of [path, bridleway, track] PEDESTRIAN 1.15 smoothness=impassable; highway one of [path, bridleway, track] NONE 1 > mtb:scale < 2; highway one of [path, bridleway, track] PEDESTRIAN 1.15 mtb:scale > 2; highway one of [path, bridleway, track] NONE"},{"location":"osm/Norway/#safety-mixins","title":"Safety mixins","text":"

    Mixins are selectors that have only an effect on the bicycle and walk safety factors but not on the permission of an OSM way. Their safety values are multiplied with the base values from the selected way properties. Multiple mixins can apply to the same way and their effects compound.

    matcher bicycle safety walk safety cycleway=shared_lane; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link, unclassified, residential] 0.85 lcn=yes\u00a6rcn=yes\u00a6ncn=yes 0.85 oneway=yes; cycleway not one of [no, none] or absent; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link, unclassified, residential] forward: 1.0 back: 1.15 embedded_rails one of [tram, light_rail, disused] 1.2 tunnel=yes; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link, unclassified] 2.0 bridge=yes; sidewalk not one of [no, separate] or absent; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link, unclassified]\u00a6verge=no; sidewalk not one of [no, separate] or absent; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link, unclassified] 2.0 junction=roundabout; sidewalk not one of [no, separate] or absent 2.0 surface=grass_paver 1.2 surface=sett 1.2 surface=cobblestone 1.2 surface=unhewn_cobblestone 3.0 surface=metal_grid 1.2 surface=metal 1.2 smoothness=intermediate; surface one of [asfalt, concrete, paving_stones, paved, wood] 1.2 smoothness=bad; surface one of [asfalt, concrete, paving_stones, paved, wood] 1.4 1.6 surface=unpaved; !tracktype 1.8 1.6 surface=compacted 1.4 1.4 surface=fine_gravel 1.8 1.6 surface=pebblestone 1.8 1.6 surface=gravel 1.8 1.6 surface=woodchip 1.8 1.6 surface=ground 2.3 2.4 surface=dirt 2.3 2.4 surface=earth 2.3 2.4 surface=grass 2.3 1.8 surface=mud 3.0 3.0 surface=sand 3.0 1.8 !tracktype; surface not one of [unpaved] or absent; highway one of [track, bridleway] 1.8 1.6 tracktype=grade2; surface not one of [unpaved] or absent; highway one of [track, bridleway, service, unclassified] 1.4 1.4 tracktype=grade3; surface not one of [unpaved] or absent; highway one of [track, bridleway, service, unclassified] 1.8 1.6 tracktype=grade4; surface not one of [unpaved] or absent; highway one of [track, bridleway, service, unclassified] 2.3 1.8 tracktype=grade5; surface not one of [unpaved] or absent; highway one of [track, bridleway, service, unclassified] 2.3 2.4 surface not one of [no, none] or absent; highway=path 2.3 2.4 sac_scale=mountain_hiking 1.8 trail_visibility=intermediate 1.8"},{"location":"osm/OsmTag/","title":"OSM tag mapping","text":"

    This page is intended to give an overview of which OpenStreetMap(OSM) tags OTP uses to evaluate its walking and bicycling instructions. If a tag is not part of the documentation on this page then this tag mapper (profile) does not use it.

    The exception are access permissions and wheelchair accessibility tags like

    These are identical for all mappers and not separately listed on this page.

    "},{"location":"osm/OsmTag/#way-properties","title":"Way properties","text":"

    Way properties set a way's permission and optionally influences its walk and bicycle safety factors.

    These factors determine how desirable an OSM way is when routing for cyclists and pedestrians. Lower safety values make an OSM way more desirable and higher values less desirable.

    specifier permission bike safety walk safety mtb:scale=3 NONE mtb:scale=4 NONE mtb:scale=5 NONE mtb:scale=6 NONE highway=corridor PEDESTRIAN highway=steps PEDESTRIAN highway=crossing PEDESTRIAN highway=platform PEDESTRIAN public_transport=platform PEDESTRIAN railway=platform PEDESTRIAN footway=sidewalk; highway=footway PEDESTRIAN mtb:scale=1 PEDESTRIAN mtb:scale=2 PEDESTRIAN mtb:scale=0 PEDESTRIAN_AND_BICYCLE highway=cycleway PEDESTRIAN_AND_BICYCLE 0.6 highway=path PEDESTRIAN_AND_BICYCLE 0.75 highway=pedestrian PEDESTRIAN_AND_BICYCLE 0.9 highway=footway PEDESTRIAN_AND_BICYCLE 1.1 highway=bridleway PEDESTRIAN_AND_BICYCLE 1.3 highway=living_street ALL 0.9 highway=unclassified ALL highway=road ALL highway=byway ALL 1.3 highway=track ALL 1.3 highway=service ALL 1.1 highway=residential ALL 0.98 highway=residential_link ALL 0.98 highway=tertiary ALL highway=tertiary_link ALL highway=secondary ALL 1.5 highway=secondary_link ALL 1.5 highway=primary ALL 2.06 highway=primary_link ALL 2.06 highway=trunk_link CAR 2.06 highway=motorway_link CAR 2.06 highway=trunk CAR 7.47 highway=motorway CAR 8.0 present(highway); cycleway=lane PEDESTRIAN_AND_BICYCLE 0.87 highway=service; cycleway=lane ALL 0.77 highway=residential; cycleway=lane ALL 0.77 highway=residential_link; cycleway=lane ALL 0.77 highway=tertiary; cycleway=lane ALL 0.87 highway=tertiary_link; cycleway=lane ALL 0.87 highway=secondary; cycleway=lane ALL 0.96 highway=secondary_link; cycleway=lane ALL 0.96 highway=primary; cycleway=lane ALL 1.15 highway=primary_link; cycleway=lane ALL 1.15 highway=trunk; cycleway=lane BICYCLE_AND_CAR 1.5 highway=trunk_link; cycleway=lane BICYCLE_AND_CAR 1.15 highway=motorway; cycleway=lane BICYCLE_AND_CAR 2.0 highway=motorway_link; cycleway=lane BICYCLE_AND_CAR 1.15 present(highway); cycleway=share_busway PEDESTRIAN_AND_BICYCLE 0.92 highway=service; cycleway=share_busway ALL 0.85 highway=residential; cycleway=share_busway ALL 0.85 highway=residential_link; cycleway=share_busway ALL 0.85 highway=tertiary; cycleway=share_busway ALL 0.92 highway=tertiary_link; cycleway=share_busway ALL 0.92 highway=secondary; cycleway=share_busway ALL 0.99 highway=secondary_link; cycleway=share_busway ALL 0.99 highway=primary; cycleway=share_busway ALL 1.25 highway=primary_link; cycleway=share_busway ALL 1.25 highway=trunk; cycleway=share_busway BICYCLE_AND_CAR 1.75 highway=trunk_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 highway=motorway; cycleway=share_busway BICYCLE_AND_CAR 2.5 highway=motorway_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 present(highway); cycleway=opposite_lane PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.87 highway=service; cycleway=opposite_lane ALL forward: 1.1 back: 0.77 highway=residential; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=residential_link; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=tertiary; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=tertiary_link; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=secondary; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=secondary_link; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=primary; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=primary_link; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=trunk; cycleway=opposite_lane BICYCLE_AND_CAR forward: 7.47 back: 1.5 highway=trunk_link; cycleway=opposite_lane BICYCLE_AND_CAR forward: 2.06 back: 1.15 present(highway); cycleway=track PEDESTRIAN_AND_BICYCLE 0.75 highway=service; cycleway=track ALL 0.65 highway=residential; cycleway=track ALL 0.65 highway=residential_link; cycleway=track ALL 0.65 highway=tertiary; cycleway=track ALL 0.75 highway=tertiary_link; cycleway=track ALL 0.75 highway=secondary; cycleway=track ALL 0.8 highway=secondary_link; cycleway=track ALL 0.8 highway=primary; cycleway=track ALL 0.85 highway=primary_link; cycleway=track ALL 0.85 highway=trunk; cycleway=track BICYCLE_AND_CAR 0.95 highway=trunk_link; cycleway=track BICYCLE_AND_CAR 0.85 present(highway); cycleway=opposite_track PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.75 highway=service; cycleway=opposite_track ALL forward: 1.1 back: 0.65 highway=residential; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=residential_link; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=tertiary; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=tertiary_link; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=secondary; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=secondary_link; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=primary; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=primary_link; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=trunk; cycleway=opposite_track BICYCLE_AND_CAR forward: 7.47 back: 0.95 highway=trunk_link; cycleway=opposite_track BICYCLE_AND_CAR forward: 2.06 back: 0.85 present(highway); cycleway=shared_lane PEDESTRIAN_AND_BICYCLE 0.77 highway=service; cycleway=shared_lane ALL 0.73 highway=residential; cycleway=shared_lane ALL 0.77 highway=residential_link; cycleway=shared_lane ALL 0.77 highway=tertiary; cycleway=shared_lane ALL 0.83 highway=tertiary_link; cycleway=shared_lane ALL 0.83 highway=secondary; cycleway=shared_lane ALL 1.25 highway=secondary_link; cycleway=shared_lane ALL 1.25 highway=primary; cycleway=shared_lane ALL 1.75 highway=primary_link; cycleway=shared_lane ALL 1.75 present(highway); cycleway=opposite PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 1.4 highway=service; cycleway=opposite ALL 1.1 highway=residential; cycleway=opposite ALL 0.98 highway=residential_link; cycleway=opposite ALL 0.98 highway=tertiary; cycleway=opposite ALL highway=tertiary_link; cycleway=opposite ALL highway=secondary; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=secondary_link; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=primary; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=primary_link; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=path; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.6 highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 highway=footway; bicycle=yes; area=yes PEDESTRIAN_AND_BICYCLE 0.9 highway=pedestrian; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 footway=sidewalk; highway=footway; bicycle=yes PEDESTRIAN_AND_BICYCLE 2.5 footway=sidewalk; highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=footway; footway=crossing PEDESTRIAN_AND_BICYCLE 2.5 highway=footway; footway=crossing; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=track; bicycle=yes PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.99 highway=track; bicycle=yes; present(surface) PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated; present(surface) PEDESTRIAN_AND_BICYCLE 0.99 highway=track; present(surface) PEDESTRIAN_AND_BICYCLE 1.3 present(highway); bicycle=designated ALL 0.97 highway=service; bicycle=designated ALL 0.84 highway=residential; bicycle=designated ALL 0.95 highway=unclassified; bicycle=designated ALL 0.95 highway=residential_link; bicycle=designated ALL 0.95 highway=tertiary; bicycle=designated ALL 0.97 highway=tertiary_link; bicycle=designated ALL 0.97 highway=secondary; bicycle=designated ALL 1.46 highway=secondary_link; bicycle=designated ALL 1.46 highway=primary; bicycle=designated ALL 2.0 highway=primary_link; bicycle=designated ALL 2.0 highway=trunk; bicycle=designated BICYCLE_AND_CAR 7.25 highway=trunk_link; bicycle=designated BICYCLE_AND_CAR 2.0 highway=motorway; bicycle=designated BICYCLE_AND_CAR 7.76 highway=motorway_link; bicycle=designated BICYCLE_AND_CAR 2.0"},{"location":"osm/OsmTag/#safety-mixins","title":"Safety mixins","text":"

    Mixins are selectors that have only an effect on the bicycle and walk safety factors but not on the permission of an OSM way. Their safety values are multiplied with the base values from the selected way properties. Multiple mixins can apply to the same way and their effects compound.

    matcher bicycle safety walk safety lcn=yes\u00a6rcn=yes\u00a6ncn=yes\u00a6bicycle_road=yes\u00a6cyclestreet=yes 0.7 surface=unpaved 1.18 surface=compacted 1.18 surface=wood 1.18 surface=cobblestone 1.3 surface=sett 1.3 surface=unhewn_cobblestone 1.5 surface=grass_paver 1.3 surface=pebblestone 1.3 surface=metal 1.3 surface=ground 1.5 surface=dirt 1.5 surface=earth 1.5 surface=grass 1.5 surface=mud 1.5 surface=woodchip 1.5 surface=gravel 1.5 surface=artifical_turf 1.5 surface=sand 100.0 foot=discouraged 3.0 bicycle=discouraged 3.0 foot=use_sidepath 5.0 bicycle=use_sidepath 5.0"},{"location":"osm/UK/","title":"OSM tag mapping","text":"

    This page is intended to give an overview of which OpenStreetMap(OSM) tags OTP uses to evaluate its walking and bicycling instructions. If a tag is not part of the documentation on this page then this tag mapper (profile) does not use it.

    The exception are access permissions and wheelchair accessibility tags like

    These are identical for all mappers and not separately listed on this page.

    "},{"location":"osm/UK/#way-properties","title":"Way properties","text":"

    Way properties set a way's permission and optionally influences its walk and bicycle safety factors.

    These factors determine how desirable an OSM way is when routing for cyclists and pedestrians. Lower safety values make an OSM way more desirable and higher values less desirable.

    specifier permission bike safety walk safety highway=trunk_link ALL 2.06 highway=trunk ALL 7.47 highway=trunk; cycleway=lane ALL 1.5 highway=trunk_link; cycleway=lane ALL 1.15 highway=trunk; cycleway=share_busway ALL 1.75 highway=trunk_link; cycleway=share_busway ALL 1.25 highway=trunk; cycleway=opposite_lane ALL forward: 7.47 back: 1.5 highway=trunk_link; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=trunk; cycleway=track ALL 0.95 highway=trunk_link; cycleway=track ALL 0.85 highway=trunk; cycleway=opposite_track ALL forward: 7.47 back: 0.95 highway=trunk_link; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=trunk; bicycle=designated ALL 7.25 highway=trunk_link; bicycle=designated ALL 2.0 indoor=area PEDESTRIAN indoor=corridor PEDESTRIAN mtb:scale=3 NONE mtb:scale=4 NONE mtb:scale=5 NONE mtb:scale=6 NONE highway=corridor PEDESTRIAN highway=steps PEDESTRIAN highway=crossing PEDESTRIAN highway=platform PEDESTRIAN public_transport=platform PEDESTRIAN railway=platform PEDESTRIAN footway=sidewalk; highway=footway PEDESTRIAN mtb:scale=1 PEDESTRIAN mtb:scale=2 PEDESTRIAN mtb:scale=0 PEDESTRIAN_AND_BICYCLE highway=cycleway PEDESTRIAN_AND_BICYCLE 0.6 highway=path PEDESTRIAN_AND_BICYCLE 0.75 highway=pedestrian PEDESTRIAN_AND_BICYCLE 0.9 highway=footway PEDESTRIAN_AND_BICYCLE 1.1 highway=bridleway PEDESTRIAN_AND_BICYCLE 1.3 highway=living_street ALL 0.9 highway=unclassified ALL highway=road ALL highway=byway ALL 1.3 highway=track ALL 1.3 highway=service ALL 1.1 highway=residential ALL 0.98 highway=residential_link ALL 0.98 highway=tertiary ALL highway=tertiary_link ALL highway=secondary ALL 1.5 highway=secondary_link ALL 1.5 highway=primary ALL 2.06 highway=primary_link ALL 2.06 highway=trunk_link CAR 2.06 highway=motorway_link CAR 2.06 highway=trunk CAR 7.47 highway=motorway CAR 8.0 present(highway); cycleway=lane PEDESTRIAN_AND_BICYCLE 0.87 highway=service; cycleway=lane ALL 0.77 highway=residential; cycleway=lane ALL 0.77 highway=residential_link; cycleway=lane ALL 0.77 highway=tertiary; cycleway=lane ALL 0.87 highway=tertiary_link; cycleway=lane ALL 0.87 highway=secondary; cycleway=lane ALL 0.96 highway=secondary_link; cycleway=lane ALL 0.96 highway=primary; cycleway=lane ALL 1.15 highway=primary_link; cycleway=lane ALL 1.15 highway=trunk; cycleway=lane BICYCLE_AND_CAR 1.5 highway=trunk_link; cycleway=lane BICYCLE_AND_CAR 1.15 highway=motorway; cycleway=lane BICYCLE_AND_CAR 2.0 highway=motorway_link; cycleway=lane BICYCLE_AND_CAR 1.15 present(highway); cycleway=share_busway PEDESTRIAN_AND_BICYCLE 0.92 highway=service; cycleway=share_busway ALL 0.85 highway=residential; cycleway=share_busway ALL 0.85 highway=residential_link; cycleway=share_busway ALL 0.85 highway=tertiary; cycleway=share_busway ALL 0.92 highway=tertiary_link; cycleway=share_busway ALL 0.92 highway=secondary; cycleway=share_busway ALL 0.99 highway=secondary_link; cycleway=share_busway ALL 0.99 highway=primary; cycleway=share_busway ALL 1.25 highway=primary_link; cycleway=share_busway ALL 1.25 highway=trunk; cycleway=share_busway BICYCLE_AND_CAR 1.75 highway=trunk_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 highway=motorway; cycleway=share_busway BICYCLE_AND_CAR 2.5 highway=motorway_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 present(highway); cycleway=opposite_lane PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.87 highway=service; cycleway=opposite_lane ALL forward: 1.1 back: 0.77 highway=residential; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=residential_link; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=tertiary; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=tertiary_link; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=secondary; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=secondary_link; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=primary; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=primary_link; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=trunk; cycleway=opposite_lane BICYCLE_AND_CAR forward: 7.47 back: 1.5 highway=trunk_link; cycleway=opposite_lane BICYCLE_AND_CAR forward: 2.06 back: 1.15 present(highway); cycleway=track PEDESTRIAN_AND_BICYCLE 0.75 highway=service; cycleway=track ALL 0.65 highway=residential; cycleway=track ALL 0.65 highway=residential_link; cycleway=track ALL 0.65 highway=tertiary; cycleway=track ALL 0.75 highway=tertiary_link; cycleway=track ALL 0.75 highway=secondary; cycleway=track ALL 0.8 highway=secondary_link; cycleway=track ALL 0.8 highway=primary; cycleway=track ALL 0.85 highway=primary_link; cycleway=track ALL 0.85 highway=trunk; cycleway=track BICYCLE_AND_CAR 0.95 highway=trunk_link; cycleway=track BICYCLE_AND_CAR 0.85 present(highway); cycleway=opposite_track PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.75 highway=service; cycleway=opposite_track ALL forward: 1.1 back: 0.65 highway=residential; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=residential_link; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=tertiary; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=tertiary_link; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=secondary; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=secondary_link; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=primary; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=primary_link; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=trunk; cycleway=opposite_track BICYCLE_AND_CAR forward: 7.47 back: 0.95 highway=trunk_link; cycleway=opposite_track BICYCLE_AND_CAR forward: 2.06 back: 0.85 present(highway); cycleway=shared_lane PEDESTRIAN_AND_BICYCLE 0.77 highway=service; cycleway=shared_lane ALL 0.73 highway=residential; cycleway=shared_lane ALL 0.77 highway=residential_link; cycleway=shared_lane ALL 0.77 highway=tertiary; cycleway=shared_lane ALL 0.83 highway=tertiary_link; cycleway=shared_lane ALL 0.83 highway=secondary; cycleway=shared_lane ALL 1.25 highway=secondary_link; cycleway=shared_lane ALL 1.25 highway=primary; cycleway=shared_lane ALL 1.75 highway=primary_link; cycleway=shared_lane ALL 1.75 present(highway); cycleway=opposite PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 1.4 highway=service; cycleway=opposite ALL 1.1 highway=residential; cycleway=opposite ALL 0.98 highway=residential_link; cycleway=opposite ALL 0.98 highway=tertiary; cycleway=opposite ALL highway=tertiary_link; cycleway=opposite ALL highway=secondary; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=secondary_link; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=primary; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=primary_link; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=path; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.6 highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 highway=footway; bicycle=yes; area=yes PEDESTRIAN_AND_BICYCLE 0.9 highway=pedestrian; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 footway=sidewalk; highway=footway; bicycle=yes PEDESTRIAN_AND_BICYCLE 2.5 footway=sidewalk; highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=footway; footway=crossing PEDESTRIAN_AND_BICYCLE 2.5 highway=footway; footway=crossing; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=track; bicycle=yes PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.99 highway=track; bicycle=yes; present(surface) PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated; present(surface) PEDESTRIAN_AND_BICYCLE 0.99 highway=track; present(surface) PEDESTRIAN_AND_BICYCLE 1.3 present(highway); bicycle=designated ALL 0.97 highway=service; bicycle=designated ALL 0.84 highway=residential; bicycle=designated ALL 0.95 highway=unclassified; bicycle=designated ALL 0.95 highway=residential_link; bicycle=designated ALL 0.95 highway=tertiary; bicycle=designated ALL 0.97 highway=tertiary_link; bicycle=designated ALL 0.97 highway=secondary; bicycle=designated ALL 1.46 highway=secondary_link; bicycle=designated ALL 1.46 highway=primary; bicycle=designated ALL 2.0 highway=primary_link; bicycle=designated ALL 2.0 highway=trunk; bicycle=designated BICYCLE_AND_CAR 7.25 highway=trunk_link; bicycle=designated BICYCLE_AND_CAR 2.0 highway=motorway; bicycle=designated BICYCLE_AND_CAR 7.76 highway=motorway_link; bicycle=designated BICYCLE_AND_CAR 2.0"},{"location":"osm/UK/#safety-mixins","title":"Safety mixins","text":"

    Mixins are selectors that have only an effect on the bicycle and walk safety factors but not on the permission of an OSM way. Their safety values are multiplied with the base values from the selected way properties. Multiple mixins can apply to the same way and their effects compound.

    matcher bicycle safety walk safety lcn=yes\u00a6rcn=yes\u00a6ncn=yes\u00a6bicycle_road=yes\u00a6cyclestreet=yes 0.7 surface=unpaved 1.18 surface=compacted 1.18 surface=wood 1.18 surface=cobblestone 1.3 surface=sett 1.3 surface=unhewn_cobblestone 1.5 surface=grass_paver 1.3 surface=pebblestone 1.3 surface=metal 1.3 surface=ground 1.5 surface=dirt 1.5 surface=earth 1.5 surface=grass 1.5 surface=mud 1.5 surface=woodchip 1.5 surface=gravel 1.5 surface=artifical_turf 1.5 surface=sand 100.0 foot=discouraged 3.0 bicycle=discouraged 3.0 foot=use_sidepath 5.0 bicycle=use_sidepath 5.0"},{"location":"sandbox/ActuatorAPI/","title":"Actuator API","text":""},{"location":"sandbox/ActuatorAPI/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/ActuatorAPI/#changelog","title":"Changelog","text":""},{"location":"sandbox/ActuatorAPI/#documentation","title":"Documentation","text":"

    This provides endpoints for checking the health status of the OTP instance. It can be useful when running OTP in a container.

    The API will be at the endpoint http://localhost:8080/otp/actuators and follows the Spring Boot actuator API standard.

    "},{"location":"sandbox/ActuatorAPI/#configuration","title":"Configuration","text":"

    To enable this you need to add the feature ActuatorAPI.

    // otp-config.json\n{\n  \"otpFeatures\" : {\n    \"ActuatorAPI\": true\n  }\n}\n
    "},{"location":"sandbox/ActuatorAPI/#endpoints","title":"Endpoints","text":""},{"location":"sandbox/ActuatorAPI/#health","title":"/health","text":"

    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.

    "},{"location":"sandbox/ActuatorAPI/#prometheus","title":"/prometheus","text":"

    Prometheus metrics are returned using Micrometer. The default JVM and jersey metrics are enabled.

    Also, GraphQL timing metrics are exported under graphql.timer.query and graphql.timer.resolver, if the GraphQL endpoints are enabled.

    "},{"location":"sandbox/DataOverlay/","title":"Data Overlay","text":"

    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.

    "},{"location":"sandbox/DataOverlay/#contact-info","title":"Contact Info","text":"

    Developed and maintained by Metatavu OY, Finland.

    Developers:

    Katja Danilova - katja.danilova@metatavu.fi\\ 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.

    Company email: info@metatavu.fi

    "},{"location":"sandbox/DataOverlay/#changelog","title":"Changelog","text":""},{"location":"sandbox/DataOverlay/#documentation","title":"Documentation","text":"

    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.

    It is a sandbox feature.

    Please see the configuration part for setup instructions and examples.

    "},{"location":"sandbox/DataOverlay/#configuration","title":"Configuration","text":"

    Enable the feature by including it to the otp-config.json:

    // otp-config.json\n{ \"otpFeatures\": { \"DataOverlay\" : true } }\n

    Plugin configuration should explain the NetCDF data file and request parameters that use the data file.

    Example of build-config.json that includes the dataOverlay plugin configuration:

    // build-config.json\n{\n  \"dataOverlay\" :\n  {\n    \"fileName\": \"graphs/data-file.nc4\",\n    \"latitudeVariable\": \"lat\",\n    \"longitudeVariable\": \"lon\",\n    \"timeVariable\": \"time\",\n    \"timeFormat\": \"HOURS\",\n    \"indexVariables\": [\n      {\n        \"name\": \"harmfulMicroparticlesPM2_5\",\n        \"displayName\": \"Harmful micro particles pm 2.5\",\n        \"variable\": \"cnc_PM2_5\"\n      },\n      {\n        \"name\": \"harmfulMicroparticlesPM10\",\n        \"displayName\": \"Harmful micro particles pm 10\",\n        \"variable\": \"cnc_PM10\"\n      }\n    ],\n    \"requestParameters\": [\n      {\n        \"name\": \"PARTICULATE_MATTER_2_5\",\n        \"variable\": \"harmfulMicroparticlesPM2_5\",\n        \"formula\": \"(VALUE + 1 - THRESHOLD) * PENALTY\"\n      },\n      {\n        \"name\": \"PARTICULATE_MATTER_10\",\n        \"variable\": \"harmfulMicroparticlesPM10\",\n        \"formula\": \"(VALUE + 1 - THRESHOLD) * PENALTY\"\n      }\n    ]\n  }\n\n}\n

    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.

    // router-config.json\n{\n  \"routingDefaults\": {\n    \"dataOverlay\" : {\n      \"particulate_matter_10_threshold\" : 100,\n      \"particulate_matter_10_penalty\" : 19\n    }\n  }\n}\n
    "},{"location":"sandbox/Emissions/","title":"CO\u2082 Emissions calculation","text":""},{"location":"sandbox/Emissions/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/Emissions/#documentation","title":"Documentation","text":"

    Graph build import of CO\u2082 Emissions from GTFS data sets (through custom emissions.txt extension) and the ability to attach them to itineraries by Digitransit team. The emissions are represented in grams per kilometer (g/Km) unit.

    Emissions data is located in an emissions.txt file within a gtfs package and has the following columns:

    route_id: route id

    avg_co2_per_vehicle_per_km: Average carbon dioxide equivalent value for the vehicles used on the route at grams/Km units.

    avg_passenger_count: Average passenger count for the vehicles on the route.

    For example:

    route_id,avg_co2_per_vehicle_per_km,avg_passenger_count\n1234,123,20\n2345,0,0\n3456,12.3,20.0\n

    Emissions data is loaded from the gtfs package and embedded into the graph during the build process.

    "},{"location":"sandbox/Emissions/#configuration","title":"Configuration","text":"

    To enable this functionality, you need to enable the \"Co2Emissions\" feature in the otp-config.json file.

    //otp-config.json\n{\n  \"Co2Emissions\": true\n}\n
    Include the emissions object in the build-config.json file. The emissions object should contain parameters called carAvgCo2PerKm and carAvgOccupancy. The carAvgCo2PerKm provides the average emissions value for a car in g/km and the carAvgOccupancy provides the average number of passengers in a car.

    "},{"location":"sandbox/Emissions/#example-configuration","title":"Example configuration","text":"
    // build-config.json\n{\n  \"emissions\" : {\n    \"carAvgCo2PerKm\" : 170,\n    \"carAvgOccupancy\" : 1.3\n  }\n}\n
    "},{"location":"sandbox/Emissions/#overview","title":"Overview","text":"Config Parameter Type Summary Req./Opt. Default Value Since carAvgCo2PerKm integer The average CO\u2082 emissions of a car in grams per kilometer. Optional 170 2.5 carAvgOccupancy double The average number of passengers in a car. Optional 1.3 2.5"},{"location":"sandbox/Emissions/#details","title":"Details","text":""},{"location":"sandbox/Emissions/#changelog","title":"Changelog","text":""},{"location":"sandbox/Emissions/#otp-25","title":"OTP 2.5","text":""},{"location":"sandbox/Fares/","title":"Fares","text":""},{"location":"sandbox/Fares/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/Fares/#documentation","title":"Documentation","text":"

    The code in this sandbox used to be part of OTP core but to allow more experimentation - in particular regarding GTFS Fares V2 - it was moved into a sandbox.

    "},{"location":"sandbox/Fares/#fares-v2","title":"Fares V2","text":"

    In 2022 the GTFS spec was extended to contain a powerful new model, called Fares V2, to describe fares, prices and products for public transport tickets. A baseline effort was merged into the main spec in May.

    OTP experimentally supports the merged baseline plus a few extensions from the larger, unmerged spec.

    To enable Fares V2 support, add the following to otp-config.json:

    {\n  \"otpFeatures\" : {\n    \"FaresV2\" : true\n  }\n}\n
    "},{"location":"sandbox/Fares/#supported-fares-v2-fields","title":"Supported Fares V2 fields","text":"

    A full list of the fields that OTP supports is available in the Fares V2 Adoption Google Sheet.

    "},{"location":"sandbox/Fares/#custom-fare-calculators","title":"Custom fare calculators","text":"

    When the GTFS Fares V1 spec was not enough, some organizations have developed their own calculators which are also part of the sandbox code.

    The classes and their maintainers are as follows:

    class maintainer HighestFareInFreeTransferWindowFareService IBI Group (David Emory) AtlantaFareService IBI Group (David Emory) CombinedInterlinedLegsFareService IBI Group (David Emory) HSLFareServiceImpl HSL (Viljami Nurminen) OrcaFareService IBI Group (Daniel Heppner)"},{"location":"sandbox/Fares/#fares-configuration","title":"Fares configuration","text":"

    By default OTP will compute fares according to the GTFS specification if fare data is provided in your GTFS input. It is possible to turn off this by setting the fare to \"off\". For more complex scenarios or to handle vehicle rental fares, it is necessary to manually configure fares using the fares section in build-config.json. You can combine different fares (for example transit and vehicle-rental) by defining a combinationStrategy parameter, and a list of sub-fares to combine (all fields starting with fare are considered to be sub-fares).

    // build-config.json\n{\n  // Select the custom fare \"seattle\"\n  \"fares\": \"seattle\"\n}\n

    Or this alternative form that could allow additional configuration

    // build-config.json\n{\n  \"fares\": {\n    \"type\": \"seattle\"\n  }\n}\n

    Turning the fare service off, this will ignore any fare data in the provided GTFS data.

    // build-config.json\n{\n  \"fares\": \"off\"\n}\n

    The current list of custom fare type is:

    "},{"location":"sandbox/Fares/#removed-fare-calculators","title":"Removed fare calculators","text":"

    The following calculators used to be part of the OTP codebase but since their maintainership was unclear and no-one offered to maintain, they were removed in July 2022.

    The NYC fare calculator was removed in #4694.

    The MultipleFareService was removed in #5100.

    The SFBayFareServiceImpl and TimeBasedVehicleRentalFareService were removed in #5145.

    If you were using these calculators, you're welcome to re-add them to the code base and become their maintainer.

    "},{"location":"sandbox/Fares/#changelog","title":"Changelog","text":""},{"location":"sandbox/Flex/","title":"Flexible transit routing","text":""},{"location":"sandbox/Flex/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/Flex/#documentation","title":"Documentation","text":"

    To enable this turn on FlexRouting as a feature in otp-config.json.

    The GTFS feeds must conform to the final, approved version of the draft which has been merged into the mainline specification in March 2024.

    "},{"location":"sandbox/Flex/#experimental-features","title":"Experimental features","text":"

    This sandbox feature also has experimental support for the following fields:

    These features are currently undergoing specification and their definition might change. OTP's implementation will be also be changed so be careful when relying on this feature.

    "},{"location":"sandbox/Flex/#configuration","title":"Configuration","text":"

    This feature allows a limited number of config options. To change the configuration, add the following to router-config.json.

    "},{"location":"sandbox/Flex/#example-configuration","title":"Example configuration","text":"
    // router-config.json\n{\n  \"flex\" : {\n    \"maxTransferDuration\" : \"5m\",\n    \"maxFlexTripDuration\" : \"45m\",\n    \"maxAccessWalkDuration\" : \"15m\",\n    \"maxEgressWalkDuration\" : \"15m\"\n  }\n}\n
    "},{"location":"sandbox/Flex/#overview","title":"Overview","text":"Config Parameter Type Summary Req./Opt. Default Value Since maxAccessWalkDuration duration The maximum duration the passenger will be allowed to walk to reach a flex stop or zone. Optional \"PT45M\" 2.3 maxEgressWalkDuration duration The maximum duration the passenger will be allowed to walk after leaving the flex vehicle at the final destination. Optional \"PT45M\" 2.3 maxFlexTripDuration duration How long can a non-scheduled flex trip at maximum be. Optional \"PT45M\" 2.3 maxTransferDuration duration How long should a passenger be allowed to walk after getting out of a flex vehicle and transferring to a flex or transit one. Optional \"PT5M\" 2.3"},{"location":"sandbox/Flex/#details","title":"Details","text":""},{"location":"sandbox/Flex/#flex_maxAccessWalkDuration","title":"maxAccessWalkDuration","text":"

    Since version: 2.3 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT45M\" Path: /flex

    The maximum duration the passenger will be allowed to walk to reach a flex stop or zone.

    If you have multiple overlapping flex zones the high default value can lead to performance problems. A lower value means faster routing.

    Depending on your service this might be what you want to do anyway: many flex services are used by passengers with mobility problems so offering a long walk might be problematic. In other words, if you can walk 45 minutes to a flex stop/zone you're unlikely to be the target audience for those services.

    "},{"location":"sandbox/Flex/#flex_maxEgressWalkDuration","title":"maxEgressWalkDuration","text":"

    Since version: 2.3 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT45M\" Path: /flex

    The maximum duration the passenger will be allowed to walk after leaving the flex vehicle at the final destination.

    If you have multiple overlapping flex zones the high default value can lead to performance problems. A lower value means faster routing.

    Depending on your service this might be what you want to do anyway: many flex services are used by passengers with mobility problems so offering a long walk might be problematic. In other words, if you can walk 45 minutes to a flex stop/zone you're unlikely to be the target audience for those services.

    "},{"location":"sandbox/Flex/#flex_maxFlexTripDuration","title":"maxFlexTripDuration","text":"

    Since version: 2.3 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT45M\" Path: /flex

    How long can a non-scheduled flex trip at maximum be.

    This is used for all trips which are of type UnscheduledTrip. The value includes the access/egress duration to the boarding/alighting of the flex trip, as well as the connection to the transit stop.

    "},{"location":"sandbox/Flex/#flex_maxTransferDuration","title":"maxTransferDuration","text":"

    Since version: 2.3 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT5M\" Path: /flex

    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.

    A lower value means that the routing is faster.

    "},{"location":"sandbox/Flex/#changelog","title":"Changelog","text":""},{"location":"sandbox/Flex/#otp-21","title":"OTP 2.1","text":""},{"location":"sandbox/Flex/#otp-23","title":"OTP 2.3","text":""},{"location":"sandbox/GeocoderAPI/","title":"Geocoder API","text":""},{"location":"sandbox/GeocoderAPI/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/GeocoderAPI/#documentation","title":"Documentation","text":"

    This sandbox feature implements geocoding endpoints for a number of use cases.

    To enable this you need to add the feature to otp-config.json.

    // otp-config.json\n{\n  \"otpFeatures\": {\n    \"SandboxAPIGeocoder\": true\n  }\n}\n
    "},{"location":"sandbox/GeocoderAPI/#endpoints","title":"Endpoints","text":""},{"location":"sandbox/GeocoderAPI/#debug-ui","title":"Debug UI","text":"

    The required geocode API for Stop and From/To searches in the debug client.

    Path: /otp/geocode

    It supports the following URL parameters:

    Parameter Description query The query string we want to geocode autocomplete Whether we should use the query string to do a prefix match stops Search for stops, either by name or stop code clusters Search for clusters by their name"},{"location":"sandbox/GeocoderAPI/#stop-clusters","title":"Stop clusters","text":"

    A stop cluster is a deduplicated groups of stops. This means that for any stop that has a parent station only the parent is returned and for stops that have identical names and are very close to each other, only one is returned.

    This is useful for a general purpose fuzzy stop search.

    Path: /otp/geocode/stopClusters

    It supports the following URL parameters:

    Parameter Description query The query string we want to geocode"},{"location":"sandbox/GeocoderAPI/#changelog","title":"Changelog","text":""},{"location":"sandbox/GoogleCloudStorage/","title":"Google Cloud Storage - Using GCS Bucket as a OTP Data Source","text":""},{"location":"sandbox/GoogleCloudStorage/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/GoogleCloudStorage/#changelog","title":"Changelog","text":""},{"location":"sandbox/GoogleCloudStorage/#otp-20","title":"OTP 2.0","text":""},{"location":"sandbox/GoogleCloudStorage/#documentation","title":"Documentation","text":"

    To enable this turn on the feature GoogleCloudStorage. OTP can load or store artifacts from one or more Google Cloud Storge locations. Each artifact must be configured in the build-config.json: See BuildConfig on how to configure artifacts.

    Example (build-config.json):

    {\n  \"gcsCredentials\": \"file:///Users/alf/secret/otp-test-1234567890.json\",\n  \"graph\": \"gs://otp-test-bucket/a/b/graph.obj\",\n  \"buildReportDir\": \"gs://otp-test-bucket/a/b/np-report\",\n  \"osm\": [\n    {\n      \"source\": \"gs://otp-test-bucket/a/b/northpole.pbf\"\n    }\n    ],\n  \"dem\": [\n    {\n      \"source\": \"gs://otp-test-bucket/a/b/northpole.dem.tif\"\n    }\n    ],\n  \"transitFeeds\": [\n    {\n      \"type\": \"gtfs\",\n      \"source\": \"gs://otp-test-bucket/a/b/gtfs.zip\"\n    }\n    ]\n}\n
    "},{"location":"sandbox/IBIAccessibilityScore/","title":"IBI Group Accessibility Score","text":""},{"location":"sandbox/IBIAccessibilityScore/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/IBIAccessibilityScore/#documentation","title":"Documentation","text":"

    This extension computes a numeric accessibility score between 0 and 1 and adds it to the itinerary and its legs.

    Note: the information to calculate this score are all available to the frontend, however calculating them on the backend makes life a little easier and changes are automatically applied to all frontends.

    To enable the feature add the following to router-config.json:

    // router-config.json\n{\n  \"routingDefaults\": {\n    \"itineraryFilters\": {\n      // add IBI accessibility score between 0 and 1\n      \"accessibilityScore\": true\n    }\n  }\n}\n

    The score is only computed when you search for wheelchair-accessible routes.

    "},{"location":"sandbox/IBIAccessibilityScore/#changelog","title":"Changelog","text":""},{"location":"sandbox/InteractiveOtpMain/","title":"Interactive OTP Launcher","text":"

    A GUI popup window to which help you to start OTP Main interactively.

    "},{"location":"sandbox/InteractiveOtpMain/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/InteractiveOtpMain/#changelog","title":"Changelog","text":""},{"location":"sandbox/InteractiveOtpMain/#documentation","title":"Documentation","text":"

    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.

    "},{"location":"sandbox/MapboxVectorTilesApi/","title":"Mapbox Vector Tiles API","text":""},{"location":"sandbox/MapboxVectorTilesApi/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/MapboxVectorTilesApi/#documentation","title":"Documentation","text":"

    This API produces Mapbox vector tiles, which are used by Digitransit-ui and otp-react-redux 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.

    Maplibre/Mapbox GL JS also requires a tilejson.json endpoint which is available at /otp/routers/{routerId}/vectorTiles/{layers}/tilejson.json.

    Translatable fields in the tiles are translated based on the accept-language header in requests. Currently, only the language with the highest priority from the header is used.

    "},{"location":"sandbox/MapboxVectorTilesApi/#configuration","title":"Configuration","text":"

    To enable this you need to add the feature otp-config.json.

    // otp-config.json\n{\n  \"otpFeatures\": {\n    \"SandboxAPIMapboxVectorTilesApi\": true\n  }\n}\n

    The feature must be configured in router-config.json as follows

    {\n  \"vectorTiles\": {\n    \"basePath\": \"/only/configure/if/required\",\n    \"layers\": [\n      {\n        \"name\": \"stops\",\n        \"type\": \"Stop\",\n        \"mapper\": \"Digitransit\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 600\n      },\n      // flex zones\n      {\n        \"name\": \"areaStops\",\n        \"type\": \"AreaStop\",\n        \"mapper\": \"OTPRR\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 600\n      },\n      {\n        \"name\": \"stations\",\n        \"type\": \"Station\",\n        \"mapper\": \"Digitransit\",\n        \"maxZoom\": 20,\n        \"minZoom\": 12,\n        \"cacheMaxSeconds\": 600\n      },\n      // all rental places: stations and free-floating vehicles\n      {\n        \"name\": \"citybikes\",\n        \"type\": \"VehicleRental\",\n        \"mapper\": \"Digitransit\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 60,\n        \"expansionFactor\": 0.25\n      },\n      // just free-floating vehicles\n      {\n        \"name\": \"rentalVehicles\",\n        \"type\": \"VehicleRentalVehicle\",\n        \"mapper\": \"DigitransitRealtime\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 60\n      },\n      // just rental stations\n      {\n        \"name\": \"rentalStations\",\n        \"type\": \"VehicleRentalStation\",\n        \"mapper\": \"Digitransit\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 600\n      },\n      // Contains just stations and real-time information for them\n      {\n        \"name\": \"realtimeRentalStations\",\n        \"type\": \"VehicleRentalStation\",\n        \"mapper\": \"DigitransitRealtime\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 60\n      },\n      // Contains just stops and real-time information for them\n      {\n        \"name\": \"realtimeStops\",\n        \"type\": \"Stop\",\n        \"mapper\": \"DigitransitRealtime\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 60\n      },\n      // This exists for backwards compatibility. At some point, we might want\n      // to add a new real-time parking mapper with better translation support\n      // and less unnecessary fields.\n      {\n        \"name\": \"stadtnaviVehicleParking\",\n        \"type\": \"VehicleParking\",\n        \"mapper\": \"Stadtnavi\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 60,\n        \"expansionFactor\": 0.25\n      },\n      // no real-time, translatable fields are translated based on accept-language header\n      // and contains less fields than the Stadtnavi mapper\n      {\n        \"name\": \"vehicleParking\",\n        \"type\": \"VehicleParking\",\n        \"mapper\": \"Digitransit\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 600,\n        \"expansionFactor\": 0.25\n      },\n      {\n        \"name\": \"vehicleParkingGroups\",\n        \"type\": \"VehicleParkingGroup\",\n        \"mapper\": \"Digitransit\",\n        \"maxZoom\": 17,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 600,\n        \"expansionFactor\": 0.25\n      }\n    ] \n  }\n}\n

    For each layer, the configuration includes:

    Config Parameter Type Summary Req./Opt. Default Value Since attribution string Custom attribution to be returned in tilejson.json Optional 2.5 basePath string The path of the vector tile source URLs in tilejson.json. Optional 2.5 layers object[] Configuration of the individual layers for the Mapbox vector tiles. Optional 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type = \"stop\" enum Type of the layer. Required 2.0 cacheMaxSeconds integer Sets the cache header in the response. Optional -1 2.0 expansionFactor double How far outside its boundaries should the tile contain information. Optional 0.25 2.0 filter enum Reduce the result set of a layer further by a specific filter. Optional \"none\" 2.6 mapper string Describes the mapper converting from the OTP model entities to the vector tile properties. Required 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0maxZoom integer Maximum zoom levels the layer is active for. Optional 20 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0minZoom integer Minimum zoom levels the layer is active for. Optional 9 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name string Used in the url to fetch tiles, and as the layer name in the vector tiles. Required 2.0"},{"location":"sandbox/MapboxVectorTilesApi/#details","title":"Details","text":""},{"location":"sandbox/MapboxVectorTilesApi/#vectorTiles_attribution","title":"attribution","text":"

    Since version: 2.5 \u2219 Type: string \u2219 Cardinality: Optional Path: /vectorTiles

    Custom attribution to be returned in tilejson.json

    By default the, attribution property in tilejson.json is computed from the names and URLs of the feed publishers. If the OTP deployment contains many feeds, this can become very unwieldy.

    This configuration parameter allows you to set the attribution to any string you wish including HTML tags, for example <a href='https://trimet.org/mod'>Regional Partners</a>.

    "},{"location":"sandbox/MapboxVectorTilesApi/#vectorTiles_basePath","title":"basePath","text":"

    Since version: 2.5 \u2219 Type: string \u2219 Cardinality: Optional Path: /vectorTiles

    The path of the vector tile source URLs in tilejson.json.

    This is useful if you have a proxy setup and rewrite the path that is passed to OTP.

    If you don't configure this optional value then the path returned in tilejson.json is in the format /otp/routers/default/vectorTiles/layer1,layer2/{z}/{x}/{x}.pbf. If you, for example, set a value of /otp_test/tiles then the returned path changes to /otp_test/tiles/layer1,layer2/{z}/{x}/{x}.pbf.

    The protocol and host are always read from the incoming HTTP request. If you run OTP behind a proxy then make sure to set the headers X-Forwarded-Proto and X-Forwarded-Host to make OTP return the protocol and host for the original request and not the proxied one.

    Note: This does not change the path that OTP itself serves the tiles or tilejson.json responses but simply changes the URLs listed in tilejson.json. The rewriting of the path is expected to be handled by a proxy.

    "},{"location":"sandbox/MapboxVectorTilesApi/#vectorTiles_layers","title":"layers","text":"

    Since version: 2.0 \u2219 Type: object[] \u2219 Cardinality: Optional Path: /vectorTiles

    Configuration of the individual layers for the Mapbox vector tiles.

    "},{"location":"sandbox/MapboxVectorTilesApi/#vectorTiles_layers_0_cacheMaxSeconds","title":"cacheMaxSeconds","text":"

    Since version: 2.0 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: -1 Path: /vectorTiles/layers/[0]

    Sets the cache header in the response.

    The lowest value of the layers included is selected.

    "},{"location":"sandbox/MapboxVectorTilesApi/#vectorTiles_layers_0_expansionFactor","title":"expansionFactor","text":"

    Since version: 2.0 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.25 Path: /vectorTiles/layers/[0]

    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.

    "},{"location":"sandbox/MapboxVectorTilesApi/#vectorTiles_layers_0_filter","title":"filter","text":"

    Since version: 2.6 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"none\" Path: /vectorTiles/layers/[0] Enum values: none | sunday-to-sunday-service-week

    Reduce the result set of a layer further by a specific filter.

    This is useful for when the schema of a layer, say stops, should remain unchanged but some elements should not be included in the result.

    "},{"location":"sandbox/MapboxVectorTilesApi/#vectorTiles_layers_0_mapper","title":"mapper","text":"

    Since version: 2.0 \u2219 Type: string \u2219 Cardinality: Required Path: /vectorTiles/layers/[0]

    Describes the mapper converting from the OTP model entities to the vector tile properties.

    Currently Digitransit is supported for all layer types.

    "},{"location":"sandbox/MapboxVectorTilesApi/#extending","title":"Extending","text":"

    If more generic layers are created for this API, the code should be moved out from the sandbox, into the core, perhaps potentially leaving specific property mappers in place.

    "},{"location":"sandbox/MapboxVectorTilesApi/#creating-a-new-layer","title":"Creating a new layer","text":"

    In order to create a new type of layer, you need to create a new class extending LayerBuilder<T>. You need to implement two methods, List<Geometry> 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.

    "},{"location":"sandbox/MapboxVectorTilesApi/#creating-a-new-mapper","title":"Creating a new mapper","text":"

    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<T>. In that class, you need to implement the method Collection<KeyValue<String, Object>> 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.

    "},{"location":"sandbox/MapboxVectorTilesApi/#changelog","title":"Changelog","text":""},{"location":"sandbox/ParkAndRideApi/","title":"Park and Ride API","text":""},{"location":"sandbox/ParkAndRideApi/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/ParkAndRideApi/#changelog","title":"Changelog","text":""},{"location":"sandbox/ParkAndRideApi/#documentation","title":"Documentation","text":"

    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.

    "},{"location":"sandbox/ReportApi/","title":"Report API","text":"

    The report API is a collection of reports generated as CSV files. The main use-case is to download data for manual analyzes and verification. The CSV files should not be used as a service by another 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.

    "},{"location":"sandbox/ReportApi/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/ReportApi/#changelog","title":"Changelog","text":""},{"location":"sandbox/ReportApi/#documentation","title":"Documentation","text":"

    This module mounts an endpoint for generating reports under otp/report. Available reports:

    "},{"location":"sandbox/ReportApi/#configuration","title":"Configuration","text":"

    The report API is turned off by default. To turn it on enable the ReportApi feature.

    // otp-config.json\n{\n  \"otpFeatures\": {\n    \"ReportApi\": true\n  }\n}\n
    "},{"location":"sandbox/RideHailing/","title":"Ride hailing services","text":"

    This sandbox feature allows you to use ride hailing services like Uber.

    "},{"location":"sandbox/RideHailing/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/RideHailing/#configuration","title":"Configuration","text":"

    In order enable this feature, add a new section rideHailingServices in router-config.json.

    The supported ride-hailing providers are listed below.

    "},{"location":"sandbox/RideHailing/#uber","title":"Uber","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"uber-car-hailing\" enum The type of the service. Required 2.3 clientId string OAuth client id to access the API. Required 2.3 clientSecret string OAuth client secret to access the API. Required 2.3 wheelchairAccessibleProductId string The id of the requested wheelchair-accessible product ID. Required 2.3 bannedProductIds string[] The IDs of those product ids that should not be used for estimates. Optional 2.3"},{"location":"sandbox/RideHailing/#details","title":"Details","text":""},{"location":"sandbox/RideHailing/#rideHailingServices_0_wheelchairAccessibleProductId","title":"wheelchairAccessibleProductId","text":"

    Since version: 2.3 \u2219 Type: string \u2219 Cardinality: Required Path: /rideHailingServices/[0]

    The id of the requested wheelchair-accessible product ID.

    See bannedProductIds for a list of product IDs.

    "},{"location":"sandbox/RideHailing/#rideHailingServices_0_bannedProductIds","title":"bannedProductIds","text":"

    Since version: 2.3 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /rideHailingServices/[0]

    The IDs of those product ids that should not be used for estimates.

    See the current list of Uber product ids.

    "},{"location":"sandbox/RideHailing/#example-configuration","title":"Example configuration","text":"
    // router-config.json\n{\n  \"rideHailingServices\" : [\n    {\n      \"type\" : \"uber-car-hailing\",\n      \"clientId\" : \"secret-id\",\n      \"clientSecret\" : \"very-secret\",\n      \"wheelchairAccessibleProductId\" : \"545de0c4-659f-49c6-be65-0d5e448dffd5\",\n      \"bannedProductIds\" : [\n        \"1196d0dd-423b-4a81-a1d8-615367d3a365\",\n        \"f58761e5-8dd5-4940-a472-872f1236c596\"\n      ]\n    }\n  ]\n}\n
    "},{"location":"sandbox/SmooveBikeRental/","title":"HSL Smoove Bike Rental Updater Support - OTP Sandbox Extension","text":""},{"location":"sandbox/SmooveBikeRental/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/SmooveBikeRental/#changelog","title":"Changelog","text":""},{"location":"sandbox/SmooveBikeRental/#documentation","title":"Documentation","text":"

    TODO

    "},{"location":"sandbox/SmooveBikeRental/#configuration","title":"Configuration","text":"

    An example updater configuration:

    {\n    \"type\": \"bike-rental\",\n    \"sourceType\": \"smoove\",\n    \"network\": \"smoove-network-1\",\n    \"url\": \"https://helsinki-fi.smoove.pro/api-public/stations\",\n    \"frequency\": 10,\n    \"overloadingAllowed\": true\n}\n

    network (optional) allows defining custom network id

    overloadingAllowed (optional) defines if the stations in the network allow overloading (ignoring available spaces)

    "},{"location":"sandbox/Sorlandsbanen/","title":"S\u00f8rlandsbanen - The southern railroad in Norway","text":"

    This sandbox module is only working in Norway, in particular only in the south of Norway. The feature flag to turn it on should only be enabled if you are routing using the norwegian data set.

    The railroad in southern Norway is very slow and does not go by the coast where most people live. It is easily beaten by coaches in the area. Despite this, we need to include it in results where it is relevant.

    When the feature flag is enabled, two Raptor searches are performed. The first is the regular search - unmodified, as requested by the user. The second search is modified to include train results with S\u00f8rlandsbanen. This is achieved by setting a high COACH reluctance. We then take any rail results(if they exist) from the second search and add it two to the results from the first search. The new set of results will contain everything we found in the first search, plus the train results in the second results.

    Note! This looks at origin and destination coordinates in addition to the feature flag to enable the second search. It is automatically enabled if: - the OTPFeature.Sorlandsbanen is on. - the origin and/or destination is in the south of Norway. - the search is a long-distance search, origin and destination are fare apart from each other.

    "},{"location":"sandbox/Sorlandsbanen/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/Sorlandsbanen/#changelog","title":"Changelog","text":""},{"location":"sandbox/Sorlandsbanen/#configuration","title":"Configuration","text":"

    This is turned off by default. To turn it on enable the Sorlandsbanen feature.

    // otp-config.json\n{\n  \"otpFeatures\": {\n    \"Sorlandsbanen\": true\n  }\n}\n
    "},{"location":"sandbox/StopConsolidation/","title":"Stop Consolidation","text":""},{"location":"sandbox/StopConsolidation/#stop-consolidation","title":"Stop consolidation","text":""},{"location":"sandbox/StopConsolidation/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/StopConsolidation/#feature-explanation","title":"Feature explanation","text":"

    This sandbox feature allows you to \"combine\" equivalent stops from across several feeds into a single, consolidated one.

    It is achieved by defining a \"primary\" stop and one or more \"secondary\" stops. During the graph build all trip patterns are modified so that the secondary ones are swapped out for their primary equivalent.

    "},{"location":"sandbox/StopConsolidation/#effects","title":"Effects","text":"

    This has the following consequences

    Downsides

    However, this feature has also severe downsides:

    "},{"location":"sandbox/StopConsolidation/#configuration","title":"Configuration","text":"

    To enable this feature you need to add a file to OTP's working directory and configure its name like this:

    // build-config.json\n{\n  \"stopConsolidationFile\" : \"consolidated-stops.csv\"\n}\n

    The additional config file must look like the following:

    stop_group_id,feed_id,stop_id,is_primary\n1,pierce,1705867009,0\n1,kcm,10225,1\n2,pierce,1569,0\n2,commtrans,473,0\n2,kcm,1040,1\n

    The column names mean the following:

    "},{"location":"sandbox/VehicleParking/","title":"Vehicle Parking Updaters","text":""},{"location":"sandbox/VehicleParking/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/VehicleParking/#documentation","title":"Documentation","text":"

    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:

    "},{"location":"sandbox/VehicleParking/#configuration","title":"Configuration","text":"

    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:

    "},{"location":"sandbox/VehicleParking/#hsl-park-and-ride","title":"HSL Park and Ride","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"vehicle-parking\" enum The type of the updater. Required 1.5 facilitiesFrequencySec integer How often the facilities should be updated. Optional 3600 2.2 facilitiesUrl string URL of the facilities. Optional 2.2 feedId string The id of the data source, which will be the prefix of the parking lot's id. Required 2.2 hubsUrl string Hubs URL Optional 2.2 sourceType enum The source of the vehicle updates. Required 2.2 timeZone time-zone The time zone of the feed. Optional 2.2 utilizationsFrequencySec integer How often the utilization should be updated. Optional 600 2.2 utilizationsUrl string URL of the utilization data. Optional 2.2"},{"location":"sandbox/VehicleParking/#details","title":"Details","text":""},{"location":"sandbox/VehicleParking/#u__2__feedId","title":"feedId","text":"

    Since version: 2.2 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[2]

    The id of the data source, which will be the prefix of the parking lot's id.

    This will end up in the API responses as the feed id of the parking lot.

    "},{"location":"sandbox/VehicleParking/#u__2__sourceType","title":"sourceType","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Required Path: /updaters/[2] Enum values: park-api | bicycle-park-api | hsl-park | bikely | bikeep | siri-fm

    The source of the vehicle updates.

    "},{"location":"sandbox/VehicleParking/#u__2__timeZone","title":"timeZone","text":"

    Since version: 2.2 \u2219 Type: time-zone \u2219 Cardinality: Optional Path: /updaters/[2]

    The time zone of the feed.

    Used for converting abstract opening hours into concrete points in time.

    "},{"location":"sandbox/VehicleParking/#example-configuration","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"vehicle-parking\",\n      \"sourceType\" : \"hsl-park\",\n      \"feedId\" : \"hslpark\",\n      \"timeZone\" : \"Europe/Helsinki\",\n      \"facilitiesFrequencySec\" : 3600,\n      \"facilitiesUrl\" : \"https://p.hsl.fi/api/v1/facilities.json?limit=-1\",\n      \"utilizationsFrequencySec\" : 600,\n      \"utilizationsUrl\" : \"https://p.hsl.fi/api/v1/utilizations.json?limit=-1\",\n      \"hubsUrl\" : \"https://p.hsl.fi/api/v1/hubs.json?limit=-1\"\n    }\n  ]\n}\n
    "},{"location":"sandbox/VehicleParking/#parkapi","title":"ParkAPI","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"vehicle-parking\" enum The type of the updater. Required 1.5 feedId string The id of the data source, which will be the prefix of the parking lot's id. Required 2.2 frequency duration How often to update the source. Optional \"PT1M\" 2.2 sourceType enum The source of the vehicle updates. Required 2.2 timeZone time-zone The time zone of the feed. Optional 2.2 url string URL of the resource. Required 2.2 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.2 tags string[] Tags to add to the parking lots. Optional 2.2"},{"location":"sandbox/VehicleParking/#details_1","title":"Details","text":""},{"location":"sandbox/VehicleParking/#u__3__feedId","title":"feedId","text":"

    Since version: 2.2 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[3]

    The id of the data source, which will be the prefix of the parking lot's id.

    This will end up in the API responses as the feed id of the parking lot.

    "},{"location":"sandbox/VehicleParking/#u__3__sourceType","title":"sourceType","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Required Path: /updaters/[3] Enum values: park-api | bicycle-park-api | hsl-park | bikely | bikeep | siri-fm

    The source of the vehicle updates.

    "},{"location":"sandbox/VehicleParking/#u__3__timeZone","title":"timeZone","text":"

    Since version: 2.2 \u2219 Type: time-zone \u2219 Cardinality: Optional Path: /updaters/[3]

    The time zone of the feed.

    Used for converting abstract opening hours into concrete points in time.

    "},{"location":"sandbox/VehicleParking/#u__3__headers","title":"headers","text":"

    Since version: 2.2 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[3]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"sandbox/VehicleParking/#u__3__tags","title":"tags","text":"

    Since version: 2.2 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /updaters/[3]

    Tags to add to the parking lots.

    "},{"location":"sandbox/VehicleParking/#example-configuration_1","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"vehicle-parking\",\n      \"sourceType\" : \"park-api\",\n      \"feedId\" : \"parkapi\",\n      \"timeZone\" : \"Europe/Berlin\",\n      \"frequency\" : \"10m\",\n      \"url\" : \"https://foo.bar\",\n      \"headers\" : {\n        \"Cache-Control\" : \"max-age=604800\"\n      },\n      \"tags\" : [\n        \"source:parkapi\"\n      ]\n    }\n  ]\n}\n
    "},{"location":"sandbox/VehicleParking/#bikely","title":"Bikely","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"vehicle-parking\" enum The type of the updater. Required 1.5 feedId string The id of the data source, which will be the prefix of the parking lot's id. Required 2.2 frequency duration How often to update the source. Optional \"PT1M\" 2.3 sourceType enum The source of the vehicle updates. Required 2.2 url uri URL of the locations endpoint. Required 2.3 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.3"},{"location":"sandbox/VehicleParking/#details_2","title":"Details","text":""},{"location":"sandbox/VehicleParking/#u__4__feedId","title":"feedId","text":"

    Since version: 2.2 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[4]

    The id of the data source, which will be the prefix of the parking lot's id.

    This will end up in the API responses as the feed id of the parking lot.

    "},{"location":"sandbox/VehicleParking/#u__4__sourceType","title":"sourceType","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Required Path: /updaters/[4] Enum values: park-api | bicycle-park-api | hsl-park | bikely | bikeep | siri-fm

    The source of the vehicle updates.

    "},{"location":"sandbox/VehicleParking/#u__4__headers","title":"headers","text":"

    Since version: 2.3 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[4]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"sandbox/VehicleParking/#example-configuration_2","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"vehicle-parking\",\n      \"feedId\" : \"bikely\",\n      \"sourceType\" : \"bikely\",\n      \"url\" : \"https://api.safebikely.com/api/v1/s/locations\",\n      \"headers\" : {\n        \"X-Bikely-Token\" : \"${BIKELY_TOKEN}\",\n        \"Authorization\" : \"${BIKELY_AUTHORIZATION}\"\n      }\n    }\n  ]\n}\n
    "},{"location":"sandbox/VehicleParking/#bikeep","title":"Bikeep","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"vehicle-parking\" enum The type of the updater. Required 1.5 feedId string The id of the data source, which will be the prefix of the parking lot's id. Required 2.2 frequency duration How often to update the source. Optional \"PT1M\" 2.6 sourceType enum The source of the vehicle updates. Required 2.2 url uri URL of the locations endpoint. Required 2.6 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.6"},{"location":"sandbox/VehicleParking/#details_3","title":"Details","text":""},{"location":"sandbox/VehicleParking/#u__13__feedId","title":"feedId","text":"

    Since version: 2.2 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[13]

    The id of the data source, which will be the prefix of the parking lot's id.

    This will end up in the API responses as the feed id of the parking lot.

    "},{"location":"sandbox/VehicleParking/#u__13__sourceType","title":"sourceType","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Required Path: /updaters/[13] Enum values: park-api | bicycle-park-api | hsl-park | bikely | bikeep | siri-fm

    The source of the vehicle updates.

    "},{"location":"sandbox/VehicleParking/#u__13__headers","title":"headers","text":"

    Since version: 2.6 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[13]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"sandbox/VehicleParking/#example-configuration_3","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"vehicle-parking\",\n      \"feedId\" : \"bikeep\",\n      \"sourceType\" : \"bikeep\",\n      \"url\" : \"https://services.bikeep.com/location/v1/public-areas/no-baia-mobility/locations\"\n    }\n  ]\n}\n
    "},{"location":"sandbox/VehicleParking/#siri-fm","title":"SIRI-FM","text":"

    The SIRI-FM updater works slightly differently from the others in that it only updates the availability of parking but does not create new lots in realtime.

    The data source must conform to the Italian SIRI-FM profile which requires SIRI 2.1.

    Config Parameter Type Summary Req./Opt. Default Value Since type = \"vehicle-parking\" enum The type of the updater. Required 1.5 feedId string The id of the data source, which will be the prefix of the parking lot's id. Required 2.2 frequency duration How often to update the source. Optional \"PT1M\" 2.6 sourceType enum The source of the vehicle updates. Required 2.2 url uri URL of the SIRI-FM Light endpoint. Required 2.6 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.6"},{"location":"sandbox/VehicleParking/#details_4","title":"Details","text":""},{"location":"sandbox/VehicleParking/#u__14__feedId","title":"feedId","text":"

    Since version: 2.2 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[14]

    The id of the data source, which will be the prefix of the parking lot's id.

    This will end up in the API responses as the feed id of the parking lot.

    "},{"location":"sandbox/VehicleParking/#u__14__sourceType","title":"sourceType","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Required Path: /updaters/[14] Enum values: park-api | bicycle-park-api | hsl-park | bikely | bikeep | siri-fm

    The source of the vehicle updates.

    "},{"location":"sandbox/VehicleParking/#u__14__url","title":"url","text":"

    Since version: 2.6 \u2219 Type: uri \u2219 Cardinality: Required Path: /updaters/[14]

    URL of the SIRI-FM Light endpoint.

    SIRI Light means that it must be available as a HTTP GET request rather than the usual SIRI request mechanism of HTTP POST.

    The contents must also conform to the Italian SIRI profile which requires SIRI 2.1.

    "},{"location":"sandbox/VehicleParking/#u__14__headers","title":"headers","text":"

    Since version: 2.6 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[14]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"sandbox/VehicleParking/#example-configuration_4","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"vehicle-parking\",\n      \"feedId\" : \"parking\",\n      \"sourceType\" : \"siri-fm\",\n      \"url\" : \"https://transmodel.api.opendatahub.com/siri-lite/fm/parking\"\n    }\n  ]\n}\n
    "},{"location":"sandbox/VehicleParking/#changelog","title":"Changelog","text":""},{"location":"sandbox/VehicleRentalServiceDirectory/","title":"Vehicle Rental Service Directory API support","text":"

    This adds support for the GBFS service directory endpoint component Lamassu. OTP uses the service directory to lookup and connects to all GBFS endpoints registered in the directory. This simplifies the management of the GBFS endpoints, since multiple services/components like OTP can connect to the directory and get the necessary configuration from it.

    "},{"location":"sandbox/VehicleRentalServiceDirectory/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/VehicleRentalServiceDirectory/#changelog","title":"Changelog","text":""},{"location":"sandbox/VehicleRentalServiceDirectory/#configuration","title":"Configuration","text":"

    To enable this you need to specify a url for the vehicleRentalServiceDirectory in the router-config.json

    "},{"location":"sandbox/VehicleRentalServiceDirectory/#parameter-summary","title":"Parameter Summary","text":"Config Parameter Type Summary Req./Opt. Default Value Since language string Language code. Optional 2.1 sourcesName string Json tag name for updater sources. Optional \"systems\" 2.1 updaterNetworkName string Json tag name for the network name for each source. Optional \"id\" 2.1 updaterUrlName string Json tag name for endpoint urls for each source. Optional \"url\" 2.1 url uri Endpoint for the VehicleRentalServiceDirectory Required 2.1 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.1 networks object[] List all networks to include. Use \"network\": \"default-network\" to set defaults. Optional 2.4 allowKeepingVehicleAtDestination boolean Enables allowKeepingVehicleAtDestination for the given network. Optional false 2.5 geofencingZones boolean Enables geofencingZones for the given network Optional false 2.4 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0network string The network name Required 2.4"},{"location":"sandbox/VehicleRentalServiceDirectory/#parameter-details","title":"Parameter Details","text":""},{"location":"sandbox/VehicleRentalServiceDirectory/#vehicleRentalServiceDirectory_headers","title":"headers","text":"

    Since version: 2.1 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /vehicleRentalServiceDirectory

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"sandbox/VehicleRentalServiceDirectory/#vehicleRentalServiceDirectory_networks","title":"networks","text":"

    Since version: 2.4 \u2219 Type: object[] \u2219 Cardinality: Optional Path: /vehicleRentalServiceDirectory

    List all networks to include. Use \"network\": \"default-network\" to set defaults.

    If no default network exists only the listed networks are used. Configure a network with name \"default-network\" to include all unlisted networks. If not present, all unlisted networks are dropped. Note! The values in the \"default-network\" are not used to set missing field values in networks listed.

    "},{"location":"sandbox/VehicleRentalServiceDirectory/#vehicleRentalServiceDirectory_networks_0_allowKeepingVehicleAtDestination","title":"allowKeepingVehicleAtDestination","text":"

    Since version: 2.5 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /vehicleRentalServiceDirectory/networks/[0]

    Enables allowKeepingVehicleAtDestination for the given network.

    Configures if a vehicle rented from a station must be returned to another one or can be kept at the end of the trip.

    See the regular GBFS documentation for more information.

    "},{"location":"sandbox/VehicleRentalServiceDirectory/#vehicleRentalServiceDirectory_networks_0_geofencingZones","title":"geofencingZones","text":"

    Since version: 2.4 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /vehicleRentalServiceDirectory/networks/[0]

    Enables geofencingZones for the given network

    See the regular GBFS documentation for more information.

    "},{"location":"sandbox/VehicleRentalServiceDirectory/#example","title":"Example","text":"
    // router-config.json\n{\n  \"vehicleRentalServiceDirectory\" : {\n    \"url\" : \"https://example.com\",\n    \"sourcesName\" : \"systems\",\n    \"updaterUrlName\" : \"url\",\n    \"updaterNetworkName\" : \"id\",\n    \"headers\" : {\n      \"ET-Client-Name\" : \"otp\"\n    },\n    \"networks\" : [\n      {\n        \"network\" : \"oslo-by-sykkel\",\n        \"geofencingZones\" : true\n      }\n    ]\n  }\n}\n
    "},{"location":"sandbox/transferanalyzer/","title":"Direct transfer analyzer module","text":""},{"location":"sandbox/transferanalyzer/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/transferanalyzer/#changelog","title":"Changelog","text":""},{"location":"sandbox/transferanalyzer/#may-20th-2019","title":"May 20th 2019","text":""},{"location":"sandbox/transferanalyzer/#documentation","title":"Documentation","text":"

    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 class

    "},{"location":"sandbox/siri/SiriAzureUpdater/","title":"Siri Azure Updater","text":"

    This is a sandbox extension developed by Sk\u00e5netrafiken that allows OTP to fetch Siri ET & SX messages through Azure Service Bus. It also enables OTP to download historical data from en HTTP endpoint on startup.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#contact-info","title":"Contact Info","text":"

    Sk\u00e5netrafiken, Sweden developer.otp@skanetrafiken.se

    "},{"location":"sandbox/siri/SiriAzureUpdater/#documentation","title":"Documentation","text":"

    Documentation available here.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#configuration","title":"Configuration","text":"

    To enable the SIRI updater you need to add it to the updaters section of the router-config.json.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#siri-azure-et-updater","title":"Siri Azure ET Updater","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"siri-azure-et-updater\" enum The type of the updater. Required 1.5 authenticationType enum Which authentication type to use Optional \"sharedaccesskey\" 2.5 autoDeleteOnIdle duration The time after which an inactive subscription is removed. Optional \"PT1H\" 2.5 customMidnight integer Time on which time breaks into new day. Optional 0 2.2 feedId string The ID of the feed to apply the updates to. Optional 2.2 fullyQualifiedNamespace string Service Bus fully qualified namespace used for authentication. Optional 2.5 fuzzyTripMatching boolean Whether to apply fuzzyTripMatching on the updates Optional false 2.2 prefetchCount integer The number of messages to fetch from the subscription at a time. Optional 10 2.5 servicebus-url string Service Bus connection used for authentication. Optional 2.2 topic string Service Bus topic to connect to. Optional 2.2 history object Configuration for fetching historical data on startup Optional 2.2 \u00a0\u00a0\u00a0fromDateTime string Datetime boundary for historical data Optional \"-P1D\" 2.2 \u00a0\u00a0\u00a0timeout integer Timeout in milliseconds Optional 300000 na \u00a0\u00a0\u00a0url string Endpoint to fetch from Optional na"},{"location":"sandbox/siri/SiriAzureUpdater/#parameter-details","title":"Parameter details","text":""},{"location":"sandbox/siri/SiriAzureUpdater/#u__11__authenticationType","title":"authenticationType","text":"

    Since version: 2.5 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"sharedaccesskey\" Path: /updaters/[11] Enum values: sharedaccesskey | federatedidentity

    Which authentication type to use

    "},{"location":"sandbox/siri/SiriAzureUpdater/#u__11__customMidnight","title":"customMidnight","text":"

    Since version: 2.2 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 0 Path: /updaters/[11]

    Time on which time breaks into new day.

    It is common that operating day date breaks a little bit later than midnight so that the switch happens when traffic is at the lowest point. Parameter uses 24-hour format. If the switch happens on 4 am then set this field to 4.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#u__11__fullyQualifiedNamespace","title":"fullyQualifiedNamespace","text":"

    Since version: 2.5 \u2219 Type: string \u2219 Cardinality: Optional Path: /updaters/[11]

    Service Bus fully qualified namespace used for authentication.

    Has to be present for authenticationMethod FederatedIdentity.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#u__11__servicebus_url","title":"servicebus-url","text":"

    Since version: 2.2 \u2219 Type: string \u2219 Cardinality: Optional Path: /updaters/[11]

    Service Bus connection used for authentication.

    Has to be present for authenticationMethod SharedAccessKey. This should be Primary/Secondary connection string from service bus.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#example-configuration","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"siri-azure-et-updater\",\n      \"topic\" : \"some_topic\",\n      \"authenticationType\" : \"SharedAccessKey\",\n      \"fullyQualifiedNamespace\" : \"fully_qualified_namespace\",\n      \"servicebus-url\" : \"service_bus_url\",\n      \"feedId\" : \"feed_id\",\n      \"customMidnight\" : 4,\n      \"history\" : {\n        \"url\" : \"endpoint_url\",\n        \"fromDateTime\" : \"-P1D\",\n        \"timeout\" : 300000\n      }\n    }\n  ]\n}\n
    "},{"location":"sandbox/siri/SiriAzureUpdater/#siri-azure-sx-updater","title":"Siri Azure SX Updater","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"siri-azure-sx-updater\" enum The type of the updater. Required 1.5 authenticationType enum Which authentication type to use Optional \"sharedaccesskey\" 2.5 autoDeleteOnIdle duration The time after which an inactive subscription is removed. Optional \"PT1H\" 2.5 customMidnight integer Time on which time breaks into new day. Optional 0 2.2 feedId string The ID of the feed to apply the updates to. Optional 2.2 fullyQualifiedNamespace string Service Bus fully qualified namespace used for authentication. Optional 2.5 fuzzyTripMatching boolean Whether to apply fuzzyTripMatching on the updates Optional false 2.2 prefetchCount integer The number of messages to fetch from the subscription at a time. Optional 10 2.5 servicebus-url string Service Bus connection used for authentication. Optional 2.2 topic string Service Bus topic to connect to. Optional 2.2 history object Configuration for fetching historical data on startup Optional 2.2 \u00a0\u00a0\u00a0fromDateTime string Datetime boundary for historical data. Optional \"-P1D\" 2.2 \u00a0\u00a0\u00a0timeout integer Timeout in milliseconds Optional 300000 na \u00a0\u00a0\u00a0toDateTime string Datetime boundary for historical data. Optional \"P1D\" 2.2 \u00a0\u00a0\u00a0url string Endpoint to fetch from Optional na"},{"location":"sandbox/siri/SiriAzureUpdater/#parameter-details_1","title":"Parameter details","text":""},{"location":"sandbox/siri/SiriAzureUpdater/#u__10__authenticationType","title":"authenticationType","text":"

    Since version: 2.5 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"sharedaccesskey\" Path: /updaters/[10] Enum values: sharedaccesskey | federatedidentity

    Which authentication type to use

    "},{"location":"sandbox/siri/SiriAzureUpdater/#u__10__customMidnight","title":"customMidnight","text":"

    Since version: 2.2 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 0 Path: /updaters/[10]

    Time on which time breaks into new day.

    It is common that operating day date breaks a little bit later than midnight so that the switch happens when traffic is at the lowest point. Parameter uses 24-hour format. If the switch happens on 4 am then set this field to 4.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#u__10__fullyQualifiedNamespace","title":"fullyQualifiedNamespace","text":"

    Since version: 2.5 \u2219 Type: string \u2219 Cardinality: Optional Path: /updaters/[10]

    Service Bus fully qualified namespace used for authentication.

    Has to be present for authenticationMethod FederatedIdentity.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#u__10__servicebus_url","title":"servicebus-url","text":"

    Since version: 2.2 \u2219 Type: string \u2219 Cardinality: Optional Path: /updaters/[10]

    Service Bus connection used for authentication.

    Has to be present for authenticationMethod SharedAccessKey. This should be Primary/Secondary connection string from service bus.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#example-configuration_1","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"siri-azure-sx-updater\",\n      \"topic\" : \"some_topic\",\n      \"servicebus-url\" : \"service_bus_url\",\n      \"feedId\" : \"feed_id\",\n      \"customMidnight\" : 4,\n      \"history\" : {\n        \"url\" : \"endpoint_url\",\n        \"fromDateTime\" : \"-P1D\",\n        \"toDateTime\" : \"P1D\",\n        \"timeout\" : 300000\n      }\n    }\n  ]\n}\n
    "},{"location":"sandbox/siri/SiriAzureUpdater/#changelog","title":"Changelog","text":""},{"location":"sandbox/siri/SiriGooglePubSubUpdater/","title":"Siri-ET Google PubSub Updater","text":"

    Support for consuming SIRI-ET messages over a Google Cloud PubSub subscription. Similarly to the SIRI-ET HTTP updater, this updater is developed to support the Nordic SIRI profile which is a subset of the SIRI specification.

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#contact-info","title":"Contact Info","text":"

    Entur, Norway https://entur.no/

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#documentation","title":"Documentation","text":"

    This updater consumes SIRI real time information over an asynchronous publisher/subscriber feed provided by a Google Cloud PubSub topic.

    For more documentation see the Entur Real-Time Data documentation and the Norwegian SIRI profile .

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#configuration","title":"Configuration","text":"

    To enable the SIRI-ET Google PubSub updater you need to add it to the updaters section of the router-config.json.

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#siri-et-via-google-pubsub","title":"Siri-ET via Google PubSub","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"siri-et-google-pubsub-updater\" enum The type of the updater. Required 1.5 dataInitializationUrl string URL used to download over HTTP the recent history of SIRI-ET messages. Optional 2.1 feedId string The ID of the feed to apply the updates to. Optional 2.1 fuzzyTripMatching boolean If the trips should be matched fuzzily. Optional false 2.1 initialGetDataTimeout duration Timeout for retrieving the recent history of SIRI-ET messages. Optional \"PT30S\" 2.1 producerMetrics boolean If failure, success, and warning metrics should be collected per producer. Optional false 2.7 reconnectPeriod duration Wait this amount of time before trying to reconnect to the PubSub subscription. Optional \"PT30S\" 2.1 subscriptionProjectName string The Google Cloud project that hosts the PubSub subscription. Required 2.1 topicName string The name of the PubSub topic that publishes the updates. Required 2.1 topicProjectName string The Google Cloud project that hosts the PubSub topic that publishes the updates. Required 2.1"},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#parameter-details","title":"Parameter details","text":""},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#u__12__dataInitializationUrl","title":"dataInitializationUrl","text":"

    Since version: 2.1 \u2219 Type: string \u2219 Cardinality: Optional Path: /updaters/[12]

    URL used to download over HTTP the recent history of SIRI-ET messages.

    Optionally the updater can download the recent history of SIRI-ET messages from this URL. If this parameter is set, the updater will be marked as initialized (primed) only when the message history is fully downloaded and applied.

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#u__12__initialGetDataTimeout","title":"initialGetDataTimeout","text":"

    Since version: 2.1 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT30S\" Path: /updaters/[12]

    Timeout for retrieving the recent history of SIRI-ET messages.

    When trying to fetch the message history over HTTP, the updater will wait this amount of time for the connection to be established. If the connection times out, the updater will retry indefinitely with exponential backoff.

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#u__12__reconnectPeriod","title":"reconnectPeriod","text":"

    Since version: 2.1 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT30S\" Path: /updaters/[12]

    Wait this amount of time before trying to reconnect to the PubSub subscription.

    In case of a network error, the updater will try periodically to reconnect to the Google PubSub subscription.

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#u__12__subscriptionProjectName","title":"subscriptionProjectName","text":"

    Since version: 2.1 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[12]

    The Google Cloud project that hosts the PubSub subscription.

    During startup, the updater creates a PubSub subscription that listens to the PubSub topic that publishes SIRI-ET updates. This parameter specifies in which Google Cloud project the subscription will be created. The topic and the subscription can be hosted in two different projects.

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#example-configuration","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"siri-et-google-pubsub-updater\",\n      \"feedId\" : \"feed_id\",\n      \"reconnectPeriod\" : \"5s\",\n      \"initialGetDataTimeout\" : \"1m20s\",\n      \"topicProjectName\" : \"google_pubsub_topic_project_name\",\n      \"subscriptionProjectName\" : \"google_pubsub_subscription_project_name\",\n      \"topicName\" : \"estimated_timetables\",\n      \"dataInitializationUrl\" : \"https://example.com/some/path\",\n      \"fuzzyTripMatching\" : true\n    }\n  ]\n}\n
    "},{"location":"sandbox/siri/SiriUpdater/","title":"Siri Updater","text":"

    Support for consuming SIRI ET and SX messages. The updater is developed to support the Nordic SIRI profile which is a subset of the SIRI specification.

    "},{"location":"sandbox/siri/SiriUpdater/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/siri/SiriUpdater/#documentation","title":"Documentation","text":"

    This updater consumes SIRI real time information. It is developed by Entur and supports 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 documentation and the Norwegian SIRI profile .

    "},{"location":"sandbox/siri/SiriUpdater/#configuration","title":"Configuration","text":"

    To enable the SIRI updater you need to add it to the updaters section of the router-config.json.

    "},{"location":"sandbox/siri/SiriUpdater/#siri-et-via-https","title":"Siri-ET via HTTPS","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"siri-et-updater\" enum The type of the updater. Required 1.5 blockReadinessUntilInitialized boolean Whether catching up with the updates should block the readiness check from returning a 'ready' result. Optional false 2.0 feedId string The ID of the feed to apply the updates to. Required 2.0 frequency duration How often the updates should be retrieved. Optional \"PT1M\" 2.0 fuzzyTripMatching boolean If the fuzzy trip matcher should be used to match trips. Optional false 2.0 previewInterval duration TODO Optional 2.0 producerMetrics boolean If failure, success, and warning metrics should be collected per producer. Optional false 2.7 requestorRef string The requester reference. Optional 2.0 timeout duration The HTTP timeout to download the updates. Optional \"PT15S\" 2.0 url string The URL to send the HTTP requests to. Required 2.0 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.3"},{"location":"sandbox/siri/SiriUpdater/#parameter-details","title":"Parameter details","text":""},{"location":"sandbox/siri/SiriUpdater/#u__8__url","title":"url","text":"

    Since version: 2.0 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[8]

    The URL to send the HTTP requests to.

    Use the file protocol to set a directory for reading updates from a directory. The file loader will look for xml files: '*.xml' in the configured directory. The files are renamed by the loader when processed:

    a.xml \u00a0 \u279e \u00a0 a.xml.inProgress \u00a0 \u279e \u00a0 a.xml.ok \u00a0 or \u00a0 a.xml.failed

    "},{"location":"sandbox/siri/SiriUpdater/#u__8__headers","title":"headers","text":"

    Since version: 2.3 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[8]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"sandbox/siri/SiriUpdater/#example-configuration","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"siri-et-updater\",\n      \"url\" : \"https://example.com/some/path\",\n      \"feedId\" : \"feed_id\",\n      \"timeout\" : \"30s\",\n      \"headers\" : {\n        \"Authorization\" : \"Some-Token\"\n      }\n    }\n  ]\n}\n
    "},{"location":"sandbox/siri/SiriUpdater/#siri-sx-via-https","title":"Siri-SX via HTTPS","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"siri-sx-updater\" enum The type of the updater. Required 1.5 blockReadinessUntilInitialized boolean Whether catching up with the updates should block the readiness check from returning a 'ready' result. Optional false 2.0 earlyStart duration This value is subtracted from the actual validity defined in the message. Optional \"PT0S\" 2.0 feedId string The ID of the feed to apply the updates to. Required 2.0 frequency duration How often the updates should be retrieved. Optional \"PT1M\" 2.0 requestorRef string The requester reference. Optional 2.0 timeout duration The HTTP timeout to download the updates. Optional \"PT15S\" 2.0 url string The URL to send the HTTP requests to. Supports http/https and file protocol. Required 2.0 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.3"},{"location":"sandbox/siri/SiriUpdater/#parameter-details_1","title":"Parameter details","text":""},{"location":"sandbox/siri/SiriUpdater/#u__9__earlyStart","title":"earlyStart","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT0S\" Path: /updaters/[9]

    This value is subtracted from the actual validity defined in the message.

    Normally the planned departure time is used, so setting this to 10s will cause the SX-message to be included in trip-results 10 seconds before the the planned departure time.

    "},{"location":"sandbox/siri/SiriUpdater/#u__9__url","title":"url","text":"

    Since version: 2.0 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[9]

    The URL to send the HTTP requests to. Supports http/https and file protocol.

    Use the file protocol to set a directory for reading updates from a directory. The file loader will look for xml files: '*.xml' in the configured directory. The files are renamed by the loader when processed:

    a.xml \u00a0 \u279e \u00a0 a.xml.inProgress \u00a0 \u279e \u00a0 a.xml.ok \u00a0 or \u00a0 a.xml.failed

    "},{"location":"sandbox/siri/SiriUpdater/#u__9__headers","title":"headers","text":"

    Since version: 2.3 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[9]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"sandbox/siri/SiriUpdater/#example-configuration_1","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"siri-sx-updater\",\n      \"url\" : \"https://example.com/some/path\",\n      \"feedId\" : \"feed_id\",\n      \"timeout\" : \"30s\",\n      \"headers\" : {\n        \"Key\" : \"Value\"\n      }\n    }\n  ]\n}\n
    "},{"location":"sandbox/siri/SiriUpdater/#changelog","title":"Changelog","text":""}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Home","text":""},{"location":"#opentripplanner-2","title":"OpenTripPlanner 2","text":"

    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 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. 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 around the world.

    You are currently reading the documentation for OpenTripPlanner 2, the second major version of OTP.

    "},{"location":"#versions-of-this-documentation","title":"Versions of this documentation","text":"

    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 upper left of the published documentation.

    Releases

    Snapshot

    "},{"location":"#audience","title":"Audience","text":"

    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 intended 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.

    "},{"location":"#quick-start","title":"Quick Start","text":"

    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 page.

    "},{"location":"#getting-help","title":"Getting help","text":"

    The fastest way to get help is to use our Gitter chat room where most of the core developers are. Bug reports may be filed via the Github issue tracker. The issue tracker is not intended for support questions or discussions. Please use the chat for this purpose. The OpenTripPlanner mailing list is treated as a legacy communications channel and used almost exclusively for project announcements. Again, please direct development and support discussions to the Gitter chat.

    "},{"location":"#financial-and-in-kind-support","title":"Financial and In-Kind Support","text":"

    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 accounting@sfconservancy.org 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.

    "},{"location":"Accessibility/","title":"Accessibility","text":""},{"location":"Accessibility/#preamble","title":"Preamble","text":"

    In this document and in OTP, the term \"accessibility\" is used with its most common meaning: design of products, devices, services, vehicles, or environments to ensure they are usable by people with disabilities. If you have reached this page looking for cumulative opportunities accessibility indicators (access to opportunities metrics) please see the Analysis page.

    While accessibility is a complex subject, at this point GTFS and Netex mostly represent it very simply as a yes/no possibility of wheelchair use. While OTP developers hope to broaden the scope and nuance of accessibility support in OTP, the lack of detailed data from data producers currently limits implementation and discussion in this document to this binary \"wheelchair accessible\" definition.

    "},{"location":"Accessibility/#unknown-data","title":"Unknown data","text":"

    Many agencies have the same problem: data on wheelchair-accessibility is, if it exists at all, patchy. If you only included trips and stops that are explicitly set to be wheelchair-accessible rather than unknown, it would be hard to get any result at all. For this reason OTP allows you to configure which sort of unknown information should be taken into account.

    "},{"location":"Accessibility/#configuration","title":"Configuration","text":"

    If you want to allow trips and stops of unknown wheelchair-accessibility then add the following to router-config.json:

    {\n  \"routingDefaults\": {\n    \"wheelchairAccessibility\": {\n      \"trip\": {\n        \"onlyConsiderAccessible\": false,\n        \"unknownCost\": 600,\n        \"inaccessibleCost\": 3600\n      },\n      \"stop\": {\n        \"onlyConsiderAccessible\": false,\n        \"unknownCost\": 600,\n        \"inaccessibleCost\": 3600\n      },\n      \"elevator\": {\n        \"onlyConsiderAccessible\": false\n      },\n      \"inaccessibleStreetReluctance\": 25,\n      \"maxSlope\": 0.08333,\n      \"slopeExceededReluctance\": 50,\n      \"stairsReluctance\": 25\n    }\n  },\n  \"updaters\": []\n}\n

    The parameters for stop, trip and elevator mean the following:

    name default onlyConsiderAccessible Whether to exclude unknown accessibility and inaccessible stops/trips/elevators in the search. true unknownCost The cost to add if an entity has unknown wheelchair accessibility 600 inaccessibleCost The cost to add if an entity is known to be inaccessible 3600

    Note: Unless your accessibility data coverage is complete you will receive much better results by setting onlyConsiderAccessible=false, because otherwise you receive barely any results.

    Other parameters are:

    "},{"location":"Accessibility/#accessible-transfers","title":"Accessible transfers","text":"

    By default OTP only pre-calculates transfers between stops for able-bodied walkers. If they have no obstacles wheelchair users can use them, too, but there won't be guaranteed to be one.

    If you want OTP to also pre-generate wheelchair-accessible transfers use the following configuration in build-config.json:

    {\n  \"transferRequests\": [\n    {\n      \"modes\": \"WALK\"\n    },\n    {\n      \"modes\": \"WALK\",\n      \"wheelchairAccessibility\": {\n        \"enabled\": true\n      }\n    }\n  ]\n}\n

    This results in OTP calculating an accessible transfer if the default one is found to be inaccessible to wheelchair users.

    "},{"location":"Accessibility/#example","title":"Example","text":"

    A full configuration example is available at /docs/examples

    "},{"location":"Analysis/","title":"Travel Time Analysis","text":""},{"location":"Analysis/#background","title":"Background","text":"

    Since the beginning of the project, many OTP contributors and users have been primarily interested in research, spatial analysis, and urban planning use cases. They have prototyped many ideas within or on top of the OTP codebase, including one-to-many searches producing travel time grids, isochrones, and access-to-opportunities indicators (see Terminology Note below). This has historically been a major area of application for OpenTripPlanner and has helped popularize cumulative opportunities metrics in urban planning. For example, the University of Minnesota Accessibility Observatory used OpenTripPlanner for Access Across America.

    Although we consider these use cases quite important, most work of this kind has long since shifted to separate projects focused on urban planning and analytics. As of version 2, OTP has chosen to focus entirely on passenger information rather than analytics.

    "},{"location":"Analysis/#travel-time-analysis-in-otp1","title":"Travel Time Analysis in OTP1","text":"

    Much of the analysis code present in the v1.x legacy branch of OTP is essentially an unmaintained and unsupported early prototype for later projects, specifically 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 used 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.

    "},{"location":"Analysis/#travel-time-analysis-in-otp2","title":"Travel Time Analysis in OTP2","text":"

    OTP2's new transit router is quite similar to R5 (indeed it was directly influenced by R5) and would not face the same technical problems. Nonetheless, we have decided not to port the OTP1 analysis features over to OTP2 since it would broaden the scope of OTP2 away from passenger information and draw the finite amount of available attention and resources away from existing open source analytics tools. If you would like to apply the routing innovations present in OTP2 in analytics situations, we recommend taking a look at projects like R5 or the R and Python language wrappers for it created by the community.

    "},{"location":"Analysis/#terminology-note","title":"Terminology Note","text":"

    In OpenTripPlanner, we usually use the term \"accessibility\" with its most common meaning: design of products, devices, services, vehicles, or environments to ensure they are usable by people with disabilities. The term \"accessibility\" has a completely separate, unrelated definition in the fields of spatial analysis, urban transportation planning, and associated social sciences, where it refers to quantitative indicators of how well-connected a particular location is to people or opportunities. OTP has been widely used in research and planning settings for the calculation of such indicators. Although this meaning of the term dates back many decades, it is less well known and has become a source of confusion, so the academic and planning communities are gradually shifting to the expression \"access to opportunities\", often shortened to \"access\".

    "},{"location":"Basic-Tutorial/","title":"OpenTripPlanner Basic Tutorial","text":"

    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!

    "},{"location":"Basic-Tutorial/#get-java","title":"Get Java","text":"

    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 21 or later. We recommend running on Java 21 rather than a later version, as it is a long-term support release. Run java -version to check that you have version 21 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.

    "},{"location":"Basic-Tutorial/#get-otp","title":"Get OTP","text":"

    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, navigate to the directory of releases, and download the file with shaded.jar suffix .

    You may also want to get your own copy of the OTP source code and build a bleeding edge development JAR from scratch, especially if you plan to do some development yourself. In that case, check out the branch dev-2.x.

    "},{"location":"Basic-Tutorial/#get-some-data","title":"Get some data","text":""},{"location":"Basic-Tutorial/#gtfs-for-transit-schedules-and-stops","title":"GTFS for Transit Schedules and Stops","text":"

    First you'll need GTFS data to build a transit network. There's an excellent description of the GTFS format here. Transport agencies throughout the world provide GTFS schedules to the public. Transitland has a registry of feeds and TransitFeeds 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. 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\n$ mkdir otp\n$ cd otp\n$ wget \"http://developer.trimet.org/schedule/gtfs.zip\" -O trimet.gtfs.zip\n
    "},{"location":"Basic-Tutorial/#osm-for-streets","title":"OSM for Streets","text":"

    You'll also need OpenStreetMap data to build a road network for walking, cycling, and driving. OpenStreetMap 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 . Geofabrik provides extracts for larger areas like countries or states, from which you can prepare your own smaller bounding-box extracts using Osmosis , osmconvert, or (our favorite) Osmium-Tool. There is also Protomaps which can create custom extracts for any region of the world with an easy to use drag and drop interface. OSM data can be delivered as XML or in the more compact binary PBF format. OpenTripPlanner consumes only PBF because it's smaller and more efficient.

    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 , then further trim that to just the TriMet service area using the bounding box switch of one of the above tools. On Linux or MacOS you could do that as follows:

    $ cd /home/username\n$ wget http://download.geofabrik.de/north-america/us/oregon-latest.osm.pbf\n$ osmconvert oregon-latest.osm.pbf -b=-123.043,45.246,-122.276,45.652 --complete-ways -o=portland.pbf\n$ mv portland.pbf otp\n

    We find this tool 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 for additional information and example commands for cropping and filtering OSM data.

    "},{"location":"Basic-Tutorial/#starting-otp","title":"Starting OTP","text":"

    A typical command to start OTP looks like java -Xmx2G -jar otp.shaded.jar <options>. 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. Here is more information about the system requirements. If you have sufficient memory in your computer, set this to a couple of gigabytes (e.g. -Xmx2G). Java uses a garbage collection approach to memory management, which requires some \"breathing room\" to efficiently operate. Without sufficient free memory OTP can grind to a halt. VisualVM is a good way to inspect Java memory usage, especially with the VisualGC plugin.

    "},{"location":"Basic-Tutorial/#building-graphs","title":"Building Graphs","text":"

    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', 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.

    "},{"location":"Basic-Tutorial/#simple-one-step-server","title":"Simple One-step Server","text":"

    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.6.0-shaded.jar --build --serve /home/username/otp\n

    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/ 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 port 8080. If by any chance some other software is already using that port number, you can specify a different port number with a switch --port 8801.

    "},{"location":"Basic-Tutorial/#saving-a-graph","title":"Saving a Graph","text":"

    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.6.0-shaded.jar --build --save .\n

    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.6.0-shaded.jar --load .\n

    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.

    "},{"location":"Basic-Tutorial/#layering-gtfs-onto-osm","title":"Layering GTFS onto OSM","text":"

    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:

    $ java -Xmx2G -jar otp-2.6.0-shaded.jar --buildStreet .\n

    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.6.0-shaded.jar --loadStreet --save .\n

    Finally, the server can be started using the --load parameter:

    $ java -Xmx2G -jar otp-2.6.0-shaded.jar --load .\n
    "},{"location":"Basic-Tutorial/#command-line-switches","title":"Command Line Switches","text":"

    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.

    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.

    "},{"location":"Basic-Tutorial/#exploring-the-api","title":"Exploring the API","text":"

    If you want to learn how to use OTP's API's, check out the GraphQL tutorial.

    "},{"location":"Bibliography/","title":"Routing Bibliography","text":"

    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.

    "},{"location":"Bibliography/#algorithms-used-in-otp2-but-not-otp1","title":"Algorithms used in OTP2 but not OTP1","text":""},{"location":"Bibliography/#techniques-used-in-or-influencing-otp1-and-otp2","title":"Techniques used in or influencing OTP1 and OTP2","text":""},{"location":"Bibliography/#general-background","title":"General Background","text":""},{"location":"Bibliography/#path-search-speedup-techniques","title":"Path Search Speedup Techniques","text":""},{"location":"Bibliography/#multi-objective-pareto-shortest-paths","title":"Multi-objective Pareto Shortest Paths","text":""},{"location":"Bibliography/#resource-constrained-routing","title":"Resource-constrained Routing","text":""},{"location":"Bibliography/#contraction-and-transfer-patterns","title":"Contraction and Transfer Patterns","text":""},{"location":"Bibliography/#timetable-based-routing","title":"Timetable-based routing","text":""},{"location":"Bibliography/#alt-and-metric-embeddings","title":"ALT and Metric Embeddings","text":""},{"location":"Bibliography/#calibration-and-implementation-details","title":"Calibration and Implementation Details","text":""},{"location":"Bibliography/#post-dijkstra-public-transit-routing","title":"Post-Dijkstra Public Transit Routing","text":""},{"location":"BoardingLocations/","title":"Boarding locations","text":"

    It is often the case that the coordinates of stops are relatively far away from where the passengers are expected to the wait for the vehicle.

    A good example of this is Buckhead subway station in Atlanta.

    There the coordinates of the stop in GTFS are located near Peachtree Road so OTP would instruct passengers to wait on the street rather than walking down the stairs to the platform.

    "},{"location":"BoardingLocations/#osm-tagging","title":"OSM tagging","text":"

    We can correct the waiting location for the passenger by adding some tags to OSM which help OTP decide to correct the location. In general, you should familiarise yourself with the OSM wiki page on public transport.

    You can add cross-references to a stop's id or code on all OSM entities (nodes, ways, relations) which have one of the following tag combinations:

    "},{"location":"BoardingLocations/#notes","title":"Notes","text":""},{"location":"BoardingLocations/#cross-referencing","title":"Cross-referencing","text":"

    In order to tell OTP how to link up the OSM entities to the stops you need to add a ref tag whose value is the stop's id or code.

    However, tagging conventions vary from location to location so other tags can be configured, too.

    For example, there is a country-wide stop reference system in Germany called IFOPT and therefore if you want to use it to match stops (example platform), add the following to build-config.json:

    {\n  \"boardingLocationTags\": [\"ref\", \"ref:IFOPT\"]\n}\n
    "},{"location":"BoardingLocations/#multiple-stops-on-the-same-platform","title":"Multiple stops on the same platform","text":"

    Some stations have a middle platform with a stop on either side of it. In such a case, you can simply add two or more references separated by a semicolon, as seen in this example.

    "},{"location":"BoardingLocations/#related-chat-threads","title":"Related chat threads","text":""},{"location":"BuildConfiguration/","title":"Build","text":""},{"location":"BuildConfiguration/#graph-build-configuration","title":"Graph Build Configuration","text":"

    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.

    "},{"location":"BuildConfiguration/#parameters-overview","title":"Parameters Overview","text":"Config Parameter Type Summary Req./Opt. Default Value Since areaVisibility boolean Perform visibility calculations. Optional false 1.5 buildReportDir uri URI to the directory where the graph build report should be written to. Optional 2.0 configVersion string Deployment version of the build-config.json. Optional 2.1 dataImportReport boolean Generate nice HTML report of Graph errors/warnings Optional false 2.0 distanceBetweenElevationSamples double The distance between elevation samples in meters. Optional 10.0 2.0 embedRouterConfig boolean Embed the Router config in the graph, which allows it to be sent to a server fully configured over the wire. Optional true 2.0 graph uri URI to the graph object file for reading and writing. Optional 2.0 gsCredentials string Local file system path to Google Cloud Platform service accounts credentials file. Optional 2.0 includeEllipsoidToGeoidDifference boolean Include the Ellipsoid to Geoid difference in the calculations of every point along every StreetWithElevationEdge. Optional false 2.0 maxAreaNodes integer Visibility calculations for an area will not be done if there are more nodes than this limit. Optional 150 2.1 maxDataImportIssuesPerFile integer When to split the import report. Optional 1000 2.0 maxElevationPropagationMeters integer The maximum distance to propagate elevation to vertices which have no elevation. Optional 2000 1.5 maxStopToShapeSnapDistance double Maximum distance between route shapes and their stops. Optional 150.0 2.1 maxTransferDuration duration Transfers up to this duration with the default walk speed value will be pre-calculated and included in the Graph. Optional \"PT30M\" 2.1 multiThreadElevationCalculations boolean Configuring multi-threading during elevation calculations. Optional false 2.0 osmCacheDataInMem boolean If OSM data should be cached in memory during processing. Optional false 2.0 osmNaming enum A custom OSM namer to use. Optional \"default\" 1.5 platformEntriesLinking boolean Link unconnected entries to public transport platforms. Optional false 2.0 readCachedElevations boolean Whether to read cached elevation data. Optional true 2.0 staticBikeParkAndRide boolean Whether we should create bike P+R stations from OSM data. Optional false 1.5 staticParkAndRide boolean Whether we should create car P+R stations from OSM data. Optional true 1.5 stopConsolidationFile uri Name of the CSV-formatted file in the build directory which contains the configuration for stop consolidation. Optional 2.5 streetGraph uri URI to the street graph object file for reading and writing. Optional 2.0 subwayAccessTime double Minutes necessary to reach stops served by trips on routes of route_type=1 (subway) from the street. Optional 2.0 1.5 transitModelTimeZone time-zone Time zone for the graph. Optional 2.2 transitServiceEnd duration Limit the import of transit services to the given end date. Optional \"P3Y\" 2.0 transitServiceStart duration Limit the import of transit services to the given START date. Optional \"-P1Y\" 2.0 writeCachedElevations boolean Reusing elevation data from previous builds Optional false 2.0 boardingLocationTags string[] What OSM tags should be looked on for the source of matching stops to platforms and stops. Optional 2.2 dataOverlay object Config for the DataOverlay Sandbox module Optional 2.2 dem object[] Specify parameters for DEM extracts. Optional 2.2 elevationUnitMultiplier double Specify a multiplier to convert elevation units from source to meters. Overrides the value specified in demDefaults. Optional 1.0 2.3 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0source uri The unique URI pointing to the data file. Required 2.2 demDefaults object Default properties for DEM extracts. Optional 2.3 elevationUnitMultiplier double Specify a multiplier to convert elevation units from source to meters. Optional 1.0 2.3 elevationBucket object Used to download NED elevation tiles from the given AWS S3 bucket. Optional na emissions object Emissions configuration. Optional 2.5 fares object Fare configuration. Optional 2.0 gtfsDefaults object The gtfsDefaults section allows you to specify default properties for GTFS files. Optional 2.3 \u00a0\u00a0\u00a0blockBasedInterlining boolean Whether to create stay-seated transfers in between two trips with the same block id. Optional true 2.3 discardMinTransferTimes boolean Should minimum transfer times in GTFS files be discarded. Optional false 2.3 \u00a0\u00a0\u00a0maxInterlineDistance integer Maximal distance between stops in meters that will connect consecutive trips that are made with same vehicle. Optional 200 2.3 \u00a0\u00a0\u00a0removeRepeatedStops boolean Should consecutive identical stops be merged into one stop time entry. Optional true 2.3 stationTransferPreference enum Should there be some preference or aversion for transfers at stops that are part of a station. Optional \"allowed\" 2.3 islandPruning object Settings for fixing street graph connectivity errors Optional 2.3 adaptivePruningDistance integer Search distance for analyzing islands in pruning. Optional 250 2.3 adaptivePruningFactor double Defines how much pruning thresholds grow maximally by distance. Optional 50.0 2.3 islandWithStopsMaxSize integer When a graph island with stops in it should be pruned. Optional 2 2.3 islandWithoutStopsMaxSize integer When a graph island without stops should be pruned. Optional 10 2.3 localFileNamePatterns object Patterns for matching OTP file types in the base directory Optional 2.0 dem regexp Pattern for matching elevation DEM files. Optional \"(?i)\\.tiff?$\" 2.0 gtfs regexp Patterns for matching GTFS zip-files or directories. Optional \"(?i)gtfs\" 2.0 netex regexp Patterns for matching NeTEx zip files or directories. Optional \"(?i)netex\" 2.0 osm regexp Pattern for matching Open Street Map input files. Optional \"(?i)(\\.pbf\u00a6\\.osm\u00a6\\.osm\\.xml)$\" 2.0 netexDefaults object The netexDefaults section allows you to specify default properties for NeTEx files. Optional 2.2 \u00a0\u00a0\u00a0feedId string This field is used to identify the specific NeTEx feed. It is used instead of the feed_id field in GTFS file feed_info.txt. Optional \"NETEX\" 2.2 groupFilePattern regexp Pattern for matching group NeTEx files. Optional \"(\\w{3})-.*\\.xml\" 2.0 \u00a0\u00a0\u00a0ignoreFareFrame boolean Ignore contents of the FareFrame Optional false 2.3 ignoreFilePattern regexp Pattern for matching ignored files in a NeTEx bundle. Optional \"$^\" 2.0 \u00a0\u00a0\u00a0ignoreParking boolean Ignore Parking elements. Optional true 2.6 \u00a0\u00a0\u00a0noTransfersOnIsolatedStops boolean Whether we should allow transfers to and from StopPlaces marked with LimitedUse.ISOLATED Optional false 2.2 sharedFilePattern regexp Pattern for matching shared NeTEx files in a NeTEx bundle. Optional \"shared-data\\.xml\" 2.0 sharedGroupFilePattern regexp Pattern for matching shared group NeTEx files in a NeTEx bundle. Optional \"(\\w{3})-.*-shared\\.xml\" 2.0 ferryIdsNotAllowedForBicycle string[] List ferries which do not allow bikes. Optional 2.0 osm object[] Configure properties for a given OpenStreetMap feed. Optional 2.2 osmTagMapping enum The named set of mapping rules applied when parsing OSM tags. Overrides the value specified in osmDefaults. Optional \"default\" 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0source uri The unique URI pointing to the data file. Required 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0timeZone time-zone The timezone used to resolve opening hours in OSM data. Overrides the value specified in osmDefaults. Optional 2.2 osmDefaults object Default properties for OpenStreetMap feeds. Optional 2.2 osmTagMapping enum The named set of mapping rules applied when parsing OSM tags. Optional \"default\" 2.2 \u00a0\u00a0\u00a0timeZone time-zone The timezone used to resolve opening hours in OSM data. Optional 2.2 transferRequests object[] Routing requests to use for pre-calculating stop-to-stop transfers. Optional 2.1 transitFeeds object[] Scan for transit data files Optional 2.2 \u00a0\u00a0\u00a0{ object } object Nested object in array. The object type is determined by the parameters. Optional 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type = \"gtfs\" enum The feed input format. Required 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0blockBasedInterlining boolean Whether to create stay-seated transfers in between two trips with the same block id. Overrides the value specified in gtfsDefaults. Optional true 2.3 discardMinTransferTimes boolean Should minimum transfer times in GTFS files be discarded. Overrides the value specified in gtfsDefaults. Optional false 2.3 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0feedId string The unique ID for this feed. This overrides any feed ID defined within the feed itself. Optional 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0maxInterlineDistance integer Maximal distance between stops in meters that will connect consecutive trips that are made with same vehicle. Overrides the value specified in gtfsDefaults. Optional 200 2.3 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0removeRepeatedStops boolean Should consecutive identical stops be merged into one stop time entry. Overrides the value specified in gtfsDefaults. Optional true 2.3 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0source uri The unique URI pointing to the data file. Required 2.2 stationTransferPreference enum Should there be some preference or aversion for transfers at stops that are part of a station. Overrides the value specified in gtfsDefaults. Optional \"allowed\" 2.3 \u00a0\u00a0\u00a0{ object } object Nested object in array. The object type is determined by the parameters. Optional 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type = \"netex\" enum The feed input format. Required 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0feedId string This field is used to identify the specific NeTEx feed. It is used instead of the feed_id field in GTFS file feed_info.txt. Required 2.2 groupFilePattern regexp Pattern for matching group NeTEx files. Optional \"(\\w{3})-.*\\.xml\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ignoreFareFrame boolean Ignore contents of the FareFrame Optional false 2.3 ignoreFilePattern regexp Pattern for matching ignored files in a NeTEx bundle. Optional \"$^\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ignoreParking boolean Ignore Parking elements. Optional true 2.6 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0noTransfersOnIsolatedStops boolean Whether we should allow transfers to and from StopPlaces marked with LimitedUse.ISOLATED Optional false 2.2 sharedFilePattern regexp Pattern for matching shared NeTEx files in a NeTEx bundle. Optional \"shared-data\\.xml\" 2.0 sharedGroupFilePattern regexp Pattern for matching shared group NeTEx files in a NeTEx bundle. Optional \"(\\w{3})-.*-shared\\.xml\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0source uri The unique URI pointing to the data file. Required 2.2 ferryIdsNotAllowedForBicycle string[] List ferries which do not allow bikes. Optional 2.0 transitRouteToStationCentroid feed-scoped-id[] List stations that should route to centroid. Optional 2.7"},{"location":"BuildConfiguration/#specifying-uris","title":"Specifying URIs","text":"

    As a general rule, references to data files are specified as absolute URIs and must start with the protocol name.

    Example

    Local files: \"file:///Users/kelvin/otp/streetGraph.obj\" HTTPS resources: \"https://download.geofabrik.de/europe/norway-latest.osm.pbf\" Google Cloud Storage files: \"gs://otp-test-bucket/a/b/graph.obj\"

    Alternatively if a relative URI can be provided, it is interpreted as a path relative to the base directory.

    Example

    File relative to the base directory (inside the base directory): streetGraph.obj File relative to the base directory (outside the base directory): ../street-graphs/streetGraph.obj

    "},{"location":"BuildConfiguration/#example-with-multiple-data-sources","title":"Example With Multiple Data Sources","text":"

    For example, this configuration could be used to load GTFS and OSM inputs from Google Cloud Storage:

    // build-config.json\n{\n  \"osm\": [\n    {\n      \"source\": \"gs://bucket-name/streets.pbf\"\n    }\n  ],\n  \"transitFeeds\": [\n    {\n      \"type\": \"netex\",\n      \"source\": \"gs://bucket-name/transit1.zip\"\n    },\n    {\n      \"type\": \"gtfs\",\n      \"source\": \"gs://bucket-name/transit2.zip\"\n    }\n  ]\n}\n

    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.

    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 OTP2 will still scan the base directory for all other types such as DEM files. Supplying an empty array for a particular file type will ensure that no inputs of that type are loaded, including by local directory scanning.

    "},{"location":"BuildConfiguration/#limit-transit-service-period","title":"Limit the transit service period","text":"

    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.

    Example

    // build-config.json\n{\n  // Include 3 months of history\n  \"transitServiceStart\" : \"-P3M\",\n  // Include 1 year 6 month and 5 days of scheduled data in the future \n  \"transitServiceEnd\" : \"P1Y6M5D\"\n}\n
    "},{"location":"BuildConfiguration/#openstreetmaposm-configuration","title":"OpenStreetMap(OSM) configuration","text":"

    It is possible to adjust how OSM data is interpreted by OpenTripPlanner when building the road part of the routing graph.

    "},{"location":"BuildConfiguration/#osm-tag-mapping","title":"OSM tag mapping","text":"

    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 roads tagged with `highway=trunk are (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. It's possible to define \"safety\" values for cycling and walking which are used in routing.

    To add your own OSM tag mapping have a look at org.opentripplanner.graph_builder.module.osm.tagmapping.NorwayTagMapper and org.opentripplanner.graph_builder.module.osm.tagmapping.DefaultMapper as examples. 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.

    // build-config.json\n{\n  \"osm\": [\n    {\n      \"source\": \"gs://marduk-dev/osm/oslo_norway.osm-160816.pbf\",\n      \"osmTagMapping\": \"norway\"\n    }\n  ]\n}\n
    "},{"location":"BuildConfiguration/#elevation-data","title":"Elevation data","text":"

    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.

    "},{"location":"BuildConfiguration/#geoid-difference","title":"Geoid Difference","text":"

    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 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 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:

    // router-config.json\n{\n    \"routingDefaults\": {\n        \"geoidElevation\": true   \n    }\n}\n

    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:

    // build-config.json\n{\n  \"includeEllipsoidToGeoidDifference\": true\n}\n

    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.

    "},{"location":"BuildConfiguration/#other-raster-elevation-data","title":"Other raster elevation data","text":"

    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 (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.

    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. Use gdal_merge.py -o merged.tiff *.dem to merge a set of dem files into one tif file.

    See Interline PlanetUtils for a set of scripts to download, merge, and resample Mapzen/Amazon Terrain Tiles.

    "},{"location":"BuildConfiguration/#elevation-unit-conversion","title":"Elevation unit conversion","text":"

    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.

    // build-config.json\n{\n  \"dem\": [\n    {\n      \"source\": \"gs://otp-test-bucket/a/b/northpole.dem.tif\",\n      // Correct conversion multiplier when source data uses decimetres instead of metres\n      \"elevationUnitMultiplier\": 0.1\n    }\n  ]\n}\n
    "},{"location":"BuildConfiguration/#elevation-data-calculation-optimizations","title":"Elevation Data Calculation Optimizations","text":"

    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 the elevations took 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 the data won't need to be downloaded.

    However, the bulk of the time will still be spent calculating elevations for 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.

    "},{"location":"BuildConfiguration/#reusing-elevation-data-from-previous-builds","title":"Reusing elevation data from previous builds","text":"

    In order to write out the precalculated elevation data, add this to your build-config.json file:

    // build-config.json\n{  \n  \"writeCachedElevations\": true\n}\n
    See writeCachedElevations for details.

    "},{"location":"BuildConfiguration/#parameter-details","title":"Parameter Details","text":""},{"location":"BuildConfiguration/#areaVisibility","title":"areaVisibility","text":"

    Since version: 1.5 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /

    Perform visibility calculations.

    If this is true OTP attempts to calculate a path straight through an OSM area using the shortest way rather than around the edge of it. (These calculations can be time consuming).

    "},{"location":"BuildConfiguration/#buildReportDir","title":"buildReportDir","text":"

    Since version: 2.0 \u2219 Type: uri \u2219 Cardinality: Optional Path: /

    URI to the directory where the graph build report should be written to.

    The html report is written into this directory. If the directory exist, any existing files are deleted. If it does not exist, it is created.

    "},{"location":"BuildConfiguration/#configVersion","title":"configVersion","text":"

    Since version: 2.1 \u2219 Type: string \u2219 Cardinality: Optional Path: /

    Deployment version of the build-config.json.

    The config-version is a parameter which each OTP deployment may set to be able to query the OTP server and verify that it uses the correct version of the config. The version should be injected into the config in the (continuous) deployment pipeline. How this is done, is up to the deployment.

    The config-version has no effect on OTP, and is provided as is on the API. There is no syntax or format check on the version and it can be any string.

    Be aware that OTP uses the config embedded in the loaded graph if no new config is provided.

    "},{"location":"BuildConfiguration/#dataImportReport","title":"dataImportReport","text":"

    Since version: 2.0 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /

    Generate nice HTML report of Graph errors/warnings

    The reports are stored in the same location as the graph.

    "},{"location":"BuildConfiguration/#distanceBetweenElevationSamples","title":"distanceBetweenElevationSamples","text":"

    Since version: 2.0 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 10.0 Path: /

    The distance between elevation samples in meters.

    The default is the approximate resolution of 1/3 arc-second NED data. This should not be smaller than the horizontal resolution of the height data used.

    "},{"location":"BuildConfiguration/#graph","title":"graph","text":"

    Since version: 2.0 \u2219 Type: uri \u2219 Cardinality: Optional Path: /

    URI to the graph object file for reading and writing.

    The file is created or overwritten if OTP saves the graph to the file.

    "},{"location":"BuildConfiguration/#gsCredentials","title":"gsCredentials","text":"

    Since version: 2.0 \u2219 Type: string \u2219 Cardinality: Optional Path: /

    Local file system path to Google Cloud Platform service accounts credentials file.

    The credentials is used to access GCS urls. When using GCS from outside of Google Cloud you need to provide a path the the service credentials. Environment variables in the path are resolved.

    This is a path to a file on the local file system, not an URI.

    "},{"location":"BuildConfiguration/#includeEllipsoidToGeoidDifference","title":"includeEllipsoidToGeoidDifference","text":"

    Since version: 2.0 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /

    Include the Ellipsoid to Geoid difference in the calculations of every point along every StreetWithElevationEdge.

    When set to true (it is false by default), the elevation module will include the Ellipsoid to Geoid difference in the calculations of every point along every StreetWithElevationEdge in the graph.

    NOTE: if this is set to true for graph building, make sure to not set the value of RoutingResource#geoidElevation to true otherwise OTP will add this geoid value again to all of the elevation values in the street edges.

    "},{"location":"BuildConfiguration/#maxDataImportIssuesPerFile","title":"maxDataImportIssuesPerFile","text":"

    Since version: 2.0 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 1000 Path: /

    When to split the import report.

    If the number of issues is larger then maxDataImportIssuesPerFile, then the files will be split in multiple files. Since browsers have problems opening large HTML files.

    "},{"location":"BuildConfiguration/#maxStopToShapeSnapDistance","title":"maxStopToShapeSnapDistance","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 150.0 Path: /

    Maximum distance between route shapes and their stops.

    This field is used for mapping routes geometry shapes. It determines max distance between shape points and their stop sequence. If mapper cannot find any stops within this radius it will default to simple stop-to-stop geometry instead.

    "},{"location":"BuildConfiguration/#multiThreadElevationCalculations","title":"multiThreadElevationCalculations","text":"

    Since version: 2.0 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /

    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. If multi-threading is activated, parallel streams will be used to calculate the elevations.

    "},{"location":"BuildConfiguration/#osmCacheDataInMem","title":"osmCacheDataInMem","text":"

    Since version: 2.0 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /

    If OSM data should be cached in memory during processing.

    When loading OSM data, the input is streamed 3 times - one phase for processing RELATIONS, one for WAYS and last one for NODES. Instead of reading the data source 3 times it might be faster to cache the entire osm file im memory. The trade off is of course that OTP might use more memory while loading osm data. You can use this parameter to choose what is best for your deployment depending on your infrastructure. Set the parameter to true to cache the data, and to false to read the stream from the source each time.

    "},{"location":"BuildConfiguration/#osmNaming","title":"osmNaming","text":"

    Since version: 1.5 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"default\" Path: / Enum values: default | portland | sidewalks

    A custom OSM namer to use.

    "},{"location":"BuildConfiguration/#readCachedElevations","title":"readCachedElevations","text":"

    Since version: 2.0 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: true Path: /

    Whether to read cached elevation data.

    When set to true, the elevation module will attempt to read this file in order to reuse calculations of elevation data for various coordinate sequences instead of recalculating them all over again.

    "},{"location":"BuildConfiguration/#streetGraph","title":"streetGraph","text":"

    Since version: 2.0 \u2219 Type: uri \u2219 Cardinality: Optional Path: /

    URI to the street graph object file for reading and writing.

    The file is created or overwritten if OTP saves the graph to the file

    "},{"location":"BuildConfiguration/#subwayAccessTime","title":"subwayAccessTime","text":"

    Since version: 1.5 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 2.0 Path: /

    Minutes necessary to reach stops served by trips on routes of route_type=1 (subway) from the street.

    Note! The preferred way to do this is to update the OSM data. See In-station navigation.

    The ride locations for some modes of transport such as subways 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.

    This setting does not generalize to other modes like airplanes because you often need much longer time to check in to a flight (2-3 hours for international flights) than to alight and exit the airport (perhaps 1 hour). Use boardSlackForMode and alightSlackForMode for this.

    "},{"location":"BuildConfiguration/#transitModelTimeZone","title":"transitModelTimeZone","text":"

    Since version: 2.2 \u2219 Type: time-zone \u2219 Cardinality: Optional Path: /

    Time zone for the graph.

    This is used to store the timetables in the transit model, and to interpret times in incoming requests.

    "},{"location":"BuildConfiguration/#transitServiceEnd","title":"transitServiceEnd","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"P3Y\" Path: /

    Limit the import of transit services to the given end date.

    See Limit the transit service period for an introduction.

    The date is inclusive. If set, any transit service on a day AFTER the given date is dropped and will not be part of the graph. Use an absolute date or a period relative to the date the graph is build(BUILD_DAY).

    Use an empty string to make it unbounded.

    "},{"location":"BuildConfiguration/#transitServiceStart","title":"transitServiceStart","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"-P1Y\" Path: /

    Limit the import of transit services to the given START date.

    See Limit the transit service period for an introduction.

    The date is inclusive. If set, any transit service on a day BEFORE the given date is dropped and will not be part of the graph. Use an absolute date or a period relative to the date the graph is build(BUILD_DAY).

    Use an empty string to make unbounded.

    "},{"location":"BuildConfiguration/#writeCachedElevations","title":"writeCachedElevations","text":"

    Since version: 2.0 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /

    Reusing elevation data from previous builds

    When set to true, the elevation module will create a file cache for calculated elevation data. Subsequent graph builds can reuse the data in this file.

    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 overridden via the CLI argument --cache <directory>. For the same graph build for multiple Northeast US states, the time it took with using this pre-downloaded and precalculated data became 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.

    "},{"location":"BuildConfiguration/#boardingLocationTags","title":"boardingLocationTags","text":"

    Since version: 2.2 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /

    What OSM tags should be looked on for the source of matching stops to platforms and stops.

    Detailed documentation

    "},{"location":"BuildConfiguration/#dem","title":"dem","text":"

    Since version: 2.2 \u2219 Type: object[] \u2219 Cardinality: Optional Path: /

    Specify parameters for DEM extracts.

    The dem section allows you to override the default behavior of scanning for elevation files in the base directory. You can specify data located outside the local filesystem (including cloud storage services) or at various different locations around the local filesystem.

    If not specified OTP will fall back to auto-detection based on the directory provided on the command line.

    "},{"location":"BuildConfiguration/#dem_0_elevationUnitMultiplier","title":"elevationUnitMultiplier","text":"

    Since version: 2.3 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 1.0 Path: /dem/[0]

    Specify a multiplier to convert elevation units from source to meters. Overrides the value specified in demDefaults.

    Unit conversion multiplier for elevation values. No conversion needed if the elevation values are defined in meters in the source data. If, for example, decimetres are used in the source data, this should be set to 0.1.

    "},{"location":"BuildConfiguration/#demDefaults_elevationUnitMultiplier","title":"elevationUnitMultiplier","text":"

    Since version: 2.3 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 1.0 Path: /demDefaults

    Specify a multiplier to convert elevation units from source to meters.

    Unit conversion multiplier for elevation values. No conversion needed if the elevation values are defined in meters in the source data. If, for example, decimetres are used in the source data, this should be set to 0.1.

    "},{"location":"BuildConfiguration/#elevationBucket","title":"elevationBucket","text":"

    Since version: na \u2219 Type: object \u2219 Cardinality: Optional Path: /

    Used to download NED elevation tiles from the given AWS S3 bucket.

    In the United States, a high resolution National Elevation Dataset 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. 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.

    This ned13 bucket is still available on S3 under a \"requester pays\" policy. As long as you specify valid AWS account credentials you should be able to download tiles, and any bandwidth costs will be billed to your AWS account.

    Once the tiles are downloaded for a particular geographic area, OTP will keep them in local cache for the next graph build operation. You should add the --cache <directory> command line parameter to specify your NED tile cache location.

    "},{"location":"BuildConfiguration/#gd_discardMinTransferTimes","title":"discardMinTransferTimes","text":"

    Since version: 2.3 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /gtfsDefaults

    Should minimum transfer times in GTFS files be discarded.

    This is useful eg. when the minimum transfer time is only set for ticketing purposes, but we want to calculate the transfers always from OSM data.

    "},{"location":"BuildConfiguration/#gd_stationTransferPreference","title":"stationTransferPreference","text":"

    Since version: 2.3 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"allowed\" Path: /gtfsDefaults Enum values: preferred | recommended | allowed | discouraged

    Should there be some preference or aversion for transfers at stops that are part of a station.

    This parameter sets the generic level of preference. What is the actual cost can be changed with the stopBoardAlightDuringTransferCost parameter in the router configuration.

    "},{"location":"BuildConfiguration/#islandPruning_adaptivePruningDistance","title":"adaptivePruningDistance","text":"

    Since version: 2.3 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 250 Path: /islandPruning

    Search distance for analyzing islands in pruning.

    The distance after which disconnected sub graph is considered as real island in pruning heuristics.

    "},{"location":"BuildConfiguration/#islandPruning_adaptivePruningFactor","title":"adaptivePruningFactor","text":"

    Since version: 2.3 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 50.0 Path: /islandPruning

    Defines how much pruning thresholds grow maximally by distance.

    Expands the pruning thresholds as the distance of an island from the rest of the graph gets smaller. Even fairly large disconnected sub graphs should be removed if they are badly entangled with other graph.

    "},{"location":"BuildConfiguration/#islandPruning_islandWithStopsMaxSize","title":"islandWithStopsMaxSize","text":"

    Since version: 2.3 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 2 Path: /islandPruning

    When a graph island with stops in it should be pruned.

    This field indicates the pruning threshold for islands with stops. Any such island under this edge count will be pruned.

    "},{"location":"BuildConfiguration/#islandPruning_islandWithoutStopsMaxSize","title":"islandWithoutStopsMaxSize","text":"

    Since version: 2.3 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 10 Path: /islandPruning

    When a graph island without stops should be pruned.

    This field indicates the pruning threshold for islands without stops. Any such island under this edge count will be pruned.

    "},{"location":"BuildConfiguration/#localFileNamePatterns","title":"localFileNamePatterns","text":"

    Since version: 2.0 \u2219 Type: object \u2219 Cardinality: Optional Path: /

    Patterns for matching OTP file types in the base directory

    When scanning the base directory for inputs, each file's name is checked against patterns to detect what kind of file it is.

    OTP1 used to peek inside ZIP files and read the CSV tables to guess if a ZIP was indeed GTFS. Now that we support remote input files (cloud storage or arbitrary URLs) not all data sources allow seeking within files to guess what they are. Therefore, like all other file types GTFS is now 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.

    "},{"location":"BuildConfiguration/#lfp_dem","title":"dem","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(?i)\\.tiff?$\" Path: /localFileNamePatterns

    Pattern for matching elevation DEM files.

    If the filename contains the given pattern it is considered a match. Any legal Java Regular expression is allowed.

    "},{"location":"BuildConfiguration/#lfp_gtfs","title":"gtfs","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(?i)gtfs\" Path: /localFileNamePatterns

    Patterns for matching GTFS zip-files or directories.

    If the filename contains the given pattern it is considered a match. Any legal Java Regular expression is allowed.

    "},{"location":"BuildConfiguration/#lfp_netex","title":"netex","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(?i)netex\" Path: /localFileNamePatterns

    Patterns for matching NeTEx zip files or directories.

    If the filename contains the given pattern it is considered a match. Any legal Java Regular expression is allowed.

    "},{"location":"BuildConfiguration/#lfp_osm","title":"osm","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(?i)(\\.pbf|\\.osm|\\.osm\\.xml)$\" Path: /localFileNamePatterns

    Pattern for matching Open Street Map input files.

    If the filename contains the given pattern it is considered a match. Any legal Java Regular expression is allowed.

    "},{"location":"BuildConfiguration/#nd_groupFilePattern","title":"groupFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(\\w{3})-.*\\.xml\" Path: /netexDefaults

    Pattern for matching group NeTEx files.

    This field is used to match group files in the module file(zip file entries). group files are loaded right the after shared group files are loaded. Files are grouped together by the first group pattern in the regular expression. The pattern \"(\\w{3})-.*\\.xml\" matches \"RUT-Line-208-Hagalia-Nevlunghavn.xml\" with group \"RUT\".

    "},{"location":"BuildConfiguration/#nd_ignoreFilePattern","title":"ignoreFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"$^\" Path: /netexDefaults

    Pattern for matching ignored files in a NeTEx bundle.

    This field is used to exclude matching files in the module file(zip file entries). The ignored files are not loaded.

    "},{"location":"BuildConfiguration/#nd_sharedFilePattern","title":"sharedFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"shared-data\\.xml\" Path: /netexDefaults

    Pattern for matching shared NeTEx files in a NeTEx bundle.

    This field is used to match shared files(zip file entries) in the module file. Shared files are loaded first. Then the rest of the files are grouped and loaded.

    The pattern \"shared-data.xml\" matches \"shared-data.xml\"

    File names are matched in the following order - and treated accordingly to the first match:

    "},{"location":"BuildConfiguration/#nd_sharedGroupFilePattern","title":"sharedGroupFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(\\w{3})-.*-shared\\.xml\" Path: /netexDefaults

    Pattern for matching shared group NeTEx files in a NeTEx bundle.

    This field is used to match shared group files in the module file(zip file entries). Typically this is used to group all files from one agency together.

    Shared group files are loaded after shared files, but before the matching group files. Each group of files are loaded as a unit, followed by next group.

    Files are grouped together by the first group pattern in the regular expression.

    The pattern \"(\\w{3})-.*-shared\\.xml\" matches \"RUT-shared.xml\" with group \"RUT\".

    "},{"location":"BuildConfiguration/#nd_ferryIdsNotAllowedForBicycle","title":"ferryIdsNotAllowedForBicycle","text":"

    Since version: 2.0 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /netexDefaults

    List ferries which do not allow bikes.

    Bicycles are allowed on most ferries however the Nordic profile doesn't contain a place where bicycle conveyance can be defined.

    For this reason we allow bicycles on ferries by default and allow to override the rare case where this is not the case.

    "},{"location":"BuildConfiguration/#osm","title":"osm","text":"

    Since version: 2.2 \u2219 Type: object[] \u2219 Cardinality: Optional Path: /

    Configure properties for a given OpenStreetMap feed.

    The osm section of build-config.json allows you to override the default behavior of scanning for OpenStreetMap files in the base directory. You can specify data located outside the local filesystem (including cloud storage services) or at various different locations around the local filesystem.

    "},{"location":"BuildConfiguration/#osm_0_osmTagMapping","title":"osmTagMapping","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"default\" Path: /osm/[0] Enum values: default | norway | uk | finland | germany | hamburg | atlanta | houston | portland | constant-speed-finland

    The named set of mapping rules applied when parsing OSM tags. Overrides the value specified in osmDefaults.

    "},{"location":"BuildConfiguration/#od_osmTagMapping","title":"osmTagMapping","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"default\" Path: /osmDefaults Enum values: default | norway | uk | finland | germany | hamburg | atlanta | houston | portland | constant-speed-finland

    The named set of mapping rules applied when parsing OSM tags.

    "},{"location":"BuildConfiguration/#transitFeeds","title":"transitFeeds","text":"

    Since version: 2.2 \u2219 Type: object[] \u2219 Cardinality: Optional Path: /

    Scan for transit data files

    The transitFeeds section of build-config.json allows you to override the default behavior of scanning for transit data files in the base directory. You can specify data located outside the local filesystem (including cloud storage services) or at various different locations around the local filesystem.

    When a feed of a particular type (netex or gtfs) is specified in the transitFeeds section, auto-scanning in the base directory for this feed type will be disabled.

    "},{"location":"BuildConfiguration/#tf_0_discardMinTransferTimes","title":"discardMinTransferTimes","text":"

    Since version: 2.3 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /transitFeeds/[0]

    Should minimum transfer times in GTFS files be discarded. Overrides the value specified in gtfsDefaults.

    This is useful eg. when the minimum transfer time is only set for ticketing purposes, but we want to calculate the transfers always from OSM data.

    "},{"location":"BuildConfiguration/#tf_0_stationTransferPreference","title":"stationTransferPreference","text":"

    Since version: 2.3 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"allowed\" Path: /transitFeeds/[0] Enum values: preferred | recommended | allowed | discouraged

    Should there be some preference or aversion for transfers at stops that are part of a station. Overrides the value specified in gtfsDefaults.

    This parameter sets the generic level of preference. What is the actual cost can be changed with the stopBoardAlightDuringTransferCost parameter in the router configuration.

    "},{"location":"BuildConfiguration/#tf_1_groupFilePattern","title":"groupFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(\\w{3})-.*\\.xml\" Path: /transitFeeds/[1]

    Pattern for matching group NeTEx files.

    This field is used to match group files in the module file(zip file entries). group files are loaded right the after shared group files are loaded. Files are grouped together by the first group pattern in the regular expression. The pattern \"(\\w{3})-.*\\.xml\" matches \"RUT-Line-208-Hagalia-Nevlunghavn.xml\" with group \"RUT\".

    "},{"location":"BuildConfiguration/#tf_1_ignoreFilePattern","title":"ignoreFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"$^\" Path: /transitFeeds/[1]

    Pattern for matching ignored files in a NeTEx bundle.

    This field is used to exclude matching files in the module file(zip file entries). The ignored files are not loaded.

    "},{"location":"BuildConfiguration/#tf_1_sharedFilePattern","title":"sharedFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"shared-data\\.xml\" Path: /transitFeeds/[1]

    Pattern for matching shared NeTEx files in a NeTEx bundle.

    This field is used to match shared files(zip file entries) in the module file. Shared files are loaded first. Then the rest of the files are grouped and loaded.

    The pattern \"shared-data.xml\" matches \"shared-data.xml\"

    File names are matched in the following order - and treated accordingly to the first match:

    "},{"location":"BuildConfiguration/#tf_1_sharedGroupFilePattern","title":"sharedGroupFilePattern","text":"

    Since version: 2.0 \u2219 Type: regexp \u2219 Cardinality: Optional \u2219 Default value: \"(\\w{3})-.*-shared\\.xml\" Path: /transitFeeds/[1]

    Pattern for matching shared group NeTEx files in a NeTEx bundle.

    This field is used to match shared group files in the module file(zip file entries). Typically this is used to group all files from one agency together.

    Shared group files are loaded after shared files, but before the matching group files. Each group of files are loaded as a unit, followed by next group.

    Files are grouped together by the first group pattern in the regular expression.

    The pattern \"(\\w{3})-.*-shared\\.xml\" matches \"RUT-shared.xml\" with group \"RUT\".

    "},{"location":"BuildConfiguration/#tf_1_ferryIdsNotAllowedForBicycle","title":"ferryIdsNotAllowedForBicycle","text":"

    Since version: 2.0 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /transitFeeds/[1]

    List ferries which do not allow bikes.

    Bicycles are allowed on most ferries however the Nordic profile doesn't contain a place where bicycle conveyance can be defined.

    For this reason we allow bicycles on ferries by default and allow to override the rare case where this is not the case.

    "},{"location":"BuildConfiguration/#transitRouteToStationCentroid","title":"transitRouteToStationCentroid","text":"

    Since version: 2.7 \u2219 Type: feed-scoped-id[] \u2219 Cardinality: Optional Path: /

    List stations that should route to centroid.

    This field contains a list of station ids for which street legs will start/end at the station centroid instead of the child stops.

    When searching from/to a station the default behaviour is to route from/to any of the stations child stops. This can cause strange results for stations that have stops spread over a large area.

    For some stations you might instead wish to use the centroid of the station as the origin/destination. In this case the centroid will be used both for direct street search and for access/egress street search where the station is used as the start/end of the access/egress. But transit that starts/ends at the station will work as usual without any additional street leg from/to the centroid.

    "},{"location":"BuildConfiguration/#build-config-example","title":"Build Config Example","text":"
    // build-config.json\n{\n  \"transitServiceStart\" : \"-P3M\",\n  \"transitServiceEnd\" : \"P1Y\",\n  \"osmCacheDataInMem\" : true,\n  \"localFileNamePatterns\" : {\n    \"osm\" : \"(i?)\\\\.osm\\\\.pbf$\",\n    \"dem\" : \"(i?)\\\\.dem\\\\.tiff?$\",\n    \"gtfs\" : \"(?i)gtfs\",\n    \"netex\" : \"(?i)netex\"\n  },\n  \"osmDefaults\" : {\n    \"timeZone\" : \"Europe/Rome\",\n    \"osmTagMapping\" : \"default\"\n  },\n  \"osm\" : [\n    {\n      \"source\" : \"gs://my-bucket/otp-work-dir/norway.osm.pbf\",\n      \"timeZone\" : \"Europe/Oslo\",\n      \"osmTagMapping\" : \"norway\"\n    }\n  ],\n  \"demDefaults\" : {\n    \"elevationUnitMultiplier\" : 1.0\n  },\n  \"dem\" : [\n    {\n      \"source\" : \"gs://my-bucket/otp-work-dir/norway.dem.tiff\",\n      \"elevationUnitMultiplier\" : 2.5\n    }\n  ],\n  \"netexDefaults\" : {\n    \"feedId\" : \"EN\",\n    \"sharedFilePattern\" : \"_stops.xml\",\n    \"sharedGroupFilePattern\" : \"_(\\\\w{3})_shared_data.xml\",\n    \"groupFilePattern\" : \"(\\\\w{3})_.*\\\\.xml\",\n    \"ignoreFilePattern\" : \"(temp|tmp)\",\n    \"ferryIdsNotAllowedForBicycle\" : [\n      \"RUT:B107\",\n      \"RUT:B209\"\n    ]\n  },\n  \"gtfsDefaults\" : {\n    \"stationTransferPreference\" : \"recommended\",\n    \"removeRepeatedStops\" : true,\n    \"discardMinTransferTimes\" : false,\n    \"blockBasedInterlining\" : true,\n    \"maxInterlineDistance\" : 200\n  },\n  \"islandPruning\" : {\n    \"islandWithStopsMaxSize\" : 2,\n    \"islandWithoutStopsMaxSize\" : 10,\n    \"adaptivePruningFactor\" : 50.0,\n    \"adaptivePruningDistance\" : 250\n  },\n  \"transitFeeds\" : [\n    {\n      \"type\" : \"gtfs\",\n      \"feedId\" : \"SE\",\n      \"source\" : \"https://skanetrafiken.se/download/sweden.gtfs.zip\"\n    },\n    {\n      \"type\" : \"netex\",\n      \"feedId\" : \"NO\",\n      \"source\" : \"gs://BUCKET/OTP_GCS_WORK_DIR/norway-netex.obj\",\n      \"sharedFilePattern\" : \"_stops.xml\",\n      \"sharedGroupFilePattern\" : \"_(\\\\w{3})_shared_data.xml\",\n      \"groupFilePattern\" : \"(\\\\w{3})_.*\\\\.xml\",\n      \"ignoreFilePattern\" : \"(temp|tmp)\"\n    }\n  ],\n  \"transferRequests\" : [\n    {\n      \"modes\" : \"WALK\"\n    },\n    {\n      \"modes\" : \"WALK\",\n      \"wheelchairAccessibility\" : {\n        \"enabled\" : true\n      }\n    }\n  ],\n  \"stopConsolidationFile\" : \"consolidated-stops.csv\",\n  \"emissions\" : {\n    \"carAvgCo2PerKm\" : 170,\n    \"carAvgOccupancy\" : 1.3\n  }\n}\n
    "},{"location":"Changelog/","title":"Changelog","text":"

    The changelog lists most feature changes between each release. The list is automatically created based on merged pull requests. Search GitHub issues and pull requests for smaller issues.

    "},{"location":"Changelog/#270-snapshot-under-development","title":"2.7.0-SNAPSHOT (under development)","text":""},{"location":"Changelog/#260-2024-09-18","title":"2.6.0 (2024-09-18)","text":""},{"location":"Changelog/#notable-changes","title":"Notable Changes","text":""},{"location":"Changelog/#detailed-changes-by-pull-request","title":"Detailed changes by Pull Request","text":""},{"location":"Changelog/#250-2024-03-13","title":"2.5.0 (2024-03-13)","text":""},{"location":"Changelog/#notable-changes_1","title":"Notable Changes","text":""},{"location":"Changelog/#detailed-changes-by-pull-request_1","title":"Detailed changes by Pull Request","text":""},{"location":"Changelog/#240-2023-09-13","title":"2.4.0 (2023-09-13)","text":""},{"location":"Changelog/#notable-changes_2","title":"Notable Changes","text":""},{"location":"Changelog/#detailed-changes-by-pull-request_2","title":"Detailed changes by Pull Request","text":""},{"location":"Changelog/#230-2023-04-24","title":"2.3.0 (2023-04-24)","text":""},{"location":"Changelog/#notable-changes_3","title":"Notable Changes","text":""},{"location":"Changelog/#detailed-changes-by-pull-request_3","title":"Detailed changes by Pull Request","text":""},{"location":"Changelog/#220-2022-11-01","title":"2.2.0 (2022-11-01)","text":""},{"location":"Changelog/#notable-changes_4","title":"Notable Changes","text":""},{"location":"Changelog/#detailed-changes-by-pull-request_4","title":"Detailed changes by Pull Request","text":""},{"location":"Changelog/#210-2022-03-17","title":"2.1.0 (2022-03-17)","text":""},{"location":"Changelog/#notable-changes_5","title":"Notable Changes","text":""},{"location":"Changelog/#detailed-changes-by-pull-request_5","title":"Detailed changes by Pull Request","text":""},{"location":"Changelog/#200-2020-11-27","title":"2.0.0 (2020-11-27)","text":""},{"location":"Changelog/#ported-over-from-14-and-15","title":"Ported over from 1.4 and 1.5","text":""},{"location":"Changelog/#13-2018-08-03","title":"1.3 (2018-08-03)","text":""},{"location":"Changelog/#12-2017-09-18","title":"1.2 (2017-09-18)","text":""},{"location":"Changelog/#11-2017-03-16","title":"1.1 (2017-03-16)","text":""},{"location":"Changelog/#10-2016-09-09","title":"1.0 (2016-09-09)","text":""},{"location":"Changelog/#020-2016-06-10","title":"0.20 (2016-06-10)","text":""},{"location":"Changelog/#0190-2016-05-25","title":"0.19.0 (2016-05-25)","text":""},{"location":"Changelog/#0180-2015-05-29","title":"0.18.0 (2015-05-29)","text":""},{"location":"Changelog/#0170-2015-05-14","title":"0.17.0 (2015-05-14)","text":""},{"location":"Changelog/#0160-2015-05-07","title":"0.16.0 (2015-05-07)","text":""},{"location":"Changelog/#0150-2015-04-14","title":"0.15.0 (2015-04-14)","text":""},{"location":"Changelog/#0140-2015-03-28","title":"0.14.0 (2015-03-28)","text":""},{"location":"Changelog/#0130-2014-12-05","title":"0.13.0 (2014-12-05)","text":""},{"location":"Changelog/#0121-2014-11-17","title":"0.12.1 (2014-11-17)","text":""},{"location":"Changelog/#0120-2014-11-11","title":"0.12.0 (2014-11-11)","text":""},{"location":"Changelog/#0110-2014-03-24","title":"0.11.0 (2014-03-24)","text":""},{"location":"Changelog/#0100-2014-03-18","title":"0.10.0 (2014-03-18)","text":"

    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.

    "},{"location":"Changelog/#070-2012-04-29","title":"0.7.0 (2012-04-29)","text":""},{"location":"Changelog/#060-2012-04-25","title":"0.6.0 (2012-04-25)","text":""},{"location":"Changelog/#054-2012-04-06","title":"0.5.4 (2012-04-06)","text":""},{"location":"Changelog/#053-2012-03-23","title":"0.5.3 (2012-03-23)","text":""},{"location":"Changelog/#052-2012-03-20","title":"0.5.2 (2012-03-20)","text":""},{"location":"Changelog/#051-2012-03-16","title":"0.5.1 (2012-03-16)","text":""},{"location":"Changelog/#050-2012-03-09","title":"0.5.0 (2012-03-09)","text":""},{"location":"Changelog/#044-2012-02-06","title":"0.4.4 (2012-02-06)","text":"

    Release in anticipation of upcoming merges.

    "},{"location":"Configuration/","title":"Introduction","text":""},{"location":"Configuration/#configuring-opentripplanner","title":"Configuring OpenTripPlanner","text":""},{"location":"Configuration/#base-directory","title":"Base Directory","text":"

    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:

    otp-config.json\nbuild-config.json\nrouter-config.json\nnew-york-city-no-buildings.osm.pbf\nnyc-elevation.tiff\nlong-island-rail-road.gtfs.zip\nmta-new-york-city-transit.gtfs.zip\nport-authority-of-new-york-new-jersey.gtfs.zip\ngraph.obj\n

    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 for further details.

    "},{"location":"Configuration/#three-scopes-of-configuration","title":"Three Scopes of Configuration","text":"

    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.

    "},{"location":"Configuration/#configuration-types","title":"Configuration types","text":"

    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 boolean This is the Boolean JSON type true, false string This is the String JSON type. \"This is a string!\" double A decimal floating point number. 64 bit. 3.15 integer A decimal integer number. 32 bit. 1, -7, 2100 long A decimal integer number. 64 bit. -1234567890 enum A fixed set of string literals. \"RAIL\", \"BUS\" enum-map List of key/value pairs, where the key is a enum and the value can be any given type. { \"RAIL: 1.2, \"BUS\": 2.3 } enum-set List of enum string values [ \"RAIL\", \"TRAM\" ] locale Language[\\_country[\\_variant]]. A Locale object represents a specific geographical, political, or cultural region. For more information see the Java Locale. \"en_US\", \"nn_NO\" date Local date. The format is YYYY-MM-DD (ISO-8601). \"2020-09-21\" date-or-period A local date, or a period relative to today. The local date has the format YYYY-MM-DD and the period has the format PnYnMnD or -PnYnMnD where n is a integer number. \"P1Y\", \"-P3M2D\", \"P1D\" duration A duration is a amount of time. The format is PnDTnHnMnS or nDnHnMnS where n is a integer number. The D(days), H(hours), M(minutes) and S(seconds) are not case sensitive. \"3h\", \"2m\", \"1d5h2m3s\", \"-P2dT-1s\" regexp A regular expression pattern used to match a sting. \"$^\", \"gtfs\", \"\\w{3})-.*\\.xml\" uri An URI path to a resource like a file or a URL. Relative URIs are resolved relative to the OTP base path. \"http://foo.bar/\", \"file:///Users/jon/local/file\", \"graph.obj\" time-zone Time-Zone ID \"UTC\", \"Europe/Paris\", \"-05:00\" feed-scoped-id FeedScopedId \"NO:1001\", \"1:101\" cost-linear-function A cost-linear-function used to calculate a cost from another cost or time/duration. Given a function of time: f(t) = a + b * t then a is the constant time part, b is the time-coefficient, and t is the variable. If a=0s and b=0.0, then the cost is always 0(zero). Examples: 0s + 2.5t, 10m + 0t and 1h5m59s + 9.9t The constant must be 0 or a positive number or duration. The unit is seconds unless specified using the duration format. A duration is automatically converted to a cost. The coefficient must be in range: [0.0, 100.0] time-penalty A time-penalty is used to add a penalty to the duration/arrival-time/departure-time for a path. It will be invisible to the end user, but used during the routing when comparing stop-arrival/paths. Given a function of time: f(t) = a + b * t then a is the constant time part, b is the time-coefficient, and t is the variable. If a=0s and b=0.0, then the cost is always 0(zero). Examples: 0s + 2.5t, 10m + 0 x and 1h5m59s + 9.9t The constant must be 0 or a positive number(seconds) or a duration. The coefficient must be in range: [0.0, 100.0] map List of key/value pairs, where the key is a string and the value can be any given type. { \"one\": 1.2, \"two\": 2.3 } object Config object containing nested elements \"walk\": { \"speed\": 1.3, \"reluctance\": 5 } array Config object containing an array/list of elements \"array\": [ 1, 2, 3 ]"},{"location":"Configuration/#system-environment-and-project-information-substitution","title":"System environment and project information substitution","text":"

    OTP supports 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 are 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.

    {\n    \"gsCredentials\": \"${GCS_SERVICE_CREDENTIALS}\",\n    \"graph\": \"file:///var/otp/graph-${otp.serialization.version.id}.obj\"\n}\n

    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:

    "},{"location":"Configuration/#config-version","title":"Config version","text":"

    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 pipeline 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-pipeline, at deployment time or use system environment variable substitution.

    "},{"location":"Configuration/#otp-serialization-version-id-and-graphobj-file-header","title":"OTP Serialization version id and Graph.obj file header","text":"

    OTP has a OTP Serialization Version Id maintained in the pom.xml_ file. OTP stores the id in the serialized Graph.obj file header, allowing OTP to check for compatibility issues when loading the graph. The header info is available to configuration substitution:

    The intended usage is to be able to have a graph build pipeline that \"knows\" the matching graph and OTP planner instance. For example, you may build new graphs for every OTP serialization version id in use by the planning OTP instances you have deployed and plan to deploy. This way you can roll forward and backward new OTP instances without worrying 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:

    The Maven pom.xml, the META-INF/MANIFEST.MF, the OTP command line(--serializationVersionId), log start-up messages and all OTP APIs can be used to get the OTP Serialization Version Id.

    "},{"location":"Configuration/#include-file-directive","title":"Include file directive","text":"

    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 text inserted is valid JSON (starts with { and ends with }).

    Variable substitution is performed on configuration file after the include file directive; Hence variable substitution is also performed on the text in the injected file.

    Here is an example including variable substitution, assuming version 2.6.0 of OTP:

    // build-config.json\n{\n  \"transitFeeds\" : \"${includeFile:transit.json}\"\n} \n
    // transit.json\n[\n  {\n  \"source\": \"netex-v${maven.version.short}.obj\"\n}\n]\n

    The result will look like this:

    {\n      \"transitFeeds\": [\n        {\n          \"source\": \"netex-v2.6.0.obj\"\n        }\n      ]\n} \n
    "},{"location":"Configuration/#system-wide-configuration","title":"System-wide Configuration","text":"

    Using the file otp-config.json you can enable or disable different APIs and experimental Sandbox Extensions. 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.

    "},{"location":"Configuration/#otp-features","title":"OTP Features","text":"

    Here is a list of all features which can be toggled on/off and their default values.

    Feature Description Enabled by default Sandbox APIBikeRental Enable the bike rental endpoint. \u2713\ufe0f APIServerInfo Enable the server info endpoint. \u2713\ufe0f APIUpdaterStatus Enable endpoint for graph updaters status. \u2713\ufe0f ConsiderPatternsForDirectTransfers Enable limiting transfers so that there is only a single transfer to each pattern. \u2713\ufe0f DebugUi Enable the debug GraphQL client and web UI and located at the root of the web server as well as the debug map tiles it uses. Be aware that the map tiles are not a stable API and can change without notice. Use the vector tiles feature if you want a stable map tiles API. \u2713\ufe0f ExtraTransferLegOnSameStop Should there be a transfer leg when transferring on the very same stop. Note that for in-seat/interlined transfers no transfer leg will be generated. FloatingBike Enable floating bike routing. \u2713\ufe0f GtfsGraphQlApi Enable the GTFS GraphQL API. \u2713\ufe0f GtfsGraphQlApiRentalStationFuzzyMatching Does vehicleRentalStation query also allow ids that are not feed scoped. MinimumTransferTimeIsDefinitive If the minimum transfer time is a lower bound (default) or the definitive time for the transfer. Set this to true if you want to set a transfer time lower than what OTP derives from OSM data. OptimizeTransfers OTP will inspect all itineraries found and optimize where (which stops) the transfer will happen. Waiting time, priority and guaranteed transfers are taken into account. \u2713\ufe0f ParallelRouting Enable performing parts of the trip planning in parallel. TransferConstraints Enforce transfers to happen according to the transfers.txt (GTFS) and Interchanges (NeTEx). Turning this off will increase the routing performance a little. \u2713\ufe0f TransmodelGraphQlApi Enable the Transmodel (NeTEx) GraphQL API. \u2713\ufe0f \u2713\ufe0f ActuatorAPI Endpoint for actuators (service health status). \u2713\ufe0f AsyncGraphQLFetchers Whether the @async annotation in the GraphQL schema should lead to the fetch being executed asynchronously. This allows batch or alias queries to run in parallel at the cost of consuming extra threads. Co2Emissions Enable the emissions sandbox module. \u2713\ufe0f DataOverlay Enable usage of data overlay when calculating costs for the street network. \u2713\ufe0f FaresV2 Enable import of GTFS-Fares v2 data. \u2713\ufe0f FlexRouting Enable FLEX routing. \u2713\ufe0f GoogleCloudStorage Enable Google Cloud Storage integration. \u2713\ufe0f LegacyRestApi Enable legacy REST API. This API will be removed in the future. \u2713\ufe0f MultiCriteriaGroupMaxFilter Keep the best itinerary with respect to each criteria used in the transit-routing search. For example the itinerary with the lowest cost, fewest transfers, and each unique transit-group (transit-group-priority) is kept, even if the max-limit is exceeded. This is turned off by default for now, until this feature is well tested. RealtimeResolver When routing with ignoreRealtimeUpdates=true, add an extra step which populates results with real-time data \u2713\ufe0f ReportApi Enable the report API. \u2713\ufe0f RestAPIPassInDefaultConfigAsJson Enable a default RouteRequest to be passed in as JSON on the REST API - FOR DEBUGGING ONLY! SandboxAPIGeocoder Enable the Geocoder API. \u2713\ufe0f SandboxAPIMapboxVectorTilesApi Enable Mapbox vector tiles API. \u2713\ufe0f SandboxAPIParkAndRideApi Enable park-and-ride endpoint. \u2713\ufe0f Sorlandsbanen Include train S\u00f8rlandsbanen in results when searching in south of Norway. Only relevant in Norway. \u2713\ufe0f TransferAnalyzer Analyze transfers during graph build. \u2713\ufe0f

    Example

    // otp-config.json\n{\n    \"otpFeatures\" : {\n        \"APIBikeRental\" : false,\n        \"ActuatorAPI\" : true\n    }\n}\n
    "},{"location":"Configuration/#jvm-configuration","title":"JVM configuration","text":"

    This section contains general recommendations for tuning the JVM in a production environment. It focuses mainly on garbage collection configuration and memory settings. See Garbage Collector Tuning for general information on garbage collection. See Large Pages in Java and Transparent Huge Pages for general information on large memory pages.

    "},{"location":"Configuration/#otp-server","title":"OTP server","text":"

    The OTP server processes concurrent routing requests in real time. The main optimization goal for the OTP server is minimizing response time.

    "},{"location":"Configuration/#garbage-collector","title":"Garbage collector","text":""},{"location":"Configuration/#memory-settings","title":"Memory settings","text":""},{"location":"Configuration/#graph-builder","title":"Graph Builder","text":"

    The Graph Builder is the non-interactive mode used to build street graphs and transit graphs. The main optimization goal for the Graph Builder is minimizing total build time.

    "},{"location":"Configuration/#garbage-collector_1","title":"Garbage collector","text":""},{"location":"Configuration/#memory-settings_1","title":"Memory settings","text":""},{"location":"Container-Image/","title":"Container image","text":"

    The CI pipeline deploys container images for runtimes like Docker, Kubernetes or Podman to Dockerhub.

    The image assumes you use a volume to mount the input data (GTFS/NeTex, OSM) and config files into /var/opentripplanner/. When serving a graph it's also expected to be in this directory. If a logback extensions file needs to be used, it should be mounted to the root location /logback-include-extensions.xml instead of the /var/opentripplanner/ directory.

    "},{"location":"Container-Image/#quick-start","title":"Quick start","text":"

    Let's use the image to build a graph in Berlin.

    # create directory for data and config\nmkdir berlin\n# download OSM\ncurl -L https://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf -o berlin/osm.pbf  \n# download GTFS\ncurl -L https://vbb.de/vbbgtfs -o berlin/vbb-gtfs.zip\n# build graph and save it onto the host system via the volume\ndocker run --rm \\\n    -e JAVA_TOOL_OPTIONS='-Xmx8g' \\\n    -v \"$(pwd)/berlin:/var/opentripplanner\" \\\n    docker.io/opentripplanner/opentripplanner:latest --build --save\n# load and serve graph\ndocker run -it --rm -p 8080:8080 \\\n    -e JAVA_TOOL_OPTIONS='-Xmx8g' \\\n    -v \"$(pwd)/berlin:/var/opentripplanner\" \\\n    docker.io/opentripplanner/opentripplanner:latest --load --serve\n

    Now open http://localhost:8080 to see your running OTP instance.

    "},{"location":"Container-Image/#additional-notes","title":"Additional notes","text":"

    Make sure to include the word \"gtfs\" when naming the gtfs files that you want to use for OTP. Otherwise, graph build will fail.

    If you want to set JVM options you can use the environment variable JAVA_TOOL_OPTIONS, so a full example to add to your docker command is -e JAVA_TOOL_OPTIONS='-Xmx4g'.

    "},{"location":"Data-Sources/","title":"Data Sources","text":""},{"location":"Data-Sources/#input-formats","title":"Input Formats","text":"

    At the core of OpenTripPlanner is a library of Java code that finds efficient paths through multi-modal transportation networks built from OpenStreetMap, GTFS/GTFS RT and GBFS.

    In addition to GTFS, OTP 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 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.

    "},{"location":"Deployments/","title":"OpenTripPlanner Deployments Worldwide","text":""},{"location":"Deployments/#official-production","title":"Official Production","text":"

    The following are known deployments of OTP in a government- or agency-sponsored production capacity:

    "},{"location":"Deployments/#independent-production","title":"Independent Production","text":"

    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.

    "},{"location":"Developers-Guide/","title":"Developers Guide","text":""},{"location":"Developers-Guide/#quick-setup","title":"Quick setup","text":"

    A Quick guide to setting up the OpenTripPlanner project.

    You need Git, Maven and Java(JDK) and an IDE installed on your computer. Your 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
    3. Run mvn package- this will download all dependencies, build the project and run tests.
    4. Open the project in your IDE.
    "},{"location":"Developers-Guide/#working-on-otp-in-an-ide","title":"Working on OTP in an IDE","text":"

    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, Eclipse, and NetBeans. 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 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.

    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 and configuration reference). 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\".

    "},{"location":"Developers-Guide/#contributing-to-the-project","title":"Contributing to the project","text":"

    OpenTripPlanner is a community based open source project, and we welcome all who wish to contribute. There are several ways to get involved:

    "},{"location":"Developers-Guide/#branches-and-branch-protection","title":"Branches and Branch Protection","text":"

    As of August 2022, we work on OTP 2.x and are using a Git branching model derived from Gitflow. All development will occur on the dev-2.x branch. 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-2.x branch. In turn, all changes to dev-2.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 developers part of the OTP Review Team. These developers act on behalf of the leadership committee members. The reviewers should be 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-1.x exist for patching OTP version 1.x, but with few people to do the reviews, very few PRs are accepted. We recommend getting in touch with the community before you spend time on making a PR.

    "},{"location":"Developers-Guide/#issues","title":"Issues","text":"

    If no ticket exists for the feature or bug your code implements or fixes, you should create a new ticket 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). The created issue should be referenced in a pull request. For really minor and uncontroversial pull requests, it is ok to not create an issue.

    "},{"location":"Developers-Guide/#unit-tests-using-real-osm-data","title":"Unit tests using real OSM data","text":"

    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

    "},{"location":"Developers-Guide/#itinerary-and-api-snapshot-tests","title":"Itinerary and API Snapshot Tests","text":"

    To test the itinerary generation, and the API there are snapshot test which save the result of the requests as *.snap JSON-like files. These are stored in git so that it is possible to compare to the expected result when running the tests.

    If the snapshots need to be recreated than running mvn clean -Pclean-test-snapshots will remove the existing *.snap files so that the next time the tests are run the snapshots will be recreated. The updated files may be committed after checking that the changes in the files are expected.

    "},{"location":"Developers-Guide/#documentation","title":"Documentation","text":"

    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 /doc/user directory under the root of the project. On every push to the dev-2.x branch the documentation will be rebuilt and deployed as static pages to our subdomain of Github Pages. 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 writing it.

    In short:

    $ pip install -r doc/user/requirements.txt\n$ mkdocs serve\n

    The OTP GTFS GraphQL API documentation is available online at

    https://docs.opentripplanner.org/api/dev-2.x/graphql-gtfs/

    You can also use the interactive GraphQL API client that is built into every instance at

    http://localhost:8080/graphiql

    "},{"location":"Developers-Guide/#debug-layers","title":"Debug layers","text":"

    Adding new renderer is very easy. You just need to create new class (preferably in org.opentripplanner.inspector package) which implements EdgeVertexRenderer. It is best if class name ends with Rendered. To implement this interface you need to write three functions renderEdge, renderVertex and getName. Both render functions accepts EdgeVisualAttributes object in which label of edge/vertex and color can be set. And both return true if edge/vertex should be rendered 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.

    After your class is written you only need to add it to TileRenderManager:

    //This is how Wheelchair renderer is added\nrenderers.put(\"wheelchair\", new EdgeVertexTileRenderer(new WheelchairEdgeRenderer()));\n

    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:

    //This lines\nCacheControl cc = new CacheControl();\ncc.setMaxAge(3600);\ncc.setNoCache(false);\n\n//to this:\nCacheControl cc = new CacheControl();\ncc.setNoCache(true);\n
    "},{"location":"Developers-Guide/#date-format","title":"Date format","text":"

    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.

    "},{"location":"Developers-Guide/#code-conventions-and-architecture","title":"Code conventions and architecture","text":"

    The development and architecture documentation are only available on GitHub, not in the user project documentation (https://www.opentripplanner.org/). These documents contain relative links to code, so they are a bit easier to maintain that way. The primary audience is also active OTP developers that have the code checked out locally.

    "},{"location":"Developers-Guide/#continuous-integration","title":"Continuous Integration","text":"

    The OpenTripPlanner project uses the Github actions continuous integration system . Any time a change is pushed to the main OpenTripPlanner repository on GitHub or to an open pull request, Github actions will compile and test the new code, providing feedback on the stability of the build.

    "},{"location":"Developers-Guide/#changelog-workflow","title":"Changelog workflow","text":"

    The changelog file is generated from the pull-request(PR) title using the changelog workflow . 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 the label skip changelog to the PR.

    "},{"location":"Developers-Guide/#how-to-update-the-changelog_token","title":"How-to update the CHANGELOG_TOKEN","text":"

    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):

    "},{"location":"Developers-Guide/#release-process","title":"Release Process","text":"

    New releases can be found on GitHub. 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 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 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 these steps manually by following the checklist. We aim to make a release every 6 months.

    Use the Release Checklist to perform the release.

    "},{"location":"Frontends/","title":"Frontends (User Interfaces) for OpenTripPlanner","text":""},{"location":"Frontends/#introduction","title":"Introduction","text":"

    OpenTripPlanner is a client-server system. A backend service written in Java is accessed over an API by some client software, which is generally embedded in a web page or a mobile app. When OpenTripPlanner developers refer to OpenTripPlanner or OTP, they often specifically mean the Java backend service. But for this service to be useful to end users who want to plan their journeys, you will typically also want to deploy a user interface as well as a few other components providing mapping capabilities and address lookup functionality.

    For the purposes of this document and in many OpenTripPlanner development discussions, the terms frontend, UI, and client will be used interchangeably. In reality many kinds of clients are possible, not all of them being user interfaces (UIs). The OpenTripPlanner API may be called by various scripts and microservices, potentially all within what would traditionally be called a \"backend\" with no user interface at all. For example, updates to trip plans could be requested, summarized and sent as text messages over a mobile network. But in this documentation page, we are exclusively talking about graphical user interfaces, usually written in Javascript for execution and display in web browsers.

    "},{"location":"Frontends/#two-kinds-of-frontends","title":"Two Kinds of Frontends","text":"

    Broadly speaking there are two kinds of frontends for OTP: debug frontends and production frontends.

    Debug frontends are included in the main OpenTripPlanner repository, and are intended to work \"out of the box\" with little to no configuration. They are served by OTP itself or a simple local web server, or set up such that a single deployment is usable by anyone via a content delivery network (CDN). The primary purpose of debug frontends is to allow OTP developers (as well as people evaluating OpenTripPlanner for their organization) to observe, test, and debug an OTP instance they're working on. Debug frontends will expose some internal details of OTP operation such as graph nodes and edges, traversal permissions, or transit data entity identifiers. Their primary role is as a development and deployment tool.

    On the other hand, production frontends are intended to be a component of larger public-facing deployments of OTP, with a more polished appearance and user experience. They generally do not work \"out of the box\", and require a significant amount of configuration and coordination with external components such as map tile servers and geocoders. They are designed to be components of a large professionally maintained and managed OTP deployment, and present a simpler view of OpenTripPlanner options and results to a non-technical audience of end users.

    "},{"location":"Frontends/#debug-frontends","title":"Debug Frontends","text":"

    The main OpenTripPlanner repository currently contains two debug web frontends:

    The new debug client is a React/TypeScript Single Page App (SPA) that can be served locally or accessed over a content delivery network (CDN). Unlike the original debug client, it connects to the OTP Java backend via the GraphQL API using the Transmodel vocabulary. By default, it is available at the root URL (http://localhost:8080/ in local operation).

    The classic debug client is a jQuery and Backbone based UI whose history can be traced back over a decade to the first days of the OTP project. It connects to the OTP Java backend via a REST API using the GTFS vocabulary. Historically this was the default OTP interface available at the root URL. It is still available, but has been moved to http://localhost:8080/classic-debug/ .

    There is a third piece of software that might qualify as an OTP client: a Java Swing application making use of the Processing visualization library, located in the GraphVisualizer class. While it would not be accurate to call this a \"native\" desktop application (as it's cross-platform Java) it is not a web app. This very developer-centric UI is also over a decade old and has been very sparsely maintained, but continues to exist because it can visualize the progress of searches through the street network, providing some insight into the internals of the routing algorithms that are not otherwise visible.

    "},{"location":"Frontends/#working-with-debug-frontends","title":"Working with Debug Frontends","text":"

    While the two debug frontends are enabled by default as of this writing, they may not be in the future, and you may wish to disable them if you've chosen to use a different frontend. Also, to get full use of the existing debug frontends you may want to enable OTP's built-in simple testing geocoder which performs fuzzy searches for transit stops by name, supplying their coordinates to the routing engine. Without it, you will be limited to origins and destinations selected on a map or specified in terms of latitude and longitude coordinates. The debug frontend and the geocoder can be toggled in otp-config.json:

    // otp-config.json\n{\n  \"otpFeatures\": {\n    \"DebugUi\": true,\n    \"SandboxAPIGeocoder\": true\n  }\n}\n
    "},{"location":"Frontends/#production-frontends","title":"Production Frontends","text":"

    Many different production OTP frontends exist. Any number of agencies and consultancies may have built new frontends, whether in Javascript or as native mobile apps, without the OpenTripPlanner development team even being aware of them.

    That said, there are two main Javascript-based web user interfaces that are generally recommended by members of the OTP development team who also work on professional, public-facing OpenTripPlanner deployments:

    Digitransit is an open-source public transportation project, originally created in Finland to replace existing nationwide and regional journey planning solutions in 2014. Digitransit has since been used around the world in other projects, for example in Germany. It is a joint project of Helsinki Regional Transport Authority (HSL), Fintraffic, and Waltti Solutions.

    Arcadis IBI has for several years actively developed, deployed, and maintained instances of the React-based OTP UI, systematically contributing their improvements back to the original repositories under the OpenTripPlanner organization:

    Both major frontend projects mentioned above support internationalization and have several translations already available.

    "},{"location":"Frontends/#deploying-a-production-frontend","title":"Deploying a Production Frontend","text":"

    Deploying a full OpenTripPlanner-based system including a web UI can be quite complex, as there are many \"moving parts\". Such a system needs to remain responsive and function smoothly under load that varies wildly from one time of day to another, constantly refresh input data, and meet customer expectations in recognizing addresses and names of landmarks etc. Because deployment and management of such a system demands long term commitment by a professional team with sufficient experience and knowledge about the component parts, the major production frontend projects do not really aim to work \"out of the box\". There's a working assumption that they'll be actively customized for any large regional deployment.

    Unfortunately this creates a bit of a barrier for organizations evaluating such components. Please don't hesitate to join the OpenTripPlanner Gitter chat and ask if you need any information on this subject. Several organizations that manage multiple large OTP deployments are active there and will be happy to engage with you.

    While you are welcome to stand up an instance of one of these UIs for testing or evaluation, and there has been some effort to make this more straightforward especially on the Arcadis IBI projects, it is still strongly recommended to collaborate with a specialist. The process of tailoring a deployment to a specific region and deployment environment is estimated to take at least several full days even for an experienced professional, and while it may start off looking deceptively simple, can rapidly grow into a seemingly never-ending project for those who are not aware of the pitfalls. The goal here is not by any means to discourage you from using or learning about any of these projects, but to set expectations that the process will be much smoother if you work with someone who's done it before. Be aware that both of these systems rely on multiple additional backend services other than the OTP Java backend. To get either one working, you will need to configure a source of map tiles and a geocoder that translates geographic names to latitude and longitude coordinates, among other components.

    That said, as of this writing (early 2024) it may now be possible to get a minimal, non-production test deployment of OTP-React-Redux working with only a few adjustments to the example configuration file. See the README and example-config.yml in the OTP-RR repo.

    "},{"location":"Frontends/#historical-background","title":"Historical Background","text":"

    The history of the more widely used OpenTripPlanner interfaces is roughly as follows:

    "},{"location":"Getting-OTP/","title":"Getting OpenTripPlanner","text":""},{"location":"Getting-OTP/#pre-built-jars","title":"Pre-built JARs","text":"

    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 or the OTP directory at Maven Central, 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.6.0-SNAPSHOT refer to development builds _ before_ the release version v2.6.0. The existence of a build vX.Y.Z-SNAPSHOT does not mean that vX.Y.Z has been released yet.

    We use the Github Actions CI system to build OTP every time a change is made. You can find the JARs resulting from those builds in the Github Packages repository . 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.

    "},{"location":"Getting-OTP/#building-from-source","title":"Building from Source","text":"

    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 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:

    mkdir git\ncd git\ngit clone git@github.com:opentripplanner/OpenTripPlanner.git\n

    Then change to the newly cloned OpenTripPlanner repository directory and start a build:

    cd OpenTripPlanner\nmvn clean package\n

    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] ------------------------------------------------------------------------\n[INFO] BUILD SUCCESS\n[INFO] ------------------------------------------------------------------------\n[INFO] Total time: 42.164s\n[INFO] Finished at: Tue Feb 18 19:35:48 CET 2014\n[INFO] Final Memory: 88M/695M\n[INFO] ------------------------------------------------------------------------\n

    This build process should produce a JAR file called otp-x.y.z-shaded.jar in the application/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:

    cd OpenTripPlanner\ngit checkout v2.6.0\ngit clean -df\nmvn clean package -DskipTests\n

    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.

    "},{"location":"Getting-OTP/#maven-repository","title":"Maven Repository","text":"

    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.6.0 will be found at https://repo1.maven.org/maven2/org/opentripplanner/otp/2.6.0/otp-2.6.0-shaded.jar.

    To make use of OTP in another Maven project, you must specify it as a dependency in that project's pom.xml:

    <dependency>\n  <groupId>org.opentripplanner</groupId>\n  <artifactId>otp</artifactId>\n  <version>2.6.0</version>\n</dependency>\n
    "},{"location":"Governance/","title":"Project Governance","text":"

    OpenTripPlanner is a member project of the Software Freedom Conservancy. 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 Sean Barbeau University of South Florida Sheldon Brown Cambridge Systematics Andrew Byrd Conveyal Thomas Craig CALACT ITS4US Drew Dara-Abrams Interline David Emory IBI Group Thomas Gran Entur (Norway) Tuukka Hastrup Transpordiamet (Estonia) Joel Lappalainan Digitransit (Finland) Frank Purcell TriMet (Portland, Oregon) David Turner ex-OpenPlans Anders Varmy Skanetrafiken Leonard Ehrenfried Independent contractor

    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 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

    "},{"location":"History/","title":"OpenTripPlanner Project History","text":""},{"location":"History/#opentripplanner-1","title":"OpenTripPlanner 1","text":"

    OpenTripPlanner was seeded by Portland, Oregon's transit agency TriMet with a Regional Travel Options grant and opened with a 3-day 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, and Brandon Martin-Anderson of Graphserver. From 2009 through 2012, development was coordinated by New York nonprofit OpenPlans. In 2011 a second workshop was held to mark the end of the first phase of development. TriMet's 2009-2011 OTP Final Report 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 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. 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.

    In summer of 2013, the OpenTripPlanner project was accepted for membership in the Software Freedom Conservancy (SFC). 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 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), 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.

    "},{"location":"History/#opentripplanner-2","title":"OpenTripPlanner 2","text":"

    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 . 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. 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 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 and the October 2019 OTP webinar 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.

    "},{"location":"In-Station-Navigation/","title":"In-station navigation","text":"

    OTP offers a variety of ways to produce precise walking instructions for walking inside a station or between transit stops.

    "},{"location":"In-Station-Navigation/#osm-generated-navigation","title":"OSM generated navigation","text":"

    In the most common case, the walking instructions for reaching a transit stop are generated from the available OSM data. For this reason it is important that the coordinate of the stop is as close as possible to where the passenger is expected to wait for the vehicle, not where the vehicle will stop.

    It is therefore a good idea to place the stop coordinates at a bus shelter or railway platform rather than at the middle of the road or the railway tracks.

    Of course you also want the data in OSM as precise as possible: data for railway platforms, stairs, tunnels and other infrastructure help OTP to generate good walking instructions.

    "},{"location":"In-Station-Navigation/#example-exiting-a-railway-platform","title":"Example: exiting a railway platform","text":"

    The train arrives in a railway station in Stuttgart (green line), the passenger alights and is instructed (grey line) to walk along the platform, up the stairs and across a bridge to continue to their final destination.

    "},{"location":"In-Station-Navigation/#boarding-locations","title":"Boarding locations","text":"

    If your stop coordinates are not very well-placed, OTP may direct passengers to the wrong waiting location or offer incorrect transfer paths and time. As this a common problem and stop coordinates can be hard to change due to upstream systems, OTP offers a way to derive the waiting coordinates from OSM data.

    Even if your stop coordinates are good, some stations are underground and to get correct walking instructions it's required to use this feature so that correct instructions for using entrances and stairs are generated.

    "},{"location":"In-Station-Navigation/#example-walking-downstairs-to-underground-stations","title":"Example: walking downstairs to underground stations","text":"

    This shows an underground subway station in Stuttgart which can only be reached by using entrances at either end walking down to the platform via a series of stairs and walkways. OTP can only generate these detailed instructions because the platform has a tag ref:IFOPT which identifies it in the German national stop register.

    "},{"location":"In-Station-Navigation/#gtfs-pathways","title":"GTFS pathways","text":"

    If your GTFS input file contains pathways this will override the OSM-generated instructions. It is therefore important that the pathways contain as much precision as possible.

    One advantage that pathways offer is the possibility to add information like \"follow signs for X\" which OTP adds to the textual turn-by-turn instructions.

    "},{"location":"In-Station-Navigation/#example-transferring-at-sudkreuz","title":"Example: Transferring at S\u00fcdkreuz","text":"

    Here the pathways don't offer a lot of precision: In a railway hub in Berlin there are suboptimal instructions on how to move from one platform to another because the pathways only contain rudimentary information about how to move inside the station. (The red lines represent train lines with the grey line showing the walking path.)

    "},{"location":"In-Station-Navigation/#transfers","title":"Transfers","text":"

    The above precedence rules of

    also apply when computing transfers from one stop to another.

    "},{"location":"In-Station-Navigation/#example-transferring-from-tram-to-rail-at-oslo-central","title":"Example: transferring from tram to rail at Oslo Central","text":"

    Here the passenger arrives in a local tram (blue line) near the main station in Oslo. They are instructed (grey line) to walk into the station right onto the correct platform and leave on a long-distance train (red line).

    "},{"location":"In-Station-Navigation/#example-transferring-between-platforms-at-oslo-central","title":"Example: transferring between platforms at Oslo Central","text":"

    This example instructs the passenger to get off a train, then walking down the stairs and via a tunnel to another platform.

    "},{"location":"In-Station-Navigation/#transfer-time","title":"Transfer time","text":"

    The routing engine calculates the time to move from one stop to another by how long it thinks the walking takes based on the navigation instructions outlined above. So, if OTP thinks that it takes 5 minutes to walk from platform 1 to platform 8, then the routing algorithm will not suggest a transit connection that departs less than 5 minutes after arriving at platform 1.

    However, how fast the passenger is assumed to walk is controllable through the walk speed parameter. This can be configured per installation or passed as an API call parameter.

    The parameters alightSlack, transferSlack and boardSlack also allow you to define extra buffer time for transferring.

    GTFS minimum transfer times are also supported but generally not advised. It is preferable to micromap your stations and improve the stop coordinates rather than force specific transfer times by adding this data.

    "},{"location":"In-Station-Navigation/#common-data-errors","title":"Common data errors","text":""},{"location":"IslandPruning/","title":"Street graph pruning","text":"

    A street graph created from OpenStreetMap data has sections which cannot be reached with some or all traverse modes. For example, true geographic islands are usually disconnected from the main graph. The street network of such islands should be kept so that routing within the island or continuing from a ferry stop on it works as expected. Even a tiny street network connected to a ferry stop improves routing to an island a lot, because coordinate based itinerary searches find something to project onto.

    Removing a small subgraph from an island causes poor routing. A ferry stop on the island links directly to mainland.

    Disconnected parts can also represent a strictly forbidden area, such as connections within an industrial unit, roads of a military base or another region which cannot and should not be accessed when using door to door routing of a public transit journey planner. Existence of such graph sections is harmful, because start and end points of an itinerary search request may accidentally get projected to such a private pathway. As a result, a user does not receive any itineraries and gets no explanation for the routing problem.

    In most cases, connectivity problems are caused by incorrect modeling of OSM data. The number of such errors is usually very large, and the problem cannot be solved by simply fixing OSM data as soon as errors are detected - the OSM street network in Finland contains over 10 000 detected walk connectivity issues! An algorithmic solution is needed to address a problem of such magnitude.

    A typical error: bus platforms are not connected to the street network at all

    A simple and efficient solution is to detect harmful disconnected parts and remove them from the street graph. Routing then uses the properly connected part of the graph and finds itineraries. As a side effect, the start point of an itinerary search which departs from the removed graph projects at the border of it, which usually is good enough. Transfers may include strange teleportation and unexpected walking, as public transit stops may link to somewhat remote streets, but at least transfers will work.

    A disconnected railway platform breaks routing. Traveler is guided to take a round trip around the country although there is one hour direct train connection.

    "},{"location":"IslandPruning/#access-restriction-islands","title":"Access restriction islands","text":"

    One common reason for OSM connectivity problems is access tagging. It is perfectly OK to tag a front yard of a private residence using access=private or access=destination tags, so that strangers are not guided to travel through the private area. Routing will still use the private streets if a trip starts or ends there - only pass through traversal gets prohibited. However, sometimes OSM contributors try to block the traffic by tagging only entrance segments of streets leading to a restricted area. Unfortunately this totally prevents access to the interior part of the network, because OTP interprets it as pass through traffic. Pruning handles such problems by converting streets behind an access restriction to have the same access properties.

    Some regular (gray colored) streets are blocked behind access restricted (red colored) connections. Walk routing to them fails because it would be considered as pass through traffic. The image on the right shows that pruning added walk nothrough restriction to those streets, and routing works again.

    "},{"location":"IslandPruning/#pruning-algorithm","title":"Pruning algorithm","text":"

    Pruning analyses the three traverse modes - walk, bike and car - separately. For example, a resting area by a motorway may include some walking paths, but the only way to get there is to use a car. Therefore, it represents a disconnected 'island' when considering the walk mode. Pruning does not erase disconnected graph geometry as long as it can be reached using any of the traverse modes. Instead, pruning removes traversal permission for each disconnected mode from the island.

    Pruning uses four parameters and some heuristics to decide if a disconnected sub graph is a real island to be retained, or a harmful data error:

    Pruning thresholds are increased adaptively so that if the distance between an examined sub graph and the other graph is zero, the threshold is multiplied by a full adaptivePruningFactor value. The idea is that if a sub graph is closely entangled with another graph, it is likely to be a harmful modeling error, not a remote place like a true geographic island. If the distance is more than adaptivePruningDistance, the actual nominal threshold values will be used. So, adaptiveness prunes much larger disconnected graphs in places where they have potential to cause routing errors.

    Adaptive pruning can be disabled by setting adaptivePruningFactor to 1. Constant pruning thresholds will then be applied.

    Pruning also examines the transport modes of graph islands with stops. If land transportation modes are not found (only ferry or no modes at all), the graph is retained. Unknown mode is accepted for island status, because ferry lines often operate only during warm seasons.

    "},{"location":"IslandPruning/#some-examples","title":"Some examples","text":"

    A disconnected small graph should be preserved, if it is located on a real island.

    A street section has tags which prevent traversal on it, and OTP has removed it from the graph. Some isolated streets remain left, and a public transit stop gets linked to them. Routing cannot use the stop unless traveler is leaving from or going to the small isolated sub graph. Isolated streets cannot be reached by walking either. After pruning, the stop is projected to the main graph. Transfers at the stop work fine. Itineraries can guide traveler quite close to the removed streets.

    The platform structure of a bus station is disconnected from the other graph. Most bus traffic of a medium size city becomes unusable. Despite of the complexity of the sub graph (54 edges and 21 stops), it must be removed in pruning, so that stops get linked to reachable and well connected streets.

    "},{"location":"IslandPruning/#issue-reports","title":"Issue reports","text":"

    Pruning creates a GraphIsland issue every time it prunes a sub graph. Issues may show up as duplicates, because pruning is run for each traverse mode.

    A PrunedStopIsland issue is added for every pruned graph island which has stops linked to it. Such islands are particularly harmful, because they are places where public transit transfers take place and hence are frequently used. Pruned stop island issues should be studied frequently and underlying OSM errors fixed, especially if the island has many stops and edges (i.e it is most likely a public transit station, see station island example above).

    "},{"location":"Logging/","title":"Logging","text":"

    OTP uses logback and slj4j 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.

    Some loggers useful for debugging.

    "},{"location":"Logging/#format","title":"Format","text":"

    By default, OTP logs in plain text to the console. However, it is possible to also log in JSON format.

    To enable it, set the Java property otp.logging.format to one of these values:

    "},{"location":"Logging/#complete-example","title":"Complete example","text":"
    java -Dotp.logging.format=json -jar otp.jar --load --serve data\n
    "},{"location":"Logging/#further-customization","title":"Further customization","text":"

    If you want to customize the exact log output even further you can use your own logback configuration by starting OTP with the following parameter:

    java -Dlogback.configurationFile=/path/to/logback.xml -jar otp.jar --load --serve data\n

    For example, Entur has their own custom log format configured as follows:

    <!-- Entur's custom log format  -->\n<appender name=\"entur\" class=\"ch.qos.logback.core.ConsoleAppender\">\n  <encoder class=\"net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder\">\n     <providers>\n        <!-- provides the timestamp <timestamp/> -->\n        <!-- provides the version <version/> -->\n        <!-- provides the fields in the configured pattern -->\n        <pattern>\n           <!-- the pattern that defines what to include -->\n           <pattern>\n           {\n             \"serviceContext\": {\n               \"service\": \"otp2\"\n             },\n             \"message\": \"%message\\n%ex{full}\",\n             \"severity\": \"%level\",\n             \"reportLocation\": {\n               \"filePath\": \"%logger\",\n               \"lineNumber\": \"%line\",\n               \"functionName\": \"%method\"\n              }\n            }\n            </pattern>\n        </pattern>\n     </providers>\n  </encoder>\n</appender>\n
    "},{"location":"Migrating-Configuration/","title":"Migrating between versions/builds","text":"

    While OTP's GraphQL APIs are very, very stable even across versions, the JSON configuration schema is not. Changes to it are relatively frequent and you can see all PRs that change it with the Github tag 'config change'.

    "},{"location":"Migrating-Configuration/#migrating-the-json-configuration","title":"Migrating the JSON configuration","text":"

    OTP validates the configuration and prints warnings during startup. This means that when you migrate to a newer version, you should carefully inspect the logs. If you see messages like

    (NodeAdapter.java:170) Unexpected config parameter: 'routingDefaults.stairsReluctance:1.65' in 'router-config.json'\n

    this means there are properties in your configuration that are unknown to OTP and therefore likely to be a configuration error, perhaps because the schema was changed. In such a case you should consult the feature, router or build configuration documentation to find out what the new schema looks like.

    By default, OTP starts up even if unknown configuration parameters exist. This supports forward and backwards migration of config parameters independent if the OTP version. This allows the configuration to follow the lifecycle of the environment and still be able to roll back OTP. Combined with the config parameter substitution it also allows using the same configuration in different environments. Tip! Rolling out the configuration before rolling out a new version of OTP, ensure you that you are safe and can roll back later.

    An example: you change the location of the graphs, a critical error occurs afterwards and you need to roll back. Any member of the dev-ops team should then be confident that they can roll back without risk - even if the environment changed since the last OTP version was rolled out.

    "},{"location":"Migrating-Configuration/#aborting-on-invalid-configuration","title":"Aborting on invalid configuration","text":"

    If you want OTP to abort the startup when encountering unknown configuration parameters, you can add the flag --abortOnUnknownConfig to your regular OTP CLI commands.

    This should of course be used wisely as it can also accidentally make your production instances refuse to start up. For some deployments this is a good solution - especially if the config substitution feature is used to inject environment specific information. Using this feature in the graph-build phase is less risky, than in the OTP serve phase.

    "},{"location":"Netex-Tutorial/","title":"NeTEx & SIRI tutorial","text":"

    One important new feature of OTP2 is the ability to load NeTEx and SIRI data. NeTEx is a European specification for transit data exchange, comparable in purpose to GTFS but broader in scope.

    First of all, you need to download a bundled jar of OTP.

    Secondly, you will use the Norwegian NeTEx file as well as the Norwegian OSM data, but OTP can download the NeTEx one for you.

    "},{"location":"Netex-Tutorial/#configuring-the-build","title":"Configuring the build","text":"

    Create a working directory and place the OTP jar file in it and call it otp.jar.

    Since we download the OSM data from a free source, we don't want to put undue stress on the server. Therefore we download it before building the graph, not during.

    curl https://download.geofabrik.de/europe/norway-latest.osm.pbf -o norway.osm.pbf\n

    Now create a file called build-config.json in the same folder and fill it with the following content:

    // build-config.json\n{\n  \"transitFeeds\" : [\n    {\n      \"type\" : \"netex\",\n      \"feedId\" : \"NO\",\n      \"source\" : \"https://storage.googleapis.com/marduk-production/outbound/netex/rb_norway-aggregated-netex.zip\",\n      \"sharedFilePattern\" : \"_stops.xml\",\n      \"sharedGroupFilePattern\" : \"_(\\\\w{3})(_flexible)?_shared_data.xml\",\n      \"groupFilePattern\" : \"(\\\\w{3})_.*\\\\.xml\"\n    }\n  ],\n  \"osm\" : [\n    {\n      \"source\" : \"norway.osm.pbf\",\n      \"osmTagMapping\" : \"norway\",\n      \"timeZone\" : \"Europe/Oslo\"\n    }\n  ],\n  \"osmCacheDataInMem\" : true\n}\n

    Note the special section specifying how to find NeTEx XML files within the single ZIP archive that OTP downloads.

    Now you can instruct OTP to build a graph from this configuration file:

    java -Xmx16G -jar otp.jar --build --save .

    This should produce a file graph.obj in the same directory as your build-config.json.

    Building the Norway graph requires downloading about 250MB of input data so stay patient at the beginning particularly on a slow internet connection. The actual build takes approximately 10 minutes (without elevation data, as is configured above), and can be done within 16GB of heap memory (JVM switch -Xmx16G). The Graph file it produces is about 1.1 GB. The server will take about 30 seconds to load this graph and start up, and will consume about 6GB of heap memory under light use.

    You can then start up an OTP server with a command like this:

    java -Xmx6G -jar otp.jar --load .

    Once the server is started up, go to http://localhost:8080 in a browser to try out your server using OTP's built in testing web client. Try some long trips like Oslo to Bergen and see if you can get long distance trains and flights as alternatives. You might need to increase the walking limit above its very low default value.

    "},{"location":"Netex-Tutorial/#adding-siri-real-time-data","title":"Adding SIRI real time Data","text":"

    Another important feature in OTP version 2 is the ability to use SIRI real-time data. Within the EU data standards, SIRI is analogous to GTFS-RT: a way to apply real-time updates on top of schedule data. While technically a distinct specification from NeTEx, both NeTEx and SIRI use the Transmodel vocabulary, allowing SIRI messages to reference entities in NeTEx schedule data. Like GTFS-RT, SIRI is consumed by OTP2 using \"graph updaters\" which are configured in the router-config.json file, which is placed in the same directory as the graph.obj file and loaded at server startup.

    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"siri-sx-updater\",\n      \"frequency\" : \"1m\",\n      \"url\" : \"https://api.entur.io/realtime/v1/services\",\n      \"feedId\" : \"NO\",\n      \"blockReadinessUntilInitialized\" : true\n    },\n    {\n      \"type\" : \"siri-et-updater\",\n      \"frequency\" : \"1m\",\n      \"previewInterval\" : \"1h30m\",\n      \"url\" : \"https://api.entur.io/realtime/v1/services\",\n      \"feedId\" : \"NO\",\n      \"blockReadinessUntilInitialized\" : true\n    }\n  ]\n}\n

    After saving the file in the working directory, restart OTP.

    The updaters fetch two different kinds of SIRI data:

    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.

    "},{"location":"Preparing-OSM/","title":"Preparing OSM Data","text":""},{"location":"Preparing-OSM/#cropping-osm-data","title":"Cropping OSM data","text":"

    Services producing automated extracts of OSM data like Geofabrik or Interline 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 is a multi-platform Java tool that works on Windows, Linux, and MacOS but is relatively slow, 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 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. Selecting the \"CSV\" format in the lower left will give exactly the format expected by these tools.

    "},{"location":"Preparing-OSM/#filtering-osm-data","title":"Filtering OSM data","text":"

    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 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 and 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 wa/public_transport=platform wa/railway=platform w/park_ride=yes r/type=restriction r/type=route -o filtered.osm.pbf -f pbf,add_metadata=false

    "},{"location":"Presentations/","title":"Presentations related to OpenTripPlanner","text":""},{"location":"Presentations/#presentations-in-english","title":"Presentations in English","text":""},{"location":"Presentations/#presentations-in-german","title":"Presentations in German","text":""},{"location":"Presentations/#case-studies-and-reports","title":"Case studies and reports","text":""},{"location":"Product-Overview/","title":"Product Overview","text":""},{"location":"Product-Overview/#opentripplanner-project","title":"OpenTripPlanner project","text":"

    OpenTripPlanner is a group of open source software applications that help individuals and organizations calculate and deliver multimodal trip plans based on a combination of open-standard data sources. These include public transit services and schedules (GTFS and NeTEx) and OpenStreetMap (OSM), as well as sources describing bicycle sharing or rental, ride hailing, and other services (e.g. GBFS).

    A community of dozens of individuals and organizations work on OpenTripPlanner collaboratively to improve multimodal trip planning best practices and to make it easier for public transit agencies and public transit riders to publish and access information about transit services.

    OpenTripPlanner deployments are locally managed in many different ways by many different types of organizations. OpenTripPlanner consistently and dependably delivers multimodal trip plans to millions of riders every day in dozens of countries around the globe. The project is actively maintained by the community, with more than 50 commits most weeks during 2022, and 20 different developers having made 50 or more commits during the life of the project.

    "},{"location":"Product-Overview/#what-exactly-is-otp","title":"What exactly is OTP?","text":"

    The most commonly used OpenTripPlanner component is a server-side Java application that is primarily designed to interpret and combine map, transit service, and other mobility data sets, providing API endpoints that receive user origins and destinations and return trip plans to other applications along with vector map tiles, stop departures, and other rider information.

    In other words, OTP is a backend application that can work with other frontend user interfaces. OTP works with your website, mobile app, physical signage or other applications in order to provide relevant customer information and meaningful trip plans to riders.

    There's no official OTP user interface, although the OpenTripPlanner ecosystem includes several user interface projects (for example Digitransit and OTP-react-redux). How your OTP deployment looks is entirely up to you.

    "},{"location":"Product-Overview/#what-otp-can-do-for-you","title":"What OTP can do for you","text":""},{"location":"Product-Overview/#transit-agencies","title":"Transit agencies","text":"

    Transit agencies can use OTP as a backend for their public website/app trip planner or internal trip planner for their customer service team.

    "},{"location":"Product-Overview/#regions-countries-and-private-entities","title":"Regions, countries, and private entities","text":"

    Regional, provincial, or national governments, or any private entity, can set up a trip planner including multiple transit agencies.

    "},{"location":"Product-Overview/#researchers","title":"Researchers","text":"

    While historically, OpenTripPlanner has often been used by researchers for the programmatic calculation of large numbers of trip plans, this is no longer an intended use case of OTP. You are welcome to use OTP for any purpose, but you may also find applications like r5 to be more appropriate for these purposes.

    "},{"location":"Product-Overview/#talk-to-an-expert-about-otp","title":"Talk to an expert about OTP","text":"

    Everyone interested in OTP is welcome to post questions on the Gitter chat or OpenTripPlanner-users group.

    If you\u2019re looking for a conversation with an individual from a similar organizational type, you can make that request and include some info about your organization on the forum linked above and a member of the OTP community will connect with you.

    "},{"location":"ReleaseChecklist/","title":"Release Checklist","text":"

    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.

    "},{"location":"ReleaseChecklist/#artifact-signing","title":"Artifact Signing","text":"

    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 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 mvn clean package site to bypass signing, but this provides less certainty that everything is set up correctly for the CI-driven final release.

    "},{"location":"Roadmap/","title":"Roadmap","text":"

    The OTP community uses a GitHub-hosted Roadmap to document all long-term feature requests for OpenTripPlanner. Unlike typical OTP Issues, the Roadmap outlines quarterly and yearly product-focused goals the community intends to propose for OTP, rather than short-term bug fixes or feature requests.

    Twice a year, product owners (POs) and developers will review and clean up the issues at the PO meetings. Product owner (PO) meetings are open to everyone interested in OTP and are held on the first Tuesday of each month at 7 AM US Pacific / 10 AM US Eastern / 4PM CET. To join, please consult this calender. For other questions, please contact members in the Gitter chat or the user mailing list.

    To create an issue on the OTP Roadmap, follow these steps:

    1. Navigate to the OpenTripPlanner GitHub.
    2. Select the \"Projects\" tab.
    3. Choose the \"Roadmap\" project.
    4. To add an issue, click \"Add item\" under the \"Wish list\" column.
    5. Click the \"+\" icon, then \"Create a new issue.\"
    6. Select the \"Roadmap Epic\" type by clicking \"Choose.\"
    7. Complete the required fields:

    Then, click \"Create.\"

    This is what your completed Roadmap Issue should like:

    Discussions about the Issue within the corresponding Gitter chat are encouraged, along with participation in the OTP product owner (PO) or developer meetings.

    "},{"location":"RouteRequest/","title":"Route Request","text":""},{"location":"RouteRequest/#route-request","title":"Route Request","text":"

    The RouteRequest is the type for the routingDefaults in router-config.json and in the transferRequests in build-config.json.

    Config Parameter Type Summary Req./Opt. Default Value Since alightSlack duration The time safety margin when alighting from a vehicle. Optional \"PT0S\" 2.0 arriveBy boolean Whether the trip should depart or arrive at the specified date and time. Optional false 2.0 boardSlack duration The time safety margin when boarding a vehicle. Optional \"PT0S\" 2.0 drivingDirection enum The driving direction to use in the intersection traversal calculation Optional \"right\" 2.2 elevatorBoardCost integer What is the cost of boarding a elevator? Optional 90 2.0 elevatorBoardTime integer How long does it take to get on an elevator, on average. Optional 90 2.0 elevatorHopCost integer What is the cost of travelling one floor on an elevator? Optional 20 2.0 elevatorHopTime integer How long does it take to advance one floor on an elevator? Optional 20 2.0 geoidElevation boolean If true, the Graph's ellipsoidToGeoidDifference is applied to all elevations returned by this query. Optional false 2.0 ignoreRealtimeUpdates boolean When true, real-time updates are ignored during this search. Optional false 2.0 intersectionTraversalModel enum The model that computes the costs of turns. Optional \"simple\" 2.2 locale locale TODO Optional \"en_US\" 2.0 maxDirectStreetDuration duration This is the maximum duration for a direct street search for each mode. Optional \"PT4H\" 2.1 maxJourneyDuration duration The expected maximum time a journey can last across all possible journeys for the current deployment. Optional \"PT24H\" 2.1 modes string The set of access/egress/direct/transit modes to be used for the route search. Optional \"TRANSIT,WALK\" 2.0 nonpreferredTransferPenalty integer Penalty (in seconds) for using a non-preferred transfer. Optional 180 2.0 numItineraries integer The maximum number of itineraries to return. Optional 50 2.0 otherThanPreferredRoutesPenalty integer Penalty added for using every route that is not preferred if user set any route as preferred. Optional 300 2.0 relaxTransitGroupPriority string The relax function for transit-group-priority Optional \"0s + 1.00 t\" 2.5 relaxTransitSearchGeneralizedCostAtDestination double Whether non-optimal transit paths at the destination should be returned Optional 2.3 searchWindow duration The duration of the search-window. Optional 2.0 streetRoutingTimeout duration The maximum time a street routing request is allowed to take before returning the results. Optional \"PT5S\" 2.2 transferPenalty integer An additional penalty added to boardings after the first. Optional 0 2.0 transferSlack duration The extra time needed to make a safe transfer. Optional \"PT2M\" 2.0 turnReluctance double Multiplicative factor on expected turning time. Optional 1.0 2.0 unpreferredCost cost-linear-function A cost function used to calculate penalty for an unpreferred route. Optional \"0s + 1.00 t\" 2.2 waitReluctance double How much worse is waiting for a transit vehicle than being on a transit vehicle, as a multiplier. Optional 1.0 2.0 accessEgress object Parameters for access and egress routing. Optional 2.4 maxDuration duration This is the maximum duration for access/egress for street searches. Optional \"PT45M\" 2.1 maxStopCount integer Maximal number of stops collected in access/egress routing Optional 500 2.4 maxDurationForMode enum map of duration Limit access/egress per street mode. Optional 2.1 penalty enum map of object Penalty for access/egress by street mode. Optional 2.4 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0FLEXIBLE object NA Optional 2.4 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0costFactor double A factor multiplied with the time-penalty to get the cost-penalty. Optional 0.0 2.4 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0timePenalty time-penalty Penalty added to the time of a path/leg. Optional \"0s + 0.00 t\" 2.4 alightSlackForMode enum map of duration How much extra time should be given when alighting a vehicle for each given mode. Optional 2.0 bicycle object Bicycle preferences. Optional 2.5 boardCost integer Prevents unnecessary transfers by adding a cost for boarding a transit vehicle. Optional 600 2.0 optimization enum The set of characteristics that the user wants to optimize for. Optional \"safe-streets\" 2.0 \u00a0\u00a0\u00a0reluctance double A multiplier for how bad cycling is, compared to being in transit for equal lengths of time. Optional 2.0 2.0 \u00a0\u00a0\u00a0speed double Max bicycle speed along streets, in meters per second Optional 5.0 2.0 \u00a0\u00a0\u00a0parking object Preferences for parking a vehicle. Optional 2.5 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cost integer Cost to park a vehicle. Optional 120 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0time duration Time to park a vehicle. Optional \"PT1M\" 2.0 unpreferredVehicleParkingTagCost integer What cost to add if a parking facility doesn't contain a preferred tag. Optional 300 2.3 bannedVehicleParkingTags string[] Tags with which a vehicle parking will not be used. If empty, no tags are banned. Optional 2.1 preferredVehicleParkingTags string[] Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. Optional 2.3 requiredVehicleParkingTags string[] Tags without which a vehicle parking will not be used. If empty, no tags are required. Optional 2.1 \u00a0\u00a0\u00a0rental object Vehicle rental options Optional 2.3 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0allowKeepingAtDestination boolean If a vehicle should be allowed to be kept at the end of a station-based rental. Optional false 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dropOffCost integer Cost to drop-off a rented vehicle. Optional 30 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dropOffTime duration Time to drop-off a rented vehicle. Optional \"PT30S\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0keepingAtDestinationCost integer The cost of arriving at the destination with the rented vehicle, to discourage doing so. Optional 0 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pickupCost integer Cost to rent a vehicle. Optional 120 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pickupTime duration Time to rent a vehicle. Optional \"PT1M\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0useAvailabilityInformation boolean Whether or not vehicle rental availability information will be used to plan vehicle rental trips. Optional false 2.0 allowedNetworks string[] The vehicle rental networks which may be used. If empty all networks may be used. Optional 2.1 bannedNetworks string[] The vehicle rental networks which may not be used. If empty, no networks are banned. Optional 2.1 triangle object Triangle optimization criteria. Optional 2.5 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0flatness double Relative importance of flat terrain (range 0-1). Optional 0.0 2.0 safety double Relative importance of safety (range 0-1). Optional 0.0 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0time double Relative importance of duration of travel (range 0-1). Optional 0.0 2.0 \u00a0\u00a0\u00a0walk object Preferences for walking a vehicle. Optional 2.5 mountDismountCost integer The cost of hopping on or off a vehicle. Optional 0 2.0 mountDismountTime duration The time it takes the user to hop on or off a vehicle. Optional \"PT0S\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0reluctance double A multiplier for how bad walking with a vehicle is, compared to being in transit for equal lengths of time. Optional 5.0 2.1 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0speed double The user's vehicle walking speed in meters/second. Defaults to approximately 3 MPH. Optional 1.33 2.1 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0stairsReluctance double How bad is it to walk the vehicle up/down a flight of stairs compared to taking a detour. Optional 10.0 2.3 boardSlackForMode enum map of duration How much extra time should be given when boarding a vehicle for each given mode. Optional 2.0 car object Car preferences. Optional 2.5 \u00a0\u00a0\u00a0accelerationSpeed double The acceleration speed of an automobile, in meters per second per second. Optional 2.9 2.0 \u00a0\u00a0\u00a0decelerationSpeed double The deceleration speed of an automobile, in meters per second per second. Optional 2.9 2.0 \u00a0\u00a0\u00a0pickupCost integer Add a cost for car pickup changes when a pickup or drop off takes place Optional 120 2.1 \u00a0\u00a0\u00a0pickupTime duration Add a time for car pickup changes when a pickup or drop off takes place Optional \"PT1M\" 2.1 \u00a0\u00a0\u00a0reluctance double A multiplier for how bad driving is, compared to being in transit for equal lengths of time. Optional 2.0 2.0 \u00a0\u00a0\u00a0parking object Preferences for parking a vehicle. Optional 2.5 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cost integer Cost to park a vehicle. Optional 120 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0time duration Time to park a vehicle. Optional \"PT1M\" 2.0 unpreferredVehicleParkingTagCost integer What cost to add if a parking facility doesn't contain a preferred tag. Optional 300 2.3 bannedVehicleParkingTags string[] Tags with which a vehicle parking will not be used. If empty, no tags are banned. Optional 2.1 preferredVehicleParkingTags string[] Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. Optional 2.3 requiredVehicleParkingTags string[] Tags without which a vehicle parking will not be used. If empty, no tags are required. Optional 2.1 \u00a0\u00a0\u00a0rental object Vehicle rental options Optional 2.3 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0allowKeepingAtDestination boolean If a vehicle should be allowed to be kept at the end of a station-based rental. Optional false 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dropOffCost integer Cost to drop-off a rented vehicle. Optional 30 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dropOffTime duration Time to drop-off a rented vehicle. Optional \"PT30S\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0keepingAtDestinationCost integer The cost of arriving at the destination with the rented vehicle, to discourage doing so. Optional 0 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pickupCost integer Cost to rent a vehicle. Optional 120 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pickupTime duration Time to rent a vehicle. Optional \"PT1M\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0useAvailabilityInformation boolean Whether or not vehicle rental availability information will be used to plan vehicle rental trips. Optional false 2.0 allowedNetworks string[] The vehicle rental networks which may be used. If empty all networks may be used. Optional 2.1 bannedNetworks string[] The vehicle rental networks which may not be used. If empty, no networks are banned. Optional 2.1 itineraryFilters object Configure itinerary filters that may modify itineraries, sort them, and filter away less preferable results. Optional 2.0 accessibilityScore boolean An experimental feature contributed by IBI which adds a sandbox accessibility score between 0 and 1 for each leg and itinerary. Optional false 2.2 bikeRentalDistanceRatio double Filter routes that consist of bike-rental and walking by the minimum fraction of the bike-rental leg using distance. Optional 0.0 2.1 debug enum Enable this to attach a system notice to itineraries instead of removing them. This is very convenient when tuning the itinerary-filter-chain. Optional \"off\" 2.0 filterDirectFlexBySearchWindow boolean Filter direct flex results by the search window. The search-window is not used during flex routing, but we use one end to align it with transit results. Optional true 2.7 filterItinerariesWithSameFirstOrLastTrip boolean If more than one itinerary begins or ends with same trip, filter out one of those itineraries so that only one remains. Optional false 2.2 \u00a0\u00a0\u00a0groupSimilarityKeepOne double Pick ONE itinerary from each group after putting itineraries that are 85% similar together. Optional 0.85 2.1 \u00a0\u00a0\u00a0groupSimilarityKeepThree double Reduce the number of itineraries to three itineraries by reducing each group of itineraries grouped by 68% similarity. Optional 0.68 2.1 groupedOtherThanSameLegsMaxCostMultiplier double Filter grouped itineraries, where the non-grouped legs are more expensive than in the lowest cost one. Optional 2.0 2.1 minBikeParkingDistance double Filter out bike park+ride results that have fewer meters of cycling than this value. Optional 0.0 2.3 nonTransitGeneralizedCostLimit cost-linear-function The function define a max-limit for generalized-cost for non-transit itineraries. Optional \"1h + 2.0 t\" 2.1 parkAndRideDurationRatio double Filter P+R routes that consist of driving and walking by the minimum fraction of the driving using of time. Optional 0.0 2.1 removeItinerariesWithSameRoutesAndStops boolean Set to true if you want to list only the first itinerary which goes through the same stops and routes. Optional false 2.2 removeTransitWithHigherCostThanBestOnStreetOnly cost-linear-function Limit function for generalized-cost computed from street-only itineries applied to transit itineraries. Optional \"1m + 1.30 t\" 2.4 transitGeneralizedCostLimit object A relative limit for the generalized-cost for transit itineraries. Optional 2.1 costLimitFunction cost-linear-function The base function used by the filter. Optional \"15m + 1.50 t\" 2.2 intervalRelaxFactor double How much the filter should be relaxed for itineraries that do not overlap in time. Optional 0.4 2.2 maxDirectStreetDurationForMode enum map of duration Limit direct route duration per street mode. Optional 2.2 scooter object Scooter preferences. Optional 2.5 optimization enum The set of characteristics that the user wants to optimize for. Optional \"safe-streets\" 2.0 \u00a0\u00a0\u00a0reluctance double A multiplier for how bad scooter travel is, compared to being in transit for equal lengths of time. Optional 2.0 2.0 \u00a0\u00a0\u00a0speed double Max scooter speed along streets, in meters per second Optional 5.0 2.0 \u00a0\u00a0\u00a0rental object Vehicle rental options Optional 2.3 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0allowKeepingAtDestination boolean If a vehicle should be allowed to be kept at the end of a station-based rental. Optional false 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dropOffCost integer Cost to drop-off a rented vehicle. Optional 30 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dropOffTime duration Time to drop-off a rented vehicle. Optional \"PT30S\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0keepingAtDestinationCost integer The cost of arriving at the destination with the rented vehicle, to discourage doing so. Optional 0 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pickupCost integer Cost to rent a vehicle. Optional 120 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pickupTime duration Time to rent a vehicle. Optional \"PT1M\" 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0useAvailabilityInformation boolean Whether or not vehicle rental availability information will be used to plan vehicle rental trips. Optional false 2.0 allowedNetworks string[] The vehicle rental networks which may be used. If empty all networks may be used. Optional 2.1 bannedNetworks string[] The vehicle rental networks which may not be used. If empty, no networks are banned. Optional 2.1 triangle object Triangle optimization criteria. Optional 2.5 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0flatness double Relative importance of flat terrain (range 0-1). Optional 0.0 2.0 safety double Relative importance of safety (range 0-1). Optional 0.0 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0time double Relative importance of duration of travel (range 0-1). Optional 0.0 2.0 transferOptimization object Optimize where a transfer between to trip happens. Optional 2.1 backTravelWaitTimeFactor double To reduce back-travel we favor waiting, this reduces the cost of waiting. Optional 1.0 2.1 extraStopBoardAlightCostsFactor double Add an extra board- and alight-cost for prioritized stops. Optional 0.0 2.1 minSafeWaitTimeFactor double Used to set a maximum wait-time cost, base on min-safe-transfer-time. Optional 5.0 2.1 optimizeTransferWaitTime boolean This enables the transfer wait time optimization. Optional true 2.1 transitGroupPriority object Group transit patterns and give each group a mutual advantage in the Raptor search. Optional 2.5 transitReluctanceForMode enum map of double Transit reluctance for a given transport mode Optional 2.1 unpreferred object Parameters listing authorities or lines that preferably should not be used in trip patters. Optional 2.2 agencies feed-scoped-id[] The ids of the agencies that incur an extra cost when being used. Format: FeedId:AgencyId Optional 2.2 routes feed-scoped-id[] The ids of the routes that incur an extra cost when being used. Format: FeedId:RouteId Optional 2.2 walk object Walking preferences. Optional 2.5 \u00a0\u00a0\u00a0boardCost integer Prevents unnecessary transfers by adding a cost for boarding a vehicle. This is the cost that is used when boarding while walking. Optional 600 2.0 \u00a0\u00a0\u00a0escalatorReluctance double A multiplier for how bad being in an escalator is compared to being in transit for equal lengths of time Optional 1.5 2.4 reluctance double A multiplier for how bad walking is, compared to being in transit for equal lengths of time. Optional 2.0 2.0 safetyFactor double Factor for how much the walk safety is considered in routing. Optional 1.0 2.2 \u00a0\u00a0\u00a0speed double The user's walking speed in meters/second. Optional 1.33 2.0 \u00a0\u00a0\u00a0stairsReluctance double Used instead of walkReluctance for stairs. Optional 2.0 2.0 stairsTimeFactor double How much more time does it take to walk a flight of stairs compared to walking a similar horizontal length. Optional 3.0 2.1 wheelchairAccessibility object See Wheelchair Accessibility Optional 2.2 \u00a0\u00a0\u00a0enabled boolean Enable wheelchair accessibility. Optional false 2.0 \u00a0\u00a0\u00a0inaccessibleStreetReluctance double The factor to multiply the cost of traversing a street edge that is not wheelchair-accessible. Optional 25.0 2.2 maxSlope double The maximum slope as a fraction of 1. Optional 0.083 2.0 slopeExceededReluctance double How much streets with high slope should be avoided. Optional 1.0 2.2 stairsReluctance double How much stairs should be avoided. Optional 100.0 2.2 \u00a0\u00a0\u00a0elevator object Configuration for when to use inaccessible elevators. Optional 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0inaccessibleCost integer The cost to add when traversing an entity which is know to be inaccessible. Optional 3600 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onlyConsiderAccessible boolean Whether to only use this entity if it is explicitly marked as wheelchair accessible. Optional false 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0unknownCost integer The cost to add when traversing an entity with unknown accessibility information. Optional 20 2.2 \u00a0\u00a0\u00a0stop object Configuration for when to use inaccessible stops. Optional 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0inaccessibleCost integer The cost to add when traversing an entity which is know to be inaccessible. Optional 3600 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onlyConsiderAccessible boolean Whether to only use this entity if it is explicitly marked as wheelchair accessible. Optional true 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0unknownCost integer The cost to add when traversing an entity with unknown accessibility information. Optional 600 2.2 \u00a0\u00a0\u00a0trip object Configuration for when to use inaccessible trips. Optional 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0inaccessibleCost integer The cost to add when traversing an entity which is know to be inaccessible. Optional 3600 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onlyConsiderAccessible boolean Whether to only use this entity if it is explicitly marked as wheelchair accessible. Optional true 2.2 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0unknownCost integer The cost to add when traversing an entity with unknown accessibility information. Optional 600 2.2"},{"location":"RouteRequest/#parameter-details","title":"Parameter Details","text":""},{"location":"RouteRequest/#rd_alightSlack","title":"alightSlack","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT0S\" Path: /routingDefaults

    The time safety margin when alighting from a vehicle.

    This time slack is added to arrival time of the vehicle before any transfer or onward travel.

    This time slack helps model potential delays or procedures a passenger experiences during the process of passing through the alighting location. This parameter is intended to be set by agencies not individual users. For specific modes, like airplane and subway, that need more time than others, this is also configurable per mode with alightSlackForMode. A related parameter (transferSlack) exists to help avoid missed connections when there are minor schedule variations.

    "},{"location":"RouteRequest/#rd_boardSlack","title":"boardSlack","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT0S\" Path: /routingDefaults

    The time safety margin when boarding a vehicle.

    The board slack is added to the passenger's arrival time at a stop, before evaluating which vehicles can be boarded.

    This time slack helps model potential delays or procedures a passenger experiences during the process of passing through the boarding location, as well as some minor schedule variation. This parameter is intended to be set by agencies not individual users.

    Agencies can use this parameter to ensure that the trip planner does not instruct passengers to arrive at the last second. This slack is added at every boarding including the first vehicle and transfers except for in-seat transfers and guaranteed transfers.

    For specific modes, like airplane and subway, that need more time than others, this is also configurable per mode with boardSlackForMode.

    A related parameter (transferSlack) also helps avoid missed connections when there are minor schedule variations.

    "},{"location":"RouteRequest/#rd_drivingDirection","title":"drivingDirection","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"right\" Path: /routingDefaults Enum values: right | left

    The driving direction to use in the intersection traversal calculation

    "},{"location":"RouteRequest/#rd_intersectionTraversalModel","title":"intersectionTraversalModel","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"simple\" Path: /routingDefaults Enum values: simple | constant

    The model that computes the costs of turns.

    "},{"location":"RouteRequest/#rd_maxDirectStreetDuration","title":"maxDirectStreetDuration","text":"

    Since version: 2.1 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT4H\" Path: /routingDefaults

    This is the maximum duration for a direct street search for each mode.

    This is a performance limit and should therefore be set high. Results close to the limit are not guaranteed to be optimal. Use itinerary-filters to limit what is presented to the client. The duration can be set per mode(maxDirectStreetDurationForMode), because some street modes searches are much more resource intensive than others. A default value is applied if the mode specific value does not exist.\"

    "},{"location":"RouteRequest/#rd_maxJourneyDuration","title":"maxJourneyDuration","text":"

    Since version: 2.1 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT24H\" Path: /routingDefaults

    The expected maximum time a journey can last across all possible journeys for the current deployment.

    Normally you would just do an estimate and add enough slack, so you are sure that there is no journeys that falls outside this window. The parameter is used find all possible dates for the journey and then search only the services which run on those dates. The duration must include access, egress, wait-time and transit time for the whole journey. It should also take low frequency days/periods like holidays into account. In other words, pick the two points within your area that has the worst connection and then try to travel on the worst possible day, and find the maximum journey duration. Using a value that is too high has the effect of including more patterns in the search, hence, making it a bit slower. Recommended values would be from 12 hours(small town/city), 1 day (region) to 2 days (country like Norway).\"

    "},{"location":"RouteRequest/#rd_otherThanPreferredRoutesPenalty","title":"otherThanPreferredRoutesPenalty","text":"

    Since version: 2.0 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 300 Path: /routingDefaults

    Penalty added for using every route that is not preferred if user set any route as preferred.

    We return number of seconds that we are willing to wait for preferred route.

    "},{"location":"RouteRequest/#rd_relaxTransitGroupPriority","title":"relaxTransitGroupPriority","text":"

    Since version: 2.5 \u2219 Type: string \u2219 Cardinality: Optional \u2219 Default value: \"0s + 1.00 t\" Path: /routingDefaults

    The relax function for transit-group-priority

    A path is considered optimal if the generalized-cost is less than the generalized-cost of another path. If this parameter is set, the comparison is relaxed further if they belong to different transit groups.

    "},{"location":"RouteRequest/#rd_relaxTransitSearchGeneralizedCostAtDestination","title":"relaxTransitSearchGeneralizedCostAtDestination","text":"

    Since version: 2.3 \u2219 Type: double \u2219 Cardinality: Optional Path: /routingDefaults

    Whether non-optimal transit paths at the destination should be returned

    Let c be the existing minimum pareto optimal generalized cost to beat. Then a trip with cost c' is accepted if the following is true: c' < Math.round(c * relaxRaptorCostCriteria).

    The parameter is optional. If not set a normal comparison is performed.

    Values equals or less than zero is not allowed. Values greater than 2.0 are not supported, due to performance reasons.

    "},{"location":"RouteRequest/#rd_searchWindow","title":"searchWindow","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional Path: /routingDefaults

    The duration of the search-window.

    This is the time/duration in seconds from the earliest-departure-time(EDT) to the latest-departure-time(LDT). In case of a reverse search it will be the time from earliest to latest arrival time (LAT - EAT).

    All optimal travels that depart within the search window is guaranteed to be found.

    This is sometimes referred to as the Range Raptor Search Window - but could be used in a none Transit search as well; Hence this is named search-window and not raptor-search-window.

    This is normally dynamically calculated by the server. Use null to unset, and zero to do one Raptor iteration. The value is dynamically assigned a suitable value, if not set. In a small to medium size operation you may use a fixed value, like 60 minutes. If you have a mixture of high frequency cities routes and infrequent long distant journeys, the best option is normally to use the dynamic auto assignment. If not provided the value is resolved depending on the other input parameters, available transit options and realtime changes.

    There is no need to set this when going to the next/previous page. The OTP Server will increase/decrease the search-window when paging to match the requested number of itineraries.

    "},{"location":"RouteRequest/#rd_streetRoutingTimeout","title":"streetRoutingTimeout","text":"

    Since version: 2.2 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT5S\" Path: /routingDefaults

    The maximum time a street routing request is allowed to take before returning the results.

    The street search(AStar) aborts after this duration and any paths found are returned to the client. The street part of the routing may take a long time if searching very long distances. You can set the street routing timeout to avoid tying up server resources on pointless searches and ensure that your users receive a timely response. You can also limit the max duration. There are is also a 'apiProcessingTimeout'. Make sure the street timeout is less than the 'apiProcessingTimeout'.

    "},{"location":"RouteRequest/#rd_transferPenalty","title":"transferPenalty","text":"

    Since version: 2.0 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 0 Path: /routingDefaults

    An additional penalty added to boardings after the first.

    The value is in OTP's internal weight units, which are roughly equivalent to seconds. Set this to a high value to discourage transfers. Of course, transfers that save significant time or walking will still be taken.

    "},{"location":"RouteRequest/#rd_transferSlack","title":"transferSlack","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT2M\" Path: /routingDefaults

    The extra time needed to make a safe transfer.

    The extra buffer time/safety margin added to transfers to make sure the connection is safe, time wise. We recommend allowing the end-user to set this, and use board-/alight-slack to enforce agency policies. This time is in addition to how long it might take to walk, board and alight.

    It is useful for passengers on long distance travel, and people with mobility issues, but can be set close to zero for everyday commuters and short distance searches in high-frequency transit areas.

    "},{"location":"RouteRequest/#rd_unpreferredCost","title":"unpreferredCost","text":"

    Since version: 2.2 \u2219 Type: cost-linear-function \u2219 Cardinality: Optional \u2219 Default value: \"0s + 1.00 t\" Path: /routingDefaults

    A cost function used to calculate penalty for an unpreferred route.

    Function should return number of seconds that we are willing to wait for preferred route or for an unpreferred agency's departure. For example: 5m + 2.0 t

    "},{"location":"RouteRequest/#rd_accessEgress_maxDuration","title":"maxDuration","text":"

    Since version: 2.1 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT45M\" Path: /routingDefaults/accessEgress

    This is the maximum duration for access/egress for street searches.

    This is a performance limit and should therefore be set high. Results close to the limit are not guaranteed to be optimal. Use itinerary-filters to limit what is presented to the client. The duration can be set per mode(maxDurationForMode), because some street modes searches are much more resource intensive than others. A default value is applied if the mode specific value does not exist.

    "},{"location":"RouteRequest/#rd_accessEgress_maxStopCount","title":"maxStopCount","text":"

    Since version: 2.4 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 500 Path: /routingDefaults/accessEgress

    Maximal number of stops collected in access/egress routing

    Safety limit to prevent access to and egress from too many stops.

    "},{"location":"RouteRequest/#rd_accessEgress_maxDurationForMode","title":"maxDurationForMode","text":"

    Since version: 2.1 \u2219 Type: enum map of duration \u2219 Cardinality: Optional Path: /routingDefaults/accessEgress Enum keys: not-set | walk | bike | bike-to-park | bike-rental | scooter-rental | car | car-to-park | car-pickup | car-rental | car-hailing | flexible

    Limit access/egress per street mode.

    Override the settings in maxDuration for specific street modes. This is done because some street modes searches are much more resource intensive than others.

    "},{"location":"RouteRequest/#rd_accessEgress_penalty","title":"penalty","text":"

    Since version: 2.4 \u2219 Type: enum map of object \u2219 Cardinality: Optional Path: /routingDefaults/accessEgress Enum keys: not-set | walk | bike | bike-to-park | bike-rental | scooter-rental | car | car-to-park | car-pickup | car-rental | car-hailing | flexible

    Penalty for access/egress by street mode.

    Use this to add a time and cost penalty to an access/egress legs for a given street mode. This will favour other street-modes and transit. This has a performance penalty, since the search-window is increased with the same amount as the maximum penalty for the access legs used. In other cases where the access(CAR) is faster than transit the performance will be better.

    The default values are

    Example: \"car-to-park\" : { \"timePenalty\": \"10m + 1.5t\", \"costFactor\": 2.5 }

    Time penalty

    The timePenalty is used to add a penalty to the access/egress duration/time. The time including the penalty is used in the algorithm when comparing paths, but the actual duration is used when presented to the end user.

    Cost factor

    The costFactor is used to add an additional cost to the leg\u00b4s generalized-cost. The time-penalty is multiplied with the cost-factor. A cost-factor of zero, gives no extra cost, while 1.0 will add the same amount to both time and cost.

    "},{"location":"RouteRequest/#rd_alightSlackForMode","title":"alightSlackForMode","text":"

    Since version: 2.0 \u2219 Type: enum map of duration \u2219 Cardinality: Optional Path: /routingDefaults Enum keys: rail | coach | subway | bus | tram | ferry | airplane | cable-car | gondola | funicular | trolleybus | monorail | carpool | taxi

    How much extra time should be given when alighting a vehicle for each given mode.

    Sometimes there is a need to configure a longer alighting times for specific modes, such as airplanes or ferries.

    "},{"location":"RouteRequest/#rd_bicycle_boardCost","title":"boardCost","text":"

    Since version: 2.0 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 600 Path: /routingDefaults/bicycle

    Prevents unnecessary transfers by adding a cost for boarding a transit vehicle.

    This is the cost that is used when boarding while cycling. This is usually higher that walkBoardCost.

    "},{"location":"RouteRequest/#rd_bicycle_optimization","title":"optimization","text":"

    Since version: 2.0 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"safe-streets\" Path: /routingDefaults/bicycle Enum values: shortest-duration | safe-streets | flat-streets | safest-streets | triangle

    The set of characteristics that the user wants to optimize for.

    If the triangle optimization is used, it's enough to just define the triangle parameters

    "},{"location":"RouteRequest/#rd_bicycle_parking_unpreferredVehicleParkingTagCost","title":"unpreferredVehicleParkingTagCost","text":"

    Since version: 2.3 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 300 Path: /routingDefaults/bicycle/parking

    What cost to add if a parking facility doesn't contain a preferred tag.

    See preferredVehicleParkingTags.

    "},{"location":"RouteRequest/#rd_bicycle_parking_bannedVehicleParkingTags","title":"bannedVehicleParkingTags","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/bicycle/parking

    Tags with which a vehicle parking will not be used. If empty, no tags are banned.

    Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed).

    "},{"location":"RouteRequest/#rd_bicycle_parking_preferredVehicleParkingTags","title":"preferredVehicleParkingTags","text":"

    Since version: 2.3 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/bicycle/parking

    Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised.

    Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed).

    "},{"location":"RouteRequest/#rd_bicycle_parking_requiredVehicleParkingTags","title":"requiredVehicleParkingTags","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/bicycle/parking

    Tags without which a vehicle parking will not be used. If empty, no tags are required.

    Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed).

    "},{"location":"RouteRequest/#rd_bicycle_rental_allowedNetworks","title":"allowedNetworks","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/bicycle/rental

    The vehicle rental networks which may be used. If empty all networks may be used.

    "},{"location":"RouteRequest/#rd_bicycle_rental_bannedNetworks","title":"bannedNetworks","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/bicycle/rental

    The vehicle rental networks which may not be used. If empty, no networks are banned.

    "},{"location":"RouteRequest/#rd_bicycle_triangle","title":"triangle","text":"

    Since version: 2.5 \u2219 Type: object \u2219 Cardinality: Optional Path: /routingDefaults/bicycle

    Triangle optimization criteria.

    Optimization type doesn't need to be defined if these values are defined.

    "},{"location":"RouteRequest/#rd_bicycle_triangle_safety","title":"safety","text":"

    Since version: 2.0 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.0 Path: /routingDefaults/bicycle/triangle

    Relative importance of safety (range 0-1).

    This factor can also include other concerns such as convenience and general cyclist preferences by taking into account road surface etc.

    "},{"location":"RouteRequest/#rd_bicycle_walk_mountDismountCost","title":"mountDismountCost","text":"

    Since version: 2.0 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 0 Path: /routingDefaults/bicycle/walk

    The cost of hopping on or off a vehicle.

    There are different parameters for the cost of renting or parking a vehicle and this is not meant for controlling the cost of those events.

    "},{"location":"RouteRequest/#rd_bicycle_walk_mountDismountTime","title":"mountDismountTime","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT0S\" Path: /routingDefaults/bicycle/walk

    The time it takes the user to hop on or off a vehicle.

    Time it takes to rent or park a vehicle have their own parameters and this is not meant for controlling the duration of those events.

    "},{"location":"RouteRequest/#rd_boardSlackForMode","title":"boardSlackForMode","text":"

    Since version: 2.0 \u2219 Type: enum map of duration \u2219 Cardinality: Optional Path: /routingDefaults Enum keys: rail | coach | subway | bus | tram | ferry | airplane | cable-car | gondola | funicular | trolleybus | monorail | carpool | taxi

    How much extra time should be given when boarding a vehicle for each given mode.

    Sometimes there is a need to configure a board times for specific modes, such as airplanes or ferries, where the check-in process needs to be done in good time before ride.

    "},{"location":"RouteRequest/#rd_car_parking_unpreferredVehicleParkingTagCost","title":"unpreferredVehicleParkingTagCost","text":"

    Since version: 2.3 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 300 Path: /routingDefaults/car/parking

    What cost to add if a parking facility doesn't contain a preferred tag.

    See preferredVehicleParkingTags.

    "},{"location":"RouteRequest/#rd_car_parking_bannedVehicleParkingTags","title":"bannedVehicleParkingTags","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/car/parking

    Tags with which a vehicle parking will not be used. If empty, no tags are banned.

    Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed).

    "},{"location":"RouteRequest/#rd_car_parking_preferredVehicleParkingTags","title":"preferredVehicleParkingTags","text":"

    Since version: 2.3 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/car/parking

    Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised.

    Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed).

    "},{"location":"RouteRequest/#rd_car_parking_requiredVehicleParkingTags","title":"requiredVehicleParkingTags","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/car/parking

    Tags without which a vehicle parking will not be used. If empty, no tags are required.

    Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed).

    "},{"location":"RouteRequest/#rd_car_rental_allowedNetworks","title":"allowedNetworks","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/car/rental

    The vehicle rental networks which may be used. If empty all networks may be used.

    "},{"location":"RouteRequest/#rd_car_rental_bannedNetworks","title":"bannedNetworks","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/car/rental

    The vehicle rental networks which may not be used. If empty, no networks are banned.

    "},{"location":"RouteRequest/#rd_itineraryFilters","title":"itineraryFilters","text":"

    Since version: 2.0 \u2219 Type: object \u2219 Cardinality: Optional Path: /routingDefaults

    Configure itinerary filters that may modify itineraries, sort them, and filter away less preferable results.

    The purpose of the itinerary filter chain is to post process the result returned by the routing search. The filters may modify itineraries, sort them, and filter away less preferable results.

    OTP2 may produce numerous pareto-optimal results when using time, number-of-transfers and generalized-cost as criteria. Use the parameters listed here to reduce/filter the itineraries return by the search engine before returning the results to client. There is also a few mandatory non-configurable filters removing none optimal results. You may see these filters pop-up in the filter debugging.

    "},{"location":"RouteRequest/#group-by-similarity-filters","title":"Group by similarity filters","text":"

    The group-by-filter is a bit complex, but should be simple to use. Set debug=true and experiment with searchWindow and the three group-by parameters(groupSimilarityKeepOne, groupSimilarityKeepThree and groupedOtherThanSameLegsMaxCostMultiplier).

    The group-by-filter work by grouping itineraries together and then reducing the number of 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 larger 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.

    The grouped itineraries can be further reduced by using groupedOtherThanSameLegsMaxCostMultiplier. This parameter filters out itineraries, where the legs that are not common for all the grouped 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.

    "},{"location":"RouteRequest/#rd_if_accessibilityScore","title":"accessibilityScore","text":"

    Since version: 2.2 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /routingDefaults/itineraryFilters

    An experimental feature contributed by IBI which adds a sandbox accessibility score between 0 and 1 for each leg and itinerary.

    This can be used by frontend developers to implement a simple traffic light UI.

    "},{"location":"RouteRequest/#rd_if_bikeRentalDistanceRatio","title":"bikeRentalDistanceRatio","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.0 Path: /routingDefaults/itineraryFilters

    Filter routes that consist of bike-rental and walking by the minimum fraction of the bike-rental leg using distance.

    This filters out results that consist of a long walk plus a relatively short bike rental leg. A value of 0.3 means that a minimum of 30% of the total distance must be spent on the bike in order for the result to be included.

    "},{"location":"RouteRequest/#rd_if_debug","title":"debug","text":"

    Since version: 2.0 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"off\" Path: /routingDefaults/itineraryFilters Enum values: off | list-all | limit-to-search-window | limit-to-num-of-itineraries

    Enable this to attach a system notice to itineraries instead of removing them. This is very convenient when tuning the itinerary-filter-chain.

    "},{"location":"RouteRequest/#rd_if_filterDirectFlexBySearchWindow","title":"filterDirectFlexBySearchWindow","text":"

    Since version: 2.7 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: true Path: /routingDefaults/itineraryFilters

    Filter direct flex results by the search window. The search-window is not used during flex routing, but we use one end to align it with transit results.

    When direct flex is mixed with a transit search in the same request, then the direct flex results are filtered by the search window of the transit results.

    Depart-at searches are filtered by latest-arrival-time and arrive-by searches are filtered by earliest-departure-time.

    Use this configuration to turn this feature off.

    "},{"location":"RouteRequest/#rd_if_filterItinerariesWithSameFirstOrLastTrip","title":"filterItinerariesWithSameFirstOrLastTrip","text":"

    Since version: 2.2 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /routingDefaults/itineraryFilters

    If more than one itinerary begins or ends with same trip, filter out one of those itineraries so that only one remains.

    Trips are considered equal if they have same id and same service day. Non-transit legs are skipped during comparison. Before filtering, trips are sorted by their generalized cost. The algorithm loops through the list from top to bottom. If an itinerary matches from any other itinerary from above, it is removed from list.

    "},{"location":"RouteRequest/#rd_if_groupedOtherThanSameLegsMaxCostMultiplier","title":"groupedOtherThanSameLegsMaxCostMultiplier","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 2.0 Path: /routingDefaults/itineraryFilters

    Filter grouped itineraries, where the non-grouped legs are more expensive than in the lowest cost one.

    Of the itineraries grouped to maximum of three itineraries, how much worse can the non-grouped legs be compared to the lowest cost. 2.0 means that they can be double the cost, and any itineraries having a higher cost will be filtered.

    "},{"location":"RouteRequest/#rd_if_minBikeParkingDistance","title":"minBikeParkingDistance","text":"

    Since version: 2.3 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.0 Path: /routingDefaults/itineraryFilters

    Filter out bike park+ride results that have fewer meters of cycling than this value.

    Useful if you want to exclude those routes which have only a few meters of cycling before parking the bike and taking public transport.

    "},{"location":"RouteRequest/#rd_if_nonTransitGeneralizedCostLimit","title":"nonTransitGeneralizedCostLimit","text":"

    Since version: 2.1 \u2219 Type: cost-linear-function \u2219 Cardinality: Optional \u2219 Default value: \"1h + 2.0 t\" Path: /routingDefaults/itineraryFilters

    The function define a max-limit for generalized-cost for non-transit itineraries.

    The max-limit is applied to itineraries with no transit legs, however all itineraries (including those with transit legs) are considered when calculating the minimum cost. The smallest generalized-cost value is used as input to the function. The function is used to calculate a max-limit. The max-limit is then used to filter non-transit itineraries by generalized-cost. Itineraries with a cost higher than the max-limit are dropped from the result set.

    For example if the function is f(x) = 30m + 2.0 x and the smallest cost is 30m = 1800s, then all non-transit itineraries with a cost larger than 1800 + 2 * 5000 = 11 800 are dropped.

    "},{"location":"RouteRequest/#rd_if_parkAndRideDurationRatio","title":"parkAndRideDurationRatio","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.0 Path: /routingDefaults/itineraryFilters

    Filter P+R routes that consist of driving and walking by the minimum fraction of the driving using of time.

    This filters out results that consist of driving plus a very long walk leg at the end. A value of 0.3 means that a minimum of 30% of the total time must be spent in the car in order for the result to be included. However, if there is only a single result, it is never filtered.

    "},{"location":"RouteRequest/#rd_if_removeItinerariesWithSameRoutesAndStops","title":"removeItinerariesWithSameRoutesAndStops","text":"

    Since version: 2.2 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /routingDefaults/itineraryFilters

    Set to true if you want to list only the first itinerary which goes through the same stops and routes.

    Itineraries visiting the same set of stops and riding the exact same routes, departing later are removed from the result.

    "},{"location":"RouteRequest/#rd_if_removeTransitWithHigherCostThanBestOnStreetOnly","title":"removeTransitWithHigherCostThanBestOnStreetOnly","text":"

    Since version: 2.4 \u2219 Type: cost-linear-function \u2219 Cardinality: Optional \u2219 Default value: \"1m + 1.30 t\" Path: /routingDefaults/itineraryFilters

    Limit function for generalized-cost computed from street-only itineries applied to transit itineraries.

    The max-limit is applied to itineraries with transit legs, and only itineraries without transit legs are considered when calculating the minimum cost. The smallest generalized-cost value is used as input to the function. The function is used to calculate a max-limit. The max-limit is then used to filter transit itineraries by generalized-cost. Itineraries with a cost higher than the max-limit are dropped from the result set. Walking is handled with a different logic: if a transit itinerary has higher cost than a plain walk itinerary, it will be removed even if the cost limit function would keep it.

    "},{"location":"RouteRequest/#rd_if_transitGeneralizedCostLimit","title":"transitGeneralizedCostLimit","text":"

    Since version: 2.1 \u2219 Type: object \u2219 Cardinality: Optional Path: /routingDefaults/itineraryFilters

    A relative limit for the generalized-cost for transit itineraries.

    The filter compares all itineraries against every other itinerary. If the generalized-cost plus a transitGeneralizedCostLimit is higher than the other generalized-cost, then the itinerary is dropped. The transitGeneralizedCostLimit is calculated using the costLimitFunction plus a relative cost for the distance in time between the itineraries. The relative cost is the intervalRelaxFactor multiplied with the interval in seconds. To set the costLimitFunction to be 1 hour plus 2 times cost use: 3600 + 2.0 x. To set an absolute value(3000s) use: 3000 + 0x

    "},{"location":"RouteRequest/#rd_if_transitGeneralizedCostLimit_costLimitFunction","title":"costLimitFunction","text":"

    Since version: 2.2 \u2219 Type: cost-linear-function \u2219 Cardinality: Optional \u2219 Default value: \"15m + 1.50 t\" Path: /routingDefaults/itineraryFilters/transitGeneralizedCostLimit

    The base function used by the filter.

    This function calculates the threshold for the filter, when the itineraries have exactly the same arrival and departure times.

    "},{"location":"RouteRequest/#rd_if_transitGeneralizedCostLimit_intervalRelaxFactor","title":"intervalRelaxFactor","text":"

    Since version: 2.2 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.4 Path: /routingDefaults/itineraryFilters/transitGeneralizedCostLimit

    How much the filter should be relaxed for itineraries that do not overlap in time.

    This value is used to increase the filter threshold for itineraries further away in time, compared to those, that have exactly the same arrival and departure times.

    The unit is cost unit per second of time difference.

    "},{"location":"RouteRequest/#rd_maxDirectStreetDurationForMode","title":"maxDirectStreetDurationForMode","text":"

    Since version: 2.2 \u2219 Type: enum map of duration \u2219 Cardinality: Optional Path: /routingDefaults Enum keys: not-set | walk | bike | bike-to-park | bike-rental | scooter-rental | car | car-to-park | car-pickup | car-rental | car-hailing | flexible

    Limit direct route duration per street mode.

    Override the settings in maxDirectStreetDuration for specific street modes. This is done because some street modes searches are much more resource intensive than others.

    "},{"location":"RouteRequest/#rd_scooter_optimization","title":"optimization","text":"

    Since version: 2.0 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"safe-streets\" Path: /routingDefaults/scooter Enum values: shortest-duration | safe-streets | flat-streets | safest-streets | triangle

    The set of characteristics that the user wants to optimize for.

    If the triangle optimization is used, it's enough to just define the triangle parameters

    "},{"location":"RouteRequest/#rd_scooter_rental_allowedNetworks","title":"allowedNetworks","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/scooter/rental

    The vehicle rental networks which may be used. If empty all networks may be used.

    "},{"location":"RouteRequest/#rd_scooter_rental_bannedNetworks","title":"bannedNetworks","text":"

    Since version: 2.1 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /routingDefaults/scooter/rental

    The vehicle rental networks which may not be used. If empty, no networks are banned.

    "},{"location":"RouteRequest/#rd_scooter_triangle","title":"triangle","text":"

    Since version: 2.5 \u2219 Type: object \u2219 Cardinality: Optional Path: /routingDefaults/scooter

    Triangle optimization criteria.

    Optimization type doesn't need to be defined if these values are defined.

    "},{"location":"RouteRequest/#rd_scooter_triangle_safety","title":"safety","text":"

    Since version: 2.0 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.0 Path: /routingDefaults/scooter/triangle

    Relative importance of safety (range 0-1).

    This factor can also include other concerns such as convenience and general cyclist preferences by taking into account road surface etc.

    "},{"location":"RouteRequest/#rd_transferOptimization","title":"transferOptimization","text":"

    Since version: 2.1 \u2219 Type: object \u2219 Cardinality: Optional Path: /routingDefaults

    Optimize where a transfer between to trip happens.

    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 is done after the Raptor search and before the paths are passed to the itinerary-filter-chain.

    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).

    The optimized transfer service will try to, in order:

    1. Use transfer priority. This includes stay-seated and guaranteed transfers.
    2. Use the transfers with the best distribution of the wait-time, and avoid very short transfers.
    3. Avoid back-travel
    4. Boost stop-priority to select preferred and recommended stops.

    If two paths have the same transfer priority level, then we break the tie by looking at waiting times. The goal is to maximize the wait-time for each stop, avoiding situations where there is little time available to make the transfer. This is balanced with the generalized-cost. The cost is adjusted with a new cost for wait-time (optimized-wait-time-cost).

    The defaults should work fine, but if you have results with short wait-times dominating a better option or \"back-travel\", then try to increase the minSafeWaitTimeFactor, backTravelWaitTimeFactor and/or extraStopBoardAlightCostsFactor.

    For details on the logic/design see transfer optimization package documentation.

    "},{"location":"RouteRequest/#rd_to_backTravelWaitTimeFactor","title":"backTravelWaitTimeFactor","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 1.0 Path: /routingDefaults/transferOptimization

    To reduce back-travel we favor waiting, this reduces the cost of waiting.

    The wait time is used to prevent back-travel, the backTravelWaitTimeFactor is multiplied with the wait-time and subtracted from the optimized-transfer-cost.

    "},{"location":"RouteRequest/#rd_to_extraStopBoardAlightCostsFactor","title":"extraStopBoardAlightCostsFactor","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.0 Path: /routingDefaults/transferOptimization

    Add an extra board- and alight-cost for prioritized stops.

    A stopBoardAlightTransferCosts is added to the generalized-cost during routing. But this cost cannot be too high, because that would add extra cost to the transfer, and favor other alternative paths. But, when optimizing transfers, we do not have to take other paths into consideration and can boost the stop-priority-cost to allow transfers to take place at a preferred stop. The cost added during routing is already added to the generalized-cost used as a base in the optimized transfer calculation. By setting this parameter to 0, no extra cost is added, by setting it to 1.0 the stop-cost is doubled. Stop priority is only supported by the NeTEx import, not GTFS.

    "},{"location":"RouteRequest/#rd_to_minSafeWaitTimeFactor","title":"minSafeWaitTimeFactor","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 5.0 Path: /routingDefaults/transferOptimization

    Used to set a maximum wait-time cost, base on min-safe-transfer-time.

    This defines the maximum cost for the logarithmic function relative to the min-safe-transfer-time (t0) when wait time goes towards zero(0). f(0) = n * t0

    "},{"location":"RouteRequest/#rd_to_optimizeTransferWaitTime","title":"optimizeTransferWaitTime","text":"

    Since version: 2.1 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: true Path: /routingDefaults/transferOptimization

    This enables the transfer wait time optimization.

    If not enabled generalizedCost function is used to pick the optimal transfer point.

    "},{"location":"RouteRequest/#rd_transitGroupPriority","title":"transitGroupPriority","text":"

    Since version: 2.5 \u2219 Type: object \u2219 Cardinality: Optional Path: /routingDefaults

    Group transit patterns and give each group a mutual advantage in the Raptor search.

    Use this to separate transit patterns into groups. Each group will be given a group-id. A path (multiple legs) will then have a set of group-ids based on the group-id from each leg. Hence, two paths with a different set of group-ids will BOTH be optimal unless the cost is worse than the relaxation specified in the relaxTransitGroupPriority parameter. This is only available in the TransmodelAPI for now.

    Unmatched patterns are put in the BASE priority-group.

    THIS IS STILL AN EXPERIMENTAL FEATURE - IT MAY CHANGE WITHOUT ANY NOTICE!

    "},{"location":"RouteRequest/#rd_transitReluctanceForMode","title":"transitReluctanceForMode","text":"

    Since version: 2.1 \u2219 Type: enum map of double \u2219 Cardinality: Optional Path: /routingDefaults Enum keys: rail | coach | subway | bus | tram | ferry | airplane | cable-car | gondola | funicular | trolleybus | monorail | carpool | taxi

    Transit reluctance for a given transport mode

    "},{"location":"RouteRequest/#rd_unpreferred","title":"unpreferred","text":"

    Since version: 2.2 \u2219 Type: object \u2219 Cardinality: Optional Path: /routingDefaults

    Parameters listing authorities or lines that preferably should not be used in trip patters.

    A cost is applied to boarding nonpreferred authorities or routes.

    The routing engine will add extra penalty - on the unpreferred routes and/or agencies using a cost function. The cost function (unpreferredCost) is defined as a linear function of the form A + B x, where A is a fixed cost (in seconds) and B is reluctance multiplier for transit leg travel time x (in seconds).

    "},{"location":"RouteRequest/#rd_unpreferred_agencies","title":"agencies","text":"

    Since version: 2.2 \u2219 Type: feed-scoped-id[] \u2219 Cardinality: Optional Path: /routingDefaults/unpreferred

    The ids of the agencies that incur an extra cost when being used. Format: FeedId:AgencyId

    How much cost is added is configured in unpreferredCost.

    "},{"location":"RouteRequest/#rd_unpreferred_routes","title":"routes","text":"

    Since version: 2.2 \u2219 Type: feed-scoped-id[] \u2219 Cardinality: Optional Path: /routingDefaults/unpreferred

    The ids of the routes that incur an extra cost when being used. Format: FeedId:RouteId

    How much cost is added is configured in unpreferredCost.

    "},{"location":"RouteRequest/#rd_walk_reluctance","title":"reluctance","text":"

    Since version: 2.0 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 2.0 Path: /routingDefaults/walk

    A multiplier for how bad walking is, compared to being in transit for equal lengths of time.

    Empirically, values between 2 and 4 seem to correspond well to the concept of not wanting to walk too much without asking for totally ridiculous itineraries, but this observation should in no way be taken as scientific or definitive. Your mileage may vary. See https://github.com/opentripplanner/OpenTripPlanner/issues/4090 for impact on performance with high values.

    "},{"location":"RouteRequest/#rd_walk_safetyFactor","title":"safetyFactor","text":"

    Since version: 2.2 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 1.0 Path: /routingDefaults/walk

    Factor for how much the walk safety is considered in routing.

    Value should be between 0 and 1. If the value is set to be 0, safety is ignored.

    "},{"location":"RouteRequest/#rd_walk_stairsTimeFactor","title":"stairsTimeFactor","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 3.0 Path: /routingDefaults/walk

    How much more time does it take to walk a flight of stairs compared to walking a similar horizontal length.

    Default value is based on: Fujiyama, T., & Tyler, N. (2010). Predicting the walking speed of pedestrians on stairs. Transportation Planning and Technology, 33(2), 177\u2013202.

    "},{"location":"RouteRequest/#rd_wheelchairAccessibility_maxSlope","title":"maxSlope","text":"

    Since version: 2.0 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.083 Path: /routingDefaults/wheelchairAccessibility

    The maximum slope as a fraction of 1.

    9 percent would be 0.09

    "},{"location":"RouteRequest/#rd_wheelchairAccessibility_slopeExceededReluctance","title":"slopeExceededReluctance","text":"

    Since version: 2.2 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 1.0 Path: /routingDefaults/wheelchairAccessibility

    How much streets with high slope should be avoided.

    What factor should be given to street edges, which are over the max slope. The penalty is not static but scales with how much you exceed the maximum slope. Set to negative to disable routing on too steep edges.

    "},{"location":"RouteRequest/#rd_wheelchairAccessibility_stairsReluctance","title":"stairsReluctance","text":"

    Since version: 2.2 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 100.0 Path: /routingDefaults/wheelchairAccessibility

    How much stairs should be avoided.

    Stairs are not completely excluded for wheelchair users but severely punished. This value determines how much they are punished. This should be a very high value as you want to only include stairs as a last result.

    "},{"location":"RouteRequest/#config-example","title":"Config Example","text":"
    // router-config.json\n{\n  \"routingDefaults\" : {\n    \"numItineraries\" : 12,\n    \"transferPenalty\" : 0,\n    \"turnReluctance\" : 1.0,\n    \"elevatorBoardTime\" : 90,\n    \"elevatorBoardCost\" : 90,\n    \"elevatorHopTime\" : 20,\n    \"elevatorHopCost\" : 20,\n    \"bicycle\" : {\n      \"speed\" : 5,\n      \"reluctance\" : 5.0,\n      \"boardCost\" : 600,\n      \"walk\" : {\n        \"reluctance\" : 10.0,\n        \"stairsReluctance\" : 150.0\n      },\n      \"rental\" : {\n        \"pickupCost\" : 120,\n        \"dropOffTime\" : \"30s\",\n        \"dropOffCost\" : 30\n      },\n      \"parking\" : {\n        \"time\" : \"1m\",\n        \"cost\" : 120\n      },\n      \"triangle\" : {\n        \"safety\" : 0.4,\n        \"flatness\" : 0.3,\n        \"time\" : 0.3\n      }\n    },\n    \"car\" : {\n      \"reluctance\" : 10,\n      \"decelerationSpeed\" : 2.9,\n      \"accelerationSpeed\" : 2.9,\n      \"rental\" : {\n        \"pickupCost\" : 120,\n        \"dropOffTime\" : \"30s\",\n        \"dropOffCost\" : 30\n      },\n      \"parking\" : {\n        \"time\" : \"5m\",\n        \"cost\" : 600\n      }\n    },\n    \"scooter\" : {\n      \"speed\" : 5,\n      \"reluctance\" : 5.0,\n      \"rental\" : {\n        \"pickupCost\" : 120,\n        \"dropOffTime\" : \"30s\",\n        \"dropOffCost\" : 30\n      },\n      \"triangle\" : {\n        \"safety\" : 0.4,\n        \"flatness\" : 0.3,\n        \"time\" : 0.3\n      }\n    },\n    \"walk\" : {\n      \"speed\" : 1.3,\n      \"reluctance\" : 4.0,\n      \"stairsReluctance\" : 1.65,\n      \"boardCost\" : 600,\n      \"escalatorReluctance\" : 1.5\n    },\n    \"waitReluctance\" : 1.0,\n    \"otherThanPreferredRoutesPenalty\" : 300,\n    \"transferSlack\" : \"2m\",\n    \"boardSlackForMode\" : {\n      \"AIRPLANE\" : \"35m\"\n    },\n    \"alightSlackForMode\" : {\n      \"AIRPLANE\" : \"15m\"\n    },\n    \"transitReluctanceForMode\" : {\n      \"RAIL\" : 0.85\n    },\n    \"accessEgress\" : {\n      \"maxDuration\" : \"45m\",\n      \"maxDurationForMode\" : {\n        \"BIKE_RENTAL\" : \"20m\"\n      },\n      \"maxStopCount\" : 500,\n      \"penalty\" : {\n        \"FLEXIBLE\" : {\n          \"timePenalty\" : \"2m + 1.1t\",\n          \"costFactor\" : 1.7\n        }\n      }\n    },\n    \"itineraryFilters\" : {\n      \"transitGeneralizedCostLimit\" : {\n        \"costLimitFunction\" : \"15m + 1.5 x\",\n        \"intervalRelaxFactor\" : 0.4\n      },\n      \"nonTransitGeneralizedCostLimit\" : \"400 + 1.5x\",\n      \"removeTransitWithHigherCostThanBestOnStreetOnly\" : \"60 + 1.3x\",\n      \"bikeRentalDistanceRatio\" : 0.3,\n      \"accessibilityScore\" : true,\n      \"minBikeParkingDistance\" : 300,\n      \"debug\" : \"limit-to-search-window\"\n    },\n    \"ignoreRealtimeUpdates\" : false,\n    \"geoidElevation\" : false,\n    \"maxJourneyDuration\" : \"36h\",\n    \"unpreferred\" : {\n      \"agencies\" : [\n        \"HSL:123\"\n      ],\n      \"routes\" : [\n        \"HSL:456\"\n      ]\n    },\n    \"unpreferredCost\" : \"10m + 2.0 x\",\n    \"streetRoutingTimeout\" : \"5s\",\n    \"transferOptimization\" : {\n      \"optimizeTransferWaitTime\" : true,\n      \"minSafeWaitTimeFactor\" : 5.0,\n      \"backTravelWaitTimeFactor\" : 1.0,\n      \"extraStopBoardAlightCostsFactor\" : 8.0\n    },\n    \"wheelchairAccessibility\" : {\n      \"trip\" : {\n        \"onlyConsiderAccessible\" : false,\n        \"unknownCost\" : 600,\n        \"inaccessibleCost\" : 3600\n      },\n      \"stop\" : {\n        \"onlyConsiderAccessible\" : false,\n        \"unknownCost\" : 600,\n        \"inaccessibleCost\" : 3600\n      },\n      \"elevator\" : {\n        \"onlyConsiderAccessible\" : false,\n        \"unknownCost\" : 20,\n        \"inaccessibleCost\" : 3600\n      },\n      \"inaccessibleStreetReluctance\" : 25,\n      \"maxSlope\" : 0.083,\n      \"slopeExceededReluctance\" : 1,\n      \"stairsReluctance\" : 100\n    }\n  }\n}\n
    "},{"location":"RouterConfiguration/","title":"Router","text":""},{"location":"RouterConfiguration/#router-configuration","title":"Router configuration","text":"

    This section covers all options that can be set for each router using the router-config.json file. These options can be applied by the OTP server without rebuilding the graph.

    "},{"location":"RouterConfiguration/#configure-using-command-line-arguments","title":"Configure using command-line arguments","text":"

    Certain settings can be provided on the command line, when starting OpenTripPlanner. See the CommandLineParameters class for a full list of arguments .

    "},{"location":"RouterConfiguration/#routing-defaults","title":"Routing defaults","text":"

    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 RouteRequest.

    "},{"location":"RouterConfiguration/#parameter-summary","title":"Parameter Summary","text":"Config Parameter Type Summary Req./Opt. Default Value Since configVersion string Deployment version of the router-config.json. Optional 2.1 flex object Configuration for flex routing. Optional 2.1 rideHailingServices object[] Configuration for interfaces to external ride hailing services like Uber. Optional 2.3 routingDefaults object The default parameters for the routing query. Optional 2.0 server object Configuration for router server. Optional 2.4 apiProcessingTimeout duration Maximum processing time for an API request Optional \"PT-1S\" 2.4 traceParameters object[] Trace OTP request using HTTP request/response parameter(s) combined with logging. Optional 2.4 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0generateIdIfMissing boolean If true a unique value is generated if no http request header is provided, or the value is missing. Optional false 2.4 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0httpRequestHeader string The header-key to use when fetching the trace parameter value Optional 2.4 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0httpResponseHeader string The header-key to use when saving the value back into the http response Optional 2.4 logKey string The log event key used. Optional 2.4 timetableUpdates object Global configuration for timetable updaters. Optional 2.2 maxSnapshotFrequency duration How long a snapshot should be cached. Optional \"PT1S\" 2.2 \u00a0\u00a0\u00a0purgeExpiredData boolean Should expired real-time data be purged from the graph. Apply to GTFS-RT and Siri updates. Optional true 2.2 transit object Configuration for transit searches with RAPTOR. Optional na iterationDepartureStepInSeconds integer Step for departure times between each RangeRaptor iterations. Optional 60 na maxNumberOfTransfers integer This parameter is used to allocate enough memory space for Raptor. Optional 12 na maxSearchWindow duration Upper limit of the request parameter searchWindow. Optional \"PT24H\" 2.4 scheduledTripBinarySearchThreshold integer This threshold is used to determine when to perform a binary trip schedule search. Optional 50 na searchThreadPoolSize integer Split a travel search in smaller jobs and run them in parallel to improve performance. Optional 0 na transferCacheMaxSize integer The maximum number of distinct transfers parameters to cache pre-calculated transfers for. Optional 25 na dynamicSearchWindow object The dynamic search window coefficients used to calculate the EDT, LAT and SW. Optional 2.1 maxWindow duration Upper limit for the search-window calculation. Optional \"PT3H\" 2.2 minTransitTimeCoefficient double The coefficient to multiply with minTransitTime. Optional 0.5 2.1 minWaitTimeCoefficient double The coefficient to multiply with minWaitTime. Optional 0.5 2.1 minWindow duration The constant minimum duration for a raptor-search-window. Optional \"PT40M\" 2.2 stepMinutes integer Used to set the steps the search-window is rounded to. Optional 10 2.1 pagingSearchWindowAdjustments duration[] The provided array of durations is used to increase the search-window for the next/previous page. Optional na stopBoardAlightDuringTransferCost enum map of integer Costs for boarding and alighting during transfers at stops with a given transfer priority. Optional 2.0 transferCacheRequests object[] Routing requests to use for pre-filling the stop-to-stop transfer cache. Optional 2.3 transmodelApi object Configuration for the Transmodel GraphQL API. Optional 2.1 hideFeedId boolean Hide the FeedId in all API output, and add it to input. Optional false na maxNumberOfResultFields integer The maximum number of fields in a GraphQL result Optional 1000000 2.6 tracingHeaderTags string[] Used to group requests when monitoring OTP. Optional na updaters object[] Configuration for the updaters that import various types of data into OTP. Optional 1.5 vectorTiles object Vector tile configuration Optional na vehicleRentalServiceDirectory object Configuration for the vehicle rental service directory. Optional 2.0"},{"location":"RouterConfiguration/#parameter-details","title":"Parameter Details","text":""},{"location":"RouterConfiguration/#configVersion","title":"configVersion","text":"

    Since version: 2.1 \u2219 Type: string \u2219 Cardinality: Optional Path: /

    Deployment version of the router-config.json.

    The config-version is a parameter which each OTP deployment may set to be able to query the OTP server and verify that it uses the correct version of the config. The version should be injected into the config in the (continuous) deployment pipeline. How this is done, is up to the deployment.

    The config-version has no effect on OTP, and is provided as is on the API. There is no syntax or format check on the version and it can be any string.

    Be aware that OTP uses the config embedded in the loaded graph if no new config is provided.

    "},{"location":"RouterConfiguration/#server","title":"server","text":"

    Since version: 2.4 \u2219 Type: object \u2219 Cardinality: Optional Path: /

    Configuration for router server.

    These parameters are used to configure the router server. Many parameters are specific to a domain, these are set in the routing request.

    "},{"location":"RouterConfiguration/#server_apiProcessingTimeout","title":"apiProcessingTimeout","text":"

    Since version: 2.4 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT-1S\" Path: /server

    Maximum processing time for an API request

    This timeout limits the server-side processing time for a given API request. This does not include network latency nor waiting time in the HTTP server thread pool. The default value is -1s(no timeout). The timeout is applied to all APIs (REST, Transmodel & GTFS GraphQL). The timeout is not enforced when the parallel routing OTP feature is in use.

    "},{"location":"RouterConfiguration/#server_traceParameters","title":"traceParameters","text":"

    Since version: 2.4 \u2219 Type: object[] \u2219 Cardinality: Optional Path: /server

    Trace OTP request using HTTP request/response parameter(s) combined with logging.

    OTP supports tracing user requests across log events and \"outside\" services. OTP can insert http-request-header parameters into all associated log events and into the http response. If the value is not present in the request, a unique value can be generated. The OTP generated value is a 6 characters long base 36[0-9a-z] character string.

    Use-case Correlation-ID

    A common use-case in a service oriented environment is to use a correlation-id to identify all log messages across multiple (micro-)services from the same user. This is done by setting the \"X-Correlation-ID\" http header in the http facade/gateway. Use the \"traceParameters\" to configure OTP to pick up the correlation id, insert it into the logs and return it. See the example below on how-to configure the \"server.traceParameters\" instance.

    "},{"location":"RouterConfiguration/#server_traceParameters_0_logKey","title":"logKey","text":"

    Since version: 2.4 \u2219 Type: string \u2219 Cardinality: Optional Path: /server/traceParameters/[0]

    The log event key used.

    OTP stores the key/value pair in the log MDC(Mapped Diagnostic Context). To use it you normally include the key in the log pattern like this: %X{LOG-KEY}. See your log framework for details. Only log4j and logback support this.

    "},{"location":"RouterConfiguration/#timetableUpdates_maxSnapshotFrequency","title":"maxSnapshotFrequency","text":"

    Since version: 2.2 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT1S\" Path: /timetableUpdates

    How long a snapshot should be cached.

    If a timetable snapshot is requested less than this number of milliseconds after the previous snapshot, then return the same instance. Throttles the potentially resource-consuming task of duplicating a TripPattern \u2192 Timetable map and indexing the new Timetables. Applies to GTFS-RT and Siri updates.

    "},{"location":"RouterConfiguration/#transit","title":"transit","text":"

    Since version: na \u2219 Type: object \u2219 Cardinality: Optional Path: /

    Configuration for transit searches with RAPTOR.

    Some of these parameters for tuning transit routing are 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.

    "},{"location":"RouterConfiguration/#transit_iterationDepartureStepInSeconds","title":"iterationDepartureStepInSeconds","text":"

    Since version: na \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 60 Path: /transit

    Step for departure times between each RangeRaptor iterations.

    This is a performance optimization parameter. A transit network usually uses minute resolution for the timetables, so to match that, set this variable to 60 seconds. Setting it to less than 60 will not give better result, but degrade performance. Setting it to 120 seconds will improve performance, but you might get a slack of 60 seconds somewhere in the result.

    "},{"location":"RouterConfiguration/#transit_maxNumberOfTransfers","title":"maxNumberOfTransfers","text":"

    Since version: na \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 12 Path: /transit

    This parameter is used to allocate enough memory space for Raptor.

    Set it to the maximum number of transfers for any given itinerary expected to be found within the entire transit network. The memory overhead of setting this higher than the maximum number of transfers is very little so it is better to set it too high than to low.

    "},{"location":"RouterConfiguration/#transit_maxSearchWindow","title":"maxSearchWindow","text":"

    Since version: 2.4 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT24H\" Path: /transit

    Upper limit of the request parameter searchWindow.

    Maximum search window that can be set through the searchWindow API parameter. Due to the way timetable data are collected before a Raptor trip search, using a search window larger than 24 hours may lead to inconsistent search results. Limiting the search window prevents also potential performance issues. The recommended maximum value is 24 hours. This parameter does not restrict the maximum duration of a dynamic search window (use the parameter transit.dynamicSearchWindow.maxWindow to specify such a restriction).

    "},{"location":"RouterConfiguration/#transit_scheduledTripBinarySearchThreshold","title":"scheduledTripBinarySearchThreshold","text":"

    Since version: na \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 50 Path: /transit

    This threshold is used to determine when to perform a binary trip schedule search.

    This reduce the number of trips departure time lookups and comparisons. When testing with data from Entur and all of Norway as a Graph, the optimal value was about 50. If you calculate the departure time every time or want to fine tune the performance, changing this may improve the performance a few percents.

    "},{"location":"RouterConfiguration/#transit_searchThreadPoolSize","title":"searchThreadPoolSize","text":"

    Since version: na \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 0 Path: /transit

    Split a travel search in smaller jobs and run them in parallel to improve performance.

    Use this parameter to set the total number of executable threads available across all searches. Multiple searches can run in parallel - this parameter has no effect with regard to that. If 0, no extra threads are started and the search is done in one thread.

    "},{"location":"RouterConfiguration/#transit_transferCacheMaxSize","title":"transferCacheMaxSize","text":"

    Since version: na \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 25 Path: /transit

    The maximum number of distinct transfers parameters to cache pre-calculated transfers for.

    If too low, requests may be slower. If too high, more memory may be used then required.

    "},{"location":"RouterConfiguration/#transit_dynamicSearchWindow","title":"dynamicSearchWindow","text":"

    Since version: 2.1 \u2219 Type: object \u2219 Cardinality: Optional Path: /transit

    The dynamic search window coefficients used to calculate the EDT, LAT and SW.

    The dynamic search window coefficients is used to calculate EDT(earliest-departure-time), LAT(latest-arrival-time) and SW(raptor-search-window) request parameters using heuristics. The heuristics perform a Raptor search (one-iteration) to find a trip which we use to find a lower bound for the travel duration time - the \"minTransitTime\". The heuristic search is used for other purposes too, and is very fast.

    At least the EDT or the LAT must be passed into Raptor to perform a Range Raptor search. If unknown/missing the parameters(EDT, LAT, DW) are dynamically calculated. The dynamic coefficients affect the performance and should be tuned to match the deployment.

    The request parameters are calculated like this:

        DW  = round_N(C + T * minTransitTime + W * minWaitTime)\n    LAT = EDT + DW + minTransitTime\n    EDT = LAT - (DW + minTransitTime)\n

    The round_N(...) method rounds the input to the closest multiplication of N.

    The 3 coefficients above are:

    In addition there is an upper bound on the calculation of the search window: maxWindow.

    "},{"location":"RouterConfiguration/#transit_dynamicSearchWindow_maxWindow","title":"maxWindow","text":"

    Since version: 2.2 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT3H\" Path: /transit/dynamicSearchWindow

    Upper limit for the search-window calculation.

    Long search windows consume a lot of resources and may take a long time. Use this parameter to tune the desired maximum search time.

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

    "},{"location":"RouterConfiguration/#transit_dynamicSearchWindow_minTransitTimeCoefficient","title":"minTransitTimeCoefficient","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.5 Path: /transit/dynamicSearchWindow

    The coefficient to multiply with minTransitTime.

    Use a value between 0.0 and 3.0. Using 0.0 will eliminate the minTransitTime from the dynamic raptor-search-window calculation.

    "},{"location":"RouterConfiguration/#transit_dynamicSearchWindow_minWaitTimeCoefficient","title":"minWaitTimeCoefficient","text":"

    Since version: 2.1 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.5 Path: /transit/dynamicSearchWindow

    The coefficient to multiply with minWaitTime.

    Use a value between 0.0 and 1.0. Using 0.0 will eliminate the minWaitTime from the dynamic raptor-search-window calculation.

    "},{"location":"RouterConfiguration/#transit_dynamicSearchWindow_minWindow","title":"minWindow","text":"

    Since version: 2.2 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT40M\" Path: /transit/dynamicSearchWindow

    The constant minimum duration for a raptor-search-window.

    Use a value between 20 and 180 minutes in a normal deployment.

    "},{"location":"RouterConfiguration/#transit_dynamicSearchWindow_stepMinutes","title":"stepMinutes","text":"

    Since version: 2.1 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 10 Path: /transit/dynamicSearchWindow

    Used to set the steps the search-window is rounded to.

    The search window is rounded off to the closest multiplication of stepMinutes. If stepMinutes = 10 minutes, the search-window can be 10, 20, 30 ... minutes. It the computed search-window is 5 minutes and 17 seconds it will be rounded up to 10 minutes.

    Use a value between 1 and 60. This should be less than the min-raptor-search-window coefficient.

    "},{"location":"RouterConfiguration/#transit_pagingSearchWindowAdjustments","title":"pagingSearchWindowAdjustments","text":"

    Since version: na \u2219 Type: duration[] \u2219 Cardinality: Optional Path: /transit

    The provided array of durations is used to increase the search-window for the next/previous page.

    The search window is expanded when the current page return few options. If ZERO result is returned the first duration in the list is used, if ONE result is returned then the second duration is used and so on. The duration is added to the existing search-window and inserted into the next and previous page cursor. See JavaDoc for TransitTuningParameters#pagingSearchWindowAdjustments\" + for more info.\"

    "},{"location":"RouterConfiguration/#transit_stopBoardAlightDuringTransferCost","title":"stopBoardAlightDuringTransferCost","text":"

    Since version: 2.0 \u2219 Type: enum map of integer \u2219 Cardinality: Optional Path: /transit Enum keys: preferred | recommended | allowed | discouraged

    Costs for boarding and alighting during transfers at stops with a given transfer priority.

    This cost is applied both to boarding and alighting at stops during transfers. All stops have a transfer cost priority set, the default is allowed. The stopBoardAlightDuringTransferCost parameter is optional, but if listed all values must be set.

    When a transfer occurs at the same stop, the cost will be applied twice since the cost is both for boarding and alighting,

    If not set the stopBoardAlightDuringTransferCost is ignored. This is only available for NeTEx imported Stops.

    The cost is a scalar, but is equivalent to the felt cost of riding a transit trip for 1 second.

    Config key Description Type discouraged Use a very high cost like 72 000 to eliminate transfers at the stop if not the only option. int allowed Allowed, but not recommended. Use something like 150. int 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 stopBoardAlightDuringTransferCost is listed.

    "},{"location":"RouterConfiguration/#transit_transferCacheRequests","title":"transferCacheRequests","text":"

    Since version: 2.3 \u2219 Type: object[] \u2219 Cardinality: Optional Path: /transit \u2219 See: RouteRequest.md

    Routing requests to use for pre-filling the stop-to-stop transfer cache.

    If not set, the default behavior is to cache stop-to-stop transfers using the default route request (routingDefaults). Use this to change the default or specify more than one RouteRequest.

    Example

    // router-config.json\n{\n  \"transit\": {\n    \"transferCacheRequests\": [\n      { \"modes\": \"WALK\"                                                     },\n      { \"modes\": \"WALK\",    \"wheelchairAccessibility\": { \"enabled\": true  } }\n    ]\n  }\n}\n
    "},{"location":"RouterConfiguration/#transmodelApi_hideFeedId","title":"hideFeedId","text":"

    Since version: na \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /transmodelApi

    Hide the FeedId in all API output, and add it to input.

    Only turn this feature on if you have unique ids across all feeds, without the feedId prefix.

    "},{"location":"RouterConfiguration/#transmodelApi_maxNumberOfResultFields","title":"maxNumberOfResultFields","text":"

    Since version: 2.6 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 1000000 Path: /transmodelApi

    The maximum number of fields in a GraphQL result

    Enforce rate limiting based on query complexity; Queries that return too much data are cancelled.

    "},{"location":"RouterConfiguration/#transmodelApi_tracingHeaderTags","title":"tracingHeaderTags","text":"

    Since version: na \u2219 Type: string[] \u2219 Cardinality: Optional Path: /transmodelApi

    Used to group requests when monitoring OTP.

    "},{"location":"RouterConfiguration/#router-config-example","title":"Router Config Example","text":"
    // router-config.json\n{\n  \"configVersion\" : \"v2.4.0-EN000121\",\n  \"server\" : {\n    \"apiProcessingTimeout\" : \"7s\",\n    \"traceParameters\" : [\n      {\n        \"httpRequestHeader\" : \"X-Correlation-ID\",\n        \"httpResponseHeader\" : \"X-Correlation-ID\",\n        \"logKey\" : \"correlationId\",\n        \"generateIdIfMissing\" : true\n      }\n    ]\n  },\n  \"routingDefaults\" : {\n    \"numItineraries\" : 12,\n    \"transferPenalty\" : 0,\n    \"turnReluctance\" : 1.0,\n    \"elevatorBoardTime\" : 90,\n    \"elevatorBoardCost\" : 90,\n    \"elevatorHopTime\" : 20,\n    \"elevatorHopCost\" : 20,\n    \"bicycle\" : {\n      \"speed\" : 5,\n      \"reluctance\" : 5.0,\n      \"boardCost\" : 600,\n      \"walk\" : {\n        \"reluctance\" : 10.0,\n        \"stairsReluctance\" : 150.0\n      },\n      \"rental\" : {\n        \"pickupCost\" : 120,\n        \"dropOffTime\" : \"30s\",\n        \"dropOffCost\" : 30\n      },\n      \"parking\" : {\n        \"time\" : \"1m\",\n        \"cost\" : 120\n      },\n      \"triangle\" : {\n        \"safety\" : 0.4,\n        \"flatness\" : 0.3,\n        \"time\" : 0.3\n      }\n    },\n    \"car\" : {\n      \"reluctance\" : 10,\n      \"decelerationSpeed\" : 2.9,\n      \"accelerationSpeed\" : 2.9,\n      \"rental\" : {\n        \"pickupCost\" : 120,\n        \"dropOffTime\" : \"30s\",\n        \"dropOffCost\" : 30\n      },\n      \"parking\" : {\n        \"time\" : \"5m\",\n        \"cost\" : 600\n      }\n    },\n    \"scooter\" : {\n      \"speed\" : 5,\n      \"reluctance\" : 5.0,\n      \"rental\" : {\n        \"pickupCost\" : 120,\n        \"dropOffTime\" : \"30s\",\n        \"dropOffCost\" : 30\n      },\n      \"triangle\" : {\n        \"safety\" : 0.4,\n        \"flatness\" : 0.3,\n        \"time\" : 0.3\n      }\n    },\n    \"walk\" : {\n      \"speed\" : 1.3,\n      \"reluctance\" : 4.0,\n      \"stairsReluctance\" : 1.65,\n      \"boardCost\" : 600,\n      \"escalatorReluctance\" : 1.5\n    },\n    \"waitReluctance\" : 1.0,\n    \"otherThanPreferredRoutesPenalty\" : 300,\n    \"transferSlack\" : \"2m\",\n    \"boardSlackForMode\" : {\n      \"AIRPLANE\" : \"35m\"\n    },\n    \"alightSlackForMode\" : {\n      \"AIRPLANE\" : \"15m\"\n    },\n    \"transitReluctanceForMode\" : {\n      \"RAIL\" : 0.85\n    },\n    \"accessEgress\" : {\n      \"maxDuration\" : \"45m\",\n      \"maxDurationForMode\" : {\n        \"BIKE_RENTAL\" : \"20m\"\n      },\n      \"maxStopCount\" : 500,\n      \"penalty\" : {\n        \"FLEXIBLE\" : {\n          \"timePenalty\" : \"2m + 1.1t\",\n          \"costFactor\" : 1.7\n        }\n      }\n    },\n    \"itineraryFilters\" : {\n      \"transitGeneralizedCostLimit\" : {\n        \"costLimitFunction\" : \"15m + 1.5 x\",\n        \"intervalRelaxFactor\" : 0.4\n      },\n      \"nonTransitGeneralizedCostLimit\" : \"400 + 1.5x\",\n      \"removeTransitWithHigherCostThanBestOnStreetOnly\" : \"60 + 1.3x\",\n      \"bikeRentalDistanceRatio\" : 0.3,\n      \"accessibilityScore\" : true,\n      \"minBikeParkingDistance\" : 300,\n      \"debug\" : \"limit-to-search-window\"\n    },\n    \"ignoreRealtimeUpdates\" : false,\n    \"geoidElevation\" : false,\n    \"maxJourneyDuration\" : \"36h\",\n    \"unpreferred\" : {\n      \"agencies\" : [\n        \"HSL:123\"\n      ],\n      \"routes\" : [\n        \"HSL:456\"\n      ]\n    },\n    \"unpreferredCost\" : \"10m + 2.0 x\",\n    \"streetRoutingTimeout\" : \"5s\",\n    \"transferOptimization\" : {\n      \"optimizeTransferWaitTime\" : true,\n      \"minSafeWaitTimeFactor\" : 5.0,\n      \"backTravelWaitTimeFactor\" : 1.0,\n      \"extraStopBoardAlightCostsFactor\" : 8.0\n    },\n    \"wheelchairAccessibility\" : {\n      \"trip\" : {\n        \"onlyConsiderAccessible\" : false,\n        \"unknownCost\" : 600,\n        \"inaccessibleCost\" : 3600\n      },\n      \"stop\" : {\n        \"onlyConsiderAccessible\" : false,\n        \"unknownCost\" : 600,\n        \"inaccessibleCost\" : 3600\n      },\n      \"elevator\" : {\n        \"onlyConsiderAccessible\" : false,\n        \"unknownCost\" : 20,\n        \"inaccessibleCost\" : 3600\n      },\n      \"inaccessibleStreetReluctance\" : 25,\n      \"maxSlope\" : 0.083,\n      \"slopeExceededReluctance\" : 1,\n      \"stairsReluctance\" : 100\n    }\n  },\n  \"flex\" : {\n    \"maxTransferDuration\" : \"5m\",\n    \"maxFlexTripDuration\" : \"45m\",\n    \"maxAccessWalkDuration\" : \"15m\",\n    \"maxEgressWalkDuration\" : \"15m\"\n  },\n  \"transit\" : {\n    \"maxNumberOfTransfers\" : 12,\n    \"dynamicSearchWindow\" : {\n      \"minTransitTimeCoefficient\" : 0.5,\n      \"minWaitTimeCoefficient\" : 0.5,\n      \"minWindow\" : \"1h\",\n      \"maxWindow\" : \"5h\"\n    },\n    \"stopBoardAlightDuringTransferCost\" : {\n      \"DISCOURAGED\" : 1500,\n      \"ALLOWED\" : 75,\n      \"RECOMMENDED\" : 30,\n      \"PREFERRED\" : 0\n    },\n    \"transferCacheRequests\" : [\n      {\n        \"modes\" : \"WALK\"\n      },\n      {\n        \"modes\" : \"WALK\",\n        \"wheelchairAccessibility\" : {\n          \"enabled\" : true\n        }\n      }\n    ]\n  },\n  \"vehicleRentalServiceDirectory\" : {\n    \"url\" : \"https://entur.no/bikeRentalServiceDirectory\",\n    \"sourcesName\" : \"systems\",\n    \"updaterUrlName\" : \"url\",\n    \"updaterNetworkName\" : \"id\",\n    \"headers\" : {\n      \"ET-Client-Name\" : \"MY_ORG_CLIENT_NAME\"\n    }\n  },\n  \"transmodelApi\" : {\n    \"hideFeedId\" : true\n  },\n  \"vectorTiles\" : {\n    \"basePath\" : \"/otp_ct/vectorTiles\",\n    \"layers\" : [\n      {\n        \"name\" : \"stops\",\n        \"type\" : \"Stop\",\n        \"mapper\" : \"Digitransit\",\n        \"maxZoom\" : 20,\n        \"minZoom\" : 14,\n        \"cacheMaxSeconds\" : 600\n      },\n      {\n        \"name\" : \"areaStops\",\n        \"type\" : \"AreaStop\",\n        \"mapper\" : \"OTPRR\",\n        \"maxZoom\" : 20,\n        \"minZoom\" : 14,\n        \"cacheMaxSeconds\" : 600\n      },\n      {\n        \"name\" : \"stations\",\n        \"type\" : \"Station\",\n        \"mapper\" : \"Digitransit\",\n        \"maxZoom\" : 20,\n        \"minZoom\" : 12,\n        \"cacheMaxSeconds\" : 600\n      },\n      {\n        \"name\" : \"rentalPlaces\",\n        \"type\" : \"VehicleRental\",\n        \"mapper\" : \"Digitransit\",\n        \"maxZoom\" : 20,\n        \"minZoom\" : 14,\n        \"cacheMaxSeconds\" : 60,\n        \"expansionFactor\" : 0.25\n      },\n      {\n        \"name\" : \"rentalVehicle\",\n        \"type\" : \"VehicleRentalVehicle\",\n        \"mapper\" : \"Digitransit\",\n        \"maxZoom\" : 20,\n        \"minZoom\" : 14,\n        \"cacheMaxSeconds\" : 60\n      },\n      {\n        \"name\" : \"rentalStation\",\n        \"type\" : \"VehicleRentalStation\",\n        \"mapper\" : \"Digitransit\",\n        \"maxZoom\" : 20,\n        \"minZoom\" : 14,\n        \"cacheMaxSeconds\" : 600\n      },\n      {\n        \"name\" : \"vehicleParking\",\n        \"type\" : \"VehicleParking\",\n        \"mapper\" : \"Digitransit\",\n        \"maxZoom\" : 20,\n        \"minZoom\" : 14,\n        \"cacheMaxSeconds\" : 60,\n        \"expansionFactor\" : 0.25\n      }\n    ]\n  },\n  \"timetableUpdates\" : {\n    \"purgeExpiredData\" : false,\n    \"maxSnapshotFrequency\" : \"2s\"\n  },\n  \"updaters\" : [\n    {\n      \"type\" : \"real-time-alerts\",\n      \"frequency\" : \"30s\",\n      \"url\" : \"http://developer.trimet.org/ws/V1/FeedSpecAlerts/appID/0123456789ABCDEF\",\n      \"feedId\" : \"TriMet\",\n      \"headers\" : {\n        \"Some-Header\" : \"A-Value\"\n      }\n    },\n    {\n      \"type\" : \"vehicle-rental\",\n      \"network\" : \"socialbicycles_coast\",\n      \"sourceType\" : \"gbfs\",\n      \"language\" : \"en\",\n      \"frequency\" : \"1m\",\n      \"allowKeepingRentedVehicleAtDestination\" : false,\n      \"geofencingZones\" : false,\n      \"url\" : \"http://coast.socialbicycles.com/opendata/gbfs.json\",\n      \"headers\" : {\n        \"Auth\" : \"<any-token>\",\n        \"<key>\" : \"<value>\"\n      }\n    },\n    {\n      \"type\" : \"vehicle-parking\",\n      \"sourceType\" : \"hsl-park\",\n      \"feedId\" : \"hslpark\",\n      \"timeZone\" : \"Europe/Helsinki\",\n      \"facilitiesFrequencySec\" : 3600,\n      \"facilitiesUrl\" : \"https://p.hsl.fi/api/v1/facilities.json?limit=-1\",\n      \"utilizationsFrequencySec\" : 600,\n      \"utilizationsUrl\" : \"https://p.hsl.fi/api/v1/utilizations.json?limit=-1\",\n      \"hubsUrl\" : \"https://p.hsl.fi/api/v1/hubs.json?limit=-1\"\n    },\n    {\n      \"type\" : \"vehicle-parking\",\n      \"sourceType\" : \"park-api\",\n      \"feedId\" : \"parkapi\",\n      \"timeZone\" : \"Europe/Berlin\",\n      \"frequency\" : \"10m\",\n      \"url\" : \"https://foo.bar\",\n      \"headers\" : {\n        \"Cache-Control\" : \"max-age=604800\"\n      },\n      \"tags\" : [\n        \"source:parkapi\"\n      ]\n    },\n    {\n      \"type\" : \"vehicle-parking\",\n      \"feedId\" : \"bikely\",\n      \"sourceType\" : \"bikely\",\n      \"url\" : \"https://api.safebikely.com/api/v1/s/locations\",\n      \"headers\" : {\n        \"X-Bikely-Token\" : \"${BIKELY_TOKEN}\",\n        \"Authorization\" : \"${BIKELY_AUTHORIZATION}\"\n      }\n    },\n    {\n      \"type\" : \"stop-time-updater\",\n      \"frequency\" : \"1m\",\n      \"backwardsDelayPropagationType\" : \"REQUIRED_NO_DATA\",\n      \"url\" : \"http://developer.trimet.org/ws/V1/TripUpdate/appID/0123456789ABCDEF\",\n      \"feedId\" : \"TriMet\",\n      \"headers\" : {\n        \"Authorization\" : \"A-Token\"\n      }\n    },\n    {\n      \"type\" : \"mqtt-gtfs-rt-updater\",\n      \"url\" : \"tcp://pred.rt.hsl.fi\",\n      \"topic\" : \"gtfsrt/v2/fi/hsl/tu\",\n      \"feedId\" : \"HSL\",\n      \"fuzzyTripMatching\" : true\n    },\n    {\n      \"type\" : \"vehicle-positions\",\n      \"url\" : \"https://s3.amazonaws.com/kcm-alerts-realtime-prod/vehiclepositions.pb\",\n      \"feedId\" : \"1\",\n      \"frequency\" : \"1m\",\n      \"headers\" : {\n        \"Header-Name\" : \"Header-Value\"\n      },\n      \"fuzzyTripMatching\" : false,\n      \"features\" : [\n        \"position\"\n      ]\n    },\n    {\n      \"type\" : \"siri-et-updater\",\n      \"url\" : \"https://example.com/some/path\",\n      \"feedId\" : \"feed_id\",\n      \"timeout\" : \"30s\",\n      \"headers\" : {\n        \"Authorization\" : \"Some-Token\"\n      }\n    },\n    {\n      \"type\" : \"siri-sx-updater\",\n      \"url\" : \"https://example.com/some/path\",\n      \"feedId\" : \"feed_id\",\n      \"timeout\" : \"30s\",\n      \"headers\" : {\n        \"Key\" : \"Value\"\n      }\n    },\n    {\n      \"type\" : \"siri-azure-sx-updater\",\n      \"topic\" : \"some_topic\",\n      \"servicebus-url\" : \"service_bus_url\",\n      \"feedId\" : \"feed_id\",\n      \"customMidnight\" : 4,\n      \"history\" : {\n        \"url\" : \"endpoint_url\",\n        \"fromDateTime\" : \"-P1D\",\n        \"toDateTime\" : \"P1D\",\n        \"timeout\" : 300000\n      }\n    },\n    {\n      \"type\" : \"siri-azure-et-updater\",\n      \"topic\" : \"some_topic\",\n      \"authenticationType\" : \"SharedAccessKey\",\n      \"fullyQualifiedNamespace\" : \"fully_qualified_namespace\",\n      \"servicebus-url\" : \"service_bus_url\",\n      \"feedId\" : \"feed_id\",\n      \"customMidnight\" : 4,\n      \"history\" : {\n        \"url\" : \"endpoint_url\",\n        \"fromDateTime\" : \"-P1D\",\n        \"timeout\" : 300000\n      }\n    },\n    {\n      \"type\" : \"siri-et-google-pubsub-updater\",\n      \"feedId\" : \"feed_id\",\n      \"reconnectPeriod\" : \"5s\",\n      \"initialGetDataTimeout\" : \"1m20s\",\n      \"topicProjectName\" : \"google_pubsub_topic_project_name\",\n      \"subscriptionProjectName\" : \"google_pubsub_subscription_project_name\",\n      \"topicName\" : \"estimated_timetables\",\n      \"dataInitializationUrl\" : \"https://example.com/some/path\",\n      \"fuzzyTripMatching\" : true\n    },\n    {\n      \"type\" : \"vehicle-parking\",\n      \"feedId\" : \"bikeep\",\n      \"sourceType\" : \"bikeep\",\n      \"url\" : \"https://services.bikeep.com/location/v1/public-areas/no-baia-mobility/locations\"\n    },\n    {\n      \"type\" : \"vehicle-parking\",\n      \"feedId\" : \"parking\",\n      \"sourceType\" : \"siri-fm\",\n      \"url\" : \"https://transmodel.api.opendatahub.com/siri-lite/fm/parking\"\n    }\n  ],\n  \"rideHailingServices\" : [\n    {\n      \"type\" : \"uber-car-hailing\",\n      \"clientId\" : \"secret-id\",\n      \"clientSecret\" : \"very-secret\",\n      \"wheelchairAccessibleProductId\" : \"545de0c4-659f-49c6-be65-0d5e448dffd5\",\n      \"bannedProductIds\" : [\n        \"1196d0dd-423b-4a81-a1d8-615367d3a365\",\n        \"f58761e5-8dd5-4940-a472-872f1236c596\"\n      ]\n    }\n  ]\n}\n
    "},{"location":"RoutingModes/","title":"Routing modes","text":"

    This page is intended as an exhaustive listing of what OTP's routing engine is capable of and therefore documents internal names. Since OTP has multiple APIs where each works slightly differently, please consult your API documentation on how to select the appropriate mode.

    "},{"location":"RoutingModes/#Street modes","title":"Street modes","text":"

    Routing modes on streets, including walking, biking, driving, and car-sharing.

    "},{"location":"RoutingModes/#BIKE","title":"BIKE","text":"

    Cycling for the entirety of the route or taking a bicycle onto the public transport and cycling from the arrival station to the destination.

    Taking a bicycle onto transit is only possible if information about the permission to do so is supplied in the source data. In GTFS this field is called bikesAllowed.

    "},{"location":"RoutingModes/#BIKE_RENTAL","title":"BIKE_RENTAL","text":"

    Taking a rented, shared-mobility bike for part or the entirety of the route.

    Prerequisite: Vehicle or station locations need to be added to OTP from dynamic data feeds. See Configuring GBFS on how to add one.

    "},{"location":"RoutingModes/#BIKE_TO_PARK","title":"BIKE_TO_PARK","text":"

    Leaving the bicycle at the departure station and walking from the arrival station to the destination. This mode needs to be combined with at least one transit mode otherwise it behaves like an ordinary bicycle journey.

    Prerequisite: Bicycle parking stations present in the OSM file and visible to OTP by enabling the property staticBikeParkAndRide during graph build.

    "},{"location":"RoutingModes/#CAR","title":"CAR","text":"

    Driving your own car the entirety of the route. This can be combined with transit, where will return routes with a Kiss & Ride 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.

    "},{"location":"RoutingModes/#CAR_HAILING","title":"CAR_HAILING","text":"

    Using a car hailing app like Uber or Lyft to get to a train station or all the way to the destination.

    See the sandbox documentation on how to configure it.

    "},{"location":"RoutingModes/#CAR_PICKUP","title":"CAR_PICKUP","text":"

    Walking to a pickup point along the road, driving to a drop-off point along the road, and walking the rest of the way. This can include various taxi-services or kiss & ride.

    "},{"location":"RoutingModes/#CAR_RENTAL","title":"CAR_RENTAL","text":"

    Walk to a car rental point, drive to a car rental drop-off point and walk the rest of the way. This can include car rental at fixed locations or free-floating services.

    Prerequisite: Vehicle or station locations need to be added to OTP from dynamic data feeds. See Configuring GBFS on how to add one.

    "},{"location":"RoutingModes/#CAR_TO_PARK","title":"CAR_TO_PARK","text":"

    Driving a car to the park-and-ride facilities near a station and taking publictransport. This mode needs to be combined with at least one transit mode otherwise, it behaves like an ordinary car journey. Prerequisite: Park-and-ride areas near the stations need to be present in the OSM input file.

    "},{"location":"RoutingModes/#FLEXIBLE","title":"FLEXIBLE","text":"

    Encompasses all types of on-demand and flexible transportation for example GTFS Flex or NeTEx Flexible Stop Places.

    "},{"location":"RoutingModes/#SCOOTER_RENTAL","title":"SCOOTER_RENTAL","text":"

    Walking to a scooter rental point, riding a scooter to a scooter rental drop-off point, and walking the rest of the way. This can include scooter rental at fixed locations or free-floating services.

    Prerequisite: Vehicle or station locations need to be added to OTP from dynamic data feeds. See Configuring GBFS on how to add one.

    "},{"location":"RoutingModes/#WALK","title":"WALK","text":"

    Walking some or all of the way of the route.

    "},{"location":"RoutingModes/#Transit modes","title":"Transit modes","text":"

    Routing modes for transit, including rail, bus, ferry, etc. Equivalent to GTFS route_type or to NeTEx TransportMode.

    "},{"location":"RoutingModes/#AIRPLANE","title":"AIRPLANE","text":"

    Taking an airplane

    "},{"location":"RoutingModes/#BUS","title":"BUS","text":"

    Used for short- and long-distance bus routes.

    "},{"location":"RoutingModes/#CABLE_CAR","title":"CABLE_CAR","text":"

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

    "},{"location":"RoutingModes/#CARPOOL","title":"CARPOOL","text":"

    Private car trips shared with others.

    This is currently not specified in GTFS so we use the mode type values 1550-1560 which are in the range of private taxis.

    "},{"location":"RoutingModes/#COACH","title":"COACH","text":"

    Used for long-distance bus routes.

    "},{"location":"RoutingModes/#FERRY","title":"FERRY","text":"

    Used for short- and long-distance boat service.

    "},{"location":"RoutingModes/#FUNICULAR","title":"FUNICULAR","text":"

    Used for any rail system that moves on steep inclines with a cable traction system.

    "},{"location":"RoutingModes/#GONDOLA","title":"GONDOLA","text":"

    Gondola or suspended cable car. Typically used for aerial cable cars where the car is suspended from the cable.

    "},{"location":"RoutingModes/#MONORAIL","title":"MONORAIL","text":"

    Used for any rail system that runs on a single rail.

    "},{"location":"RoutingModes/#RAIL","title":"RAIL","text":"

    Used for intercity or long-distance travel.

    "},{"location":"RoutingModes/#SUBWAY","title":"SUBWAY","text":"

    Subway or Metro, used for any underground rail system within a metropolitan area.

    "},{"location":"RoutingModes/#TAXI","title":"TAXI","text":"

    Using a taxi service

    "},{"location":"RoutingModes/#TRAM","title":"TRAM","text":"

    Tram, streetcar or light rail. Used for any light rail or street level system within a metropolitan area.

    "},{"location":"RoutingModes/#TROLLEYBUS","title":"TROLLEYBUS","text":"

    Used for trolleybus systems which draw power from overhead wires using poles on the roof of the vehicle.

    "},{"location":"SandboxExtension/","title":"OTP Sandbox Extensions","text":""},{"location":"SandboxExtension/#terminology","title":"Terminology","text":"

    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)

    "},{"location":"SandboxExtension/#sandbox-goals","title":"Sandbox Goals","text":""},{"location":"SandboxExtension/#contract","title":"Contract","text":""},{"location":"StopAreas/","title":"Stop Areas","text":"

    Public transit stations and stops can be modeled using a relation tagged with public_transport=stop_area. Description of such relations can be found from this OSM wiki page.

    OpenTripPlanner detects such relations and applies some special logic to them. Nodes, which are linked to street network, and are located within platform areas, are interpreted as connection points from the street network to the platform. OTP automatically links such points with the platform geometry in order to improve walk routing.

    For example, an elevator or stairs can connect a normal street to a railway platform above it. There is no need to add an explicit edge, which connects the entrance point with the actual geometry of the platform.

    An example: Huopalahti railway station in Helsinki

    "},{"location":"StopAreas/#instructions","title":"Instructions","text":""},{"location":"System-Requirements/","title":"System Requirements and Suggestions","text":""},{"location":"System-Requirements/#system-requirements","title":"System requirements","text":""},{"location":"System-Requirements/#memory","title":"Memory","text":"

    OTP is relatively memory-hungry as it includes all the required data in memory. How much memory is required to build the graph for OTP, or to run the OTP server, depends on the used data sets (is OSM, elevation and/or transit data included?), on the size of the covered geographical area and the density of the transit and street network. The required memory can vary from less than one GB to more than 100 GB. For example, including all available data for Finland takes a bit over 10 GB but for Germany it requires 95 GB.

    "},{"location":"System-Requirements/#processor","title":"Processor","text":"

    Single thread performance is an important factor for OTP's performance. Additionally, OTP benefits from larger CPU cache as reading from memory can be a bottleneck.

    OTP's performance scales with the number of available CPU cores. OTP processes each request in a separate thread and usually one request doesn't utilize more than one thread, but with some requests and configurations, it's possible that multiple threads are used in parallel for a small part of a request or to process multiple queries within one request. How much parallel processing we utilize in requests might change in the future. Real-time updates also run in a separate thread. Therefore, to have a good performance, it makes sense to have multiple cores available. How OTP uses parallel processing also depends on the available cores (<= 2 cores vs >2 cores) in some cases. Therefore, load testing should be done against a machine that doesn't differ too much from production machines.

    Entur and the Digitransit project have found that the 3rd generation AMD processors have a slightly better performance for OTP2 than the Intel 3rd generation CPUs (and especially better than the 2nd generation CPUs).

    "},{"location":"System-Requirements/#suggested-vm-types-in-cloud-service-providers","title":"Suggested VM types in cloud service providers","text":""},{"location":"System-Requirements/#azure","title":"Azure","text":"

    For Azure, the Digitransit project did benchmarking of the available virtual machines types for OTP 2.3 in early 2023 and found that the D2as \u2013 D96as v5 family had the best performance of the reasonable priced virtual machines types. These machines use the 3rd generation AMD EPYCTM 7763v (Milan) processor. The 3rd generation Intel machines had a slightly worse performance and a slightly higher cost. Digitransit chose to use the D8as v5 machine as it had enough memory for running OTP in Finland and a reasonable number of vCPUs.

    "},{"location":"System-Requirements/#google-cloud","title":"Google Cloud","text":"

    Entur uses a scalable fleet of instances of type c2d-standard-8.

    "},{"location":"Troubleshooting-Routing/","title":"Troubleshooting Routing","text":""},{"location":"Troubleshooting-Routing/#graph-builder-data-import-issues","title":"Graph Builder Data Import Issues","text":"

    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:

     11:35:57.515 INFO (Graph.java:970) Summary (number of each type of issues):\n 11:35:57.518 INFO (Graph.java:976)     TurnRestrictionBad - 560\n 11:35:57.518 INFO (Graph.java:976)     TurnRestrictionException - 15\n 11:35:57.518 INFO (Graph.java:976)     StopLinkedTooFar - 22\n 11:35:57.518 INFO (Graph.java:976)     HopSpeedSlow - 22\n 11:35:57.518 INFO (Graph.java:976)     Graphwide - 1\n 11:35:57.518 INFO (Graph.java:976)     GraphConnectivity - 407\n 11:35:57.519 INFO (Graph.java:976)     ParkAndRideUnlinked - 1\n 11:35:57.519 INFO (Graph.java:976)     StopNotLinkedForTransfers - 31\n 11:35:57.519 INFO (Graph.java:976)     NoFutureDates - 1\n

    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.

    "},{"location":"Troubleshooting-Routing/#debug-layers","title":"Debug layers","text":"

    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.

    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. 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:

    "},{"location":"Troubleshooting-Routing/#interpretation-traversal-permissions-layer","title":"Interpretation Traversal permissions layer","text":"

    A sample traversal permissions layer looks like the following

    "},{"location":"Troubleshooting-Routing/#openstreetmap-data","title":"OpenStreetMap Data","text":""},{"location":"Troubleshooting-Routing/#tags-affecting-permissions-and-bicycle-safety","title":"Tags affecting permissions and bicycle safety","text":"

    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 osmTagMapping config attribute.

    In the following section we will discuss the default case, which will be used if the property is not set.

    "},{"location":"Troubleshooting-Routing/#default-settings","title":"Default settings","text":"

    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.

    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.

    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.

    "},{"location":"Troubleshooting-Routing/#bicycle-safety-factor","title":"Bicycle safety factor","text":"

    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.

    How this is calculated depends on two things

    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:

    props.setProperties(\"highway=track\", StreetTraversalPermission.ALL, 1.3, 1.3);\n

    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, 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 OsmTagMapper 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):

    props.setProperties(\"surface=mud\", StreetTraversalPermission.ALL, 1.5, 1.5, true);\n

    The Javadoc of 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.

    To enable it activate the Report API sandbox feature.

    To view the output of the bicycle safety calculation on a map, check the debug layers.

    "},{"location":"Troubleshooting-Routing/#railway-platforms","title":"Railway Platforms","text":"

    OTP users in Helsinki have documented their best practices for coding railway platforms in OpenStreetMap. These guidelines are available in the OSM Wiki.

    "},{"location":"Troubleshooting-Routing/#transit-search","title":"Transit search","text":"

    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.

    Read the logging page for more information.

    "},{"location":"Troubleshooting-Routing/#gtfs-transferstxt-and-netex-interchange-import","title":"GTFS Transfers.txt and NeTEx Interchange import","text":"

    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:

      <logger name=\"TRANSFERS_EXPORT\" level=\"info\" />\n
    "},{"location":"Troubleshooting-Routing/#further-information","title":"Further information","text":""},{"location":"UpdaterConfig/","title":"Realtime Updaters","text":""},{"location":"UpdaterConfig/#updater-configuration","title":"Updater configuration","text":"

    This section covers options that can be set in the updaters section of router-config.json. See the parameter summary and examples in the router configuration documentation

    Real-time data are those that are not added to OTP during the graph build phase but during runtime.

    Real-time data sources are configured in the updaters section is an array of JSON objects, each of which has a type field and other configuration fields specific to that type.

    "},{"location":"UpdaterConfig/#gtfs-realtime","title":"GTFS-Realtime","text":"

    GTFS feeds contain schedule data that 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 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 updated from minute to minute.

    "},{"location":"UpdaterConfig/#alerts","title":"Alerts","text":"

    Alerts are text messages attached to GTFS objects, informing riders of disruptions and changes. The information is downloaded in a single HTTP request and polled regularly.

    Config Parameter Type Summary Req./Opt. Default Value Since type = \"real-time-alerts\" enum The type of the updater. Required 1.5 earlyStartSec integer How long before the posted start of an event it should be displayed to users Optional 0 1.5 feedId string The id of the feed to apply the alerts to. Required 1.5 frequency duration How often the URL should be fetched. Optional \"PT1M\" 1.5 fuzzyTripMatching boolean Whether to match trips fuzzily. Optional false 1.5 url string URL to fetch the GTFS-RT feed from. Required 1.5 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.3"},{"location":"UpdaterConfig/#parameter-details","title":"Parameter details","text":""},{"location":"UpdaterConfig/#u_0_headers","title":"headers","text":"

    Since version: 2.3 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[0]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"UpdaterConfig/#example-configuration","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"real-time-alerts\",\n      \"frequency\" : \"30s\",\n      \"url\" : \"http://developer.trimet.org/ws/V1/FeedSpecAlerts/appID/0123456789ABCDEF\",\n      \"feedId\" : \"TriMet\",\n      \"headers\" : {\n        \"Some-Header\" : \"A-Value\"\n      }\n    }\n  ]\n}\n
    "},{"location":"UpdaterConfig/#tripupdates-via-https","title":"TripUpdates via HTTP(S)","text":"

    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. The information is downloaded in a single HTTP request and polled regularly.

    Config Parameter Type Summary Req./Opt. Default Value Since type = \"stop-time-updater\" enum The type of the updater. Required 1.5 backwardsDelayPropagationType enum How backwards propagation should be handled. Optional \"required-no-data\" 2.2 feedId string Which feed the updates apply to. Required 1.5 frequency duration How often the data should be downloaded. Optional \"PT1M\" 1.5 fuzzyTripMatching boolean If the trips should be matched fuzzily. Optional false 1.5 url string The URL of the GTFS-RT resource. Required 1.5 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.3"},{"location":"UpdaterConfig/#parameter-details_1","title":"Parameter details","text":""},{"location":"UpdaterConfig/#u__5__backwardsDelayPropagationType","title":"backwardsDelayPropagationType","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"required-no-data\" Path: /updaters/[5] Enum values: required-no-data | required | always

    How backwards propagation should be handled.

    REQUIRED_NO_DATA: Default value. Only propagates delays backwards when it is required to ensure that the times are increasing, and it sets the NO_DATA flag on the stops so these automatically updated times are not exposed through APIs.

    REQUIRED: Only propagates delays backwards when it is required to ensure that the times are increasing. The updated times are exposed through APIs.

    ALWAYS Propagates delays backwards on stops with no estimates regardless if it's required or not. The updated times are exposed through APIs.

    "},{"location":"UpdaterConfig/#u__5__url","title":"url","text":"

    Since version: 1.5 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[5]

    The URL of the GTFS-RT resource.

    file: URLs are also supported if you want to read a file from the local disk.

    "},{"location":"UpdaterConfig/#u__5__headers","title":"headers","text":"

    Since version: 2.3 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[5]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"UpdaterConfig/#example-configuration_1","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"stop-time-updater\",\n      \"frequency\" : \"1m\",\n      \"backwardsDelayPropagationType\" : \"REQUIRED_NO_DATA\",\n      \"url\" : \"http://developer.trimet.org/ws/V1/TripUpdate/appID/0123456789ABCDEF\",\n      \"feedId\" : \"TriMet\",\n      \"headers\" : {\n        \"Authorization\" : \"A-Token\"\n      }\n    }\n  ]\n}\n
    "},{"location":"UpdaterConfig/#streaming-tripupdates-via-mqtt","title":"Streaming TripUpdates via MQTT","text":"

    This updater connects to an MQTT broker and processes TripUpdates in a streaming fashion. This means that they will be applied individually in near-realtime rather than in batches at a certain interval.

    This system powers the realtime updates in Helsinki and more information can be found on Github.

    Config Parameter Type Summary Req./Opt. Default Value Since type = \"mqtt-gtfs-rt-updater\" enum The type of the updater. Required 1.5 backwardsDelayPropagationType enum How backwards propagation should be handled. Optional \"required-no-data\" 2.2 feedId string The feed id to apply the updates to. Required 2.0 fuzzyTripMatching boolean Whether to match trips fuzzily. Optional false 2.0 qos integer QOS level. Optional 0 2.0 topic string The topic to subscribe to. Required 2.0 url string URL of the MQTT broker. Required 2.0"},{"location":"UpdaterConfig/#parameter-details_2","title":"Parameter details","text":""},{"location":"UpdaterConfig/#u__6__backwardsDelayPropagationType","title":"backwardsDelayPropagationType","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"required-no-data\" Path: /updaters/[6] Enum values: required-no-data | required | always

    How backwards propagation should be handled.

    REQUIRED_NO_DATA: Default value. Only propagates delays backwards when it is required to ensure that the times are increasing, and it sets the NO_DATA flag on the stops so these automatically updated times are not exposed through APIs.

    REQUIRED: Only propagates delays backwards when it is required to ensure that the times are increasing. The updated times are exposed through APIs.

    ALWAYS: Propagates delays backwards on stops with no estimates regardless if it's required or not. The updated times are exposed through APIs.

    "},{"location":"UpdaterConfig/#example-configuration_2","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"mqtt-gtfs-rt-updater\",\n      \"url\" : \"tcp://pred.rt.hsl.fi\",\n      \"topic\" : \"gtfsrt/v2/fi/hsl/tu\",\n      \"feedId\" : \"HSL\",\n      \"fuzzyTripMatching\" : true\n    }\n  ]\n}\n
    "},{"location":"UpdaterConfig/#vehicle-positions","title":"Vehicle Positions","text":"

    VehiclePositions give the location of some or all vehicles currently in service, in terms of geographic coordinates or position relative to their scheduled stops. The information is downloaded in a single HTTP request and polled regularly.

    Config Parameter Type Summary Req./Opt. Default Value Since type = \"vehicle-positions\" enum The type of the updater. Required 1.5 feedId string Feed ID to which the update should be applied. Required 2.2 frequency duration How often the positions should be updated. Optional \"PT1M\" 2.2 fuzzyTripMatching boolean Whether to match trips fuzzily. Optional false 2.5 url uri The URL of GTFS-RT protobuf HTTP resource to download the positions from. Required 2.2 features enum set Which features of GTFS RT vehicle positions should be loaded into OTP. Optional 2.5 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.3"},{"location":"UpdaterConfig/#parameter-details_3","title":"Parameter details","text":""},{"location":"UpdaterConfig/#u__7__features","title":"features","text":"

    Since version: 2.5 \u2219 Type: enum set \u2219 Cardinality: Optional Path: /updaters/[7] Enum values: position | stop-position | occupancy

    Which features of GTFS RT vehicle positions should be loaded into OTP.

    "},{"location":"UpdaterConfig/#u__7__headers","title":"headers","text":"

    Since version: 2.3 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[7]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"UpdaterConfig/#example-configuration_3","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"vehicle-positions\",\n      \"url\" : \"https://s3.amazonaws.com/kcm-alerts-realtime-prod/vehiclepositions.pb\",\n      \"feedId\" : \"1\",\n      \"frequency\" : \"1m\",\n      \"headers\" : {\n        \"Header-Name\" : \"Header-Value\"\n      },\n      \"fuzzyTripMatching\" : false,\n      \"features\" : [\n        \"position\"\n      ]\n    }\n  ]\n}\n
    "},{"location":"UpdaterConfig/#gbfs-vehicle-rental-systems","title":"GBFS vehicle rental systems","text":"

    Besides GTFS-RT transit data, OTP can also fetch real-time data about vehicle rental networks including the number of vehicles and free parking spaces at each station. We support vehicle rental systems that use the GBFS standard.

    GBFS can be used for a variety of shared mobility services, with partial support for both v1 and v2.2 (list of known GBFS feeds). OTP supports the following GBFS form factors:

    Config Parameter Type Summary Req./Opt. Default Value Since type = \"vehicle-rental\" enum The type of the updater. Required 1.5 allowKeepingRentedVehicleAtDestination boolean If a vehicle should be allowed to be kept at the end of a station-based rental. Optional false 2.1 frequency duration How often the data should be updated. Optional \"PT1M\" 1.5 geofencingZones boolean Compute rental restrictions based on GBFS 2.2 geofencing zones. Optional false 2.3 language string TODO Optional 2.1 network string The name of the network to override the one derived from the source data. Optional 1.5 overloadingAllowed boolean Allow leaving vehicles at a station even though there are no free slots. Optional false 2.2 sourceType enum What source of vehicle rental updater to use. Required 1.5 url string The URL to download the data from. Required 1.5 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 1.5"},{"location":"UpdaterConfig/#parameter-details_4","title":"Parameter details","text":""},{"location":"UpdaterConfig/#u_1_allowKeepingRentedVehicleAtDestination","title":"allowKeepingRentedVehicleAtDestination","text":"

    Since version: 2.1 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /updaters/[1]

    If a vehicle should be allowed to be kept at the end of a station-based rental.

    In some cases it may be useful to not drop off the rented vehicle before arriving at the destination. This is useful if vehicles may only be rented for round trips, or the destination is an intermediate place.

    For this to be possible three things need to be configured:

    "},{"location":"UpdaterConfig/#u_1_geofencingZones","title":"geofencingZones","text":"

    Since version: 2.3 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /updaters/[1]

    Compute rental restrictions based on GBFS 2.2 geofencing zones.

    This feature is somewhat experimental and therefore turned off by default for the following reasons:

    "},{"location":"UpdaterConfig/#u_1_network","title":"network","text":"

    Since version: 1.5 \u2219 Type: string \u2219 Cardinality: Optional Path: /updaters/[1]

    The name of the network to override the one derived from the source data.

    GBFS feeds must include a system_id which will be used as the default network. These ids are sometimes not helpful so setting this property will override it.

    "},{"location":"UpdaterConfig/#u_1_sourceType","title":"sourceType","text":"

    Since version: 1.5 \u2219 Type: enum \u2219 Cardinality: Required Path: /updaters/[1] Enum values: gbfs | smoove

    What source of vehicle rental updater to use.

    "},{"location":"UpdaterConfig/#u_1_headers","title":"headers","text":"

    Since version: 1.5 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[1]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"UpdaterConfig/#example-configuration_4","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"vehicle-rental\",\n      \"network\" : \"socialbicycles_coast\",\n      \"sourceType\" : \"gbfs\",\n      \"language\" : \"en\",\n      \"frequency\" : \"1m\",\n      \"allowKeepingRentedVehicleAtDestination\" : false,\n      \"geofencingZones\" : false,\n      \"url\" : \"http://coast.socialbicycles.com/opendata/gbfs.json\",\n      \"headers\" : {\n        \"Auth\" : \"<any-token>\",\n        \"<key>\" : \"<value>\"\n      }\n    }\n  ]\n}\n
    "},{"location":"UpdaterConfig/#other-updaters-in-sandboxes","title":"Other updaters in sandboxes","text":""},{"location":"Version-Comparison/","title":"Comparing OTP2 and OTP1","text":""},{"location":"Version-Comparison/#summary","title":"Summary","text":"

    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 2023, OTP2 is the only version to receive regular updates and OTP1 is considered legacy and unsupported. This page explains key differences between the two versions (referred to as OTP1 and OTP2).

    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 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 very similar 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.

    "},{"location":"Version-Comparison/#otp2-use-cases","title":"OTP2 Use Cases","text":"

    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.

    "},{"location":"Version-Comparison/#high-level-feature-comparison","title":"High-level feature comparison","text":"Feature OTP1 OTP2 OSM street data yes yes GTFS transit data yes yes Netex transit data no yes(Nordic profile) GTFS-Realtime yes(streaming, polling, incremental) yes(streaming, polling, incremental) SIRI Realtime no yes Elevation data TIFF and NED TIFF and NED One-to-many routing, isochrones and scripting yes no Isochrones yes yes Java version 8+ 21+ Multiple regions per server yes no Hot reloading of graphs yes no Street (OSM) routing algorithm Generalized cost A* Generalized cost A* Transit routing algorithm Generalized cost A* Multi-criteria range-RAPTOR Search segmentation Single search through access, transit, egress Access/egress separate from transit search Goal direction Upper bound search backward from destination, over streets and transit, interleaved with forward search Upper bound search backward from destination on transit only, before forward search begins Alternative itineraries \"Trip banning\", N lowest generalized costs True Pareto-optimal results Departure/arrival time Single departure or arrival time only Every minute in a window up to several days long API Paging no yes Timetable View no yes Plugin Sandbox Extensions no yes (See extensions) Data storage local, S3 (elevation only) extensible with local, ZIP,and Google Cloud plugins, S3 available Transfer Priority yes yes"},{"location":"Version-Comparison/#commentary-on-otp1-features-removed-from-otp2","title":"Commentary on OTP1 features removed from OTP2","text":"

    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.

    Some features have been removed to simplify the code base and improve maintainability. Others 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.

    "},{"location":"Version-Comparison/#analysis","title":"Analysis","text":"

    From the beginning of the project, many OTP contributors and users have used OTP in research, analysis, and planning applications. They have prototyped many ideas within the OTP codebase, including one-to-many searches producing travel time grids, isochrones, and access-to-opportunities metrics. While some of these features may still be available as optional \"sandbox\" features in OTP2, they are unsupported and may be removed in the near future.

    Most work of this kind moved over separate projects focused on urban planning and analytics. As of version 2, OTP has chosen to focus entirely on passenger information rather than analytics applications. See the Analysis page for more details.

    "},{"location":"Version-Comparison/#routers-api-and-hot-reloading","title":"Routers API and Hot Reloading","text":"

    Via its 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.

    "},{"location":"Version-Comparison/#routing-request-parameters","title":"Routing request parameters","text":"

    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

    "},{"location":"Version-Comparison/#otp-trip-planning-and-transit-index-apis","title":"OTP Trip planning and Transit index APIs","text":"

    OTP1 had two APIs for trip planning, the REST API and an GraphQL API (early version of the GTFS GraphQL API). This API has been formalised and is now, together with the Transmodel GraphQL API, the only supported way of sending requests to the OTP routing engine.

    Details of those two APIs are available at the following pages:

    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 semantics and structure, and provide the same functionality.

    "},{"location":"Version-Comparison/#additional-characteristics-added-in-otp2","title":"Additional characteristics added in OTP2","text":"

    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 \u201cequal\u201d, 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.

    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

    "},{"location":"Version-Comparison/#other-features-removed-from-otp2","title":"Other features removed from OTP2","text":"

    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.

    "},{"location":"Version-Comparison/#migration-guide","title":"Migration guide","text":"

    The development community has maintained a migration guide from version 1.5.0 up to 2.2.0 when it was no longer feasible to document every change as version 2 was considered the only supported one. The document can be found in the documentation of version 2.2.0.

    "},{"location":"Visual-Identity/","title":"OpenTripPlanner Visual Identity","text":"

    This is the OpenTripPlanner logo in scalable vector format, with knockout transparency:

    Here is a link to this SVG logo as a downloadable file. This is the raw SVG XML source code:

    <?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" \n    x=\"0px\" y=\"0px\" width=\"512px\" height=\"512px\" viewBox=\"0 0 125.333 125.334\" xml:space=\"preserve\">\n<path fill=\"#2179BF\" d=\"M62.668,0C33.83,0,9.559,19.483,2.258,46l72.681-0.003c4.729-0.011,8.555-3.837,8.561-8.568\n    c-0.006-4.729-3.831-8.555-8.561-8.559c-4.731,0.004-8.557,3.83-8.564,8.559v4.592h-13.7v-4.592\n    c0-12.294,9.962-22.261,22.265-22.263c12.298,0.002,22.262,9.969,22.266,22.263c-0.003,12.3-9.968,22.264-22.266,22.271H0.074\n    C0.028,60.684,0,61.671,0,62.666c0,34.611,28.057,62.668,62.668,62.668c34.609,0,62.665-28.057,62.665-62.668\n    C125.333,28.057,97.277,0,62.668,0 M92.222,85.667v-3.473v-4.86l-47.058,0.003c-4.729,0.011-8.556,3.837-8.561,8.568\n    c0.005,4.728,3.831,8.555,8.561,8.559c4.731-0.004,8.558-3.831,8.565-8.559v-4.592h13.699v4.592\n    c0,12.294-9.961,22.261-22.265,22.263c-12.298-0.002-22.26-9.969-22.264-22.263c0.002-12.3,9.966-22.264,22.264-22.271h47.058V56.12\n    l21.712,14.775L92.222,85.667z\"/>\n</svg>\n

    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 OpenTripPlanner logo was created by Brooklyn-based cartographer and graphic designer Kate Chanba, who has also done extensive work on transit system maps.

    "},{"location":"apis/Apis/","title":"APIs","text":"

    Several services are built upon OTP's routing and transit data indexing engines. They expose these APIs:

    The GTFS GraphQL API has been used by the Digitransit and otp-react-redux projects as a general purpose routing and transit data API in production for many years. If your input data is mostly GTFS then this is probably the best choice as it uses the same vocabulary.

    The Transmodel GraphQL API is used at Entur in production since 2020. Like the GTFS GraphQL API it is also a general purpose API. If your input data is mostly NeTeX then you might want to investigate this API as it uses the Transmodel vocabulary to describe its entities.

    The Vector tiles API is a special purpose API for displaying entities on a vector map.

    The Actuator API provides endpoints for checking the health status of the OTP instance and reading live application metrics.

    The Geocoder API allows you to geocode stop names and codes.

    "},{"location":"apis/Apis/#legacy-apis-to-be-removed","title":"Legacy APIs (to be removed)","text":"

    The OTP REST API used to power many apps and frontends. For years it was the only way to access OTP programmatically.

    Over time it has been replaced by the GraphQL APIs and is now disabled by default and will eventually be removed completely. It's therefore not recommended to use it.

    "},{"location":"apis/GTFS-GraphQL-API/","title":"GTFS GraphQL API","text":"

    The GTFS GraphQL API is a general purpose API which was created for the Digitransit project and is used heavily by digitransit-ui.

    otp-react-redux has also migrated to this API in 2023.

    There is also a Java client available which makes it easy to use this API in a Java application.

    "},{"location":"apis/GTFS-GraphQL-API/#urls","title":"URLs","text":""},{"location":"apis/GTFS-GraphQL-API/#built-in-api-client","title":"Built-in API client","text":"

    A browser based GraphQL API client is available at http://localhost:8080/graphiql

    curl example

    A complete example that fetches the list of all stops from OTP is:

    curl --request POST \\\n  --url http://localhost:8080/otp/gtfs/v1 \\\n  --header 'Content-Type: application/json' \\\n  --header 'OTPTimeout: 180000' \\\n  --data '{\"query\":\"query stops {\\n  stops {\\n    gtfsId\\n    name\\n  }\\n}\\n\",\"operationName\":\"stops\"}'\n
    "},{"location":"apis/GTFS-GraphQL-API/#configuration","title":"Configuration","text":"

    The API is enabled by default.

    If you want to disable it, do it in otp-config.json:

    // otp-config.json\n{\n  \"otpFeatures\" : {\n    \"GtfsGraphQlApi\": false\n  }\n}\n
    "},{"location":"apis/GraphQL-Tutorial/","title":"GraphQL Tutorial","text":""},{"location":"apis/GraphQL-Tutorial/#graphql-tutorial","title":"GraphQL tutorial","text":"

    This document will give you a quick start tutorial on how to get started with OTP's GraphQL APIs. For this tutorial we will be using the GTFS GraphQL API as this is the most commonly used one.

    First of all, make sure that you've loaded street and transit data into your instance by following the basic tutorial

    "},{"location":"apis/GraphQL-Tutorial/#visual-graphql-api-client","title":"Visual GraphQL API client","text":"

    OTP has a built-in API client to help you build queries and view documentation. After having started OTP, visit http://localhost:8080/graphiql to open it.

    It should look like this:

    "},{"location":"apis/GraphQL-Tutorial/#sending-your-first-query","title":"Sending your first query","text":"

    For our first query we want to get the list of routes loaded into OTP. Therefore paste the following GraphQL query in the left hand panel of the page:

    {\n  routes {\n    longName\n    shortName\n    gtfsId\n    agency {\n      gtfsId\n      name\n    }\n    mode\n  }\n}\n

    After pressing the \"Execute query\" button you should see the result of the query on the right hand side panel.

    Now would be a good time to explore the auto-complete capabilities of the tool by moving the cursor into the query panel and hitting Ctrl-Space to see what other query parameters are possible.

    The explorer also has documentation built into it. If you hover your pointer over a property on the left hand side you can see its documentation.

    "},{"location":"apis/GraphQL-Tutorial/#a-more-advanced-query","title":"A more advanced query","text":"

    Most people want to get routing results out of OTP, so lets see the query for this:

    {\n  planConnection(\n    origin: {\n      # these coordinates are in Portland, change this to YOUR origin\n      location: { coordinate: { latitude: 45.5552, longitude: -122.6534 } }\n    }\n    destination: {\n      # these coordinates are in Portland, change this to YOUR destination\n      location: { coordinate: { latitude: 45.4908, longitude: -122.5519 } }\n    }\n    # use the correct date and time of your request\n    dateTime: { earliestDeparture: \"2023-06-13T14:30-07:00\" }\n    # choose the transport modes you need\n    modes: {\n      direct: [WALK]\n      transit: { transit: [{ mode: BUS }, { mode: RAIL }] }\n    }\n  ) {\n    edges {\n      node {\n        start\n        end\n        legs {\n          mode\n          from {\n            name\n            lat\n            lon\n            departure {\n              scheduledTime\n              estimated {\n                time\n                delay\n              }\n            }\n          }\n          to {\n            name\n            lat\n            lon\n            arrival {\n              scheduledTime\n              estimated {\n                time\n                delay\n              }\n            }\n          }\n          route {\n            gtfsId\n            longName\n            shortName\n          }\n          legGeometry {\n            points\n          }\n        }\n      }\n    }\n  }\n}\n

    Again, please use the autocomplete and documentation viewers to figure out what each input parameter and property means.

    More examples for a variety of queries can also be found in the test code.

    "},{"location":"apis/TransmodelApi/","title":"Transmodel GraphQL API","text":""},{"location":"apis/TransmodelApi/#contact-info","title":"Contact Info","text":""},{"location":"apis/TransmodelApi/#documentation","title":"Documentation","text":"

    This is the official OTP2 API for Transmodel (NeTEx). 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 provides a GraphQL explorer where you may browse the GraphQL schema and try your own queries.

    When running OTP locally the endpoint is available at: http://localhost:8080/otp/transmodel/v3

    Note! Versions v1 and v2 do not exist in the main OTP git repository, but in the Entur fork from which this code originates from.

    "},{"location":"apis/TransmodelApi/#configuration","title":"Configuration","text":"

    To turn this API off, add the feature TransmodelGraphQlApi : false in otp-config.json.

    "},{"location":"apis/TransmodelApi/#changelog-old","title":"Changelog - old","text":"

    The Transmodel API is now part of the main OTP supported APIs. New changes in the changelog will be added to the main change log, and NOT here (2023-12-13).

    "},{"location":"examples/Readme/","title":"Example configurations","text":"

    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.

    "},{"location":"examples/Readme/#examples","title":"Examples","text":"Name Organisation Description entur Entur, Norway Deployment Configuration with NeTEX input data ibi IBI Group, USA Allow routing for wheelchair users even if accessibility data is incomplete skanetrafiken Sk\u00e5netrafiken, Sweden, Sk\u00e5ne Deployment Configuration with combination of NeTEx and GTFS input data"},{"location":"examples/Readme/#support","title":"Support","text":"

    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.

    "},{"location":"examples/Readme/#how-to-share-an-example","title":"How to share an example","text":"

    Anyone who want can add their example here as long as it is OTP \"related\". Just create a normal pull-request to add it.

    "},{"location":"examples/entur/Readme/","title":"Entur Deployment Configuration","text":"

    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.

    "},{"location":"examples/entur/Readme/#config-files","title":"Config files","text":"

    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 <host>, <OperatorNameSpace> and ${GCS_BUCKET} are placeholders you need to change.

    "},{"location":"examples/entur/Readme/#data-input-files","title":"Data input files","text":"

    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 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.

    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 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.

    "},{"location":"examples/skanetrafiken/Readme/","title":"Sk\u00e5netrafiken Deployment Configuration","text":"

    This is a snapshot of Sk\u00e5netrafiken deployment configuration. At Sk\u00e5netrafiken we deploy our OTP instances as microservices to a Kubernetes cluster. Some parts of the config are missing due to confidentiality.

    "},{"location":"examples/skanetrafiken/Readme/#data-input-files","title":"Data input files","text":""},{"location":"examples/skanetrafiken/Readme/#netex","title":"NeTEx","text":"

    NeTEx is used for transport data inside Sweden. Each night the system automatically builds new file based on data from SQL database. At the moment those files are not accessible through any public endpoint.

    "},{"location":"examples/skanetrafiken/Readme/#gtfs","title":"GTFS","text":"

    GTFS data is used for traffic inside Denmark. GTFS for danish public transport can be downloaded here. There is some processing applied to the original data so that unnecessary trips are filtered out and ID structure for journeys and stop point / stop places matches with the NeTEx. The modified GTFS is not accessible through any public endpoint either.

    "},{"location":"examples/skanetrafiken/Readme/#osm","title":"OSM","text":"

    Two different OSM files are used:

    "},{"location":"examples/skanetrafiken/Readme/#sweden","title":"Sweden","text":"

    OSM data is downloaded from http://download.geofabrik.de/europe/sweden-latest.osm.pbf. To reduced graph size, only data for southern part of Sweden is used.

    "},{"location":"examples/skanetrafiken/Readme/#denmark","title":"Denmark","text":"

    OSM data is downloaded from http://download.geofabrik.de/europe/denmark-latest.osm.pbf. To reduce graph size, only data for northern part of Denmark is used.

    "},{"location":"examples/skanetrafiken/Readme/#real-time","title":"Real-time","text":"

    The Azure Service Bus is used to propagate SIRI SX and ET real-time messages to OTP. This is solved through Siri Azure updaters that Sk\u00e5netrafiken had implemented in OTP. There are separate updaters for SIRI SX and ET. Those updaters are used to provide data for Swedish traffic (NeTEx). Right now, there is no connection to any real-time source for danish traffic (GTFS data).

    Except for receiving messages from Service Bus there are two endpoints through which historical ET and SX messages can be downloaded at OTP startup. The updater will first create new subscription on ServiceBus topic and then send request to the history endpoint. It can take some time get a response from the endpoint, so the timeout is set quite high. Once OTP is done with processing of history messages the updater will start querying messages from the subscription.

    Once the updaters are done with processing of history messages they will change their status to primed, and the system will start channeling request to this OTP instance. This ensures that no real-time message is omitted and all OTP instance that ran in the cluster does have exact same real-time data. Thi means that no matter which instance the client is hitting it will always get the same search results.

    "},{"location":"examples/skanetrafiken/Readme/#history-endpoint-contract","title":"History endpoint contract","text":"

    See the updaters section of router-config.json file provided in this folder. This is an example configuration for the updaters. The history configuration is optional. It can be skipped so that OTP does not fetch any historical messages on startup.

    There are two separate endpoints for respectively SX and ET. They are basic GET endpoints with following query parameters:

    parameters format fromDateTime ISO 8601 toDateTime ISO 8601

    Those two parameters are used to define time boundaries for the messages.

    Both endpoints generate XML response which is an SIRI object containing SX or ET messages. Messages are formatted according to Siri Nordic Profile. Since in SIRI ET standard each messages contains all necessary data, Sk\u00e5netrafikens implementation of the endpoint returns only the last message for each DatedServiceJourney ID (sending multiple messages would be pointless since they will override each other). The messages are processed in the same order as they came in (in the list) so it would still work to include multiple messages on same DatedServiceJourney as long as they are sorted in correct order and the newest message is the last one in the list.

    "},{"location":"examples/skanetrafiken/Readme/#matching-on-stop-arrival-times","title":"Matching on stop arrival-times","text":"

    Normally ET messages are matched with corresponding trips based on ServiceJourney or DatedServiceJourney id from the message. In case OTP was not able to find corresponding trip additional search will be performed based on arrival-times/stop-patterns from the ET message. This feature turned off by default but can be activated by adding fuzzyTripMatching property to updater configuration.

    "},{"location":"examples/skanetrafiken/Readme/#federatedidentity","title":"FederatedIdentity","text":"

    It is also possible to connect to Service Bus through FederatedIdentity. Change authenticationType to FederatedIdentity and provide fullyQualifiedNamespace in router-config.

    "},{"location":"features-explained/Netex-Siri-Compatibility/","title":"NeTEx and SIRI compatibility","text":"

    NeTEx and SIRI are two European public transport data specifications that are comparable to GTFS and GTFS-RT but have a broader scope. Support for both was added by Entur in OTP version 2 and you can find examples of those in their examples repo.

    "},{"location":"features-explained/Netex-Siri-Compatibility/#profiles","title":"Profiles","text":""},{"location":"features-explained/Netex-Siri-Compatibility/#nordic-profile","title":"Nordic profile","text":"

    Different countries are currently using different incompatible \"profiles\" of NeTEx, but an effort is underway to converge on a single European standard profile. This is based in large part on the Nordic profile used by Entur.

    The Nordic profile is the only profile that has been thoroughly tested in production in OTP and is used in Norway, Finland and Sweden.

    "},{"location":"features-explained/Netex-Siri-Compatibility/#epip","title":"EPIP","text":"

    The European Passenger Information Profile is an attempt to unify other country profiles and support in OTP is adequate, but it is difficult to tell how much of EPIP is supported since it is a very large profile. The current status of the support is tracked on Github.

    Sometimes it is difficult to tell if a file conforms to EPIP so to find out, you can run the following commands:

    git clone git@github.com:NeTEx-CEN/NeTEx-Profile-EPIP.git\nxmllint --noout --schema NeTEx-Profile-EPIP/NeTEx_publication_EPIP.xsd your-filename.xml\n
    "},{"location":"features-explained/Netex-Siri-Compatibility/#other-profiles","title":"Other profiles","text":"

    It is the goal of the community to support both the Nordic profile and EPIP. If you have another profile, we encourage to get in touch with the community to find a way forward.

    "},{"location":"osm/Finland/","title":"OSM tag mapping","text":"

    This page is intended to give an overview of which OpenStreetMap(OSM) tags OTP uses to evaluate its walking and bicycling instructions. If a tag is not part of the documentation on this page then this tag mapper (profile) does not use it.

    The exception are access permissions and wheelchair accessibility tags like

    These are identical for all mappers and not separately listed on this page.

    "},{"location":"osm/Finland/#way-properties","title":"Way properties","text":"

    Way properties set a way's permission and optionally influences its walk and bicycle safety factors.

    These factors determine how desirable an OSM way is when routing for cyclists and pedestrians. Lower safety values make an OSM way more desirable and higher values less desirable.

    specifier permission bike safety walk safety highway=living_street ALL 0.9 highway=unclassified ALL highway=road ALL highway=byway ALL 1.3 highway=track ALL 1.3 highway=service ALL 1.1 highway=residential ALL 0.98 highway=residential_link ALL 0.98 highway=tertiary ALL highway=tertiary_link ALL highway=secondary ALL 1.5 highway=secondary_link ALL 1.5 highway=primary ALL 2.06 highway=primary_link ALL 2.06 highway=trunk_link ALL 2.06 highway=trunk ALL 7.47 highway=trunk; tunnel=yes CAR 7.47 motorroad=yes CAR 7.47 present(highway); informal=yes NONE highway=service; access=private NONE highway=trail NONE present(highway); seasonal=winter NONE present(highway); ice_road=yes NONE present(highway); winter_road=yes NONE highway=footway PEDESTRIAN footway=sidewalk; highway=footway PEDESTRIAN highway=cycleway; segregated=yes PEDESTRIAN_AND_BICYCLE 0.6 1.1 highway=footway; bridge=yes PEDESTRIAN highway=footway; tunnel=yes PEDESTRIAN highway=cycleway; bridge=yes PEDESTRIAN_AND_BICYCLE 0.6 highway=cycleway; tunnel=yes PEDESTRIAN_AND_BICYCLE 0.6 highway=footway; footway=crossing; crossing=traffic_signals PEDESTRIAN 1.1 highway=footway; footway=crossing PEDESTRIAN 1.2 highway=cycleway; cycleway=crossing; segregated=yes; crossing=traffic_signals PEDESTRIAN_AND_BICYCLE 0.8 1.1 highway=cycleway; footway=crossing; segregated=yes; crossing=traffic_signals PEDESTRIAN 0.8 1.1 highway=cycleway; cycleway=crossing; segregated=yes PEDESTRIAN_AND_BICYCLE 1.2 1.2 highway=cycleway; footway=crossing; segregated=yes PEDESTRIAN 1.2 1.2 highway=cycleway; cycleway=crossing; crossing=traffic_signals PEDESTRIAN_AND_BICYCLE 0.8 1.15 highway=cycleway; footway=crossing; crossing=traffic_signals PEDESTRIAN_AND_BICYCLE 0.8 1.15 highway=cycleway; cycleway=crossing PEDESTRIAN_AND_BICYCLE 1.2 1.25 highway=cycleway; footway=crossing PEDESTRIAN_AND_BICYCLE 1.2 1.25 highway=cycleway; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.6 highway=service; tunnel=yes; access=destination NONE highway=service; access=destination ALL 1.1 mtb:scale=3 NONE mtb:scale=4 NONE mtb:scale=5 NONE mtb:scale=6 NONE highway=corridor PEDESTRIAN highway=steps PEDESTRIAN highway=crossing PEDESTRIAN highway=platform PEDESTRIAN public_transport=platform PEDESTRIAN railway=platform PEDESTRIAN footway=sidewalk; highway=footway PEDESTRIAN mtb:scale=1 PEDESTRIAN mtb:scale=2 PEDESTRIAN mtb:scale=0 PEDESTRIAN_AND_BICYCLE highway=cycleway PEDESTRIAN_AND_BICYCLE 0.6 highway=path PEDESTRIAN_AND_BICYCLE 0.75 highway=pedestrian PEDESTRIAN_AND_BICYCLE 0.9 highway=footway PEDESTRIAN_AND_BICYCLE 1.1 highway=bridleway PEDESTRIAN_AND_BICYCLE 1.3 highway=living_street ALL 0.9 highway=unclassified ALL highway=road ALL highway=byway ALL 1.3 highway=track ALL 1.3 highway=service ALL 1.1 highway=residential ALL 0.98 highway=residential_link ALL 0.98 highway=tertiary ALL highway=tertiary_link ALL highway=secondary ALL 1.5 highway=secondary_link ALL 1.5 highway=primary ALL 2.06 highway=primary_link ALL 2.06 highway=trunk_link CAR 2.06 highway=motorway_link CAR 2.06 highway=trunk CAR 7.47 highway=motorway CAR 8.0 present(highway); cycleway=lane PEDESTRIAN_AND_BICYCLE 0.87 highway=service; cycleway=lane ALL 0.77 highway=residential; cycleway=lane ALL 0.77 highway=residential_link; cycleway=lane ALL 0.77 highway=tertiary; cycleway=lane ALL 0.87 highway=tertiary_link; cycleway=lane ALL 0.87 highway=secondary; cycleway=lane ALL 0.96 highway=secondary_link; cycleway=lane ALL 0.96 highway=primary; cycleway=lane ALL 1.15 highway=primary_link; cycleway=lane ALL 1.15 highway=trunk; cycleway=lane BICYCLE_AND_CAR 1.5 highway=trunk_link; cycleway=lane BICYCLE_AND_CAR 1.15 highway=motorway; cycleway=lane BICYCLE_AND_CAR 2.0 highway=motorway_link; cycleway=lane BICYCLE_AND_CAR 1.15 present(highway); cycleway=share_busway PEDESTRIAN_AND_BICYCLE 0.92 highway=service; cycleway=share_busway ALL 0.85 highway=residential; cycleway=share_busway ALL 0.85 highway=residential_link; cycleway=share_busway ALL 0.85 highway=tertiary; cycleway=share_busway ALL 0.92 highway=tertiary_link; cycleway=share_busway ALL 0.92 highway=secondary; cycleway=share_busway ALL 0.99 highway=secondary_link; cycleway=share_busway ALL 0.99 highway=primary; cycleway=share_busway ALL 1.25 highway=primary_link; cycleway=share_busway ALL 1.25 highway=trunk; cycleway=share_busway BICYCLE_AND_CAR 1.75 highway=trunk_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 highway=motorway; cycleway=share_busway BICYCLE_AND_CAR 2.5 highway=motorway_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 present(highway); cycleway=opposite_lane PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.87 highway=service; cycleway=opposite_lane ALL forward: 1.1 back: 0.77 highway=residential; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=residential_link; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=tertiary; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=tertiary_link; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=secondary; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=secondary_link; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=primary; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=primary_link; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=trunk; cycleway=opposite_lane BICYCLE_AND_CAR forward: 7.47 back: 1.5 highway=trunk_link; cycleway=opposite_lane BICYCLE_AND_CAR forward: 2.06 back: 1.15 present(highway); cycleway=track PEDESTRIAN_AND_BICYCLE 0.75 highway=service; cycleway=track ALL 0.65 highway=residential; cycleway=track ALL 0.65 highway=residential_link; cycleway=track ALL 0.65 highway=tertiary; cycleway=track ALL 0.75 highway=tertiary_link; cycleway=track ALL 0.75 highway=secondary; cycleway=track ALL 0.8 highway=secondary_link; cycleway=track ALL 0.8 highway=primary; cycleway=track ALL 0.85 highway=primary_link; cycleway=track ALL 0.85 highway=trunk; cycleway=track BICYCLE_AND_CAR 0.95 highway=trunk_link; cycleway=track BICYCLE_AND_CAR 0.85 present(highway); cycleway=opposite_track PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.75 highway=service; cycleway=opposite_track ALL forward: 1.1 back: 0.65 highway=residential; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=residential_link; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=tertiary; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=tertiary_link; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=secondary; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=secondary_link; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=primary; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=primary_link; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=trunk; cycleway=opposite_track BICYCLE_AND_CAR forward: 7.47 back: 0.95 highway=trunk_link; cycleway=opposite_track BICYCLE_AND_CAR forward: 2.06 back: 0.85 present(highway); cycleway=shared_lane PEDESTRIAN_AND_BICYCLE 0.77 highway=service; cycleway=shared_lane ALL 0.73 highway=residential; cycleway=shared_lane ALL 0.77 highway=residential_link; cycleway=shared_lane ALL 0.77 highway=tertiary; cycleway=shared_lane ALL 0.83 highway=tertiary_link; cycleway=shared_lane ALL 0.83 highway=secondary; cycleway=shared_lane ALL 1.25 highway=secondary_link; cycleway=shared_lane ALL 1.25 highway=primary; cycleway=shared_lane ALL 1.75 highway=primary_link; cycleway=shared_lane ALL 1.75 present(highway); cycleway=opposite PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 1.4 highway=service; cycleway=opposite ALL 1.1 highway=residential; cycleway=opposite ALL 0.98 highway=residential_link; cycleway=opposite ALL 0.98 highway=tertiary; cycleway=opposite ALL highway=tertiary_link; cycleway=opposite ALL highway=secondary; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=secondary_link; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=primary; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=primary_link; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=path; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.6 highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 highway=footway; bicycle=yes; area=yes PEDESTRIAN_AND_BICYCLE 0.9 highway=pedestrian; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 footway=sidewalk; highway=footway; bicycle=yes PEDESTRIAN_AND_BICYCLE 2.5 footway=sidewalk; highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=footway; footway=crossing PEDESTRIAN_AND_BICYCLE 2.5 highway=footway; footway=crossing; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=track; bicycle=yes PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.99 highway=track; bicycle=yes; present(surface) PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated; present(surface) PEDESTRIAN_AND_BICYCLE 0.99 highway=track; present(surface) PEDESTRIAN_AND_BICYCLE 1.3 present(highway); bicycle=designated ALL 0.97 highway=service; bicycle=designated ALL 0.84 highway=residential; bicycle=designated ALL 0.95 highway=unclassified; bicycle=designated ALL 0.95 highway=residential_link; bicycle=designated ALL 0.95 highway=tertiary; bicycle=designated ALL 0.97 highway=tertiary_link; bicycle=designated ALL 0.97 highway=secondary; bicycle=designated ALL 1.46 highway=secondary_link; bicycle=designated ALL 1.46 highway=primary; bicycle=designated ALL 2.0 highway=primary_link; bicycle=designated ALL 2.0 highway=trunk; bicycle=designated BICYCLE_AND_CAR 7.25 highway=trunk_link; bicycle=designated BICYCLE_AND_CAR 2.0 highway=motorway; bicycle=designated BICYCLE_AND_CAR 7.76 highway=motorway_link; bicycle=designated BICYCLE_AND_CAR 2.0"},{"location":"osm/Finland/#safety-mixins","title":"Safety mixins","text":"

    Mixins are selectors that have only an effect on the bicycle and walk safety factors but not on the permission of an OSM way. Their safety values are multiplied with the base values from the selected way properties. Multiple mixins can apply to the same way and their effects compound.

    matcher bicycle safety walk safety bicycle=use_sidepath 5.0 lcn=yes\u00a6rcn=yes\u00a6ncn=yes\u00a6bicycle_road=yes\u00a6cyclestreet=yes 0.7 surface=unpaved 1.18 surface=compacted 1.18 surface=wood 1.18 surface=cobblestone 1.3 surface=sett 1.3 surface=unhewn_cobblestone 1.5 surface=grass_paver 1.3 surface=pebblestone 1.3 surface=metal 1.3 surface=ground 1.5 surface=dirt 1.5 surface=earth 1.5 surface=grass 1.5 surface=mud 1.5 surface=woodchip 1.5 surface=gravel 1.5 surface=artifical_turf 1.5 surface=sand 100.0 foot=discouraged 3.0 bicycle=discouraged 3.0 foot=use_sidepath 5.0 bicycle=use_sidepath 5.0"},{"location":"osm/Germany/","title":"OSM tag mapping","text":"

    This page is intended to give an overview of which OpenStreetMap(OSM) tags OTP uses to evaluate its walking and bicycling instructions. If a tag is not part of the documentation on this page then this tag mapper (profile) does not use it.

    The exception are access permissions and wheelchair accessibility tags like

    These are identical for all mappers and not separately listed on this page.

    "},{"location":"osm/Germany/#way-properties","title":"Way properties","text":"

    Way properties set a way's permission and optionally influences its walk and bicycle safety factors.

    These factors determine how desirable an OSM way is when routing for cyclists and pedestrians. Lower safety values make an OSM way more desirable and higher values less desirable.

    specifier permission bike safety walk safety highway=track PEDESTRIAN_AND_BICYCLE highway=track; present(surface) PEDESTRIAN_AND_BICYCLE highway=residential; junction=roundabout ALL 0.98 present(highway); junction=roundabout BICYCLE_AND_CAR highway=pedestrian PEDESTRIAN highway=residential; maxspeed=30 ALL 0.9 highway=footway; bicycle=yes PEDESTRIAN_AND_BICYCLE 0.8 footway=sidewalk; highway=footway; bicycle=yes PEDESTRIAN_AND_BICYCLE 1.2 highway=unclassified; cycleway=lane ALL 0.87 mtb:scale=3 NONE mtb:scale=4 NONE mtb:scale=5 NONE mtb:scale=6 NONE highway=corridor PEDESTRIAN highway=steps PEDESTRIAN highway=crossing PEDESTRIAN highway=platform PEDESTRIAN public_transport=platform PEDESTRIAN railway=platform PEDESTRIAN footway=sidewalk; highway=footway PEDESTRIAN mtb:scale=1 PEDESTRIAN mtb:scale=2 PEDESTRIAN mtb:scale=0 PEDESTRIAN_AND_BICYCLE highway=cycleway PEDESTRIAN_AND_BICYCLE 0.6 highway=path PEDESTRIAN_AND_BICYCLE 0.75 highway=pedestrian PEDESTRIAN_AND_BICYCLE 0.9 highway=footway PEDESTRIAN_AND_BICYCLE 1.1 highway=bridleway PEDESTRIAN_AND_BICYCLE 1.3 highway=living_street ALL 0.9 highway=unclassified ALL highway=road ALL highway=byway ALL 1.3 highway=track ALL 1.3 highway=service ALL 1.1 highway=residential ALL 0.98 highway=residential_link ALL 0.98 highway=tertiary ALL highway=tertiary_link ALL highway=secondary ALL 1.5 highway=secondary_link ALL 1.5 highway=primary ALL 2.06 highway=primary_link ALL 2.06 highway=trunk_link CAR 2.06 highway=motorway_link CAR 2.06 highway=trunk CAR 7.47 highway=motorway CAR 8.0 present(highway); cycleway=lane PEDESTRIAN_AND_BICYCLE 0.87 highway=service; cycleway=lane ALL 0.77 highway=residential; cycleway=lane ALL 0.77 highway=residential_link; cycleway=lane ALL 0.77 highway=tertiary; cycleway=lane ALL 0.87 highway=tertiary_link; cycleway=lane ALL 0.87 highway=secondary; cycleway=lane ALL 0.96 highway=secondary_link; cycleway=lane ALL 0.96 highway=primary; cycleway=lane ALL 1.15 highway=primary_link; cycleway=lane ALL 1.15 highway=trunk; cycleway=lane BICYCLE_AND_CAR 1.5 highway=trunk_link; cycleway=lane BICYCLE_AND_CAR 1.15 highway=motorway; cycleway=lane BICYCLE_AND_CAR 2.0 highway=motorway_link; cycleway=lane BICYCLE_AND_CAR 1.15 present(highway); cycleway=share_busway PEDESTRIAN_AND_BICYCLE 0.92 highway=service; cycleway=share_busway ALL 0.85 highway=residential; cycleway=share_busway ALL 0.85 highway=residential_link; cycleway=share_busway ALL 0.85 highway=tertiary; cycleway=share_busway ALL 0.92 highway=tertiary_link; cycleway=share_busway ALL 0.92 highway=secondary; cycleway=share_busway ALL 0.99 highway=secondary_link; cycleway=share_busway ALL 0.99 highway=primary; cycleway=share_busway ALL 1.25 highway=primary_link; cycleway=share_busway ALL 1.25 highway=trunk; cycleway=share_busway BICYCLE_AND_CAR 1.75 highway=trunk_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 highway=motorway; cycleway=share_busway BICYCLE_AND_CAR 2.5 highway=motorway_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 present(highway); cycleway=opposite_lane PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.87 highway=service; cycleway=opposite_lane ALL forward: 1.1 back: 0.77 highway=residential; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=residential_link; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=tertiary; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=tertiary_link; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=secondary; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=secondary_link; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=primary; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=primary_link; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=trunk; cycleway=opposite_lane BICYCLE_AND_CAR forward: 7.47 back: 1.5 highway=trunk_link; cycleway=opposite_lane BICYCLE_AND_CAR forward: 2.06 back: 1.15 present(highway); cycleway=track PEDESTRIAN_AND_BICYCLE 0.75 highway=service; cycleway=track ALL 0.65 highway=residential; cycleway=track ALL 0.65 highway=residential_link; cycleway=track ALL 0.65 highway=tertiary; cycleway=track ALL 0.75 highway=tertiary_link; cycleway=track ALL 0.75 highway=secondary; cycleway=track ALL 0.8 highway=secondary_link; cycleway=track ALL 0.8 highway=primary; cycleway=track ALL 0.85 highway=primary_link; cycleway=track ALL 0.85 highway=trunk; cycleway=track BICYCLE_AND_CAR 0.95 highway=trunk_link; cycleway=track BICYCLE_AND_CAR 0.85 present(highway); cycleway=opposite_track PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.75 highway=service; cycleway=opposite_track ALL forward: 1.1 back: 0.65 highway=residential; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=residential_link; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=tertiary; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=tertiary_link; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=secondary; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=secondary_link; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=primary; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=primary_link; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=trunk; cycleway=opposite_track BICYCLE_AND_CAR forward: 7.47 back: 0.95 highway=trunk_link; cycleway=opposite_track BICYCLE_AND_CAR forward: 2.06 back: 0.85 present(highway); cycleway=shared_lane PEDESTRIAN_AND_BICYCLE 0.77 highway=service; cycleway=shared_lane ALL 0.73 highway=residential; cycleway=shared_lane ALL 0.77 highway=residential_link; cycleway=shared_lane ALL 0.77 highway=tertiary; cycleway=shared_lane ALL 0.83 highway=tertiary_link; cycleway=shared_lane ALL 0.83 highway=secondary; cycleway=shared_lane ALL 1.25 highway=secondary_link; cycleway=shared_lane ALL 1.25 highway=primary; cycleway=shared_lane ALL 1.75 highway=primary_link; cycleway=shared_lane ALL 1.75 present(highway); cycleway=opposite PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 1.4 highway=service; cycleway=opposite ALL 1.1 highway=residential; cycleway=opposite ALL 0.98 highway=residential_link; cycleway=opposite ALL 0.98 highway=tertiary; cycleway=opposite ALL highway=tertiary_link; cycleway=opposite ALL highway=secondary; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=secondary_link; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=primary; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=primary_link; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=path; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.6 highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 highway=footway; bicycle=yes; area=yes PEDESTRIAN_AND_BICYCLE 0.9 highway=pedestrian; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 footway=sidewalk; highway=footway; bicycle=yes PEDESTRIAN_AND_BICYCLE 2.5 footway=sidewalk; highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=footway; footway=crossing PEDESTRIAN_AND_BICYCLE 2.5 highway=footway; footway=crossing; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=track; bicycle=yes PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.99 highway=track; bicycle=yes; present(surface) PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated; present(surface) PEDESTRIAN_AND_BICYCLE 0.99 highway=track; present(surface) PEDESTRIAN_AND_BICYCLE 1.3 present(highway); bicycle=designated ALL 0.97 highway=service; bicycle=designated ALL 0.84 highway=residential; bicycle=designated ALL 0.95 highway=unclassified; bicycle=designated ALL 0.95 highway=residential_link; bicycle=designated ALL 0.95 highway=tertiary; bicycle=designated ALL 0.97 highway=tertiary_link; bicycle=designated ALL 0.97 highway=secondary; bicycle=designated ALL 1.46 highway=secondary_link; bicycle=designated ALL 1.46 highway=primary; bicycle=designated ALL 2.0 highway=primary_link; bicycle=designated ALL 2.0 highway=trunk; bicycle=designated BICYCLE_AND_CAR 7.25 highway=trunk_link; bicycle=designated BICYCLE_AND_CAR 2.0 highway=motorway; bicycle=designated BICYCLE_AND_CAR 7.76 highway=motorway_link; bicycle=designated BICYCLE_AND_CAR 2.0"},{"location":"osm/Germany/#safety-mixins","title":"Safety mixins","text":"

    Mixins are selectors that have only an effect on the bicycle and walk safety factors but not on the permission of an OSM way. Their safety values are multiplied with the base values from the selected way properties. Multiple mixins can apply to the same way and their effects compound.

    matcher bicycle safety walk safety highway=tertiary 1.2 maxspeed=70 1.5 maxspeed=80 2.0 maxspeed=90 3.0 maxspeed=100 5.0 tracktype=grade1 tracktype=grade2 1.1 tracktype=grade3 1.15 tracktype=grade4 1.3 tracktype=grade5 1.5 lit=no 1.05 lcn=yes\u00a6rcn=yes\u00a6ncn=yes\u00a6bicycle_road=yes\u00a6cyclestreet=yes 0.7 surface=unpaved 1.18 surface=compacted 1.18 surface=wood 1.18 surface=cobblestone 1.3 surface=sett 1.3 surface=unhewn_cobblestone 1.5 surface=grass_paver 1.3 surface=pebblestone 1.3 surface=metal 1.3 surface=ground 1.5 surface=dirt 1.5 surface=earth 1.5 surface=grass 1.5 surface=mud 1.5 surface=woodchip 1.5 surface=gravel 1.5 surface=artifical_turf 1.5 surface=sand 100.0 foot=discouraged 3.0 bicycle=discouraged 3.0 foot=use_sidepath 5.0 bicycle=use_sidepath 5.0"},{"location":"osm/Norway/","title":"OSM tag mapping","text":"

    This page is intended to give an overview of which OpenStreetMap(OSM) tags OTP uses to evaluate its walking and bicycling instructions. If a tag is not part of the documentation on this page then this tag mapper (profile) does not use it.

    The exception are access permissions and wheelchair accessibility tags like

    These are identical for all mappers and not separately listed on this page.

    "},{"location":"osm/Norway/#way-properties","title":"Way properties","text":"

    Way properties set a way's permission and optionally influences its walk and bicycle safety factors.

    These factors determine how desirable an OSM way is when routing for cyclists and pedestrians. Lower safety values make an OSM way more desirable and higher values less desirable.

    specifier permission bike safety walk safety highway one of [motorway, motorway_link] CAR highway one of [trunk, trunk_link, primary, primary_link]; motorroad=yes CAR highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link, unclassified, residential] ALL cycleway=track; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link, unclassified, residential] ALL cycleway=lane; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link] ALL 1.27 cycleway=lane; maxspeed < 50; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link] ALL 1.1 cycleway=lane; highway one of [unclassified, residential] ALL 1.1 highway=service ALL highway=service; service=parking_aisle ALL 2.5 highway=service; service=drive-through ALL 2.5 highway=living_street ALL 1.83 highway=pedestrian PEDESTRIAN_AND_BICYCLE 1.2 highway=busway PEDESTRIAN_AND_BICYCLE 2.37 1.9 highway=service; bus one of [yes, designated] PEDESTRIAN_AND_BICYCLE 2.37 1.9 highway=footway PEDESTRIAN_AND_BICYCLE 1.42 highway=cycleway PEDESTRIAN_AND_BICYCLE 1.05 1.4 highway=cycleway; lanes > 1 PEDESTRIAN_AND_BICYCLE 1.4 highway=cycleway; oneway=yes PEDESTRIAN_AND_BICYCLE 1.4 highway=cycleway; sidewalk one of [yes, left, right, both] PEDESTRIAN_AND_BICYCLE 1.05 highway=cycleway; lanes > 1; sidewalk one of [yes, left, right, both] PEDESTRIAN_AND_BICYCLE highway=cycleway; oneway=yes; sidewalk one of [yes, left, right, both] PEDESTRIAN_AND_BICYCLE highway=cycleway; foot=designated; segregated=no PEDESTRIAN_AND_BICYCLE 1.05 1.15 highway=path; foot=designated; bicycle=designated; segregated=no PEDESTRIAN_AND_BICYCLE 1.05 1.15 highway=cycleway; foot=designated; segregated=yes PEDESTRIAN_AND_BICYCLE 1.05 highway=path; foot=designated; bicycle=designated; segregated=yes PEDESTRIAN_AND_BICYCLE 1.05 highway=cycleway; foot=designated; segregated=yes; lanes > 1 PEDESTRIAN_AND_BICYCLE highway=cycleway; foot=designated; present(segregated); motor_vehicle=destination PEDESTRIAN_AND_BICYCLE 1.57 highway=path; foot=designated; bicycle=designated; present(segregated); motor_vehicle=destination PEDESTRIAN_AND_BICYCLE 1.57 highway=footway; footway=sidewalk PEDESTRIAN_AND_BICYCLE 1.93 1.1 highway=footway; footway=crossing PEDESTRIAN_AND_BICYCLE 2.33 1.35 highway=cycleway; cycleway=crossing PEDESTRIAN_AND_BICYCLE 2.33 1.35 highway=track PEDESTRIAN_AND_BICYCLE highway=bridleway PEDESTRIAN_AND_BICYCLE highway=path PEDESTRIAN_AND_BICYCLE highway=steps PEDESTRIAN highway=corridor PEDESTRIAN highway=footway; indoor=yes PEDESTRIAN highway=platform PEDESTRIAN public_transport=platform PEDESTRIAN trail_visibility one of [bad, low, poor, horrible, no]; highway=path NONE sac_scale one of [demanding_mountain_hiking, alpine_hiking, demanding_alpine_hiking, difficult_alpine_hiking]; highway one of [path, steps] NONE smoothness one of [horrible, very_horrible]; highway one of [path, bridleway, track] PEDESTRIAN 1.15 smoothness=impassable; highway one of [path, bridleway, track] NONE 1 > mtb:scale < 2; highway one of [path, bridleway, track] PEDESTRIAN 1.15 mtb:scale > 2; highway one of [path, bridleway, track] NONE"},{"location":"osm/Norway/#safety-mixins","title":"Safety mixins","text":"

    Mixins are selectors that have only an effect on the bicycle and walk safety factors but not on the permission of an OSM way. Their safety values are multiplied with the base values from the selected way properties. Multiple mixins can apply to the same way and their effects compound.

    matcher bicycle safety walk safety cycleway=shared_lane; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link, unclassified, residential] 0.85 lcn=yes\u00a6rcn=yes\u00a6ncn=yes 0.85 oneway=yes; cycleway not one of [no, none] or absent; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link, unclassified, residential] forward: 1.0 back: 1.15 embedded_rails one of [tram, light_rail, disused] 1.2 tunnel=yes; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link, unclassified] 2.0 bridge=yes; sidewalk not one of [no, separate] or absent; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link, unclassified]\u00a6verge=no; sidewalk not one of [no, separate] or absent; highway one of [trunk, trunk_link, primary, primary_link, secondary, secondary_link, tertiary, tertiary_link, unclassified] 2.0 junction=roundabout; sidewalk not one of [no, separate] or absent 2.0 surface=grass_paver 1.2 surface=sett 1.2 surface=cobblestone 1.2 surface=unhewn_cobblestone 3.0 surface=metal_grid 1.2 surface=metal 1.2 smoothness=intermediate; surface one of [asfalt, concrete, paving_stones, paved, wood] 1.2 smoothness=bad; surface one of [asfalt, concrete, paving_stones, paved, wood] 1.4 1.6 surface=unpaved; !tracktype 1.8 1.6 surface=compacted 1.4 1.4 surface=fine_gravel 1.8 1.6 surface=pebblestone 1.8 1.6 surface=gravel 1.8 1.6 surface=woodchip 1.8 1.6 surface=ground 2.3 2.4 surface=dirt 2.3 2.4 surface=earth 2.3 2.4 surface=grass 2.3 1.8 surface=mud 3.0 3.0 surface=sand 3.0 1.8 !tracktype; surface not one of [unpaved] or absent; highway one of [track, bridleway] 1.8 1.6 tracktype=grade2; surface not one of [unpaved] or absent; highway one of [track, bridleway, service, unclassified] 1.4 1.4 tracktype=grade3; surface not one of [unpaved] or absent; highway one of [track, bridleway, service, unclassified] 1.8 1.6 tracktype=grade4; surface not one of [unpaved] or absent; highway one of [track, bridleway, service, unclassified] 2.3 1.8 tracktype=grade5; surface not one of [unpaved] or absent; highway one of [track, bridleway, service, unclassified] 2.3 2.4 surface not one of [no, none] or absent; highway=path 2.3 2.4 sac_scale=mountain_hiking 1.8 trail_visibility=intermediate 1.8"},{"location":"osm/OsmTag/","title":"OSM tag mapping","text":"

    This page is intended to give an overview of which OpenStreetMap(OSM) tags OTP uses to evaluate its walking and bicycling instructions. If a tag is not part of the documentation on this page then this tag mapper (profile) does not use it.

    The exception are access permissions and wheelchair accessibility tags like

    These are identical for all mappers and not separately listed on this page.

    "},{"location":"osm/OsmTag/#way-properties","title":"Way properties","text":"

    Way properties set a way's permission and optionally influences its walk and bicycle safety factors.

    These factors determine how desirable an OSM way is when routing for cyclists and pedestrians. Lower safety values make an OSM way more desirable and higher values less desirable.

    specifier permission bike safety walk safety mtb:scale=3 NONE mtb:scale=4 NONE mtb:scale=5 NONE mtb:scale=6 NONE highway=corridor PEDESTRIAN highway=steps PEDESTRIAN highway=crossing PEDESTRIAN highway=platform PEDESTRIAN public_transport=platform PEDESTRIAN railway=platform PEDESTRIAN footway=sidewalk; highway=footway PEDESTRIAN mtb:scale=1 PEDESTRIAN mtb:scale=2 PEDESTRIAN mtb:scale=0 PEDESTRIAN_AND_BICYCLE highway=cycleway PEDESTRIAN_AND_BICYCLE 0.6 highway=path PEDESTRIAN_AND_BICYCLE 0.75 highway=pedestrian PEDESTRIAN_AND_BICYCLE 0.9 highway=footway PEDESTRIAN_AND_BICYCLE 1.1 highway=bridleway PEDESTRIAN_AND_BICYCLE 1.3 highway=living_street ALL 0.9 highway=unclassified ALL highway=road ALL highway=byway ALL 1.3 highway=track ALL 1.3 highway=service ALL 1.1 highway=residential ALL 0.98 highway=residential_link ALL 0.98 highway=tertiary ALL highway=tertiary_link ALL highway=secondary ALL 1.5 highway=secondary_link ALL 1.5 highway=primary ALL 2.06 highway=primary_link ALL 2.06 highway=trunk_link CAR 2.06 highway=motorway_link CAR 2.06 highway=trunk CAR 7.47 highway=motorway CAR 8.0 present(highway); cycleway=lane PEDESTRIAN_AND_BICYCLE 0.87 highway=service; cycleway=lane ALL 0.77 highway=residential; cycleway=lane ALL 0.77 highway=residential_link; cycleway=lane ALL 0.77 highway=tertiary; cycleway=lane ALL 0.87 highway=tertiary_link; cycleway=lane ALL 0.87 highway=secondary; cycleway=lane ALL 0.96 highway=secondary_link; cycleway=lane ALL 0.96 highway=primary; cycleway=lane ALL 1.15 highway=primary_link; cycleway=lane ALL 1.15 highway=trunk; cycleway=lane BICYCLE_AND_CAR 1.5 highway=trunk_link; cycleway=lane BICYCLE_AND_CAR 1.15 highway=motorway; cycleway=lane BICYCLE_AND_CAR 2.0 highway=motorway_link; cycleway=lane BICYCLE_AND_CAR 1.15 present(highway); cycleway=share_busway PEDESTRIAN_AND_BICYCLE 0.92 highway=service; cycleway=share_busway ALL 0.85 highway=residential; cycleway=share_busway ALL 0.85 highway=residential_link; cycleway=share_busway ALL 0.85 highway=tertiary; cycleway=share_busway ALL 0.92 highway=tertiary_link; cycleway=share_busway ALL 0.92 highway=secondary; cycleway=share_busway ALL 0.99 highway=secondary_link; cycleway=share_busway ALL 0.99 highway=primary; cycleway=share_busway ALL 1.25 highway=primary_link; cycleway=share_busway ALL 1.25 highway=trunk; cycleway=share_busway BICYCLE_AND_CAR 1.75 highway=trunk_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 highway=motorway; cycleway=share_busway BICYCLE_AND_CAR 2.5 highway=motorway_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 present(highway); cycleway=opposite_lane PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.87 highway=service; cycleway=opposite_lane ALL forward: 1.1 back: 0.77 highway=residential; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=residential_link; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=tertiary; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=tertiary_link; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=secondary; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=secondary_link; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=primary; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=primary_link; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=trunk; cycleway=opposite_lane BICYCLE_AND_CAR forward: 7.47 back: 1.5 highway=trunk_link; cycleway=opposite_lane BICYCLE_AND_CAR forward: 2.06 back: 1.15 present(highway); cycleway=track PEDESTRIAN_AND_BICYCLE 0.75 highway=service; cycleway=track ALL 0.65 highway=residential; cycleway=track ALL 0.65 highway=residential_link; cycleway=track ALL 0.65 highway=tertiary; cycleway=track ALL 0.75 highway=tertiary_link; cycleway=track ALL 0.75 highway=secondary; cycleway=track ALL 0.8 highway=secondary_link; cycleway=track ALL 0.8 highway=primary; cycleway=track ALL 0.85 highway=primary_link; cycleway=track ALL 0.85 highway=trunk; cycleway=track BICYCLE_AND_CAR 0.95 highway=trunk_link; cycleway=track BICYCLE_AND_CAR 0.85 present(highway); cycleway=opposite_track PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.75 highway=service; cycleway=opposite_track ALL forward: 1.1 back: 0.65 highway=residential; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=residential_link; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=tertiary; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=tertiary_link; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=secondary; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=secondary_link; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=primary; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=primary_link; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=trunk; cycleway=opposite_track BICYCLE_AND_CAR forward: 7.47 back: 0.95 highway=trunk_link; cycleway=opposite_track BICYCLE_AND_CAR forward: 2.06 back: 0.85 present(highway); cycleway=shared_lane PEDESTRIAN_AND_BICYCLE 0.77 highway=service; cycleway=shared_lane ALL 0.73 highway=residential; cycleway=shared_lane ALL 0.77 highway=residential_link; cycleway=shared_lane ALL 0.77 highway=tertiary; cycleway=shared_lane ALL 0.83 highway=tertiary_link; cycleway=shared_lane ALL 0.83 highway=secondary; cycleway=shared_lane ALL 1.25 highway=secondary_link; cycleway=shared_lane ALL 1.25 highway=primary; cycleway=shared_lane ALL 1.75 highway=primary_link; cycleway=shared_lane ALL 1.75 present(highway); cycleway=opposite PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 1.4 highway=service; cycleway=opposite ALL 1.1 highway=residential; cycleway=opposite ALL 0.98 highway=residential_link; cycleway=opposite ALL 0.98 highway=tertiary; cycleway=opposite ALL highway=tertiary_link; cycleway=opposite ALL highway=secondary; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=secondary_link; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=primary; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=primary_link; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=path; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.6 highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 highway=footway; bicycle=yes; area=yes PEDESTRIAN_AND_BICYCLE 0.9 highway=pedestrian; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 footway=sidewalk; highway=footway; bicycle=yes PEDESTRIAN_AND_BICYCLE 2.5 footway=sidewalk; highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=footway; footway=crossing PEDESTRIAN_AND_BICYCLE 2.5 highway=footway; footway=crossing; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=track; bicycle=yes PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.99 highway=track; bicycle=yes; present(surface) PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated; present(surface) PEDESTRIAN_AND_BICYCLE 0.99 highway=track; present(surface) PEDESTRIAN_AND_BICYCLE 1.3 present(highway); bicycle=designated ALL 0.97 highway=service; bicycle=designated ALL 0.84 highway=residential; bicycle=designated ALL 0.95 highway=unclassified; bicycle=designated ALL 0.95 highway=residential_link; bicycle=designated ALL 0.95 highway=tertiary; bicycle=designated ALL 0.97 highway=tertiary_link; bicycle=designated ALL 0.97 highway=secondary; bicycle=designated ALL 1.46 highway=secondary_link; bicycle=designated ALL 1.46 highway=primary; bicycle=designated ALL 2.0 highway=primary_link; bicycle=designated ALL 2.0 highway=trunk; bicycle=designated BICYCLE_AND_CAR 7.25 highway=trunk_link; bicycle=designated BICYCLE_AND_CAR 2.0 highway=motorway; bicycle=designated BICYCLE_AND_CAR 7.76 highway=motorway_link; bicycle=designated BICYCLE_AND_CAR 2.0"},{"location":"osm/OsmTag/#safety-mixins","title":"Safety mixins","text":"

    Mixins are selectors that have only an effect on the bicycle and walk safety factors but not on the permission of an OSM way. Their safety values are multiplied with the base values from the selected way properties. Multiple mixins can apply to the same way and their effects compound.

    matcher bicycle safety walk safety lcn=yes\u00a6rcn=yes\u00a6ncn=yes\u00a6bicycle_road=yes\u00a6cyclestreet=yes 0.7 surface=unpaved 1.18 surface=compacted 1.18 surface=wood 1.18 surface=cobblestone 1.3 surface=sett 1.3 surface=unhewn_cobblestone 1.5 surface=grass_paver 1.3 surface=pebblestone 1.3 surface=metal 1.3 surface=ground 1.5 surface=dirt 1.5 surface=earth 1.5 surface=grass 1.5 surface=mud 1.5 surface=woodchip 1.5 surface=gravel 1.5 surface=artifical_turf 1.5 surface=sand 100.0 foot=discouraged 3.0 bicycle=discouraged 3.0 foot=use_sidepath 5.0 bicycle=use_sidepath 5.0"},{"location":"osm/UK/","title":"OSM tag mapping","text":"

    This page is intended to give an overview of which OpenStreetMap(OSM) tags OTP uses to evaluate its walking and bicycling instructions. If a tag is not part of the documentation on this page then this tag mapper (profile) does not use it.

    The exception are access permissions and wheelchair accessibility tags like

    These are identical for all mappers and not separately listed on this page.

    "},{"location":"osm/UK/#way-properties","title":"Way properties","text":"

    Way properties set a way's permission and optionally influences its walk and bicycle safety factors.

    These factors determine how desirable an OSM way is when routing for cyclists and pedestrians. Lower safety values make an OSM way more desirable and higher values less desirable.

    specifier permission bike safety walk safety highway=trunk_link ALL 2.06 highway=trunk ALL 7.47 highway=trunk; cycleway=lane ALL 1.5 highway=trunk_link; cycleway=lane ALL 1.15 highway=trunk; cycleway=share_busway ALL 1.75 highway=trunk_link; cycleway=share_busway ALL 1.25 highway=trunk; cycleway=opposite_lane ALL forward: 7.47 back: 1.5 highway=trunk_link; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=trunk; cycleway=track ALL 0.95 highway=trunk_link; cycleway=track ALL 0.85 highway=trunk; cycleway=opposite_track ALL forward: 7.47 back: 0.95 highway=trunk_link; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=trunk; bicycle=designated ALL 7.25 highway=trunk_link; bicycle=designated ALL 2.0 indoor=area PEDESTRIAN indoor=corridor PEDESTRIAN mtb:scale=3 NONE mtb:scale=4 NONE mtb:scale=5 NONE mtb:scale=6 NONE highway=corridor PEDESTRIAN highway=steps PEDESTRIAN highway=crossing PEDESTRIAN highway=platform PEDESTRIAN public_transport=platform PEDESTRIAN railway=platform PEDESTRIAN footway=sidewalk; highway=footway PEDESTRIAN mtb:scale=1 PEDESTRIAN mtb:scale=2 PEDESTRIAN mtb:scale=0 PEDESTRIAN_AND_BICYCLE highway=cycleway PEDESTRIAN_AND_BICYCLE 0.6 highway=path PEDESTRIAN_AND_BICYCLE 0.75 highway=pedestrian PEDESTRIAN_AND_BICYCLE 0.9 highway=footway PEDESTRIAN_AND_BICYCLE 1.1 highway=bridleway PEDESTRIAN_AND_BICYCLE 1.3 highway=living_street ALL 0.9 highway=unclassified ALL highway=road ALL highway=byway ALL 1.3 highway=track ALL 1.3 highway=service ALL 1.1 highway=residential ALL 0.98 highway=residential_link ALL 0.98 highway=tertiary ALL highway=tertiary_link ALL highway=secondary ALL 1.5 highway=secondary_link ALL 1.5 highway=primary ALL 2.06 highway=primary_link ALL 2.06 highway=trunk_link CAR 2.06 highway=motorway_link CAR 2.06 highway=trunk CAR 7.47 highway=motorway CAR 8.0 present(highway); cycleway=lane PEDESTRIAN_AND_BICYCLE 0.87 highway=service; cycleway=lane ALL 0.77 highway=residential; cycleway=lane ALL 0.77 highway=residential_link; cycleway=lane ALL 0.77 highway=tertiary; cycleway=lane ALL 0.87 highway=tertiary_link; cycleway=lane ALL 0.87 highway=secondary; cycleway=lane ALL 0.96 highway=secondary_link; cycleway=lane ALL 0.96 highway=primary; cycleway=lane ALL 1.15 highway=primary_link; cycleway=lane ALL 1.15 highway=trunk; cycleway=lane BICYCLE_AND_CAR 1.5 highway=trunk_link; cycleway=lane BICYCLE_AND_CAR 1.15 highway=motorway; cycleway=lane BICYCLE_AND_CAR 2.0 highway=motorway_link; cycleway=lane BICYCLE_AND_CAR 1.15 present(highway); cycleway=share_busway PEDESTRIAN_AND_BICYCLE 0.92 highway=service; cycleway=share_busway ALL 0.85 highway=residential; cycleway=share_busway ALL 0.85 highway=residential_link; cycleway=share_busway ALL 0.85 highway=tertiary; cycleway=share_busway ALL 0.92 highway=tertiary_link; cycleway=share_busway ALL 0.92 highway=secondary; cycleway=share_busway ALL 0.99 highway=secondary_link; cycleway=share_busway ALL 0.99 highway=primary; cycleway=share_busway ALL 1.25 highway=primary_link; cycleway=share_busway ALL 1.25 highway=trunk; cycleway=share_busway BICYCLE_AND_CAR 1.75 highway=trunk_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 highway=motorway; cycleway=share_busway BICYCLE_AND_CAR 2.5 highway=motorway_link; cycleway=share_busway BICYCLE_AND_CAR 1.25 present(highway); cycleway=opposite_lane PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.87 highway=service; cycleway=opposite_lane ALL forward: 1.1 back: 0.77 highway=residential; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=residential_link; cycleway=opposite_lane ALL forward: 0.98 back: 0.77 highway=tertiary; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=tertiary_link; cycleway=opposite_lane ALL forward: 1.0 back: 0.87 highway=secondary; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=secondary_link; cycleway=opposite_lane ALL forward: 1.5 back: 0.96 highway=primary; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=primary_link; cycleway=opposite_lane ALL forward: 2.06 back: 1.15 highway=trunk; cycleway=opposite_lane BICYCLE_AND_CAR forward: 7.47 back: 1.5 highway=trunk_link; cycleway=opposite_lane BICYCLE_AND_CAR forward: 2.06 back: 1.15 present(highway); cycleway=track PEDESTRIAN_AND_BICYCLE 0.75 highway=service; cycleway=track ALL 0.65 highway=residential; cycleway=track ALL 0.65 highway=residential_link; cycleway=track ALL 0.65 highway=tertiary; cycleway=track ALL 0.75 highway=tertiary_link; cycleway=track ALL 0.75 highway=secondary; cycleway=track ALL 0.8 highway=secondary_link; cycleway=track ALL 0.8 highway=primary; cycleway=track ALL 0.85 highway=primary_link; cycleway=track ALL 0.85 highway=trunk; cycleway=track BICYCLE_AND_CAR 0.95 highway=trunk_link; cycleway=track BICYCLE_AND_CAR 0.85 present(highway); cycleway=opposite_track PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 0.75 highway=service; cycleway=opposite_track ALL forward: 1.1 back: 0.65 highway=residential; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=residential_link; cycleway=opposite_track ALL forward: 0.98 back: 0.65 highway=tertiary; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=tertiary_link; cycleway=opposite_track ALL forward: 1.0 back: 0.75 highway=secondary; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=secondary_link; cycleway=opposite_track ALL forward: 1.5 back: 0.8 highway=primary; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=primary_link; cycleway=opposite_track ALL forward: 2.06 back: 0.85 highway=trunk; cycleway=opposite_track BICYCLE_AND_CAR forward: 7.47 back: 0.95 highway=trunk_link; cycleway=opposite_track BICYCLE_AND_CAR forward: 2.06 back: 0.85 present(highway); cycleway=shared_lane PEDESTRIAN_AND_BICYCLE 0.77 highway=service; cycleway=shared_lane ALL 0.73 highway=residential; cycleway=shared_lane ALL 0.77 highway=residential_link; cycleway=shared_lane ALL 0.77 highway=tertiary; cycleway=shared_lane ALL 0.83 highway=tertiary_link; cycleway=shared_lane ALL 0.83 highway=secondary; cycleway=shared_lane ALL 1.25 highway=secondary_link; cycleway=shared_lane ALL 1.25 highway=primary; cycleway=shared_lane ALL 1.75 highway=primary_link; cycleway=shared_lane ALL 1.75 present(highway); cycleway=opposite PEDESTRIAN_AND_BICYCLE forward: 1.0 back: 1.4 highway=service; cycleway=opposite ALL 1.1 highway=residential; cycleway=opposite ALL 0.98 highway=residential_link; cycleway=opposite ALL 0.98 highway=tertiary; cycleway=opposite ALL highway=tertiary_link; cycleway=opposite ALL highway=secondary; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=secondary_link; cycleway=opposite ALL forward: 1.5 back: 1.71 highway=primary; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=primary_link; cycleway=opposite ALL forward: 2.06 back: 2.99 highway=path; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.6 highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 highway=footway; bicycle=yes; area=yes PEDESTRIAN_AND_BICYCLE 0.9 highway=pedestrian; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.75 footway=sidewalk; highway=footway; bicycle=yes PEDESTRIAN_AND_BICYCLE 2.5 footway=sidewalk; highway=footway; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=footway; footway=crossing PEDESTRIAN_AND_BICYCLE 2.5 highway=footway; footway=crossing; bicycle=designated PEDESTRIAN_AND_BICYCLE 1.1 highway=track; bicycle=yes PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated PEDESTRIAN_AND_BICYCLE 0.99 highway=track; bicycle=yes; present(surface) PEDESTRIAN_AND_BICYCLE 1.18 highway=track; bicycle=designated; present(surface) PEDESTRIAN_AND_BICYCLE 0.99 highway=track; present(surface) PEDESTRIAN_AND_BICYCLE 1.3 present(highway); bicycle=designated ALL 0.97 highway=service; bicycle=designated ALL 0.84 highway=residential; bicycle=designated ALL 0.95 highway=unclassified; bicycle=designated ALL 0.95 highway=residential_link; bicycle=designated ALL 0.95 highway=tertiary; bicycle=designated ALL 0.97 highway=tertiary_link; bicycle=designated ALL 0.97 highway=secondary; bicycle=designated ALL 1.46 highway=secondary_link; bicycle=designated ALL 1.46 highway=primary; bicycle=designated ALL 2.0 highway=primary_link; bicycle=designated ALL 2.0 highway=trunk; bicycle=designated BICYCLE_AND_CAR 7.25 highway=trunk_link; bicycle=designated BICYCLE_AND_CAR 2.0 highway=motorway; bicycle=designated BICYCLE_AND_CAR 7.76 highway=motorway_link; bicycle=designated BICYCLE_AND_CAR 2.0"},{"location":"osm/UK/#safety-mixins","title":"Safety mixins","text":"

    Mixins are selectors that have only an effect on the bicycle and walk safety factors but not on the permission of an OSM way. Their safety values are multiplied with the base values from the selected way properties. Multiple mixins can apply to the same way and their effects compound.

    matcher bicycle safety walk safety lcn=yes\u00a6rcn=yes\u00a6ncn=yes\u00a6bicycle_road=yes\u00a6cyclestreet=yes 0.7 surface=unpaved 1.18 surface=compacted 1.18 surface=wood 1.18 surface=cobblestone 1.3 surface=sett 1.3 surface=unhewn_cobblestone 1.5 surface=grass_paver 1.3 surface=pebblestone 1.3 surface=metal 1.3 surface=ground 1.5 surface=dirt 1.5 surface=earth 1.5 surface=grass 1.5 surface=mud 1.5 surface=woodchip 1.5 surface=gravel 1.5 surface=artifical_turf 1.5 surface=sand 100.0 foot=discouraged 3.0 bicycle=discouraged 3.0 foot=use_sidepath 5.0 bicycle=use_sidepath 5.0"},{"location":"sandbox/ActuatorAPI/","title":"Actuator API","text":""},{"location":"sandbox/ActuatorAPI/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/ActuatorAPI/#changelog","title":"Changelog","text":""},{"location":"sandbox/ActuatorAPI/#documentation","title":"Documentation","text":"

    This provides endpoints for checking the health status of the OTP instance. It can be useful when running OTP in a container.

    The API will be at the endpoint http://localhost:8080/otp/actuators and follows the Spring Boot actuator API standard.

    "},{"location":"sandbox/ActuatorAPI/#configuration","title":"Configuration","text":"

    To enable this you need to add the feature ActuatorAPI.

    // otp-config.json\n{\n  \"otpFeatures\" : {\n    \"ActuatorAPI\": true\n  }\n}\n
    "},{"location":"sandbox/ActuatorAPI/#endpoints","title":"Endpoints","text":""},{"location":"sandbox/ActuatorAPI/#health","title":"/health","text":"

    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.

    "},{"location":"sandbox/ActuatorAPI/#prometheus","title":"/prometheus","text":"

    Prometheus metrics are returned using Micrometer. The default JVM and jersey metrics are enabled.

    Also, GraphQL timing metrics are exported under graphql.timer.query and graphql.timer.resolver, if the GraphQL endpoints are enabled.

    "},{"location":"sandbox/DataOverlay/","title":"Data Overlay","text":"

    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.

    "},{"location":"sandbox/DataOverlay/#contact-info","title":"Contact Info","text":"

    Developed and maintained by Metatavu OY, Finland.

    Developers:

    Katja Danilova - katja.danilova@metatavu.fi\\ 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.

    Company email: info@metatavu.fi

    "},{"location":"sandbox/DataOverlay/#changelog","title":"Changelog","text":""},{"location":"sandbox/DataOverlay/#documentation","title":"Documentation","text":"

    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.

    It is a sandbox feature.

    Please see the configuration part for setup instructions and examples.

    "},{"location":"sandbox/DataOverlay/#configuration","title":"Configuration","text":"

    Enable the feature by including it to the otp-config.json:

    // otp-config.json\n{ \"otpFeatures\": { \"DataOverlay\" : true } }\n

    Plugin configuration should explain the NetCDF data file and request parameters that use the data file.

    Example of build-config.json that includes the dataOverlay plugin configuration:

    // build-config.json\n{\n  \"dataOverlay\" :\n  {\n    \"fileName\": \"graphs/data-file.nc4\",\n    \"latitudeVariable\": \"lat\",\n    \"longitudeVariable\": \"lon\",\n    \"timeVariable\": \"time\",\n    \"timeFormat\": \"HOURS\",\n    \"indexVariables\": [\n      {\n        \"name\": \"harmfulMicroparticlesPM2_5\",\n        \"displayName\": \"Harmful micro particles pm 2.5\",\n        \"variable\": \"cnc_PM2_5\"\n      },\n      {\n        \"name\": \"harmfulMicroparticlesPM10\",\n        \"displayName\": \"Harmful micro particles pm 10\",\n        \"variable\": \"cnc_PM10\"\n      }\n    ],\n    \"requestParameters\": [\n      {\n        \"name\": \"PARTICULATE_MATTER_2_5\",\n        \"variable\": \"harmfulMicroparticlesPM2_5\",\n        \"formula\": \"(VALUE + 1 - THRESHOLD) * PENALTY\"\n      },\n      {\n        \"name\": \"PARTICULATE_MATTER_10\",\n        \"variable\": \"harmfulMicroparticlesPM10\",\n        \"formula\": \"(VALUE + 1 - THRESHOLD) * PENALTY\"\n      }\n    ]\n  }\n\n}\n

    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.

    // router-config.json\n{\n  \"routingDefaults\": {\n    \"dataOverlay\" : {\n      \"particulate_matter_10_threshold\" : 100,\n      \"particulate_matter_10_penalty\" : 19\n    }\n  }\n}\n
    "},{"location":"sandbox/Emissions/","title":"CO\u2082 Emissions calculation","text":""},{"location":"sandbox/Emissions/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/Emissions/#documentation","title":"Documentation","text":"

    Graph build import of CO\u2082 Emissions from GTFS data sets (through custom emissions.txt extension) and the ability to attach them to itineraries by Digitransit team. The emissions are represented in grams per kilometer (g/Km) unit.

    Emissions data is located in an emissions.txt file within a gtfs package and has the following columns:

    route_id: route id

    avg_co2_per_vehicle_per_km: Average carbon dioxide equivalent value for the vehicles used on the route at grams/Km units.

    avg_passenger_count: Average passenger count for the vehicles on the route.

    For example:

    route_id,avg_co2_per_vehicle_per_km,avg_passenger_count\n1234,123,20\n2345,0,0\n3456,12.3,20.0\n

    Emissions data is loaded from the gtfs package and embedded into the graph during the build process.

    "},{"location":"sandbox/Emissions/#configuration","title":"Configuration","text":"

    To enable this functionality, you need to enable the \"Co2Emissions\" feature in the otp-config.json file.

    //otp-config.json\n{\n  \"Co2Emissions\": true\n}\n
    Include the emissions object in the build-config.json file. The emissions object should contain parameters called carAvgCo2PerKm and carAvgOccupancy. The carAvgCo2PerKm provides the average emissions value for a car in g/km and the carAvgOccupancy provides the average number of passengers in a car.

    "},{"location":"sandbox/Emissions/#example-configuration","title":"Example configuration","text":"
    // build-config.json\n{\n  \"emissions\" : {\n    \"carAvgCo2PerKm\" : 170,\n    \"carAvgOccupancy\" : 1.3\n  }\n}\n
    "},{"location":"sandbox/Emissions/#overview","title":"Overview","text":"Config Parameter Type Summary Req./Opt. Default Value Since carAvgCo2PerKm integer The average CO\u2082 emissions of a car in grams per kilometer. Optional 170 2.5 carAvgOccupancy double The average number of passengers in a car. Optional 1.3 2.5"},{"location":"sandbox/Emissions/#details","title":"Details","text":""},{"location":"sandbox/Emissions/#changelog","title":"Changelog","text":""},{"location":"sandbox/Emissions/#otp-25","title":"OTP 2.5","text":""},{"location":"sandbox/Fares/","title":"Fares","text":""},{"location":"sandbox/Fares/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/Fares/#documentation","title":"Documentation","text":"

    The code in this sandbox used to be part of OTP core but to allow more experimentation - in particular regarding GTFS Fares V2 - it was moved into a sandbox.

    "},{"location":"sandbox/Fares/#fares-v2","title":"Fares V2","text":"

    In 2022 the GTFS spec was extended to contain a powerful new model, called Fares V2, to describe fares, prices and products for public transport tickets. A baseline effort was merged into the main spec in May.

    OTP experimentally supports the merged baseline plus a few extensions from the larger, unmerged spec.

    To enable Fares V2 support, add the following to otp-config.json:

    {\n  \"otpFeatures\" : {\n    \"FaresV2\" : true\n  }\n}\n
    "},{"location":"sandbox/Fares/#supported-fares-v2-fields","title":"Supported Fares V2 fields","text":"

    A full list of the fields that OTP supports is available in the Fares V2 Adoption Google Sheet.

    "},{"location":"sandbox/Fares/#custom-fare-calculators","title":"Custom fare calculators","text":"

    When the GTFS Fares V1 spec was not enough, some organizations have developed their own calculators which are also part of the sandbox code.

    The classes and their maintainers are as follows:

    class maintainer HighestFareInFreeTransferWindowFareService IBI Group (David Emory) AtlantaFareService IBI Group (David Emory) CombinedInterlinedLegsFareService IBI Group (David Emory) HSLFareServiceImpl HSL (Viljami Nurminen) OrcaFareService IBI Group (Daniel Heppner)"},{"location":"sandbox/Fares/#fares-configuration","title":"Fares configuration","text":"

    By default OTP will compute fares according to the GTFS specification if fare data is provided in your GTFS input. It is possible to turn off this by setting the fare to \"off\". For more complex scenarios or to handle vehicle rental fares, it is necessary to manually configure fares using the fares section in build-config.json. You can combine different fares (for example transit and vehicle-rental) by defining a combinationStrategy parameter, and a list of sub-fares to combine (all fields starting with fare are considered to be sub-fares).

    // build-config.json\n{\n  // Select the custom fare \"seattle\"\n  \"fares\": \"seattle\"\n}\n

    Or this alternative form that could allow additional configuration

    // build-config.json\n{\n  \"fares\": {\n    \"type\": \"seattle\"\n  }\n}\n

    Turning the fare service off, this will ignore any fare data in the provided GTFS data.

    // build-config.json\n{\n  \"fares\": \"off\"\n}\n

    The current list of custom fare type is:

    "},{"location":"sandbox/Fares/#removed-fare-calculators","title":"Removed fare calculators","text":"

    The following calculators used to be part of the OTP codebase but since their maintainership was unclear and no-one offered to maintain, they were removed in July 2022.

    The NYC fare calculator was removed in #4694.

    The MultipleFareService was removed in #5100.

    The SFBayFareServiceImpl and TimeBasedVehicleRentalFareService were removed in #5145.

    If you were using these calculators, you're welcome to re-add them to the code base and become their maintainer.

    "},{"location":"sandbox/Fares/#changelog","title":"Changelog","text":""},{"location":"sandbox/Flex/","title":"Flexible transit routing","text":""},{"location":"sandbox/Flex/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/Flex/#documentation","title":"Documentation","text":"

    To enable this turn on FlexRouting as a feature in otp-config.json.

    The GTFS feeds must conform to the final, approved version of the draft which has been merged into the mainline specification in March 2024.

    "},{"location":"sandbox/Flex/#experimental-features","title":"Experimental features","text":"

    This sandbox feature also has experimental support for the following fields:

    These features are currently undergoing specification and their definition might change. OTP's implementation will be also be changed so be careful when relying on this feature.

    "},{"location":"sandbox/Flex/#configuration","title":"Configuration","text":"

    This feature allows a limited number of config options. To change the configuration, add the following to router-config.json.

    "},{"location":"sandbox/Flex/#example-configuration","title":"Example configuration","text":"
    // router-config.json\n{\n  \"flex\" : {\n    \"maxTransferDuration\" : \"5m\",\n    \"maxFlexTripDuration\" : \"45m\",\n    \"maxAccessWalkDuration\" : \"15m\",\n    \"maxEgressWalkDuration\" : \"15m\"\n  }\n}\n
    "},{"location":"sandbox/Flex/#overview","title":"Overview","text":"Config Parameter Type Summary Req./Opt. Default Value Since maxAccessWalkDuration duration The maximum duration the passenger will be allowed to walk to reach a flex stop or zone. Optional \"PT45M\" 2.3 maxEgressWalkDuration duration The maximum duration the passenger will be allowed to walk after leaving the flex vehicle at the final destination. Optional \"PT45M\" 2.3 maxFlexTripDuration duration How long can a non-scheduled flex trip at maximum be. Optional \"PT45M\" 2.3 maxTransferDuration duration How long should a passenger be allowed to walk after getting out of a flex vehicle and transferring to a flex or transit one. Optional \"PT5M\" 2.3"},{"location":"sandbox/Flex/#details","title":"Details","text":""},{"location":"sandbox/Flex/#flex_maxAccessWalkDuration","title":"maxAccessWalkDuration","text":"

    Since version: 2.3 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT45M\" Path: /flex

    The maximum duration the passenger will be allowed to walk to reach a flex stop or zone.

    If you have multiple overlapping flex zones the high default value can lead to performance problems. A lower value means faster routing.

    Depending on your service this might be what you want to do anyway: many flex services are used by passengers with mobility problems so offering a long walk might be problematic. In other words, if you can walk 45 minutes to a flex stop/zone you're unlikely to be the target audience for those services.

    "},{"location":"sandbox/Flex/#flex_maxEgressWalkDuration","title":"maxEgressWalkDuration","text":"

    Since version: 2.3 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT45M\" Path: /flex

    The maximum duration the passenger will be allowed to walk after leaving the flex vehicle at the final destination.

    If you have multiple overlapping flex zones the high default value can lead to performance problems. A lower value means faster routing.

    Depending on your service this might be what you want to do anyway: many flex services are used by passengers with mobility problems so offering a long walk might be problematic. In other words, if you can walk 45 minutes to a flex stop/zone you're unlikely to be the target audience for those services.

    "},{"location":"sandbox/Flex/#flex_maxFlexTripDuration","title":"maxFlexTripDuration","text":"

    Since version: 2.3 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT45M\" Path: /flex

    How long can a non-scheduled flex trip at maximum be.

    This is used for all trips which are of type UnscheduledTrip. The value includes the access/egress duration to the boarding/alighting of the flex trip, as well as the connection to the transit stop.

    "},{"location":"sandbox/Flex/#flex_maxTransferDuration","title":"maxTransferDuration","text":"

    Since version: 2.3 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT5M\" Path: /flex

    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.

    A lower value means that the routing is faster.

    "},{"location":"sandbox/Flex/#changelog","title":"Changelog","text":""},{"location":"sandbox/Flex/#otp-21","title":"OTP 2.1","text":""},{"location":"sandbox/Flex/#otp-23","title":"OTP 2.3","text":""},{"location":"sandbox/GeocoderAPI/","title":"Geocoder API","text":""},{"location":"sandbox/GeocoderAPI/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/GeocoderAPI/#documentation","title":"Documentation","text":"

    This sandbox feature implements geocoding endpoints for a number of use cases.

    To enable this you need to add the feature to otp-config.json.

    // otp-config.json\n{\n  \"otpFeatures\": {\n    \"SandboxAPIGeocoder\": true\n  }\n}\n
    "},{"location":"sandbox/GeocoderAPI/#endpoints","title":"Endpoints","text":""},{"location":"sandbox/GeocoderAPI/#debug-ui","title":"Debug UI","text":"

    The required geocode API for Stop and From/To searches in the debug client.

    Path: /otp/geocode

    It supports the following URL parameters:

    Parameter Description query The query string we want to geocode autocomplete Whether we should use the query string to do a prefix match stops Search for stops, either by name or stop code clusters Search for clusters by their name"},{"location":"sandbox/GeocoderAPI/#stop-clusters","title":"Stop clusters","text":"

    A stop cluster is a deduplicated groups of stops. This means that for any stop that has a parent station only the parent is returned and for stops that have identical names and are very close to each other, only one is returned.

    This is useful for a general purpose fuzzy stop search.

    Path: /otp/geocode/stopClusters

    It supports the following URL parameters:

    Parameter Description query The query string we want to geocode"},{"location":"sandbox/GeocoderAPI/#changelog","title":"Changelog","text":""},{"location":"sandbox/GoogleCloudStorage/","title":"Google Cloud Storage - Using GCS Bucket as a OTP Data Source","text":""},{"location":"sandbox/GoogleCloudStorage/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/GoogleCloudStorage/#changelog","title":"Changelog","text":""},{"location":"sandbox/GoogleCloudStorage/#otp-20","title":"OTP 2.0","text":""},{"location":"sandbox/GoogleCloudStorage/#documentation","title":"Documentation","text":"

    To enable this turn on the feature GoogleCloudStorage. OTP can load or store artifacts from one or more Google Cloud Storge locations. Each artifact must be configured in the build-config.json: See BuildConfig on how to configure artifacts.

    Example (build-config.json):

    {\n  \"gcsCredentials\": \"file:///Users/alf/secret/otp-test-1234567890.json\",\n  \"graph\": \"gs://otp-test-bucket/a/b/graph.obj\",\n  \"buildReportDir\": \"gs://otp-test-bucket/a/b/np-report\",\n  \"osm\": [\n    {\n      \"source\": \"gs://otp-test-bucket/a/b/northpole.pbf\"\n    }\n    ],\n  \"dem\": [\n    {\n      \"source\": \"gs://otp-test-bucket/a/b/northpole.dem.tif\"\n    }\n    ],\n  \"transitFeeds\": [\n    {\n      \"type\": \"gtfs\",\n      \"source\": \"gs://otp-test-bucket/a/b/gtfs.zip\"\n    }\n    ]\n}\n
    "},{"location":"sandbox/IBIAccessibilityScore/","title":"IBI Group Accessibility Score","text":""},{"location":"sandbox/IBIAccessibilityScore/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/IBIAccessibilityScore/#documentation","title":"Documentation","text":"

    This extension computes a numeric accessibility score between 0 and 1 and adds it to the itinerary and its legs.

    Note: the information to calculate this score are all available to the frontend, however calculating them on the backend makes life a little easier and changes are automatically applied to all frontends.

    To enable the feature add the following to router-config.json:

    // router-config.json\n{\n  \"routingDefaults\": {\n    \"itineraryFilters\": {\n      // add IBI accessibility score between 0 and 1\n      \"accessibilityScore\": true\n    }\n  }\n}\n

    The score is only computed when you search for wheelchair-accessible routes.

    "},{"location":"sandbox/IBIAccessibilityScore/#changelog","title":"Changelog","text":""},{"location":"sandbox/InteractiveOtpMain/","title":"Interactive OTP Launcher","text":"

    A GUI popup window to which help you to start OTP Main interactively.

    "},{"location":"sandbox/InteractiveOtpMain/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/InteractiveOtpMain/#changelog","title":"Changelog","text":""},{"location":"sandbox/InteractiveOtpMain/#documentation","title":"Documentation","text":"

    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.

    "},{"location":"sandbox/MapboxVectorTilesApi/","title":"Mapbox Vector Tiles API","text":""},{"location":"sandbox/MapboxVectorTilesApi/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/MapboxVectorTilesApi/#documentation","title":"Documentation","text":"

    This API produces Mapbox vector tiles, which are used by Digitransit-ui and otp-react-redux 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.

    Maplibre/Mapbox GL JS also requires a tilejson.json endpoint which is available at /otp/routers/{routerId}/vectorTiles/{layers}/tilejson.json.

    Translatable fields in the tiles are translated based on the accept-language header in requests. Currently, only the language with the highest priority from the header is used.

    "},{"location":"sandbox/MapboxVectorTilesApi/#configuration","title":"Configuration","text":"

    To enable this you need to add the feature otp-config.json.

    // otp-config.json\n{\n  \"otpFeatures\": {\n    \"SandboxAPIMapboxVectorTilesApi\": true\n  }\n}\n

    The feature must be configured in router-config.json as follows

    {\n  \"vectorTiles\": {\n    \"basePath\": \"/only/configure/if/required\",\n    \"layers\": [\n      {\n        \"name\": \"stops\",\n        \"type\": \"Stop\",\n        \"mapper\": \"Digitransit\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 600\n      },\n      // flex zones\n      {\n        \"name\": \"areaStops\",\n        \"type\": \"AreaStop\",\n        \"mapper\": \"OTPRR\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 600\n      },\n      {\n        \"name\": \"stations\",\n        \"type\": \"Station\",\n        \"mapper\": \"Digitransit\",\n        \"maxZoom\": 20,\n        \"minZoom\": 12,\n        \"cacheMaxSeconds\": 600\n      },\n      // all rental places: stations and free-floating vehicles\n      {\n        \"name\": \"citybikes\",\n        \"type\": \"VehicleRental\",\n        \"mapper\": \"Digitransit\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 60,\n        \"expansionFactor\": 0.25\n      },\n      // just free-floating vehicles\n      {\n        \"name\": \"rentalVehicles\",\n        \"type\": \"VehicleRentalVehicle\",\n        \"mapper\": \"DigitransitRealtime\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 60\n      },\n      // just rental stations\n      {\n        \"name\": \"rentalStations\",\n        \"type\": \"VehicleRentalStation\",\n        \"mapper\": \"Digitransit\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 600\n      },\n      // Contains just stations and real-time information for them\n      {\n        \"name\": \"realtimeRentalStations\",\n        \"type\": \"VehicleRentalStation\",\n        \"mapper\": \"DigitransitRealtime\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 60\n      },\n      // Contains just stops and real-time information for them\n      {\n        \"name\": \"realtimeStops\",\n        \"type\": \"Stop\",\n        \"mapper\": \"DigitransitRealtime\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 60\n      },\n      // This exists for backwards compatibility. At some point, we might want\n      // to add a new real-time parking mapper with better translation support\n      // and less unnecessary fields.\n      {\n        \"name\": \"stadtnaviVehicleParking\",\n        \"type\": \"VehicleParking\",\n        \"mapper\": \"Stadtnavi\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 60,\n        \"expansionFactor\": 0.25\n      },\n      // no real-time, translatable fields are translated based on accept-language header\n      // and contains less fields than the Stadtnavi mapper\n      {\n        \"name\": \"vehicleParking\",\n        \"type\": \"VehicleParking\",\n        \"mapper\": \"Digitransit\",\n        \"maxZoom\": 20,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 600,\n        \"expansionFactor\": 0.25\n      },\n      {\n        \"name\": \"vehicleParkingGroups\",\n        \"type\": \"VehicleParkingGroup\",\n        \"mapper\": \"Digitransit\",\n        \"maxZoom\": 17,\n        \"minZoom\": 14,\n        \"cacheMaxSeconds\": 600,\n        \"expansionFactor\": 0.25\n      }\n    ] \n  }\n}\n

    For each layer, the configuration includes:

    Config Parameter Type Summary Req./Opt. Default Value Since attribution string Custom attribution to be returned in tilejson.json Optional 2.5 basePath string The path of the vector tile source URLs in tilejson.json. Optional 2.5 layers object[] Configuration of the individual layers for the Mapbox vector tiles. Optional 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type = \"stop\" enum Type of the layer. Required 2.0 cacheMaxSeconds integer Sets the cache header in the response. Optional -1 2.0 expansionFactor double How far outside its boundaries should the tile contain information. Optional 0.25 2.0 filter enum Reduce the result set of a layer further by a specific filter. Optional \"none\" 2.6 mapper string Describes the mapper converting from the OTP model entities to the vector tile properties. Required 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0maxZoom integer Maximum zoom levels the layer is active for. Optional 20 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0minZoom integer Minimum zoom levels the layer is active for. Optional 9 2.0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name string Used in the url to fetch tiles, and as the layer name in the vector tiles. Required 2.0"},{"location":"sandbox/MapboxVectorTilesApi/#details","title":"Details","text":""},{"location":"sandbox/MapboxVectorTilesApi/#vectorTiles_attribution","title":"attribution","text":"

    Since version: 2.5 \u2219 Type: string \u2219 Cardinality: Optional Path: /vectorTiles

    Custom attribution to be returned in tilejson.json

    By default the, attribution property in tilejson.json is computed from the names and URLs of the feed publishers. If the OTP deployment contains many feeds, this can become very unwieldy.

    This configuration parameter allows you to set the attribution to any string you wish including HTML tags, for example <a href='https://trimet.org/mod'>Regional Partners</a>.

    "},{"location":"sandbox/MapboxVectorTilesApi/#vectorTiles_basePath","title":"basePath","text":"

    Since version: 2.5 \u2219 Type: string \u2219 Cardinality: Optional Path: /vectorTiles

    The path of the vector tile source URLs in tilejson.json.

    This is useful if you have a proxy setup and rewrite the path that is passed to OTP.

    If you don't configure this optional value then the path returned in tilejson.json is in the format /otp/routers/default/vectorTiles/layer1,layer2/{z}/{x}/{x}.pbf. If you, for example, set a value of /otp_test/tiles then the returned path changes to /otp_test/tiles/layer1,layer2/{z}/{x}/{x}.pbf.

    The protocol and host are always read from the incoming HTTP request. If you run OTP behind a proxy then make sure to set the headers X-Forwarded-Proto and X-Forwarded-Host to make OTP return the protocol and host for the original request and not the proxied one.

    Note: This does not change the path that OTP itself serves the tiles or tilejson.json responses but simply changes the URLs listed in tilejson.json. The rewriting of the path is expected to be handled by a proxy.

    "},{"location":"sandbox/MapboxVectorTilesApi/#vectorTiles_layers","title":"layers","text":"

    Since version: 2.0 \u2219 Type: object[] \u2219 Cardinality: Optional Path: /vectorTiles

    Configuration of the individual layers for the Mapbox vector tiles.

    "},{"location":"sandbox/MapboxVectorTilesApi/#vectorTiles_layers_0_cacheMaxSeconds","title":"cacheMaxSeconds","text":"

    Since version: 2.0 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: -1 Path: /vectorTiles/layers/[0]

    Sets the cache header in the response.

    The lowest value of the layers included is selected.

    "},{"location":"sandbox/MapboxVectorTilesApi/#vectorTiles_layers_0_expansionFactor","title":"expansionFactor","text":"

    Since version: 2.0 \u2219 Type: double \u2219 Cardinality: Optional \u2219 Default value: 0.25 Path: /vectorTiles/layers/[0]

    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.

    "},{"location":"sandbox/MapboxVectorTilesApi/#vectorTiles_layers_0_filter","title":"filter","text":"

    Since version: 2.6 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"none\" Path: /vectorTiles/layers/[0] Enum values: none | sunday-to-sunday-service-week

    Reduce the result set of a layer further by a specific filter.

    This is useful for when the schema of a layer, say stops, should remain unchanged but some elements should not be included in the result.

    "},{"location":"sandbox/MapboxVectorTilesApi/#vectorTiles_layers_0_mapper","title":"mapper","text":"

    Since version: 2.0 \u2219 Type: string \u2219 Cardinality: Required Path: /vectorTiles/layers/[0]

    Describes the mapper converting from the OTP model entities to the vector tile properties.

    Currently Digitransit is supported for all layer types.

    "},{"location":"sandbox/MapboxVectorTilesApi/#extending","title":"Extending","text":"

    If more generic layers are created for this API, the code should be moved out from the sandbox, into the core, perhaps potentially leaving specific property mappers in place.

    "},{"location":"sandbox/MapboxVectorTilesApi/#creating-a-new-layer","title":"Creating a new layer","text":"

    In order to create a new type of layer, you need to create a new class extending LayerBuilder<T>. You need to implement two methods, List<Geometry> 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.

    "},{"location":"sandbox/MapboxVectorTilesApi/#creating-a-new-mapper","title":"Creating a new mapper","text":"

    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<T>. In that class, you need to implement the method Collection<KeyValue<String, Object>> 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.

    "},{"location":"sandbox/MapboxVectorTilesApi/#changelog","title":"Changelog","text":""},{"location":"sandbox/ParkAndRideApi/","title":"Park and Ride API","text":""},{"location":"sandbox/ParkAndRideApi/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/ParkAndRideApi/#changelog","title":"Changelog","text":""},{"location":"sandbox/ParkAndRideApi/#documentation","title":"Documentation","text":"

    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.

    "},{"location":"sandbox/ReportApi/","title":"Report API","text":"

    The report API is a collection of reports generated as CSV files. The main use-case is to download data for manual analyzes and verification. The CSV files should not be used as a service by another 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.

    "},{"location":"sandbox/ReportApi/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/ReportApi/#changelog","title":"Changelog","text":""},{"location":"sandbox/ReportApi/#documentation","title":"Documentation","text":"

    This module mounts an endpoint for generating reports under otp/report. Available reports:

    "},{"location":"sandbox/ReportApi/#configuration","title":"Configuration","text":"

    The report API is turned off by default. To turn it on enable the ReportApi feature.

    // otp-config.json\n{\n  \"otpFeatures\": {\n    \"ReportApi\": true\n  }\n}\n
    "},{"location":"sandbox/RideHailing/","title":"Ride hailing services","text":"

    This sandbox feature allows you to use ride hailing services like Uber.

    "},{"location":"sandbox/RideHailing/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/RideHailing/#configuration","title":"Configuration","text":"

    In order enable this feature, add a new section rideHailingServices in router-config.json.

    The supported ride-hailing providers are listed below.

    "},{"location":"sandbox/RideHailing/#uber","title":"Uber","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"uber-car-hailing\" enum The type of the service. Required 2.3 clientId string OAuth client id to access the API. Required 2.3 clientSecret string OAuth client secret to access the API. Required 2.3 wheelchairAccessibleProductId string The id of the requested wheelchair-accessible product ID. Required 2.3 bannedProductIds string[] The IDs of those product ids that should not be used for estimates. Optional 2.3"},{"location":"sandbox/RideHailing/#details","title":"Details","text":""},{"location":"sandbox/RideHailing/#rideHailingServices_0_wheelchairAccessibleProductId","title":"wheelchairAccessibleProductId","text":"

    Since version: 2.3 \u2219 Type: string \u2219 Cardinality: Required Path: /rideHailingServices/[0]

    The id of the requested wheelchair-accessible product ID.

    See bannedProductIds for a list of product IDs.

    "},{"location":"sandbox/RideHailing/#rideHailingServices_0_bannedProductIds","title":"bannedProductIds","text":"

    Since version: 2.3 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /rideHailingServices/[0]

    The IDs of those product ids that should not be used for estimates.

    See the current list of Uber product ids.

    "},{"location":"sandbox/RideHailing/#example-configuration","title":"Example configuration","text":"
    // router-config.json\n{\n  \"rideHailingServices\" : [\n    {\n      \"type\" : \"uber-car-hailing\",\n      \"clientId\" : \"secret-id\",\n      \"clientSecret\" : \"very-secret\",\n      \"wheelchairAccessibleProductId\" : \"545de0c4-659f-49c6-be65-0d5e448dffd5\",\n      \"bannedProductIds\" : [\n        \"1196d0dd-423b-4a81-a1d8-615367d3a365\",\n        \"f58761e5-8dd5-4940-a472-872f1236c596\"\n      ]\n    }\n  ]\n}\n
    "},{"location":"sandbox/SmooveBikeRental/","title":"HSL Smoove Bike Rental Updater Support - OTP Sandbox Extension","text":""},{"location":"sandbox/SmooveBikeRental/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/SmooveBikeRental/#changelog","title":"Changelog","text":""},{"location":"sandbox/SmooveBikeRental/#documentation","title":"Documentation","text":"

    TODO

    "},{"location":"sandbox/SmooveBikeRental/#configuration","title":"Configuration","text":"

    An example updater configuration:

    {\n    \"type\": \"bike-rental\",\n    \"sourceType\": \"smoove\",\n    \"network\": \"smoove-network-1\",\n    \"url\": \"https://helsinki-fi.smoove.pro/api-public/stations\",\n    \"frequency\": 10,\n    \"overloadingAllowed\": true\n}\n

    network (optional) allows defining custom network id

    overloadingAllowed (optional) defines if the stations in the network allow overloading (ignoring available spaces)

    "},{"location":"sandbox/Sorlandsbanen/","title":"S\u00f8rlandsbanen - The southern railroad in Norway","text":"

    This sandbox module is only working in Norway, in particular only in the south of Norway. The feature flag to turn it on should only be enabled if you are routing using the norwegian data set.

    The railroad in southern Norway is very slow and does not go by the coast where most people live. It is easily beaten by coaches in the area. Despite this, we need to include it in results where it is relevant.

    When the feature flag is enabled, two Raptor searches are performed. The first is the regular search - unmodified, as requested by the user. The second search is modified to include train results with S\u00f8rlandsbanen. This is achieved by setting a high COACH reluctance. We then take any rail results(if they exist) from the second search and add it two to the results from the first search. The new set of results will contain everything we found in the first search, plus the train results in the second results.

    Note! This looks at origin and destination coordinates in addition to the feature flag to enable the second search. It is automatically enabled if: - the OTPFeature.Sorlandsbanen is on. - the origin and/or destination is in the south of Norway. - the search is a long-distance search, origin and destination are fare apart from each other.

    "},{"location":"sandbox/Sorlandsbanen/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/Sorlandsbanen/#changelog","title":"Changelog","text":""},{"location":"sandbox/Sorlandsbanen/#configuration","title":"Configuration","text":"

    This is turned off by default. To turn it on enable the Sorlandsbanen feature.

    // otp-config.json\n{\n  \"otpFeatures\": {\n    \"Sorlandsbanen\": true\n  }\n}\n
    "},{"location":"sandbox/StopConsolidation/","title":"Stop Consolidation","text":""},{"location":"sandbox/StopConsolidation/#stop-consolidation","title":"Stop consolidation","text":""},{"location":"sandbox/StopConsolidation/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/StopConsolidation/#feature-explanation","title":"Feature explanation","text":"

    This sandbox feature allows you to \"combine\" equivalent stops from across several feeds into a single, consolidated one.

    It is achieved by defining a \"primary\" stop and one or more \"secondary\" stops. During the graph build all trip patterns are modified so that the secondary ones are swapped out for their primary equivalent.

    "},{"location":"sandbox/StopConsolidation/#effects","title":"Effects","text":"

    This has the following consequences

    Downsides

    However, this feature has also severe downsides:

    "},{"location":"sandbox/StopConsolidation/#configuration","title":"Configuration","text":"

    To enable this feature you need to add a file to OTP's working directory and configure its name like this:

    // build-config.json\n{\n  \"stopConsolidationFile\" : \"consolidated-stops.csv\"\n}\n

    The additional config file must look like the following:

    stop_group_id,feed_id,stop_id,is_primary\n1,pierce,1705867009,0\n1,kcm,10225,1\n2,pierce,1569,0\n2,commtrans,473,0\n2,kcm,1040,1\n

    The column names mean the following:

    "},{"location":"sandbox/VehicleParking/","title":"Vehicle Parking Updaters","text":""},{"location":"sandbox/VehicleParking/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/VehicleParking/#documentation","title":"Documentation","text":"

    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:

    "},{"location":"sandbox/VehicleParking/#configuration","title":"Configuration","text":"

    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:

    "},{"location":"sandbox/VehicleParking/#hsl-park-and-ride","title":"HSL Park and Ride","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"vehicle-parking\" enum The type of the updater. Required 1.5 facilitiesFrequencySec integer How often the facilities should be updated. Optional 3600 2.2 facilitiesUrl string URL of the facilities. Optional 2.2 feedId string The id of the data source, which will be the prefix of the parking lot's id. Required 2.2 hubsUrl string Hubs URL Optional 2.2 sourceType enum The source of the vehicle updates. Required 2.2 timeZone time-zone The time zone of the feed. Optional 2.2 utilizationsFrequencySec integer How often the utilization should be updated. Optional 600 2.2 utilizationsUrl string URL of the utilization data. Optional 2.2"},{"location":"sandbox/VehicleParking/#details","title":"Details","text":""},{"location":"sandbox/VehicleParking/#u__2__feedId","title":"feedId","text":"

    Since version: 2.2 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[2]

    The id of the data source, which will be the prefix of the parking lot's id.

    This will end up in the API responses as the feed id of the parking lot.

    "},{"location":"sandbox/VehicleParking/#u__2__sourceType","title":"sourceType","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Required Path: /updaters/[2] Enum values: park-api | bicycle-park-api | hsl-park | bikely | bikeep | siri-fm

    The source of the vehicle updates.

    "},{"location":"sandbox/VehicleParking/#u__2__timeZone","title":"timeZone","text":"

    Since version: 2.2 \u2219 Type: time-zone \u2219 Cardinality: Optional Path: /updaters/[2]

    The time zone of the feed.

    Used for converting abstract opening hours into concrete points in time.

    "},{"location":"sandbox/VehicleParking/#example-configuration","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"vehicle-parking\",\n      \"sourceType\" : \"hsl-park\",\n      \"feedId\" : \"hslpark\",\n      \"timeZone\" : \"Europe/Helsinki\",\n      \"facilitiesFrequencySec\" : 3600,\n      \"facilitiesUrl\" : \"https://p.hsl.fi/api/v1/facilities.json?limit=-1\",\n      \"utilizationsFrequencySec\" : 600,\n      \"utilizationsUrl\" : \"https://p.hsl.fi/api/v1/utilizations.json?limit=-1\",\n      \"hubsUrl\" : \"https://p.hsl.fi/api/v1/hubs.json?limit=-1\"\n    }\n  ]\n}\n
    "},{"location":"sandbox/VehicleParking/#parkapi","title":"ParkAPI","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"vehicle-parking\" enum The type of the updater. Required 1.5 feedId string The id of the data source, which will be the prefix of the parking lot's id. Required 2.2 frequency duration How often to update the source. Optional \"PT1M\" 2.2 sourceType enum The source of the vehicle updates. Required 2.2 timeZone time-zone The time zone of the feed. Optional 2.2 url string URL of the resource. Required 2.2 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.2 tags string[] Tags to add to the parking lots. Optional 2.2"},{"location":"sandbox/VehicleParking/#details_1","title":"Details","text":""},{"location":"sandbox/VehicleParking/#u__3__feedId","title":"feedId","text":"

    Since version: 2.2 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[3]

    The id of the data source, which will be the prefix of the parking lot's id.

    This will end up in the API responses as the feed id of the parking lot.

    "},{"location":"sandbox/VehicleParking/#u__3__sourceType","title":"sourceType","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Required Path: /updaters/[3] Enum values: park-api | bicycle-park-api | hsl-park | bikely | bikeep | siri-fm

    The source of the vehicle updates.

    "},{"location":"sandbox/VehicleParking/#u__3__timeZone","title":"timeZone","text":"

    Since version: 2.2 \u2219 Type: time-zone \u2219 Cardinality: Optional Path: /updaters/[3]

    The time zone of the feed.

    Used for converting abstract opening hours into concrete points in time.

    "},{"location":"sandbox/VehicleParking/#u__3__headers","title":"headers","text":"

    Since version: 2.2 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[3]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"sandbox/VehicleParking/#u__3__tags","title":"tags","text":"

    Since version: 2.2 \u2219 Type: string[] \u2219 Cardinality: Optional Path: /updaters/[3]

    Tags to add to the parking lots.

    "},{"location":"sandbox/VehicleParking/#example-configuration_1","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"vehicle-parking\",\n      \"sourceType\" : \"park-api\",\n      \"feedId\" : \"parkapi\",\n      \"timeZone\" : \"Europe/Berlin\",\n      \"frequency\" : \"10m\",\n      \"url\" : \"https://foo.bar\",\n      \"headers\" : {\n        \"Cache-Control\" : \"max-age=604800\"\n      },\n      \"tags\" : [\n        \"source:parkapi\"\n      ]\n    }\n  ]\n}\n
    "},{"location":"sandbox/VehicleParking/#bikely","title":"Bikely","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"vehicle-parking\" enum The type of the updater. Required 1.5 feedId string The id of the data source, which will be the prefix of the parking lot's id. Required 2.2 frequency duration How often to update the source. Optional \"PT1M\" 2.3 sourceType enum The source of the vehicle updates. Required 2.2 url uri URL of the locations endpoint. Required 2.3 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.3"},{"location":"sandbox/VehicleParking/#details_2","title":"Details","text":""},{"location":"sandbox/VehicleParking/#u__4__feedId","title":"feedId","text":"

    Since version: 2.2 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[4]

    The id of the data source, which will be the prefix of the parking lot's id.

    This will end up in the API responses as the feed id of the parking lot.

    "},{"location":"sandbox/VehicleParking/#u__4__sourceType","title":"sourceType","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Required Path: /updaters/[4] Enum values: park-api | bicycle-park-api | hsl-park | bikely | bikeep | siri-fm

    The source of the vehicle updates.

    "},{"location":"sandbox/VehicleParking/#u__4__headers","title":"headers","text":"

    Since version: 2.3 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[4]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"sandbox/VehicleParking/#example-configuration_2","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"vehicle-parking\",\n      \"feedId\" : \"bikely\",\n      \"sourceType\" : \"bikely\",\n      \"url\" : \"https://api.safebikely.com/api/v1/s/locations\",\n      \"headers\" : {\n        \"X-Bikely-Token\" : \"${BIKELY_TOKEN}\",\n        \"Authorization\" : \"${BIKELY_AUTHORIZATION}\"\n      }\n    }\n  ]\n}\n
    "},{"location":"sandbox/VehicleParking/#bikeep","title":"Bikeep","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"vehicle-parking\" enum The type of the updater. Required 1.5 feedId string The id of the data source, which will be the prefix of the parking lot's id. Required 2.2 frequency duration How often to update the source. Optional \"PT1M\" 2.6 sourceType enum The source of the vehicle updates. Required 2.2 url uri URL of the locations endpoint. Required 2.6 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.6"},{"location":"sandbox/VehicleParking/#details_3","title":"Details","text":""},{"location":"sandbox/VehicleParking/#u__13__feedId","title":"feedId","text":"

    Since version: 2.2 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[13]

    The id of the data source, which will be the prefix of the parking lot's id.

    This will end up in the API responses as the feed id of the parking lot.

    "},{"location":"sandbox/VehicleParking/#u__13__sourceType","title":"sourceType","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Required Path: /updaters/[13] Enum values: park-api | bicycle-park-api | hsl-park | bikely | bikeep | siri-fm

    The source of the vehicle updates.

    "},{"location":"sandbox/VehicleParking/#u__13__headers","title":"headers","text":"

    Since version: 2.6 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[13]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"sandbox/VehicleParking/#example-configuration_3","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"vehicle-parking\",\n      \"feedId\" : \"bikeep\",\n      \"sourceType\" : \"bikeep\",\n      \"url\" : \"https://services.bikeep.com/location/v1/public-areas/no-baia-mobility/locations\"\n    }\n  ]\n}\n
    "},{"location":"sandbox/VehicleParking/#siri-fm","title":"SIRI-FM","text":"

    The SIRI-FM updater works slightly differently from the others in that it only updates the availability of parking but does not create new lots in realtime.

    The data source must conform to the Italian SIRI-FM profile which requires SIRI 2.1.

    Config Parameter Type Summary Req./Opt. Default Value Since type = \"vehicle-parking\" enum The type of the updater. Required 1.5 feedId string The id of the data source, which will be the prefix of the parking lot's id. Required 2.2 frequency duration How often to update the source. Optional \"PT1M\" 2.6 sourceType enum The source of the vehicle updates. Required 2.2 url uri URL of the SIRI-FM Light endpoint. Required 2.6 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.6"},{"location":"sandbox/VehicleParking/#details_4","title":"Details","text":""},{"location":"sandbox/VehicleParking/#u__14__feedId","title":"feedId","text":"

    Since version: 2.2 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[14]

    The id of the data source, which will be the prefix of the parking lot's id.

    This will end up in the API responses as the feed id of the parking lot.

    "},{"location":"sandbox/VehicleParking/#u__14__sourceType","title":"sourceType","text":"

    Since version: 2.2 \u2219 Type: enum \u2219 Cardinality: Required Path: /updaters/[14] Enum values: park-api | bicycle-park-api | hsl-park | bikely | bikeep | siri-fm

    The source of the vehicle updates.

    "},{"location":"sandbox/VehicleParking/#u__14__url","title":"url","text":"

    Since version: 2.6 \u2219 Type: uri \u2219 Cardinality: Required Path: /updaters/[14]

    URL of the SIRI-FM Light endpoint.

    SIRI Light means that it must be available as a HTTP GET request rather than the usual SIRI request mechanism of HTTP POST.

    The contents must also conform to the Italian SIRI profile which requires SIRI 2.1.

    "},{"location":"sandbox/VehicleParking/#u__14__headers","title":"headers","text":"

    Since version: 2.6 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[14]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"sandbox/VehicleParking/#example-configuration_4","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"vehicle-parking\",\n      \"feedId\" : \"parking\",\n      \"sourceType\" : \"siri-fm\",\n      \"url\" : \"https://transmodel.api.opendatahub.com/siri-lite/fm/parking\"\n    }\n  ]\n}\n
    "},{"location":"sandbox/VehicleParking/#changelog","title":"Changelog","text":""},{"location":"sandbox/VehicleRentalServiceDirectory/","title":"Vehicle Rental Service Directory API support","text":"

    This adds support for the GBFS service directory endpoint component Lamassu. OTP uses the service directory to lookup and connects to all GBFS endpoints registered in the directory. This simplifies the management of the GBFS endpoints, since multiple services/components like OTP can connect to the directory and get the necessary configuration from it.

    "},{"location":"sandbox/VehicleRentalServiceDirectory/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/VehicleRentalServiceDirectory/#changelog","title":"Changelog","text":""},{"location":"sandbox/VehicleRentalServiceDirectory/#configuration","title":"Configuration","text":"

    To enable this you need to specify a url for the vehicleRentalServiceDirectory in the router-config.json

    "},{"location":"sandbox/VehicleRentalServiceDirectory/#parameter-summary","title":"Parameter Summary","text":"Config Parameter Type Summary Req./Opt. Default Value Since language string Language code. Optional 2.1 sourcesName string Json tag name for updater sources. Optional \"systems\" 2.1 updaterNetworkName string Json tag name for the network name for each source. Optional \"id\" 2.1 updaterUrlName string Json tag name for endpoint urls for each source. Optional \"url\" 2.1 url uri Endpoint for the VehicleRentalServiceDirectory Required 2.1 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.1 networks object[] List all networks to include. Use \"network\": \"default-network\" to set defaults. Optional 2.4 allowKeepingVehicleAtDestination boolean Enables allowKeepingVehicleAtDestination for the given network. Optional false 2.5 geofencingZones boolean Enables geofencingZones for the given network Optional false 2.4 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0network string The network name Required 2.4"},{"location":"sandbox/VehicleRentalServiceDirectory/#parameter-details","title":"Parameter Details","text":""},{"location":"sandbox/VehicleRentalServiceDirectory/#vehicleRentalServiceDirectory_headers","title":"headers","text":"

    Since version: 2.1 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /vehicleRentalServiceDirectory

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"sandbox/VehicleRentalServiceDirectory/#vehicleRentalServiceDirectory_networks","title":"networks","text":"

    Since version: 2.4 \u2219 Type: object[] \u2219 Cardinality: Optional Path: /vehicleRentalServiceDirectory

    List all networks to include. Use \"network\": \"default-network\" to set defaults.

    If no default network exists only the listed networks are used. Configure a network with name \"default-network\" to include all unlisted networks. If not present, all unlisted networks are dropped. Note! The values in the \"default-network\" are not used to set missing field values in networks listed.

    "},{"location":"sandbox/VehicleRentalServiceDirectory/#vehicleRentalServiceDirectory_networks_0_allowKeepingVehicleAtDestination","title":"allowKeepingVehicleAtDestination","text":"

    Since version: 2.5 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /vehicleRentalServiceDirectory/networks/[0]

    Enables allowKeepingVehicleAtDestination for the given network.

    Configures if a vehicle rented from a station must be returned to another one or can be kept at the end of the trip.

    See the regular GBFS documentation for more information.

    "},{"location":"sandbox/VehicleRentalServiceDirectory/#vehicleRentalServiceDirectory_networks_0_geofencingZones","title":"geofencingZones","text":"

    Since version: 2.4 \u2219 Type: boolean \u2219 Cardinality: Optional \u2219 Default value: false Path: /vehicleRentalServiceDirectory/networks/[0]

    Enables geofencingZones for the given network

    See the regular GBFS documentation for more information.

    "},{"location":"sandbox/VehicleRentalServiceDirectory/#example","title":"Example","text":"
    // router-config.json\n{\n  \"vehicleRentalServiceDirectory\" : {\n    \"url\" : \"https://example.com\",\n    \"sourcesName\" : \"systems\",\n    \"updaterUrlName\" : \"url\",\n    \"updaterNetworkName\" : \"id\",\n    \"headers\" : {\n      \"ET-Client-Name\" : \"otp\"\n    },\n    \"networks\" : [\n      {\n        \"network\" : \"oslo-by-sykkel\",\n        \"geofencingZones\" : true\n      }\n    ]\n  }\n}\n
    "},{"location":"sandbox/transferanalyzer/","title":"Direct transfer analyzer module","text":""},{"location":"sandbox/transferanalyzer/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/transferanalyzer/#changelog","title":"Changelog","text":""},{"location":"sandbox/transferanalyzer/#may-20th-2019","title":"May 20th 2019","text":""},{"location":"sandbox/transferanalyzer/#documentation","title":"Documentation","text":"

    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 class

    "},{"location":"sandbox/siri/SiriAzureUpdater/","title":"Siri Azure Updater","text":"

    This is a sandbox extension developed by Sk\u00e5netrafiken that allows OTP to fetch Siri ET & SX messages through Azure Service Bus. It also enables OTP to download historical data from en HTTP endpoint on startup.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#contact-info","title":"Contact Info","text":"

    Sk\u00e5netrafiken, Sweden developer.otp@skanetrafiken.se

    "},{"location":"sandbox/siri/SiriAzureUpdater/#documentation","title":"Documentation","text":"

    Documentation available here.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#configuration","title":"Configuration","text":"

    To enable the SIRI updater you need to add it to the updaters section of the router-config.json.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#siri-azure-et-updater","title":"Siri Azure ET Updater","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"siri-azure-et-updater\" enum The type of the updater. Required 1.5 authenticationType enum Which authentication type to use Optional \"sharedaccesskey\" 2.5 autoDeleteOnIdle duration The time after which an inactive subscription is removed. Optional \"PT1H\" 2.5 customMidnight integer Time on which time breaks into new day. Optional 0 2.2 feedId string The ID of the feed to apply the updates to. Optional 2.2 fullyQualifiedNamespace string Service Bus fully qualified namespace used for authentication. Optional 2.5 fuzzyTripMatching boolean Whether to apply fuzzyTripMatching on the updates Optional false 2.2 prefetchCount integer The number of messages to fetch from the subscription at a time. Optional 10 2.5 servicebus-url string Service Bus connection used for authentication. Optional 2.2 topic string Service Bus topic to connect to. Optional 2.2 history object Configuration for fetching historical data on startup Optional 2.2 \u00a0\u00a0\u00a0fromDateTime string Datetime boundary for historical data Optional \"-P1D\" 2.2 \u00a0\u00a0\u00a0timeout integer Timeout in milliseconds Optional 300000 na \u00a0\u00a0\u00a0url string Endpoint to fetch from Optional na"},{"location":"sandbox/siri/SiriAzureUpdater/#parameter-details","title":"Parameter details","text":""},{"location":"sandbox/siri/SiriAzureUpdater/#u__11__authenticationType","title":"authenticationType","text":"

    Since version: 2.5 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"sharedaccesskey\" Path: /updaters/[11] Enum values: sharedaccesskey | federatedidentity

    Which authentication type to use

    "},{"location":"sandbox/siri/SiriAzureUpdater/#u__11__customMidnight","title":"customMidnight","text":"

    Since version: 2.2 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 0 Path: /updaters/[11]

    Time on which time breaks into new day.

    It is common that operating day date breaks a little bit later than midnight so that the switch happens when traffic is at the lowest point. Parameter uses 24-hour format. If the switch happens on 4 am then set this field to 4.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#u__11__fullyQualifiedNamespace","title":"fullyQualifiedNamespace","text":"

    Since version: 2.5 \u2219 Type: string \u2219 Cardinality: Optional Path: /updaters/[11]

    Service Bus fully qualified namespace used for authentication.

    Has to be present for authenticationMethod FederatedIdentity.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#u__11__servicebus_url","title":"servicebus-url","text":"

    Since version: 2.2 \u2219 Type: string \u2219 Cardinality: Optional Path: /updaters/[11]

    Service Bus connection used for authentication.

    Has to be present for authenticationMethod SharedAccessKey. This should be Primary/Secondary connection string from service bus.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#example-configuration","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"siri-azure-et-updater\",\n      \"topic\" : \"some_topic\",\n      \"authenticationType\" : \"SharedAccessKey\",\n      \"fullyQualifiedNamespace\" : \"fully_qualified_namespace\",\n      \"servicebus-url\" : \"service_bus_url\",\n      \"feedId\" : \"feed_id\",\n      \"customMidnight\" : 4,\n      \"history\" : {\n        \"url\" : \"endpoint_url\",\n        \"fromDateTime\" : \"-P1D\",\n        \"timeout\" : 300000\n      }\n    }\n  ]\n}\n
    "},{"location":"sandbox/siri/SiriAzureUpdater/#siri-azure-sx-updater","title":"Siri Azure SX Updater","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"siri-azure-sx-updater\" enum The type of the updater. Required 1.5 authenticationType enum Which authentication type to use Optional \"sharedaccesskey\" 2.5 autoDeleteOnIdle duration The time after which an inactive subscription is removed. Optional \"PT1H\" 2.5 customMidnight integer Time on which time breaks into new day. Optional 0 2.2 feedId string The ID of the feed to apply the updates to. Optional 2.2 fullyQualifiedNamespace string Service Bus fully qualified namespace used for authentication. Optional 2.5 fuzzyTripMatching boolean Whether to apply fuzzyTripMatching on the updates Optional false 2.2 prefetchCount integer The number of messages to fetch from the subscription at a time. Optional 10 2.5 servicebus-url string Service Bus connection used for authentication. Optional 2.2 topic string Service Bus topic to connect to. Optional 2.2 history object Configuration for fetching historical data on startup Optional 2.2 \u00a0\u00a0\u00a0fromDateTime string Datetime boundary for historical data. Optional \"-P1D\" 2.2 \u00a0\u00a0\u00a0timeout integer Timeout in milliseconds Optional 300000 na \u00a0\u00a0\u00a0toDateTime string Datetime boundary for historical data. Optional \"P1D\" 2.2 \u00a0\u00a0\u00a0url string Endpoint to fetch from Optional na"},{"location":"sandbox/siri/SiriAzureUpdater/#parameter-details_1","title":"Parameter details","text":""},{"location":"sandbox/siri/SiriAzureUpdater/#u__10__authenticationType","title":"authenticationType","text":"

    Since version: 2.5 \u2219 Type: enum \u2219 Cardinality: Optional \u2219 Default value: \"sharedaccesskey\" Path: /updaters/[10] Enum values: sharedaccesskey | federatedidentity

    Which authentication type to use

    "},{"location":"sandbox/siri/SiriAzureUpdater/#u__10__customMidnight","title":"customMidnight","text":"

    Since version: 2.2 \u2219 Type: integer \u2219 Cardinality: Optional \u2219 Default value: 0 Path: /updaters/[10]

    Time on which time breaks into new day.

    It is common that operating day date breaks a little bit later than midnight so that the switch happens when traffic is at the lowest point. Parameter uses 24-hour format. If the switch happens on 4 am then set this field to 4.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#u__10__fullyQualifiedNamespace","title":"fullyQualifiedNamespace","text":"

    Since version: 2.5 \u2219 Type: string \u2219 Cardinality: Optional Path: /updaters/[10]

    Service Bus fully qualified namespace used for authentication.

    Has to be present for authenticationMethod FederatedIdentity.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#u__10__servicebus_url","title":"servicebus-url","text":"

    Since version: 2.2 \u2219 Type: string \u2219 Cardinality: Optional Path: /updaters/[10]

    Service Bus connection used for authentication.

    Has to be present for authenticationMethod SharedAccessKey. This should be Primary/Secondary connection string from service bus.

    "},{"location":"sandbox/siri/SiriAzureUpdater/#example-configuration_1","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"siri-azure-sx-updater\",\n      \"topic\" : \"some_topic\",\n      \"servicebus-url\" : \"service_bus_url\",\n      \"feedId\" : \"feed_id\",\n      \"customMidnight\" : 4,\n      \"history\" : {\n        \"url\" : \"endpoint_url\",\n        \"fromDateTime\" : \"-P1D\",\n        \"toDateTime\" : \"P1D\",\n        \"timeout\" : 300000\n      }\n    }\n  ]\n}\n
    "},{"location":"sandbox/siri/SiriAzureUpdater/#changelog","title":"Changelog","text":""},{"location":"sandbox/siri/SiriGooglePubSubUpdater/","title":"Siri-ET Google PubSub Updater","text":"

    Support for consuming SIRI-ET messages over a Google Cloud PubSub subscription. Similarly to the SIRI-ET HTTP updater, this updater is developed to support the Nordic SIRI profile which is a subset of the SIRI specification.

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#contact-info","title":"Contact Info","text":"

    Entur, Norway https://entur.no/

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#documentation","title":"Documentation","text":"

    This updater consumes SIRI real time information over an asynchronous publisher/subscriber feed provided by a Google Cloud PubSub topic.

    For more documentation see the Entur Real-Time Data documentation and the Norwegian SIRI profile .

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#configuration","title":"Configuration","text":"

    To enable the SIRI-ET Google PubSub updater you need to add it to the updaters section of the router-config.json.

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#siri-et-via-google-pubsub","title":"Siri-ET via Google PubSub","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"siri-et-google-pubsub-updater\" enum The type of the updater. Required 1.5 dataInitializationUrl string URL used to download over HTTP the recent history of SIRI-ET messages. Optional 2.1 feedId string The ID of the feed to apply the updates to. Optional 2.1 fuzzyTripMatching boolean If the trips should be matched fuzzily. Optional false 2.1 initialGetDataTimeout duration Timeout for retrieving the recent history of SIRI-ET messages. Optional \"PT30S\" 2.1 producerMetrics boolean If failure, success, and warning metrics should be collected per producer. Optional false 2.7 reconnectPeriod duration Wait this amount of time before trying to reconnect to the PubSub subscription. Optional \"PT30S\" 2.1 subscriptionProjectName string The Google Cloud project that hosts the PubSub subscription. Required 2.1 topicName string The name of the PubSub topic that publishes the updates. Required 2.1 topicProjectName string The Google Cloud project that hosts the PubSub topic that publishes the updates. Required 2.1"},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#parameter-details","title":"Parameter details","text":""},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#u__12__dataInitializationUrl","title":"dataInitializationUrl","text":"

    Since version: 2.1 \u2219 Type: string \u2219 Cardinality: Optional Path: /updaters/[12]

    URL used to download over HTTP the recent history of SIRI-ET messages.

    Optionally the updater can download the recent history of SIRI-ET messages from this URL. If this parameter is set, the updater will be marked as initialized (primed) only when the message history is fully downloaded and applied.

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#u__12__initialGetDataTimeout","title":"initialGetDataTimeout","text":"

    Since version: 2.1 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT30S\" Path: /updaters/[12]

    Timeout for retrieving the recent history of SIRI-ET messages.

    When trying to fetch the message history over HTTP, the updater will wait this amount of time for the connection to be established. If the connection times out, the updater will retry indefinitely with exponential backoff.

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#u__12__reconnectPeriod","title":"reconnectPeriod","text":"

    Since version: 2.1 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT30S\" Path: /updaters/[12]

    Wait this amount of time before trying to reconnect to the PubSub subscription.

    In case of a network error, the updater will try periodically to reconnect to the Google PubSub subscription.

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#u__12__subscriptionProjectName","title":"subscriptionProjectName","text":"

    Since version: 2.1 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[12]

    The Google Cloud project that hosts the PubSub subscription.

    During startup, the updater creates a PubSub subscription that listens to the PubSub topic that publishes SIRI-ET updates. This parameter specifies in which Google Cloud project the subscription will be created. The topic and the subscription can be hosted in two different projects.

    "},{"location":"sandbox/siri/SiriGooglePubSubUpdater/#example-configuration","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"siri-et-google-pubsub-updater\",\n      \"feedId\" : \"feed_id\",\n      \"reconnectPeriod\" : \"5s\",\n      \"initialGetDataTimeout\" : \"1m20s\",\n      \"topicProjectName\" : \"google_pubsub_topic_project_name\",\n      \"subscriptionProjectName\" : \"google_pubsub_subscription_project_name\",\n      \"topicName\" : \"estimated_timetables\",\n      \"dataInitializationUrl\" : \"https://example.com/some/path\",\n      \"fuzzyTripMatching\" : true\n    }\n  ]\n}\n
    "},{"location":"sandbox/siri/SiriUpdater/","title":"Siri Updater","text":"

    Support for consuming SIRI ET and SX messages. The updater is developed to support the Nordic SIRI profile which is a subset of the SIRI specification.

    "},{"location":"sandbox/siri/SiriUpdater/#contact-info","title":"Contact Info","text":""},{"location":"sandbox/siri/SiriUpdater/#documentation","title":"Documentation","text":"

    This updater consumes SIRI real time information. It is developed by Entur and supports 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 documentation and the Norwegian SIRI profile .

    "},{"location":"sandbox/siri/SiriUpdater/#configuration","title":"Configuration","text":"

    To enable the SIRI updater you need to add it to the updaters section of the router-config.json.

    "},{"location":"sandbox/siri/SiriUpdater/#siri-et-via-https","title":"Siri-ET via HTTPS","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"siri-et-updater\" enum The type of the updater. Required 1.5 blockReadinessUntilInitialized boolean Whether catching up with the updates should block the readiness check from returning a 'ready' result. Optional false 2.0 feedId string The ID of the feed to apply the updates to. Required 2.0 frequency duration How often the updates should be retrieved. Optional \"PT1M\" 2.0 fuzzyTripMatching boolean If the fuzzy trip matcher should be used to match trips. Optional false 2.0 previewInterval duration TODO Optional 2.0 producerMetrics boolean If failure, success, and warning metrics should be collected per producer. Optional false 2.7 requestorRef string The requester reference. Optional 2.0 timeout duration The HTTP timeout to download the updates. Optional \"PT15S\" 2.0 url string The URL to send the HTTP requests to. Required 2.0 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.3"},{"location":"sandbox/siri/SiriUpdater/#parameter-details","title":"Parameter details","text":""},{"location":"sandbox/siri/SiriUpdater/#u__8__url","title":"url","text":"

    Since version: 2.0 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[8]

    The URL to send the HTTP requests to.

    Use the file protocol to set a directory for reading updates from a directory. The file loader will look for xml files: '*.xml' in the configured directory. The files are renamed by the loader when processed:

    a.xml \u00a0 \u279e \u00a0 a.xml.inProgress \u00a0 \u279e \u00a0 a.xml.ok \u00a0 or \u00a0 a.xml.failed

    "},{"location":"sandbox/siri/SiriUpdater/#u__8__headers","title":"headers","text":"

    Since version: 2.3 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[8]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"sandbox/siri/SiriUpdater/#example-configuration","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"siri-et-updater\",\n      \"url\" : \"https://example.com/some/path\",\n      \"feedId\" : \"feed_id\",\n      \"timeout\" : \"30s\",\n      \"headers\" : {\n        \"Authorization\" : \"Some-Token\"\n      }\n    }\n  ]\n}\n
    "},{"location":"sandbox/siri/SiriUpdater/#siri-sx-via-https","title":"Siri-SX via HTTPS","text":"Config Parameter Type Summary Req./Opt. Default Value Since type = \"siri-sx-updater\" enum The type of the updater. Required 1.5 blockReadinessUntilInitialized boolean Whether catching up with the updates should block the readiness check from returning a 'ready' result. Optional false 2.0 earlyStart duration This value is subtracted from the actual validity defined in the message. Optional \"PT0S\" 2.0 feedId string The ID of the feed to apply the updates to. Required 2.0 frequency duration How often the updates should be retrieved. Optional \"PT1M\" 2.0 requestorRef string The requester reference. Optional 2.0 timeout duration The HTTP timeout to download the updates. Optional \"PT15S\" 2.0 url string The URL to send the HTTP requests to. Supports http/https and file protocol. Required 2.0 headers map of string HTTP headers to add to the request. Any header key, value can be inserted. Optional 2.3"},{"location":"sandbox/siri/SiriUpdater/#parameter-details_1","title":"Parameter details","text":""},{"location":"sandbox/siri/SiriUpdater/#u__9__earlyStart","title":"earlyStart","text":"

    Since version: 2.0 \u2219 Type: duration \u2219 Cardinality: Optional \u2219 Default value: \"PT0S\" Path: /updaters/[9]

    This value is subtracted from the actual validity defined in the message.

    Normally the planned departure time is used, so setting this to 10s will cause the SX-message to be included in trip-results 10 seconds before the the planned departure time.

    "},{"location":"sandbox/siri/SiriUpdater/#u__9__url","title":"url","text":"

    Since version: 2.0 \u2219 Type: string \u2219 Cardinality: Required Path: /updaters/[9]

    The URL to send the HTTP requests to. Supports http/https and file protocol.

    Use the file protocol to set a directory for reading updates from a directory. The file loader will look for xml files: '*.xml' in the configured directory. The files are renamed by the loader when processed:

    a.xml \u00a0 \u279e \u00a0 a.xml.inProgress \u00a0 \u279e \u00a0 a.xml.ok \u00a0 or \u00a0 a.xml.failed

    "},{"location":"sandbox/siri/SiriUpdater/#u__9__headers","title":"headers","text":"

    Since version: 2.3 \u2219 Type: map of string \u2219 Cardinality: Optional Path: /updaters/[9]

    HTTP headers to add to the request. Any header key, value can be inserted.

    "},{"location":"sandbox/siri/SiriUpdater/#example-configuration_1","title":"Example configuration","text":"
    // router-config.json\n{\n  \"updaters\" : [\n    {\n      \"type\" : \"siri-sx-updater\",\n      \"url\" : \"https://example.com/some/path\",\n      \"feedId\" : \"feed_id\",\n      \"timeout\" : \"30s\",\n      \"headers\" : {\n        \"Key\" : \"Value\"\n      }\n    }\n  ]\n}\n
    "},{"location":"sandbox/siri/SiriUpdater/#changelog","title":"Changelog","text":""}]} \ No newline at end of file