node-geocoder
Version:
Node Geocoder, node geocoding library, supports google maps, mapquest, open street map, tom tom, promise
169 lines (139 loc) • 4.99 kB
JavaScript
var util = require('util'),
AbstractGeocoder = require('./abstractgeocoder');
/**
* Constructor
*/
var OpenStreetMapGeocoder = function OpenStreetMapGeocoder(httpAdapter, options) {
this.options = ['language','email','apiKey', 'osmServer'];
OpenStreetMapGeocoder.super_.call(this, httpAdapter, options);
var osmServer = (options && options.osmServer) || 'http://nominatim.openstreetmap.org';
OpenStreetMapGeocoder.prototype._endpoint = osmServer + '/search';
OpenStreetMapGeocoder.prototype._endpoint_reverse = osmServer + '/reverse';
};
util.inherits(OpenStreetMapGeocoder, AbstractGeocoder);
OpenStreetMapGeocoder.prototype._endpoint = 'https://nominatim.openstreetmap.org/search';
OpenStreetMapGeocoder.prototype._endpoint_reverse = 'https://nominatim.openstreetmap.org/reverse';
/**
* Geocode
* @param <string|object> value Value to geocode (Address or parameters, as specified at https://wiki.openstreetmap.org/wiki/Nominatim#Parameters)
* @param <function> callback Callback method
*/
OpenStreetMapGeocoder.prototype._geocode = function(value, callback) {
var _this = this;
var params = this._getCommonParams();
params.addressdetails = 1;
if (typeof value == 'string') {
params.q = value;
} else {
for (var k in value) {
var v = value[k];
params[k] = v;
}
}
this._forceParams(params);
this.httpAdapter.get(this._endpoint , params, function(err, result) {
if (err) {
return callback(err);
} else {
var results = [];
if(result.error) {
return callback(new Error(result.error));
}
if (result instanceof Array) {
for (var i = 0; i < result.length; i++) {
results.push(_this._formatResult(result[i]));
}
} else {
results.push(_this._formatResult(result));
}
results.raw = result;
callback(false, results);
}
});
};
OpenStreetMapGeocoder.prototype._formatResult = function(result) {
var countryCode, latitude, longitude, formattedAddress, country, city, state, zipcode, streetName, streetNumber, neighbourhood;
if (result.address) {
countryCode = result.address.country_code ? result.address.country_code.toUpperCase() : undefined;
country = result.address.country;
city = result.address.city || result.address.town || result.address.village || result.address.hamlet;
state = result.address.state;
zipcode = result.address.postcode;
streetName = result.address.road || result.address.cycleway;
streetNumber = result.address.house_number;
neighbourhood = result.address.neighbourhood || '';
}
latitude = result.lat ? parseFloat(result.lat) : undefined;
longitude = result.lon ? parseFloat(result.lon) : undefined;
formattedAddress = result.display_name;
return {
'latitude': latitude,
'longitude': longitude,
'formattedAddress': formattedAddress,
'country': country,
'city': city,
'state': state,
'zipcode': zipcode,
'streetName': streetName,
'streetNumber': streetNumber,
'countryCode': countryCode,
'neighbourhood': neighbourhood
};
};
/**
* Reverse geocoding
* @param {lat:<number>,lon:<number>, ...} lat: Latitude, lon: Longitude, ... see https://wiki.openstreetmap.org/wiki/Nominatim#Parameters_2
* @param <function> callback Callback method
*/
OpenStreetMapGeocoder.prototype._reverse = function(query, callback) {
var _this = this;
var params = this._getCommonParams();
for (var k in query) {
var v = query[k];
params[k] = v;
}
this._forceParams(params);
this.httpAdapter.get(this._endpoint_reverse , params, function(err, result) {
if (err) {
return callback(err);
} else {
if(result.error) {
return callback(new Error(result.error));
}
var results = [];
if (result instanceof Array) {
for (var i = 0; i < result.length; i++) {
results.push(_this._formatResult(result[i]));
}
} else {
results.push(_this._formatResult(result));
}
results.raw = result;
callback(false, results);
}
});
};
/**
* Prepare common params
*
* @return <Object> common params
*/
OpenStreetMapGeocoder.prototype._getCommonParams = function(){
var params = {};
for (var k in this.options) {
var v = this.options[k];
if (!v) {
continue;
}
if (k === 'language') {
k = 'accept-language';
}
params[k] = v;
}
return params;
};
OpenStreetMapGeocoder.prototype._forceParams = function(params){
params.format = 'json';
params.addressdetails = 1;
};
module.exports = OpenStreetMapGeocoder;