<?php
function geoCodeiPhone($location) {
// see if there are coordinates in the location, ie. "iPhone: 52.043900,5.555832". if so, use those coordinates as lat & lng
// translate coordinates to english
$translate = array(
'NB' => 'N',
'OL' => 'E',
'O' => 'E',
);
$location = str_replace(array_keys($translate), array_values($translate), $location);
// grab the coordinates out from the location
preg_match_all(
'/\s*
(?<!\d)
(\d{1,3}(?:[,.]\d+)?)
[^\d\snwes]*
(?:
\s*
(\d{1,2}(?:[,.]\d+)?)
[^\d\snwes]*
(?:
\s*
(\d{1,2}(?:[,.]\d+)?)
[^\d\snwe]*
)?
)?
[\s-]*([nwes])
|
(?<!\d)
(?:([nwes-]?)\s*)
(\d{1,3}(?:[,.]\d+)?)
(?:
[^\d,]+\s*
(\d{1,2}(?:[,.]\d+)?)
[^\d\s]*
(?:
\s*
(\d{1,2}(?:[,.]\d+)?)
[^\d\s]*
)?
)?
(?!\d)/imx'
,$location, $coords, PREG_SET_ORDER);
// look for the various bits in the matches and combine them as needed
foreach ($coords as $i => $coord) {
$val = 999; // set to some number that will throw a false below
// pad the array so we don't throw any notices
$coord = array_pad($coord, 10, '');
// check for DMS value with trailing cardinal point
if ('' !== (string) $coord[1]) {
$val = DMS2dec($coord[1], $coord[2], $coord[3], $coord[4]);
}
// check for DMS value with leading cardinal point (or signed decimal)
if ('' !== (string) $coord[6]) {
$val = DMS2dec($coord[6], $coord[7], $coord[8], $coord[5]);
}
// store the value in the proper coordinate
if (0 == $i) {
$lat = $val;
}
else {
$lng = $val;
}
}
$invalid_coords = isset($coords[2]); // more than two full matches, something is wrong
$invalid_lat = ( ! isset($lat) || ( -90 > $lat) || ( 90 < $lat));
$invalid_lng = ( ! isset($lng) || (-180 > $lng) || (180 < $lng));
if ($invalid_coords || $invalid_lat || $invalid_lng) {
return false;
}
return array($lng, $lat);
}
function DMS2dec($deg, $min = 0, $sec = 0, $card = '') {
// convert all inputs to floats
$deg = (float) str_replace(',', '.', trim($deg));
$min = (float) str_replace(',', '.', trim($min));
$sec = (float) str_replace(',', '.', trim($sec));
// make value positive if we need to
if (0 > $deg) {
$deg = -$deg;
$card = '-';
}
// convert to decimal value
$dec = $deg;
$dec += $min / 60;
$dec += $sec / (60 * 60);
// adjust value according to cardinal point
if (in_array(strtoupper(trim($card)), array('S', 'W', '-'))) {
$dec = -$dec;
}
return $dec;
}
var_dump(geoCodeiPhone('iPhone: -52.043900,-5.555832'));
var_dump(geoCodeiPhone('34.3330°S, 150.9170°E'));
var_dump(geoCodeiPhone('-34.3330°, 150.9170°'));
var_dump(geoCodeiPhone('N 52°35\' 0" / W 2°1\' 0"'));
var_dump(geoCodeiPhone('N 35 32 4.678 W 124 23 18.234'));
var_dump(geoCodeiPhone('N 35 32 4,678 W 124 23 18,234'));
var_dump(geoCodeiPhone('- 35 32.678 - 124 23.234'));
var_dump(geoCodeiPhone('45 Reseda, Ca. 01335'));
var_dump(geoCodeiPhone('Reseda, Ca. 91335'));
var_dump(geoCodeiPhone('38d 33m 06.32sN 121d 29m 04.75'));
var_dump(geoCodeiPhone('Pre: 39.8714500,-105.01943'));
var_dump(geoCodeiPhone('51° 50\' North 006°50\' East'));
var_dump(geoCodeiPhone('35°29\'18.15?N 76°37\'06.18W'));
var_dump(geoCodeiPhone('52°15\' NB 6°9\' OL'));
var_dump(geoCodeiPhone('53°15\'10.69"N 5°15\'6.87"O'));
var_dump(geoCodeiPhone('+29° 35\' 3.6, -95° 13\' 45.1'));
var_dump(geoCodeiPhone('40° 0\' N 105° 16\' W'));
var_dump(geoCodeiPhone('Hengelo, 52.2670°N, 6.8000°E'));
var_dump(geoCodeiPhone('35°57\'17.10 N, 84°06\'03.79 W'));
var_dump(geoCodeiPhone('30°19?10?N 81°39?36?'));
var_dump(geoCodeiPhone('1.3819056°N 103.8448167°E'));
var_dump(geoCodeiPhone('1°16\'S & 36°48\'E'));
var_dump(geoCodeiPhone('ÜT: 52.07764,4.35581'));
var_dump(geoCodeiPhone('ÜT: 52,07764,4,35581'));
var_dump(geoCodeiPhone('51°14\'0.93N, 0°10\'2.60W'));