2016-09-02 4 views
0

Моя цельПочему моя оверлейная линия не приводит к тому, что я ожидаю на карте, основанной на полярных формулах (swift, ios)?

имеют линию, проведенную на основе трех битов данных: координат дано, расстояние, подшипник.

Я хочу, чтобы линия была нарисована из моего текущего местоположения в направлении подшипника, в точке и в конце точки.

Голые в виду

Я получаю линию на карте, обновляется каждый раз, когда текущее местоположение, так что это не проблема в этом смысле (код я уже показал, не может включать в себя все определения - но предположим, что нет ошибки компиляции и т.д.)

проблема

появляется Моя линия, но всегда только в одном направлении, на расстоянии через весь мир (вместо 1 км!). Я попытался изменить ввод заголовка, но все равно получаю ту же строку.

Код

func drawHeadingLine(currentLocation: [Double], heading: Double){ 

     //to radians 
     let headingR = heading * 0.0174533; 

     if viewLine != nil{ 
      mapView.removeOverlay(viewLine); 
     } 
     // setup data for polar formulae 
     let pi = M_PI; 
     let currentLONG = currentLocation[0]; 
     let currentLAT = currentLocation[1]; 
     let currentLongRadian = currentLocation[0] * (pi * 180); 
     let currentLatRadian = currentLocation[1] * (pi * 180); 
     let lineDistance: Double = 1; //km 
     let earthRadius: Double = 6378.1; //km 
     let angularDistance: Double = lineDistance/earthRadius; 

     //use polar formulae (given point, distance, bearing) for line end point 

     let latitude2 = asin(sin(currentLatRadian) * cos(angularDistance) 
           + cos(currentLatRadian) * sin(angularDistance) * cos(headingR)); 

     let longitude2 = currentLongRadian + atan2(cos(angularDistance) - sin(currentLatRadian) * sin(latitude2), 
               sin(headingR) * sin(angularDistance) * cos(currentLatRadian)); 


     var coordinates1 = CLLocationCoordinate2D(); 
     coordinates1.longitude = currentLONG; 
     coordinates1.latitude = currentLAT; 

     var coordinates2 = CLLocationCoordinate2D(); 
     coordinates2.longitude = longitude2; 
     coordinates2.latitude = latitude2; 

     var lineCoords = [ coordinates1,coordinates2]; 

     viewLine = MKPolyline(coordinates: &lineCoords, count: lineCoords.count); 
     self.mapView.addOverlay(viewLine); 

    } 


func mapView(mapView: MKMapView!, viewForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! { 

     if (overlay is MKPolyline) { 
      viewLine = overlay; 
      let line = MKPolylineRenderer(overlay: viewLine); 
      line.strokeColor = UIColor.redColor().colorWithAlphaComponent(0.5); 
      line.lineWidth = 5; 
      return line; 
     } 

     return nil 
    } 

enter image description here Скажите, пожалуйста, если вам нужна дополнительная информация. Спасибо за любую помощь.

+0

Ваш код добавляет 'MKPolyline' представляется правильным. Попробуйте просмотреть ваш расчет второй координаты. – zcui93

ответ

1

Ваша математика выключена. Попробуйте это:

func drawHeadingLine(currentLocation: [Double], heading: Double){ 
    if viewLine != nil { 
     mapView.removeOverlay(viewLine!) 
    } 

    let (lat, long) = (currentLocation[0], currentLocation[1]) 
    let headingR = heading * M_PI/180.0 
    let lineDistance = 1.0 //km 

    let latDelta = cos(headingR) * lineDistance/EarthMeasurement.lengthOfLatitude(at: lat) 
    let longDelta = sin(headingR) * lineDistance/EarthMeasurement.lengthOfLongitude(at: lat) 

    let pointA = CLLocationCoordinate2D(latitude: lat, longitude: long) 
    let pointB = CLLocationCoordinate2D(latitude: lat + latDelta, longitude: long + longDelta) 

    // For debugging, let's calculate a geodesic distance between these 2 points 
    // Results are in meters 
    let locationA = CLLocation(latitude: lat, longitude: long) 
    let locationB = CLLocation(latitude: lat + latDelta, longitude: long + longDelta) 
    print("heading = \(heading), distance = \(locationA.distanceFromLocation(locationB)") 

    var coordinates = [pointA, pointB] 
    let polyline = MKPolyline(coordinates: &coordinates, count: 2) 
    self.mapView.addOverlay(polyline) 
} 

И в EarthMeasurement класс:

final class EarthMeasurement { 
    static func lengthOfLatitude(at latitude: Double) -> Double { 
     return 110.574 
    } 

    static func lengthOfLongitude(at latitude: Double) -> Double { 
     let latitudeR = latitude * M_PI/180.0 
     return cos(latitudeR) * 111.320 
    } 
} 

Идея заключается в том, что карта Kit сделок в широтах и ​​долготы, а не в километр, так что нам нужно знать, сколько километров есть в широта Долгота. Это далеко не просто, так как Земля не идеальная сфера. но мы можем сделать приближение:

  • Длина 1 градуса широты действительно становится больше по мере приближения к полюсам, но разница невелика: около 1 км (или 1%) между экватором и полюсами. Мы можем игнорировать это и использовать длину на экваторе, которая согласно Wikipedia составляет 111,574 км.
  • Формула для длины 1 градуса широты взята из this question.

Это не означает, что это точно в 1 км от нас из-за приближений, которые мы использовали. Ошибка меньше на широтах около экватора и постепенно увеличивается по мере приближения к полюсам (~ 10 м). Если вы хотите получить более точный результат, соответствующим образом отрегулируйте класс EarthMeasurement.

+0

Оказывается, было немало проблем, но это помогло. Большое спасибо. –

 Смежные вопросы

  • Нет связанных вопросов^_^