Source: directives/mapa-endereco/mapa-endereco.service.js

/**
 * @ngdoc directives
 * @name MapaEnderecoService
 * @module s4c.directives.mapa.MapaEnderecoService
 *
 * @description
 * `MapaEnderecoServico` Componente para acesso ao api do backend e/ou comunicação entre controllers
 * 
 * 
 */
(function () {
    angular.module('s4c.directives.MapaEndereco')
        .factory('MapaEndereco', MapaEndereco);

    MapaEndereco.$inject = ['Geocode', 'LocationService'];

    function MapaEndereco(Geocode, LocationService) {
        var service = {
            _eventos: {
                atualizarCoordenadas: []
            },
            _triggers: {
                atualizarCoordenadas: _triggerAtualizarCoordenadas
            },
            trigger: trigger,
            on: on,
            _marker: null,
            endereco: '',
            longitude: -43.48789,
            latitude: -22.94249,
            atualizarEndereco: atualizarEndereco,
            atualizarCoordenadas: atualizarCoordenadas,
            limparEventos: limparEventos
        };

      /**
         * Limpa os eventos
         * 
         * @method limparEventos
         * 
         */         
        function limparEventos() {
            service._eventos = {
                atualizarCoordenadas: []
            };
        }

      /**
         * Chama a função de atualizar coordenadas
         * 
         * @method _triggerAtualizarCoordenadas
         * 
         */           
        function _triggerAtualizarCoordenadas() {
            _.each(service._eventos.atualizarCoordenadas, function (callback) {
                callback({
                    latitude: service.latitude,
                    longitude: service.longitude,
                    endereco: service.endereco
                })
            })
        }

      /**
         * Atualiza a localização dos markers no mapa com as novas coordenadas
         * 
         * @method _atualizarCoordenadasMarker
         * 
         */           
        function _atualizarCoordenadasMarker() {

            if (service.latitude && service.longitude) {
                service._marker.setLatLng({
                    lat: service.latitude,
                    lng: service.longitude
                });
            } else {
                service._marker.setLatLng({
                    lat: -22.94249,
                    lng: -43.48789
                });
            }

            var zoom = service._marker._map.getZoom();

            service._marker._map.setView(service._marker.getLatLng(), zoom, {
                animation: true
            });

            service.trigger('atualizarCoordenadas');
        }

      /**
         * Atualiza o endereço referente as novas coordenadas
         * 
         * @method atualizarEndereco
         * 
         * @param endereco {Object}
         */          
        function atualizarEndereco(endereco) {
            service.endereco = endereco;

            Geocode.obterCoordenadas(endereco).then(function (coordenadas) {
                service.latitude = coordenadas[0].latitude;
                service.longitude = coordenadas[0].longitude;

                _atualizarCoordenadasMarker();
            }, _atualizarCoordenadasMarker);
        }

        LocationService.getLocation();

        /**
         * Atualiza a localização com as novas coordenadas
         * 
         * @method atualizarCoordenadas
         * 
         * @param latitude {Object}
         * @param longitude {Object} 
         */         
        function atualizarCoordenadas(latitude, longitude) {

            if (latitude && longitude) {

                service.latitude = latitude;
                service.longitude = longitude;

                Geocode.obterEndereco({
                    latitude: latitude ? latitude : -22.94249,
                    longitude: longitude ? longitude : -43.48789
                }).then(function (endereco) {
                    service.endereco = endereco.valor;

                    _atualizarCoordenadasMarker();
                }, _atualizarCoordenadasMarker);
            } else {

                service.latitude = LocationService.getLat();
                service.longitude = LocationService.getLon();
                _atualizarCoordenadasMarker();
            }
        }

        function trigger(eventName) {
            service._triggers[eventName]();
        }

        function on(eventName, callback) {
            service._eventos[eventName].push(callback);
        }

        return service;
    }
}());