按最接近的位置对PHP数组进行排序。

huangapple go评论70阅读模式
英文:

Sorting PHP array by closest location

问题

我有一个包含Paysera包裹机的数组:

Array
(
    [0] => Array
        (
            [id] => PMFOzGmlcQ-9GmEt5vj9JTGals_1nI87Lm
            [shipment_gateway_code] => lp
            [code] => 0199
            [address] => Array
                (
                    [country] => LT
                    [city] => Vilnius
                    [street] => Žirmūnų g. 48A
                    [postal_code] => 09226
                )

            [coordinates] => Array
                (
                    [latitude] => 54.70274
                    [longitude] => 25.30368
                )

            [location_name] => Express Market
            [enabled] => 1
        )

    [1] => Array
        (
            [id] => PMBBGl0TsF1vuv8YqeLsn4gyWwGB9-vd98
            [shipment_gateway_code] => lp
            [code] => 0198
            [address] => Array
                (
                    [country] => LT
                    [city] => Vilnius
                    [street] => Lazdynėlių g. 23
                    [postal_code] => 04126
                )

            [coordinates] => Array
                (
                    [latitude] => 54.66283
                    [longitude] => 25.19253
                )

            [location_name] => Maxima
            [enabled] => 1
        )
)

我也有用户坐标的数组:

Array
(
    [latitude] => 54.70274
    [longitude] => 25.30368
)

我需要根据距离用户最近的位置对第一个数组进行排序,但我不太理解如何做到这一点。

我尝试了以下解决方案,但似乎没有任何效果:

$cities = <your array>;

$point = array(
    'latitude' => 50.6000,
    'longitude' => -74.15000
);

function distance($a, $b) {
    return sqrt(
        pow($a['latitude'] - $b['latitude'], 2)
        + pow($a['longitude'] - $b['longitude'], 2));
}

usort($cities, function($p, $q) {
    global $point;
    return distance($p, $point) - distance($q, $point);
});

请帮助我实现我的目标。谢谢!

英文:

I have an array with parcel machines from Paysera:

Array
(
    [0] =&gt; Array
        (
            [id] =&gt; PMFOzGmlcQ-9GmEt5vj9JTGals_1nI87Lm
            [shipment_gateway_code] =&gt; lp
            [code] =&gt; 0199
            [address] =&gt; Array
                (
                    [country] =&gt; LT
                    [city] =&gt; Vilnius
                    [street] =&gt; Žirmūnų g. 48A
                    [postal_code] =&gt; 09226
                )

            [coordinates] =&gt; Array
                (
                    [latitude] =&gt; 54.70274
                    [longitude] =&gt; 25.30368
                )

            [location_name] =&gt; Express Market
            [enabled] =&gt; 1
        )

    [1] =&gt; Array
        (
            [id] =&gt; PMBBGl0TsF1vuv8YqeLsn4gyWwGB9-vd98
            [shipment_gateway_code] =&gt; lp
            [code] =&gt; 0198
            [address] =&gt; Array
                (
                    [country] =&gt; LT
                    [city] =&gt; Vilnius
                    [street] =&gt; Lazdynėlių g. 23
                    [postal_code] =&gt; 04126
                )

            [coordinates] =&gt; Array
                (
                    [latitude] =&gt; 54.66283
                    [longitude] =&gt; 25.19253
                )

            [location_name] =&gt; Maxima
            [enabled] =&gt; 1
        )
)

Also I have user's coordinates in array:

Array
    (
        [latitude] =&gt; 54.70274
        [longitude] =&gt; 25.30368
    )

I have to sort my first array by the nearest location to my user but I don't really understand how to do it.

I tried the following solution but it seems like it does nothing at all:

$cities = &lt;your array&gt;;

$point = array(
    &#39;latitude&#39; =&gt; 50.6000,
    &#39;longitude&#39; =&gt; -74.15000
);

function distance($a, $b) {
    return sqrt(
        pow($a[&#39;latitude&#39;] - $b[&#39;latitude&#39;], 2)
        + pow($a[&#39;longitude&#39;] - $b[&#39;longitude&#39;], 2));
}

usort($cities, function($p, $q) {
    global $point;
    return distance($p, $point) - distance($q, $point);
});

Please help me to achieve my goal. Thanks!

答案1

得分: 1

根据我从上面的评论和维基百科了解,Vincenty's formula 是计算距离的最准确的公式。

所以我编写了以下代码:

$arParcelMachines = Array(); // $arParcelMachines 是来自 Paysera 的包裹机器数组

if ($latitude && $longitude) { // $latitude 和 $longitude 是用户的坐标
    foreach ($arParcelMachines as &$arParcelMachine) {
        $arParcelMachine["distance"] = getDistance($latitude, $longitude, $arParcelMachine["coordinates"]["latitude"], $arParcelMachine["coordinates"]["longitude"]);
    }

    usort($arParcelMachines, function($a, $b) {
        return $a["distance"] - $b["distance"];
    });
}

function getDistance($fromLatitude, $fromLongitude, $toLatitude, $toLongitude, $radius = 6371000) { // Vincenty's formula
    $fromLatitude = deg2rad($fromLatitude);
    $fromLongitude = deg2rad($fromLongitude);
    $toLatitude = deg2rad($toLatitude);
    $toLongitude = deg2rad($toLongitude);
  
    $deltaLongitude = abs($fromLongitude - $toLongitude);
  
    $centralAngle = atan2(sqrt(pow(cos($toLatitude) * sin($deltaLongitude), 2) + pow(cos($fromLatitude) * sin($toLatitude) - sin($fromLatitude) * cos($toLatitude) * cos($deltaLongitude), 2)), sin($fromLatitude) * sin($toLatitude) + cos($fromLatitude) * cos($toLatitude) * cos($deltaLongitude));
    
    return $radius * $centralAngle;
}

希望这对你有帮助。

英文:

As far as I understood from the comments above and from the Wikipedia the Vincenty's formula is the most accurate formula for calculating a distance.

So I came up with the following code:

$arParcelMachines = Array(); // $arParcelMachines is an array of parcell machines from Paysera

if ($latitude &amp;&amp; $longitude) { // $latitude &amp;&amp; $longitude are user&#39;s coordinates
    foreach ($arParcelMachines as &amp;$arParcelMachine) {
        $arParcelMachine[&quot;distance&quot;] = getDistance($latitude, $longitude, $arParcelMachine[&quot;coordinates&quot;][&quot;latitude&quot;], $arParcelMachine[&quot;coordinates&quot;][&quot;longitude&quot;]);
    }

    usort($arParcelMachines, function($a, $b) {
        return $a[&quot;distance&quot;] - $b[&quot;distance&quot;];
    });
}

function getDistance($fromLatitude, $fromLongitude, $toLatitude, $toLongitude, $radius = 6371000) { // Vincenty&#39;s formula
	$fromLatitude = deg2rad($fromLatitude);
	$fromLongitude = deg2rad($fromLongitude);
	$toLatitude = deg2rad($toLatitude);
	$toLongitude = deg2rad($toLongitude);
  
	$deltaLongitude = abs($fromLongitude - $toLongitude);
  
	$centralAngle = atan2(sqrt(pow(cos($toLatitude) * sin($deltaLongitude), 2) + pow(cos($fromLatitude) * sin($toLatitude) - sin($fromLatitude) * cos($toLatitude) * cos($deltaLongitude), 2)), sin($fromLatitude) * sin($toLatitude) + cos($fromLatitude) * cos($toLatitude) * cos($deltaLongitude));
	
	return $radius * $centralAngle;
}

huangapple
  • 本文由 发表于 2023年7月7日 03:16:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76631923.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定