0

我在 PHP 中有一个 foreach 循环,它从 GPX 文件中剔除数字并生成一个表格。

例如:

Distance | Elevation
--------------------
0        | 268
0.27     | 294
0.87     | 294
1.14     | 321
1.25     | 324
1.49     | 371
2.30     | 399
3.00     | 372
3.91     | 346

我想在海拔升高时加起来。所以,对于这张表:

增加:294 - 268 = 26, 294 - 294 = 0 (26), 321 - 294 = 27 (53), 324 - 321 = 3 (56).....等等

我还想计算它何时减少并将其分开以获得总增加和总高度减少。

所以,我基本上想问一下之前的每个数字是更高还是更低,然后根据它添加到一个变量中以备后用。

有任何想法吗?

我试图保持简单,但要求代码......提前道歉!

<?php
function objectsIntoArray($arrObjData, $arrSkipIndices = array())
{
    $arrData = array();

    // if input is object, convert into array
    if (is_object($arrObjData)) {
        $arrObjData = get_object_vars($arrObjData);
    }

    if (is_array($arrObjData)) {
        foreach ($arrObjData as $index => $value) {
            if (is_object($value) || is_array($value)) {
                $value = objectsIntoArray($value, $arrSkipIndices); // recursive call
            }
            if (in_array($index, $arrSkipIndices)) {
                continue;
            }
            $arrData[$index] = $value;
        }
    }
    return $arrData;
}

//$xmlUrl = "../wp-content/uploads/2012/11/stoodley-pike-walk-cragg-vale-withens-clough-circular.gpx"; // XML feed file/URL
$uploadyr = $_GET['yr'];
$uploadmth = $_GET['mth'];
$gpx = $_GET['gpx'];

$xmlUrl = "../wp-content/uploads/" . $uploadyr . "/" . $uploadmth . "/" . $gpx . ".gpx";
$xmlStr = file_get_contents($xmlUrl);
$xmlObj = simplexml_load_string($xmlStr);
$arrXml = objectsIntoArray($xmlObj);
?>

<!doctype html>
<head>
    <title>Graph</title>

    <!--<link href="visualize.css" rel="stylesheet">
    <link href="visualize-light.css" rel="stylesheet">-->
    <link href="visualize-override.css" rel="stylesheet">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>    
    <script src="visualize.jQuery.js"></script>
    <script>
        $(document).ready(function(){
            $('#elevation').visualize({
                type: 'area',
                parseDirection: 'y',
                colors: ['#339933','#00ff00','#0000ff','#ffff00','#ff00ff','#00ffff','#000000','#666666','#AAAAAA']
            });
            $('.visualize-labels-x li:odd').hide();
        });
    </script>
</head>

<body>

<div id="wrapper">

<?php

echo '<table id="elevation"><caption>Elevation Profile</caption><thead><td>Total Distance (mi)</td><th>Elevation</th></thead><tbody>';

foreach($arrXml["rte"]["rtept"] as $single){

        $lat1 = $prevLat;
        $lng1 = $prevLon;
        if($prevLat == null && $prevLon == null){
            $lat1 = $single["@attributes"]["lat"];
            $lng1 = $single["@attributes"]["lon"];
        }
        $lat2 = $single["@attributes"]["lat"];
        $lng2 = $single["@attributes"]["lon"];

        $pi80 = M_PI / 180;
        $lat1 *= $pi80;
        $lng1 *= $pi80;
        $lat2 *= $pi80;
        $lng2 *= $pi80;

        $r = 6372.797; // mean radius of Earth in km
        $dlat = $lat2 - $lat1;
        $dlng = $lng2 - $lng1;
        $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2);
        $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
        $km = $r * $c;

        $distance += $km;

        $buildrow = '';
        $buildrow .= '<tr>';     
        if($prevLat !== null && $prevLon !== null){
            $buildrow .= '<th>' . number_format(($miles ? ($distance * 0.621371192) : $distance),2) . '</th>';
        } else {
            $buildrow .= '<th>0</th>';
        }
        $buildrow .= '<td>' . number_format($single["ele"],0) . '</td>';
        $buildrow .= '</tr>';

        echo $buildrow;

    $prevLat = $single["@attributes"]["lat"];
    $prevLon = $single["@attributes"]["lon"];
}
echo '</tbody></table>';

echo '<p>Total Distance: ' . number_format($distance,2) . 'mi</p>';

?>

</div>

</body>

</html>
4

3 回答 3

1

您只需要在循环之前添加一个变量来保存之前的值。说$prevValue。然后在循环中,在循环结束时,将其设置为当前值。当循环运行下一个时,它将是前一个值。

然后,只需检查它是否大于或小于当前值。

if($val > $prevVal){}
elseif($val < $prevVal){}
于 2012-12-12T16:43:00.033 回答
1

这可以使用以下代码完成:

<?php
/**
 * Calculates elevation information for a given array
 */
class ElevationInfo {
  private $arrHeight= array();
  private $intTotal= 0;
  private $intUpHill= 0;
  private $intDownHill= 0;

  public function __construct($arrHeight) {
    $this->arrHeight= $arrHeight;
    $this->calculate();
  }

  private function calculate() {
    $intLast=0;
    if (is_array($this->arrHeight)) {
      foreach ($this->arrHeight as $val) {
        if ($val > $intLast) {
            $this->intTotal += $val-$intLast;
            $this->intUpHill += $val-$intLast;
        } else {
            $this->intTotal += $intLast-$val;
            $this->intDownHill += $intLast-$val;
        }
        $intLast=$val;
      }
    }
  }

  public function getTotal() {
    return $this->intTotal;
  }

  public function getUpHill() {
    return $this->intUpHill;
  }

  public function getDownHill() {
    return $this->intDownHill;
  }
}

// define heights field
$arrHeight= array(268,294,294,321,324,371,399,372,346);

$elevation= new ElevationInfo($arrHeight);
print sprintf('Total: %s<br />Up hill: %s<br />Down hill: %s',
    $elevation->getTotal(), 
    $elevation->getUpHill(),
    $elevation->getDownHill());

这将遍历给定的数组,计算总数和起伏,并允许您使用类方法“getDownHill()”、“getUpHill”和“getTotal”获得减少、增加和总数。希望我没有忽略任何事情,还无法测试代码,但我认为它应该可以工作。

于 2012-12-12T16:27:51.127 回答
1
 $elevationTotals = array('up' => 0,'down' =>0);
 $lastelevation = false;
 foreach($gpxdata as $key => $data){
      if($lastelevation !== false){
          $gpxdata[$key]['ElevationAlteration'] = $gpxdata['Elevation'] - $lastelevation;
          if($gpxdata[$key]['ElevationAlteration'] > 0){
               $elevationTotals['up'] += $gpxdata[$key]['ElevationAlteration'];
          } else {
               $elevationTotals['down'] += abs($gpxdata[$key]['ElevationAlteration']);
          }
      } else {
         $gpxdata[$key]['ElevationAlteration'] = 0;
      }
      $lastelevation = $gpxdata['Elevation'];
 }
于 2012-12-12T16:13:21.740 回答