Как я могу расширить MKMapRect на фиксированный процент?
Я хочу получить результат MKMapRect, который на 10-20% больше по всем направлениям, чем текущий visibleMapRect
. Если бы это был CGRect, я бы использовал CGRectInset с отрицательными значениями x и y, предоставив мне обратную вставку (т.е. Большую прямую). К сожалению, MKMapInset не поддерживает отрицательные значения вставки, поэтому это не так просто.
Это может быть проще, если значения для прямоугольника отображения были распознаваемыми единицами, но значения начала x и y имеют порядок 4.29445e + 07, а ширина/высота - 2500-3000.
Мне нужно около 10 секунд от написания категории, чтобы сделать это вручную, но я хотел убедиться, что я ничего не пропустил. Есть ли более простой способ расширения MKMapRect?
Ответы
Ответ 1
В iOS7, rectForMapRect:
и mapRectForRect:
устарели и теперь являются частью класса MKOverlayRenderer
. Я бы предпочел использовать методы MapView
mapRectThatFits: edgePadding:
. Вот пример кода:
MKMapRect visibleRect = self.mapView.visibleMapRect;
UIEdgeInsets insets = UIEdgeInsetsMake(50, 50, 50, 50);
MKMapRect biggerRect = [self.mapView mapRectThatFits:visibleRect edgePadding:insets];
последняя версия Swift для 2017 года.
func updateMap() {
mkMap.removeAnnotations(mkMap.annotations)
mkMap.addAnnotations(yourAnnotationsArray)
var union = MKMapRectNull
for p in yourAnnotationsArray {
// make a small, say, 50meter square for each
let pReg = MKCoordinateRegionMakeWithDistance( pa.coordinate, 50, 50 )
// convert it to a MKMapRect
let r = mkMapRect(forMKCoordinateRegion: pReg)
// union all of those
union = MKMapRectUnion(union, r)
// probably want to turn on the "sign" for each
mkMap.selectAnnotation(pa, animated: false)
}
// expand the union, using the new #edgePadding call. T,L,B,R
let f = mkMap.mapRectThatFits(union, edgePadding: UIEdgeInsetsMake(70, 0, 10, 35))
// NOTE you want the TOP padding much bigger than the BOTTOM padding
// because the pins/signs are actually very tall
mkMap.setVisibleMapRect(f, animated: false)
}
Ответ 2
Как преобразовать visibleMapRect
в CGRect
с помощью rectForMapRect:
, получив новый CGRect
с CGRectInset
, а затем преобразов его обратно в MKMapRect
с mapRectForRect:
?
Ответ 3
Исправлено и исправлено user2285781 ответ для Swift 4:
// reference: https://stackoverflow.com/a/15683034/347339
func MKMapRectForCoordinateRegion(region:MKCoordinateRegion) -> MKMapRect {
let topLeft = CLLocationCoordinate2D(latitude: region.center.latitude + (region.span.latitudeDelta/2), longitude: region.center.longitude - (region.span.longitudeDelta/2))
let bottomRight = CLLocationCoordinate2D(latitude: region.center.latitude - (region.span.latitudeDelta/2), longitude: region.center.longitude + (region.span.longitudeDelta/2))
let a = MKMapPointForCoordinate(topLeft)
let b = MKMapPointForCoordinate(bottomRight)
return MKMapRect(origin: MKMapPoint(x:min(a.x,b.x), y:min(a.y,b.y)), size: MKMapSize(width: abs(a.x-b.x), height: abs(a.y-b.y)))
}
// reference: /questions/681745/how-can-i-expand-a-mkmaprect-by-a-fixed-percentage/2642465#2642465
// assuming coordinates that create a polyline as well as a destination annotation
func updateMap(coordinates: [CLLocationCoordinate2D], annotation: MKAnnotation) {
var union = MKMapRectNull
var coordinateArray = coordinates
coordinateArray.append(annotation.coordinate)
for coordinate in coordinateArray {
// make a small, say, 50meter square for each
let pReg = MKCoordinateRegionMakeWithDistance( coordinate, 50, 50 )
// convert it to a MKMapRect
let r = MKMapRectForCoordinateRegion(region: pReg)
// union all of those
union = MKMapRectUnion(union, r)
}
// expand the union, using the new #edgePadding call. T,L,B,R
let f = mapView.mapRectThatFits(union, edgePadding: UIEdgeInsetsMake(70, 35, 10, 35))
// NOTE you want the TOP padding much bigger than the BOTTOM padding
// because the pins/signs are actually very tall
mapView.setVisibleMapRect(f, animated: false)
}
Ответ 4
Простое и чистое решение для Xcode 10+, Swift 4.2
Просто установите краевые вставки для полей карты следующим образом:
self.mapView.layoutMargins = UIEdgeInsets(top: 8, right: 8, bottom: 8, left: 8)
self.mapView.showAnnotations(map.annotations, animated: true)
Пожалуйста, дайте нам знать, если это работает для вас.