Sample code

There are sample codes implemented encoding and decoding method of GeoPo code in various computer languages. Also these has mistakes of programing or bug codes. And we didn't enough tests.

Please contact us when you implement efficient algorithm or sample codes in other languages. We will post there, if you allow to public.

Existing sample codes
  1. JavaScript
  2. PHP
  3. C++
  4. Objective-C
  5. Perl
  6. Ruby
  7. Java
  8. Python
  9. Haskell
  10. Excel

1. JavaScript


/*
 * GeoPo Encode in JavaScript
 * @author : Shintaro Inagaki
 * @param location (Object)
 * @return geopo (String)
 */
function geopoEncode(location){
	// 64characters (number + big and small letter + hyphen + underscore)
	var chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";

	var geopo = new String();
	var lat = parseFloat(location.lat); // Parse as float
	var lng = parseFloat(location.lng); // Parse as float
	var scale = parseInt(location.scale); // Parse as int
	
	// Change a degree measure to a decimal number
	lat = (lat + 90) / 180 * Math.pow(8, 10);
	lng = (lng + 180) / 360 * Math.pow(8, 10);

	// Compute a GeoPo code from head and concatenate
	for(var i = 0; i < scale; i++) {
		geopo = geopo + chars.substr(Math.floor(lat / Math.pow(8, 9 - i) % 8) + Math.floor(lng / Math.pow(8, 9 - i) % 8) * 8, 1);
	}
	return geopo;
}		

/*
 * GeoPo Decode in JavaScript
 * @author : Shintaro Inagaki
 * @param geopo (String)
 * @return location (Object)
 */
function geopoDecode(geopo){
	// 64characters (number + big and small letter + hyphen + underscore)
	var chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";

	var location = new Object();
	var lat = 0;
	var lng = 0;
	var scale = geopo.length; // Scale is length of GeoPo code
	var order = 0;

	for (var i = 0; i < scale; i++) {
		// What number of character that equal to a GeoPo code (0-63)
		order = chars.indexOf(geopo.substr(i, 1));
		// Lat/Lng plus geolocation value of scale 
		lat = lat + Math.floor(order % 8) * Math.pow(8, 9 - i);
		lng = lng + Math.floor(order / 8) * Math.pow(8, 9 - i);
	}
	
	// Change a decimal number to a degree measure, and plus revised value that shift center of area
	location.lat = lat * 180 / Math.pow(8, 10) + 180 / Math.pow(8, scale) / 2 - 90;
	location.lng = lng * 360 / Math.pow(8, 10) + 360 / Math.pow(8, scale) / 2 - 180;
	location.scale = scale;

	return location;
}		

2. PHP


/*
 * GeoPo Encode in PHP
 * @author : Shintaro Inagaki
 * @param $location (Array)
 * @return $geopo (String)
 */
function geopoEncode($location) {
	// 64characters (number + big and small letter + hyphen + underscore)
	$chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";

	$geopo = "";
	$lat = $location['lat'];
	$lng = $location['lng'];
	$scale = $location['scale'];
	
	// Change a degree measure to a decimal number
	$lat = ($lat + 90) / 180 * pow(8, 10);
	$lng = ($lng + 180) / 360 * pow(8, 10);

	// Compute a GeoPo code from head and concatenate
	for($i = 0; $i < $scale; $i++) {
		$geopo .= substr($chars, floor($lat / pow(8, 9 - $i) % 8) + floor($lng / pow(8, 9 - $i) % 8) * 8, 1);
	}
	return $geopo;
}		

/*
 * GeoPo Decode in PHP
 * @author : Shintaro Inagaki
 * @param $geopo (String)
 * @return $location (Array)
 */
function geopoDecode($geopo) {
	// 64characters (number + big and small letter + hyphen + underscore)
	$chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
	// Array for geolocation
	$location = array ();

	for ($i = 0; $i < strlen($geopo); $i++) {
		// What number of character that equal to a GeoPo code (0-63)
		$order = strpos($chars, substr($geopo, $i, 1));
		// Lat/Lng plus geolocation value of scale 
		$location['lat'] = $location['lat'] + floor($order % 8) * pow(8, 9 - $i);
		$location['lng'] = $location['lng'] + floor($order / 8) * pow(8, 9 - $i);
	}

	// Change a decimal number to a degree measure, and plus revised value that shift center of area
	$location['lat'] = $location['lat'] * 180 / pow(8, 10) + 180 / pow(8, strlen($geopo)) / 2 - 90;
	$location['lng'] = $location['lng'] * 360 / pow(8, 10) + 360 / pow(8, strlen($geopo)) / 2 - 180;
	$location['scale'] = strlen($geopo);

	return $location;
}		

