Quantcast
Channel: freelabs
Viewing all articles
Browse latest Browse all 13

Aggregazione di dati (data clustering) con OpenLayers

$
0
0

[ OpenLayers.js, Javascript, jQuery ]

Presupponendo che si stia lavorando con una mappa che dovrà contenere una gran mole di markers, ognuno dei quali è un valore (ad esempio il valore relativo alla temperatura istantanea di tutte le stazioni del Nord Italia), se ne avessimo ad esempio un migliaio, il risultato sarà un grosso pasticcio di numeri. Per evitare tutto questo, è necessario aggregare i dati, in questo caso facendone la media.

1

Data not clustered

 

2

Clustered data

Avendo già creato il nostro vettore di elementi “punto” in OpenLayers.Feature.Vector e aggiunto ad un array di tipo OpenLayers.Layer.Vector, andiamo a settare le caratteristiche di quest’ultimo, compreso il clustering:

var vectorLayer = new OpenLayers.Layer.Vector("Valori", {
	strategies: [
		new OpenLayers.Strategy.Cluster({distance: 50, threshold: 2})
	],
	styleMap: new OpenLayers.StyleMap({'default': pointStyle}), 
	renderers: renderer
});

“distance” determina la distanza in punti sulla mappa tra un marker e un altro per essere clusterizzati,
“treshold” è la soglia di elementi minimi da clusterizzare se presenti all’interno della distanza definita in “distance”.

In questo momento gli elementi vengono clusterizzati correttamente, rimane da definire lo stile differente in caso di clustering:

var pointStyle = new OpenLayers.Style({
	strokeColor: "#000000",
	strokeOpacity: 1,
	strokeWidth: "${strokeFunction}",
	fillColor: "#f3f3f3",
	fillOpacity: 0.7,
	cursor:"pointer",
	pointRadius: "${radiusfunction}",
	pointerEvents: "visiblePainted",
	label: "${val}",
	fontColor: "#000000",
	fontSize: "10px",
	fontFamily: "verdana",
	fontWeight: "normal",
	labelAlign: "${align}"
},{
	context: {
		val: function(feature) { 
			if(feature.attributes.count>1) {
				var sumValue = 0;
				for (var i=0; i<feature.cluster.length; i++)="" {="" sumvalue="" +="feature.cluster[i].attributes['val'];" }="" var="" averagevalue="sumValue/feature.cluster.length;" return="" averagevalue.tofixed(1);="" else="" feature.attributes.val;="" },="" strokefunction:="" function(feature)="" if(feature.attributes.count="">1) {
				var count = feature.attributes.count;
				var stk = Math.max(0.4 * count, 3);
				return stk;
			} else return 2;
		},
		radiusfunction: function(feature) {
			if(feature.attributes.count>1) {
				var count = feature.attributes.count;
				var radius = Math.max(0.8 * count, 16);
				return radius;
			} else return 16;
		}
	}
});

In questo caso stiamo passando il valore in “val” come attributo dell’elemento (se ciclato come risultato di una richiesta ajax o da un array, possiamo inserire il valore richiesto tramite “valore_elemento”.

var pointFeature = OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lat,lon));
pointFeature.attributes = {
	val: valore_elemento
};

Il resto si dovrebbe facilmente capire, si utilizzano funzioni richiamate per il calcolo della media, la dimensione del raggio e del bordo a seconda del numero di elementi clusterizzati. In questo modo si può lavorare sullo stile dell’elemento nel momento in cui è singolo e nell’elemento clusterizzato.


Viewing all articles
Browse latest Browse all 13

Trending Articles