User:Amake/gmcoords.php

From Wikipedia, the free encyclopedia

gmcoords.php is a PHP script that fetches coordinates from Google Maps and formats them for inclusion on Wikipedia articles. It is meant to be run locally from the command line. A variant of this script is used by my bot JMuniBot to semi-automatically tag Japanese municipality articles with geodata.

Notes[edit]

  • Usage: gmcoords.php [d|dm|dms] query
  • The first argument is the desired accuracy: degrees, minutes, seconds
  • On Mac OS X and Linux systems, it puts the resulting string in your clipboard for easy pasting, assuming you have pbcopy (part of the OS X developer tools) or xclip installed. Otherwise it goes to stdout.
  • If you'd like to try it out
    1. copy and paste the code below into a text file on your machine,
    2. make the file executable (chmod u+x gmcoords.php)
    3. run the file from the command line as suggested above.
  • However, it won't work as-is; you must get your own Google Maps API key at http://www.google.com/apis/maps/signup.html and insert it for the value of the $key variable.
  • You also need the cURL module for PHP. This may already be supplied with your PHP package.
  • The default case assumes the following:
    • The query is for a town, city, or village
    • The town, city, or village is in Japan
    • The appropriate precision for these cases is degrees+minutes

Example usage[edit]

user@mybox:~$ ./gmcoords.php 由仁町役場

Querying google for 由仁町役場 ... done
Copying to X11 pasteboard: {{coor title dm|43|0|N|141|47|E|region:JP_type:city}}

I typically query for city halls (市役所) or town/village offices (町役場 or 村役場). Google usually has coordinates for these, except in the cases of (relatively) recently merged or renamed towns. In those cases I query the address listed on the ja: page; if that still doesn't work, I figure out which of the merged towns' offices became the new town office, and query that one.

Code[edit]

#!/usr/bin/php -f

<?php

$usage = "Usage: $argv[0] [d|dm|dms] query\n";
$debug = true;

$key = 'GOOGLE MAPS API KEY GOES HERE';

// Handle arguments
if (count($argv) == 3) {
	$accuracy = $argv[1];
	switch ($accuracy) {
		case 'd':
		case 'dm':
		case 'dms':	break;
		default: 	die($usage);
	}
	$query = $argv[2];
} elseif (count($argv) == 2) {
	$query = $argv[1];
	// Default to degrees+minutes
	$accuracy = 'dm';
} else {
	die($usage);
}

// Perform query (requires cURL module for PHP)
$query = str_replace(' ', '+', $query);
$ch = curl_init("http://maps.google.com/maps/geo?q=$query&output=csv&key=$key");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
echo 'Querying google for ' . $query . ' ... ';
$reply = curl_exec($ch);
echo "done\n";

if ($debug) echo "Google returned: $reply\n";

$coords = explode(',', $reply);

// Handle errors from Google
switch ($coords[0]) {
	case 602:	die("Query not found\n");
	case 610:	die("Bad API key.  Get one at http://www.google.com/apis/maps/signup.html\n");
}

// Google returns (blah),(blah),(N coord),(E coord) so remove first 2 items
array_shift($coords);
array_shift($coords);

// Convert decimal coords to dms
switch ($accuracy) {
	case 'd':	for ($i = 0; $i < 2; $i++) {
				$degrees[$i] = round($coords[$i]);
			}
			$wiki = "{{coor title d|$degrees[0]|N|$degrees[1]|E|region:JP_type:city}}";
			break;
	case 'dm':	for ($i = 0; $i < 2; $i++) {
				$degrees[$i] = (int) $coords[$i];
				// regular modulus (%) only works on ints
				$decimal1 = fmod($coords[$i], 1);
				$minutes[$i] = round($decimal1 * 60);
				if ($minutes[$i] == 60) {
					$minutes[$i] = '0';
					$degrees[$i]++;
				}
			}
			$wiki = "{{coor title dm|$degrees[0]|$minutes[0]|N|$degrees[1]|$minutes[1]|E|region:JP_type:city}}";
			break;
	case 'dms':	for ($i = 0; $i < 2; $i++) {
				$degrees[$i] = (int) $coords[$i];
				$decimal1 = fmod($coords[$i], 1);
				$minutes[$i] = (int) ($decimal1 * 60);
				$decimal2 = fmod($decimal1 * 60, 1);
				$seconds[$i] = round($decimal2 * 60);
				if ($seconds[$i] == 60) {
					$seconds[$i] = '0';
					$minutes[$i]++;
				}
				if ($minutes[$i] == 60) {
					$minutes[$i] = '0';
					$degrees[$i]++;
				}
			}
			$wiki = "{{coor title dms|$degrees[0]|$minutes[0]|$seconds[0]|N|$degrees[1]|$minutes[1]|$seconds[1]|E|region:JP_type:city}}";
			break;
	default:	die("Unknown error\n");
}

// Copy to pasteboard if available
if (exec("which xclip")) {
	echo "Copying to X11 pasteboard: $wiki\n";
	exec("echo -n \"$wiki\" | xclip -selection clipboard");
} elseif (exec("which pbcopy")) {
	echo "Copying to OS X pasteboard: $wiki\n";
	exec("echo -n \"$wiki\" | pbcopy");
} else {
	echo $wiki . "\n";
}

?>