How to create CLCircularRegion using min max geometry bounds - ios

I am working on geofencing where I have to do region monitoring. I am new to geofence topic. I have bounds(min-max coordinates) and geometry data(all location coordinates). From the below bounds, I am creating CLCircularRegion.
"bounds":{"minlat":50.7238333,"minlon":-1.8716499,"maxlat":50.7248599,"maxlon":-1.8683962}
To initialise CLCircularRegion, we need center and radius. I have calculated centerpoint using the following formula:
center = CLLocationCoordinate2D(latitude: CLLocationDegrees((minLat + maxLat) / 2), longitude: CLLocationDegrees((minLng + maxLng) / 2))
But I am unable to understand how to calculate radius.
Any Idea how to do that?

You only have to calculate the distance from center to a point.
Use CLLocation method distance(from:). You can create CLLocation instances with latitude and longitude.

Related

Find coordinates in MKCoordinateRegion

I have a list of places with their coordinates (latitude + longitude).
I want to get only the places that are in the region displayed on the screen.
I can get the current region displayed on my screen with:
MKCoordinateRegion(center: CLLocationCoordinate2D, span: MKCoordinateSpan)
However I don't know under which parameters I should filter the coordinates of my list to only get the places in this region.
MKCoordinateSpan isn't convertible into a distance mesure from the center.
Thanks for helping
I think the simplest way is to get the displayed region as an MKMapRect with visibleMapRect and convert your coordinates to MKMapPoint using the MKMapPoint(_:) initializer. That way you can just call MKMapRect contains(_:).

Calculate coordinates of map square from map center

I want to get the coordinates of the corners of the rectangle. Or to find the coordinate of the north-westest most point, 50 km from the map centre.
Does anyone know how I can do that?
The point is when I move around the map, I want to always have a rectangle(the rectangle does not need to drew, I just need its coordinates for a backend request), with it's corners always at 50 km from the current centre of the map.
I'm thinking of using somehow the distance function from CLLocation, but in this case I have the distance, but not one of the coordinates.
50km = mapCenterLocation.distance(from: coordinatesUnknown)
Not really sure what do you mean, but maybe this can help
func getNewTargetCoordinate(position: CLLocationCoordinate2D, userBearing: Float, distance: Float)-> CLLocationCoordinate2D{
//haversine formula
//r is earth radius
let r = 6378140.0
let latitude1 = position.latitude * (Double.pi/180);
let longitude1 = position.longitude * (Double.pi/180);
//bearing for user heading in degree
let brng = Double(userBearing) * (Double.pi/180);
//calculating user new position based on user distance and bearing can be seen at haversine formula
var latitude2 = asin(sin(latitude1)*cos(Double(distance)/r) + cos(latitude1)*sin(Double(distance)/r)*cos(brng));
var longitude2 = longitude1 + atan2(sin(brng)*sin(Double(distance)/r)*cos(latitude1),cos(Double(distance)/r)-sin(latitude1)*sin(latitude2));
//converting latitude as degree
latitude2 = latitude2 * (180/Double.pi)
longitude2 = longitude2 * (180/Double.pi)
// return location of user
return CLLocationCoordinate2DMake(latitude2, longitude2)
}
This work for NE direction and distance in meters
for the north-west direction, I think you can just put 135 for the degree and 5000 for distance.
For the position, you need to put map center location.
edit:
For custom rectangle., you can first check for the diagonal degree
func getDiagonalDegree(x: Float, y:Float) -> Float{
return atan2(y,x)*(180/Double.pi)
}
So now you can get that returned diagonal degree to and put it in getNewTargetCoordinate. New bearing is 270+diagonalDegree.
Not sure if I understand you correctly, but I think this could help, or at least point you on some direction
CLLocationCoordinate2D northWest;
northWest = [mapView convertPoint:CGPointMake(0, 0) toCoordinateFromView:mapView];
With this you will get the coordinates for the top left corner of the map, I think you just need to adjust this to set a point 50 km of your center and get the coordinate with this same logic.

MKMapView - how to calculate radius consistent with set-up

