webentwicklung-frage-antwort-db.com.de

Die Grenzen eines MKMapView abrufen

Um eine Abfrage an einen externen Server einzurichten, möchte ich die Grenzen der aktuellen Kartenansicht in einer iPhone-App ermitteln, die ich gerade baue. UIView sollte auf Grenzen reagieren, aber MKMapView scheint dies nicht zu tun. Nachdem ich eine Region festgelegt und die Karte vergrößert habe, versuche ich, die Grenzen zu bestimmen. Ich bleibe beim ersten Schritt, der versucht, die CGPoints zu ermitteln, die die SE- und NW-Ecken der Karte darstellen. Danach wollte ich verwenden:

- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view

Um die Punkte in Kartenkoordinaten umzuwandeln. Aber ich kann nicht so weit kommen ...

//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);

Der Code wird ohne Warnungen kompiliert, jedoch sind sowohl se als auch nw null. Wenn Sie sich self.mapView.bounds.Origin.x ansehen, ist die Variable 0. Wenn Sie NSLog direkt ausprobieren, erhalten Sie durch self.mapView.bounds.size.width ein "Programm empfangen Signal:" EXC_BAD_ACCESS "." was scheint von NSLog zu kommen.

Kennt jemand den richtigen Weg, um die südöstliche Ecke und die nordwestliche Ecke (in Kartenkoordinaten) aus dem sichtbaren Bereich eines MKMapView zu erhalten?

EDIT: Es scheint, wenn Sie etwas hier gefragt haben, kommt die Antwort direkt danach. Ich habe% @ anstelle von @f verwendet, um jede Variable in NSLog zu drucken, die dort Fehler ausgegeben hat. Ich habe auch die AnnotationVisibleRect-Eigenschaft von MKMapview entdeckt. Es scheint jedoch, dass AnnotationVisibleRect auf den übergeordneten Ansichtskoordinaten basiert.

31
deadroxy

Okay, ich habe meine Frage offiziell beantwortet, aber da ich sie nirgendwo gefunden habe, werde ich die Antwort hier posten:

//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];
74
deadroxy

Eine andere Option besteht darin, die visibleMapRect -Eigenschaft in Ihrer MKMapView-Instanz zu verwenden und MKCoordinateForMapPoint () zum Konvertieren in lat/lon zu verwenden. 

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);
41
afarnham

Schnell weg ... (basierend auf @ deadroxys Antwort ...)

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)
    }
}
9
Aviel Gross

Diese http://wiki.openstreetmap.org/wiki/Bounding_Box ist ein Dokument für den Begrenzungsrahmen

bbox = left,bottom,right,top
bbox = min Longitude , min Latitude , max Longitude , max Latitude

 enter image description here

Sie können eine BoundingBox-Struktur haben, die dies darstellt

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,
    ]
  }
}

Die visibleMapRect ist die gleiche wie 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)
6
onmyway133

Diese Erweiterung behebt dieses Problem und behält die centerCoordinate -Syntax in Swift 5 bei

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
    }
}
3
RodolfoAntonici

Die ausgezeichnete Antwort von @ onmyway133 wurde für meine Zwecke aktualisiert. Ich benötigte die Koordinaten aller vier Ecken:

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,
        ]
    }
}

Und ein Beispiel, wie ich diese Daten verwendet habe:

        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)
1

Ich konnte dies mit der Parse-GeoBox-Abfrage erreichen:

//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];
1
Cindy

diese Website löst das Problem. http://www.softwarepassion.com/how-to-get-geographic-koordinates-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]];
}
1
Zgpeace

Ich hatte einige Probleme mit einigen anderen Antworten für Karten, die um zwei Finger gedreht worden waren. Dieser Code hat für mich funktioniert:

MKMapRect rect = self.mapView.visibleMapRect;
CLLocationCoordinate2D northeast = MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMaxX(rect),rect.Origin.y));
CLLocationCoordinate2D southwest = MKCoordinateForMapPoint(MKMapPointMake(rect.Origin.x         ,MKMapRectGetMaxY(rect)));

Meine Antwort leitet sich von 陈 保 状 s Antwort ab und der dazugehörigen Website Linkbeschreibung hier eingeben . Es ist zu 3 Linien für südwestliche und nordöstliche Ecken hinunter vereinfacht.

0
Marc

Dieser Code funktioniert mit einer Karte, die sich um 90/180 Grad dreht. Set mapView.pitchEnabled = NO; für weniger Fehler.

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];
0
Can Aksoy