Birden çok enlem / boylam koordinat çiftinin merkez noktasını hesaplayın


152

Bir dizi enlem ve boylam noktası verildiğinde, bu kümenin merkez noktasının enlem ve boylamını nasıl hesaplayabilirim (diğer bir deyişle, bir görünümü tüm noktalara ortalayacak bir nokta)?

DÜZENLEME: Kullandığım Python çözümü:

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
Çözümünüzle ilgili olarak: Küresel bir dünya varsayımınızla muhtemelen hatalarınız çok büyük olmayacaktır, ancak dünya bir elipsoid olarak daha iyi tanımlanır.
John

1
Bunu bir python işlevi olarak yazdı ve gist.github.com/3718961
Alvin

14
Bunun, enlem ve boy değerinizin radyan cinsinden olduğunu varsaydığına dikkat etmek çok önemlidir! Bir süredir farkında olmadan kafamı kaşıyordum. Ondalıktan radyana dönüştürmek için ondalık * pi / 180 ile çarpın. Sonra radyanlardan ondalık sayıya dönüştürmek için 180 / pi ile çarpın. HTH
Ryan Guill

1
Geç kaldığım için üzgünüm, ama merak ediyordum, bu algoritmanın ardındaki matematik nedir, biri bana bunun açıklandığı bazı okumalar önerebilir mi? Teşekkürler!
tonix

1
Nedir z, lütfen?
SoS

Yanıtlar:


50

Sadece ortalamasını almanın basit yaklaşımı, 359'dan 0'a sardıklarında açılı garip kenar durumlarına sahiptir.

Bir SO üzerinde çok daha erken bir soru pusula açıları bir dizi ortalama bulma konusunda istedi.

Küresel koordinatlar için orada önerilen yaklaşımın genişletilmesi şöyle olacaktır:

  • Her enlem / boylam çifti birim uzunluklu 3B vektöre dönüştürün.
  • Bu vektörlerin her birini toplayın
  • Ortaya çıkan vektörü normalleştirin
  • Küresel koordinatlara geri dön

6
İyi görünüyor, bu web sitesinde bulduklarıma dayanarak benzer bir şey yaptım: geomidpoint.com/calculation.html .
zeke

4
Olumsuz oy veren - lütfen açıklayın ve mümkünse daha iyi bir çözüm önerin.
Alnitak

90

Teşekkürler! İşte derece kullanan OP çözümlerinin bir C # sürümü. System.Device.Location.GeoCoordinate sınıfını kullanır

    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);
    }

41

Bu yazıyı çok faydalı buldum, işte PHP'deki çözüm. Bunu başarılı bir şekilde kullanıyorum ve bir süre başka bir geliştirici kaydetmek istedim.

