User:Klaus/KingOfTheGraticules

From Geohashing

This is just a stupid idea which I had. I'll dump it here for now, until I improve it.

What is the idea?

The idea is to create a (daily) world map where the whole world cube is claimed by geohashers. Each point of the world is claimed by one geohasher at a time and he/she is the "king"/"queen" of that area. If you want to improve your kingdom, you can either visit more hashes in your existing kingdom which makes it harder for others to claim your area or you can visit more hashes in foreign weak areas and expand your kingdom.

Someone in Siberia or on the Atlantic ocean might claim a huge amount of land by just doing one geohash in the middle of it. People living in high density geohashing areas might not claim any land at all if they live close to someone with 100+ hashes.

I might only count "recent" hashes, too.

Things I need to decide

  • Should geohashes fade out linearly over time, i.e. after 10 years, a geohash does not count anymore?
  • What kind of weight function to use? Something exponential like "exp(-dist/C)" or something quadratic like "1/(1+dist)^2"? I'll probably decide as soon as I have some maps.
  • Count only reached hashes? I think so...
  • How fine? 100 pixels per Graticule or more?

Script for now

# !/usr/bin/python

import json
from math import radians, cos, sin, asin, sqrt, exp
from copy import deepcopy

# ugly parsing of https://fippe.de/alldata.js
data=open("alldata.js","r").read()
HEADER = "var expeditions = "
FOOTER = ",\n];\n"
assert(data.startswith(HEADER))
assert(data.endswith(FOOTER))
data=data[len(HEADER):]
data=data[:-len(FOOTER)]
data=data+"]"
data = json.loads(data)

# now we have a list of geohashes like
# ["2023-08-16_52_7",52.05395,7.73412,["Fippe"],true,1,["Bicycle_geohash_achievement", "Land_geohash_achievement"]],
# ["2010-01-12_global",33.67653,-81.27146,["NWoodruff","LuxMundi"],true,12,["Globalhash_achievement"]],

# filter only reached hashes
data = [i for i in data if i[4] == True]

# get set of users
users = set()
for i in data:
    users |= set(i[3])
print(users)

