php Laravel -基于Bounds参数从数据库中过滤和转换坐标

brqmpdu1  于 2023-09-29  发布在  PHP
关注(0)|答案(1)|浏览(118)

我在PHP Laravel项目中遇到了一个问题,我需要根据URL中提供的边界参数过滤和转换存储在数据库中的坐标。下面是我的应用程序的结构:
我的数据库中有一个Airspace表,其中DP列包含JSON编码字符串形式的坐标。
空域表的JSON:

{
    "AC": "A",
    "AN": "AUCKLAND",
    "AL": "24500",
    "AH": "60000",
    "DP": [
        "59,59,59,S,163,00,00,E",
        "59,59,59,S,174,00,00,E",
        "63,44,18,S,179,59,59,W",
        "73,30,00,S,131,00,00,W",
        "89,59,59,S,131,00,00,W"
    ]
},
{
    "AC": "A",
    "AN": "AUCKLAND",
    "AL": "24500",
    "AH": "60000",
    "DP": [
        "5,00,00,S,171,00,00,W",
        "5,00,00,S,156,59,59,W",
        "29,59,59,S,156,59,59,W",
        "29,59,59,S,131,00,00,W",
}

]
API端点/airspace接受URL中的bounds参数,如下所示:http://127.0.0.1:8000/airspace?bounds=39.42,26.41,33.88,54.40
我想从空域表中获取边界覆盖范围内的坐标。
另外,我有一个函数convertCoordinates,它将坐标从格式“26,58,35,N,080,19,42,W”转换为十进制度数。
下面是我的当前代码:

Route::get('/airspace', function (Request $request) {
    // Parse the bounds parameter from the URL
    $bounds = explode(',', $request->query('bounds'));

    if (count($bounds) !== 4) {
        return response()->json(['error' => 'Invalid bounds parameter'], 400);
    }

    $southwest = [$bounds[0], $bounds[1]];
    $northeast = [$bounds[2], $bounds[3]];

    // Fetch the airports from the database and convert to an array
    $airports = Airspace::all()->toArray();

    // Filter and convert the coordinates
    $filteredAirports = [];

    foreach ($airports as $airport) {
        $coordinates = json_decode($airport['DP']);

        if (is_array($coordinates)) {
            $filteredCoordinates = [];

            foreach ($coordinates as $coordStr) {
                $coords = explode(',', $coordStr);

                if (count($coords) === 8) {
                    list($lat, $lon) = convertCoordinates($coords);

                    if ($lat >= $southwest[0] && $lat <= $northeast[0] &&
                        $lon >= $southwest[1] && $lon <= $northeast[1]) {
                        $filteredCoordinates[] = [$lat, $lon];
                    }
                } else {
                    // Log an error for invalid coordinate format
                    error_log("Invalid coordinate format: $coordStr");
                }
            }

            if (!empty($filteredCoordinates)) {
                $filteredAirport = [
                    'AC' => $airport['AC'],
                    'AN' => $airport['AN'],
                    'Coordinates' => $filteredCoordinates,
                ];

                $filteredAirports[] = $filteredAirport;
            }
        } else {
            // Log an error for invalid DP format
            error_log("Invalid DP format: " . $airport['DP']);
        }
    }

    return response()->json($filteredAirports, 200);
});

function convertCoordinates($parts) {
    // Add error handling for invalid coordinate parts here if needed

    $latDeg = floatval($parts[0]);
    $latMin = floatval($parts[1]);
    $latSec = floatval($parts[2]);
    $latDir = $parts[3];
    $lonDeg = floatval($parts[4]);
    $lonMin = floatval($parts[5]);
    $lonSec = floatval($parts[6]);
    $lonDir = $parts[7];

    // Convert latitude and longitude to decimal degrees
    $latitude = ($latDeg + $latMin / 60 + $latSec / 3600) * ($latDir === 'S' ? -1 : 1);
    $longitude = ($lonDeg + $lonMin / 60 + $lonSec / 3600) * ($lonDir === 'W' ? -1 : 1);

    return [$latitude, $longitude];
}

问题是我从这段代码中得到的响应是空的,我不知道为什么。我怀疑这个问题可能与我处理数据库记录和过滤过程的方式有关。

uurity8g

uurity8g1#

我发现问题了。boundsString的格式为north,west,south,east。因此,将以north,west,south,east格式解析boundsString,并根据提供的边界框正确过滤坐标。

Route::get('/airspace', function (Request $request) {
    // Step 1: Parse bounds parameter
    $boundsString = $request->query('bounds');
    $bounds = explode(',', $boundsString);
    $neLat = floatval($bounds[0]);
    $swLon = floatval($bounds[1]);
    $swLat = floatval($bounds[2]);
    $neLon = floatval($bounds[3]);

    // Step 2: Fetch all airports and filter based on bbox coverage
    $airports = Airspace::all(); // Assuming Airspace is your model
    $filteredAirports = [];

    foreach ($airports as $airport) {
        $coordinates = json_decode($airport->DP);

        $insideBBox = false;

        foreach ($coordinates as $coordStr) {
            $parts = explode(',', $coordStr);

            // Convert latitude and longitude to decimal degrees
            $latDeg = floatval($parts[0]);
            $latMin = floatval($parts[1]);
            $latSec = floatval($parts[2]);
            $latDir = $parts[3];
            $lonDeg = floatval($parts[4]);
            $lonMin = floatval($parts[5]);
            $lonSec = floatval($parts[6]);
            $lonDir = $parts[7];

            $latitude = ($latDeg + $latMin / 60 + $latSec / 3600) * ($latDir === 'S' ? -1 : 1);
            $longitude = ($lonDeg + $lonMin / 60 + $lonSec / 3600) * ($lonDir === 'W' ? -1 : 1);

            // Handle the wrap-around issue with longitudes
            if ($swLon > $neLon) {
                if ($longitude >= $swLon || $longitude <= $neLon) {
                    $insideBBox = true;
                }
            } else {
                if ($latitude >= $swLat && $latitude <= $neLat && $longitude >= $swLon && $longitude <= $neLon) {
                    $insideBBox = true;
                }
            }
        }

        if ($insideBBox) {
            $filteredAirports[] = $airport;
        }
    }

    return response()->json($filteredAirports, 200);
});

花了几个小时才修好:)

相关问题