MatrixRouting() throws an error

Hi,

I’m new with TomTom SDK, coming from GoogleMaps, and I’m trying to migrate my application. I have been able to migrate to calculateRoute() service, and it is working fine.

I need to ask for several routers from a common origin, so I want to check if matrixRoute() fits my needs. However, I’m not able to get it working, as I get the following error when doing it:

converters.js:371 Uncaught (in promise) TypeError: e.forEach is not a function
at converters.js:371
at service.js:72
at Array.reduce ()
at y (service.js:72)
at service.js:111
at b (runtime.js:62)
at Generator._invoke (runtime.js:288)
at Generator.t. [as next] (runtime.js:114)
at c (service.js:110)
at a (service.js:110)

This is a very basic code I’m using, in which it is possible to get route between two points, but there is the above error when trying matrixRouting() for the same points. I’m not sure if I’m missing something or there is some format error, but I don’t find it.

One couple of extra questions:

  1. Is it possible in CalculateRoute() to set locations parameter as a set of points instead of a formatted string?

  2. Why it takes so long to load a map on the page? I find it is much slower that with google maps. Is there any way to improve it?

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="google" content="notranslate" />
<link rel='stylesheet' type='text/css' href='https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/5.53.0/maps/maps.css'>
<script src="https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/5.53.0/maps/maps-web.min.js"></script>
<script src='https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/5.53.0/services/services-web.min.js'></script>
</head>

<script>

var ttKey = 'myKey';
var ttRoutesMap;
var ttRoutesMapId = 'routesMap';
var ttRoutesMapZoom = 11;
var ttRoutesMapLayerId = 'route';

var ttMallAddress = [-4.478265, 36.656793];
var ttFinishAddress = [-4.280200, 36.718607];
var ttMapBaseStyle = 'tomtom://vector/1/';
var ttMapMainStyle = ttMapBaseStyle + 'basic-main';


function init()
{
    ttRoutesMap = tt.map({
        key: ttKey,
        container: ttRoutesMapId,
        style: ttMapMainStyle,
        center: ttMallAddress,
        zoom: ttRoutesMapZoom
    });

    var startMarker = new tt.Marker().setLngLat(ttMallAddress).addTo(ttRoutesMap);
    var endMarker = new tt.Marker().setLngLat(ttFinishAddress).addTo(ttRoutesMap);

    calculateRoute(ttFinishAddress);
    calculateMatrixRoute();
}

function convertToPoint(lng, lat) {
    return {
        point: {
            latitude: lat,
            longitude: lng
        }
    };
}

function calculateMatrixRoute()
{
    var callParameters = {
        key: ttKey,
        destinations: convertToPoint(ttFinishAddress),
        origins: convertToPoint(ttMallAddress)
    };

    tt.services.matrixRouting(callParameters)
    .go()
    .then(callbackFn);
}

function callbackFn(routeGeoJson) {
  console.log(routeGeoJson);
}

function calculateRoute(destination) {
    var loc = ttMallAddress.join(',') + ':' + destination.join(',');
    tt.services.calculateRoute({
        key: ttKey,
        locations: loc,
        departAt: 'now',
        routeType: 'fastest',
        traffic: true,
        travelMode: 'car'
    })
    .go()
    .then(function(response) {
        var geojson = response.toGeoJson();
        ttRoutesMap.addLayer({
            'id': ttRoutesMapLayerId,
            'type': 'line',
            'source': {
                'type': 'geojson',
                'data': geojson
            },
            'paint': {
                'line-color': '#2faaff',
                'line-width': 8
            }
        });

        //Update map bounds to new Route
        var bounds = new tt.LngLatBounds();
        geojson.features[0].geometry.coordinates.forEach(function(point) {
            bounds.extend(tt.LngLat.convert(point));
        });
        ttRoutesMap.fitBounds(bounds, {padding: 20});
    });
}
</script>

<body onLoad="init()" >
    <div style="width:90vw; height:90vh" id='routesMap'></div>
