Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

converting GPS latitude/longitude from different formats to one format (in PHP)

i'm trying to built in support for locations in my application and i'm expecting users to be inputting gps coordinates in a variety of ways. I need to convert all of the below to: latitude - direction (N/s), degres, minutes, seconds; longitude (E/W) - degrees, minuts, seconds.

Note, each user input will be in a single line. I would like my users to input only in one single way, but ppl will definitely enter as one of the following...:

eg: 9.182, -39.140625
9.182 / -39.140625
9.182,-39.140625
9.182 -39.140625
21° 16' 674S[some_separator]27° 30' 318E
21 16 674S[some_separator]27 30 318E

[some_separator] may be a single space as well...

The final format needs to beas:
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) what is the simplest way of asking ordinary-non-tech users to input the GPS coordinate?s
(b) how do i convert the above to the final format? any built in functions that handle these variations in data input?

i've seen GPS format in PHP - but i need to handle a more varied input.

like image 330
Dave Avatar asked Jun 16 '10 10:06

Dave


People also ask

What are the different formats for latitude and longitude?

The numbers are in decimal degrees format and range from -90 to 90 for latitude and -180 to 180 for longitude. For example, Washington DC has a latitude 38.8951 and longitude -77.0364 . In API calls you will often see the numbers placed together and separated by a comma: -77.0364,38.8951 .


2 Answers

I have been working around with this further (and I notice that you edited your question).

A) What is the simplest way of asking ordinary-non-tech users to input the GPS coordinates?

The simplest, and most user friendly fashion for getting non-tech users to enter details would be using Google Maps. This would allow for you to use the Google Geocoder to parse their input (and provide a more standardised and formatted output). Further, if the location the user is inputting is their current location, you could look at using the Geolocation functionality offered by some of the modern browsers.

B) How do i convert the above to the final format? Any built in functions that handle these variations in data input?

Based on your test data, I have formulated a PHP Regular Expression to parse it and return a predictable and standardised output.

$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
  }
}

Outputs:

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)
)

Example:

// 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]=> ""
)

You could then, subsequently, process the results of the Regular Expression, to produce a float for the Lat/Long link so:

// (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);

Which produces:

// 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
like image 198
Luke Stevenson Avatar answered Sep 28 '22 16:09

Luke Stevenson


I think the best way would be to restrict user input as much as possible, so that they may only enter valid data. Have the user separate the data in tokens for you, instead of you trying to account for every single possibility. Use as many textboxes/drop downs/etc as necessary to force the user to populate the data correctly. I think it would be desirable to minimize the amount & variations of text parsing you will be doing.

What format do the users get their data in? If it is just a decimal lat/long e.g(50.32,123.55) then just simply have two numerical inputs they can fill out, and possibly include an example value in the box. If the users get their data in degree/minute/second format then have exactly these fields that they need to fill out for each latitude and longitude. If you allow for both decimal & degree representations it should cover all your users.

Have as many inputs as needed to break down the data in enough tokens that ensures consistency when interpreting it in your program!

EDIT: A funky idea if you find it acceptable for your site would be to have a Google Map where the user drags a marker to their desired location. You can then get the GPS coordinates in a consistent manner from that marker, and use that for whatever further work you need to do!

like image 26
filip-fku Avatar answered Sep 28 '22 15:09

filip-fku