여러 위도 / 경도 좌표 쌍의 중심점 계산


148

위도 및 경도 포인트 세트가 주어지면 해당 세트의 중심점 (모든 포인트에서 뷰를 중심으로하는 포인트)의 위도 및 경도를 어떻게 계산할 수 있습니까?

편집 : 내가 사용한 Python 솔루션 :

Convert lat/lon (must be in radians) to Cartesian coordinates for each location.
X = cos(lat) * cos(lon)
Y = cos(lat) * sin(lon)
Z = sin(lat)

Compute average x, y and z coordinates.
x = (x1 + x2 + ... + xn) / n
y = (y1 + y2 + ... + yn) / n
z = (z1 + z2 + ... + zn) / n

Convert average x, y, z coordinate to latitude and longitude.
Lon = atan2(y, x)
Hyp = sqrt(x * x + y * y)
Lat = atan2(z, hyp)

2
당신의 해결책에 관하여 : 아마도 당신의 오차는 구형 지구를 가정하면 너무 크지 않을 것입니다. 그러나 지구는 타원체로 더 잘 묘사됩니다.
John

1
파이썬 함수로 쓴과 그것을 공유 gist.github.com/3718961
앨빈

14
위도 및 경도는 라디안 인 것으로 가정합니다. 나는 그것을 깨닫지 못하는 동안 내 머리를 긁적이었다. 10 진수에서 라디안으로 변환하려면 decimal * pi / 180을 곱하십시오. 그런 다음 라디안에서 10 진수로 다시 변환하려면 180 / pi를 곱하십시오. HTH
Ryan Guill

1
늦어서 죄송하지만이 알고리즘의 수학은 무엇인지 궁금합니다. 감사!
tonix

1
zpls 는 무엇입니까 ?
SoS

답변:


48

그것들을 평균화하는 간단한 접근 방식은 359 '에서 0'으로 다시 랩핑 할 때 각도가 이상한 가장자리 케이스가 있습니다.

SO에 대한 훨씬 이전의 질문 은 일련의 나침반 각도의 평균을 찾는 것에 대해 물었습니다.

구형 좌표에 대해 권장되는 접근 방식의 확장은 다음과 같습니다.

  • 각 위도 / 경도 쌍을 단위 길이 3D 벡터로 변환합니다.
  • 각 벡터를 합산
  • 결과 벡터를 정규화
  • 구형 좌표로 다시 변환

6
이 웹 사이트에서 찾은 내용에 따라 geomidpoint.com/calculation.html 과 비슷한 작업을 수행 한 것 같습니다 .
zeke

4
downvoter-설명하고 가능한 경우 더 나은 솔루션을 제공하십시오.
Alnitak

90

감사! 다음은 학위를 사용하는 OP 솔루션의 C # 버전입니다. System.Device.Location.GeoCoordinate 클래스를 활용합니다.

    public static GeoCoordinate GetCentralGeoCoordinate(
        IList<GeoCoordinate> geoCoordinates)
    {
        if (geoCoordinates.Count == 1)
        {
            return geoCoordinates.Single();
        }

        double x = 0;
        double y = 0;
        double z = 0;

        foreach (var geoCoordinate in geoCoordinates)
        {
            var latitude = geoCoordinate.Latitude * Math.PI / 180;
            var longitude = geoCoordinate.Longitude * Math.PI / 180;

            x += Math.Cos(latitude) * Math.Cos(longitude);
            y += Math.Cos(latitude) * Math.Sin(longitude);
            z += Math.Sin(latitude);
        }

        var total = geoCoordinates.Count;

        x = x / total;
        y = y / total;
        z = z / total;

        var centralLongitude = Math.Atan2(y, x);
        var centralSquareRoot = Math.Sqrt(x * x + y * y);
        var centralLatitude = Math.Atan2(z, centralSquareRoot);

        return new GeoCoordinate(centralLatitude * 180 / Math.PI, centralLongitude * 180 / Math.PI);
    }

40

