简体   繁体   English

获取圆多边形圆周点(经纬度)

[英]Get circle polygon circumference points (latitude and longitude)

I am passing a center point (latitude, longitude) with a radius to this function to get the circumference points (latitude, longitude) so that I make a geometry from them and store it in MYSQL for me to do ST_Contains function later on.我将一个带有半径的中心点(纬度、经度)传递给此函数以获取圆周点(纬度、经度),以便我根据它们制作几何图形并将其存储在 MYSQL 中,以便稍后执行 ST_Contains 函数。

This is getting me an oval shape instead of a circle when drawing them on Google Maps.在 Google 地图上绘制它们时,这让我得到了椭圆形而不是圆形。

public static function convert($center, $radius, $numberOfSegments = 360)
{
    $n = $numberOfSegments;
    $flatCoordinates = [];
    $coordinates = [];
    for ($i = 0; $i < $n; $i++) {
        $flatCoordinates = array_merge($flatCoordinates, static::offset($center, $radius, 2 * pi() * $i / $n));
    }
    $flatCoordinates[] = $flatCoordinates[0];
    $flatCoordinates[] = $flatCoordinates[1];
    for ($i = 0, $j = 0; $j < count($flatCoordinates); $j += 2) {
        $coordinates[$i++] = array_slice($flatCoordinates, $j, 2);
    }

    return [
        'type' => 'Polygon',
        'coordinates' => [array_reverse($coordinates)]
    ];
}

public static function toRadians($angleInDegrees = null)
{
    return $angleInDegrees * pi() / 180;
}

public static function toDegrees($angleInRadians = null)
{
    return $angleInRadians * 180 / pi();
}

public static function offset($c1, $distance, $bearing)
{
    $lat1 = static::toRadians($c1[1]);
    $lon1 = static::toRadians($c1[0]);
    $dByR = $distance / 6378137; // distance divided by 6378137 (radius of the earth) wgs84
    $lat = asin(
        sin($lat1) * cos($dByR) +
            cos($lat1) * sin($dByR) * cos($bearing)
    );
    $lon = $lon1 + atan2(
        sin($bearing) * sin($dByR) * cos($lat1),
        cos($dByR) - sin($lat1) * sin($lat)
    );
    return [static::toDegrees($lon), static::toDegrees($lat)];
}

I do not really need it to be as accurate in terms of the earth curvature with taking into consideration WGS84, as the radius is quite small (25m-150m).考虑到 WGS84,我真的不需要它在地球曲率方面如此准确,因为半径非常小 (25m-150m)。

I'm guessing by the variable names that you got your function from this question but you forgot one line of the code, specifically the line that was causing that person problems.我根据变量名猜测您从这个问题中获得了函数,但您忘记了一行代码,特别是导致那个人出现问题的那一行。

In addition, your array code in the first function was quite more verbose than it needed to be.此外,您在第一个函数中的数组代码比需要的要冗长得多。 I condensed it considerably here, and used built-in PHP functions for the radians/degrees conversion:我在这里对其进行了相当大的压缩,并使用内置的 PHP 函数进行弧度/度数转换:

<?php
function convert($center, $radius, $numberOfSegments = 360)
{
    $n = $numberOfSegments;
    $flatCoordinates = [];
    $coordinates = [];
    for ($i = 0; $i < $n; $i++) {
        $bearing = 2 * M_PI * $i / $n;
        $flatCoordinates[] = offset($center, $radius, $bearing);
    }
    $flatCoordinates[] = $flatCoordinates[0];

    return [
        'type' => 'Polygon',
        'coordinates' => [$flatCoordinates]
    ];
}

function offset($c1, $distance, $bearing) {
    $lat1 = deg2rad($c1[0]);
    $lon1 = deg2rad($c1[1]);
    $dByR = $distance/6378137; // convert dist to angular distance in radians

    $lat = asin(
        sin($lat1) * cos($dByR) + 
            cos($lat1) * sin($dByR) * cos($bearing)
    );
    $lon = $lon1 + atan2(
        sin($bearing) * sin($dByR) * cos($lat1),
        cos($dByR) - sin($lat1) * sin($lat)
    );
    $lon = fmod(
        $lon + 3 * M_PI,
        2 * M_PI
    ) - M_PI;
    return [rad2deg($lon), rad2deg($lat)];
}

$result = convert([49, -122], 5000, 20);
foreach ($result['coordinates'][0] as $v) echo "$v[1]\t$v[0]\n";

Output:输出:

49.044915764206 -122
49.042715494198 -121.97882560793
49.036330613043 -121.9597290805
49.026387559463 -121.94458290688
49.01386140937  -121.93486968973
48.999979747353 -121.93153702633
48.986101953242 -121.93490597976
48.973585929464 -121.94464162541
48.963655392709 -121.95978779908
48.957280637886 -121.97886189803
48.955084235794 -122
48.957280637886 -122.02113810197
48.963655392709 -122.04021220092
48.973585929464 -122.05535837459
48.986101953242 -122.06509402024
48.999979747353 -122.06846297367
49.01386140937  -122.06513031027
49.026387559463 -122.05541709312
49.036330613043 -122.0402709195
49.042715494198 -122.02117439207
49.044915764206 -122

I used this site for testing and it drew the circle as expected.我使用这个网站进行测试,它按预期绘制了圆圈。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM