UNPKG

@vtmap/vtmap-sdk-js

Version:

JS SDK for accessing Viettelmaps APIs

184 lines (170 loc) 6.92 kB
'use strict'; var v = require('./service-helpers/validator'); var createServiceFactory = require('./service-helpers/create-service-factory'); var objectClean = require('./service-helpers/object-clean'); var stringifyBooleans = require('./service-helpers/stringify-booleans'); /** * Directions API service. * * Learn more about this service and its responses in * [the HTTP service documentation](https://docs.mapbox.com/api/navigation/#directions). */ var Directions = {}; /** * Get directions. * * Please read [the full HTTP service documentation](https://docs.mapbox.com/api/navigation/#directions) * to understand all of the available options. * * @param {Object} config * @param {'driving-traffic'|'driving'|'walking'|'cycling'} [config.profile="driving"] * @param {Array<DirectionsWaypoint>} config.waypoints - An ordered array of [`DirectionsWaypoint`](#directionswaypoint) objects, between 2 and 25 (inclusive). * @param {boolean} [config.alternatives=false] - Whether to try to return alternative routes. * @param {Array<'duration'|'distance'|'speed'|'congestion'>} [config.annotations] - Specify additional metadata that should be returned. * @param {boolean} [config.bannerInstructions=false] - Should be used in conjunction with `steps`. * @param {boolean} [config.continueStraight] - Sets the allowed direction of travel when departing intermediate waypoints. * @param {string} [config.exclude] - Exclude certain road types from routing. See HTTP service documentation for options. * @param {'geojson'|'polyline'|'polyline6'} [config.geometries="polyline"] - Format of the returned geometry. * @param {string} [config.language="en"] - Language of returned turn-by-turn text instructions. * See options listed in [the HTTP service documentation](https://docs.mapbox.com/api/navigation/#instructions-languages). * @param {'simplified'|'full'|'false'} [config.overview="simplified"] - Type of returned overview geometry. * @param {boolean} [config.roundaboutExits=false] - Emit instructions at roundabout exits. * @param {boolean} [config.steps=false] - Whether to return steps and turn-by-turn instructions. * @param {boolean} [config.voiceInstructions=false] - Whether or not to return SSML marked-up text for voice guidance along the route. * @param {'imperial'|'metric'} [config.voiceUnits="imperial"] - Which type of units to return in the text for voice instructions. * @return {MapiRequest} * * @example * directionsClient.getDirections({ * profile: 'driving-traffic', * waypoints: [ * { * coordinates: [13.4301, 52.5109], * approach: 'unrestricted' * }, * { * coordinates: [13.4265, 52.508] * }, * { * coordinates: [13.4194, 52.5072], * bearing: [100, 60] * } * ] * }) * .send() * .then(response => { * const directions = response.body; * }); */ Directions.getDirections = function(config) { v.assertShape({ profile: v.oneOf('driving-traffic', 'driving', 'walking', 'cycling'), waypoints: v.required( v.arrayOf( v.shape({ coordinates: v.required(v.coordinates), approach: v.oneOf('unrestricted', 'curb'), bearing: v.arrayOf(v.range([0, 360])), radius: v.oneOfType(v.number, v.equal('unlimited')), waypointName: v.string }) ) ), alternatives: v.boolean, annotations: v.arrayOf( v.oneOf('duration', 'distance', 'speed', 'congestion') ), bannerInstructions: v.boolean, continueStraight: v.boolean, exclude: v.string, geometries: v.string, language: v.string, overview: v.string, roundaboutExits: v.boolean, steps: v.boolean, voiceInstructions: v.boolean, voiceUnits: v.string })(config); config.profile = config.profile || 'driving'; var path = { coordinates: [], approach: [], bearing: [], radius: [], waypointName: [] }; var waypointCount = config.waypoints.length; if (waypointCount < 2 || waypointCount > 25) { throw new Error( 'waypoints must include between 2 and 25 DirectionsWaypoints' ); } /** * @typedef {Object} DirectionsWaypoint * @property {Coordinates} coordinates * @property {'unrestricted'|'curb'} [approach="unrestricted"] - Used to indicate how requested routes consider from which side of the road to approach the waypoint. * @property {[number, number]} [bearing] - Used to filter the road segment the waypoint will be placed on by direction and dictates the angle of approach. * This option should always be used in conjunction with a `radius`. The first value is an angle clockwise from true north between 0 and 360, * and the second is the range of degrees the angle can deviate by. * @property {number|'unlimited'} [radius] - Maximum distance in meters that the coordinate is allowed to move when snapped to a nearby road segment. * @property {string} [waypointName] - Custom name for the waypoint used for the arrival instruction in banners and voice instructions. */ config.waypoints.forEach(function(waypoint) { path.coordinates.push( waypoint.coordinates[0] + ',' + waypoint.coordinates[1] ); // join props which come in pairs ['bearing'].forEach(function(prop) { if (waypoint.hasOwnProperty(prop) && waypoint[prop] != null) { waypoint[prop] = waypoint[prop].join(','); } }); ['approach', 'bearing', 'radius', 'waypointName'].forEach(function(prop) { if (waypoint.hasOwnProperty(prop) && waypoint[prop] != null) { path[prop].push(waypoint[prop]); } else { path[prop].push(''); } }); }); ['approach', 'bearing', 'radius', 'waypointName'].forEach(function(prop) { // avoid sending params which are all `;` if ( path[prop].every(function(char) { return char === ''; }) ) { delete path[prop]; } else { path[prop] = path[prop].join(';'); } }); var query = stringifyBooleans({ alternatives: config.alternatives, annotations: config.annotations, banner_instructions: config.bannerInstructions, continue_straight: config.continueStraight, exclude: config.exclude, geometries: config.geometries, language: config.language, overview: config.overview, roundabout_exits: config.roundaboutExits, steps: config.steps, voice_instructions: config.voiceInstructions, voice_units: config.voiceUnits, approaches: path.approach, bearings: path.bearing, radiuses: path.radius, waypoint_names: path.waypointName }); return this.client.createRequest({ method: 'GET', path: '/directions/v5/mapbox/:profile/:coordinates', params: { profile: config.profile, coordinates: path.coordinates.join(';') }, query: objectClean(query) }); }; module.exports = createServiceFactory(Directions);