/
geocoder.js
135 lines (118 loc) · 4.92 KB
/
geocoder.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
'use strict';
var invariant = require('invariant'),
request = require('superagent'),
makeService = require('../make_service'),
makeURL = require('../make_url'),
constants = require('../constants'),
formatError = require('../format_error');
var MapboxGeocoder = makeService('MapboxGeocoder');
/**
* Search for a location with a string, using the
* [Mapbox Geocoding API](https://www.mapbox.com/developers/api/geocoding/).
*
* @param {string} query desired location
* @param {Object} [options={}] additional options meant to tune
* the request
* @param {Object} options.proximity 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.
* @param {string} [options.dataset=mapbox.places] 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.
* @param {Function} callback called with (err, results)
* @returns {undefined} nothing, calls callback
* @memberof MapboxClient
* @example
* var mapboxClient = new MapboxClient('ACCESSTOKEN');
* mapboxClient.geocodeForward('Paris, France', function(err, res) {
* // res is a GeoJSON document with geocoding matches
* });
* // using the proximity option to weight results closer to texas
* mapboxClient.geocodeForward('Paris, France', {
* proximity: { latitude: 33.6875431, longitude: -95.4431142 }
* }, function(err, res) {
* // res is a GeoJSON document with geocoding matches
* });
*/
MapboxGeocoder.prototype.geocodeForward = function(query, options, callback) {
// permit the options argument to be omitted
if (callback === undefined && typeof options === 'function') {
callback = options;
options = {};
}
// typecheck arguments
invariant(typeof query === 'string', 'query must be a string');
invariant(typeof options === 'object', 'options must be an object');
invariant(typeof callback === 'function', 'callback must be a function');
var queryOptions = {};
if (options.proximity) {
invariant(typeof options.proximity.latitude === 'number' &&
typeof options.proximity.longitude === 'number',
'proximity must be an object with numeric latitude & longitude properties');
queryOptions.proximity = options.proximity.longitude + ',' + options.proximity.latitude;
}
var dataset = 'mapbox.places';
if (options.dataset) {
invariant(typeof options.dataset === 'string', 'dataset option must be string');
dataset = options.dataset;
}
var url = makeURL(this, constants.API_GEOCODER_FORWARD, {
forwardQuery: query,
dataset: dataset
}, queryOptions);
request(url, function(err, res) {
callback(formatError(err), res.body);
});
};
/**
* Given a location, determine what geographical features are located
* there. This uses the [Mapbox Geocoding API](https://www.mapbox.com/developers/api/geocoding/).
*
* @param {Object} location the geographical point to search
* @param {number} location.latitude decimal degrees latitude, in range -90 to 90
* @param {number} location.longitude decimal degrees longitude, in range -180 to 180
* @param {Object} [options={}] additional options meant to tune
* the request
* @param {string} [options.dataset=mapbox.places] 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.
* @param {Function} callback called with (err, results)
* @returns {undefined} nothing, calls callback
* @example
* var mapboxClient = new MapboxGeocoder('ACCESSTOKEN');
* mapboxClient.geocodeReverse(
* { latitude: 33.6875431, longitude: -95.4431142 },
* function(err, res) {
* // res is a GeoJSON document with geocoding matches
* });
*/
MapboxGeocoder.prototype.geocodeReverse = function(location, options, callback) {
// permit the options argument to be omitted
if (callback === undefined && typeof options === 'function') {
callback = options;
options = {};
}
// typecheck arguments
invariant(typeof location === 'object', 'location must be an object');
invariant(typeof options === 'object', 'options must be an object');
invariant(typeof callback === 'function', 'callback must be a function');
invariant(typeof location.latitude === 'number' &&
typeof location.longitude === 'number',
'location must be an object with numeric latitude & longitude properties');
var dataset = 'mapbox.places';
if (options.dataset) {
invariant(typeof options.dataset === 'string', 'dataset option must be string');
dataset = options.dataset;
}
var url = makeURL(this, constants.API_GEOCODER_REVERSE, {
location: location,
dataset: dataset
}, {});
request(url, function(err, res) {
callback(formatError(err), res.body);
});
};
module.exports = MapboxGeocoder;