按照這里的指南 https://www.intelliwolf.com/find-nearest-location-from-array-of-coordinates-php/
我正在嘗試撰寫一個從https://easytide.admiralty.co.uk/Home/GetStations找到的 JSON 提要中找到最近的“ID”的版本
到目前為止,我已經構建了以下沙箱 https://3v4l.org/JX0i5#v7.3.1
<?PHP
// json will eventually be obtained via json_decode(file_get_contents('https://easytide.admiralty.co.uk/Home/GetStations')
$json = '
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-4.702540,
51.672791
]
},
"properties": {
"Id": "1603",
"Name": "TENBY",
"Country": "Channel Islands",
"ContinuousHeightsAvailable": true
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-1.878530,
50.721680
]
},
"properties": {
"Id": "1603A",
"Name": "Bournmouth",
"Country": "Channel Islands",
"ContinuousHeightsAvailable": true
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-2.35,
49.433333
]
},
"properties": {
"Id": "1603A",
"Name": "Maseline Pier",
"Country": "Channel Islands",
"ContinuousHeightsAvailable": true
}
}]
}';
$locations = json_decode($json, true);
#print_r($locations); //check json decoded
// set the base location will eventually be passed via $_GET
$base_location = array(
'lat' => "51.672791",
'lng' => "-4.702540"
);
//create the array for recording the calculated distances
$distances = array();
//sure this count is not needed but used it to check the array was being read
for ($c = 0; $c < count($locations["features"]); $c ) {
// this is where I go wrong
foreach($locations as $i){
foreach ($i as $z) {
foreach ($z['geometry'] as $key => $location) {
if ($key == "coordinates"){
# print_r($z);
//work out the distance Pythagorean Theorem calculating how far it is from $base_location is
$a = $base_location['lat'] - $location[1];
$b = $base_location['lng'] - $location[0];
$distance = sqrt(($a**2) ($b**2));
$distances[$c] = $distance;
//nonsense used to test I was getting the correct output
echo "The value of key '$key' is '$location'", PHP_EOL;
}
}
}
}
}
#print_r($base_location);
//sort distances to get the closest first
asort($distances);
print_r($distances);
//not really got to this part yet but want to return the "properties=>ID"
$closest = $location[key($distances)];
#print_r($closest);
#echo "<br>Closest port from ARRAY is: " . $closest['features'][1]['properties']['Id'];
我希望有人用簡單的術語解釋我如何使它起作用:-
- 搜索在https://easytide.admiralty.co.uk/Home/GetStations找到的陣列
- 根據提供的緯度/經度查找最近的位置
- 從相應的陣列中列印“properties=>ID”(稍后在另一個 file_get_contents 請求中使用)
我已經傾注了好幾個小時,并發布了該問題的其他版本,這些版本已自動關閉。
我想將其創建為一個學習專案,但被困在這個元素上。如果這不是尋求此類幫助的地方,請告知在哪里。
非常感謝
uj5u.com熱心網友回復:
這似乎是一個有趣的練習,有點繞,你需要的所有代碼都在那里供你使用
function getDistance($from_lat, $from_long, $to_lat, $to_long, $unit = 'nmi', $decimals = 2) {
// Calculate the distance in degrees
$degrees = rad2deg(acos((sin(deg2rad($from_lat))*sin(deg2rad($to_lat))) (cos(deg2rad($from_lat))*cos(deg2rad($to_lat))*cos(deg2rad($from_long-$to_long)))));
// Convert the distance in degrees to the chosen unit (kilometres, miles or nautical miles)
switch($unit) {
case 'km':
$distance = $degrees * 111.13384; // 1 degree = 111.13384 km, based on the average diameter of the Earth (12,735 km)
break;
case 'mi':
$distance = $degrees * 69.05482; // 1 degree = 69.05482 miles, based on the average diameter of the Earth (7,913.1 miles)
break;
case 'nmi':
$distance = $degrees * 59.97662; // 1 degree = 59.97662 nautic miles, based on the average diameter of the Earth (6,876.3 nautical miles)
}
return round($distance, $decimals);
}
$json_stations = file_get_contents('https://easytide.admiralty.co.uk/Home/GetStations');
$stations = json_decode($json_stations);
$i_am_here = ['lat' => 50.77842324616663, 'lng' => -1.087804949548603]; // Castle Field Portsmouth
$closest = []; // index into stations
$distance = null;
foreach ($stations->features as $index => $feature){
$lng = $feature->geometry->coordinates[0];
$lat = $feature->geometry->coordinates[1];
$dist = getDistance($i_am_here['lat'], $i_am_here['lng'], $lat, $lng, $unit = 'nmi', $decimals = 4);
if ( $distance == NULL || $dist < $distance ){
$distance = $dist;
$closest = ['distance' => $dist, 'index' => $index, 'properties' => $feature->properties];
}
}
print_r($closest);
echo 'Distance = ' . $distance;
結果
Array
(
[distance] => 1.6947
[index] => 85
[properties] => stdClass Object
(
[Id] => 0065
[Name] => PORTSMOUTH
[Country] => England
[ContinuousHeightsAvailable] => 1
)
)
Distance = 1.6947
uj5u.com熱心網友回復:
I managed to work out a 'solution' but perhaps not the most graceful?
foreach($locations as $i){
if (is_array($i) || is_object($i)) {
foreach ($i as $z) {
foreach ($z['geometry'] as $key => $location) {
if ($key == "coordinates"){
# print_r($z);
$a = $base_location['lat'] - $location[1];
$b = $base_location['lng'] - $location[0];
$distance = sqrt(($a**2) ($b**2));
$distances[$c ] = $distance;
# echo "The value of key '$key' is '$location'", PHP_EOL;
}
}
}
}
}
asort($distances);
$closest = $i[key($distances)];
print_r($closest);
echo "Closest Id: " . $closest['properties']['Id']. " name: " . $closest['properties']['Name'];
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/435745.html
