UNPKG

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
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;