# Thread: Distance calculation based on multiple locations including starting/ finishing point

1. ## Distance calculation based on multiple locations including starting/ finishing point

I would like to calculate the total distance of driving beetween multiple locations (loop), including the distance (starting point (garage) - first location sarting point) and (last location finishig point - finishing point (garage)). Example: (Garage + D1) + (D1 + D2) + (D2 + E1) + (E1 + E2) + E2 + Garage)

PHP Code:
<?
\$driver
5;

\$result2 mysql_query("SELECT * FROM test WHERE id='\$driver' LIMIT 1") or die(mysql_error());
while(
\$row2 mysql_fetch_array\$result2 )) {

\$lon=\$row2['lon'];

\$lat=\$row2['lat'];
echo
"\$lon\$lat";
}

\$result mysql_query("SELECT * FROM test1 WHERE driver='\$driver'") or die(mysql_error());
while(
\$row mysql_fetch_array\$result )) {

\$lon1=\$row['lon1'];

\$lat1=\$row['lat1'];

\$lon2=\$row['lon2'];

\$lat2=\$row['lat2'];

\$distancecalc = (3958*3.1415926*sqrt((\$lat-\$lat1)*(\$lat-\$lat1) + cos(\$lat/57.29578)*cos(\$lat1/57.29578)*(\$lon-\$lon1)*(\$lon-\$lon1))/180);

\$distancecalc1 \$distancecalc1 + (3958*3.1415926*sqrt((\$lat2-\$lat1)*(\$lat2-\$lat1) + cos(\$lat2/57.29578)*cos(\$lat1/57.29578)*(\$lon2-\$lon1)*(\$lon2-\$lon1))/180);

\$distancecalc2 = (3958*3.1415926*sqrt((\$lat2-\$lat)*(\$lat2-\$lat) + cos(\$lat2/57.29578)*cos(\$lat/57.29578)*(\$lon2-\$lon)*(\$lon2-\$lon))/180);

\$distancetotal \$distancecalc \$distancecalc1 +\$distancecalc2;

echo
"\$distancecalc<br>

\$distancecalc1<br>

\$distancecalc2<br>";
}
echo
"\$distancetotal";

?>
I'm aware that code posted above doesnt't do what it meant to .. i just want to keep it clear.. there is some things i tried but no correct resoults.

I would appreciate some help on this one.

Thank you very much.

2. Ok. I worked it out with help of mac_gyver (php freaks). All calculations are done as i wish. My code below:

<?
include "connectdb.php";
\$driver = 5;
\$datestamp = '2013/05/07';
\$result2 = mysql_query("SELECT * FROM drivers WHERE id='\$driver' LIMIT 1") or die(mysql_error());
while(\$row2 = mysql_fetch_array( \$result2 )) {
\$lon=\$row2['lon'];
\$lat=\$row2['lat'];
}

\$result = mysql_query("SELECT * FROM quotedb WHERE moveday='\$datestamp' AND driver='\$driver' AND cleared='Not Cleared' AND status='Done' ORDER BY moveday, timeday") or die(mysql_error());
\$distance = 0; // accumulate the distance
\$first_pass = true; // flag to detect the first row inside the loop
while(\$row = mysql_fetch_assoc( \$result )) {
\$lon2a=\$lon2;
\$lat2a=\$lat2;
\$lon1=\$row['lon1'];
\$lat1=\$row['lat1'];
\$lon2=\$row['lon2'];
\$lat2=\$row['lat2'];
// calculate the distance from the Garage to the first point of the first row
if(\$first_pass){
\$distance += (3958*3.1415926*sqrt((\$lat-\$lat1)*(\$lat-\$lat1) + cos(\$lat/57.29578)*cos(\$lat1/57.29578)*(\$lon-\$lon1)*(\$lon-\$lon1))/180);
\$first_pass = false;
}
// calculate the distance for each row (segment) in the route
\$distance += (3958*3.1415926*sqrt((\$lat2-\$lat1)*(\$lat2-\$lat1) + cos(\$lat2/57.29578)*cos(\$lat1/57.29578)*(\$lon2-\$lon1)*(\$lon2-\$lon1))/180);
if ( \$lon2a == "" or \$lat2a =="" ) {
} else {
// calculate the distance from the second point of the first row to the first point of the next row
\$distance += (3958*3.1415926*sqrt((\$lat2a-\$lat1)*(\$lat2a-\$lat1) + cos(\$lat2a/57.29578)*cos(\$lat1/57.29578)*(\$lon2a-\$lon1)*(\$lon2a-\$lon1))/180);
}
}
// calculate the distance from the second point of the last row to the Garage
\$distance += (3958*3.1415926*sqrt((\$lat2-\$lat)*(\$lat2-\$lat) + cos(\$lat2/57.29578)*cos(\$lat/57.29578)*(\$lon2-\$lon)*(\$lon2-\$lon))/180);
echo "\$distance<br>
";
?>
Still think there is a place for improvement in the code. Will aplay Haversine method for calculations. Do you guys have some suggestion to improve this piece of code ... thx