3. C++


/*
 * GeoPo Encode in C++
 * @author : Shintaro Inagaki
 * @param geopo, lat lng, scale (pointer)
 */
void geopoEncode(char *geopo, double &lat, double &lng, int &scale)
{
	// 64characters (number + big and small letter + hyphen + underscore)
	char chars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
	int i;

	// Change a degree measure to a decimal number
	lat = (lat + 90) / 180 * pow(8.0, 10.0);
	lng = (lng + 180) / 360 * pow(8.0, 10.0);

	// Compute a GeoPo code from head and concatenate
	for(i = 0;i < scale;i++){
		geopo[i] = chars[(int)(floor(fmod(lat / pow(8.0, 9.0 - i), 8.0)) + floor(fmod(lng / pow(8.0, 9.0 - i), 8.0)) * 8)];
	}
	geopo[i] = '\0';
}		

/*
 * GeoPo Decode in C++
 * @author : Shintaro Inagaki
 * @param geopo, lat lng, scale (pointer)
 */
void geopoDecode(char *geopo, double &lat, double &lng, int &scale)
{
	// 64characters (number + big and small letter + hyphen + underscore)
	char chars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
	int order, i;

	scale = strlen(geopo);

	for(i = 0;i < scale;i++){
		// What number of character that equal to a GeoPo code (0-63)
		order = (strchr(chars, geopo[i]) - chars);
		// Lat/Lng plus geolocation value of scale 
		lat = lat + fmod(order, 8.0) * pow(8.0, 9.0 - i);
		lng = lng + floor((double)order / 8.0) * pow(8.0, 9.0 - i);
	}
	// Change a decimal number to a degree measure, and plus revised value that shift center of area
	lat = lat * 180 / pow(8.0, 10.0) - 90 + 180 / pow(8.0, scale) / 2;
	lng = lng * 360 / pow(8.0, 10.0) - 180 + 360 / pow(8.0, scale) / 2;
}		

Caution:use standard library "stdio.h", "math.h" and "string.h"

4. Objective-C


/*
 * GeoPo Encode in Objective-C
 * @author : Shintaro Inagaki
 * @param geopo, latitude, longitude, scale (pointer)
 */
-(void)encodeGeopo:(id)geopo latitude:(double *)lat longitude:(double *)lng scale:(int *)scale {
	NSString *chars = @"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
	
	*lat = (*lat + 90) / 180 * pow(8.0, 10.0);
	*lng = (*lng + 180) / 360 * pow(8.0, 10.0);
	
	for(int i = 0; i < *scale; i++){
		[geopo appendString:[chars substringWithRange:NSMakeRange(floor(fmod(*lat / pow(8.0, 9.0 - i), 8.0)) + floor(fmod(*lng / pow(8.0, 9.0 - i), 8.0)) * 8, 1)]];
	}
}		

/*
 * GeoPo Decode in Objective-C
 * @author : Shintaro Inagaki
 * @param geopo, latitude, longitude, scale (pointer)
 */
-(void)decodeGeopo:(id)geopo latitude:(double *)lat longitude:(double *)lng scale:(int *)scale {
	NSString *chars = @"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
	int order;

	*scale = [geopo length];
	
	for (int i = 0; i < *scale; i++) {
		order = NSMaxRange([chars rangeOfString:[geopo substringWithRange:NSMakeRange(i, 1)]]) - 1;
		*lat += (order % 8) * pow(8, 9 - i);
		*lng += floor(order / 8) * pow(8, 9 - i);
	}
	
	*lat = *lat * 180 / pow(8, 10) + 180 / pow(8, *scale) / 2 - 90;
	*lng = *lng * 360 / pow(8, 10) + 360 / pow(8, *scale) / 2 - 180;
}		

5. Perl