이 게시물이 매우 유용하므로 PHP의 솔루션이 있습니다. 나는 이것을 성공적으로 사용하고 있었고 다른 개발자를 시간을 절약하고 싶었습니다.

/**
 * Get a center latitude,longitude from an array of like geopoints
 *
 * @param array data 2 dimensional array of latitudes and longitudes
 * For Example:
 * $data = array
 * (
 *   0 = > array(45.849382, 76.322333),
 *   1 = > array(45.843543, 75.324143),
 *   2 = > array(45.765744, 76.543223),
 *   3 = > array(45.784234, 74.542335)
 * );
*/
function GetCenterFromDegrees($data)
{
    if (!is_array($data)) return FALSE;

    $num_coords = count($data);

    $X = 0.0;
    $Y = 0.0;
    $Z = 0.0;

    foreach ($data as $coord)
    {
        $lat = $coord[0] * pi() / 180;
        $lon = $coord[1] * pi() / 180;

        $a = cos($lat) * cos($lon);
        $b = cos($lat) * sin($lon);
        $c = sin($lat);

        $X += $a;
        $Y += $b;
        $Z += $c;
    }

    $X /= $num_coords;
    $Y /= $num_coords;
    $Z /= $num_coords;

    $lon = atan2($Y, $X);
    $hyp = sqrt($X * $X + $Y * $Y);
    $lat = atan2($Z, $hyp);

    return array($lat * 180 / pi(), $lon * 180 / pi());
}

1
이 솔루션을 사용했지만 어떤 방식 으로든 잘못된 솔루션을 제공합니다.지도에서 일부 좌표의 중심을 검색하면 포인트의 "무게"와 더 많은 포인트가있는 곳에 머무는 경향이 있습니다.
LowFieldTheory

2
@Alnitak 여기서 좌표로 둘러싸인 영역의 중심을 검색하려고합니다. 올바른 장소에 댓글을 달았습니까?
LowFieldTheory

29

매우 유용한 게시물! 이 코드를 JavaScript로 구현했습니다. 나는 이것을 성공적으로 사용했다.

function rad2degr(rad) { return rad * 180 / Math.PI; }
function degr2rad(degr) { return degr * Math.PI / 180; }

/**
 * @param latLngInDeg array of arrays with latitude and longtitude
 *   pairs in degrees. e.g. [[latitude1, longtitude1], [latitude2
 *   [longtitude2] ...]
 *
 * @return array with the center latitude longtitude pairs in 
 *   degrees.
 */
function getLatLngCenter(latLngInDegr) {
    var LATIDX = 0;
    var LNGIDX = 1;
    var sumX = 0;
    var sumY = 0;
    var sumZ = 0;

    for (var i=0; i<latLngInDegr.length; i++) {
        var lat = degr2rad(latLngInDegr[i][LATIDX]);
        var lng = degr2rad(latLngInDegr[i][LNGIDX]);
        // sum of cartesian coordinates
        sumX += Math.cos(lat) * Math.cos(lng);
        sumY += Math.cos(lat) * Math.sin(lng);
        sumZ += Math.sin(lat);
    }

    var avgX = sumX / latLngInDegr.length;
    var avgY = sumY / latLngInDegr.length;
    var avgZ = sumZ / latLngInDegr.length;

    // convert average x, y, z coordinate to latitude and longtitude
    var lng = Math.atan2(avgY, avgX);
    var hyp = Math.sqrt(avgX * avgX + avgY * avgY);
    var lat = Math.atan2(avgZ, hyp);

    return ([rad2degr(lat), rad2degr(lng)]);
}


1
게시물이 오래되었다는 것을 알고 있지만 게시 한 알고리즘 뒤에있는 수학을 설명하는 참조 나 무언가를 게시 할 수 있습니까? 감사!
tonix

완벽하게 일했습니다! 감사합니다
andrewoodleyjr

Google Apps Script로 스크립트를 테스트했지만 결과는 트랙의 정확한 중심점이 아닙니다. 근처 어딘가에 있지만 트랙에 직접 있지는 않습니다. 트랙에서 정확한 중간 점을 얻는 더 좋은 공식이 있습니까?
Dirk

