Getting die Grenzen eines MKMapView

stimmen
29

Ich baue Um eine Abfrage an einen externen Server einrichten möchte ich die Grenzen des aktuellen Kartenansicht in einer iPhone-App bekommen. UIView sollte Grenzen reagieren, aber es scheint MKMapView nicht. eine Region und Zoomen in der Karte nach dem Abbinden ich versuche, die Grenzen zu erhalten. Ich bin fest auf dem ersten Schritt, der die CGPoints zu versuchen, zu erhalten, die die SE und NW Ecken der Karte darstellen. Danach habe ich verwenden würde:

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

Um die Punkte in Kartenkoordinaten zu transformieren. Aber ich kann nicht einmal 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 kompiliert ohne Warnungen jedoch se und nw beide null sind. Mit Blick auf self.mapView.bounds.origin.x die Variable 0. Der Versuch, NSLog direkt gibt self.mapView.bounds.size.width mir ein „Programm empfangene Signal:‚EXC_BAD_ACCESS‘.“ die von NSLog zu kommen scheint.

Wer weiß, den richtigen Weg, um die Süd-Ost-Ecke und nordwestliche Ecke zu bekommen (in Kartenkoordinaten) aus dem sichtbaren Bereich einer MKMapView?

EDIT: Es scheint, wenn Sie etwas hier die Antwort gebeten, direkt nach dem zu Ihnen kommt. Ich war mit% @ statt @f jede Variable in NSLog zu drucken, die Fehler dort wirft. Ich entdeckte auch die annotationVisibleRect Eigenschaft MKMapView. Es scheint aber, dass der annotationVisibleRect auf dem übergeordnete Ansicht Koordinaten basiert.

Veröffentlicht am 17/01/2010 um 17:53
quelle vom benutzer
In anderen Sprachen...                            


10 antworten

stimmen
73

Okay, ich antwortete offiziell meine eigene Frage, aber da ich es nicht überall finden, bevor ich die Antwort schreiben würde hier:

//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];
Beantwortet am 17/01/2010 um 20:14
quelle vom benutzer

stimmen
38

Eine weitere Option ist das visibleMapRect Eigentum auf Ihrer MKMapView Instanz verwenden und MKCoordinateForMapPoint () an die lat / lon zu konvertieren.

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);
Beantwortet am 06/12/2010 um 06:04
quelle vom benutzer

stimmen
9

Swift weg ... (Basierend auf Antwort des @ 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)
    }
}
Beantwortet am 23/02/2015 um 21:30
quelle vom benutzer

stimmen
3

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

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

Geben Sie hier image description

Sie können eine haben BoundingBoxStruktur, 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,
    ]
  }
}

Das visibleMapRectist die gleiche wieregion.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)
Beantwortet am 04/04/2017 um 07:34
quelle vom benutzer

stimmen
1

diese Website das Problem lösen. 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]];
}
Beantwortet am 18/12/2017 um 13:14
quelle vom benutzer

stimmen
1

Ich konnte dies mit dem Parse GEObox Abfrage zur Arbeit kommen:

//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];
Beantwortet am 19/12/2014 um 14:39
quelle vom benutzer

stimmen
0

Aktualisiert @ ausgezeichnete Antwort des onmyway133 für meine Zwecke, brauchte ich 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 dafür, wie ich diese Daten verwendet:

        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)
Beantwortet am 27/05/2019 um 23:57
quelle vom benutzer

stimmen
0

Diese Erweiterung löst dieses Problem und halten Sie die centerCoordinateSyntax in 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
    }
}
Beantwortet am 17/04/2019 um 18:02
quelle vom benutzer

stimmen
0

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

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 ist abgeleitet von 陈保状's Antwort und die zugehörige Webseite eingeben hier Linkbeschreibung . Durch die vereinfachte nach unten zu 3 Zeilen für Süd - West und Nord - Ost - Ecken.

Beantwortet am 24/08/2018 um 20:04
quelle vom benutzer

stimmen
0

Dieser Code funktioniert mit Karte wie 90/180 Grad drehen. set mapView.pitchEnabled = NO; für weniger Bugs.

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];
Beantwortet am 15/10/2015 um 01:17
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more