#20200615 Raku programming solutionuse Geo::Hash;# task example 1 : Ireland, most of England and Wales, small part of Scotlandsay geo-encode(51.433718e0, -0.214126e0, 2);# task example 2 : the umpire's chair on Center Court at Wimbledonsay geo-encode(51.433718e0, -0.214126e0, 9);# Lake Raku is an artificial lake in Tallinn, Estonia# https://goo.gl/maps/MEBXXhiFbN8WMo5z8say geo-encode(59.358639e0, 24.744778e0, 4);# Village Raku is a development committee in north-western Nepal# https://goo.gl/maps/33s7k2h3UrHCg8Tb6say geo-encode(29.2021188e0, 81.5324561e0, 4);
Output:
gc
gcpue5hp4
ud99
tv1y
Roll your own
Alternately, a roll-your-own version that will work with any Real coordinate, not just floating point values, and thus can return ridiculous precision. The geo-decode routine returns the range in which the actual value will be found; converted here to the mid-point with the interval size. Probably better to specify an odd precision so the error interval ends up the same for both latitude and longitude.
my @Geo32 = <0 1 2 3 4 5 6 7 8 9 b c d e f g h j k m n p q r s t u v w x y z>;subgeo-encode ( Rat(Real) $latitude, Rat(Real) $longitude, Int $precision = 9 ) {my @coord = $latitude, $longitude;my @range = [-90, 90], [-180, 180];my $which = 1;my $value = '';while $value.chars < $precision * 5 {my $mid = @range[$which].sum / 2; $value ~= my $upper = +(@coord[$which] > $mid); @range[$which][not $upper] = $mid; $which = not $which; } @Geo32[$value.comb(5)».parse-base(2)].join;}subgeo-decode ( Str $geo ) {my @range = [-90, 90], [-180, 180];my $which = 1;my %Geo32 = @Geo32.antipairs;for %Geo32{$geo.comb}».fmt('%05b').join.comb { @range[$which][$_] = @range[$which].sum / 2; $which = not $which; } @range}# TESTINGfor 51.433718, -0.214126, 2, # Ireland, most of England and Wales, small part of Scotland 51.433718, -0.214126, 9, # the umpire's chair on Center Court at Wimbledon 51.433718, -0.214126, 17, # likely an individual molecule of the chair 57.649110, 10.407440, 11, # Wikipedia test value - Råbjerg Mile in Denmark 59.358639, 24.744778, 7, # Lake Raku in Estonia 29.2021188, 81.5324561, 7 # Village Raku in Nepal-> $lat, $long, $precision {say"$lat, $long, $precision:\ngeo-encoded: ",my $enc = geo-encode $lat, $long, $precision;say'geo-decoded: ', geo-decode($enc).map( {-.sum/2 ~ ' ± ' ~ (abs(.[0]-.[1])/2).Num.fmt('%.3e')} ).join(', ') ~ "\n";}