12

원래 함수의 자바 스크립트 버전

/**
 * Get a center latitude,longitude from an array of like geopoints
 *
 * @param array data 2 dimensional array of latitudes and longitudes
 * For Example:
 * $data = array
 * (
 *   0 = > array(45.849382, 76.322333),
 *   1 = > array(45.843543, 75.324143),
 *   2 = > array(45.765744, 76.543223),
 *   3 = > array(45.784234, 74.542335)
 * );
*/
function GetCenterFromDegrees(data)
{       
    if (!(data.length > 0)){
        return false;
    } 

    var num_coords = data.length;

    var X = 0.0;
    var Y = 0.0;
    var Z = 0.0;

    for(i = 0; i < data.length; i++){
        var lat = data[i][0] * Math.PI / 180;
        var lon = data[i][1] * Math.PI / 180;

        var a = Math.cos(lat) * Math.cos(lon);
        var b = Math.cos(lat) * Math.sin(lon);
        var c = Math.sin(lat);

        X += a;
        Y += b;
        Z += c;
    }

    X /= num_coords;
    Y /= num_coords;
    Z /= num_coords;

    var lon = Math.atan2(Y, X);
    var hyp = Math.sqrt(X * X + Y * Y);
    var lat = Math.atan2(Z, hyp);

    var newX = (lat * 180 / Math.PI);
    var newY = (lon * 180 / Math.PI);

    return new Array(newX, newY);
}

12

1 ~ 2 분 정도 누군가를 구할 수 있도록하기 위해 Python 대신 Objective-C에서 사용 된 솔루션이 있습니다. 이 버전은 MKMapCoordinates를 포함하는 NSValue의 NSArray를 취합니다.

#import <MapKit/MKGeometry.h>
+ (CLLocationCoordinate2D)centerCoordinateForCoordinates:(NSArray *)coordinateArray {
    double x = 0;
    double y = 0;
    double z = 0;

    for(NSValue *coordinateValue in coordinateArray) {
        CLLocationCoordinate2D coordinate = [coordinateValue MKCoordinateValue];

        double lat = GLKMathDegreesToRadians(coordinate.latitude);
        double lon = GLKMathDegreesToRadians(coordinate.longitude);
        x += cos(lat) * cos(lon);
        y += cos(lat) * sin(lon);
        z += sin(lat);
    }

    x = x / (double)coordinateArray.count;
    y = y / (double)coordinateArray.count;
    z = z / (double)coordinateArray.count;

    double resultLon = atan2(y, x);
    double resultHyp = sqrt(x * x + y * y);
    double resultLat = atan2(z, resultHyp);

    CLLocationCoordinate2D result = CLLocationCoordinate2DMake(GLKMathRadiansToDegrees(resultLat), GLKMathRadiansToDegrees(resultLon));
    return result;
}

2
대한 거기 누구, 무엇의 가치, 대신 라디안, 수입에도에 대한 자신의 매크로를 사용 <GLKit/GLKMath.h>하고 사용 GLKMathDegreesToRadians하고GLKMathRadiansToDegrees
pnizzle

8

아주 좋은 솔루션, 신속한 프로젝트에 필요한 것이므로 여기에 신속한 포트가 있습니다. 감사합니다 & 놀이터 프로젝트도 있습니다 : https://github.com/ppoh71/playgounds/tree/master/centerLocationPoint.playground

/*
* calculate the center point of multiple latitude longitude coordinate-pairs
*/

import CoreLocation
import GLKit

var LocationPoints = [CLLocationCoordinate2D]()

//add some points to Location ne, nw, sw, se , it's a rectangle basicaly
LocationPoints.append(CLLocationCoordinate2D(latitude: 37.627512369999998, longitude: -122.38780611999999))
LocationPoints.append(CLLocationCoordinate2D(latitude: 37.627512369999998, longitude:  -122.43105867))
LocationPoints.append(CLLocationCoordinate2D(latitude: 37.56502528, longitude: -122.43105867))
LocationPoints.append(CLLocationCoordinate2D(latitude: 37.56502528, longitude: -122.38780611999999))

