una segmento sacar recta razon puntos punto pendiente medio geometria entre distancia dada como analitica objective-c mapkit core-location

objective c - segmento - Determinación del punto medio entre 2 cooridinatos



punto medio formula (5)

Estoy tratando de determinar el punto medio entre las ubicaciones en un MKMapView . Estoy siguiendo el método descrito here (y here ) y lo reescribí en Objective-C, pero el mapa está centrado en algún lugar al noreste de la Isla Baffin, que no está cerca de los dos puntos.

Mi método basado en el método java vinculado anteriormente:

+(CLLocationCoordinate2D)findCenterPoint:(CLLocationCoordinate2D)_lo1 :(CLLocationCoordinate2D)_loc2 { CLLocationCoordinate2D center; double lon1 = _lo1.longitude * M_PI / 180; double lon2 = _loc2.longitude * M_PI / 100; double lat1 = _lo1.latitude * M_PI / 180; double lat2 = _loc2.latitude * M_PI / 100; double dLon = lon2 - lon1; double x = cos(lat2) * cos(dLon); double y = cos(lat2) * sin(dLon); double lat3 = atan2( sin(lat1) + sin(lat2), sqrt((cos(lat1) + x) * (cos(lat1) + x) + y * y) ); double lon3 = lon1 + atan2(y, cos(lat1) + x); center.latitude = lat3 * 180 / M_PI; center.longitude = lon3 * 180 / M_PI; return center; }

Los 2 parámetros tienen los siguientes datos:

_loc1: latitude = 45.4959839 longitude = -73.67826455 _loc2: latitude = 45.482889 longitude = -73.57522299

Lo anterior se coloca correctamente en el mapa (en y alrededor de Montreal). Estoy tratando de centrar el mapa en el punto medio entre los 2, pero mi método devuelve lo siguiente:

latitude = 65.29055 longitude = -82.55425

que en algún lugar del ártico, cuando debería estar alrededor de 500 millas al sur.


Creo que estás sobre pensándolo un poco. Solo haz:

float lon3 = ((lon1 + lon2) / 2) float lat3 = ((lat1 + lat2) / 2)

lat3 y lon3 serán el punto central.


En caso de que alguien necesite un código en Swift, he escrito una función de biblioteca en Swift para calcular el punto medio entre las coordenadas MÚLTIPLES:

// /** Degrees to Radian **/ class func degreeToRadian(angle:CLLocationDegrees) -> CGFloat { return ( (CGFloat(angle)) / 180.0 * CGFloat(M_PI) ) } // /** Radians to Degrees **/ class func radianToDegree(radian:CGFloat) -> CLLocationDegrees { return CLLocationDegrees( radian * CGFloat(180.0 / M_PI) ) } class func middlePointOfListMarkers(listCoords: [CLLocationCoordinate2D]) -> CLLocationCoordinate2D { var x = 0.0 as CGFloat var y = 0.0 as CGFloat var z = 0.0 as CGFloat for coordinate in listCoords{ var lat:CGFloat = degreeToRadian(coordinate.latitude) var lon:CGFloat = degreeToRadian(coordinate.longitude) x = x + cos(lat) * cos(lon) y = y + cos(lat) * sin(lon) z = z + sin(lat) } x = x/CGFloat(listCoords.count) y = y/CGFloat(listCoords.count) z = z/CGFloat(listCoords.count) var resultLon: CGFloat = atan2(y, x) var resultHyp: CGFloat = sqrt(x*x+y*y) var resultLat:CGFloat = atan2(z, resultHyp) var newLat = radianToDegree(resultLat) var newLon = radianToDegree(resultLon) var result:CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: newLat, longitude: newLon) return result }

La respuesta detallada se puede encontrar here


Es importante decir que la fórmula que utilizó el OP para calcular el punto medio geográfico se basa en esta fórmula que explica el cálculo de cos / sin / sqrt.

Esta fórmula le dará el punto medio geográfico para cualquier distancia larga, incluidos los cuatro trimestres y el primer meridiano.

Pero, si su cálculo es para un rango corto de alrededor de 1 kilómetro, el uso de un promedio simple producirá los mismos resultados del punto medio. es decir:

let firstPoint = CLLocation(....) let secondPoint = CLLocation(....) let midPointLat = (firstPoint.coordinate.latitude + secondPoint.coordinate.latitude) / 2 let midPointLong = (firstPoint.coordinate.longitude + secondPoint.coordinate.longitude) / 2

De hecho, puede usarlo por 10 km, pero espere una desviación: si solo necesita una estimación para un punto medio de corto alcance con una solución rápida, será suficiente.


Para usuarios rápidos, variante corregida como sugieren @dinjas

import Foundation import MapKit extension CLLocationCoordinate2D { // MARK: CLLocationCoordinate2D+MidPoint func middleLocationWith(location:CLLocationCoordinate2D) -> CLLocationCoordinate2D { let lon1 = longitude * M_PI / 180 let lon2 = location.longitude * M_PI / 180 let lat1 = latitude * M_PI / 180 let lat2 = location.latitude * M_PI / 180 let dLon = lon2 - lon1 let x = cos(lat2) * cos(dLon) let y = cos(lat2) * sin(dLon) let lat3 = atan2( sin(lat1) + sin(lat2), sqrt((cos(lat1) + x) * (cos(lat1) + x) + y * y) ) let lon3 = lon1 + atan2(y, cos(lat1) + x) let center:CLLocationCoordinate2D = CLLocationCoordinate2DMake(lat3 * 180 / M_PI, lon3 * 180 / M_PI) return center } }


Solo una corazonada, pero me di lat2 variables lon2 y lat2 se están calculando con M_PI/100 y no con M_PI/180 .

double lon1 = _lo1.longitude * M_PI / 180; double lon2 = _loc2.longitude * M_PI / 100; double lat1 = _lo1.latitude * M_PI / 180; double lat2 = _loc2.latitude * M_PI / 100;

Cambiar esos a 180 podría ayudarte un poco.