Wednesday, December 30, 2015

Alterando uma extensão do ThingWorx - Criando funções em Runtime e fazendo as chamadas da API HeatmapLayer

Criando a função para a execução (Runtime)

Fala galera, em meu post anterior eu descrevi como criei as propriedades que serão consumidas nas chamadas da API em Runtime. Agora vou descrever como ficou a função que chama a API e alguns detalhes e dificuldades que tive. Fiquei surpreso em ver o tamanho do código depois que fiz uma limpeza: sofri tanto para deixar funcionando que nem parece que foi só isso que fiz. :)

Antes...

Também decidi deixar o código mais flexível e para isso criei mais duas propriedades: CustomLayerDataField, CustomLayerLocationField. Isso permitirá escolher qual o campo irá ser usado para os dados e para a localização, sem depender de um Datashape específico. Também criei outras propriedades para a chamada da API, mas isso é mais para configurações de raio, opacidade, etc.

Aqui como ficaram as propriedades:

'CustomLayerDataField': {
'description' : 'Field which will provide data for Custom Layer',
'isBindingTarget': true,
'isVisible': true,
'isEditable': true,
'defaultValue': 'Reading',
'sourcePropertyName': 'CustomLayerData',
'baseTypeRestriction': 'NUMBER',
'baseType': 'FIELDNAME'
},
'CustomLayerLocationField': {
'description' : 'Field which will provide data for Custom Layer',
'isBindingTarget': true,
'isVisible': true,
'isEditable': true,
'defaultValue': 'location',
'sourcePropertyName': 'CustomLayerData',
'baseTypeRestriction': 'LOCATION',
'baseType': 'FIELDNAME'
},

Vejam que há outras características importantes:
sourcePropertyName - relaciona a outra propriedade e define a lista de propriedades que serão exibidas;
baseTypeRestriction - restringe o tipo que será mostrado na lista.

Em outras palavras, ao relacionar-se os dados ao campo CustomLayerData, as propriedades desse campo estão disponíveis para seleção, mas apenas as propriedades do tipo selecionado.






Agora sim, a função para Runtime 

Ficou assim:

if (updatePropertyInfo.TargetProperty === 'CustomLayerData') {
var customLayerDataRows = updatePropertyInfo.ActualDataRows;
var nRows = customLayerDataRows.length;
var heatmapData=[];
for (var rowNumber = 0; rowNumber < nRows; rowNumber++) {
var row = customLayerDataRows[rowNumber];
heatmapData[rowNumber] = 
{location: new google.maps.LatLng(parseFloat(row[this.getProperty('CustomLayerLocationField')].latitude) , parseFloat(row[this.getProperty('CustomLayerLocationField')].longitude)), weight: parseFloat(row[this.getProperty('CustomLayerDataField')])};
}  
var heatMapDissipating = this.getProperty('heatMapDissipating');
var heatMapGradient = this.getProperty('heatMapGradient');
var heatMapOpacity= this.getProperty('heatMapOpacity')
var heatMapRadius=this.getProperty('heatMapRadius')
var heatmap = new google.maps.visualization.HeatmapLayer({
data: heatmapData,
dissipating: heatMapDissipating,
opacity: heatMapOpacity,
radius: heatMapRadius
});
heatmap.setMap(this.map); 
return;
}

Algumas considerações:

  • Para usar o valor de uma propriedade, usei o método getProperty, como em: this.getProperty('CustomLayerLocationField')
    • Nesse caso específico irei pegar o nome da coluna definida nesse campo para que seja usada como location no mapa.
  • No caso acima, o Google Maps necessita dos valores de lat e long separados, por isso ao consumir esses dados foi usado: this.getProperty('CustomLayerLocationField')].latitude
  • O bloco for está iterando todos os dados associados ao Widget e criando um vetor (heatmapData) para que esse seja passado na chamada da API. Esse vetor possui um Object LatLong do GoogleMaps
    • Na tag location, estão sendo passados os valores de lat e long, como mencionei antes.
    • Na tag weight está sendo passado o valor dos pontos que serão plotados, com seu devido peso. Quanto maior, mais "vermelho" é o mapa.
O resultado no Thingworx ficou assim:

Tive várias dificuldades, muitas delas em como acessar os dados de uma matriz (pegar a lat e long do campo location, por exemplo) e outras com sintaxe de chamadas.

Vou continuar trabalhando nessa alteração, mas acho que isso já dá pra começar! Espero que ajude!

Cheers!
Ewerton

PS.. Faltou falar de Autenticação, que cobri no meu próximo post



No comments:

Post a Comment