/**
 * 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
Bu çözümü kullandım ama bir şekilde yanlış bir çözüm veriyor - bir haritada bazı koordinatların merkezini araştırırsam, noktaları "tartar" ve daha fazla noktanın olduğu yerde kalma eğilimindedir.
LowFieldTheory

2
@Alnitak Burada koordinatlarla çevrili alanın merkezini aramak istiyoruz. Doğru yere yorum yaptığınızdan emin misiniz?
LowFieldTheory

32

Çok faydalı gönderi! Bunu JavaScript'te uyguladım, burada kodum. Bunu başarıyla kullandım.

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
Gönderinin eski olduğunu biliyorum, ancak lütfen gönderdiğiniz algoritmanın arkasındaki Matematiği açıklayan bir referans veya başka bir şey gönderebilir misiniz? Teşekkürler!
tonix

Mükemmel Çalıştı! Teşekkürler
andrewoodleyjr

Komut dosyasını Google Apps Komut Dosyası ile test ettim, ancak sonuç bir parçanın tam merkez noktası değil. Yakınlarda bir yerdedir ancak doğrudan pistte değil. PARÇADA tam orta noktayı elde etmek için daha iyi bir formül var mı?
Dirk

13

Orijinal işlevin Javascript sürümü

/**
 * 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

Muhtemelen birini bir veya iki dakika kurtarmak adına, işte Python yerine Objective-C'de kullanılan çözüm. Bu sürüm, uygulamamda çağrılan MKMapCoordinates'i içeren NSValues ​​NSArray'i alır:

#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
Dışarıdaki herkes için, değeri ne <GLKit/GLKMath.h>GLKMathDegreesToRadiansGLKMathRadiansToDegrees
olursa olsun, Radyana

10

çok güzel çözümler, hızlı projem için tam da ihtiyacım olan şey, işte hızlı bir liman. teşekkürler & işte bir oyun alanı projesi: 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

Noktaların çok basitleştirilmiş bir 'merkezini' elde etmekle ilgileniyorsanız (örneğin, bir haritayı boşluk poligonunuzun merkezine basitçe ortalamak için), işte benim için işe yarayan temel bir yaklaşım.

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;
}

Bu, bir çokgenin merkezi için orta enlem / boylam koordinatını döndürür.


4

Django'da bu önemsizdir (ve aslında işe yarıyor, enlem için negatifleri doğru şekilde döndürmeyen bazı çözümlerle ilgili sorunlar yaşadım).

Örneğin, django-geopostcodes kullandığınızı varsayalım (bunların yazarı benim).

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

pointdaha Pointsonra merkez noktasının 10 km içindeki tüm nesneleri almak gibi şeyler yapmak için kullanılabilen bir Django örneğidir;

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

Bunu ham Python'a değiştirmek önemsizdir;

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

Davanın altında Django GEOS kullanıyor - daha fazla ayrıntı https://docs.djangoproject.com/en/1.10/ref/contrib/gis/geos/ adresinde


3

Herhangi birinin ihtiyacı varsa Java Sürümü. Sabitler, iki kez hesaplanmamak için statik olarak tanımlandı.

/**************************************************************************************************************
 *   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 Haritalar api kullanan @ Yodacheese'nin C # yanıtına dayanan Android sürümü:

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);

}

uygulama build.gradle'da ekleyin:

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

2

Çoklu Enlem, Boylam için Merkez noktasını bulmak için Flutter için Dart Uygulaması .

matematik paketini içe aktar

import 'dart:math' as math;

Enlem ve Boylam Listesi

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

LatLng 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 = latLongList.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

Bu, tüm ağırlıkların aynı olduğu ve iki boyutun bulunduğu ağırlıklı ortalama problemi ile aynıdır.

Merkez enleminiz için tüm enlemlerin ortalamasını ve merkez boylam için tüm boylamların ortalamasını bulun.

Caveat Emptor: Bu bir yakın mesafe tahminidir ve Dünya'nın eğriliği nedeniyle ortalamadan sapmalar birkaç milden fazla olduğunda hata asılsız hale gelecektir. Enlemlerin ve boylamların derece olduğunu unutmayın (gerçekte bir ızgara değildir).


1
[-179,0], [+ 179,0] ortalama [0,0], bu doğru sonuçtan biraz uzak;)
Piskvor,


1

PHP'de nesne dışı. Verilen koordinat çifti dizisi, merkeze döner.

/**
 * 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'ten fikir alındı


1
Bu 180. meridyeni geçen koordinatlar için işe yaramaz. Örneğin, iki uzunlamasına nokta, -175 ve 175, algoritmanızda 0'ın bir merkezini döndürür ve gerçek merkez -180 veya 180 olur.
Winch

1

İşte merkez noktasını bulmak için kullanılan python Versiyonu. Enlem1 ve lon1, enlem ve boylam listeleridir. merkez noktanın enlem ve boylamını değiştirecektir.

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

Dart / Flutter Birden çok enlem / boylam koordinat çiftinin merkez noktasını hesaplayın

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

Görüntüde tüm noktaların görünür olmasını istiyorsanız, enlem ve boylam olarak ekstremanın olmasını istersiniz ve görünümünüzün, istediğiniz sınıra sahip bu değerleri içerdiğinden emin olun.

(Alnitak'ın cevabına göre, ekstremayı nasıl hesapladığınız biraz sorunlu olabilir, ancak etrafı saran boylamın her iki tarafında birkaç derece iseler, o zaman çekimi çağırır ve doğru mesafeyi alırsınız.)

Bu noktaların üzerinde olduğu haritayı deforme etmek istemiyorsanız, sınırlayıcı kutunun en boy oranını, görünüme tahsis ettiğiniz piksellere uyacak ancak ekstremayı içerecek şekilde ayarlayın.

Noktaları rastgele bir yakınlaştırma düzeyinde ortalamak için, yukarıdaki noktalara "tam olarak uyan" sınırlayıcı kutunun merkezini hesaplayın ve bu noktayı merkez noktası olarak tutun.


0

Bu görevi javascript'te aşağıdaki gibi yaptım

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

Bu ileti dizisine bir minnettarlık olarak, Ruby'deki uygulamayla ilgili küçük katkım, birisini değerli zamanlarından birkaç dakika kurtaracağımı umuyorum:

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'dan aldığım bir formül kullandım ve aşağıdaki C ++ uygulamasını yazdım. arrayVe geocoordskimin işlevsellik kendini açıklayıcı olmalıdır kendi sınıflardır.

/*
 * 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;
   }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.