Map view span changes when updating the location - ios

I have a function in my view controller with a mapkit that is called when the location changes. I would like set to the map view so that is is centered around the current location and moves with it as it updates.
It works in a sense i.e it tracks along, however it is always zoomed in really far. If I zoom out it snaps back to where it was when it calls the update again after getting a new location.
in from params CLLocation *loc
bool first = TRUE;
if(first){
first=FALSE; // bit of a bodge...if i set this to false it will track the update possition but not at the desired "zoom" its look far to close.
CLLocation *loc = [[CLLocation alloc] initWithLatitude:54.976619 longitude:-1.613118];//newcastle city center.
CLLocationDegrees spanLat = 1000;
CLLocationDegrees spanLng = 1000;
userLocation = MKCoordinateRegionMakeWithDistance(loc.coordinate, spanLat, spanLng);
[mapview setRegion:userLocation animated:TRUE];
}else {
CLLocationDegrees spanLat = [mapview region].span.latitudeDelta;// keep the originals? DOESN'T WORK!!
CLLocationDegrees spanLng = [mapview region].span.longitudeDelta;//
userLocation = MKCoordinateRegionMakeWithDistance(loc.coordinate, spanLat, spanLng);
[mapview setRegion:userLocation animated:TRUE];
}

Just keep setting the center coordinate and don't set the region.
By the way, you do know that you don't need any of that code, right? You can just tell the mapview to track the device's current location. See my book for an example:
http://www.apeth.com/iOSBook/ch34.html#_map_kit_and_current_location

Related

MKPolyline replacement causes MKTileOverlay to flash on map since iOS 13

I have an MKMapView that has a MKTileOverlay so that I can show Open Street Map tiles:
NSString *templateURL = #"http://tile.openstreetmap.org/{z}/{x}/{y}.png";
self.tileOverlay = [[MKTileOverlay alloc] initWithURLTemplate:templateURL];
self.tileOverlay.canReplaceMapContent = YES;
[self.mapView addOverlay:self.tileOverlay level:MKOverlayLevelAboveLabels];
I also want to show an MKPolyline from my current location to Apple Park in Cupertino. This polyline needs to be updated as I move, and since an MKPolyline object isn't mutable, I have to remove it and add it for each location update:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray*)locations {
self.currentLocation = userLocation;
// Update polyline
CLLocationCoordinate2D applePark = CLLocationCoordinate2DMake(37.334626, -122.008895);
[self buildPolylineWithDestinationLocation:applePark];
}
- (void)buildPolylineWithDestinationLocation:(CLLocationCoordinate2D)coordinate {
// Remove the polyline each time so we can redraw it
if (self.polylineApple) {
[self.mapView removeOverlay:self.polylineApple];
}
// Get current location
CLLocation *location = self.currentLocation;
CLLocationCoordinate2D currentLocation = location.coordinate;
CLLocationCoordinate2D points[2];
points[0] = currentLocation;
points[1] = coordinate;
// Remove all route polylines
MKPolyline *oldPolyline = self.polylineApple;
// Draw a line
self.polylineApple = [MKPolyline polylineWithCoordinates:points count:2];
[self.mapView addOverlay:self.polylineApple];
if (oldPolyline) {
[self.mapView removeOverlay:oldPolyline];
oldPolyline = nil;
}
}
The problem is, this used to work great in older versions of iOS, but ever since iOS 13 this has caused the tiles to be redrawn each time that MKPolyline is removed and added:
Is this just an iOS 13 bug, or is there something I need to fix in my code to make this not happen?
As I know since iOS 8, I have seen this issue. Not always but some times.
This issue is linked to 2 things:
1) The action every second to remove and add again a polyline will ask the MKMapView to redrawn the part with the polyline and as a consequence the MKTileOverlay below.
2) If the tile's size (in KB, not the resolution) is low, the issue may not be present.
The best advice I can give to you is to add you own view to the MKMapView and update this own view by calling setNeedsDisplay. It will trigger the draw method where you can convert the map points (latitude, longitude) to screen points and draw the line.
Edit: A link speaking about MKTileOverlay reload issue
https://forums.developer.apple.com/message/313677#313677

MKCoordinateRegionMakeWithDistance displaying wrong coordinates

I'm trying to set approx a 10 mile range around the current location of the user when my mapView loads.
Here is my Objective C code in viewDidLoad:
self.mapView = [[MKMapView alloc] initWithFrame:self.view.frame];
self.mapView.delegate = self;
self.mapView.showsUserLocation = YES;
[self.view addSubview:self.mapView];
//Set initial scope of map
CLLocationDistance mapWidith = 16000;
CLLocationDistance mapHeight = 16000;
CLLocationCoordinate2D userLocation = self.mapView.userLocation.coordinate;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation, mapHeight , mapWidith);
[self.mapView setRegion: region
animated:false];
When I run it's starting with the correct zoom (I think) but randomly centered in the atlantic ocean somewhere. Not sure if I'm accessing the userLocation coordinate correctly but it seems right. Im pretty new to MKMapView so Im struggling a bit.
The userLocation property on mapView isn't populated yet. You should implement the mapView:didUpdateUserLocation: method and after that point you can reliably use that property (or use the location sent to you).

Showing a location with respect to another location without using Map

