Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapbox gl & directions API call - doesn't display routes

I have an app with multiple markers, for displaying a travel. Each marker is a step, and I want to create a route between each marker with it following marker (following step).

For that, right now I have this code :

$(document).ready(function() {
  var map;
  var directions;

  // token access for MAPBOX GL
  mapboxgl.accessToken = 'pk.eyJ1IjoiYW50b3RvIiwiYSI6ImNpdm15YmNwNTAwMDUyb3FwbzlzeWluZHcifQ.r44fcNU5pnX3-mYYM495Fw';

  // generate map
  var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/streets-v10',
    center: [-96, 37.8],
    zoom: 5
  });

  // center map on selected marker
  map.on('click', 'markers', function (e) {
    map.flyTo({center: e.features[0].geometry.coordinates});
  });

  // change mouse action on enter / leave in marker
  map.on('mouseenter', 'markers', function () {
    map.getCanvas().style.cursor = 'pointer';
  });

  map.on('mouseleave', 'markers', function () {
    map.getCanvas().style.cursor = '';
  });

  $.ajax({
    dataType: 'json',
    url: grabTravelData(),
    success: function(data) {
        geojson = data;
        map.addSource("markers", {
            "type": "geojson",
            "data": {
                "type": "FeatureCollection",
                "features": data
            }
        });
        map.addLayer({
            "id": "markers",
            "type": "circle",
            "source": "markers",
            "paint": {
                "circle-radius": 7,
                "circle-color": "#ff7e5f"
            },
        });
        // center map on markers
        var bounds = new mapboxgl.LngLatBounds();
        data.forEach(function(feature) {
            bounds.extend(feature.geometry.coordinates);
        });
        map.fitBounds(bounds);

        for(var i = 0; i < data.length; i++) {
            var last = data.length - 1
            var from = data[i];
            var to = data[i + 1];
            if(i != last) {
                apiCall(from.geometry.coordinates[0], from.geometry.coordinates[1], to.geometry.coordinates[0], to.geometry.coordinates[1], mapboxgl.accessToken, i);
            } else {
                apiCall(from.geometry.coordinates[0], from.geometry.coordinates[1], from.geometry.coordinates[0], from.geometry.coordinates[1], mapboxgl.accessToken, i);
            }
        }
    }, error: function(data) {
        console.log(data + ' error');
    }
});

function apiCall(from_one, from_two, to_one, to_two, token, number) {
  $.get("https://api.mapbox.com/directions/v5/mapbox/driving/" + from_one + "," + from_two + ";" + to_one + "," + to_two + "?access_token=" + token, function(data) {
    var naming = "route-" + number;
    map.on('load', function () {
        map.addSource(naming, {
            "type": "geojson",
            "data": {
                "type": "Feature",
                "properties": {},
                "geometry": {
                    "type": "LineString",
                    "coordinates": data.routes[0].geometry
                }
            }
        });

        map.addLayer({
            "id": naming,
            "type": "line",
            "source": naming,
            "layout": {
                "line-join": "round",
                "line-cap": "round"
            },
            "paint": {
                "line-color": "#ff7e5f",
                "line-width": 8
            }
        });
    });
  }
}

But the routes doesn't appear on the map, and I read on the API Documentation this line : // This API is not available through the JavaScript SDK

So maybe I can't call the API. With this code I have a good result:

with this url : https://api.mapbox.com/directions/v5/mapbox/driving/18.0944238,42.65066059999999;15.981919,45.8150108?access_token=

And the result is a json with geometry... so a good result as it's write in the documentation.

Maybe someone know how should I display routes on the map ? And if I can't with the API call, how should I modify my code to use the Directions Plugin ?

like image 573
Antonin Mrchd Avatar asked May 16 '17 18:05

Antonin Mrchd


People also ask

Is mapbox-gl free?

Is Mapbox GL JS open source? The previous version, Mapbox GL JS v1, is indeed a free and open-source, BSD3 licensed software. Anyone can contribute to it, or start their own derived work based on it, for free. As of February 2021, the v1 source code is still available from the Mapbox Github.

What does GL stand for Mapbox?

The abbreviation "GL" comes from OpenGL, the industry-standard Open Graphics Library. Mapbox GL allows you to use custom styles designed in Mapbox Studio. You can also manipulate every aspect of the style's appearance dynamically, because Mapbox GL renders vector tiles.

Is Mapbox better than Google Maps?

Customization: Mapbox has the best customization features, hands down. Google Maps is less flexible – for instance, it forces you to use its default base layer, while Mapbox does not. Ease of Integration: This really depends on the experience that your developers and designers have with the APIs and their SDKs.

Is Mapbox Studio free?

While Mapbox isn't entirely free, it has a generous free tier in its pricing packages that makes the service attractive for apps with a low volume of users. Free for up to 25,000 mobile users and 50,000 web loads. Customization of maps is easy.


1 Answers

Your problem is that the directions API is returning by default geometries encoded in polylines, which are not geojson features.

To get around that, you can specify the &geometries=geojson query parameter to your url, and it will return you the data in the correct format you can display easily.

Also one thing, it seems better to me to do your ajax after the map has finished loaded.

// This is the token from their docs, don't be evil
mapboxgl.accessToken = 'pk.eyJ1IjoiYXBlcmN1IiwiYSI6ImNpZ3M0ZDZ2OTAwNzl2bmt1M2I0dW1keTIifQ.I5BD9uEHdm_91TiyBEk7Pw'

const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v9',
  center: [18.0944238, 42.65066059999999],
  zoom: 9,
})

map.on('load', () => {

  $.get(`https://api.mapbox.com/directions/v5/mapbox/driving/18.0944238,42.65066059999999;15.981919,45.8150108?access_token=${mapboxgl.accessToken}&geometries=geojson`, data => {
  
    map.addLayer({
      id: 'route',
      type: 'line',
      source: {
        type: 'geojson',
        data: {
          type: 'Feature',
          properties: {},
          geometry: data.routes[0].geometry,
        },
      },
      layout: {
        'line-join': 'round',
        'line-cap': 'round',
      },
      paint: {
        'line-color': '#ff7e5f',
        'line-width': 8,
      },
    })
  
  })

})
html, body, #map {
  height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.37.0/mapbox-gl.js"></script>
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.37.0/mapbox-gl.css" rel="stylesheet"/>

<body>
  <div id='map'></div>
</body>
like image 134
Preview Avatar answered Sep 26 '22 22:09

Preview