Comment puis-je calculer la moyenne entre plusieurs spots de latitude et de longitude?
Dois-je simplement calculer la moyenne arithmétique pour lat et lng?
Comment puis-je calculer la moyenne entre plusieurs spots de latitude et de longitude?
Dois-je simplement calculer la moyenne arithmétique pour lat et lng?
Réponses:
Pour une moyenne simple, vous ne voulez pas faire la moyenne des coordonnées de longitude et de latitude. Cela pourrait fonctionner assez bien aux latitudes inférieures, mais aux latitudes plus élevées, cela commencera à donner de mauvais résultats et à se décomposer complètement près des pôles.
La méthode que j'ai utilisée pour ce type de chose est de convertir les coordonnées de longitude / latitude en coordonnées cartésiennes 3d (x, y, z). Faites la moyenne de ceux-ci (pour donner un vecteur cartésien), puis reconvertissez-la. Notez que vous n'avez probablement pas besoin de normaliser le vecteur, donc le processus moyen réel pourrait être une simple somme.
Edit, voici mon code c # :
Ce qui suit convertit les coordonnées cartésiennes en latitude / longitude (en degrés): supprimez les RAD2DEG
constantes des radians.
Latitude = MPUtility.RAD2DEG * Math.Atan2(z, Math.Sqrt(x * x + y * y));
Longitude = MPUtility.RAD2DEG * Math.Atan2(-y, x);
Et ici, nous calculons les coordonnées cartésiennes à partir de la latitude / longitude (spécifiées en radians):
private void CalcCartesianCoord()
{
_x = Math.Sin(LatitudeRadians) * Math.Cos(LongitudeRadians);
_y = Math.Sin(LatitudeRadians) * Math.Sin(LongitudeRadians);
_z = Math.Cos(LatitudeRadians);
}
Les deux sont copiés et collés à partir du code réel, d'où le mélange de degrés et de radians. Il existe ici des propriétés qui effectuent certaines des conversions (par exemple, LatitudeRadians
une propriété qui renvoie une valeur en radians).
Notez que l'optimisation est possible: les calculs de sinus en double, par exemple. Les calculs de trig peuvent également être mis en cache si vous les appelez souvent.
Options de clustering : Je pense que le mot à la mode conceptuel qui couvre ce type d'opération est "clustering". La moyenne est de loin la plus simple à mettre en œuvre et fonctionne bien dans la plupart des cas. La seule fois où j'utiliserais autre chose, c'est si vous vous inquiétez des valeurs aberrantes [Modifier] -> ou des pôles ou de la ligne de données internationale. [Modifier] -> également la moyenne, même si cela vous donnera quelque chose qui ressemble au centre de la grappe, sera un peu hors tension en raison des inexactitudes de projection causées par le fait que les degrés lat lng ne sont pas toujours la même distance à part en km / miles. Plus la zone est moyenne, plus la distorsion est importante.
Voici une comparaison de quelques options de clustering
Moyenne (facile, rapide, imprécise): additionnez simplement les valeurs lat et divisez par le nombre et faites de même pour les valeurs lng. Assurez-vous de faire attention au débordement si vous utilisez un Int32, certains systèmes (notamment c #) déborderont silencieusement vers les faibles nombres. Vous pouvez éviter ces erreurs en utilisant la précision à virgule flottante pour votre accumulateur de somme. Un problème avec cette méthode est que les valeurs aberrantes peuvent fausser votre emplacement. [Modifier] -> Un autre est que les mathématiques près des pôles et de la ligne de date internationale ne sont pas bien moyennes et biaiseront mal les emplacements.
Voisin le plus proche (un peu plus difficile, plus lent, pas biaisé aux valeurs aberrantes) Plutôt que de faire la moyenne, vous pouvez aller avec l'emplacement réel de lat lng avec la plus petite distance moyenne à tous ses voisins. C'est un peu comme prendre une "médiane". L'inconvénient est que cela est coûteux en calcul car vous comparez chaque point à tous les autres points et calculez la distance entre eux. Par exemple, le regroupement de 10 000 points nécessiterait 100 millions de calculs de distance .. pas si lent, mais il n'évolue certainement pas bien.
Grid Cell (nécessite un peu de configuration supplémentaire, beaucoup plus rapide, pas biaisé en cas de valeur aberrante) Ceci est similaire au voisin le plus proche mais beaucoup plus rapide. Vous pouvez choisir un niveau de précision arbitraire, par exemple 0,01 deg lat lng (ce qui correspond à environ 1 km à des latitudes peuplées) et regrouper vos points en tranches de 0,01 x 0,01 degré. Vous pouvez ensuite choisir le seau contenant le plus de points et prendre la moyenne de ces points ou exécuter une analyse du voisin le plus proche sur ces points uniquement. J'utilise beaucoup cette méthode avec de très gros ensembles de données (des centaines de milliards d'enregistrements) et je trouve que c'est un bon équilibre entre précision et vitesse.
Convex Hull Centroid (résultats durs, lents et nets): vous pouvez également dessiner une bande autour de vos points pour définir une forme qui les couvre tous ( voir wikipedia ), puis calculer le point central de cette forme. Les fonctions centroïdes typiques ne sont pas pondérées au centre, vous devrez donc effectuer une sorte d'analyse inverse du plus proche voisin en utilisant des points d'échantillonnage à l'intérieur de votre forme jusqu'à ce que vous trouviez celle la plus éloignée des bords. Cette méthode est vraiment plus intéressante en raison de la coque convexe elle-même plutôt que de l'algorithme de recherche de centre réel qui n'est ni rapide ni particulièrement précis .. mais la forme de la coque peut avoir d'autres applications utiles avec vos données.
Vous ne savez pas exactement ce que vous essayez d'atteindre, mais le point dont la latitude est la moyenne des latitudes de l'ensemble de points d'origine et la longitude est la moyenne des longitudes de l'ensemble de points d'origine, sera le point moyen de l'ensemble de points d'origine. [MISE À JOUR]: Dans ce qui précède, avg est la moyenne arithmétique.