Source: services/geocode.js

    /**
     * @ngdoc service
     * @name Geocode
     * @module s4c.services.Geocode
     * 
     * @description  Componente para acesso a api do backend e/ou comunicação entre controllers
     * 
     *
     */
     
(function () {
    'use strict';

    angular.module('s4c.services.geocoding', [])
        .factory('Geocode', Geocode);

    Geocode.inject = ['$http', '$q', '$interpolate'];

   /**	
	* @method Geocode
	* @param {*} $http
	* @param {*} $q
	* @param {*} $interpolate
	*/
    function Geocode($http, $q, $interpolate) {
        var service = {
            obterEndereco: obterEndereco,
            obterCoordenadas: obterCoordenadas
        };

  		/**	
		* @method _obterEnderecoPorExtenso
		* @param {*} endereco
		*/
        function _obterEnderecoPorExtenso(endereco) {
            var expressao = '{{rua}}, {{bairro}}, {{cidade}}, {{estado}}'
            var map = {
                rua: endereco.road,
                bairro: endereco.suburb,
                cidade: endereco.city,
                estado: endereco.state
            };
            return $interpolate(expressao)(map);
        }

  		/**	
		* @method obterEndereco
		* @param {*} coordenada
		*/
        function obterEndereco(coordenada) {
            var deferred = $q.defer();

            $http({
                method: 'GET',
                url: '/externalServiceCaller',
                params: {
                    url: "http://nominatim.openstreetmap.org/reverse?format=json"
                        +
                        '&lat=' + coordenada.latitude +
                        '&lon=' + coordenada.longitude
                }
            }).then(function (result) {
                var endereco = result.data.address;

                if (endereco) {
                    deferred.resolve({
                        rua: endereco.road,
                        numero: endereco.house_number,
                        barrio: endereco.suburb,
                        cidade: endereco.city,
                        estado: endereco.state,
                        cep: endereco.postcode,
                        pais: endereco.country,
                        valor: _obterEnderecoPorExtenso(endereco)
                    });
                } else {
                    deferred.reject({
                        mensagem: 'não foram encontrados endereços para esta coordenada',
                        detalhes: {}
                    })
                }
            }, function (result) {
                deferred.reject({
                    mensagem: 'Ocorreu um erro ao tentar obter o endereço da coordenada fornecida.',
                    detalhes: result.data
                });
            });

            return deferred.promise;
        }

  		/**	
		* @method obterCoordenadas
		* @param {*} endereco
		*/
        function obterCoordenadas(endereco) {
            var deferred = $q.defer();

            $http({
                method: 'GET',
                url: '/externalServiceCaller',
                params: { url: "http://nominatim.openstreetmap.org/search?format=json&q=" + endereco }
            }).then(function (result) {

                if (result.data.length) {
                    deferred.resolve(_.map(result.data, function (coordenada) {
                        return {
                            latitude: coordenada.lat,
                            longitude: coordenada.lon
                        }
                    }));
                } else {
                    deferred.reject({
                        mensagem: 'não foram encontradas coordenadas para este endereço',
                        detalhes: {}
                    })
                }

            }, function (result) {
                deferred.reject({
                    mensagem: 'Ocorreu um erro ao tentar obter a coordenada do endereço fornecido',
                    detalhes: result.data
                });
            });

            return deferred.promise
        }

        return service;
    }
}());