GTFS Routes and stops
3 steps install procedure:
- Please ask for the activation of the GTFS extractors to the ODS support team
- Upload the data (i, ii and iii correspond to three distinct datasets in your catalog):
- The GTFS raw datasets are uploaded on the platform using the classic extractor ‘CSV with attached media’
- The GTFS stations are uploaded by configuring each GTFS zip file as a source and by selecting ‘GTFS Stops’ for the extractor,
- The GTFS routes are uploaded by configuring each GTFS zip file as a source and by selecting ‘GTFS Routes’ for the extractor.
One needs to check the ‘Extract filename’ option during the steps 2 and 3. You may also configure the tooltips.
- Create the custom tab: Copy and paste the code of the mini dashboard in order to visualize the routes and stops. Please check that you are using the correct dataset identifiers. The CSS code below implies that the map takes exactly the remaining height of the screen in the default theme configuration.
Note: This component cannot harness the capability of custom views to inherit the
ctx
context from catalog filters, since download links cannot be fitlered by routes or stops. It simply provides a nice way to display a gtfs and shows how to use other datasets in a custom view—not only the one you are currently exploring.
Dataset in use: gtfs_ny_routes
(See it on userclub domain)
Fields in use:
route_color | filename | route_type | route_short_name | route_long_name |
---|---|---|---|---|
FAA61A | us-ny_brx_bronx | Bus | S54 | West New Brighton - Eltingville |
EE352E | us-ny_brx_bronx | Bus | S53 | Port Richmond - Bay Ridge |
B933AD | us-ny_brx_bronx | Bus | S52 | St. George - Staten Island Univ. Hospital |
B933AD | us-ny_brx_bronx | Bus | Q56 | Broadway Junction - Jamaica |
Dataset in use: gtfs_ny_stops
(See it on userclub domain)
Fields in use:
filename |
---|
us-ny_brx_bronx |
us-ny_brx_bronx |
us-ny_brx_bronx |
us-ny_brx_bronx |
<ods-dataset-context context="lines,stops"
lines-dataset="gtfs_ny_routes"
lines-parameters="{'disjunctive.filename':'true',
'disjunctive.route_type':'true',
'disjunctive.route_short_name':'true',
'disjunctive.route_long_name':'true'}"
stops-dataset="gtfs_ny_stops"
stops-parameters="{'disjunctive.filename':'true',
'disjunctive.route_type':'true',
'disjunctive.route_short_name':'true',
'disjunctive.route_long_name':'true'}">
<div class="row">
<div class="col-md-12">
<h2>
Routes and stations' visualisation from GTFS files
</h2>
</div>
<div class="col-md-8 dashboard">
<ods-map no-refit="true" display-control="false" search-box="false" toolbar-fullscreen="true"
toolbar-geolocation="true" basemap="jawg.streets" location="10,40.70795,-73.97688"
scroll-wheel-zoom="false">
<ods-map-layer-group>
<ods-map-layer context="stops" color="#6A79B0" picto="ods-bus" show-marker="true" display="auto"
shape-opacity="0.5" point-opacity="1" border-color="#FFFFFF" border-opacity="1"
border-size="1" border-pattern="solid" caption="false"
title="Stations du réseau urbain" size="2" size-min="3" size-max="5"
size-function="linear" show-if="stations"></ods-map-layer>
</ods-map-layer-group>
<ods-map-layer-group>
<ods-map-layer context="lines" color-by-field="route_color" picto="ods-circle" show-marker="true"
display="categories" shape-opacity="0.5" point-opacity="1" border-color="#FFFFFF"
border-opacity="1" border-size="1" border-pattern="solid" caption="false"
title="Lignes du réseau urbain" size="1"></ods-map-layer>
</ods-map-layer-group>
</ods-map>
</div>
<div class="col-md-4 dashboard filters">
<label class="switch">
<div class="switch-label">
Display GTFS stops
</div>
<input class="switch-input"
type="checkbox"
ng-click="stations=!stations">
<span class="switch-button"></span>
</label>
<hr/>
<div class="clearfilters"
ng-class="{'active': lines.parameters['refine.filename'].length > 0 ||
lines.parameters['refine.route_type'].length > 0 ||
lines.parameters['refine.route_short_name'].length > 0 ||
lines.parameters['refine.route_long_name'].length > 0}"
ng-click="stops.parameters['refine.filename'] = undefined;
lines.parameters['refine.filename'] = undefined;
lines.parameters['refine.route_type'] = undefined;
lines.parameters['refine.route_short_name'] = undefined;
lines.parameters['refine.route_long_name'] = undefined;">
Clear all filters
</div>
<ods-facets context="lines">
<h3>
Operator
</h3>
<!--ods-facet name="filename" refine-also="stops" disjunctive="true"></ods-facet-->
<div ods-facet-results="filenames"
ods-facet-results-context="lines"
ods-facet-results-facet-name="filename"
ods-facet-results-sort="alphanum">
<ods-select options="filenames"
selected-values="lines.parameters['refine.filename']"
placeholder="Select one or more operator"
label-modifier="name"
value-modifier="name"
multiple="true"></ods-select>
{{ stops.parameters['refine.filename'] = lines.parameters['refine.filename'] ; '' }}
</div>
<h3>
Route type <i>(filter routes only)</i>
</h3>
<!--ods-facet name="route_type" disjunctive="true"></ods-facet-->
<div ods-facet-results="routetypes"
ods-facet-results-context="lines"
ods-facet-results-facet-name="route_type"
ods-facet-results-sort="alphanum">
<ods-select options="routetypes"
selected-values="lines.parameters['refine.route_type']"
placeholder="Select one or more route type"
label-modifier="name"
value-modifier="name"
multiple="true"></ods-select>
</div>
<h3>
Route number <i>(filter routes only)</i>
</h3>
<!--ods-facet name="route_short_name" disjunctive="true"></ods-facet-->
<div ods-facet-results="routeshortnames"
ods-facet-results-context="lines"
ods-facet-results-facet-name="route_short_name"
ods-facet-results-sort="alphanum">
<ods-select options="routeshortnames"
selected-values="lines.parameters['refine.route_short_name']"
placeholder="Select one or more route number"
label-modifier="name"
value-modifier="name"
multiple="true"></ods-select>
</div>
<h3>
Route name <i>(filter routes only)</i>
</h3>
<!--ods-facet name="route_long_name" disjunctive="true"></ods-facet-->
<div ods-facet-results="routelongnames"
ods-facet-results-context="lines"
ods-facet-results-facet-name="route_long_name"
ods-facet-results-sort="alphanum">
<ods-select options="routelongnames"
selected-values="lines.parameters['refine.route_long_name']"
placeholder="Select one or more route name"
label-modifier="name"
value-modifier="name"
multiple="true"></ods-select>
</div>
</ods-facets>
</div>
</div>
</ods-dataset-context>
.dashboard p {
text-align: right;
margin-bottom: 0;
}
.dashboard {
height: calc(100vh - 210px);
margin-bottom: 1rem;
}
.clearfilters {
margin-bottom: 0.6em;
opacity: 0.5;
cursor: default;
}
.clearfilters.active {
margin-bottom: 0.6em;
opacity: 1;
cursor: pointer;
}
.clearfilters.active:hover {
opacity: 0.75;
}
.filters {
overflow-y: scroll;
}
.odswidget-map, .odswidget-map__map {
height: 100%;
}
.odswidget-map-display-control__groups {
min-height: 0px;
}
h3 i {
font-size: 0.7em;
font-weight: 300;
}
/* Light switch
========================================================================== */
.switch {
display: flex;
align-items: center;
margin-bottom: .5rem;
}
.switch-label {
font-weight: 500;
font-size: 1.2em;
margin: 0 0.5em 0 0;
}
.switch-button {
/* background color when "off" */
background: #FFFFFF;
/* size of switch */
width: 43px;
height: 25px;
border: 2px solid #E6E6E6;
border-radius: 100px;
display: block;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
outline: 0;
-webkit-transition: all .4s ease;
-o-transition: all .4s ease;
transition: all .4s ease;
}
/* Style of the "bubble" that toggles */
.switch-button::after {
/* size of bubble */
width: 21px;
height: 21px;
border-radius: 50%;
background-color: #FFFFFF;
position: relative;
display: block;
content: "";
-webkit-transition: tranform .4s cubic-bezier(0.175, 0.885, 0.320, 1.275),
padding .3s ease, margin .3s ease;
-o-transition: tranform .4s cubic-bezier(0.175, 0.885, 0.320, 1.275),
padding .3s ease, margin .3s ease;
transition: tranform .4s cubic-bezier(0.175, 0.885, 0.320, 1.275),
padding .3s ease, margin .3s ease;
-webkit-transform: translateX(0);
-ms-transform: translateX(0);
transform: translateX(0);
-webkit-box-shadow: 0 1px 3px rgba(0,0,0,.4);
box-shadow: 0 1px 3px rgba(0,0,0,.4);
}
.switch-input {
display: none;
}
.switch-button:hover::after {
will-change: padding;
}
.switch-button:active::after {
padding-right: .4rem;
}
/* "On" state
========================== */
.switch-input:checked + .switch-button {
/* border and background color when the button is "on" */
border-color: var(--highlight);
background: var(--highlight);
}
.switch-input:checked + .switch-button::after {
/* bubble position when "on" */
-webkit-transform: translateX(18px);
-ms-transform: translateX(18px);
transform: translateX(18px);
}
.switch-input:checked + .switch-button:active::after {
margin-left: -.4rem;
}
/* Checkbox in disabled state
========================== */
.switch-input[type="checkbox"]:disabled + .switch-button {
opacity: .6;
cursor: not-allowed;
-webkit-box-shadow: 0 0 0 transparent;
box-shadow: 0 0 0 transparent;
}
.switch-input[type="checkbox"]:checked:disabled + .switch-button {
/* border and background color when button is disabled */
border-color: #cccccc;
background: #cccccc;
}