Source: open-layers/ol-geocoder.js

/**

 * @namespace WPGMZA

 * @module OLGeocoder

 * @requires WPGMZA.Geocoder

 */

(function($) {

	

	/**

	 * @class OLGeocoder

	 * @extends Geocoder

	 * @summary OpenLayers geocoder - uses Nominatim by default

	 */

	WPGMZA.OLGeocoder = function()

	{

		

	}

	

	WPGMZA.OLGeocoder.prototype = Object.create(WPGMZA.Geocoder.prototype);

	WPGMZA.OLGeocoder.prototype.constructor = WPGMZA.OLGeocoder;

	

	/**

	 * @function getResponseFromCache

	 * @access protected

	 * @summary Tries to retrieve cached coordinates from server cache

	 * @param {string} address The street address to geocode

	 * @param {function} callback Where to send the results, as an array

	 * @return {void}

	 */

	WPGMZA.OLGeocoder.prototype.getResponseFromCache = function(address, callback)

	{

		$.ajax(WPGMZA.ajaxurl, {

			data: {

				action: "wpgmza_query_nominatim_cache",

				query: address

			},

			success: function(response, xhr, status) {

				callback(response);

			}

		});

	}

	

	/**

	 * @function getResponseFromNominatim

	 * @access protected

	 * @summary Queries Nominatim on the specified address

	 * @param {object} options An object containing the options for geocoding, address is a mandatory field

	 * @param {function} callback The function to send the results to, as an array

	 */

	WPGMZA.OLGeocoder.prototype.getResponseFromNominatim = function(options, callback)

	{

		var data = {

			q: options.address,

			format: "json"

		};

		

		if(options.country)

			data.countrycodes = options.country;

		

		$.ajax("https://nominatim.openstreetmap.org/search/", {

			data: data,

			success: function(response, xhr, status) {

				callback(response);

			},

			error: function(response, xhr, status) {

				callback(null, WPGMZA.Geocoder.FAIL)

			}

		});

	}

	

	/**

	 * @function cacheResponse

	 * @access protected

	 * @summary Caches a response on the server, usually after it's been returned from Nominatim

	 * @param {string} address The street address

	 * @param {object|array} response The response to cache

	 * @returns {void}

	 */

	WPGMZA.OLGeocoder.prototype.cacheResponse = function(address, response)

	{

		$.ajax(WPGMZA.ajaxurl, {

			data: {

				action: "wpgmza_store_nominatim_cache",

				query: address,

				response: JSON.stringify(response)

			},

			method: "POST"

		});

	}

	

	/**

	 * @function getLatLngFromAddress

	 * @access public

	 * @summary Attempts to geocode an address, firstly by checking the cache for previous

	 * results, if this fails the Nominatim server will be queried, cached and sent to the

	 * specified callback

	 * @param {object} options An object containing the options for geocoding, address is a mandatory field

	 * @param {function} callback The function to send the results to, as an array

	 * @returns {void}

	 */

	WPGMZA.OLGeocoder.prototype.getLatLngFromAddress = function(options, callback)

	{

		var self = this;

		var address = options.address;

		

		var latLng;

		if(latLng = WPGMZA.isLatLngString(address))

			return WPGMZA.Geocoder.prototype.getLatLngFromAddress.call(this, options, callback);

		

		function finish(response, status)

		{

			for(var i = 0; i < response.length; i++)

			{

				response[i].geometry = {

					location: new WPGMZA.LatLng({

						lat: parseFloat(response[i].lat),

						lng: parseFloat(response[i].lon)

					})

				};

				

				response[i].lat = parseFloat(response[i].lat);

				response[i].lng = parseFloat(response[i].lon);

			}

			

			callback(response, status);

		}

		

		this.getResponseFromCache(address, function(response) {

			if(response.length)

			{

				finish(response, WPGMZA.Geocoder.SUCCESS);

				return;

			}

			

			self.getResponseFromNominatim(options, function(response, status) {

				if(status == WPGMZA.Geocoder.FAIL)

				{

					callback(null, WPGMZA.Geocoder.FAIL);

					return;

				}

				

				if(response.length == 0)

				{

					callback(response, WPGMZA.Geocoder.ZERO_RESULTS);

					return;

				}

				

				finish(response, WPGMZA.Geocoder.SUCCESS);

				

				self.cacheResponse(address, response);

			});

		});

	}

	

})(jQuery);