// center func
func getCenterCoord(LocationPoints: [CLLocationCoordinate2D]) -> CLLocationCoordinate2D{

    var x:Float = 0.0;
    var y:Float = 0.0;
    var z:Float = 0.0;

    for points in LocationPoints {

     let lat = GLKMathDegreesToRadians(Float(points.latitude));
     let long = GLKMathDegreesToRadians(Float(points.longitude));

        x += cos(lat) * cos(long);
        y += cos(lat) * sin(long);
        z += sin(lat);
    }

    x = x / Float(LocationPoints.count);
    y = y / Float(LocationPoints.count);
    z = z / Float(LocationPoints.count);

    let resultLong = atan2(y, x);
    let resultHyp = sqrt(x * x + y * y);
    let resultLat = atan2(z, resultHyp);



    let result = CLLocationCoordinate2D(latitude: CLLocationDegrees(GLKMathRadiansToDegrees(Float(resultLat))), longitude: CLLocationDegrees(GLKMathRadiansToDegrees(Float(resultLong))));

    return result;

}

//get the centerpoint
var centerPoint = getCenterCoord(LocationPoints)
print("Latitude: \(centerPoint.latitude) / Longitude: \(centerPoint.longitude)")

4

점의 매우 단순화 된 '중심'을 얻는 데 관심이 있다면 (예를 들어 단순히 맵을 gmaps 다각형의 중심에 맞추기 위해), 다음은 나에게 도움이되는 기본 접근법입니다.

public function center() {
    $minlat = false;
    $minlng = false;
    $maxlat = false;
    $maxlng = false;
    $data_array = json_decode($this->data, true);
    foreach ($data_array as $data_element) {
        $data_coords = explode(',',$data_element);
        if (isset($data_coords[1])) {
            if ($minlat === false) { $minlat = $data_coords[0]; } else { $minlat = ($data_coords[0] < $minlat) ? $data_coords[0] : $minlat; }
            if ($maxlat === false) { $maxlat = $data_coords[0]; } else { $maxlat = ($data_coords[0] > $maxlat) ? $data_coords[0] : $maxlat; }
            if ($minlng === false) { $minlng = $data_coords[1]; } else { $minlng = ($data_coords[1] < $minlng) ? $data_coords[1] : $minlng; }
            if ($maxlng === false) { $maxlng = $data_coords[1]; } else { $maxlng = ($data_coords[1] > $maxlng) ? $data_coords[1] : $maxlng; }
        }
    }
    $lat = $maxlat - (($maxlat - $minlat) / 2);
    $lng = $maxlng - (($maxlng - $minlng) / 2);
    return $lat.','.$lng;
}

다각형 중심의 중간 위도 / 경도 좌표를 반환합니다.


4

Django에서 이것은 사소한 것입니다 (실제로는 위도에 대한 음수를 올바르게 반환하지 않는 여러 솔루션에 문제가 있음).

예를 들어 django-geopostcodes (저는 저자입니다)를 사용한다고 가정 해 봅시다 .

from django.contrib.gis.geos import MultiPoint
from django.contrib.gis.db.models.functions import Distance
from django_geopostcodes.models import Locality

qs = Locality.objects.anything_icontains('New York')
points = [locality.point for locality in qs]
multipoint = MultiPoint(*points)
point = multipoint.centroid

pointDjango Point인스턴스는 중심점에서 10km 이내에있는 모든 객체를 검색하는 등의 작업을 수행하는 데 사용할 수 있습니다.

Locality.objects.filter(point__distance_lte=(point, D(km=10)))\
    .annotate(distance=Distance('point', point))\
    .order_by('distance')

이것을 원시 파이썬으로 변경하는 것은 쉽지 않습니다.

from django.contrib.gis.geos import Point, MultiPoint

points = [
    Point((145.137075, -37.639981)),
    Point((144.137075, -39.639981)),
]
multipoint = MultiPoint(*points)
point = multipoint.centroid

