Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bing将地理数据解压缩算法端口映射到PHP 我试图将微软的解压缩算法移植到java(或者是C++或C语言),因为那是微软。这是一种从Bing Maps Geodata API结果中获取压缩形状数据并将其扩展到lat/lon坐标的算法。他们已经在他们的网站上发布了他们的算法_Java_Php_Bing Maps_Compression_Bing Api - Fatal编程技术网

Bing将地理数据解压缩算法端口映射到PHP 我试图将微软的解压缩算法移植到java(或者是C++或C语言),因为那是微软。这是一种从Bing Maps Geodata API结果中获取压缩形状数据并将其扩展到lat/lon坐标的算法。他们已经在他们的网站上发布了他们的算法

Bing将地理数据解压缩算法端口映射到PHP 我试图将微软的解压缩算法移植到java(或者是C++或C语言),因为那是微软。这是一种从Bing Maps Geodata API结果中获取压缩形状数据并将其扩展到lat/lon坐标的算法。他们已经在他们的网站上发布了他们的算法,java,php,bing-maps,compression,bing-api,Java,Php,Bing Maps,Compression,Bing Api,我的数据库中存储了一个坐标列表,我正在尝试检索定义多边形以处理形状的坐标数组。我的结果不同。有人能指出两者之间的差异吗 编辑:我认为我的问题在于PHP不处理长类型整数,并且在执行逐位运算时会发生精度损失。我可能需要转换一些操作以使用BCMath。帮帮忙 解压算法(微软的) 预期产出 an array of coordinates 35.894309002906084, -110.72522000409663 35.893930979073048, -110.72577999904752 35.8

我的数据库中存储了一个坐标列表,我正在尝试检索定义多边形以处理形状的坐标数组。我的结果不同。有人能指出两者之间的差异吗

编辑:我认为我的问题在于PHP不处理长类型整数,并且在执行逐位运算时会发生精度损失。我可能需要转换一些操作以使用BCMath。帮帮忙

解压算法(微软的)

预期产出

an array of coordinates
35.894309002906084, -110.72522000409663
35.893930979073048, -110.72577999904752
35.893744984641671, -110.72606003843248
35.893366960808635, -110.72661500424147
array(4) {
  [0]=>
  array(2) {
    [0]=>
    float(1.0E-5)
    [1]=>
    float(1.0E-5)
  }
  [1]=>
  array(2) {
    [0]=>
    float(1.027027027027E-5)
    [1]=>
    float(1.0181818181818E-5)
  }
  [2]=>
  array(2) {
    [0]=>
    float(1.0825825825826E-5)
    [1]=>
    float(1.0552188552189E-5)
  }
  [3]=>
  array(2) {
    [0]=>
    float(1.1103603603604E-5)
    [1]=>
    float(1.0734006734007E-5)
  }
}
我的输出

an array of coordinates
35.894309002906084, -110.72522000409663
35.893930979073048, -110.72577999904752
35.893744984641671, -110.72606003843248
35.893366960808635, -110.72661500424147
array(4) {
  [0]=>
  array(2) {
    [0]=>
    float(1.0E-5)
    [1]=>
    float(1.0E-5)
  }
  [1]=>
  array(2) {
    [0]=>
    float(1.027027027027E-5)
    [1]=>
    float(1.0181818181818E-5)
  }
  [2]=>
  array(2) {
    [0]=>
    float(1.0825825825826E-5)
    [1]=>
    float(1.0552188552189E-5)
  }
  [3]=>
  array(2) {
    [0]=>
    float(1.1103603603604E-5)
    [1]=>
    float(1.0734006734007E-5)
  }
}
因此,我们可以看到PHP输出没有被正确计算,我有一种感觉,这与Java中转换为长整数和对整数运行逐位操作的差异有关。PHP应该处理整数,不管它们是长的、浮点数还是整数,但我觉得我忽略了一些东西

我打赌问题与这条线有关。有人能指出差异吗

n |= ((long)b & 31) << k;   // mask off the top bit and append the rest to the accumulator

n |=((长)b&31)我怀疑你的问题在于你转换了以下C代码:

在PHP代码中,将其转换为:

$nx = pow(($nx >> 1), (-($nx & 1)) );
$ny = pow(($ny >> 1), (-($ny & 1)) );
在C中,^是一种按位异或运算,而不是幂运算。PHP对按位异或使用相同的符号,因此请尝试将代码更改为:

$nx = ($nx >> 1) ^ (-($nx & 1));
$ny = ($ny >> 1) ^ (-($ny & 1));

我怀疑您的问题在于您转换了以下C#代码:

在PHP代码中,将其转换为:

$nx = pow(($nx >> 1), (-($nx & 1)) );
$ny = pow(($ny >> 1), (-($ny & 1)) );
在C中,^是一种按位异或运算,而不是幂运算。PHP对按位异或使用相同的符号,因此请尝试将代码更改为:

$nx = ($nx >> 1) ^ (-($nx & 1));
$ny = ($ny >> 1) ^ (-($ny & 1));
我已将C#代码转换为PHP。问题确实在于php中的大浮点数会丢失精度。由于一些值超出了32位整数的边界,并且在C#中存储为64位整数,因此必须将这些值转换为。GMP支持长的按位操作

/*
*   Microsoft's decompression algorithm - php version
*   returns an array of coordinates (pairs of doubles)
*/
function tryParseEncodedValue($value) {

    $safeCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
    $list = array();
    (int)$index = 0;
    (int)$xsum = 0;
    (int)$ysum = 0;

    while ($index < strlen($value))        // While we have more data,
    {
        $n = 0;                             // initialize the accumulator
        $k = 0;                              // initialize the count of bits

        while (true)
        {
            if ($index >= strlen($value)) // If we ran out of data mid-number
            {
                var_error_log('failed: inxed >= strlen($value)');
                return false;             // indicate failure.
            }
            $b = strpos($safeCharacters, $value[$index++]);

            if ($b === false) {           // If the character wasn't on the valid list,
                var_error_log('failed: character not in valid list');
                return false;             // indicate failure.
            }

            // mask off the top bit and append the rest to the accumulator
            // n |= ((long)b & 31) << k;
            $bgmp = gmp_init($b);                           // Here i'm breaking out this function
            $bitwiseand = gmp_and($bgmp, 31);               // on multiple lines because there's 
            $shifted = gmp_shiftl($bitwiseand, $k);         // so many steps
            $n = gmp_or($n, $shifted);
            $k += 5;
            if (gmp_cmp($bgmp, gmp_init(32)) < 0) break;    // gmp compare: b < 32
        }

        // The resulting number encodes an x, y pair in the following way:
        //
        //  ^ Y
        //  |
        //  14
        //  9 13
        //  5 8 12
        //  2 4 7 11
        //  0 1 3 6 10 ---> X

        // determine which diagonal it's on
        //$diagonal = (int)((sqrt(8 * $n + 5) - 1) / 2);
        $diagonal = gmp_intval(gmp_div_q(gmp_sub(gmp_sqrt(gmp_add(gmp_mul($n, 8), 5)), 1), 2));

        // subtract the total number of points from lower diagonals
        // n -= diagonal * (diagonal + 1L) / 2;
        $n = gmp_sub($n, gmp_div_q(gmp_mul($diagonal, gmp_add($diagonal, 1)), 2));

        // get the X and Y from what's left over
        (int)$ny = gmp_intval($n);
        (int)$nx = $diagonal - $ny;

        // undo the sign encoding
        $nx = ($nx >> 1)^ (-($nx & 1));
        $ny = ($ny >> 1)^ (-($ny & 1));

        // undo the delta encoding
        $xsum += $nx;
        $ysum += $ny;

        // position the decimal point
        $coordinate = array($ysum * 0.00001, $xsum * 0.00001);
        array_push($list, $coordinate);
    }

    return $list;
}

// shift left, $x number to shift, $n shift n times. 
function gmp_shiftl($x,$n) { 
    return(gmp_mul($x,gmp_pow(2,$n)));
}
/*
*微软的解压算法-php版本
*返回坐标数组(成对的双精度)
*/
函数tryParseEncodedValue($value){
$safeCharacters=“abcdefghijklmnopqrstuvxyzabdfghijklmnopqrstuvxyzo123456789_-”;
$list=array();
(int)$index=0;
(int)$xsum=0;
(int)$ysum=0;
while($index=strlen($value))//如果我们用完了中间数的数据
{
变量错误日志('failed:inx>=strlen($value');
返回false;//表示失败。
}
$b=strpos($safeCharacters,$value[$index++]);
如果($b==false){//如果字符不在有效列表中,
变量错误日志('失败:字符不在有效列表中');
返回false;//表示失败。
}
//屏蔽顶部位并将其余位附加到累加器
//n |=((长)b&31)X
//确定它在哪个对角线上
//$diagonal=(int)((sqrt(8*$n+5)-1)/2);
$diagonal=gmp_intval(gmp_div_q)(gmp_sub(gmp_sqrt)(gmp_add(gmp_mul($n,8),5)),1),2));
//从下对角线减去总点数
//n-=对角线*(对角线+1L)/2;
$n=gmp_sub($n,gmp_div_q(gmp_mul($diagonal,gmp_add($diagonal,1)),2));
//从剩下的东西中得到X和Y
(int)$ny=gmp_intval($n);
(int)$nx=$diagonal-$ny;
//撤消符号编码
$nx=($nx>>1)^($nx&1));
$ny=($ny>>1)^($ny&1));
//撤消增量编码
$xsum+=$nx;
$ysum+=$ny;
//定位小数点
$coordinate=array($ysum*0.00001,$xsum*0.00001);
数组推送($list,$coordinate);
}
返回$list;
}
//向左移位,$x要移位的次数,$n移位n次。
函数gmpu shiftl($x,$n){
返回(gmp_-mul($x,gmp_-pow(2,$n)));
}
我已将C#代码转换为PHP。问题确实在于PHP中的大浮点数丢失了精度。由于一些值超出了32位整数的边界,并在C#中存储为64位整数,因此必须将这些值转换为。GMP支持长位操作