I am creating a location based iPhone App.
I have two locations (their lat and long).
One location is fixed to center of the UIView, How can show the other location with respect to first location.
Please give me code if available.
If you're just trying to find the distance between your two points then you could use the CoreLocation function:
CLLocation *startLocation = [[CLLocation alloc] initWithLatitude:startLatitude longitude:startLongitude];
CLLocation *endLocation = [[CLLocation alloc] initWithLatitude:endLatitude longitude:endLongitude];
CLLocationDistance distanceMeters = [startLocation distanceFromLocation:endLocation];

MKAnnotation not updating position

I am using the HGMovingAnnotation and HGMovingAnnotationView code off of github to animate a MKAnnotation on an MKmap. When I run the example project from HG project everything works fine.
I have altred the original HG project to allow me to manually push a new coordinate to the HGMapPath and then move the annotation where I want it.
I have placed a button, for testing, to run the manual process and everything works fine. The annotation moves around the screen. The issue is, when I try to now call this manual method with data from a live socket.io connection, the map annotation won't move.
Also, when the map first loads the annotation won't show up until I move the map a little bit. The same thing for the moving annotation manually, it won't show the movement from the stream of data, until I zoom the map. But if I do the push button way, avoiding the io stream, the annotation moves without needing to zoom or pan the map?
PLACING THE VIEW ANNOTATIONS
if(doubleLat && doubleLng) {
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(doubleLat, doubleLng);
//Create path object
self.assignedAmbPath = [[HGMapPath alloc] initWithCoordinate:coordinate];
HGMovingAnnotation *movingObject = [[HGMovingAnnotation alloc] initWithMapPath:self.assignedAmbPath];
self.movingAssignedAmbObject = movingObject;
// add the annotation to the map
[self.mapView addAnnotation:movingObject];
// zoom the map around the moving object
MKCoordinateSpan span = MKCoordinateSpanMake(0.01, 0.01);
MKCoordinateRegion region = MKCoordinateRegionMake(MKCoordinateForMapPoint(self.movingAssignedAmbObject.currentLocation), span);
[self.mapView setRegion:region animated:YES];
// start moving the object
[movingObject start];
}
CODE THAT WORKS
- (IBAction)testMoveBtnPressed:(id)sender {
//TODO: move x and y
DLog(#"============== Test move button was pressed ================ ");
NSLog(#"");
int randn = (random() % 15)+15;
float pscale = (float)randn / 10000;
double lat = 39.9813855 + pscale;
double lng = -75.1502155 + pscale;
for (id<MKAnnotation> annotation in self.mapView.annotations){
MKAnnotationView* anView = [self.mapView viewForAnnotation: annotation];
if (![annotation isKindOfClass:[PhoneAnnotation class]]){
// Process annotation view
[((HGMovingAnnotation *)annotation) trackToNewPosition:CLLocationCoordinate2DMake(lat, lng)];
}
}
}
CODE THAT DOESN'T WORK
{
//TODO: move thing to new location
double doubleLat = [lat doubleValue];
double doubleLng = [lng doubleValue];
// NSLog(#"--------------- Jason it is ------------- Latitude being passed in is %f", doubleLat);
// NSLog(#"--------------- Jason it is ------------- Longitude being passed in is %f", doubleLng);
//
// [self.movingAssignedAmbObject trackToNewPosition:CLLocationCoordinate2DMake(doubleLat, doubleLng)];
for (id<MKAnnotation> annotation in self.mapView.annotations){
MKAnnotationView* anView = [self.mapView viewForAnnotation: annotation];
if (![annotation isKindOfClass:[PhoneAnnotation class]]){
// Process annotation view
[((HGMovingAnnotation *)annotation) trackToNewPosition:CLLocationCoordinate2DMake(doubleLat, doubleLng)];
}
}
}
The issue is the HG library though works as described doesn't work proper, unless your using the path, if you don't create the annotation with a coordinate attached, which it doesn't.

How to zoom into user current location?

I wanna zoom into the user current location when the app starts in the MapKit.
This is my code (in the viewDidLoad function):
Locate=[[CLLocationManager alloc]init];
Locate.delegate=self;
Locate.desiredAccuracy=kCLLocationAccuracyBestForNavigation;
Locate.distanceFilter=kCLDistanceFilterNone;
[Locate startUpdatingLocation];
[super viewDidLoad];
//Region
MKCoordinateRegion myRegion;
//Center
CLLocationCoordinate2D center;
center.latitude=Locate.location.coordinate.latitude;
center.longitude=Locate.location.coordinate.longitude;
//Span
MKCoordinateSpan span;
span.latitudeDelta=0.3f;
span.longitudeDelta=0.3f;
//Set Region
myRegion.center=center;
myRegion.span=span;
[_MyMap setRegion:myRegion animated:YES];
Also I implemented the didUpdateLocation function with the same code as previous.
The problem is that when the user location is changing (when the user is moving) the screen makes zoom at him but I can't move the screen, if I try to move it return to the user location immediately, so I can't see the whole map.
For Zooming the map you have to change the region values means center and span.once see this one Mapview Zoom
in my case i have used this one for moving the map when i click on particular button.
MKCoordinateSpan span = MKCoordinateSpanMake(30.5982f,0.0001f);
CLLocationCoordinate2D coordinate = {36, 90};
MKCoordinateRegion region = {coordinate, span};
MKCoordinateRegion regionThatFits = [self.mapView regionThatFits:region];
[self.mapView setRegion:regionThatFits animated:YES];
I solved this issue by adding touchesMoved function and I stopped updating the Location in this function.
Solved.

Resources