Django는 GEOS를 사용하고 있습니다-자세한 내용은 https://docs.djangoproject.com/en/1.10/ref/contrib/gis/geos/


3

필요한 경우 Java 버전. 상수는 두 번 계산하지 않도록 정적으로 정의되었습니다.

/**************************************************************************************************************
 *   Center of geometry defined by coordinates
 **************************************************************************************************************/
private static double pi = Math.PI / 180;
private static double xpi = 180 / Math.PI;

public static Coordinate center(Coordinate... arr) {
    if (arr.length == 1) {
        return arr[0];
    }
    double x = 0, y = 0, z = 0;

    for (Coordinate c : arr) {
        double latitude = c.lat() * pi, longitude = c.lon() * pi;
        double cl = Math.cos(latitude);//save it as we need it twice
        x += cl * Math.cos(longitude);
        y += cl * Math.sin(longitude);
        z += Math.sin(latitude);
    }

    int total = arr.length;

    x = x / total;
    y = y / total;
    z = z / total;

    double centralLongitude = Math.atan2(y, x);
    double centralSquareRoot = Math.sqrt(x * x + y * y);
    double centralLatitude = Math.atan2(z, centralSquareRoot);

    return new Coordinate(centralLatitude * xpi, centralLongitude * xpi);
}

3

다음은 Google지도 API를 사용한 @Yodacheese의 C # 답변을 기반으로하는 Android 버전입니다.

public static LatLng GetCentralGeoCoordinate(List<LatLng> geoCoordinates) {        
    if (geoCoordinates.size() == 1)
    {
        return geoCoordinates.get(0);
    }

    double x = 0;
    double y = 0;
    double z = 0;

    for(LatLng geoCoordinate : geoCoordinates)
    {
        double  latitude = geoCoordinate.latitude * Math.PI / 180;
        double longitude = geoCoordinate.longitude * Math.PI / 180;

        x += Math.cos(latitude) * Math.cos(longitude);
        y += Math.cos(latitude) * Math.sin(longitude);
        z += Math.sin(latitude);
    }

    int total = geoCoordinates.size();

    x = x / total;
    y = y / total;
    z = z / total;

    double centralLongitude = Math.atan2(y, x);
    double centralSquareRoot = Math.sqrt(x * x + y * y);
    double centralLatitude = Math.atan2(z, centralSquareRoot);

    return new LatLng(centralLatitude * 180 / Math.PI, centralLongitude * 180 / Math.PI);

}

앱 build.gradle에서 다음을 추가하십시오.

implementation 'com.google.android.gms:play-services-maps:17.0.0'

2

Flutter의 Dart 구현으로 다중 위도, 경도의 중심점을 찾습니다.

수학 패키지 가져 오기

import 'dart:math' as math;

위도 및 경도 목록

List<LatLng> latLongList = [LatLng(12.9824, 80.0603),LatLng(13.0569,80.2425,)];

void getCenterLatLong(List<LatLng> latLongList) {
    double pi = math.pi / 180;
    double xpi = 180 / math.pi;
    double x = 0, y = 0, z = 0;

    if(latLongList.length==1)
    {
        return latLongList[0];
    }
    for (int i = 0; i < latLongList.length; i++) {
      double latitude = latLongList[i].latitude * pi;
      double longitude = latLongList[i].longitude * pi;
      double c1 = math.cos(latitude);
      x = x + c1 * math.cos(longitude);
      y = y + c1 * math.sin(longitude);
      z = z + math.sin(latitude);
    }

    int total = loadList.length;
    x = x / total;
    y = y / total;
    z = z / total;

    double centralLongitude = math.atan2(y, x);
    double centralSquareRoot = math.sqrt(x * x + y * y);
    double centralLatitude = math.atan2(z, centralSquareRoot);

    return LatLng(centralLatitude*xpi,centralLongitude*xpi);
}

1

이것은 모든 가중치가 동일하고 2 차원이있는 가중 평균 문제와 동일합니다.