I draw a circle on an MKMapView. But how do I calculate the radius of this circle such that it equals the value of the radius used to draw the circle in the first place?
func setArea(_ center:CLLocationCoordinate2D, radius:CLLocationDistance) {
let area = MKCircle(center:center, radius:radius / LocationViewController.kRadiusInset)
mapView.setVisibleMapRect(mapView.mapRectThatFits(area.boundingMapRect), animated:false)
}
I've tried the following but it returns a value very slightly larger than radius passed to setArea. It calculates the distance from the center of the map to the left-hand edge.
// getRadius
let distance = middle.distance(from: edge)
let middle = CLLocation(latitude: mapView.region.center.latitude, longitude: mapView.region.center.longitude)
let edge = CLLocation(latitude: mapView.region.center.latitude, longitude: mapView.centerCoordinate.longitude - (mapView.region.span.longitudeDelta * 0.5))
let distance = middle.distance(from: edge)
If I pass in '4000' metres to setArea() and then afterwards calculate the map's radius (say, within mapViewDidFinishRenderingMap() I get 4010.61219348448
Why the discrepancy?
I replaced the use of a MKCircle with the following:
let region = MKCoordinateRegionMakeWithDistance(center, radius * 2, radius * 2)
mapView.region = region
This is less inaccurate. With radius == 4000 fed into this I get 4000.00048143541 after I set my MKMapView's region. This difference will creep into the user-interface but not nearly as quickly as my first approach.
Can anyone get closer?

Request mapkit annotations to the server by position and zoom level

I have this question:
I have an API server to request points nearest a position (lat & long) and distance (km)
I would to call this API when the user make a pan on the map..so I would to calculate the distance parameter in function of zoom level..
How can I obtain this?
At this moment I have this MapKit delegate method:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
MKZoomScale currentZoomScale = mapView.bounds.size.width / mapView.visibleMapRect.size.width;
NSLog(#"currentZoom:%f", currentZoomScale);
[self.dataReader sendServerRequestWithCoordinate:mapView.region.center andDistance:[self getDistanceByZoomLevel:currentZoomScale];
}
- (float) getDistanceByZoomLevel:(MKZoomScale) zoomLevel {
/// ?????? ////
}
You don't need to calculate the distance based on a "zoom level" or "zoom scale".
Map Kit and Core Location have methods and functions to calculate distance given coordinates or map points.
Assume you want to use the diagonal distance (from top-left to bottom-right) covered by the currently visible map.
The corner coordinates (CLLocationCoordinate2Ds) can be obtained from the map view's region property and then you can use the distanceFromLocation method to calculate the distance between the two coordinates.
The corner map points (MKMapPoints) can be obtained from the map view's visibleMapRect property and then you can use the MKMetersBetweenMapPoints function to get the distance between them.
Here's an example using the map points:
MKMapRect vmr = mapView.visibleMapRect;
//vmr.origin is the top-left corner MKMapPoint
MKMapPoint bottomRightMapPoint =
MKMapPointMake(vmr.origin.x + vmr.size.width,
vmr.origin.y + vmr.size.height);
CLLocationDistance distanceMeters =
MKMetersBetweenMapPoints(vmr.origin, bottomRightMapPoint);
Of course, if you want kilometers instead of meters, divide distanceMeters by 1000.0.
Also, if by "distance" you actually want the radius (distance from the center point), then also divide distanceMeters by 2.0.

MKMapView - Get corner of region

I'm currently trying to get the South-West and North-East corner (long and lat of each one) of the currently displayed region. I'm using the following delegate to get notified about region changes:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;
I hope someone can help me!
Cheers,
Lukas
The region will give you the center (latitude, longitude), latitudinal span (in degrees of latitude) and longitudinal span.
To find the latitude of the North West corner, add 1/2 the latitudeDelta to the latitude of the region's center. Repeat as necessary with the other 3 values, adding or subtracting as necessary.
CLLocationCoordinate2D northWest = CLLocationCoordinate2DMake(
myRegion.center.latitude + myRegion.span.latitudeDelta / 2.0,
myRegion.center.longitude - myRegion.span.longitudeDelta / 2.0)
(code untested, just from the top of my head).

Resources