UNPKG

geocoder

Version:

node wrapper around google's geocoder api

157 lines (130 loc) 4.44 kB
// xml2js is optional because only needed for geonames support var xml2js = require("xml2js"); var request = require("request"); var _ = require('underscore'); exports.geocode = function ( providerOpts, loc, cbk, opts ) { var options = _.extend({q: loc, flags: "J", appid:providerOpts.appid||"[yourappidhere]" }, opts || {}); request({ uri:"http://where.yahooapis.com/geocode", qs:options }, function(err,resp,body) { if (err) return cbk(err); var result; try { result = JSON.parse(body); } catch (err) { cbk(err); return; } cbk(null,result); }); }; // yahoo placefinder api http://developer.yahoo.com/geo/placefinder/guide/ exports.reverseGeocode = function ( providerOpts, lat, lng, cbk, opts ) { var options = _.extend({q: lat+", "+lng, gflags:"R", flags: "J", appid:providerOpts.appid||"[yourappidhere]" }, opts || {}); request({ uri:"http://where.yahooapis.com/geocode", qs:options }, function(err,resp,body) { // console.log("[GEOCODER Yahoo API] uri:", "http://where.yahooapis.com/geocode"); // console.log("[GEOCODER Yahoo API] options:", JSON.stringify(options)); // console.log("[GEOCODER Yahoo API] body:", body); if (err) return cbk(err); var result; try { result = JSON.parse(body); } catch (err) { cbk(err); return; } // Transform yahoo' structure into something that looks like Google's JSON outpu // https://developers.google.com/maps/documentation/geocoding/#JSON var googlejson = { "status":"OK", "results":[ { "address_components":[], "formatted_address":"", "geometry":{ "location":{ "lat":lat, "lng":lng } } } ] }; if (result.ResultSet.Error !== "0" && result.ResultSet.Error !== 0) { console.log("[GEOCODER Yahoo API] ERROR", result.Error, result.ErrorMessage); return cbk(result.ResultSet.ErrorMessage); } var a = null; // Yahoo seems to change its response format "randomly". So, sometimes, it there is only one result, // it will be in ResultSet.Result, and sometimes, in ResultSet.Results[0] if (undefined !== result.ResultSet.Result) { a = result.ResultSet.Result; } else if (result.ResultSet.Results && result.ResultSet.Results.length) { a = result.ResultSet.Results[0]; } if (!a) { return cbk("Error getting results from Yahoo API"); } if (a.house) googlejson.results[0].address_components.push({ "long_name":a.house, "short_name":a.house, "types":["street_number"] }); if (a.street) googlejson.results[0].address_components.push({ "long_name":a.street, "short_name":a.street, "types":["route"] }); if (a.city) googlejson.results[0].address_components.push({ "long_name":a.city, "short_name":a.city, "types":["locality", "political"] }); if (a.state) googlejson.results[0].address_components.push({ "long_name":a.state, "short_name":a.statecode || a.state, "types":[ "administrative_area_level_1", "political" ] }); if (a.county) googlejson.results[0].address_components.push({ "long_name":a.county, "short_name":a.countycode || a.county, "types":[ "administrative_area_level_2", "political" ] }); if (a.country) googlejson.results[0].address_components.push({ "long_name":a.country, "short_name":a.countrycode, "types":[ "country" ] }); if (a.postal) googlejson.results[0].address_components.push({ "long_name":a.postal, "short_name":a.postal, "types":[ "postal_code" ] }); if (a.latitude) googlejson.results[0].geometry.location = { "lat":parseFloat(a.latitude), "lng":parseFloat(a.longitude) }; // Make a formatted address as well as we can var formatted = []; if (a.line1) formatted.push(a.line1); if (a.line2) formatted.push(a.line2); if (a.line3) formatted.push(a.line3); if (a.line4) formatted.push(a.line4); googlejson.results[0].formatted_address = formatted.join(", "); // console.log("[GEOCODER Yahoo API], calling callback w/", JSON.stringify(googlejson)); cbk(null, googlejson); }); };