Формула географического назначения - PullRequest
1 голос
/ 23 апреля 2010

У меня есть эта функция PHP, но, похоже, она дает неверные результаты. Кто-нибудь имеет представление, что с ним не так (особенно формула)?

/**
 * Finds a destination given a starting location, bearing and distance.
 * 
 * @param array $startingCoordinates The starting coordinates, as non-directional floats in an array with lat and lon keys.
 * @param float $bearing The initial bearing in degrees.
 * @param float $distance The distance to travel in km.
 * 
 * @return array The desitination coordinates, as non-directional floats in an array with lat and lon keys.
 */
public static function findDestination( array $startingCoordinates, $bearing, $distance ) {
        $startingCoordinates['lat'] = (float)$startingCoordinates['lat'];
        $startingCoordinates['lon'] = (float)$startingCoordinates['lon'];
        $angularDistance = $distance / Maps_EARTH_RADIUS;
        $lat = asin(
                        sin( $startingCoordinates['lat'] ) * cos( $angularDistance ) +
                        cos( $startingCoordinates['lat'] ) * sin( $angularDistance ) * cos( $bearing )
        );
        return array(
                'lat' => $lat,
                'lon' => $startingCoordinates['lon'] + atan2(
                        sin( $bearing ) * sin( $angularDistance ) * cos( $startingCoordinates['lat'] ),
                        cos( $angularDistance ) - sin( $startingCoordinates['lat'] ) * sin( $lat )
                )
        );
}

1 Ответ

1 голос
/ 14 сентября 2011

Расчеты выполняются на радианах, поэтому сначала вам нужно преобразовать значения, основанные на градусах, а затем обратно для получения значимого значения для вас. Например:

public static function findDestination(array $startingCoordinates, $bearing, $distance) {
        $startingCoordinates['lat'] = deg2rad((float)$startingCoordinates['lat']);
        $startingCoordinates['lon'] = deg2rad((float)$startingCoordinates['lon']);
        $bearing = deg2rad($bearing);
        $angularDistance = $distance / Maps_EARTH_RADIUS;
        $lat = asin(
            sin($startingCoordinates['lat']) * cos( $angularDistance) +
            cos($startingCoordinates['lat']) * sin( $angularDistance) * cos($bearing)
        );
        return array(
            'lat' => rad2deg($lat),
            'lon' => rad2deg($startingCoordinates['lon'] + atan2(
                    sin($bearing ) * sin($angularDistance ) * cos($startingCoordinates['lat']),
                    cos($angularDistance) - sin($startingCoordinates['lat'] ) * sin($lat)
            ))
        );
}

Тестирование с findDestination(array('lat' => 40.7142691, 'lon' => -74.0059729), 90, 1000) дает результат 40.714268492616,-73.994108059287, который, я думаю, больше похож на то, что вы ищете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...