중심 위도에 대한 모든 위도의 평균과 중심 경도에 대한 모든 경도의 평균을 찾으십시오.

Caveat Emptor : 이것은 근거리 근사치이며 지구의 곡률로 인해 평균과의 편차가 수 마일 이상이면 오류가 거의 발생하지 않습니다. 위도와 경도는도 (실제로 그리드가 아님)입니다.


1
[-179,0], [+ 179,0] 올바른 결과로부터 약간 멀리 [0,0]에서의 평균)
Piskvor 건물 왼쪽


1

PHP에서 개체가 부족합니다. 주어진 좌표 쌍의 배열은 중심을 반환합니다.

/**
 * Calculate center of given coordinates
 * @param  array    $coordinates    Each array of coordinate pairs
 * @return array                    Center of coordinates
 */
function getCoordsCenter($coordinates) {    
    $lats = $lons = array();
    foreach ($coordinates as $key => $value) {
        array_push($lats, $value[0]);
        array_push($lons, $value[1]);
    }
    $minlat = min($lats);
    $maxlat = max($lats);
    $minlon = min($lons);
    $maxlon = max($lons);
    $lat = $maxlat - (($maxlat - $minlat) / 2);
    $lng = $maxlon - (($maxlon - $minlon) / 2);
    return array("lat" => $lat, "lon" => $lng);
}

# 4에서 가져온 아이디어


1
180 자오선을 가로 지르는 좌표에는 적용되지 않습니다. 예를 들어, -175와 175의 두 개의 longitudal point는 알고리즘에서 0의 중심을 반환하므로 실제 중심은 -180 또는 180입니다.
Winch

1

중심점을 찾기위한 파이썬 버전입니다. lat1 및 lon1은 위도 및 경도 목록입니다. 중심점의 위도와 경도를 조정합니다.

def GetCenterFromDegrees(lat1,lon1):    
    if (len(lat1) <= 0):
    return false;

num_coords = len(lat1)

X = 0.0
Y = 0.0
Z = 0.0

for i in range (len(lat1)):
    lat = lat1[i] * np.pi / 180
    lon = lon1[i] * np.pi / 180

    a = np.cos(lat) * np.cos(lon)
    b = np.cos(lat) * np.sin(lon)
    c = np.sin(lat);

    X += a
    Y += b
    Z += c


X /= num_coords
Y /= num_coords
Z /= num_coords

lon = np.arctan2(Y, X)
hyp = np.sqrt(X * X + Y * Y)
lat = np.arctan2(Z, hyp)

newX = (lat * 180 / np.pi)
newY = (lon * 180 / np.pi)
return newX, newY

1

다트 / 필터 여러 위도 / 경도 좌표 쌍의 중심점을 계산합니다.

Map<String, double> getLatLngCenter(List<List<double>> coords) {
    const LATIDX = 0;
    const LNGIDX = 1;
    double sumX = 0;
    double sumY = 0;
    double sumZ = 0;

    for (var i = 0; i < coords.length; i++) {
      var lat = VectorMath.radians(coords[i][LATIDX]);
      var lng = VectorMath.radians(coords[i][LNGIDX]);
      // sum of cartesian coordinates
      sumX += Math.cos(lat) * Math.cos(lng);
      sumY += Math.cos(lat) * Math.sin(lng);
      sumZ += Math.sin(lat);
    }

    var avgX = sumX / coords.length;
    var avgY = sumY / coords.length;
    var avgZ = sumZ / coords.length;

    // convert average x, y, z coordinate to latitude and longtitude
    var lng = Math.atan2(avgY, avgX);
    var hyp = Math.sqrt(avgX * avgX + avgY * avgY);
    var lat = Math.atan2(avgZ, hyp);

    return {
      "latitude": VectorMath.degrees(lat),
      "longitude": VectorMath.degrees(lng)
    };
  }

0

이미지에 모든 점을 표시하려면 위도 및 경도의 극한을 원하고 원하는 경계가있는 값이 뷰에 포함되도록해야합니다.

