MKCoordinateRegionMakeWithDistance does not set the correct region on the MapView

I have this code:

- (void)viewDidLoad { [super viewDidLoad]; CLLocationCoordinate2D userLocation = CLLocationCoordinate2DMake(48.9793946200, 2.4726272850); CLLocationDistance dist1 = 636.9887048804; CLLocationDistance dist2 = 900.8380655203; CLLocationDistance dist = dist1; [self.myMapView setRegion:MKCoordinateRegionMakeWithDistance(userLocation, dist, dist) animated:YES]; // TEST // ------------------------------------------------------------ MKCoordinateRegion region = self.myMapView.region; CLLocationDegrees lat = region.center.latitude; CLLocationDegrees lon = region.center.longitude - region.span.longitudeDelta/2; CLLocation *west = [[[CLLocation alloc] initWithLatitude:lat longitude:lon] autorelease]; NSLog(@"User location: lat : %.10lf long : %.10lf", userLocation.latitude, userLocation.longitude); NSLog(@"distance set: %.10lfm", dist); NSLog(@"center: lat : %.8lf long : %.8lf", region.center.latitude, region.center.longitude); CLLocation* centerRegion = [[[CLLocation alloc] initWithLatitude:region.center.latitude longitude:region.center.longitude] autorelease]; NSLog(@"distance to western boundary: %.2lfm", [centerRegion distanceFromLocation:west]); lat = region.center.latitude - region.span.latitudeDelta/2 ; lon = region.center.longitude; CLLocation *north = [[[CLLocation alloc] initWithLatitude:lat longitude:lon] autorelease]; NSLog(@"distance to western boundary: %.2lfm", [centerRegion distanceFromLocation:north]); // ------------------------------------------------------------ } 

When setting dist = dist1, which gives:

 User location: lat : 48.9793946200 long : 2.4726272850 distance set: 636.9887048804m center: lat : 48.97937199 long : 2.47269630 distance to western boundary: 500.44m distance to western boundary: 650.57m 

enter image description here

When setting dist = dist2, which gives:

 User location: lat : 48.9793946200 long : 2.4726272850 distance set: 900.8380655203m center: lat : 48.97937199 long : 2.47269630 distance to western boundary: 500.44m distance to western boundary: 650.57m 

enter image description here

What is the problem? Why do I have the same display with two different distances?

The final question: how can I confidently display the required counters on the map, at least for horizontal and vertical visualization (with or without a course)?

+4
source share
2 answers

If I understand correctly, you want to tell mapView to "give me a map that is 636 meters across" or "give me a map that is 900 meters across." But the map gives you the same distance for both of them.

When you set the region of a map, you usually don’t get exactly what you ask for, but they’re best suited. The map view looks at the region you requested, and then creates a region that matches your region within it. The problem is that the map view doesn't exactly come close to your requested region, it finds the highest zoom level that allows you to see your entire region. It will not use an intermediate zoom level. That is why when you use setRegion: map always looks crisp. You can manually set the intermediate zoom level by inserting or pulling, but not (as far as I know) programmatically.

Note that the map view may change the actual region variable that you pass to it. Here are the docs:

When setting up a new area, the map can adjust the value in the area parameter so that it exactly matches the visible area of ​​the map. This is normal and done to ensure that the value in the area property always reflects the visible part of the map. However, this means that if you get the value of this property immediately after calling this method, the return value may not match the value you set. (You can use the regionThatFits: method to determine the area that will actually be defined by the map.)

You can see the difference in the regions by registering the region that you give it to and the one that actually displays the map view (although I did not see the passed myRegion change):

 MKCoordinateRegion myRegion = MKCoordinateRegionMakeWithDistance(userLocation, dist, dist); NSLog(@"Passed: %f %f", myRegion.span.latitudeDelta, myRegion.span.longitudeDelta); [self.mapView setRegion:myRegion animated:YES]; NSLog(@"Passed 2: %f %f", myRegion.span.latitudeDelta, myRegion.span.longitudeDelta); NSLog(@"Set: %f %f", mapView.region.span.latitudeDelta, mapView.region.span.longitudeDelta); > Passed: 0.005728 0.008702 > Passed 2: 0.005728 0.008702 > Set: 0.012957 0.013733 

If you hit a distance of up to 1200 m, you can see the next zoom level.

By the way, there is a small error in your code:

 NSLog(@"distance to western boundary: %.2lfm", [centerRegion distanceFromLocation:north]); 

it should be

 NSLog(@"distance to northern boundary: %.2lfm", [centerRegion distanceFromLocation:north]); 
+7
source

One possible reason for this is because the area you specify has a square aspect ratio, and your MKMapView probably has a rectangular shape.

When you set the MKMapView , it will not use it exactly as it is, but it will change it so that:

  • its aspect ratio is consistent with the representation
  • the new region contains the specified

Thus, if your view has a width: height ratio of 2: 1, then the west / east borders will be 200 meters from the center, and north / south - 100 meters from the center.

Try something after setting the area as above:

 MKCoordinateRegion region = self.mapView.region; CLLocationDegrees lat = region.center.latitude; CLLocationDegrees lon = region.center.longitude - region.span.longitudeDelta/2; CLLocation *west = [[CLLocation alloc] initWithLatitude:lat longitude:lon]; NSLog(@"distance to western boundary: %.2lfm", [userLocation distanceFromLocation:west]); lat = region.center.latitude + region.span.latitudeDelta/2 lon = region.center.longitude; CLLocation *north = [[CLLocation alloc] initWithLatitude:lat longitude:lon]; NSLog(@"distance to northern boundary: %.2lfm", [userLocation distanceFromLocation:north]); 

One of them should be 100 m. If not, I would be interested to see what they are.

PS The above code has not been tested in any way.

+1
source

All Articles