外部サーバーへのクエリを設定するために、作成中のiPhoneアプリで現在のマップビューの境界を取得したいと考えています。 UIViewは境界に応答する必要がありますが、MKMapViewは応答しないようです。地域を設定して地図を拡大した後、境界を取得しようとします。マップのSEコーナーとNWコーナーを表すCGPointsを取得しようとする最初のステップで立ち往生しています。その後、私は使用するつもりでした:
- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view
ポイントをマップ座標に変換します。しかし、私はそんなに遠くまで行くことができません...
//Recenter and zoom map in on search location
MKCoordinateRegion region = {{0.0f, 0.0f}, {0.0f, 0.0f}};
region.center = mySearchLocation.searchLocation.coordinate;
region.span.longitudeDelta = 0.01f;
region.span.latitudeDelta = 0.01f;
[self.mapView setRegion:region animated:YES];
//After the new search location has been added to the map, and the map zoomed, we need to update the search bounds
//First we need to calculate the corners of the map
CGPoint se = CGPointMake(self.mapView.bounds.Origin.x, mapView.bounds.Origin.y);
CGPoint nw = CGPointMake((self.mapView.bounds.Origin.x + mapView.bounds.size.width), (mapView.bounds.Origin.y + mapView.bounds.size.height));
NSLog(@"points are: se %@, nw %@", se, nw);
コードは警告なしでコンパイルされますが、seとnwは両方ともnullです。 self.mapView.bounds.Origin.xを見ると、変数は0です。直接NSLogを実行しようとすると、self.mapView.bounds.size.widthによって「プログラム受信信号:「EXC_BAD_ACCESS」が表示されます。」 NSLogから来たようです。
MKMapViewの可視領域から南東コーナーと北西コーナー(マップ座標)を取得する適切な方法を知っている人はいますか?
編集:あなたがここで何かを尋ねたときはいつでも答えがすぐにあなたに来るようです。エラーをスローしていたNSLogの各変数を出力するために、@ fではなく%@を使用していました。 MKMapviewのannotationVisibleRectプロパティも発見しました。ただし、annotationVisibleRectは親ビューの座標に基づいているようです。
さて、私は自分の質問に正式に回答しましたが、ここに回答を投稿する前にどこにもそれが見つからなかったので:
//To calculate the search bounds...
//First we need to calculate the corners of the map so we get the points
CGPoint nePoint = CGPointMake(self.mapView.bounds.Origin.x + mapView.bounds.size.width, mapView.bounds.Origin.y);
CGPoint swPoint = CGPointMake((self.mapView.bounds.Origin.x), (mapView.bounds.Origin.y + mapView.bounds.size.height));
//Then transform those point into lat,lng values
CLLocationCoordinate2D neCoord;
neCoord = [mapView convertPoint:nePoint toCoordinateFromView:mapView];
CLLocationCoordinate2D swCoord;
swCoord = [mapView convertPoint:swPoint toCoordinateFromView:mapView];
別のオプションは、MKMapViewインスタンスのvisibleMapRectプロパティを使用し、MKCoordinateForMapPoint()を使用して緯度/経度に変換することです。
MKMapRect mRect = self.mapView.visibleMapRect;
MKMapPoint neMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), mRect.Origin.y);
MKMapPoint swMapPoint = MKMapPointMake(mRect.Origin.x, MKMapRectGetMaxY(mRect));
CLLocationCoordinate2D neCoord = MKCoordinateForMapPoint(neMapPoint);
CLLocationCoordinate2D swCoord = MKCoordinateForMapPoint(swMapPoint);
すぐに...(@deadroxyの回答に基づいて...)
typealias Edges = (ne: CLLocationCoordinate2D, sw: CLLocationCoordinate2D)
extension MKMapView {
func edgePoints() -> Edges {
let nePoint = CGPoint(x: self.bounds.maxX, y: self.bounds.Origin.y)
let swPoint = CGPoint(x: self.bounds.minX, y: self.bounds.maxY)
let neCoord = self.convertPoint(nePoint, toCoordinateFromView: self)
let swCoord = self.convertPoint(swPoint, toCoordinateFromView: self)
return (ne: neCoord, sw: swCoord)
}
}
これ http://wiki.openstreetmap.org/wiki/Bounding_Box はバウンディングボックスのドキュメントです
bbox = left,bottom,right,top
bbox = min Longitude , min Latitude , max Longitude , max Latitude
これを表すBoundingBox
構造体を持つことができます
struct BoundingBox {
let min: CLLocationCoordinate2D
let max: CLLocationCoordinate2D
init(rect: MKMapRect) {
let bottomLeft = MKMapPointMake(rect.Origin.x, MKMapRectGetMaxY(rect))
let topRight = MKMapPointMake(MKMapRectGetMaxX(rect), rect.Origin.y)
min = MKCoordinateForMapPoint(bottomLeft)
max = MKCoordinateForMapPoint(topRight)
}
var points: [CLLocationDegrees] {
return [
min.latitude,
min.longitude,
max.latitude
max.longitude,
]
}
}
visibleMapRect
はregion.span
と同じです
let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: 320, height: 640))
XCTAssertEqual(mapView.userLocation.coordinate.latitude, 0)
XCTAssertEqual(mapView.userLocation.coordinate.longitude, 0)
let boundingBox = BoundingBox(rect: mapView.visibleMapRect)
XCTAssertEqual(boundingBox.max.longitude-boundingBox.min.longitude, mapView.region.span.longitudeDelta)
XCTAssertEqual(boundingBox.max.latitude-boundingBox.min.latitude, mapView.region.span.latitudeDelta)
この拡張機能はこの問題を解決し、centerCoordinate
構文をSwift 5
extension MKMapView {
var northWestCoordinate: CLLocationCoordinate2D {
return MKMapPoint(x: visibleMapRect.minX, y: visibleMapRect.minY).coordinate
}
var northEastCoordinate: CLLocationCoordinate2D {
return MKMapPoint(x: visibleMapRect.maxX, y: visibleMapRect.minY).coordinate
}
var southEastCoordinate: CLLocationCoordinate2D {
return MKMapPoint(x: visibleMapRect.maxX, y: visibleMapRect.maxY).coordinate
}
var southWestCoordinate: CLLocationCoordinate2D {
return MKMapPoint(x: visibleMapRect.minX, y: visibleMapRect.maxY).coordinate
}
}
私の目的のために@ onmyway133の優れた答えを更新しました、私はすべての四隅の座標が必要でした:
struct BoundingBox {
let topRight: CLLocationCoordinate2D
let topLeft: CLLocationCoordinate2D
let bottomRight: CLLocationCoordinate2D
let bottomLeft: CLLocationCoordinate2D
init(rect: MKMapRect) {
topRight = MKMapPoint(x: rect.maxX, y: rect.Origin.y).coordinate
topLeft = MKMapPoint(x: rect.Origin.x, y: rect.Origin.y).coordinate
bottomRight = MKMapPoint(x: rect.maxX, y: rect.maxY).coordinate
bottomLeft = MKMapPoint(x: rect.Origin.x, y: rect.maxY).coordinate
}
var items: [String: CLLocationCoordinate2D] {
return [
"topRight": topRight,
"topLeft": topLeft,
"bottomRight": bottomRight,
"bottomLeft": bottomLeft,
]
}
var points: [CLLocationDegrees] {
return [
topRight.latitude,
topRight.longitude,
topLeft.latitude,
topLeft.longitude,
bottomRight.latitude,
bottomRight.longitude,
bottomLeft.latitude,
bottomLeft.longitude,
]
}
}
そして、私がこのデータをどのように使用したかの例:
let boundingBox = BoundingBox(rect: mapView.visibleMapRect)
var annotations = Array<MKPointAnnotation>()
for point in boundingBox.items {
let newPoint = MKPointAnnotation()
newPoint.coordinate = point.value
annotations.append(newPoint)
}
mapView.addAnnotations(annotations)
これをParse GeoBoxクエリで機能させることができました。
//Calculate the corners of the map to get the points
CGPoint nePoint = CGPointMake(self.mapView.bounds.Origin.x + self.mapView.bounds.size.width, self.mapView.bounds.Origin.y);
CGPoint swPoint = CGPointMake((self.mapView.bounds.Origin.x),(self.mapView.bounds.Origin.y+ self.mapView.bounds.size.height));
//Transform points into lat/long values
CLLocationCoordinate2D NECoordinate = [self.mapView convertPoint:nePoint toCoordinateFromView:self.mapView];
CLLocationCoordinate2D SWCoordinate = [self.mapView convertPoint:swPoint toCoordinateFromView:self.mapView];
//Convert to Parse GeoPoints
PFGeoPoint *Southwest = [PFGeoPoint geoPointWithLatitude:SWCoordinate.latitude longitude:SWCoordinate.longitude];
PFGeoPoint *Northeast = [PFGeoPoint geoPointWithLatitude:NECoordinate.latitude longitude:NECoordinate.longitude];
このウェブサイトは問題を解決します。 http://www.softwarepassion.com/how-to-get-geographic-coordinates-of-the-visible-mkmapview-area-in-ios/
MKMapRect mRect = self.mapView.visibleMapRect;
-(CLLocationCoordinate2D)getNECoordinate:(MKMapRect)mRect{
return [self getCoordinateFromMapRectanglePoint:MKMapRectGetMaxX(mRect) y:mRect.Origin.y];
}
-(CLLocationCoordinate2D)getNWCoordinate:(MKMapRect)mRect{
return [self getCoordinateFromMapRectanglePoint:MKMapRectGetMinX(mRect) y:mRect.Origin.y];
}
-(CLLocationCoordinate2D)getSECoordinate:(MKMapRect)mRect{
return [self getCoordinateFromMapRectanglePoint:MKMapRectGetMaxX(mRect) y:MKMapRectGetMaxY(mRect)];
}
-(CLLocationCoordinate2D)getSWCoordinate:(MKMapRect)mRect{
return [self getCoordinateFromMapRectanglePoint:mRect.Origin.x y:MKMapRectGetMaxY(mRect)];
}
-(CLLocationCoordinate2D)getCoordinateFromMapRectanglePoint:(double)x y:(double)y{
MKMapPoint swMapPoint = MKMapPointMake(x, y);
return MKCoordinateForMapPoint(swMapPoint);
}
-(NSArray *)getBoundingBox:(MKMapRect)mRect{
CLLocationCoordinate2D bottomLeft = [self getSWCoordinate:mRect];
CLLocationCoordinate2D topRight = [self getNECoordinate:mRect];
return @[[NSNumber numberWithDouble:bottomLeft.latitude ],
[NSNumber numberWithDouble:bottomLeft.longitude],
[NSNumber numberWithDouble:topRight.latitude],
[NSNumber numberWithDouble:topRight.longitude]];
}
2本の指で回転させたマップについて、他のいくつかの回答で問題が発生しました。このコードは私のために働きました:
MKMapRect rect = self.mapView.visibleMapRect;
CLLocationCoordinate2D northeast = MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMaxX(rect),rect.Origin.y));
CLLocationCoordinate2D southwest = MKCoordinateForMapPoint(MKMapPointMake(rect.Origin.x ,MKMapRectGetMaxY(rect)));
私の答えは 陈保状の答え および関連するWebサイト ここにリンクの説明を入力 から派生しています。南西と北東のコーナーの3つのラインも簡略化しました。
このコードは、90/180度のように回転するマップで機能します。 set MapView.pitchEnabled = NO;バグが少ない。
CLLocationDirection heading = mapView.camera.heading;
float mapWidth = mapView.frame.size.width;
float mapHeight = mapView.frame.size.height;
float neX = mapWidth;
float neY = 0.0;
float swX = 0.0;
float swY = mapHeight;
if (heading >= 0 && heading <= 90) {
//println("Q1")
float ratio = heading / 90;
neX = (1-ratio) * mapWidth;
swX = (mapWidth*ratio);
} else if (heading >= 90 && heading <= 180) {
//println("Q2")
float ratio = (heading - 90) / 90;
neX = 0;
neY = (mapHeight*ratio);
swY = (1-ratio) * mapHeight;
swX = mapWidth;
} else if (heading >= 180 && heading <= 270) {
//println("Q3")
float ratio = (heading - 180) / 90;
neX = mapWidth*ratio;
neY = mapHeight;
swX = (1-ratio) * mapWidth;
swY = 0;
} else if (heading >= 270 && heading <= 360) {
//println("Q4");
float ratio = (heading - 270) / 90;
neX = mapWidth;
neY = (1-ratio) * mapHeight;
swY = ratio * mapHeight;
}
CGPoint swPoint = CGPointMake(swX, swY);
CGPoint nePoint = CGPointMake(neX, neY);
CLLocationCoordinate2D swCoord = [mapView convertPoint:swPoint toCoordinateFromView:mapView];
CLLocationCoordinate2D neCoord = [mapView convertPoint:nePoint toCoordinateFromView:mapView];