/**
* @ngdoc service
* @name RepresentacaoService
* @module s4c.services.RepresentacaoService
*
* @description Componente para acesso a api do backend e/ou comunicação entre controllers
*
*
*/
(function () {
angular.module('s4c.services')
.factory('RepresentacaoService', RepresentacaoService);
RepresentacaoService.$inject = ['$q'];
/**
* @method RepresentacaoService
* @param {*} $q
*/
function RepresentacaoService($q) {
var service = {
obterLayoutByZoom: obterLayoutByZoom,
obterLayout: obterLayout,
buildFeatureHtml: buildFeatureHtml,
buildGeometryStyle: buildGeometryStyle,
getFunctionResult: getFunctionResult
};
/**
* @method saveobterLayoutByZoom
* @param {*} featureCollection
* @param {*} mapa
*/
function obterLayoutByZoom(featureCollection, mapa) {
if (!featureCollection.representacao) {
return;
}
_.each(featureCollection.features, function (feature) {
if (!feature.representacoesByZoom) {
return;
}
var featureHtml;
for (var i = 0; i < feature.representacoesByZoom.length; i++) {
if (mapa.getZoom() >= feature.representacoesByZoom[i].minZoom
&& mapa.getZoom() <= feature.representacoesByZoom[i].maxZoom) {
featureHtml = feature.representacoesByZoom[i].html;
break;
}
}
feature.representacao = {
iconAnchor: {
w: 60,
h: 30
},
html: featureHtml
}
});
}
/**
* @method obterLayout
* @param {*} featureCollection
* @param {*} mapa
*/
function obterLayout(featureCollection, mapa) {
if (!featureCollection.representacao) {
return;
}
_.each(featureCollection.features, function (feature) {
if (!feature.geometry || feature.geometry.type == 'Point') {
if (featureCollection.representacao.pointLayout) {
buildFeatureHtml(featureCollection.representacao.pointLayout, feature, mapa);
}
return;
}
buildGeometryStyle(featureCollection.representacao.geometryStyle, feature);
});
}
/**
* @method save
* @param {*} alarme
*/
function buildGeometryStyle(representacao, feature) {
feature.style = getFunctionResult(feature, representacao.funcao, representacao);
}
/**
* @method buildFeatureHtml
* @param {*} representacao
* @param {*} alarmefeature
* @param {*} mapa
*/
function buildFeatureHtml(representacao, feature, mapa) {
var deferred = $q.defer();
loadRepresentationValues(feature, representacao);
var htmlByZoom = [];
var featureHtml;
for (var index = 0; index < representacao.length; index++) {
var html = obterHtml(representacao[index]);
structure = {
html: html,
minZoom: representacao[index].minZoom,
maxZoom: representacao[index].maxZoom
};
htmlByZoom.push(structure);
//A representação inicial será a primeira declarada no json de representação.
if (!featureHtml) {
featureHtml = html;
}
}
if (mapa) {
mapa.pegarZoom(function (zoom) {
_.each(htmlByZoom, function (structure) {
if (zoom >= structure.minZoom && zoom <= structure.maxZoom) {
featureHtml = structure.html;
feature.representacoesByZoom = htmlByZoom;
feature.representacao = {
iconAnchor: {
w: 60,
h: 30
},
html: featureHtml
}
}
});
});
deferred.resolve(feature);
return deferred.promise;
}
feature.representacoesByZoom = htmlByZoom;
feature.representacao = {
iconAnchor: {
w: 60,
h: 30
},
html: featureHtml
}
deferred.resolve(feature);
return deferred.promise;
}
/**
* Executa as funções contidas em cada json dos items da representação.
*/
/**
* @method loadRepresentationValues
* @param {*} feature
* @param {*} representacaoArray
*/
function loadRepresentationValues(feature, representacaoArray) {
if (!representacaoArray) {
return;
}
for (var index = 0; index < representacaoArray.length; index++) {
var representacao = representacaoArray[index];
if (representacao.linhas) {
for (var i = 0; i < representacao.linhas.length; i++) {
for (var j = 0; j < representacao.linhas[i].items.length; j++) {
var item = representacao.linhas[i].items[j];
var result = getFunctionResult(feature, item.funcao);
if (item.tipo == 'icon') {
item.urlIcon = result;
} else {
item.valor = result;
}
}
}
}
if (representacao.circulo) {
var result = getFunctionResult(feature, representacao.circulo.centro.funcao);
if (result) {
if (representacao.circulo.centro.tipo == 'icon') {
representacao.circulo.centro.urlIcon = result;
} else {
representacao.circulo.centro.valor = result;
}
}
}
}
}
/**
* Função para obter os extras de um poi de acordo com um label. Será usado dentro da função
* de representação de cada item.
*
*/
/**
* @method getValueExtra
* @param {*} extras
* @param {*} label
*/
var getValueExtra = function (extras, label) {
for (var index = 0; index < extras.informacoes.length; index++) {
if (extras.informacoes[index].label.toLowerCase() == label.toLowerCase()) {
return extras.informacoes[index].valor;
}
}
}
/**
* Executa apenas a função js dentro da representacao. Pode ser chamada externamente, como por exemplo na tabela do módulo de Pois.
*/
/**
* @method getFunctionResult
* @param {*} style
* @param {*} feature
* @param {*} funcao
*/
function getFunctionResult(feature, funcao, style) {
var code;
if (!feature.geometry || feature.geometry.type == 'Point') {
code = 'var poi = ' + JSON.stringify(feature) + '; var getValueExtra = ' + getValueExtra.toString() + '; ' + funcao;
} else if (style) {
code = 'var style = ' + JSON.stringify(style) + '; var poi = ' + JSON.stringify(feature) + '; var getValueExtra = ' + getValueExtra.toString() + '; ' + funcao;
}
if (code) {
var F = new Function(code);
return F();
}
return '';
}
/**
* Lógica para processar o json representação e converter em uma página html
*/
/**
* @method obterHtml
* @param {*} representacao
*/
function obterHtml(representacao) {
var tmpDiv = document.createElement("div");
var mainDiv = document.createElement("div");
mainDiv.setAttribute('id', 'divMain');
var ratioW = 7.3;
var ratioH = 3;
if (representacao.estilo != 'transparente') {
mainDiv.setAttribute('style', 'border-color:#a9a9a9; border-width:2px; border-style: solid; background-color:#867979; margin-top:-'
+ (representacao.height / ratioH) + 'px; margin-left:-' + representacao.width / ratioW + 'px;');
} else {
mainDiv.setAttribute('style', 'background-color:transparent; margin-top:-' + (representacao.height / ratioH) + 'px; margin-left:-' + representacao.width / ratioW + 'px;');
}
mainDiv.style.width = representacao.width + 'px';
mainDiv.style.height = representacao.height + 'px';
if (representacao.linhas) {
//Verifica se há linhas horizontais no topo e adiciona na mainDiv
_.each(representacao.linhas, function (linha) {
if (linha.tipo == 'top') {
mainDiv.appendChild(createRow(linha, representacao));
}
});
//Verifica se há linhas verticais na esquerda e adiciona na mainDiv
_.each(representacao.linhas, function (linha) {
if (linha.tipo == 'left') {
mainDiv.appendChild(createRow(linha, representacao));
}
});
//Verifica se há a área central e adiciona na mainDiv
if (representacao.circulo) {
mainDiv.appendChild(createCentralDiv(representacao));
}
//Verifica se há linhas verticais na direita e adiciona na mainDiv
_.each(representacao.linhas, function (linha) {
if (linha.tipo == 'right') {
mainDiv.appendChild(createRow(linha, representacao));
}
});
//Verifica se há linhas horizontais no fundo e adiciona na mainDiv
_.each(representacao.linhas, function (linha) {
if (linha.tipo == 'bottom') {
mainDiv.appendChild(createRow(linha, representacao));
}
});
} else {
if (representacao.estilo != 'transparente') {
mainDiv.setAttribute('style', 'border-color:#a9a9a9; border-width:2px; border-style: solid; background-color:#867979;');
} else {
mainDiv.setAttribute('style', 'background-color:transparent;');
}
//Verifica se há a área central e adiciona na mainDiv
if (representacao.circulo) {
mainDiv.appendChild(createCentralDiv(representacao));
}
}
tmpDiv.appendChild(mainDiv);
return tmpDiv.innerHTML;
}
/**
* @method createCentralDiv
* @param {*} representacao
*/
function createCentralDiv(representacao) {
var div = document.createElement("div");
div.setAttribute('id', 'divCentral');
if (representacao.estilo != 'transparente') {
div.setAttribute('style', representacao.circulo.background + ' display:table; margin:0 auto; margin-top:6px; margin-bottom:-4px;');
} else {
div.setAttribute('style', 'background-color:transparent; display:table; margin:0 auto; margin-top:6px; margin-bottom:-4px;');
}
div.style.width = (representacao.width - 4) + 'px';
div.style.height = (representacao.circulo.height) + 'px';
if (representacao.circulo.centro.tipo == 'icon') {
var icon = document.createElement("span");
icon.setAttribute('style', 'width:' + representacao.circulo.centro.iconWidth + '; display:table; margin:0 auto;' + representacao.circulo.centro.style || '');
icon.appendChild(htmlToElement('<img style="width:' + representacao.circulo.centro.iconWidth + '; max-height:48px; color:#00ff00;" src="' + representacao.circulo.centro.urlIcon + '"></img>'));
div.appendChild(icon);
} else if (item.tipo == 'progress') {
if (!representacao.circulo.centro.valor || representacao.circulo.centro.valor.toString().length == 0) {
return div;
}
div.appendChild(htmlToElement('<progress value="' + representacao.circulo.centro.valor + '" max="100" style="margin-left:3px; margin-top:4px;"></progress>'));
if (representacao.circulo.centro.valor.toString().length > 4) {
representacao.circulo.centro.valor = parseFloat(representacao.circulo.centro.valor.toString().substring(0, 4));
}
var label = item.progress_label;
if (!label || label.length == 0) {
label = representacao.circulo.centro.valor + '%';
}
else if (label.includes('*')) {
label = label.replace('*', '');
label = label + ' ' + representacao.circulo.centro.valor + '%';
}
div.appendChild(htmlToElement('<center><span style="width:100%; font-weight: bold; color:#696969; position: fixed; left: 0px; font-size: 10; z-index:100; margin-top:2px;">' +
label + '</span> </center>'));
} else {
var style = item.style;
if (style) {
style = style + ' width:100%; margin-top:2px; text-align: center; z-index:100; min-height:18px;';
} else {
style = 'width:100%; font-weight: bold; color:black; font-size: 11px; margin-top:2px; text-align: center; z-index:100; min-height:18px;';
}
div.appendChild(htmlToElement('<p style="' + style + '">' + item.valor + '</p>'));
}
return div;
}
/**
* @method htmlToElement
* @param {*} html
*/
function htmlToElement(html) {
var template = document.createElement('template');
template.innerHTML = html;
return template.content.firstChild;
}
/**
* @method createRow
* @param {*} representacao
* @param {*} linha
*/
function createRow(linha, representacao) {
var div = document.createElement("div");
if (representacao.estilo != 'transparente') {
div.setAttribute('style', 'background-color:#333333; padding-left:1px;');
} else {
div.setAttribute('style', 'background-color:transparent; padding-left:1px;');
}
if (linha.tipo == 'top' || linha.tipo == 'bottom') {
div.setAttribute("layout", "row");
div.style.width = (representacao.width - 4) + 'px';
div.style.height = "21px";
} else {
div.style.width = "10%";
div.style.height = (representacao.height - 4) + 'px';
}
var count = 0;
_.each(linha.items, function (item) {
if (item.tipo == 'icon') {
var icon = document.createElement("span");
icon.setAttribute('style', 'width:' + item.iconWidth + '; padding-top:3px; display:table; margin:0 auto; ' + item.style || '');
var margin = '';
//Só coloca margem left nos itens diferentes do primeiro item.
if (count > 0) {
margin = 'margin-left:' + count + 'px;';
}
icon.appendChild(htmlToElement('<img src="' + item.urlIcon + '" style="width:' + item.iconWidth + '; ' + margin + '"></img>'));
div.appendChild(icon);
} else if (item.tipo == 'progress') {
if (!item.valor || item.valor.toString().length == 0) {
return;
}
div.appendChild(htmlToElement('<progress value="' + item.valor + '" max="100" style="margin-left:3px; margin-top:4px;"></progress>'));
if (item.valor.toString().length > 4) {
item.valor = parseFloat(item.valor.toString().substring(0, 4));
}
var label = item.progress_label;
if (!label || label.length == 0) {
label = item.valor + '%';
}
else if (label.includes('*')) {
label = label.replace('*', '');
label = label + ' ' + item.valor + '%';
}
div.appendChild(htmlToElement('<center><span style="width:100%; font-weight: bold; color:#696969; position: fixed; left: 0px; font-size: 10; z-index:100; margin-top:2px;">' +
label + '</span> </center>'));
} else {
var style = item.style;
if (style) {
style = style + ' width:100%; margin-top:2px; text-align: center; z-index:100; min-height:18px;';
} else {
style = 'width:100%; font-weight: bold; color:black; font-size: 11px; margin-top:2px; text-align: center; z-index:100; min-height:18px;';
}
div.appendChild(htmlToElement('<p style="' + style + '">' + item.valor + '</p>'));
}
count++;
});
return div;
}
return service;
}
}());