I'm doing something that seems so simple that I can't believe it's not working, and I can't figure out what I"m doing wrong.
Basically, I'm loading an MKMapView, and it's working great; all the features I want work, except for one. I want to have it default to a larger region than it does. To that end, I've done the following:
MKCoordinateRegion biggerMap = MKCoordinateRegionMake(self.MyMap.centerCoordinate, MKCoordinateSpanMake(80.0, 80.0));
[self.MyMap setRegion:biggerMap animated:YES];
I don't really want 80 degrees in each direction, but I wanted to go big just to make sure that the change from the built-in default was drastic enough to notice. Unfortunately, nothing changes. I put this code right alongside all the code that sets the MKMapView's other parameters, and they're doing the right thing, so I know the block is executing...
Just in case it was an issue with my region not aligning nicely, I tried a second version of that second line:
[self.MyMap setRegion:[self.MyMap regionThatFits:biggerMap] animated:YES];
But that didn't fix it.
The documentation makes it seem like there just isn't that much to changing the region, so I'm stumped. Anyone have any ideas as to what I might be doing wrong?
Thanks!
This is what I do to change region:
MKCoordinateRegion myRegion;
myRegion.center.latitude = -31.952745;
myRegion.center.longitude = 115.857697;
// this sets the zoom level, a smaller value like 0.02
// zooms in, a larger value like 80.0 zooms out
myRegion.span.latitudeDelta = 0.02;
myRegion.span.longitudeDelta = 0.02;
[myMap setRegion:myRegion animated:YES];
Does it work for you?
Related
I'm using mapbox-iOS-SDK 3.2.3 and can't find any properties or smth like this to control the map bounds. I need to limit the visible area for the user. Is it possible in current SDK version?
There's nothing built in to the current version of Mapbox that looks like it would do what you want. You might be able to get something like it by
Implementing mapViewRegionIsChanging: or mapView:regionDidChangeAnimated: in the map view delegate
In those methods, check the current region. If it's outside the desired area, reset the map view to something inside the desired region. That is, as soon as the map view starts to move outside the region, make it go back.
This would probably work but it might make the view "stutter" if the user tries to scroll outside the target region. I don't know what your app does, but it might be worth considering (a) whether this is actually necessary and (b) whether there might be a better way to avoid whatever problem you expect than restricting map view scrolling.
I took the idea from #Tom Harrington and implemented the delegate with the goal of seeing how much stutter or animation jankiness there was while keeping a user within a known Mapbox bound. I upvoted his answer, but also wanted to share this example.
Here is a Swift delegate that fills out the delegate for mapViewRegionIsChanging
the main goal is to test if the experience is still pleasing to the customer (yes)
Can the delegate properly keep the user within bounds without calling the delegate too often? (still needs to be verified)
Uses Balboa Park, as a square Mapbox MGLCoordinateBounds
Only checks if the customer scrolls too far north
The concept of too far is checked by some tolerance, epsilon
Checking out of bounds on four sides should be straightforward
func mapViewRegionIsChanging (mapView: MGLMapView) {
let viewBounds = mapView.visibleCoordinateBounds
// Set the map's bounds to Balboa Park, San Diego
let boundsBalboaPark = MGLCoordinateBounds(
sw: CLLocationCoordinate2D(latitude: 32.71942, longitude: -117.15914),
ne: CLLocationCoordinate2D(latitude: 32.74093, longitude: -117.13374))
let deltaNorth = viewBounds.ne.latitude - boundsBalboaPark.ne.latitude
let epsilon = 0.025 // Magic number for tolerance of how far 'north' we allow (in degrees); Q.E.D meters
if( deltaNorth > epsilon) {
mapView.setVisibleCoordinateBounds(boundsBalboaPark, animated: true)
}
}
This animation shows moving the mapView too far north of Balboa Park. The stutter you see is real, but acceptable.
I am trying to focus my map view on a particular region, but in such a way that it doesn't break the current camera (viewing angle). When I call setVisibleMapRect, the camera always resets and the view becomes completely top-down.
Is there any way to either preserve the map's camera angle, or restore it after calling setVisibleMapRect? I can't seem to get this to work to matter what I try. To be clear, I obviously don't want the exact same camera, because then calling setVisibleMapRect would be pointless, but I want to keep the "relative angle" of the camera while still zooming in or out based on the given visible map rect.
I've even gone so far as to attempt to compute the altitude based on the angle using some trigonometry but I can't seem to get it to work properly by setting the camera immediately after calling setVisibleRect. I'm guessing they're not meant to be used together.
Is trying to use setVisibleRect with a custom camera a bad idea? Should I just try to figure out the appropriate values to set the camera to? This is tricky because the camera properties are not intuitive and there don't seem to be any handy helper methods to focus on a particular region or rect on the map while using a nonzero camera angle. Any pointers would be appreciated.
You can use MKMapCamera to control the pitch and altitude. You can read the settings of the camera before changing the rect and then set them again once the new rect has been set. Here is how you set up a camera:
//create camera object
MKMapCamera *newCamera=[[MKMapCamera alloc] init];
//set a new camera angle
[newCamera setCenterCoordinate:CLLocationCoordinate2DMake(lat,lon)];
[newCamera setPitch:60.0];
[newCamera setAltitude:100.0];
[mapView setCamera:newCamera animated:YES];
Easiest way to fix this issue is, set the pitch right after setVisibleRect.
i.e.,
mapView.setVisibleMapRect(yourRect, edgePadding: yourPadding, animated: true)
mapView.camera.pitch = 45
I am trying to use the following function zoomWithLatitudeLongitudeBoundsSouthWest to zoom to the extent of the uk. I have the following latlongs:
SouthWest = (latitude = 49.724355000000003, longitude = -8.7919210000000003)
NorthEast = (latitude = 59.556961999999999, longitude = 2.102922)
So use the following:
[rmMapView zoomWithLatitudeLongitudeBoundsSouthWest:self.southWest northEast:self.northEast animated:YES];
When this is passed in to the function it returns the following projected bounds:
origin: (185130.482481, 6398696.510918) size: (48919.698096, 66653.088655)
However, this is not the extent of the UK as expected, it actually zooms in to France. During the process I also set the constraints of the map using the following:
[rmMapView setConstraintsSouthWest:self.southWest northEast:self.northEast];
When I pan around the map and zoom out, the constraints of the map are correct i.e. I can't move outside of the UK. This means that the southWest and northEast are set correctly, however, the zoomWithLatitudeLongitude function is not moving to the correct area. I use this function on smaller areas (subsections of the uk) and it seems to work correctly. Can anyone tell me if they have had similar issues or what I am doing wrong?
Thanks
Maybe this is little late, but this issue lost me a whole day of work. You are probably testing on 64 bit devices. Try your code on 32 bit devices and it should probably be working fine.
Mapbox had a problem of centering the zoom on 64 bit devices (the zoom level is ok, but the map offset is not).
I worked around this solution by setting the new center of the map after setting the zoom.
Try adding this line:
[rmMapView setCenterCoordinate:CLLocationCoordinate2DMake(lat,lng)];
just after zoomWithLatitudeLongitudeBoundsSouthWest
where lat = (latMin + latMax)/2 and lng = (lngMin + lngMax)/2)
NOTE: I was passing animated:NO so this worked in my case. Try somehow animating seCenterCoordinate in your case.
For some reason there is a problem with the MapView frame during initialisation. Updating the frame based on another view in the ViewDidLoad seemed to fix the problem.
[self.mapView setFrame:self.view.frame];
Not investigated this fully but seemed to be a good workaround.
This is a small method of mine which takes the location manager's current location and focuses the map just a little bit above it to make room for some other subviews that I've added to the top of the map. If the span's lat/long deltas get too big (more than 1.0), every time the region is set, the span gets bigger and bigger until the map is zoomed out all the way, even without actually touching the map. I think it has something to do with reusing the map view's span, but I don't know exactly what's going on.
- (void)setRegion {
CLLocationCoordinate2D coord = locationManager.location.coordinate;
MKCoordinateSpan span = mapView.region.span;
coord.latitude += 0.002 * (span.latitudeDelta / 0.012523);
MKCoordinateRegion region = MKCoordinateRegionMake(coord, span);
[mapViewGlobal setRegion:region animated:animated];
}
From Apple's docs "If you want to change the center coordinate without changing the zoom level, use the setCenterCoordinate:animated: instead." MKMapView
- (void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated
MKMapView will pick a new region that nicely fits the to a redefined zoom level while still displaying your entire target region and each time yo move north the span changes and things spiral out of control.
Also, your way of working out how much to change the latitude by is a bit odd. Aside from doing a multiple and divide when one would do the trick, it'll only work at a certain latitude (they get stretched away from the equator) and a certain zoom level. You'd be better off working out how many pixels you need the map scrolled by (presumably half the height of your subviews) and then using this function to work out where you need to center the map.
- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view
Another way would be to put the subviews outside of the MKMapView, but that'll affect your aesthetics.
I am using PanoramaGL to make a 360 degree rotating image,the problem is how can i make it stop rotating automatically?
While researching for a solution on this case I've managed to get it working.
All you need to do on iOS is insert a line on PLViewBase.m, at method drawViewInternally.
After:
[camera rotateWithStartPoint:startPoint endPoint:endPoint];
Insert:
startPoint = endPoint;
This will trick PanoramaGL to assume the "first touch location" as the last one, therefore the "distance" between the drag points are always tiny enough to make a consistent and smooth scroll.
Then you just need to adjust the sensitivity. 10.0f did fine for me.
try this
plView.isScrollingEnabled = NO