diff --git a/py/gencache.py b/py/gencache.py
index 3c4d86828703383fa58fe20f672412d6edd338ca..f1b72b3ad90b9e396cdfffc6d0ffb83bd9f160c9 100644
--- a/py/gencache.py
+++ b/py/gencache.py
@@ -170,7 +170,7 @@ Options:
 		certs = json.loads(cindex.get(pub).decode())
 		pubkey = idty["pub"]
 		
-		output["accounts"][pubkey] = [[idty["uid"], int(idty["member"]), None], None, None]
+		output["accounts"][pubkey] = [[idty["uid"], int(idty["member"]), None], None, None, 1, 1]
 		
 		if not pubkey in moredata:
 			moredata[pubkey] = [0,0,0,0,0,None]
@@ -284,21 +284,30 @@ Options:
 	log("Total accounts: {}".format(len(output["accounts"])), LOG_INFO)
 	
 	log("Placing non-geolocated accounts")
-	for _ in range(5):
+	for i in range(5):
 		for pubkey in output["accounts"]:
+			if not pubkey in neighbors:
+				continue
+			
 			account = output["accounts"][pubkey]
-			if account[2] == None and (account[1] == None or account[1][2] == None):
-				pos = [0.0, 0.0]
-				n_neighbors = 0
-				for neighbor_pubkey in neighbors[pubkey]:
-					neighbor = output["accounts"][neighbor_pubkey]
-					neighbor_pos = neighbor[1][2] if neighbor[1] and neighbor[1][2] else (neighbor[2] if neighbor[2] else None)
-					if neighbor_pos:
-						pos[0] += neighbor_pos[0]
-						pos[1] += neighbor_pos[1]
-						n_neighbors += 1
-				if n_neighbors != 0:
-					account[2] = [pos[0]/n_neighbors, pos[1]/n_neighbors]
+			account[3] = account[4]
+			pos = [0.0, 0.0]
+			n_neighbors = 0
+			for neighbor_pubkey in neighbors[pubkey]:
+				neighbor = output["accounts"][neighbor_pubkey]
+				#neighbor_pos = neighbor[1][2] if neighbor[1] and neighbor[1][2] else (neighbor[2] if neighbor[2] else None)
+				neighbor_pos = neighbor[2] if neighbor[2] else (neighbor[1][2] if neighbor[1] and neighbor[1][2] else None)
+				if neighbor_pos:
+					pos[0] += neighbor_pos[0]*neighbor[3]
+					pos[1] += neighbor_pos[1]*neighbor[3]
+					n_neighbors += neighbor[3]
+			if account[1] and account[1][2]:
+				pos[0] += account[1][2][0]*account[3]*5
+				pos[1] += account[1][2][1]*account[3]*5
+				n_neighbors += account[3]*5
+			if n_neighbors != 0:
+				account[2] = [pos[0]/n_neighbors, pos[1]/n_neighbors]
+				account[4] = n_neighbors / 2**i
 	
 	if do_repulsion:
 		log("Computing force layout")
@@ -462,5 +471,5 @@ Options:
 
 
 """
-pubkey => [[pseudo:str, member:bool, community:uint]?, [title:str?, avatar:bool, [lat:float, lon:float]?]?, [computed_lat:float, computed_lon:float]?]
+pubkey => [[pseudo:str, member:bool, community:uint]?, [title:str?, avatar:bool, [lat:float, lon:float]?]?, [computed_lat:float, computed_lon:float]?, computed_pos_weight]
 """
diff --git a/templates/index.html b/templates/index.html
index 376a84ca8ef097727a537b594b8913432fd2c028..9fda8233128ccb28ef4bf0d0c9280525f0d116aa 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -58,7 +58,8 @@
 						<option value="received">{{certs-show-received}}</option>
 						<option value="issued">{{certs-show-issued}}</option>
 					</select><hr />
-					<a id="mapmenu-idcard-cesiumlink" href="#" target="_blank">{{cesium-link}}</a>
+					<a id="mapmenu-idcard-cesiumlink" href="#" target="_blank">{{cesium-link}}</a><br/>
+					<span id="weight"></span>
 				</div>
 			</div>
 		</div>
diff --git a/templates/worldwotmap.js b/templates/worldwotmap.js
index 5b1e4b68f395d64697d2f43409bfa8c15965bb45..1466182d9bd747683d0fdd1309b77405128037b9 100644
--- a/templates/worldwotmap.js
+++ b/templates/worldwotmap.js
@@ -32,7 +32,7 @@ var map_default_zoom = 6;
 var COMMUNITY_COLORS = ["#ff0000", "#00ff00", "#0000ff", "#c0c000", "#c000c0", "#00c0c0", "#d05000", "#d00050", "#50d000", "#00d050", "#d00050", "#00d050"];
 
 class Account {
-	constructor(pubkey, member=false, uid=null, title=null, pos=null, point=null, avatar=false, community=null) {
+	constructor(pubkey, member=false, uid=null, title=null, pos=null, point=null, avatar=false, community=null, weight=null, declared_pos=null, computed_pos=null) {
 		this.pubkey = pubkey;
 		this.member = member;
 		this.uid = uid
@@ -43,6 +43,9 @@ class Account {
 		this.certsReceived = [];
 		this.avatar = avatar;
 		this.community = community;
+		this.weight = weight;
+		this.declared_pos = declared_pos;
+		this.computed_pos = computed_pos;
 	}
 	
 	mapActiveAccount() {// `this` is the Leaflet Circle, not the Account
@@ -101,6 +104,17 @@ function mapActiveAccount(pubkey) {
 		if(line = certs[account.certsReceived[cert]].line)
 			line.setStyle({color:"#f44", weight:3, opacity:0.6});
 	}
+	$("#weight").html(account.weight);
+	if(account.declared_pos && account.computed_pos) {
+		console.log(geoDist(account.declared_pos, account.computed_pos));
+		L.circle(account.declared_pos, {
+			color: "#0f0",
+			fillColor: "#0f0",
+			fillOpacity: 0.5,
+			radius: 1000*geoDist(account.declared_pos, account.computed_pos)
+		}).addTo(map);
+		// TODO remove circle when deselected
+	}
 	showURL();
 }
 
@@ -422,6 +436,7 @@ $.get(settings["data_url"]+"mapdata.json", null, function(data) {
 			account.member = account_data[0][1];
 			account.uid = account_data[0][0];
 			account.community = account_data[0][2];
+			account.weight = account_data[3];
 			
 			if(account.member)
 				nmembers_total ++;
@@ -433,6 +448,7 @@ $.get(settings["data_url"]+"mapdata.json", null, function(data) {
 			
 			if(account_data[1][2]) {
 				account.pos = account_data[1][2];
+				account.declared_pos = account_data[1][2]
 				
 				var point = L.circle(account.pos, {
 					color: account.member ? "#f0f" : "#ed9a00",
@@ -469,6 +485,7 @@ $.get(settings["data_url"]+"mapdata.json", null, function(data) {
 		
 		if(account_data[2]) {
 			account.pos = account_data[2];
+			account.computed_pos = account_data[2];
 			
 			var point = L.circle(account.pos, {
 				color: account.member ? "#f0f" : "#ed9a00",