将GPS纬度/经度从不同格式转换为一种格式(在PHP中)

Dav*_*ave 5 php gps geolocation

我正在尝试建立对我的应用程序中的位置的支持,并且我期望用户以各种方式输入gps坐标.我需要将以下所有内容转换为:纬度 - 方向(N/s),degres,分钟,秒; 经度(E/W) - 度,小时,秒.

注意,每个用户输入将在一行中.我希望我的用户只能以一种方式输入,但是ppl肯定会输入以下内容之一...:

例如:9.182,-39.140625
9.182/-39.140625
9.182,-39.140625
9.182 -39.140625
21°16'672S [some_separator] 27°30'218E
21 16 674S [some_separator] 27 30 318E

[some_separator]也可能是一个单一的空间......

最终格式需要为:
latitude.direction = south
latitude.degrees = 21
latitude.minutes = 16
latitude.seconds = 674
longitude.direction = east
longitude.degrees = 27
longitude.minutes = 30
longitude.seconds = 318

(a)要求普通非科技用户输入GPS坐标的最简单方法是什么?
(b)如何将上述内容转换为最终格式?任何处理数据输入变化的内置函数?

在PHP中看过GPS格式 - 但我需要处理更多变化的输入.

Luk*_*son 11

我一直在努力解决这个问题(我注意到你编辑了你的问题).

A)要求普通非技术用户输入GPS坐标的最简单方法是什么?

让非技术用户输入详细信息的最简单,最友好的方式是使用谷歌地图.这将允许您使用Google Geocoder解析其输入(并提供更标准化和格式化的输出).此外,如果用户输入的位置是他们当前的位置,您可以查看使用某些现代浏览器提供的地理位置功能.

B)我如何将上述转换为最终格式?任何处理数据输入变化的内置函数?

根据您的测试数据,我制定了一个PHP正则表达式来解析它并返回一个可预测的标准化输出.

$rexp = '/^(\-?\d+(?:\.\d+)?)(?:\D+(\d+)\D+(\d+)([NS]?))?[^\d\-]+(\-?\d+(?:\.\d+)?)(?:\D+(\d+)\D+(\d+)([EW]?))?$/i';

$data = array(
  "21° 16' 674S, 27° 30' 318E" ,
  '21 16 674S, 27 30 318E' ,
  '9.182, -39.140625' ,
  '9.182 / -39.140625' ,
  '9.182,-39.140625' ,
  '9.182 -39.140625'
);

foreach( $data as $test ) {
  if( !preg_match( $rexp , $test , $matches ) ) {
    echo '<b>Failed</b>';
  } else {
    // Match Found
  }
}
Run Code Online (Sandbox Code Playgroud)

输出:

array(
  [0] => Matched Text ,
  [1] => Full Degrees ,
  [2] => Minutes ,
  [3] => Seconds ,
  [4] => Hemisphere (N or S) ,
  [5] => Full Degrees ,
  [6] => Minutes ,
  [7] => Seconds ,
  [8] => Hemisphere (E or W)
)
Run Code Online (Sandbox Code Playgroud)

例:

// Matching 21° 16' 674S, 27° 30' 318E
array(
  [0] => "21° 16' 674S, 27° 30' 318E" ,
  [1] => "21" , [2] => "16" , [3] => "674" , [4] => "S" ,
  [5] => "27" , [6] => "30" , [7] => "318" , [8] => "E"
)

// Matching 21 16 674S, 27 30 318E
array(
  [0]=> "21 16 674S, 27 30 318E" ,
  [1]=> "21" , [2]=> "16" , [3]=> "674" , [4]=> "S" ,
  [5]=> "27" , [6]=> "30" , [7]=> "318" , [8]=> "E"
)

// Matching 9.182, -39.140625
array(
  [0]=> "9.182, -39.140625" ,
  [1]=>   "9.182" ,    [2]=> "" , [3]=> "" , [4]=> "" ,
  [5]=> "-39.140625" , [6]=> "" , [7]=> "" , [8]=> ""
)

// Matching 9.182 / -39.140625
array(
  [0]=> "9.182 / -39.140625" ,
  [1]=>   "9.182" ,    [2]=> "" , [3]=> "" , [4]=> "" ,
  [5]=> "-39.140625" , [6]=> "" , [7]=> "" , [8]=> ""
)

// Matching 9.182,-39.140625
array(
  [0]=> "9.182,-39.140625" ,
  [1]=>   "9.182" ,    [2]=> "" , [3]=> "" , [4]=> "" ,
  [5]=> "-39.140625" , [6]=> "" , [7]=> "" , [8]=> ""
)

// Matching 9.182 -39.140625
array(
  [0]=> "9.182 -39.140625" ,
  [1]=>   "9.182" ,    [2]=> "" , [3]=> "" , [4]=> "" ,
  [5]=> "-39.140625" , [6]=> "" , [7]=> "" , [8]=> ""
)
Run Code Online (Sandbox Code Playgroud)

然后,您可以随后处理正则表达式的结果,以生成Lat/Long链接的浮点数,以便:

// (Replacing the "Match Found" comment)
  $latitude  = $matches[1]+((int)$matches[2]/60)+((int)$matches[3]/3600)*(strtolower($matches[4])=='s'?-1:1);
  $longitude = $matches[5]+((int)$matches[6]/60)+((int)$matches[7]/3600)*(strtolower($matches[8])=='w'?-1:1);
Run Code Online (Sandbox Code Playgroud)

哪个产生:

// Matching 21° 16' 674S, 27° 30' 318E
$latitude  = -21.4538888889
$longitude =  27.5883333333

// Matching 21 16 674S, 27 30 318E
$latitude  = -21.4538888889
$longitude =  27.5883333333

// Matching 9.182, -39.140625
$latitude  =   9.182
$longitude = -39.140625

// Matching 9.182 / -39.140625
$latitude  =   9.182
$longitude = -39.140625

// Matching 9.182,-39.140625
$latitude  =   9.182
$longitude = -39.140625

// Matching 9.182 -39.140625
$latitude  =   9.182
$longitude = -39.140625
Run Code Online (Sandbox Code Playgroud)