ItineraryService.js

ItineraryService()


constructor

The ItineraryService object is responsible for computing the itinerary between a start point and an end point and optionally waypoints can be included.

Parameter Type Description
customer String The customer name.
key String The authorization key necessary for using the [ItineraryService].

computeItinerary()


method

Computes the itinerary.

Options:
  • travelMode(String)The travel mode. Accepted values: vehicle, pedestrian, publictransport. Default is vehicle.
  • avoidTollRoad(Boolean)Indicates if toll roads should ve avoided. Defauls is true.
  • avoidHighways(Boolean)Indicates if highways should be avoided. Default is true.
  • unitSystem(String)Specifies the unit system that the itinerary service should use. Accepted values: metric, imperial, metricandimperial. Deafult is metricandimperial.
  • optimizationType(String)Indicates the type of oprimization the itinerary service should take into consideration. Accepted values: distance, time. Default is time.
  • customSpeedProfile(Array)An array of custom speed limits on different types of roads (highway, express road, national road, etc.).
Parameter Type Description
start LatLng The start point.
end LatLng The end point.
waypoints Array An array of {LatLng} objects.
options Object The options to set for computing the itinerary.
returns
Promise - A promise which returns the computed itinerary.

Example

$(document).ready(function(){

    var mapContainer = T.DomUtil.get("map"),
        mapoLayer = new T.TibcoLayer();

    // init map
    var map = new T.Map(
        mapContainer,					
        {
            zoom: 3, 
            center: new T.LatLng(46, 2)
        }
    );		

    map.addLayer(mapoLayer);

    // Itinerary computation
    var itineraryService = new T.ItineraryService("demo", "2u7kdn4DnYE=", "https://geowebservices.maporama.com/");

    // Init itinerary renderer
    var itineraryRenderer = new T.ItineraryRenderer(map);

    $( "#results #toggle" ).click(function() {
        $( "#results #container" ).toggle( "slow", function() {
            // Animation complete.
        });
    });

    var computeItineraryHandler = function () {

        // Add overlay
        showHideOverlay(true);

        var startStringNoSpaces = $("#start").val().replace(/\s/g, "");
        var endStringNoSpaces = $("#end").val().replace(/\s/g, "");
        var speedLimits = $("#custom-speed-profile").val();

        if (speedLimits) {
            speedLimits = speedLimits.replace(/\s/g, "");
            speedLimits = speedLimits.split(',');
        }

        var start = new T.LatLng(startStringNoSpaces.split(',')[0], startStringNoSpaces.split(',')[1]),
            end = new T.LatLng(endStringNoSpaces.split(',')[0], endStringNoSpaces.split(',')[1]),
            waypoints = [];

        // Parse waypoints
        $("#waypoints .waypoint").each(function (index) {
            var waypoint = {},
                locationNoSpaces = "",
                theIndex = index + 1;

            locationNoSpaces = $('#waypoints #waypoint-' + theIndex + ' #location').val().replace(" ", "");
            waypoint = new T.LatLng(locationNoSpaces.split(',')[0], locationNoSpaces.split(',')[1]);

            // Add to waypoints array
            waypoints.push(waypoint);
        });

        // Save options
        var itineraryOptions = {
            travelMode: $("#travel-mode").val(),
            language: $("#language").val(),
            avoidTollRoad: $("#avoid-toll-roads").val(),
            avoidHighways: $("#avoid-highways").val(),
            unitSystem: $("#unit-system").val(),
            optimizationType: $("#optimization-type").val(),
            customSpeedProfile: speedLimits,
        };

        // Compute distance
        itineraryService.computeItinerary(start, end, waypoints, itineraryOptions).then(function (itineraryServiceResults) {

            if (itineraryServiceResults) {
                // Remove itinerary
                itineraryRenderer.removeItinerary();

                itineraryRenderer.displayItinerary(itineraryServiceResults, {
                    zoomToItinerary: true,
                    stroke: true,
                    strokeColor: "#FF0000",
                    strokeOpacity: 0.9,
                    strokeWeight: 2
                });

                showHideOverlay(false);
                    map.$layersArray[0].events.detach('tiles-loaded', f);

                    $('#results').toggle(true);

                    var template = $("#itinerary-results-tpl").html(),
                        rendered = Mustache.render(template, itineraryServiceResults);

                    $("#results #container").html(rendered);
            }

        }, function (itineraryServiceError) {
            var template = $("#itinerary-error-tpl").html(),
                rendered = Mustache.render(template, itineraryServiceError);

            // Remove overlay
            showHideOverlay(false);

            $('#results').toggle(true);
            $("#results #container").html(rendered);
        });
    };

    var addWaypointHandler = function () {
        var template = $("#waypoint-tpl").html(),
            rendered = Mustache.render(template, {
                index: $("#waypoints").children().length + 1
            });

        $("#waypoints").append(rendered);
    };

    var deleteWaypointHandler = function () {
        var lastIndex = 1;

        $("#waypoints .waypoint").each(function (index) {
            lastIndex = index + 1;
        });

        $("#waypoints #waypoint-" + lastIndex).remove();
    };

    var showHideOverlay = function (show) {

        if (show) {
            var docHeight = $(document).height();

            $("body").append("<div id='overlay'></div>");

            $("#overlay")
                .height(docHeight)
                .css({
                'opacity' : 0.4,
                'position': 'absolute',
                'top': 0,
                'left': 0,
                'background-color': 'black',
                'width': '100%',
                'z-index': 5000
            });
        } else {
            $("#overlay").remove();
        }
    };

    // Event listeners
    $("#compute-distance-btn").click(T.Util.bind(computeItineraryHandler, this));
    $("#add-waypoint-btn").click(T.Util.bind(addWaypointHandler, this));
    $("#delete-waypoint-btn").click(T.Util.bind(deleteWaypointHandler, this));
});
<html>    
    <head>
        <title>TibcoMaps - Itinerary Service</title>
        <meta charset="UTF-8">

        <!-- CSS -->
        <link rel="stylesheet", href="itinerary-service.css"/>

        <!-- Javascript -->
        <script type="text/javascript" src='../../lib/GeoAnalytics.js'></script>
        <script type="text/javascript" src='../../lib/jquery-1.9.1.min.js'></script>
        <script type="text/javascript" src='../../lib/mustache.min.js'></script>
        <script type="text/javascript" src="itinerary-service.js"></script>
    </head>


    <body>
        <div class="container">
            <div id="form">
                <div class="options">
                    <div class="form-group">
                        <div class="title">Language:</div>
                        <select id="language">
                            <option value="EN">English</option>
                            <option value="FR">French</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <div class="title">Travel mode:</div>
                        <select id="travel-mode">
                            <option value="vehicle">Vehicle</option>
                            <option value="pedestrian">Pedestrian</option>
                            <option value="publictransport">Public transport</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <div class="title">Avoid toll roads:</div>
                        <select id="avoid-toll-roads">
                            <option value="true">True</option>
                            <option value="false">False</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <div class="title">Avoid highways:</div>
                        <select id="avoid-highways">
                            <option value="true">True</option>
                            <option value="false">False</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <div class="title">Unit system:</div>
                        <select id="unit-system">
                            <option value="metric">Metric</option>
                            <option value="imperial">Imperial</option>
                            <option value="metricandimperial">Metric & Imperial</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <div class="title">Optimize by:</div>
                        <select id="optimization-type">
                            <option value="time">Time</option>
                            <option value="distance">Distance</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <div class="title">Custom speed limits:</div>
                        <div class="inputs">
                            <input id="custom-speed-profile" type="text" placeholder="e.g. 150,125,85,65,48,34,24,8" value=""/>
                        </div>
                    </div>
                </div>

                <div id="btn-group">
                    <button id="add-waypoint-btn">Add waypoint</button>
                    <button id="delete-waypoint-btn">Delete waypoint</button>
                    <button id="compute-distance-btn">Compute Itinerary</button>
                </div>

                <div class="form-group">
                    <div class="title">Start:</div>
                    <div class="inputs">
                        <input id="start" type="text" placeholder="Latitude, Longitude" value="48.859367, 2.339850"/>
                    </div>
                </div>

                <div class="form-group">
                    <div class="title">End:</div>
                    <div class="inputs">
                        <input id="end" type="text" placeholder="Latitude, Longitude" value="45.767835, 4.831688"/>
                    </div>
                </div>

                <div id="waypoints"></div>

            </div>
            <div id="map"></div>
            <div id="results">
                <div id="toggle">Results</div>
                <div id="container"></div>
            </div>
        </div>

        <script id="waypoint-tpl" type="x-tmpl-mustache">
            <div id="waypoint-{{index}}" class="form-group waypoint">
                <div class="title">Waypoint {{index}}</div>
                <div class="inputs">
                    <input id="location" type="text" placeholder="Latitude, Longitude" value=""/>
            </div>
            </div>
        </script>

        <script id="itinerary-results-tpl" type="x-tmpl-mustache">
            <div id="summary">
                <div id="distance">
                    <b>Distance:</b>
                    {{#Summary.Distance.KmLabel}}<i>{{Summary.Distance.KmLabel}}</i>{{/Summary.Distance.KmLabel}}
                    {{#Summary.Distance.MileLabel}}, <i>{{Summary.Distance.MileLabel}}</i>{{/Summary.Distance.MileLabel}}
            </div>
                <div id="time"><b>Time:</b> <i>{{Summary.Time.TimeLabel}}</i></div>
            </div>
            <div id=segments>
                {{#Segments}}
                    <div class="result-item">
                        <div id="title" class="title">{{SegmentNumber}}. {{Name}}</div>
                        <br/>
                        <div id="distance">
                            <b>Distance:</b>
                            {{#SegmentSummary.Distance.KmLabel}}<i>{{SegmentSummary.Distance.KmLabel}}</i>{{/SegmentSummary.Distance.KmLabel}}
                            {{#SegmentSummary.Distance.MileLabel}}, <i>{{SegmentSummary.Distance.MileLabel}}</i>{{/SegmentSummary.Distance.MileLabel}}
            </div>
                        <div id="time"><b>Time:</b> <i>{{SegmentSummary.Time.TimeLabel}}</i></div>
                        <br/>
                        <div id="sentence"><b>Directions:</b> <i>{{Sentence}}</i></div>
            </div>
                {{/Segments}}
            </div>
        </script>

        <script id="itinerary-error-tpl" type="x-tmpl-mustache">
            <div class="error">{{Code}}, {{CustomMessage}}, {{Message}}</div>
        </script>
    </body>
</html>
body, html { 
    height: 100%;
    width: 100%;
    margin: 0px;
}

.error {
    color: red;
}

.container  {
    display: flex;
    height: 100%;
    padding: 0 0 0 15px;
}

.container #form {
    width: 400px;
    height: 100%;
    padding-right: 15px;
    overflow: auto;
}

.container #form .options {
    border-bottom: 1px solid black;
    padding-bottom: 10px;
}

.container #form .form-group {
    display: flex;
    margin-top: 10px;
}

.container #form .form-group .title {
    width: 160px;
    font-weight: bold;
    margin-bottom: 5px;
}

.container #form .form-group .inputs > input {
    width: 190px;
    margin-bottom: 5px;
}

.container #map {			
    flex: 1;
}

.container #btn-group {
    margin: 20px 0;
}

.container #waypoints .waypoint {
    padding: 10px;
    border: 1px dotted black;
}

#results {
    position: absolute;
    top: 50px;
    right: 0px;
    display: none;
    background-color: white;
    max-width: 500px;
    padding: 20px 0;
}

#results #container {
    padding: 0 30px;
}

#results #container #segments {
    max-height: 500px;
    overflow: auto;
}

#results #summary {
    margin-bottom: 20px;
}

#results #toggle {
    position: absolute;
    top: 0;
    left: -60px;
    width: 50px;
    background-color: white;
    padding: 10px 0 10px 10px;
    cursor: pointer;
}

#results .result-item {
    border: 1px dotted black;
    padding: 10px;
    margin-bottom: 10px;
}

#results .result-item .title {
    font-weight: bold;
}