You can enter the GPS coordinates in two ways, Decimal Degrees or Degrees, Minutes, Seconds :
┌─────────────────────────────────┬─────────────────────┐
│ DMS (Degrees, Minutes, Seconds) │ DD (Decimal Degree) │
┌───────────┼─────────────────────────────────┼─────────────────────┤
│ Latitude │ N 40° 11′ 48.055″ │ 40.196682 │
├───────────┼─────────────────────────────────┼─────────────────────┤
│ Longitude │ W 8° 25′ 52.134″ │ -8.431149 │
└───────────┴─────────────────────────────────┴─────────────────────┘
These values have to be treated so that they remain in a single format for conversion between them, as well as for storage in the database.
The problem is in the DMS format, where the coordinates entered can vary from several digits, different references to the hemisphere to the characters that identify the separation between the values.
To facilitate, the introduction of the coordinates, it is divided into two fields, Latitude and Longitude, and the spaces are blocked, which gives us:
┌─────────────────────────────────┬─────────────────────┐
│ DMS (Degrees, Minutes, Seconds) │ DD (Decimal Degree) │
┌───────────┼─────────────────────────────────┼─────────────────────┤
│ Latitude │ N40°11′48.055″ │ 40.196682 │
├───────────┼─────────────────────────────────┼─────────────────────┤
│ Longitude │ W8°25′52.134″ │ -8.431149 │
└───────────┴─────────────────────────────────┴─────────────────────┘
In operation
I'm trying to extract the value in degrees, minutes, and seconds to an array, so I can convert it to decimal format, but I find the whole process a little too long and susceptible to crashes: p>
Code
Assuming that the variable $entity_gps
contains N40°11'43.44" W8°25'1.31"
:
Note: The values, although entered separately, are stored in a single field separated by a space.
$coordinatesArr = array(
"lat" => array(
"hem" => '',
"deg" => '',
"min" => '',
"sec" => ''
),
"lng" => array(
"hem" => '',
"deg" => '',
"min" => '',
"sec" => ''
)
);
if ($entity_gps!='') {
$gpsArr = explode(' ', $entity_geo->gps);
if (is_array($gpsArr)) {
$i = 0;
foreach ($gpsArr as $str) {
// Extract hemisphere
$hemisphere = mb_substr($str, 0, 1, 'UTF-8');
// Validate hemisphere
if (ctype_alpha($hemisphere)) {
/* Store hemisphere
*/
if ($i==0) {
$coordinatesArr["lat"]["hem"] = $hemisphere;
} else {
$coordinatesArr["lng"]["hem"] = $hemisphere;
}
// Extract degrees
$degree = mb_substr($str, 1, mb_strpos($str, '°')-1, 'UTF-8');
// Validate degrees
if (ctype_digit($degree)) {
/* Store degrees
*/
if ($i==0) {
$coordinatesArr["lat"]["deg"] = $degree;
} else {
$coordinatesArr["lng"]["deg"] = $degree;
}
// Extract minutes
$iniPos = mb_strpos($str, '°')+1;
$minutes = mb_substr($str, $iniPos, mb_strpos($str, "'")-$iniPos, 'UTF-8');
// Validate minutes
if (ctype_digit($minutes)) {
/* Store minutes
*/
if ($i==0) {
$coordinatesArr["lat"]["min"] = $minutes;
} else {
$coordinatesArr["lng"]["min"] = $minutes;
}
// Extract seconds
$iniPos = mb_strpos($str, "'")+1;
$seconds = mb_substr($str, $iniPos, mb_strpos($str, '"')-$iniPos, 'UTF-8');
// Validate seconds
if ($seconds!='') {
/* Store seconds
*/
if ($i==0) {
$coordinatesArr["lat"]["sec"] = $seconds;
} else {
$coordinatesArr["lng"]["sec"] = $seconds;
}
} else {
echo 'Erro ao identificar os segundos!';
}
} else {
echo 'Erro ao identificar os minutos!';
}
} else {
echo 'Erro ao identificar os graus!';
}
} else {
echo "Erro ao identificar o hemisfério!";
}
$i++;
}
}
}
Result:
Result when you make a var_dump()
to the array $coordinatesArr
, it contains the values as expected:
array(2) {
["lat"]=>
array(4) {
["hem"]=>
string(1) "N"
["deg"]=>
string(2) "40"
["min"]=>
string(2) "11"
["sec"]=>
string(5) "43.44"
}
["lng"]=>
array(4) {
["hem"]=>
string(1) "W"
["deg"]=>
string(1) "8"
["min"]=>
string(2) "25"
["sec"]=>
string(4) "1.31"
}
}
Problem
In addition to the density of code, which can be passed to individual functions, there are a number of problems mainly caused by the separators entered by the user.
Likewise, this check is to be reused when processing GPS coordinates in DMS format from other sources.
- Instead of
°
another one is present. - Instead of
'
´
or other is present. - Instead of
"
¨
or other is present.
Question
How can I simplify and refine the result of this code in order to convert the GPS coordinates in DMS format into an array?