SitePoint Sponsor

User Tag List

Results 1 to 5 of 5
  1. #1
    SitePoint Enthusiast
    Join Date
    May 2007
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    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'];

            
    //////////  distance between driver address and starting address    
            
    $distancecalc = (3958*3.1415926*sqrt(($lat-$lat1)*($lat-$lat1) + cos($lat/57.29578)*cos($lat1/57.29578)*($lon-$lon1)*($lon-$lon1))/180);
            
    //////////  distance between statring address and finishing address  - multiple adsresses
            
    $distancecalc1 $distancecalc1 + (3958*3.1415926*sqrt(($lat2-$lat1)*($lat2-$lat1) + cos($lat2/57.29578)*cos($lat1/57.29578)*($lon2-$lon1)*($lon2-$lon1))/180);
            
    //////////  distance between finishing address and driver address
            
    $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. #2
    SitePoint Enthusiast
    Join Date
    May 2007
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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. #3
    SitePoint Mentor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,256
    Mentioned
    32 Post(s)
    Tagged
    4 Thread(s)
    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. #4
    SitePoint Enthusiast
    Join Date
    May 2007
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks a lot fretburner ! Good lesson. Applied the changes. It works.

  5. #5
    SitePoint Enthusiast
    Join Date
    May 2007
    Posts
    44
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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>
    "
    ;
      
    ?>


Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •