/**
* @ngdoc service
* @name MapaAreaDeAtuacaoService
* @module s4c.directives.MapaAreaDeAtuacaoService
*
* @description
* `MapaAreaDeAtuacaoService` Componente para acesso ao api do backend e/ou comunicação entre controllers
*
*
*/
(function () {
'use strict';
angular
.module('s4c.directives.mapa-area-de-atuacao')
.factory('MapaAreaDeAtuacao', MapaAreaDeAtuacao);
MapaAreaDeAtuacao.$inject = ['$timeout', '$rootScope'];
function MapaAreaDeAtuacao($timeout, $rootScope) {
var service = {
_novoDesenhoHandler: null,
_map: null,
_layer: null,
_array_layer: [],
_regiao: null,
_popup: null,
_eventos: {
areaDeAtuacaoEditada: []
},
_triggers: {
areaDeAtuacaoEditada: _triggerareaDeAtuacaoEditada
},
trigger: trigger,
on: on,
atualizarArea: atualizarArea,
limparArea: limparArea,
editarRegiao: editarRegiao,
desativarEdicao: desativarEdicao
};
/**
* Dispara um evento para avisar aos controllers que a área de atuação foi editada
*
* @method _triggerareaDeAtuacaoEditada
*
*
*/
function _triggerareaDeAtuacaoEditada() {
_.each(service._eventos.areaDeAtuacaoEditada, function (callback) {
var geometryCollection = {
type: 'GeometryCollection',
geometries: []
};
_.each(service._array_layer, function (layer) {
if (layer.data._id == service._regiao._id) {
if (layer.toGeoJSON().type == "GeometryCollection") {
_.each(layer.toGeoJSON().geometries, function (feature) {
geometryCollection.geometries.push(feature);
});
}
else {
var geojson = layer.toGeoJSON().geometry;
if (geojson.type === 'GeometryCollection') {
_.each(geojson.geometries, function (geometry) {
geometryCollection.geometries.push(geometry);
});
}
else {
if (geojson.type === 'MultiPolygon') {
geojson.type = 'Polygon';
geojson.coordinates = geojson.coordinates[0];
}
geometryCollection.geometries.push(geojson);
}
}
}
});
callback({
geojson: geometryCollection
});
});
}
/**
* Dispara eventos
*
* @method trigger
*
* @param eventName {Object}
*
*/
function trigger(eventName) {
service._triggers[eventName]();
}
/**
* Listener de eventos
*
* @method on
*
* @param eventName {Object}
* @param callback {Object}
*
*/
function on(eventName, callback) {
service._eventos[eventName].push(callback);
}
/**
* Atualiza a Área de Atuação com os novas geometrias
*
* @method atualizarArea
*
* @param regioes {Object}
* @param opcoes {Object}
*
*/
function atualizarArea(regioes, opcoes) {
_.each(service._array_layer, function (layer) {
service._map.removeLayer(layer);
});
service._array_layer = [];
if (opcoes.desenhar) {
if (service._novoDesenhoHandler) {
service._novoDesenhoHandler.enable();
} else {
service._novoDesenhoHandler =
new L.Draw.Polygon(service._map, new L.Control.Draw().options.polygon);
service._novoDesenhoHandler.enable();
}
$timeout(function () {
service._map.setView({
lat: -22.9009167,
lng: -43.1795591,
}, 13);
service._map.invalidateSize(true);
}, 0);
} else {
if (service._novoDesenhoHandler) {
service._novoDesenhoHandler.disable();
}
var geometry;
var geometryCollection = {
type: 'GeometryCollection',
geometries: []
};
_.each(regioes, function (regiao) {
if (typeof regiao.poiGeometrico === 'string' || regiao.poiGeometrico instanceof String) {
geometry = JSON.parse(regiao.poiGeometrico);
}
else {
geometry = regiao.poiGeometrico;
}
if (geometry != null) {
if (geometry.type == "GeometryCollection") {
_.each(geometry.geometries, function (_geometry) {
_geometry.regiao = regiao;
geometryCollection.geometries.push(_geometry);
});
}
else {
geometry.regiao = regiao;
geometryCollection.geometries.push(geometry);
}
}
});
service._layer = L.geoJson(geometryCollection).addTo(service._map);
service._layer.eachLayer(function (layer) {
var index = 0;
layer.eachLayer(function (itemLayer) {
itemLayer.data = layer.feature.geometry.geometries[index].regiao;
delete layer.feature.geometry.geometries[index].regiao;
service._array_layer.push(itemLayer);
index++;
itemLayer.on('edit', function () {
service.trigger('areaDeAtuacaoEditada');
});
if (itemLayer.eachLayer) {
itemLayer.eachLayer(function (subItemLayer) {
subItemLayer.on({
click: deleteDraw
});
});
}
else {
itemLayer.on({
click: deleteDraw
});
}
});
layer.setStyle({
weight: 5,
color: opcoes.cor,
dashArray: '',
fillOpacity: 0.2
});
});
$timeout(function () {
// bug do leaflet, definindo zoom quando abre o mapa pela primeira vez
if (service._layer != null) {
if (service._map.getBoundsZoom(service._layer.getBounds()) == 0) {
var center = service._layer.getBounds().getCenter();
service._map.setView(center, 12);
} else {
service._map.fitBounds(service._layer.getBounds());
}
service._map.invalidateSize(true);
}
}, 0);
}
}
/**
* Edita as regiões da Área de Atuação
*
* @method editarRegiao
*
* @param regiao {Object}
*
*/
function editarRegiao(regiao) {
if (service._map != null) {
service._regiao = regiao;
desativarEdicao();
_.each(service._array_layer, function (layer) {
if (layer != undefined && regiao && layer.data._id == regiao._id) {
if (layer.eachLayer) {
layer.eachLayer(function (itemLayer) {
itemLayer.editing.enable();
});
}
else {
layer.editing.enable();
}
}
});
}
}
/**
* Desativa a edição da Área de Atuação
*
* @method editarRegiao
*
* @param regiao {Object}
*
*/
function desativarEdicao() {
if (service._map != null) {
//Desativa as edições existentes
_.each(service._array_layer, function (layer) {
if (layer.eachLayer) {
layer.eachLayer(function (itemLayer) {
itemLayer.editing.disable();
});
}
else {
layer.editing.disable();
}
});
}
}
/**
* Remove do Mapa as camadas referente a Área de Atuação
*
* @method limparArea
*
* @param regiao {Object}
*
*/
function limparArea(regiao) {
if (service._map != null) {
service._regiao = null;
var index = 0;
var indexDelete = -1;
_.each(service._array_layer, function (layer) {
if (!regiao || (layer != undefined && regiao && layer.data._id == regiao._id)) {
indexDelete = index;
service._map.removeLayer(layer);
}
index++;
});
if (indexDelete >= 0) {
service._array_layer.splice(indexDelete, 1);
}
else {
$timeout(function () {
service._map.setView({
lat: -22.9009167,
lng: -43.1795591,
}, 13);
service._map.invalidateSize(true);
}, 0);
}
}
if (service._novoDesenhoHandler) {
service._novoDesenhoHandler.disable();
}
}
/**
* Remove do mapa os desenhos referente a Área de Atuação
*
* @method deleteDraw
*
* @param e {Evento}
*
*/
function deleteDraw(e) {
/*var element = angular.element('<div class="wrapper">Remover<md-icon ng-click="removerDesenho()" class="remover-desenho" md-svg-icon="menu:delete"></md-icon></div>');
var newScope = $scope.$new();
$compile(element)(newScope, function(clonedElement, scope) {
e.target.bindPopup.bindPopup(clonedElement[0]);
});*/
if (service._regiao != null) {
service._popup = e.target.bindPopup('<div><a id="btRemoverLayer" href="#">' + $rootScope.res('COMUM_REMOVER') + '</a></div>');
e.target.on('popupopen', function () {
L.DomEvent.on(
document.getElementById('btRemoverLayer'),
'click',
getHandlerForFeature(e.target)
);
});
}
}
/**
* Função chamada no click do botão btRemoverLayer
*
* @method getHandlerForFeature
*
* @param layer {Object}
*
*/
function getHandlerForFeature(layer) {
return function (ev) {
if (service._regiao == null) {
service._map.closePopup();
return;
}
removerDesenho(layer);
}
}
/**
* Remove os desenhos da camada
*
* @method removerDesenho
*
* @param layerToRemove {Object}
*
*/
function removerDesenho(layerToRemove) {
service._map.removeLayer(layerToRemove);
var index = 0;
_.each(service._array_layer, function (layer) {
if (layer != undefined && layer != null && layer._leaflet_id == layerToRemove._leaflet_id) {
service._array_layer.splice(index, 1);
}
index++;
});
service.trigger('areaDeAtuacaoEditada');
}
return service;
}
}());