#
# GeoPo Encode in Perl
# @author : Shintaro Inagaki
# @param %location (Hash) [lat (Float), lng (Float), scale(Int)]
# @return $geopo (String)
#
sub geopoEncode(%location) {
	# 64characters (number + big and small letter + hyphen + underscore)
	$chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";

	$geopo = "";
	$lat = $location{'lat'};
	$lng = $location{'lng'};
	$scale = $location{'scale'};

	# Change a degree measure to a decimal number
	$lat = ($lat + 90) / 180 * 8 ** 10;
	$lng = ($lng + 180) / 360 * 8 ** 10;

	# Compute a GeoPo code from head and concatenate
	for($i = 0; $i < $scale; $i++) {
		$geopo .= substr($chars, int($lat / 8 ** (9 - $i) % 8) + int($lng / 8 ** (9 - $i) % 8) * 8, 1);
	}
	return $geopo;
}		

#
# GeoPo Decode in Perl
# @author : Shintaro Inagaki
# @param $geopo (String)
# @return %location (Hash) [lat (Float), lng (Float), scale(Int)]
#
sub geopoDecode($geopo) {
	# 64characters (number + big and small letter + hyphen + underscore)
	$chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
	# Hash for geolocation
	%location = ();

	for ($i = 0; $i < length($geopo); $i++) {
		# What number of character that equal to a GeoPo code (0-63)
		$order = index($chars, substr($geopo, $i, 1));
		# Lat/Lng plus geolocation value of scale 
		$location{'lat'} += $order % 8 * 8 ** (9 - $i);
		$location{'lng'} += int($order / 8) * 8 ** (9 - $i);
	}

	# Change a decimal number to a degree measure, and plus revised value that shift center of area
	$location{'lat'} = $location{'lat'} * 180 / 8 ** 10 - 90 + 180 / 8 ** length($geopo) / 2;
	$location{'lng'} = $location{'lng'} * 360 / 8 ** 10 - 180 + 360 / 8 ** length($geopo) / 2;
	$location{'scale'} = length($geopo);

	return %location;
}		

6. Ruby


#
# GeoPo Encode in Ruby
# @author : Shintaro Inagaki
# @param location (Hash) [lat (Float), lng (Float), scale(Int)]
# @return geopo (String)
#
def geopoEncode(location)
	# 64characters (number + big and small letter + hyphen + underscore)
	chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"
	
	geopo = ""
	lat = location['lat']
	lng = location['lng']
	scale = location['scale']
	
	# Change a degree measure to a decimal number
	lat = (lat + 90.0) / 180 * 8 ** 10; # 90.0 is forced FLOAT type when lat is INT
	lng = (lng + 180.0) / 360 * 8 ** 10; # 180.0 is same

	# Compute a GeoPo code from head and concatenate
	for i in 0..scale
		geopo += chars[(lat / 8 ** (9 - i) % 8).floor + (lng / 8 ** (9 - i) % 8).floor * 8, 1];
	end
	return geopo;
end		

#
# GeoPo Decode in Ruby
# @author : Shintaro Inagaki
# @param geopo (String)
# @return location (Hash) [lat (Float), lng (Float), scale(Int)]
#
def geopoDecode(geopo)
	# 64characters (number + big and small letter + hyphen + underscore)
	chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"
	# Hash for geolocation
	location = {}

	lat = 0.0
	lng = 0.0
	scale = geopo.size # Scale is length of GeoPo code
	order = 0

	for i in 0..(scale - 1)
		# What number of character that equal to a GeoPo code (0-63)
		order = chars.index(geopo[i])
		# Lat/Lng plus geolocation value of scale
		lat = lat + order % 8 * 8 ** (9 - i)
		lng = lng + (order / 8).floor * 8 ** (9 - i)
	end

	# Change a decimal number to a degree measure, and plus revised value that shift center of area
	location['lat'] = lat * 180 / 8 ** 10 - 90 + 180 / 8 ** scale / 2
	location['lng'] = lng * 360 / 8 ** 10 - 180 + 360 / 8 ** scale / 2
	location['scale'] = scale

	return location
end		

Implemented in Ruby by id:faw. Thank you for coding.
http://d.hatena.ne.jp/faw/20090306/1236310192

7. Java


/**
 * GeoPo Encode in Java.
 *
 * @param lat latitude
 * @param lng longnitude
 * @param scale scale of map
 * @return geopo code
 */
public static String encode(double lat, double lng, int scale) {

    // 64characters (number + big and small letter + hyphen + underscore).
    final String chars =
            "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";

    StringBuffer geopo = new StringBuffer();

    lat = (lat + 90) / 180 * Math.pow(8, 10);
    lng = (lng + 180) / 360 * Math.pow(8, 10);

    for(int i = 0; i < scale; i++) {
        geopo.append(
                chars.charAt((int)(Math.floor(lat / Math.pow(8, 9 - i) % 8)
                        + Math.floor(lng / Math.pow(8, 9 - i) % 8) * 8)));
    }

    return geopo.toString();

}		

