【问题标题】:PHP function required to convert hex to lat & long将十六进制转换为经纬度所需的 PHP 函数
【发布时间】:2011-10-31 16:22:53
【问题描述】:

我有一个关于纬度和经度编码的问题,我的大脑拒绝给出答案。

我需要编写一个 php 函数,它接受值“1446041F”和“447D1100”(Lat & Lng)进行一些处理(我无法理解的位)并输出“52.062297”和“0.191030”。

我被告知 Lat 和 Lng 被编码为 4 个字节,从带符号的度数、分钟数和十进制分钟数开始,格式如下;

Latitude: SDDMM.MMMMM where 0≤DD≤90, S = [+|-], 0≤M≤9
Longitude: SDDDMM.MMMMM where 0≤DDD≤180, S = [+|-], 0≤M≤9

看到最后一点,我搜索了很多网站,但我仍然不知道这意味着什么。

我知道这是在黑暗中拍摄的巨大镜头,它可能非常简单,以至于我被正确地告诉我戴着傻帽坐在角落里,但我的头发快要拔掉了!

非常感谢任何建议。

谢谢, 马修

【问题讨论】:

  • 至少你不会一个人在那个角落里。

标签: php binary hex coordinates


【解决方案1】:

您给出的示例 1446041F447D1100 可能是 little-endian 字节顺序的 32 位有符号整数。 它们的读法如下:

1446041F -> 0x1F044614 -> 520373780
447D1100 -> 0x00117D44 -> 001146180

它们可以像这样以度数和分钟数来解释:

520373780 -> 52 degrees, 03.73780 minutes
1146480 -> 0 degrees, 11.46480 minutes

以下函数会将您指定的十六进制值转换为度数。我假设这些值是整数,如 0x447D1100 等。如果我假设错误并且输入值实际上是字符串,请告诉我。我把这个功能放到了公共领域。

function hextolatlon($hex){
  // Assume hex is a value like 0x1446041F or 0x447D1100
  // Convert to a signed integer
  $h=$hex&0xFF;
  $h=($h<<8)|(($hex>>8)&0xFF);
  $h=($h<<8)|(($hex>>16)&0xFF);
  $h=($h<<8)|(($hex>>24)&0xFF);
  $negative=($h>>31)!=0; // Get the sign
  if($negative){
   $h=~$h;
   $h=$h&0x7FFFFFFF;
   $h++;
  }
  // Convert to degrees and minutes
  $degrees=floor($h/10000000);
  $minutes=$h%10000000;
  // Convert to full degrees
  $degrees+=($minutes/100000.0) / 60.0;
  if($negative)$degrees=-$degrees;
  return $degrees;
}

【讨论】:

    【解决方案2】:

    这是 PHP(为了清楚起见,详细说明):

    function llconv($hex) {
        // Pack hex string:
        $bin = pack('H*', $hex);
    
        // Unpack into integer (returns array):
        $unpacked = unpack('V', $bin);
    
        // Get first (and only) element:
        $int = array_shift($unpacked);
    
        // Decimalize minutes:
        $degmin = $int / 100000;
    
        // Get degrees:
        $deg = (int)($degmin/100);
    
        // Get minutes:
        $min = $degmin - $deg*100;
    
        // Return degress:
        return round($deg + ($min/60), 6);
    }
    
    $long = '1446041F';
    $lat = '447D1100';
    
    $iLong = llconv($long);
    $iLat = llconv($lat);
    
    print "Out: $iLong x $iLat\n";
    

    【讨论】:

    • 这很酷。无论如何,我给了你一个+1,因为你首先提到了小端的事情。我以为是这样,但是当我看到您的帖子时仍在检查。
    • 感谢 Peter O 的出色回答,但 Doug 的功能完美地完成了这项工作。我还有一些难题要解决,我将使用此代码示例为其他难题打下基础。感谢您抽出宝贵时间 - 我喜欢 Stack Overflow 社区!顺便说一句 - 道格;如果你有贝宝账户,请告诉我,我会给你一些啤酒钱:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    • 2021-12-26
    • 2018-01-10
    • 1970-01-01
    • 2019-08-04
    • 2011-07-04
    • 1970-01-01
    相关资源
    最近更新 更多