diff --git a/source/mxn.geocoder.js b/source/mxn.geocoder.js index 91373b5..1cec9b0 100644 --- a/source/mxn.geocoder.js +++ b/source/mxn.geocoder.js @@ -6,7 +6,7 @@ * @private */ var init = function() { - this.invoker.go('init'); + this.invoker.go('init'); }; /** @@ -16,30 +16,32 @@ var init = function() { * @param {String} api The API to use, currently only 'mapquest' is supported * @param {Function} callback The function to call when a geocode request returns (function(waypoint)) * @param {Function} error_callback The optional function to call when a geocode request fails + * @param {String} key Optional api auth key. Currently only used for Microsoft v7. * @exports Geocoder as mxn.Geocoder */ -var Geocoder = mxn.Geocoder = function (api, callback, error_callback) { - this.api = api; - this.geocoders = {}; - this.callback = callback; - this.error_callback = error_callback || function(){}; - - // set up our invoker for calling API methods - this.invoker = new mxn.Invoker(this, 'Geocoder', function(){ return this.api; }); - init.apply(this); +var Geocoder = mxn.Geocoder = function (api, callback, error_callback, key) { + this.api = api; + this.geocoders = {}; + this.callback = callback; + this.error_callback = error_callback || function(){}; + this.key = (typeof(key) == 'string') ? key : false + + // set up our invoker for calling API methods + this.invoker = new mxn.Invoker(this, 'Geocoder', function(){ return this.api; }); + init.apply(this); }; mxn.addProxyMethods(Geocoder, [ - - /** - * Geocodes the provided address. - * @name mxn.Geocoder#geocode - * @function - * @param {Object} address Address hash, keys are: street, locality, region, country. - */ - 'geocode', - - 'geocode_callback' + + /** + * Geocodes the provided address. + * @name mxn.Geocoder#geocode + * @function + * @param {Object} address Address hash (street, locality, region, country), literal address as String, or LatLanPoint object + */ + 'geocode', + + 'geocode_callback' ]); @@ -49,12 +51,12 @@ mxn.addProxyMethods(Geocoder, [ * @param {String} api The API to swap to */ Geocoder.prototype.swap = function(api) { - if (this.api == api) { return; } + if (this.api == api) { return; } - this.api = api; - if (!this.geocoders.hasOwnProperty(this.api)) { - init.apply(this); - } + this.api = api; + if (!this.geocoders.hasOwnProperty(this.api)) { + init.apply(this); + } }; })(); \ No newline at end of file diff --git a/source/mxn.googlev3.geocoder.js b/source/mxn.googlev3.geocoder.js index 66d3e25..10cbf03 100644 --- a/source/mxn.googlev3.geocoder.js +++ b/source/mxn.googlev3.geocoder.js @@ -1,84 +1,87 @@ -mxn.register('googlev3', { +mxn.register('googlev3', { Geocoder: { - - init: function() { - this.geocoders[this.api] = new google.maps.Geocoder(); - }, - - geocode: function(address){ - var me = this; - - if (!address.hasOwnProperty('address') || address.address === null || address.address === '') { - address.address = [ address.street, address.locality, address.region, address.country ].join(', '); - } - - if (address.hasOwnProperty('lat') && address.hasOwnProperty('lon')) { - var latlon = address.toProprietary(this.api); - this.geocoders[this.api].geocode({'latLng': latlon }, function(results, status) { - me.geocode_callback(results, status); - }); - } else { - this.geocoders[this.api].geocode({'address': address.address }, function(results, status) { - me.geocode_callback(results, status); - }); - } - }, - - geocode_callback: function(results, status){ - var return_location = {}; + + init: function() { + this.geocoders[this.api] = new google.maps.Geocoder(); + }, + + geocode: function(query){ + var me = this; + var geocode_request_object = {}; + if(typeof(query) == 'object'){ + // query is a LatLonPoint object (reverse geocode) + if (query.hasOwnProperty('lat') && query.hasOwnProperty('lon')) { + geocode_request_object.latLng = query.toProprietary(this.api); + } + // query is an address object + else{ + geocode_request_object.address = [ query.street, query.locality, query.region, query.country ].join(', '); + } + } + // query is an address string + else{ + geocode_request_object.address = query; + } + this.geocoders[this.api].geocode(geocode_request_object, function(results, status) { + me.geocode_callback(results, status); + }); + }, - if (status != google.maps.GeocoderStatus.OK) { - this.error_callback(status); - } - else { - return_location.street = ''; - return_location.locality = ''; - return_location.postcode = ''; - return_location.region = ''; - return_location.country = ''; + geocode_callback: function(results, status){ + var return_location = {}; - var place = results[0]; - var streetparts = []; - - for (var i = 0; i < place.address_components.length; i++) { - var addressComponent = place.address_components[i]; - for (var j = 0; j < addressComponent.types.length; j++) { - var componentType = addressComponent.types[j]; - switch (componentType) { - case 'country': - return_location.country = addressComponent.long_name; - break; - case 'administrative_area_level_1': - return_location.region = addressComponent.long_name; - break; - case 'locality': - return_location.locality = addressComponent.long_name; - break; - case 'street_address': - return_location.street = addressComponent.long_name; - break; - case 'postal_code': - return_location.postcode = addressComponent.long_name; - break; - case 'street_number': - streetparts.unshift(addressComponent.long_name); - break; - case 'route': - streetparts.push(addressComponent.long_name); - break; - } - } - } - - if (return_location.street === '' && streetparts.length > 0) { - return_location.street = streetparts.join(' '); - } - - return_location.point = new mxn.LatLonPoint(place.geometry.location.lat(), place.geometry.location.lng()); - - this.callback(return_location); - } - } + if (status != google.maps.GeocoderStatus.OK) { + this.error_callback(status); + } + else { + return_location.street = ''; + return_location.locality = ''; + return_location.postcode = ''; + return_location.region = ''; + return_location.country = ''; + + var place = results[0]; + var streetparts = []; + + for (var i = 0; i < place.address_components.length; i++) { + var addressComponent = place.address_components[i]; + for (var j = 0; j < addressComponent.types.length; j++) { + var componentType = addressComponent.types[j]; + switch (componentType) { + case 'country': + return_location.country = addressComponent.long_name; + break; + case 'administrative_area_level_1': + return_location.region = addressComponent.long_name; + break; + case 'locality': + return_location.locality = addressComponent.long_name; + break; + case 'street_address': + return_location.street = addressComponent.long_name; + break; + case 'postal_code': + return_location.postcode = addressComponent.long_name; + break; + case 'street_number': + streetparts.unshift(addressComponent.long_name); + break; + case 'route': + streetparts.push(addressComponent.long_name); + break; + } + } + } + + if (return_location.street === '' && streetparts.length > 0) { + return_location.street = streetparts.join(' '); + } + + return_location.point = new mxn.LatLonPoint(place.geometry.location.lat(), place.geometry.location.lng()); + + this.callback(return_location); + } + } } }); \ No newline at end of file diff --git a/source/mxn.microsoft7.geocoder.js b/source/mxn.microsoft7.geocoder.js new file mode 100644 index 0000000..02f09fd --- /dev/null +++ b/source/mxn.microsoft7.geocoder.js @@ -0,0 +1,52 @@ +mxn.register('microsoft7', { + Geocoder: { + + init: function(){ + + }, + + geocode: function(query){ + var self = this; + var _address = ''; + var is_reverse = false; + if(typeof(query) == 'object'){ + // query is a LatLonPoint object (reverse geocode) + if (query.hasOwnProperty('lat') && query.hasOwnProperty('lon')) { + _address = query.lat + ',' + query.lon; + } + // query is an address object + else{ + _address = [ query.street, query.locality, query.region, query.country ].join(', '); + } + } + // query is an address string + else{ + _address = query; + } + jsonp_callback_context = this; + var searchRequest = 'http://dev.virtualearth.net/REST/v1/Locations/' + _address + '?output=json&jsonp=jsonp_callback_context.geocode_callback&key=' + this.key; + var mapscript = document.createElement('script'); + mapscript.type = 'text/javascript'; + mapscript.src = searchRequest; + document.body.appendChild(mapscript); + }, + + geocode_callback: function(results){ + if(results.statusDescription != 'OK'){ + this.error_callback(results.statusDescription); + } + else{ + var topResult = results.resourceSets[0].resources[0]; + var return_location = { + street: topResult.address.addressLine, + locality: topResult.address.locality, + postcode: topResult.address.postalCode, + region: topResult.address.adminDistrict, + country: topResult.address.countryRegion, + point: new mxn.LatLonPoint(topResult.point.coordinates[0], topResult.point.coordinates[1]) + }; + this.callback(return_location); + } + } + } +}); \ No newline at end of file