Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion API.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ The Directions control
- `options.congestion` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Whether to enable congestion along the route line. (optional, default `false`)
- `options.unit` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Measurement system to be used in navigation instructions. Options: `imperial`, `metric` (optional, default `"imperial"`)
- `options.compile` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** Provide a custom function for generating instruction, compatible with osrm-text-instructions. (optional, default `null`)
- `options.geocoder` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** Accepts an object containing the query parameters as [documented here](https://www.mapbox.com/api-documentation/#search-for-places).
- `options.geocoder` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** Accepts an object containing the query parameters as [documented here](https://docs.mapbox.com/api/search/#forward-geocoding) in addition to the following:
- `options.geocoder.localGeocoder` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function accepting the query string which performs local geocoding to supplement results from the Mapbox Geocoding API. Expected to return an Array of GeoJSON Features in the [Carmen GeoJSON](https://github.com/mapbox/carmen/blob/master/carmen-geojson.md) format.
- `options.controls` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?**
- `options.controls.inputs` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Hide or display the inputs control. (optional, default `true`)
- `options.controls.instructions` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Hide or display the instructions control. (optional, default `true`)
Expand Down
44 changes: 43 additions & 1 deletion example/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,53 @@ removeWaypointsButton.style = 'z-index:10;position:absolute;top:30px;right:10px;
removeWaypointsButton.textContent = 'Remove all waypoints';

// directions
var coordinatesGeocoder = function (query) {
var matches = query.match(/^[ ]*(-?\d+\.?\d*)[, ]+(-?\d+\.?\d*)[ ]*$/);
if (!matches) {
return null;
}
function coordinateFeature(lng, lat) {
var lng = Number(lng);
var lat = Number(lat);
return {
center: [lng, lat],
geometry: {
type: "Point",
coordinates: [lng, lat]
},
place_name: 'Lat: ' + lat + ', Lng: ' + lng,
place_type: ['coordinate'],
properties: {},
type: 'Feature'
};
}
var coord1 = matches[1];
var coord2 = matches[2];
var geocodes = [];
if (coord1 < -90 || coord1 > 90) {
// must be lng, lat
geocodes.push(coordinateFeature(coord1, coord2));
}
if (coord2 < -90 || coord2 > 90) {
// must be lat, lng
geocodes.push(coordinateFeature(coord2, coord1));
}
if (geocodes.length == 0) {
// else could be either
geocodes.push(coordinateFeature(coord1, coord2));
geocodes.push(coordinateFeature(coord2, coord1));
}
console.log(geocodes);
return geocodes;
};
var MapboxDirections = require('../src/index');
var directions = new MapboxDirections({
accessToken: window.localStorage.getItem('MapboxAccessToken'),
unit: 'metric',
profile: 'mapbox/cycling'
profile: 'mapbox/cycling',
geocoder: {
localGeocoder: coordinatesGeocoder
}
});
window.directions = directions;

Expand Down
47 changes: 46 additions & 1 deletion src/controls/geocoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,16 @@ export default class Geocoder {
this._loadingEl.classList.add('active');
this.fire('loading');

var localGeocoderRes = [];
if (this.options.localGeocoder) {
localGeocoderRes = this.options.localGeocoder(q);
if (!localGeocoderRes) {
localGeocoderRes = [];
}
}

const geocodingOptions = this.options
const exclude = ['placeholder', 'zoom', 'flyTo', 'accessToken', 'api'];
const exclude = ['placeholder', 'zoom', 'flyTo', 'accessToken', 'api', 'localGeocoder'];
const options = Object.keys(this.options).filter(function(key) {
return exclude.indexOf(key) === -1;
}).map(function(key) {
Expand All @@ -108,6 +116,10 @@ export default class Geocoder {
this._loadingEl.classList.remove('active');
if (this.request.status >= 200 && this.request.status < 400) {
var data = JSON.parse(this.request.responseText);

// supplement Mapbox Geocoding API results with locally populated results
data.features = data.features ? localGeocoderRes.concat(data.features) : localGeocoderRes;

if (data.features.length) {
this._clearEl.classList.add('active');
} else {
Expand All @@ -119,13 +131,40 @@ export default class Geocoder {
this._typeahead.update(data.features);
return callback(data.features);
} else {
// in the event of an error in the Mapbox Geocoding API still display results from the localGeocoder
if (localGeocoderRes.length) {
this._clearEl.classList.add('active');
} else {
this._clearEl.classList.remove('active');
this._typeahead.selected = null;
}

this.fire('results', { results: localGeocoderRes });
this._typeahead.update(localGeocoderRes);

this.fire('error', { error: JSON.parse(this.request.responseText).message });

return callback(localGeocoderRes);
}
}.bind(this);

this.request.onerror = function() {
this._loadingEl.classList.remove('active');

// in the event of an error in the Mapbox Geocoding API still display results from the localGeocoder
if (localGeocoderRes.length) {
this._clearEl.classList.add('active');
} else {
this._clearEl.classList.remove('active');
this._typeahead.selected = null;
}

this.fire('results', { results: localGeocoderRes });
this._typeahead.update(localGeocoderRes);

this.fire('error', { error: JSON.parse(this.request.responseText).message });

return callback(localGeocoderRes);
}.bind(this);

this.request.send();
Expand Down Expand Up @@ -237,6 +276,12 @@ export default class Geocoder {
});
return this;
}

once(type, fn) {
this._ev.once(type, fn);
return this;
}

/**
* Fire an event
* @param {String} type event name.
Expand Down
3 changes: 2 additions & 1 deletion src/directions.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ import Instructions from './controls/instructions';
* @param {Boolean} [options.congestion=false] Whether to enable congestion along the route line.
* @param {String} [options.unit="imperial"] Measurement system to be used in navigation instructions. Options: `imperial`, `metric`
* @param {Function} [options.compile=null] Provide a custom function for generating instruction, compatible with osrm-text-instructions.
* @param {Object} [options.geocoder] Accepts an object containing the query parameters as [documented here](https://www.mapbox.com/api-documentation/#search-for-places).
* @param {Object} [options.geocoder] Accepts an object containing the query parameters as [documented here](https://docs.mapbox.com/api/search/#forward-geocoding).
* @param {Function} [options.gocoder.localGeocoder] A function accepting the query string which performs local geocoding to supplement results from the Mapbox Geocoding API. Expected to return an Array of GeoJSON Features in the [Carmen GeoJSON](https://github.com/mapbox/carmen/blob/master/carmen-geojson.md) format.
* @param {Object} [options.controls]
* @param {Boolean} [options.controls.inputs=true] Hide or display the inputs control.
* @param {Boolean} [options.controls.instructions=true] Hide or display the instructions control.
Expand Down
39 changes: 39 additions & 0 deletions test/test.geocoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,45 @@ test('Geocoder#constructor', t =>{
t.end();
});

t.test('options.localGeocoder', function(t) {
//t.plan(3);
const geocoder = new Geocoder({
flyTo: false,
limit: 6,
localGeocoder: function(q) {
return [{place_name: q}];
}
});

geocoder.onAdd();
new Promise((resolve, reject) => {
geocoder.query('-30,150');
geocoder.once('results', function(e) {
t.equal(e.results.length, 1, 'Local geocoder used');
resolve();
});
geocoder.once('error', function(e) {});
}).then(function(result) {
return new Promise((resolve, reject) => {
geocoder.query('London');
geocoder.once('results', function(e) {
t.equal(e.results.length, 7, 'Local geocoder supplement remote response');
resolve();
});
});
}).then(function(result) {
return new Promise((resolve, reject) => {
geocoder.query('London');
geocoder.once('results', function(e) {
t.equal(e.results[0].place_name, 'London', 'Local geocoder results above remote response');
resolve();
});
});
}).then(function(result) {
t.end();
});
});

// TODO test to confirm the query parameters actually get passed.
/*
t.test('query parameters passed are added to the request', t =>{
Expand Down