Page Templates - GTFS Custom View

This custom view will let you display routes and stops from a General Transit Feed Specification (GTFS) file. It can be used either as a custom view inside your catalog or on a custom page.

GTFS Routes and stops New

See it live!

This component cannot harness the capability of custom views to inherit the ctx contex 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.

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