dow46218 2015-07-23 16:35
浏览 106
已采纳

简化数组中的数据以平滑PHP中的曲线

I'm using an API to get elevation data for GPX points, and try to create a graphic representation of it. My problem is that each point in the API is separated by 90meters, and my GPX points are separated by 5meters, causing several points in a row to have the same altitude before changing abruptly to a new altitude.

Basically, I obtain an array like this one:

[0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15...]

How would you draw it as a PNG image representation of the altitudes while easing the curves? I need to be able to change the size of the output picture.

I'm trying to change my array to something like that but I'm not sure how to do it and if this is the best solution:

[0, 0, 0, 0, 5, 5, 10, 10, 10, 12, 13, 15, 15, 15, 15...]

Thanks for any hints, I'm not used to work on pictures and data easing.

  • 写回答

1条回答 默认 最新

  • douyan4470 2015-07-23 16:52
    关注

    Here's a basic way to smooth the points on an "average" basis:

    <?php
    $points = [0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15];
    $refined = [];
    
    foreach($points as $index => $point) {
      // make sure we don't divide by 0
      $prev = isset($points[$index - 1]) ? $points[$index - 1] : false;
      $next = isset($points[$index + 1]) ? $points[$index + 1] : false;
    
      if($point > 0 || ($prev && $prev > 0) || ($next && $next > 0)) {
        $total = $point;
        if($prev) {
          $total += $prev;
          $total = $total / 2;
        } 
    
        if($next) {
          $total += $next;
          $total = $total / 2;
        }
    
        $refined[] = round($total, 0);
      } else {
        $refined[] = $point;
      }
    }
    
    echo implode(" ", $points);
    echo "<hr>";
    echo implode(" ", $refined);
    

    Results in:

    0 0 0 0 0 10 10 10 10 10 15 15 15 15 15
    ---------------------------------------
    0 0 0 0 5 10 10 10 10 13 14 15 15 15 15
    

    To increase smoothing, you'll need a more elaborate method that has look-ahead's, look-behind's, and a higher amount of sampling... you could probably also interpolate between points -- but I excluded that in the sample above. To do interpolation, you could do the below:

    <?php
    $points = [0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15];
    $refined = [];
    
    foreach($points as $index => $point) {
      $prev = isset($points[$index - 1]) ? $points[$index - 1] : false;
      $next = isset($points[$index + 1]) ? $points[$index + 1] : false;
    
      if($point > 0 || ($prev && $prev > 0) || ($next && $next > 0)) {
        $refined[] = $point;
    
        while($next && $point < $next) {
          $point++;
          $refined[] = $point;
        }
      } else {
        $refined[] = $point;
      }
    }
    
    echo implode(" ", $points);
    echo "<hr>";
    echo implode(" ", $refined);
    

    Which will yield:

    0 0 0 0 0 10 10 10 10 10 15 15 15 15 15
    ---------------------------------------------------------------------------
    0 0 0 0 0 1 2 3 4 5 6 7 8 9 10 10 10 10 10 10 11 12 13 14 15 15 15 15 15 15
    

    To draw an image, we'll need more info. The points in the array are not 2D... meaning there's no X or Y, unless we assume that each point increases the X axis by one pixel? If so, here's a rough shot:

    $width = count($refined);
    $height = max($refined);
    
    $gd = imagecreatetruecolor($width, $height);
    
    // Allocate a color
    $red = imagecolorallocate($gd, 255, 0, 0); 
    
    foreach($refined as $x => $y) {
      imagesetpixel($gd, $x, $height-$y, $red);
    }
    
    header('Content-Type: image/png');
    imagepng($gd);
    

    See: http://codepad.viper-7.com/VsuD1G

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 R语言卸载之后无法重装,显示电脑存在下载某些较大二进制文件行为,怎么办
  • ¥15 java 的protected权限 ,问题在注释里