Skip to content

Commit

Permalink
Merge pull request #18 from mapbox/multi-endpoint
Browse files Browse the repository at this point in the history
Multi-endpoint refactor
  • Loading branch information
tmcw committed Jul 19, 2015
2 parents 66f44f3 + 6235909 commit 36f91ff
Show file tree
Hide file tree
Showing 14 changed files with 105 additions and 78 deletions.
15 changes: 15 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ Search for a location with a string, using the

* `query` **`string`** desired location
* `options` **`[Object]`** additional options meant to tune the request (optional, default `{}`)
* `options.proximity` **`Object`** a proximity argument: this is a geographical point given as an object with latitude and longitude properties. Search results closer to this point will be given higher priority.
* `options.dataset` **`[string]`** the desired data to be geocoded against. The default, mapbox.places, does not permit unlimited caching. `mapbox.places-permanent` is available on request and does permit permanent caching. (optional, default `mapbox.places`)
* `callback` **`Function`** called with (err, results)


Expand Down Expand Up @@ -54,7 +56,10 @@ there. This uses the [Mapbox Geocoding API](https://www.mapbox.com/developers/ap
### Parameters

* `location` **`Object`** the geographical point to search
* `location.latitude` **`number`** decimal degrees latitude, in range -90 to 90
* `location.longitude` **`number`** decimal degrees longitude, in range -180 to 180
* `options` **`[Object]`** additional options meant to tune the request (optional, default `{}`)
* `options.dataset` **`[string]`** the desired data to be geocoded against. The default, mapbox.places, does not permit unlimited caching. `mapbox.places-permanent` is available on request and does permit permanent caching. (optional, default `mapbox.places`)
* `callback` **`Function`** called with (err, results)


Expand All @@ -81,6 +86,10 @@ for more documentation.

* `waypoints` **`Array<Object>`** an array of objects with `latitude` and `longitude` properties that represent waypoints in order. Up to 25 waypoints can be specified.
* `options` **`[Object]`** additional options meant to tune the request (optional, default `{}`)
* `options.profile` **`[string]`** the directions profile, which determines how to prioritize different routes. Options are `'mapbox.driving'`, which assumes transportation via an automobile and will use highways, `'mapbox.walking'`, which avoids streets without sidewalks, and `'mapbox.cycling'`, which prefers streets with bicycle lanes and lower speed limits for transportation via bicycle. (optional, default `mapbox.driving`)
* `options.alternatives` **`[string]`** whether to generate alternative routes along with the preferred route. (optional, default `true`)
* `options.instructions` **`[string]`** format for turn-by-turn instructions along the route. (optional, default `text`)
* `options.geometry` **`[string]`** format for the returned route. Options are `'geojson'`, `'polyline'`, or `false`: `polyline` yields more compact responses which can be decoded on the client side. [GeoJSON](http://geojson.org/), the default, is compatible with libraries like [Mapbox GL](https://www.mapbox.com/mapbox-gl/), Leaflet and [Mapbox.js](https://www.mapbox.com/mapbox.js/). `false` omits the geometry entirely and only returns instructions. (optional, default `geojson`)
* `callback` **`Function`** called with (err, results)


Expand Down Expand Up @@ -122,6 +131,9 @@ for more documentation.

* `trace` **`Object`** a single [GeoJSON](http://geojson.org/) Feature with a LineString geometry, containing up to 100 positions.
* `options` **`[Object]`** additional options meant to tune the request (optional, default `{}`)
* `options.profile` **`[string]`** the directions profile, which determines how to prioritize different routes. Options are `'mapbox.driving'`, which assumes transportation via an automobile and will use highways, `'mapbox.walking'`, which avoids streets without sidewalks, and `'mapbox.cycling'`, which prefers streets with bicycle lanes and lower speed limits for transportation via bicycle. (optional, default `mapbox.driving`)
* `options.geometry` **`[string]`** format for the returned route. Options are `'geojson'`, `'polyline'`, or `false`: `polyline` yields more compact responses which can be decoded on the client side. [GeoJSON](http://geojson.org/), the default, is compatible with libraries like [Mapbox GL](https://www.mapbox.com/mapbox-gl/), Leaflet and [Mapbox.js](https://www.mapbox.com/mapbox.js/). `false` omits the geometry entirely and only returns matched points. (optional, default `geojson`)
* `options.gps_precision` **`[number]`** An integer in meters indicating the assumed precision of the used tracking device. Use higher numbers (5-10) for noisy traces and lower numbers (1-3) for clean traces. The default value is 4. (optional, default `4`)
* `callback` **`Function`** called with (err, results)


Expand Down Expand Up @@ -174,6 +186,9 @@ for more documentation.
* `fields` **`Array<string>`** layer within the given `mapid` for which to pull data
* `path` **`Array<Object> or string`** either an encoded polyline, provided as a string, or an array of objects with longitude and latitude properties, similar to waypoints.
* `options` **`[Object]`** additional options meant to tune the request (optional, default `{}`)
* `options.geojson` **`[string]`** whether to return data as a GeoJSON point (optional, default `false`)
* `options.zoom` **`[string]`** zoom level at which features are queried (optional, default `maximum`)
* `options.interpolate` **`[boolean]`** Whether to interpolate between matches in the feature collection. (optional, default `true`)
* `callback` **`Function`** called with (err, results)


Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# node-mapbox
# mapbox-sdk-js

[![npm version](https://badge.fury.io/js/mapbox.svg)](http://badge.fury.io/js/mapbox)
[![Build Status](https://travis-ci.org/mapbox/mapbox-sdk-js.svg?branch=master)](https://travis-ci.org/mapbox/mapbox-sdk-js)
Expand Down
9 changes: 2 additions & 7 deletions lib/client.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'use strict';

var invariant = require('invariant');
var makeClient = require('./make_service');
var xtend = require('xtend/mutable');

var MapboxGeocoder = require('./services/geocoder');
var MapboxSurface = require('./services/surface');
var MapboxDirections = require('./services/directions');
Expand All @@ -17,11 +16,7 @@ var MapboxMatching = require('./services/matching');
* @example
* var client = new MapboxClient('ACCESSTOKEN');
*/
function MapboxClient(accessToken) {
invariant(typeof accessToken === 'string',
'accessToken required to instantiate MapboxClient');
this.accessToken = accessToken;
}
var MapboxClient = makeClient('MapboxClient');

xtend(MapboxClient.prototype,
MapboxGeocoder.prototype,
Expand Down
15 changes: 6 additions & 9 deletions lib/constants.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
var compile = require('es6-template-strings/compile');

var API = 'https://api.tiles.mapbox.com/';
var APIV4 = API + 'v4/';

module.exports.API = API;
module.exports.API_GEOCODER_FORWARD = compile(APIV4 + 'geocode/${dataset}/${encodeURIComponent(query)}.json');
module.exports.API_GEOCODER_REVERSE = compile(APIV4 + 'geocode/${dataset}/${location.longitude},${location.latitude}.json');
module.exports.API_DIRECTIONS = compile(APIV4 + 'directions/${profile}/${encodedWaypoints}.json');
module.exports.API_MATCHING = compile(API + 'matching/v4/${profile}.json');
module.exports.API_SURFACE = compile(APIV4 + 'surface/${mapid}.json');
module.exports.DEFAULT_ENDPOINT = 'https://api.mapbox.com';
module.exports.API_GEOCODER_FORWARD = compile('${endpoint}/v4/geocode/${dataset}/${encodeURIComponent(query)}.json?${query}');
module.exports.API_GEOCODER_REVERSE = compile('${endpoint}/v4/geocode/${dataset}/${location.longitude},${location.latitude}.json?${query}');
module.exports.API_DIRECTIONS = compile('${endpoint}/v4/directions/${profile}/${encodedWaypoints}.json?${query}');
module.exports.API_SURFACE = compile('${endpoint}/v4/surface/${mapid}.json?${query}');
module.exports.API_MATCHING = compile('${endpoint}/matching/v4/${profile}.json?${query}');
10 changes: 0 additions & 10 deletions lib/make_query.js

This file was deleted.

29 changes: 29 additions & 0 deletions lib/make_service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict';

var invariant = require('invariant');
var constants = require('./constants');

function makeService(name) {

function service(accessToken, options) {
this.name = name;

invariant(typeof accessToken === 'string',
'accessToken required to instantiate MapboxDirections');

this.accessToken = accessToken;
this.endpoint = constants.DEFAULT_ENDPOINT;

if (options !== undefined) {
invariant(typeof options === 'object', 'options must be an object');
if (options.endpoint) {
invariant(typeof options.endpoint === 'string', 'endpoint must be a string');
this.endpoint = options.endpoint;
}
}
}

return service;
}

module.exports = makeService;
15 changes: 15 additions & 0 deletions lib/make_url.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

var xtend = require('xtend'),
qs = require('querystring'),
resolveToString = require('es6-template-strings/resolve-to-string');

function makeURL(self, template, params, query) {
return resolveToString(template,
xtend(params, {
endpoint: self.endpoint,
query: qs.stringify(xtend(query, { access_token: self.accessToken }))
}));
}

module.exports = makeURL;
14 changes: 5 additions & 9 deletions lib/services/directions.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@

var invariant = require('invariant'),
request = require('superagent'),
resolveToString = require('es6-template-strings/resolve-to-string'),
formatPoints = require('../format_points'),
makeQuery = require('../make_query'),
makeService = require('../make_service'),
makeURL = require('../make_url'),
constants = require('../constants');

function MapboxDirections(accessToken) {
invariant(typeof accessToken === 'string',
'accessToken required to instantiate MapboxDirections');
this.accessToken = accessToken;
}
var MapboxDirections = makeService('MapboxDirections');

/**
* Find directions from A to B, or between any number of locations.
Expand Down Expand Up @@ -102,10 +98,10 @@ MapboxDirections.prototype.getDirections = function(waypoints, options, callback
geometry = options.geometry;
}

var url = resolveToString(constants.API_DIRECTIONS, {
var url = makeURL(this, constants.API_DIRECTIONS, {
encodedWaypoints: encodedWaypoints,
profile: profile
}) + makeQuery(this.accessToken, {
}, {
instructions: instructions,
geometry: geometry,
alternatives: alternatives
Expand Down
18 changes: 7 additions & 11 deletions lib/services/geocoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@

var invariant = require('invariant'),
request = require('superagent'),
resolveToString = require('es6-template-strings/resolve-to-string'),
makeQuery = require('../make_query'),
makeService = require('../make_service'),
makeURL = require('../make_url'),
constants = require('../constants');

function MapboxGeocoder(accessToken) {
invariant(typeof accessToken === 'string',
'accessToken required to instantiate MapboxGeocoder');
this.accessToken = accessToken;
}
var MapboxGeocoder = makeService('MapboxGeocoder');

/**
* Search for a location with a string, using the
Expand Down Expand Up @@ -69,10 +65,10 @@ MapboxGeocoder.prototype.geocodeForward = function(query, options, callback) {
dataset = options.dataset;
}

var url = resolveToString(constants.API_GEOCODER_FORWARD, {
var url = makeURL(this, constants.API_GEOCODER_FORWARD, {
query: query,
dataset: dataset
}) + makeQuery(this.accessToken, queryOptions);
}, queryOptions);

request(url, function(err, res) {
callback(err, res.body);
Expand Down Expand Up @@ -125,10 +121,10 @@ MapboxGeocoder.prototype.geocodeReverse = function(location, options, callback)
dataset = options.dataset;
}

var url = resolveToString(constants.API_GEOCODER_REVERSE, {
var url = makeURL(this, constants.API_GEOCODER_REVERSE, {
location: location,
dataset: dataset
}) + makeQuery(this.accessToken, {});
}, {});

request(url, function(err, res) {
callback(err, res.body);
Expand Down
14 changes: 5 additions & 9 deletions lib/services/matching.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@
var invariant = require('invariant'),
request = require('superagent'),
geojsonhint = require('geojsonhint/object'),
resolveToString = require('es6-template-strings/resolve-to-string'),
makeQuery = require('../make_query'),
makeService = require('../make_service'),
makeURL = require('../make_url'),
constants = require('../constants');

function MapboxMatching(accessToken) {
invariant(typeof accessToken === 'string',
'accessToken required to instantiate MapboxMatching');
this.accessToken = accessToken;
}
var MapboxMatching = makeService('MapboxMatching');

/**
* Snap recorded location traces to roads and paths from OpenStreetMap.
Expand Down Expand Up @@ -104,9 +100,9 @@ MapboxMatching.prototype.matching = function(trace, options, callback) {
geometry = options.geometry;
}

var url = resolveToString(constants.API_MATCHING, {
var url = makeURL(this, constants.API_MATCHING, {
profile: profile
}) + makeQuery(this.accessToken, {
}, {
geometry: geometry,
gps_precision: gps_precision
});
Expand Down
15 changes: 5 additions & 10 deletions lib/services/surface.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,12 @@

var invariant = require('invariant'),
request = require('superagent'),
resolveToString = require('es6-template-strings/resolve-to-string'),
formatPoints = require('../format_points'),
makeQuery = require('../make_query'),
makeService = require('../make_service'),
makeURL = require('../make_url'),
constants = require('../constants');

function MapboxSurface(accessToken) {
invariant(typeof accessToken === 'string',
'accessToken required to instantiate MapboxSurface');
this.accessToken = accessToken;
}

var MapboxSurface = makeService('MapboxSurface');

/**
* Given a list of locations, retrieve vector tiles, find the nearest
Expand Down Expand Up @@ -92,9 +87,9 @@ MapboxSurface.prototype.surface = function(mapid, layer, fields, path, options,
surfaceOptions.z = options.zoom;
}

var url = resolveToString(constants.API_SURFACE, {
var url = makeURL(this, constants.API_SURFACE, {
mapid: mapid
}) + makeQuery(this.accessToken, surfaceOptions);
}, surfaceOptions);

request(url, function(err, res) {
callback(err, res.body);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"homepage": "https://github.com/mapbox/mapbox-sdk-js",
"devDependencies": {
"browserify": "^11.0.0",
"documentation": "^2.1.0-alpha1",
"documentation": "^2.1.0-alpha2",
"eslint": "^0.24.1",
"geojsonhint": "^1.1.0",
"polyline": "^0.1.0",
Expand Down
11 changes: 0 additions & 11 deletions test/make_query.js

This file was deleted.

14 changes: 14 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,17 @@ test('MapboxClient', function(t) {
t.equal(client.accessToken, 'token');
t.end();
});

test('MapboxClient - custom endpoint', function(t) {
t.throws(function() {
var client = new MapboxClient('foo', 1);
t.notOk(client);
}, /options/);
t.throws(function() {
var client = new MapboxClient('foo', { endpoint: 1 });
t.notOk(client);
}, /endpoint/);
var customClient = new MapboxClient('foo', { endpoint: 'foo.bar' });
t.equal(customClient.endpoint, 'foo.bar', 'receives an endpoint from options');
t.end();
});

0 comments on commit 36f91ff

Please sign in to comment.