Обратная функция mkcoordinateregionmakewithdistance?

Встроенная функция MapKit MKCoordinateRegionMakeWithDistance измеряет расстояния в метрах и превращает их в MKCoordinateRegion:

func MKCoordinateRegionMakeWithDistance(
    _ centerCoordinate: CLLocationCoordinate2D, 
    _ latitudinalMeters: CLLocationDistance, 
    _ longitudinalMeters: CLLocationDistance) 
        -> MKCoordinateRegion

есть ли обратная функция, которая берет MKCoordinateRegion и дает мне широты и долготы?

Прошу прощения за то, что изначально разместил ответ как комментарий. Если да, дайте мне знать, если это сработало для вас.

Adam H. 10.08.2018 16:29

Привет, Адам, да, как вы видите, я опубликовал свою реализацию с модульными тестами в качестве второго ответа, отдавая вам должное. Теперь я могу точно переключаться между регионом Apple и камерой Google с масштабированием.

Gerd Castan 10.08.2018 19:40
3
2
443
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

MKCoordinateRegion дает центр (широту и долготу) и диапазон (дельта широты и долготы). Зная эти значения, вы можете определить расположение краев региона по широте и долготе. Сделав это, вы можете использовать формулу гаверсинуса для получения широтных и долготных расстояний, а центр вам уже известен. Фактически, CLLocation имеет функцию distanceFromLocation:(const CLLocation *)location, которую следует использовать, чтобы избежать прямого выполнения формулы.

Основываясь на идее Адама Х., это моя реализация в Swift 4 с модульными тестами:

extension MKCoordinateRegion {
    /// middle of the south edge
    var south: CLLocation {
        return CLLocation(latitude: center.latitude - span.latitudeDelta / 2, longitude: center.longitude)
    }
    /// middle of the north edge
    var north: CLLocation {
        return CLLocation(latitude: center.latitude + span.latitudeDelta / 2, longitude: center.longitude)
    }
    /// middle of the east edge
    var east: CLLocation {
        return CLLocation(latitude: center.latitude, longitude: center.longitude + span.longitudeDelta / 2)
    }
    /// middle of the west edge
    var west: CLLocation {
        return CLLocation(latitude: center.latitude, longitude: center.longitude - span.longitudeDelta / 2)
    }
    /// distance between south and north in meters. Reverse function for MKCoordinateRegionMakeWithDistance
    var latitudinalMeters: CLLocationDistance {
        return south.distance(from: north)
    }
    /// distance between east and west in meters. Reverse function for MKCoordinateRegionMakeWithDistance
    var longitudinalMeters: CLLocationDistance {
        return east.distance(from: west)
    }
}

Модульный тест:

func testMKCoordinateRegionMakeWithDistance() {
    // arbitrary parameters
    let center = CLLocationCoordinate2DMake(49, 9)
    let latitudinalMeters: CLLocationDistance = 1000
    let longitudinalMeters: CLLocationDistance = 2000

    let region = MKCoordinateRegionMakeWithDistance(center, latitudinalMeters, longitudinalMeters)
    XCTAssertEqual(latitudinalMeters, round(region.latitudinalMeters*100)/100)
    XCTAssertEqual(longitudinalMeters, round(region.longitudinalMeters*100)/100)
}

дизайн теста:

  • используйте разные числа для широты и долготы, чтобы найти ошибки, в которых переменные перепутаны
  • округление проверяет около 5 значащих десятичных знаков

Другие вопросы по теме