# https://stackoverflow.com/questions/4913349/haversine-formula-in-python-bearing-and-distance-between-two-gps-points/4913653#4913653
def haversine(lon1, lat1, lon2, lat2):
    """
    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    r = 6371 # Radius of earth in kilometers. Use 3956 for miles
    return c * r


LONRANGE = [i for i in range(-90,91)]
LATRANGE = [i for i in range(-180,181)]
LONRANGE = [i for i in range(47,55+1)]
LATRANGE = [i for i in range(5,15+1)]


king = [ [ "" for lat in LATRANGE ] for lon in LONRANGE] 
print("init density done")


def weight(dist):
    assert(dist >= 0)
    return 1. / (dist+1)**2

for lonindex, lon in enumerate(LONRANGE):
    for latindex, lat in enumerate(LATRANGE):
        tmp = deepcopy(dict.fromkeys(users, 0.))
        for geohash in data:
            geolon, geolat = geohash[1], geohash[2]
            for geouser in geohash[3]:
                tmp[geouser] += weight(haversine(lon,lat,geolon,geolat))
        max_user  = max(tmp, key=tmp.get)
        #print(tmp)
        print(f"maximum for {lon},{lat} is {max_user} with weight {tmp[max_user]}")
        king[lonindex][latindex] = (max_user, tmp[max_user])

example output for Germany

maximum for 47,5 is Baarde with weight 0.0023012356385766286
maximum for 47,6 is Crox with weight 0.007699984689657429
maximum for 47,7 is Crox with weight 0.038897544181984746
maximum for 47,8 is Tungmar with weight 0.018528739383917605
maximum for 47,9 is MykaDragonBlue with weight 0.040467624501727084
maximum for 47,10 is Ekorren with weight 0.00479617522599326
maximum for 47,11 is LeslieHapablap with weight 0.010826449652301917
maximum for 47,12 is LeslieHapablap with weight 0.004651845155012959
maximum for 47,13 is Reinhard with weight 0.00181486196596779
maximum for 47,14 is B2c with weight 0.0013414195123689567
maximum for 47,15 is B2c with weight 0.0017957337500081071
maximum for 48,5 is GeorgDerReisende with weight 0.0018293951759897626
maximum for 48,6 is Baarde with weight 0.0036729989744967197
maximum for 48,7 is Baarde with weight 0.03905682877442473
maximum for 48,8 is RecentlyChanged with weight 0.0634133129194444
maximum for 48,9 is Ekorren with weight 0.0573629377999951
maximum for 48,10 is Ekorren with weight 0.013606021617061224
maximum for 48,11 is TheOneRing with weight 0.10490586164127187
maximum for 48,12 is Harleydavidsonandy with weight 0.049155557595685906
maximum for 48,13 is Robert with weight 0.014065845915421692
maximum for 48,14 is B2c with weight 0.008400864577314968
maximum for 48,15 is B2c with weight 0.0048942445828206275
maximum for 49,5 is GeorgDerReisende with weight 0.002298096872817964
maximum for 49,6 is Baarde with weight 0.004815191763979033
maximum for 49,7 is Baarde with weight 0.010452285862118691
maximum for 49,8 is Q-Owl with weight 0.1308363622024999
maximum for 49,9 is DODO with weight 0.11608691966236
maximum for 49,10 is DODO with weight 0.16226044004570395
maximum for 49,11 is Danatar with weight 0.015067194959247333
maximum for 49,12 is dawidi with weight 0.9275373146653234
maximum for 49,13 is dawidi with weight 0.054531989434608054
maximum for 49,14 is Danatar with weight 0.0026655669753878207
maximum for 49,15 is B2c with weight 0.003035046716508224
maximum for 50,5 is GeorgDerReisende with weight 0.0028013838715444327
maximum for 50,6 is GeorgDerReisende with weight 0.004819725875603006
maximum for 50,7 is Gefrierbrand with weight 0.011305720533205395
maximum for 50,8 is Mampfred with weight 0.2493283500677317
maximum for 50,9 is GeorgDerReisende with weight 0.10955262573524727
maximum for 50,10 is Danatar with weight 0.5574659857259744
maximum for 50,11 is Klaus with weight 0.03246377476871615
maximum for 50,12 is Danatar with weight 0.04510605156118596
maximum for 50,13 is Danatar with weight 0.006932465340946476
maximum for 50,14 is Thepiguy with weight 0.016236373964000697
maximum for 50,15 is redguy with weight 0.0036676901158184134
maximum for 51,5 is NeThuS with weight 0.02278942467026077
maximum for 51,6 is GeorgDerReisende with weight 0.007758063094770804
maximum for 51,7 is GeorgDerReisende with weight 0.046127187525615246
maximum for 51,8 is GeorgDerReisende with weight 0.031176024530840462
maximum for 51,9 is GeorgDerReisende with weight 0.11182640443754852
maximum for 51,10 is GeorgDerReisende with weight 0.20197117796069514
maximum for 51,11 is Rincewind with weight 0.3068679952657682
maximum for 51,12 is Paintedhell with weight 0.18043674734153983
maximum for 51,13 is Danatar with weight 0.042979847300641985
maximum for 51,14 is Danatar with weight 0.10304354931677923
maximum for 51,15 is Danatar with weight 0.05158105699417946
maximum for 52,5 is JwB with weight 0.08384123652599894
maximum for 52,6 is FelixTheCat with weight 0.03751767255243819
maximum for 52,7 is Arvid with weight 0.10008613866271686
maximum for 52,8 is Fippe with weight 0.04333370440046326
maximum for 52,9 is Fippe with weight 0.11099314064914968
maximum for 52,10 is Fippe with weight 0.23921887962904775
maximum for 52,11 is Fippe with weight 0.028824683331931167
maximum for 52,12 is Reinhard with weight 0.012544702986250447
maximum for 52,13 is relet with weight 0.18398722671708406
maximum for 52,14 is relet with weight 0.012282745304953786
maximum for 52,15 is Danatar with weight 0.003753119935988901
maximum for 53,5 is Eupeodes with weight 0.014214693402230935
maximum for 53,6 is Shevek with weight 0.006978796178056222
maximum for 53,7 is Blauwe_BIC with weight 0.15384901950770558
maximum for 53,8 is Fippe with weight 0.05434795167890141
maximum for 53,9 is Fippe with weight 0.09637262165602019
maximum for 53,10 is Fippe with weight 0.06578415936139503
maximum for 53,11 is Fippe with weight 0.029673455220319597
maximum for 53,12 is relet with weight 0.02162159157388358
maximum for 53,13 is relet with weight 0.0200411966585085
maximum for 53,14 is relet with weight 0.01004751712891905
maximum for 53,15 is relet with weight 0.002251959454330422
maximum for 54,5 is Sourcerer with weight 0.002593321050567368
maximum for 54,6 is GeorgDerReisende with weight 0.0030226125726690372
maximum for 54,7 is Fippe with weight 0.005984561424176756
maximum for 54,8 is Fippe with weight 0.01124357033856347
maximum for 54,9 is π_π_π with weight 0.02349812462248916
maximum for 54,10 is π_π_π with weight 0.407150149215557
maximum for 54,11 is π_π_π with weight 0.012193396496538186
maximum for 54,12 is Trurl with weight 0.010269151954365657
maximum for 54,13 is SastRe.O with weight 0.021989678217166495
maximum for 54,14 is π_π_π with weight 0.07916964180279705
maximum for 54,15 is JRK with weight 0.0026736658022132624
maximum for 55,5 is Sourcerer with weight 0.0020892046174319605
maximum for 55,6 is GeorgDerReisende with weight 0.0022102755980369965
maximum for 55,7 is Fippe with weight 0.002978486381969255
maximum for 55,8 is Fippe with weight 0.004453126739758758
maximum for 55,9 is π_π_π with weight 0.005982335660953738
maximum for 55,10 is π_π_π with weight 0.009470347531698415
maximum for 55,11 is π_π_π with weight 0.005449596705163217
maximum for 55,12 is Pastori with weight 0.004622361573023937
maximum for 55,13 is Llavids with weight 0.00900023902201388
maximum for 55,14 is Llavids with weight 0.008172263901904994
maximum for 55,15 is Llavids with weight 0.0029021091702394843