3. Hi nitapita,

There are a couple of things that you could do which I think would improve the readability of the code and make it easier to maintain.

1. Make the distance calculation into its own function:
PHP Code:
function calculate_distance(\$lon1\$lat1\$lon2\$lat2) {
return (
3958 3.1415926 sqrt((\$lat2 \$lat1) * (\$lat2 \$lat1) + cos(\$lat2 57.29578) * cos(\$lat1 57.29578) * (\$lon2 \$lon1) * (\$lon2 \$lon1)) / 180);

This avoids repeating the code, and means you only need to make the change once if you change how the calculation is done (or if there's a bug).

2. You can simplify your while loop:
PHP Code:
\$previous_lon \$garage_lon;
\$previous_lat \$garage_lat;
\$distance 0// accumulate the distance

while(\$row mysql_fetch_assoc\$result ))
{

\$lon1 \$row['lon1'];

\$lat1 \$row['lat1'];

\$lon2 \$row['lon2'];

\$lat2 \$row['lat2'];

if (
\$previous_lon && \$previous_lat )
{

// calculate the distance from the second point of the first row to the first point of the next row

\$distance += calculate_distance(\$lon1\$lat1\$previous_lon\$previous_lat);
}

// calculate the distance for each row (segment) in the route

\$distance += calculate_distance(\$lon1\$lat1\$lon2\$lat2);

\$previous_lon \$lon2;

\$previous_lat \$lat2;
}

// calculate the distance from the second point of the last row to the Garage
\$distance += calculate_distance(\$garage_lon\$garage_lat\$lon2\$lat2);
here, instead of checking if it's the first pass, you can set your previous latitude & longitude variables to the garage values before beginning the loop.

3. Instead of checking if variables are empty and then running some code in the else block:
PHP Code:
if ( \$lon2a == "" or \$lat2a =="" ) {
} else {

// calculate the distance from the second point of the first row to the first point of the next row

you can simplify it like this (php will return false if the variables are empty strings) and avoid the empty braces:
PHP Code:
if ( \$lon2a && \$lat2a )
{

// calculate the distance from the second point of the first row to the first point of the next row

4. In the code above, I've renamed several of the variables to make it clearer what they are - for example, \$lon2a and \$lat2a become \$previous_lon, and \$previous_lat.

4. Thanks a lot fretburner ! Good lesson. Applied the changes. It works.

5. PHP Code:
<?
include "connectdb.php";
\$driver 5;
\$datestamp '2013/05/07';
\$result2 mysql_query("SELECT * FROM drivers WHERE id='\$driver' LIMIT 1") or die(mysql_error());
while(
\$row2 mysql_fetch_array\$result2 )) {

\$garage_lon=\$row2['lon'];

\$garage_lat=\$row2['lat'];
}

\$result mysql_query("SELECT * FROM quotedb WHERE moveday='\$datestamp' AND driver='\$driver' AND cleared='Not Cleared' AND status='Done' ORDER BY moveday, timeday") or die(mysql_error());

function
calculate_distance(\$lon1\$lat1\$lon2\$lat2) {
return (
3958 3.1415926 sqrt((\$lat2 \$lat1) * (\$lat2 \$lat1) + cos(\$lat2 57.29578) * cos(\$lat1 57.29578) * (\$lon2 \$lon1) * (\$lon2 \$lon1)) / 180);}

\$previous_lon \$garage_lon;
\$previous_lat \$garage_lat;
\$distance 0// accumulate the distance

while(\$row mysql_fetch_assoc\$result ))
{

\$lon1 \$row['lon1'];

\$lat1 \$row['lat1'];

\$lon2 \$row['lon2'];

\$lat2 \$row['lat2'];
if (
\$previous_lon && \$previous_lat )
{

// calculate the distance from the starting point garage to the first point of the first row

\$distance += calculate_distance(\$lon1\$lat1\$previous_lon\$previous_lat);
}

// calculate the distance for each row (segment) in the route

\$distance += calculate_distance(\$lon1\$lat1\$lon2\$lat2);

\$previous_lon \$lon2;

\$previous_lat \$lat2;
}
// calculate the distance from the second point of the last row to the Garage
\$distance += calculate_distance(\$garage_lon\$garage_lat\$lon2\$lat2);

\$distance round(\$distance,0);
echo
"\$distance<br>
"
;

?>