</body>
</html>

Regards,

1 Like

Hi Daniel.

Welcome to our community! :slight_smile:

You have an error in your code when calling convertToPoint function and when constructing origins and destinations of the matrix routing callParameters object. I’ve fixed those errors and it should work fine now. You can check the code here:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="google" content="notranslate" />
<link rel='stylesheet' type='text/css' href='https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/5.53.0/maps/maps.css'>
<script src="https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/5.53.0/maps/maps-web.min.js"></script>
<script src='https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/5.53.0/services/services-web.min.js'></script>
</head>
<script>
var ttKey = 'apiKey';
var ttRoutesMap;
var ttRoutesMapId = 'routesMap';
var ttRoutesMapZoom = 11;
var ttRoutesMapLayerId = 'route';
var ttMallAddress = [-4.478265, 36.656793]; //long, lat
var ttFinishAddress = [-4.280200, 36.718607];
var ttMapBaseStyle = 'tomtom://vector/1/';
var ttMapMainStyle = ttMapBaseStyle + 'basic-main';

function init()
{
    ttRoutesMap = tt.map({
        key: ttKey,
        container: ttRoutesMapId,
        style: ttMapMainStyle,
        center: ttMallAddress,
        zoom: ttRoutesMapZoom
    });
    ttRoutesMap.on("load", onMapLoaded);
}

function onMapLoaded() {
    var startMarker = new tt.Marker().setLngLat(ttMallAddress).addTo(ttRoutesMap);
    var endMarker = new tt.Marker().setLngLat(ttFinishAddress).addTo(ttRoutesMap);

    calculateRoute(ttFinishAddress);
    calculateMatrixRoute();
}

function convertToPoint(lng, lat) {
    return {
        point: {
            latitude: lat,
            longitude: lng
        }
    };
}

function calculateMatrixRoute()
{
    var callParameters = {
        key: ttKey,
        destinations: [convertToPoint(ttFinishAddress[0], ttFinishAddress[1])],
        origins: [convertToPoint(ttMallAddress[0], ttMallAddress[1])]
    };
    tt.services.matrixRouting(callParameters)
    .go()
    .then(callbackFn);
}

function callbackFn(routeGeoJson) {
  console.log(routeGeoJson);
}

function calculateRoute(destination) {
    var loc = ttMallAddress.join(',') + ':' + destination.join(',');
    tt.services.calculateRoute({
        key: ttKey,
        locations: loc,
        departAt: 'now',
        routeType: 'fastest',
        traffic: true,
        travelMode: 'car'
    })
    .go()
    .then(function(response) {
        var geojson = response.toGeoJson();
        ttRoutesMap.addLayer({
            'id': ttRoutesMapLayerId,
            'type': 'line',
            'source': {
                'type': 'geojson',
                'data': geojson
            },
            'paint': {
                'line-color': '#2faaff',
                'line-width': 8
            }
        });

        //Update map bounds to new Route
        var bounds = new tt.LngLatBounds();
        geojson.features[0].geometry.coordinates.forEach(function(point) {
            bounds.extend(tt.LngLat.convert(point));
        });
        ttRoutesMap.fitBounds(bounds, {padding: 20});
    });
}
</script>

<body onLoad="init()" >
    <div style="width:90vw; height:90vh" id='routesMap'></div>
</body>
</html>

Regarding your extra questions:
Ad. 1: Please refer to the docs. There are more possibilities than a formatted string.
Ad. 2: Inside your code, I’ve moved some functionality to the map load event. It should improve loading a little bit.

Please also take a look at our Taxi Cars Dispatcher tutorial application. It is using the Matrix Routing API and you should find a lot of ready to use code examples there.

Regards,
Mateusz

1 Like

Hi Mateusz,

thanks for your help. I didn’t realize on the errors :slight_smile:

I’ll check the changes on the maps loading, and the Taxi Cars example.

Regards,
Daniel

2 Likes