I'm trying to see if some extents (max x, max y, min x, min y coordinates) I have are in the current visible map view.
I take my extents and create a MKMapRect:
MKMapPoint upperLeft = MKMapPointForCoordinate(CLLocationCoordinate2DMake([boundary.extents.maxY floatValue], [boundary.extents.minY floatValue]));
MKMapPoint lowerLeft = MKMapPointForCoordinate(CLLocationCoordinate2DMake([boundary.extents.minY floatValue], [boundary.extents.minY floatValue]));
MKMapPoint upperRight = MKMapPointForCoordinate(CLLocationCoordinate2DMake([boundary.extents.maxY floatValue], [boundary.extents.maxY floatValue]));
MKMapRect mapRect = MKMapRectMake(upperLeft.x, upperLeft.y, fabs(upperLeft.x - upperRight.x), fabs(upperLeft.y - lowerLeft.y));
Now I want to check if my 'mapRect' is in the mapView.visibleMapRect:
if (MKMapRectContainsRect(mapView.visibleMapRect, mapRect)) {
// do some stuff
}
But my extents are never contained by the mapView.visibleMapRect when I know they should be.
If I replace the mapView.visibleMapRect with MKMapRectWorld, then it will contain my extents 'mapRect'.
Am I doing something wrong? is mapView.visibleMapRect not what I think it is (the viewable area on the screen)?
D'oh!
The issue was that I used minY instead of minX.
MKMapPoint upperLeft = MKMapPointForCoordinate(CLLocationCoordinate2DMake([boundary.extents.maxY floatValue], [boundary.extents.**minX** floatValue]));
MKMapPoint lowerLeft = MKMapPointForCoordinate(CLLocationCoordinate2DMake([boundary.extents.minY floatValue], [boundary.extents.**minX** floatValue]));
MKMapPoint upperRight = MKMapPointForCoordinate(CLLocationCoordinate2DMake([boundary.extents.maxY floatValue], [boundary.extents.**maxX** floatValue]));
mapView.visibleMapRect is exactly what you think it is, the map rect displayed by your map view. The problem is probably that the MKMapRectContainsRect function only tells you if one map rect is entirely contained (completely enclosed) in another. It's likely that you just want to use MKMapRectIntersectsRect which just tells you that part of your map rect is inside your mapView.visibleMapRect
Related
My map view contains one circle which covers many pinpoints with one center point.Whenever the user clicks a button the map should be zoomed in such a level the circle is visible.The map should not be zoomed more or less it should show exact circle.When user logs out then circle will have new radius in next login.How to calculate the appropriate zoom level.
My code:
-(void)showCircle{
//calculate new radius
long radius=[self calculateRadius];
MKCircle *circle= [[MKCircle alloc]init];
circle = [MKCircle circleWithCenterCoordinate:CLLocationCoordinate2DMake([groupLat floatValue], [groupLon floatValue]) radius:radius];
[myMapView addOverlay:circle];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(CLLocationCoordinate2DMake([groupLat floatValue], [groupLon floatValue]), 800, 800);
MKCoordinateSpan span;
//calculate zoom level
double radius=[circle radius]);
double rad = radius + radius / 2;
double scale = rad / 500;
zoomLevel=(16 - log(scale) / log(2));
region.span.latitudeDelta =zoomLevel;
region.span.longitudeDelta =zoomLevel;
[myMapView setRegion:region animated:YES];
}
Thank you in advance!
You can try : mapRectThatFits(:) or mapRectThatFits(:edgePadding:)
Something like this, maybe, to zoom the map according to your circle :
myMapView.visibleMapRect = [myMapView mapRectThatFits:circle.boundingMapRect];
Hope this helps you :)
I'm trying to zoom to fit annotations on a map while locking the center and providing some insets.
- (void)fitAnnotations:(NSArray *)annotations edgeInsets:(UIEdgeInsets)insets
{
CLLocationCoordinate2D originalCenter = self.centerCoordinate;
MKMapRect mapRect = MKMapRectNull;
for (id<MKAnnotation> annotation in annotations) {
MKMapPoint p = MKMapPointForCoordinate([annotation coordinate]);
mapRect = MKMapRectUnion(mapRect, MKMapRectMake(p.x, p.y, 0, 0));
}
mapRect = [self mapRectThatFits:mapRect edgePadding:insets];
MKCoordinateRegion mapRegion = MKCoordinateRegionForMapRect(mapRect);
// we now try to go back to the original center, while increasing the span by neccessary amount
MKCoordinateSpan centeringDelta = MKCoordinateSpanMake(fabs(mapRegion.center.latitude - originalCenter.latitude), fabs(mapRegion.center.longitude - originalCenter.longitude));
mapRegion.center = originalCenter;
mapRegion.span.latitudeDelta += centeringDelta.latitudeDelta * 2.0;
mapRegion.span.longitudeDelta += centeringDelta.longitudeDelta * 2.0;
mapRegion = [self regionThatFits:mapRegion];
[self setRegion:mapRegion animated:YES];
}
The first part of the code here works as expected: it zooms to fit while respecting the insets. However, it shifts the center.
I try to re-adjust the center after that, but it fails. I'm not sure if my math on the re-centering is correct.
The first part of your code that calculates the bounding map rect that fits the annotations is OK.
Only the adjustment of that "minimal" map rect so that the "locked" center is actually in the center needs to be corrected.
The main problem, I believe, is that the code in the question is adjusting the span to both re-center the region and account for the insets after calling mapRectThatFits: (which will itself already give a slightly modified version of the rect you actually requested).
Instead, your code should only calculate the actual, minimal rect it wants and then finally call setVisibleMapRect:edgePadding:animated: and let the map view figure out both the "rect that fits" and the insets.
Please try the following:
- (void)fitAnnotations:(NSArray *)annotations edgeInsets:(UIEdgeInsets)insets
{
MKMapPoint centerMapPoint = MKMapPointForCoordinate(originalCenter);
//--- First create minimal bounding map rect to tightly fit annotations...
MKMapRect minimalMapRect = MKMapRectNull;
for (id<MKAnnotation> annotation in annotations) {
MKMapPoint annMapPoint = MKMapPointForCoordinate(annotation.coordinate);
minimalMapRect = MKMapRectUnion(minimalMapRect, MKMapRectMake(annMapPoint.x, annMapPoint.y, 0, 0));
}
//--- Now create adjusted map rect so center coordinate is in the center...
//distance of desired center from minimal left edge...
double centerXOffset = centerMapPoint.x - minimalMapRect.origin.x;
//raw amount width needs to be adjusted to get center in center...
//negative/positive indicates whether center is in left/right half
double widthOffset = 2.0 * centerXOffset - minimalMapRect.size.width;
//add absolute value of raw width offset to minimal width...
double adjustedWidth = minimalMapRect.size.width + fabs(widthOffset);
//distance of desired center from minimal top edge...
double centerYOffset = centerMapPoint.y - minimalMapRect.origin.y;
//raw amount height needs to be adjusted to get center in center...
//negative/positive indicates whether center is in top/bottom half
double heightOffset = 2.0 * centerYOffset - minimalMapRect.size.height;
//add absolute value of raw height offset to minimal height...
double adjustedHeight = minimalMapRect.size.height + fabs(heightOffset);
//adjust origin if necessary (if center is in top/left half)...
MKMapPoint adjustedOrigin = minimalMapRect.origin;
if ((centerXOffset / minimalMapRect.size.width) < 0.5)
{
adjustedOrigin.x = adjustedOrigin.x + widthOffset;
}
if ((centerYOffset / minimalMapRect.size.height) < 0.5)
{
adjustedOrigin.y = adjustedOrigin.y + heightOffset;
}
//create adjusted MKMapRect...
MKMapRect adjustedMapRect = MKMapRectMake(adjustedOrigin.x, adjustedOrigin.y, adjustedWidth, adjustedHeight);
//--- Apply the adjusted map rect with insets to map view...
[mapView setVisibleMapRect:adjustedMapRect edgePadding:insets animated:YES];
}
Try something like this, where you use your calculated mapRect to create the new region with your originalCenter via the MKCoordinateRegionMake method
MKCoordinateRegion mapRegion = MKCoordinateRegionForMapRect(mapRect);
mapRegion = MKCoordinateRegionMake(originalCenter, mapRegion.span);
mapView.region = mapRegion;
Try this.
MKMapPoint center = MKMapPointForCoordinate(self.mapView.centerCoordinate);
double maxX = 0;
double maxY = 0;
for (MKPointAnnotation *a in self.mapView.annotations)
{
MKMapPoint p = MKMapPointForCoordinate(a.coordinate);
double deltaX = fabs(center.x - p.x);
double deltaY = fabs(center.y - p.y);
maxX = MAX(maxX, deltaX);
maxY = MAX(maxY, deltaY);
}
MKMapRect rect = MKMapRectMake(center.x - maxX, center.y - maxY, maxX * 2, maxY * 2);
rect = [self.mapView mapRectThatFits:rect edgePadding:UIEdgeInsetsMake(20, 20, 20, 20)];
[self.mapView setVisibleMapRect:rect animated:1];
#moby I am thinking of a different approach. How about taking the maps centre location as you already did. Now calculate distance to each annotation from this centre coordinate till you find the longest annotation (say 'requiredDistance' ).
Get a new map rect with all your annotations plotted with same centre using below code:
MKCircle *circleLine = [MKCircle circleWithCenterCoordinate:self.centerCoordinate radius:requiredDistance];
[self.mapView setVisibleMapRect:circleLine.boundingMapRect];
Coming to your insets what ever insets you wanted to apply should be applied to your 'requiredDistace' variable in such a way that your 'requiredDistance' variable has a value always greater than or equal to the distance between your centre coordinate and your longest annotation to make sure all the annotations are always visible.
I need to place annotations according to their polar coordinate (with radius in pixels) originated at the user position. I use the following code snippet to do that.
CGPoint origin = [mapView convertCoordinate:userCoordinate toPointToView:mapView];
double dx = radius * cos(theta);
double dy = radius * sin(theta);
CGPoint point = CGPointMake(origin.x + dx, origin.y + dy);
NSLog(#"mapViewSize=(%f, %f), point=(%f,%f)", CGRectGetWidth(mapView.bounds), CGRectGetHeight(mapView.bounds), point.x, point.y);
return [mapView convertPoint:point toCoordinateFromView:mapView];
Here is an example of the NSLog output:
mapViewSize=(228.000000, 228.000000), point=(40.817908,123.346518)
In my opinion, this would mean that the point is indeed located on the map view. However, when adding them back on the map after convertPoint:point toCoordinateFromView:, it is placed very far (distance ~ 148847.221119 meters while the span of my region is just hundreds of meter) and therefore are out of the range of my map. What am I doing wrong?
I'm displaying an MKMapView inside a Path-style parallax table view header. To create the effect, the mapView bounds is larger than the area visible to the user. I need to set the map view region such that all the map's annotations are contained within the visible rect of MKMapView. What's the best way to do this?
Edit for clarity: Here's a use-case. The mapView size is 320 x 380. The visible area, however, is defined by the rect (0.0, 20.0, 320.0, 100.0). I need to set the region such that all the annotations appear in this rect within the mapView.
Setting the map region so that all annotations are contained in a certain part of an MKMapView can be done in three steps. Input are the mapView and the annotationsFrame.
Calculate an MKMapRect mapRect that contains all annotations.
Calculate the padding insets from mapView.bounds and annotationsFrame.
Call -setVisibleMapRect:edgePadding:animated: on the map view.
Below is a screen shot of a test. The red overlay shows the annotationsFrame.
Here is the code. Beware: It's all in one method to simplify adding it to your code, and it is not tested for edge cases like passing in n annotations with the same coordinate, or having the annotations so far apart that the map would have to get zoomed out too much, or having coordinates that span the edge of the map at +/-180 degrees longitude.
- (void)zoomAnnotationsOnMapView:(MKMapView *)mapView toFrame:(CGRect)annotationsFrame animated:(BOOL)animated
{
if (_mapView.annotations.count < 2) return;
// Step 1: make an MKMapRect that contains all the annotations
NSArray *annotations = _mapView.annotations;
id <MKAnnotation> firstAnnotation = [annotations objectAtIndex:0];
MKMapPoint minPoint = MKMapPointForCoordinate(firstAnnotation.coordinate);
MKMapPoint maxPoint = minPoint;
for (id <MKAnnotation> annotation in annotations) {
MKMapPoint point = MKMapPointForCoordinate(annotation.coordinate);
if (point.x < minPoint.x) minPoint.x = point.x;
if (point.y < minPoint.y) minPoint.y = point.y;
if (point.x > maxPoint.x) maxPoint.x = point.x;
if (point.y > maxPoint.y) maxPoint.y = point.y;
}
MKMapRect mapRect = MKMapRectMake(minPoint.x, minPoint.y, maxPoint.x - minPoint.x, maxPoint.y - minPoint.y);
// Step 2: Calculate the edge padding
UIEdgeInsets edgePadding = UIEdgeInsetsMake(
CGRectGetMinY(annotationsFrame),
CGRectGetMinX(annotationsFrame),
CGRectGetMaxY(mapBounds) - CGRectGetMaxY(annotationsFrame),
CGRectGetMaxX(mapBounds) - CGRectGetMaxX(annotationsFrame)
);
// Step 3: Set the map rect
[mapView setVisibleMapRect:mapRect edgePadding:edgePadding animated:animated];
}
If you go for a perfect placement (and who doesn't), here are three things to consider:
The code assures that all the coordinates are in the annotationsFrame, but the annotations themselves may be outside. To prevent that, simply use more padding. For example, if your annotations are 20x20 and centered on the coordinate, use 10 more padding on all sides.
Below iOS 7, the map was not zooming to the perfect zoom scale, but to the next tile size (power of two). So there will be more space around the annotations than needed, just as shown on the screenshot.
On iOS 7, the map view will not only zoom perfectly, but automatically care about the status bar. To make the calculation correct, you need to subtract the status bar height from the top padding on iOS 7.
Starting from iOS 7.0, this can be easily achieved with showAnnotations.
Swift:
mapView.showAnnotations(mapView.annotations, animated: true)
Objective-C:
[mapView showAnnotations:mapView.annotations animated:YES];
The above statement will adjust the map view's visible rect in order to display all annotations.
You first need to add the annotations:
(of course this is after you already have a list of annotations)
Swift4:
self.mapView.addAnnotations(annotations)
let currentView = mapView.visibleMapRect
mapView.annotations(in: currentView)
You can use the currentView constant or directly place the MKMapRect as such: Below: (.visibleMapRect returns:
"The area currently displayed by the map view."
mapView.annotations(in: mapView.visibleMapRect)
I found an easier way without calculating is let the map view calculate it, then we adjust the edges.
//1: Show all annotation on the map view, but without animation
self.mapView.showAnnotations(self.mapView.annotations, animated: false)
//2: Get the current visible map rect
let currentMapRect = self.mapView.visibleMapRect
//3: Create the edges inset that you want the map view to show all annotation within
let padding = UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100)
//4: Set current map rect but with new padding, also set animation to true to see effect
self.mapView.setVisibleMapRect(currentMapRect, edgePadding: padding, animated: true)
If you're prepared to approximate the calculations you can do it using some clever scaling.
Your target area is 80 tall out of a mapView that is 380. Therefore you want a region that is 4.75x taller than the region calculated to fit your annotations. (0.25 extra above and 3.5 extra below).
First you need to get a region (or maprect, what ever you prefer working in) and make it the same proportions as your target viewable area. This is because a really wide and short region would not be touching the top and bottom of the viewable area and therefore multiplying its height would not make something that touched the top and bottom of your map view. So if viewable_height/viewable_width > annotations_height/annotations_width you should set the annotations_height to annotations_width * (viewable_height/viewable_width).
With that you then add 25% on to the north of the annotations box and 350% on to the south. You can do this by moving the center 212.5% (of the current height) south and increasing the vertical span by 475%.
Now, all of this is an approximation given that the world is sphere and we're not looking at a planar projection (i.e. 1 degree of latitude near the equator is drawn smaller than 1 degree near the poles). But if you wally want to be accurate you could look into scaling the numbers according to latitude and such. If you're only dealing with annotations on a city-sized scale you'll probably be ok.
Hope that helps.
if you want to find the annotations that are in a given rect:
- (NSArray*)allAnnotationsInMapRect:(MKMapRect)mapRect {
NSMutableArray *annotationsInRect = [NSMutableArray array];
for(id<MKAnnotation *ann in self.allAnnotations) {
MKMapPoint pt = MKMapPointForCoordinate(ann.coordinate);
if(MKMapRectContainsPoint(mapRect, pt)) {
[annotationsInRect addObject:ann];
}
}
return annotationsInRect;
}
and to assure the annotation VIEWS are in the rect, get the region for the annotations,
then walk through them and get each view's bounds see if the bounds fit inside the visibleRect of the map and if not modify the region!
~~ like this:
- (void)assureAnnotationViewsAreVisible:(NSArray*)annotations originalRegion:(MKCoordinateRegion)originalRegion {
CGFloat smallestX = MAXFLOAT;
CGFloat smallestY = MAXFLOAT;
CGFloat biggestX = -100;
CGFloat biggestY = -100;
//NSLog(#"---: %d", annotations.count);
for(id<MKAnnotation> *annotation in annotations) {
UIView *annotationView = [self.mapView viewForAnnotation:v];
CGRect annotationViewFrame = annotationView.bounds;
annotationViewFrame.origin = [self.mapView convertCoordinate:annotationView.coordinate toPointToView:self.mapView];
annotationViewFrame.origin = CGPointMake(annotationViewFrame.origin.x-annotationViewFrame.size.width/2,
annotationViewFrame.origin.y-annotationViewFrame.size.height);
smallestX = MIN(annotationViewFrame.origin.x, smallestX);
smallestY = MIN(annotationViewFrame.origin.y, smallestY);
biggestX = MAX(annotationViewFrame.origin.x+annotationViewFrame.size.width, biggestX);
biggestY = MAX(annotationViewFrame.origin.y+annotationViewFrame.size.height, biggestY);
}
//NSLog(#"---");
CGRect bounds = self.mapView.bounds;
if(smallestX < bounds.origin.x || smallestY < bounds.origin.y || biggestX > bounds.origin.x+bounds.size.width || biggestY > bounds.origin.y+bounds.size.height) {
CGRect neededRect = bounds;
neededRect.origin = CGPointMake(MIN(bounds.origin.x, smallestX), MIN(bounds.origin.y, smallestY));
neededRect.size = CGSizeMake(MAX(bounds.size.width, biggestX), MAX(bounds.size.height, biggestY));
MKCoordinateRegion neededRegion = [self.mapView convertRect:neededRect toRegionFromView:self.mapView];
_ignoreRegionChange = YES;
[self.mapView setRegion:originalRegion animated:NO];
_ignoreRegionChange = NO;
[self.mapView setRegion:neededRegion animated:YES];
}
else {
MKCoordinateRegion currentRegion = self.mapView.region;
_ignoreRegionChange = YES;
[self.mapView setRegion:originalRegion animated:NO];
_ignoreRegionChange = NO;
[self.mapView setRegion:currentRegion animated:YES];
}
}
Try to get from all your annotation edges value (max and min) for lan and lon.
Define this value on the beginning:
static float maxLat = FLT_MIN;
static float maxLon = FLT_MIN;
static float minLat = FLT_MAX;
static float minLon = FLT_MAX;
and then use this function to calculate span and region:
- (void) zoomAndFit {
for(int i = 0; i < [self.points count]; i++) {
PRPlaceModel *place = [self.points objectAtIndex:i];
CLLocationCoordinate2D location;
location.latitude = [place.lat floatValue];
location.longitude = [place.lon floatValue];
minLat = MIN(minLat, location.latitude);
minLon = MIN(minLon, location.longitude);
maxLat = MAX(maxLat, location.latitude);
maxLon = MAX(maxLon, location.longitude);
}
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 1.2*(maxLat - minLat);
span.longitudeDelta = 1.2*(maxLon - minLon);
CLLocationCoordinate2D location;
location.latitude = (minLat + maxLat)/2;
location.longitude = (minLon + maxLon)/2;
region.span=span;
region.center=location;
[self.mapView setRegion:region animated:TRUE];
[self.mapView regionThatFits:region];
}
And use it in viewDidLoad method:
-(void)viewDidLoad
{
[super viewDidLoad];
[self zoomAndFit];
}
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:
{
northeast = {
lat = "30.4212235";
lng = "-97.486942";
};
southwest = {
lat = "30.1128403";
lng = "-97.99917959999999";
};
}
I then convert these into CLLocationCoordinate2D
NSDictionary *viewport = [[[results objectAtIndex:0] objectForKey:#"geometry"]
objectForKey:#"viewport"];
NSDictionary *NEDictionary = [viewport objectForKey:#"northeast"];
NSDictionary *SWDictionary = [viewport objectForKey:#"southwest"];
CLLocationCoordinate2D SWCoordinate =
CLLocationCoordinate2DMake(
[[SWDictionary objectForKey:#"lat"] floatValue],
[[SWDictionary objectForKey:#"lng"] floatValue]
);
CLLocationCoordinate2D NECoordinate =
CLLocationCoordinate2DMake(
[[NEDictionary objectForKey:#"lat"] floatValue],
[[NEDictionary objectForKey:#"lng"] floatValue]
);
I know I need to generate a MKMapRect (or MKMapRegion, whichever is easier) from these coordinates and then [mapView setVisibleRect:newRect animated:YES] (or [mapView setRegion:newRegion animated:YES] but I'm not quite sure how to get there. I need a method to convert the bounds into the proper data structure, something like:
- (MKMapRect) mapRectThatFitsBoundsSW:(CLLocationCoordinate2D)sw
NE:(CLLocationCoordinate2D)ne {
// CGFloat x = ??
// CGFloat y = ??
// CGFloat width = ??
// CGFloat height = ??
MKMapRect mapRectFromBounds = MKMapRectMake(x,y,width,height);
return mapRectFromBounds;
}
Any thoughts?
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.)
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!
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 {
// ????
// }
}