(Alnitak의 답변에 따르면, 극한을 계산하는 방법은 약간 문제가 될 수 있지만, 그들이 감싸는 경도의 양쪽에서 약간의 각도에 있다면, 당신은 샷을 호출하고 올바른 범위를 취할 것입니다.)

이러한 점이있는 맵을 왜곡하지 않으려면 경계 상자의 종횡비를 조정하여 뷰에 할당했지만 아무 극값도 포함하도록 픽셀에 맞도록 조정하십시오.

점을 임의의 확대 / 축소 수준으로 중앙에 유지하려면 위와 같이 점을 "적합한"경계 상자의 중심을 계산하고 그 점을 중심점으로 유지하십시오.


0

아래처럼 자바 스크립트 로이 작업을 수행했습니다.

function GetCenterFromDegrees(data){
    // var data = [{lat:22.281610498720003,lng:70.77577162868579},{lat:22.28065743343672,lng:70.77624369747241},{lat:22.280860953131217,lng:70.77672113067706},{lat:22.281863655593973,lng:70.7762061465462}];
    var num_coords = data.length;
    var X = 0.0;
    var Y = 0.0;
    var Z = 0.0;

    for(i=0; i<num_coords; i++){
        var lat = data[i].lat * Math.PI / 180;
        var lon = data[i].lng * Math.PI / 180;
        var a = Math.cos(lat) * Math.cos(lon);
        var b = Math.cos(lat) * Math.sin(lon);
        var c = Math.sin(lat);

        X += a;
        Y += b;
        Z += c;
    }

    X /= num_coords;
    Y /= num_coords;
    Z /= num_coords;

    lon = Math.atan2(Y, X);
    var hyp = Math.sqrt(X * X + Y * Y);
    lat = Math.atan2(Z, hyp);

    var finalLat = lat * 180 / Math.PI;
    var finalLng =  lon * 180 / Math.PI; 

    var finalArray = Array();
    finalArray.push(finalLat);
    finalArray.push(finalLng);
    return finalArray;
}

0

이 글에 감사하는 마음으로 Ruby의 구현에 약간의 기여를했으며 귀중한 시간에서 몇 분을 구할 수 있기를 바랍니다.

def self.find_center(locations)

 number_of_locations = locations.length

 return locations.first if number_of_locations == 1

 x = y = z = 0.0
 locations.each do |station|
   latitude = station.latitude * Math::PI / 180
   longitude = station.longitude * Math::PI / 180

   x += Math.cos(latitude) * Math.cos(longitude)
   y += Math.cos(latitude) * Math.sin(longitude)
   z += Math.sin(latitude)
 end

 x = x/number_of_locations
 y = y/number_of_locations
 z = z/number_of_locations

 central_longitude =  Math.atan2(y, x)
 central_square_root = Math.sqrt(x * x + y * y)
 central_latitude = Math.atan2(z, central_square_root)

 [latitude: central_latitude * 180 / Math::PI, 
 longitude: central_longitude * 180 / Math::PI]
end

0

www.geomidpoint.com에서 얻은 수식을 사용하여 다음 C ++ 구현을 작성했습니다. arraygeocoords그 기능 자체 설명해야 내 자신의 클래스입니다.

/*
 * midpoints calculated using formula from www.geomidpoint.com
 */
   geocoords geocoords::calcmidpoint( array<geocoords>& points )
   {
      if( points.empty() ) return geocoords();

      float cart_x = 0,
            cart_y = 0,
            cart_z = 0;

      for( auto& point : points )
      {
         cart_x += cos( point.lat.rad() ) * cos( point.lon.rad() );
         cart_y += cos( point.lat.rad() ) * sin( point.lon.rad() );
         cart_z += sin( point.lat.rad() );
      }

      cart_x /= points.numelems();
      cart_y /= points.numelems();
      cart_z /= points.numelems();

      geocoords mean;

      mean.lat.rad( atan2( cart_z, sqrt( pow( cart_x, 2 ) + pow( cart_y, 2 ))));
      mean.lon.rad( atan2( cart_y, cart_x ));

      return mean;
   }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.