/*
*   Microsoft's decompression algorithm - php version
*   returns an array of coordinates (pairs of doubles)
*/
function tryParseEncodedValue($value) {

    $safeCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
    $list = array();
    (int)$index = 0;
    (int)$xsum = 0;
    (int)$ysum = 0;

    while ($index < strlen($value))        // While we have more data,
    {
        $n = 0;                             // initialize the accumulator
        $k = 0;                              // initialize the count of bits

        while (true)
        {
            if ($index >= strlen($value)) // If we ran out of data mid-number
            {
                var_error_log('failed: inxed >= strlen($value)');
                return false;             // indicate failure.
            }
            $b = strpos($safeCharacters, $value[$index++]);

            if ($b === false) {           // If the character wasn't on the valid list,
                var_error_log('failed: character not in valid list');
                return false;             // indicate failure.
            }

            // mask off the top bit and append the rest to the accumulator
            // n |= ((long)b & 31) << k;
            $bgmp = gmp_init($b);                           // Here i'm breaking out this function
            $bitwiseand = gmp_and($bgmp, 31);               // on multiple lines because there's 
            $shifted = gmp_shiftl($bitwiseand, $k);         // so many steps
            $n = gmp_or($n, $shifted);
            $k += 5;
            if (gmp_cmp($bgmp, gmp_init(32)) < 0) break;    // gmp compare: b < 32
        }

        // The resulting number encodes an x, y pair in the following way:
        //
        //  ^ Y
        //  |
        //  14
        //  9 13
        //  5 8 12
        //  2 4 7 11
        //  0 1 3 6 10 ---> X

        // determine which diagonal it's on
        //$diagonal = (int)((sqrt(8 * $n + 5) - 1) / 2);
        $diagonal = gmp_intval(gmp_div_q(gmp_sub(gmp_sqrt(gmp_add(gmp_mul($n, 8), 5)), 1), 2));

        // subtract the total number of points from lower diagonals
        // n -= diagonal * (diagonal + 1L) / 2;
        $n = gmp_sub($n, gmp_div_q(gmp_mul($diagonal, gmp_add($diagonal, 1)), 2));

        // get the X and Y from what's left over
        (int)$ny = gmp_intval($n);
        (int)$nx = $diagonal - $ny;

        // undo the sign encoding
        $nx = ($nx >> 1)^ (-($nx & 1));
        $ny = ($ny >> 1)^ (-($ny & 1));

        // undo the delta encoding
        $xsum += $nx;
        $ysum += $ny;

        // position the decimal point
        $coordinate = array($ysum * 0.00001, $xsum * 0.00001);
        array_push($list, $coordinate);
    }

    return $list;
}

// shift left, $x number to shift, $n shift n times. 
function gmp_shiftl($x,$n) { 
    return(gmp_mul($x,gmp_pow(2,$n)));
}
/*
*微软的解压算法-php版本
*返回坐标数组(成对的双精度)
*/
函数tryParseEncodedValue($value){
$safeCharacters=“abcdefghijklmnopqrstuvxyzabdfghijklmnopqrstuvxyzo123456789_-”;
$list=array();
(int)$index=0;
(int)$xsum=0;
(int)$ysum=0;
while($index=strlen($value))//如果我们用完了中间数的数据
{
变量错误日志('failed:inx>=strlen($value');
返回false;//表示失败。
}
$b=strpos($safeCharacters,$value[$index++]);
如果($b==false){//如果字符不在有效列表中,
变量错误日志('失败:字符不在有效列表中');
返回false;//表示失败。
}
//遮罩掉顶部的一位,然后消失