How to fit a certain bounds consisting of NE and SW coordinates into the visible map view?

后端 未结 3 1582
迷失自我
迷失自我 2021-02-09 23:52

I need to fit a certain bounds within a map. I get the bounds from calling the google geocoder and reading the viewport property which looks like:

{
    northeas         


        
相关标签:
3条回答
  • 2021-02-10 00:45

    If your bounds can span the 180th meridian, you have to account for that in the conversion:

    - (MKMapRect) mapRectThatFitsBoundsSW:(CLLocationCoordinate2D)sw 
                                       NE:(CLLocationCoordinate2D)ne 
    {
        MKMapPoint pSW = MKMapPointForCoordinate(sw);
        MKMapPoint pNE = MKMapPointForCoordinate(ne);
    
        double antimeridianOveflow = 
          (ne.longitude > sw.longitude) ? 0 : MKMapSizeWorld.width;    
    
        return MKMapRectMake(pSW.x, pNE.y, 
                            (pNE.x - pSW.x) + antimeridianOveflow, 
                            (pSW.y - pNE.y));
    }
    

    But beware those MKMapRects that span the anitmeridian, because they come from the land where the dragons live. If you want to learn about some of the dangers that lie there, have a look at MKMapRect and displaying map overlays that span 180th meridian. You have been warned!

    0 讨论(0)
  • 2021-02-10 00:54

    I found something that works. I ended up going with this:

    - (MKMapRect) mapRectThatFitsBoundsSW:(CLLocationCoordinate2D)sw 
                                       NE:(CLLocationCoordinate2D)ne {
        MKMapPoint nePoint = MKMapPointForCoordinate(ne);
        MKMapPoint swPoint = MKMapPointForCoordinate(sw);
        CGFloat width = ABS(nePoint.x - swPoint.x);
        CGFloat height = ABS(nePoint.y - swPoint.y);
        MKMapRect newMapRect = MKMapRectMake(
            MIN(swPoint.x, nePoint.x), 
            MIN(swPoint.y, nePoint.y), 
            width, 
            height
        );
    
        // if (!MKMapRectSpans180thMeridian(newMapRect)) {
            return newMapRect;
        // } else {
            // ????
        // }
    }
    
    0 讨论(0)
  • 2021-02-10 00:55

    There are several ways to do this.

    You could create an MKCoordinateRegion by figuring out the center point and then the span is the absolute difference in degrees between the corners.

    Or you could create an MKMapRect by using the MapKit function MKMapPointForCoordinate. To get the origin, figure out the northwest coordinate and convert it to an MKMapPoint. To get the width and height, get the absolute difference in mappoints between the corners (convert the corners from coordinates to MKMapPoints using the function first).

    Another quick way is a slight trick using the MKMapRectUnion function. Create a zero-size MKMapRect from each coordinate and then merge the two rects into one big rect using the function:

    MKMapPoint swPoint = MKMapPointForCoordinate(SWCoordinate);
    MKMapRect swRect = MKMapRectMake(swPoint.x, swPoint.y, 0, 0);
    
    MKMapPoint nePoint = MKMapPointForCoordinate(NECoordinate);
    MKMapRect neRect = MKMapRectMake(nePoint.x, nePoint.y, 0, 0);
    
    MKMapRect rect = MKMapRectUnion(swRect, neRect);
    

    Remember that the map view will still make its own adjustments to the rect you request based on the proportions of the map view and the required zoom. (If you want to know what that adjusted rect will be, call the map view's mapRectThatFits: method.)

    0 讨论(0)
提交回复
热议问题