/**
 * GeoPo Decode in Java.
 *
 * @param geopo geopo code
 * @return latitude and longnitude
 */
public static double[] decode(String geopo) {

    // 64characters (number + big and small letter + hyphen + underscore).
    final String chars =
            "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";

    int scale = geopo.length();

    double[] loc = new double[2];
    loc[0] = 0;
    loc[1] = 0;

    for(int i = 0; i < scale; i++) {

        int order = chars.indexOf(geopo.charAt(i));

        loc[0] += Math.floor(order % 8) * Math.pow(8, 9 - i);
        loc[1] += Math.floor(order / 8) * Math.pow(8, 9 - i);

    }

    loc[0] = loc[0] * 180 / Math.pow(8, 10) - 90 + 180 / Math.pow(8, scale) / 2;
    loc[1] = loc[1] * 360 / Math.pow(8, 10) - 180 + 360 / Math.pow(8, scale) / 2;

    return loc;

}		

Above code was implemented in Java by takimura. Thank you for coding.

8. Python


#
# GeoPo Encode in Python
# @author : Shintaro Inagaki
# @param location (Dictionary) [lat (Float), lng (Float), scale(Int)]
# @return geopo (String)
#
def geopoEncode(location) :
       # 64characters (number + big and small letter + hyphen + underscore)
       chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"

       geopo = ""
       lat = location['lat']
       lng = location['lng']
       scale = location['scale']

       # Change a degree measure to a decimal number
       lat = (lat + 90.0) / 180 * 8 ** 10 # 90.0 is forced FLOAT type when lat is INT
       lng = (lng + 180.0) / 360 * 8 ** 10 # 180.0 is same

       # Compute a GeoPo code from head and concatenate
       for i in range(scale):
               order = int(lat / (8 ** (9 - i)) % 8) + int(lng / (8 ** (9 - i)) % 8) * 8
               geopo = geopo + chars[order]

       return geopo		

#
# GeoPo Decode in Python
# @author : Shintaro Inagaki
# @param geopo (String)
# @return location (Dictionary) [lat (Float), lng (Float), scale(Int)]
#
def geopoDecode(geopo) :
       # 64characters (number + big and small letter + hyphen + underscore)
       chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"

       lat = 0.0
       lng = 0.0
       scale = len(geopo) # Scale is length of GeoPo code
       order = 0

       for i in range(scale):
               # What number of character that equal to a GeoPo code (0-63)
               order = chars.find(geopo[i])
               # Lat/Lng plus geolocation value of scale
               lat = lat + order % 8 * 8 ** (9 - i)
               lng = lng + int(order / 8) * 8 ** (9 - i)

       # Change a decimal number to a degree measure, and plus revised value
that shift center of area
       location['lat'] = lat * 180 / 8 ** 10 - 90 + 180 / 8 ** scale / 2
       location['lng'] = lng * 360 / 8 ** 10 - 180 + 360 / 8 ** scale / 2
       location['scale'] = scale

       return location		

Implemented in Python by id:faw. Thank you for coding.
http://d.hatena.ne.jp/faw/20090306/1236306272

10. Excel


GeoPo Encode in Excel function

Following "[]" means location of cell (ex. A1,B4)

[latitude] is location of latitude entry cell
[longitude] is location of longitude entry cell
[chars] is location of characters to use encoding entry cell and
enter "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"
(exclude "")

Enter the cell of display 1st GeoPo code
"=MID([chars],INT(MOD(([latitude]+90)/180*POWER(8,10)/POWER(8,9),8))+INT(MOD(([longitude]+180)/360*POWER(8,10)/POWER(8,9),8))*8+1,1)"
by the same token,
"=MID([chars],INT(MOD(([latitude]+90)/180*POWER(8,10)/POWER(8,8),8))+INT(MOD(([longitude]+180)/360*POWER(8,10)/POWER(8,8),8))*8+1,1)"
2nd argument of POWER minus 1 is 2nd GeoPo code, and repeat after 2nd character.

Then, you can make GeoPo code characters to combine these GeoPo code cells using by "&"

