Source: directives/mapa/MapaState.service.js

(function () {
    'use strict';

    /**
     * @ngdoc directives
     * @name MapaStateService
     * @module s4c.directives.mapa.MapaStateService
     *
     * @description
     * `MapaStateService` gerencia o estado atual do mapa, as camadas ativas e
     * cameras ativas.
     */
    function MapaStateService(ParametrosS4C, MapaService) {

        this.mapa = null;

        var camadasAtivas = {};
        var cameraAtiva = {
            ativo: false,
            obj: null
        };

        /**
         * Filtra os Incidentes
         * 
         * @method _filtroIncidentes
         * 
         * @param feature {Object}
         * 
         */ 
        function _filtroIncidentes(feature) {

            var incidente = feature.properties;

            // Pegando filtros do service de camadas (Default: Prioridade 0)
            var filters = MapaService.IncidentesFilters;

            if (!incidente.extras) {
                return false;
            }

            //var categoriasPermitidas = _.chain(filters.categorias)
            if (filters.categorias.indexOf(incidente.CategoriaIncidente) < 0) {
                //console.log('Incidente fora do filtro de categorias..')
                //return false;
            }

            if (incidente.extras.informacoes) {
                // Encontrando prioridade:
                var prioridade = _.find(incidente.extras.informacoes, function (informacao) {
                    return informacao.label === 'Prioridade';
                });

                var criticidade = _.find(incidente.extras.informaceos, function (informacao) {
                    return informacao.label === 'Criticidade';
                });

                if (prioridade) {
                    return filters.prioridades.indexOf(prioridade.valor) > -1;
                }

                if (criticidade) {
                    return filters.criticidades.indexOf(criticidade.valor) > -1;
                }
            }

            return false;
        }

        /*
         * @ngdoc method
         * @methodOf s4c.components.mapa.MapaStateService
         * @name s4c.components.mapa.MapaStateService#addCamada
         *
         * @description
         * Adiciona uma camada ao mapa e persiste ela na memória independente
         * do estado atual da aplicação
         *
         * @param {string} nome Nome da camada a ser adicionada no mapa
         * @param {obj} data Dados da camada a ser adicionada no mapa
         * @param {string} label Label da camada a ser adicionada no mapa
         * @param {obj} extraOpts Atributos que podem ser adicionados ao objeto
         * Leaflet da camada.
         * @param {function} clickFunction Função que é executada ao clicarem
         * em um ponto de interesse desta camada.
         *
         * @param {string} clusterIcon String com a url do ícone do cluster desta categoria
         *
         * @param {obj} categoria Objeto com as informações desta categoria
         *
         * @returns {Promise} Promise que resolve com um GeoJSON contendo os
         * pontos da categoria buscada.
         */
        /**
         * Adiciona uma camada ao mapa e persiste ela na memória independente
         * do estado atual da aplicação
         *
         * @method addCamada
         * 
         * @param {string} nome Nome da camada a ser adicionada no mapa
         * @param {obj} data Dados da camada a ser adicionada no mapa
         * @param {string} label Label da camada a ser adicionada no mapa
         * @param {obj} extraOpts Atributos que podem ser adicionados ao objeto
         * Leaflet da camada.
         * @param {function} clickFunction Função que é executada ao clicarem
         * em um ponto de interesse desta camada.
         *
         * @param {string} clusterIcon String com a url do ícone do cluster desta categoria
         *
         * @param {obj} categoria Objeto com as informações desta categoria
         *
         * @returns {Promise} Promise que resolve com um GeoJSON contendo os
         * pontos da categoria buscada.
         * 
         * @returns {Promise} Promise que resolve com um GeoJSON contendo os
         * pontos da categoria buscada.
         */         
        function addCamada(nome, data, label, extraOpts, clickFunction, clusterIcon, categoria) {
            console.log('ativando camada.....');
            if (categoria && categoria.tipo === 'incidentes') {
                data.features = _.filter(data.features, _filtroIncidentes);
            }

            var clusterDistance = parseInt(ParametrosS4C.parametros.cluster.pois.distancia, 10) / 10;

            if (categoria && categoria.tipo && categoria.tipo === 'incidentes') {
                clusterDistance = 1;
            }

            if (clusterDistance <= 0) {
                clusterDistance = 1;
            }

            var markerCluster = new L.MarkerClusterGroup({
                maxClusterRadius: clusterDistance,
                iconCreateFunction: function (cluster) {
                    return new L.DivIcon({
                        html: '<div class="marker-cluster-wrapper" style="background-image: url(\'' + clusterIcon + '\');"><b class="marker-cluster-counter">' + cluster.getChildCount() + '</b></div>',
                        iconSize: [24, 24],
                        iconAnchor: [0, 0]
                    });
                }
            });

            var geoJson = L.geoJson(data, {
                pointToLayer: function (feature, latlng) {
                    var urlIcone = feature.properties.urlIcone ||
                        feature.properties.icone ||
                        categoria.icone ||
                        data.urlIcone;

                    var html = '<div class="marker-cluster-wrapper" style="background-image: url(' + urlIcone + ')"></div>';
                    if (feature.properties.comentarios !== undefined) {
                        if (feature.properties.comentarios.length > 0) {
                            html = '<div class="marker-cluster-wrapper" style="background-image: url(' + urlIcone + ')"><b class="marker-cluster-counter comentarios-incidentes">' + feature.properties.comentarios.length + '</b></div>';
                        }
                    }

                    var marker = L.marker(latlng, {
                        icon: new L.DivIcon({
                            html: html,
                            iconSize: [24, 24]
                        })
                    });

                    console.log('icon', html);


                    // Colocando todas as properties dentro do marker
                    angular.extend(marker.options, feature.properties);

                    marker.options.id = feature.properties.id;
                    angular.extend(marker.options, extraOpts);

                    if (categoria && categoria.tipo && categoria.tipo === 'cameras') {
                        marker.bindLabel('' + feature.properties.numero || 'Camera');
                    } else {
                        console.log('binding label..');
                        marker.bindLabel(label);
                    }

                    marker.on('click', clickFunction);

                    if (clusterIcon) {
                        markerCluster.addLayer(marker);
                    }

                    return marker;
                }

            });

            if (!clusterIcon) {
                camadasAtivas[nome] = geoJson;
                //var incidentes = this.getCamadasByType('incidente');
                return geoJson;
            } else {
                camadasAtivas[nome] = markerCluster;
                //var incidentes = this.getCamadasByType('incidente');
                return markerCluster;
            }
        }

        /**
         * Retorna as camadas ativas do mapa
         * 
         * @method getCamadasAtivas
         * 
         * @returns camadasAtivas 
         * 
         */         
        function getCamadasAtivas() {
            return camadasAtivas;
        }

        /**
         * Retorna as camadas ativas por tipo
         * 
         * @method getCamadasByType
         * 
         * @returns camadasAtivas Camadas Ativas por tipo
         * 
         */          
        function getCamadasByType(type) {
            return _.chain(Object.keys(camadasAtivas))
                .filter(function (camadaKey) {
                    return camadaKey.indexOf(type) > -1;
                })
                .map(function (camadaKey) {
                    return camadasAtivas[camadaKey];
                })
                .value();
        }

        /**
         * Altera quantidade de comentários no Incidente
         * 
         * @method updateIconCount
         * 
         * @param marker 
         * @param count
         * 
         */        
        function updateIconCount(marker, count) {
            var html = '<div class="marker-cluster-wrapper" style="background-image: url(' + marker.feature.properties.icone + ')"><b class="marker-cluster-counter comentarios-incidentes">' + count + '</b></div>';
            $(marker._icon).html(html);
        }

        return {
            addCamada: addCamada,
            camadasAtivas: camadasAtivas,
            cameraAtiva: cameraAtiva,
            getCamadasAtivas: getCamadasAtivas,
            getCamadasByType: getCamadasByType,
            updateIconCount: updateIconCount,
            mapa: this.mapa
        };
    }

    MapaStateService.$inject = ['ParametrosS4C', 'MapaService'];

    /**
     * @ngdoc overview
     * @name s4c.components.mapa
     */
    angular.module('s4c.components.mapa')
        .factory('MapaStateService', MapaStateService);

}());