(Ex.)
A1 is latitude, B1 is longintude and C1 is characters to use encoding
Enter "=MID(C1,INT(MOD((A1+90)/180*POWER(8,10)/POWER(8,9),8))+INT(MOD((B1+180)/360*POWER(8,10)/POWER(8,9),8))*8+1,1)" at A2
Enter "=MID(C1,INT(MOD((A1+90)/180*POWER(8,10)/POWER(8,8),8))+INT(MOD((B1+180)/360*POWER(8,10)/POWER(8,8),8))*8+1,1)" at B2
Enter "=MID(C1,INT(MOD((A1+90)/180*POWER(8,10)/POWER(8,7),8))+INT(MOD((B1+180)/360*POWER(8,10)/POWER(8,7),8))*8+1,1)" at C2
Enter "=MID(C1,INT(MOD((A1+90)/180*POWER(8,10)/POWER(8,6),8))+INT(MOD((B1+180)/360*POWER(8,10)/POWER(8,6),8))*8+1,1)" at D2
Enter "=MID(C1,INT(MOD((A1+90)/180*POWER(8,10)/POWER(8,5),8))+INT(MOD((B1+180)/360*POWER(8,10)/POWER(8,5),8))*8+1,1)" at E2
Enter "=MID(C1,INT(MOD((A1+90)/180*POWER(8,10)/POWER(8,4),8))+INT(MOD((B1+180)/360*POWER(8,10)/POWER(8,4),8))*8+1,1)" at F2
Enter "=A2&B2&C2&D2&E2&F2" at A3, A3 display 6 characters GeoPo code.
		

GeoPo Decode in Excel function

Following "[]" means location of cell (ex. A1,B4)

[GeoPo] is location of GeoPo code entry cell
[chars] is location of characters to use encoding entry cell and
enter "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"
(exclude "")
Scale is 6 characters for descriptive purposes.

Enter the cell of display latitude
"=MOD(FIND(MID([GeoPo],1,1),[chars])-1,8)*POWER(8,9)+MOD(FIND(MID([GeoPo],2,1),[chars])-1,8)*POWER(8,8)+MOD(FIND(MID([GeoPo],3,1),[chars])-1,8)*POWER(8,7)+MOD(FIND(MID([GeoPo],4,1),[chars])-1,8)*POWER(8,6)+MOD(FIND(MID([GeoPo],5,1),[chars])-1,8)*POWER(8,5)+MOD(FIND(MID([GeoPo],6,1),[chars])-1,8)*POWER(8,4)"
Enter the cell of display longitude
"=(INT((FIND(MID([GeoPo],1,1),[chars])-1)/8)*POWER(8,9)+INT((FIND(MID([GeoPo],2,1),[chars])-1)/8)*POWER(8,8)+INT((FIND(MID([GeoPo],3,1),[chars])-1)/8)*POWER(8,7)+INT((FIND(MID([GeoPo],4,1),[chars])-1)/8)*POWER(8,6)+INT((FIND(MID([GeoPo],5,1),[chars])-1)/8)*POWER(8,5)+INT((FIND(MID([GeoPo],6,1),[chars])-1)/8)*POWER(8,4))*360/POWER(8,10)+360/POWER(8,6)/2-180"

(Ex.)
A3 is 6 characters GeoPo code and C1 is characters to use encoding
Enter "=(MOD(FIND(MID(A3,1,1),C1)-1,8)*POWER(8,9)+MOD(FIND(MID(A3,2,1),C1)-1,8)*POWER(8,8)+MOD(FIND(MID(A3,3,1),C1)-1,8)*POWER(8,7)+MOD(FIND(MID(A3,4,1),C1)-1,8)*POWER(8,6)+MOD(FIND(MID(A3,5,1),C1)-1,8)*POWER(8,5)+MOD(FIND(MID(A3,6,1),C1)-1,8)*POWER(8,4))*180/POWER(8,10)+180/POWER(8,6)/2-90" at A1
Enter "=(INT((FIND(MID(A3,1,1),C1)-1)/8)*POWER(8,9)+INT((FIND(MID(A3,2,1),C1)-1)/8)*POWER(8,8)+INT((FIND(MID(A3,3,1),C1)-1)/8)*POWER(8,7)+INT((FIND(MID(A3,4,1),C1)-1)/8)*POWER(8,6)+INT((FIND(MID(A3,5,1),C1)-1)/8)*POWER(8,5)+INT((FIND(MID(A3,6,1),C1)-1)/8)*POWER(8,4))*360/POWER(8,10)+360/POWER(8,6)/2-180" at B1
A1 display latitude and B1 display longitude.