Center coordinate with radius convert to ne and sw coordinates - ios

I have CLLocationCoordinate2D and some radius in meters.
I would like to get two bounding coordinates (top-right and bottom-left) of the area.

If I understand you correctly you want to location these 2 red squares:
Thanks to the code you that can find here the implementation is pretty simple:
CLLocationCoordinate2D cc0 = coordinate;
CLLocationCoordinate2D cc1 = [self coordinateFromCoord:cc0 atDistanceKm:circleRadius atBearingDegrees:45];
CLLocationCoordinate2D cc2 = [self coordinateFromCoord:cc0 atDistanceKm:circleRadius atBearingDegrees:225];
NSLog(#"%.5f,%.5f -> %.5f,%.5f AND %.5f, %.5f", cc0.latitude, cc0.longitude, cc1.latitude, cc1.longitude, cc2.latitude, cc2.longitude);

Related

How To Set a Restricted Region or Limited Region in Google Map,Swift

I have list of markers on my Googlemap,fixed all the markers.Now I need to get Limited Region only possible to scroll inside the limited Region.How its possible.anyone Please help me to fix it.
Here is My Center Location
let center = CLLocationCoordinate2DMake(11.250220, 75.781573)
let camera: GMSCameraPosition = GMSCameraPosition.camera(withLatitude: center.latitude, longitude: center.longitude, zoom: 18.0)
Start by defining two locations which specify the bounds of the region you want to display. These could be opposite corners of the bounding box, or just two locations, for example:
CLLocationCoordinate2D location1 =
CLLocationCoordinate2DMake(-33.8683, 151.2086); // Sydney
CLLocationCoordinate2D location2 =
CLLocationCoordinate2DMake(-31.9554, 115.8585); // Perth
If you have more than two points that you want to include, you could calculate the bounds of them yourself. This can also be done using GMSCoordinateBounds, for example:
GMSCoordinateBounds* bounds =
[[GMSCoordinateBounds alloc]
initWithCoordinate: CLLocationCoordinate2DMake(-33.8683, 151.2086) // Sydney
andCoordinate: CLLocationCoordinate2DMake(-31.9554, 115.8585)]; // Perth
bounds = [bounds including:
CLLocationCoordinate2DMake(-12.4667, 130.8333)]; // Darwin
CLLocationCoordinate2D location1 = bounds.southWest;
CLLocationCoordinate2D location2 = bounds.northEast;
Next, you need to get the size of the map view in points. You could use this:
float mapViewWidth = _mapView.frame.size.width;
float mapViewHeight = _mapView.frame.size.height;
Now you have the info necessary to calculate the camera position:
MKMapPoint point1 = MKMapPointForCoordinate(location1);
MKMapPoint point2 = MKMapPointForCoordinate(location2);
MKMapPoint centrePoint = MKMapPointMake(
(point1.x + point2.x) / 2,
(point1.y + point2.y) / 2);
CLLocationCoordinate2D centreLocation = MKCoordinateForMapPoint(centrePoint);
double mapScaleWidth = mapViewWidth / fabs(point2.x - point1.x);
double mapScaleHeight = mapViewHeight / fabs(point2.y - point1.y);
double mapScale = MIN(mapScaleWidth, mapScaleHeight);
double zoomLevel = 20 + log2(mapScale);
GMSCameraPosition *camera = [GMSCameraPosition
cameraWithLatitude: centreLocation.latitude
longitude: centreLocation.longitude
zoom: zoomLevel];
You can then initialize the map view with this camera, or set the map view to this camera.
For this code to compile, you will need to add the MapKit framework to your project, and then also import it:
#import <MapKit/MapKit.h>
Note that this code doesn't handle wrap-around if your coordinates span across the date line. For example if you tried using this code with Tokyo and Hawaii, instead of displaying an area of the Pacific, it will try to display almost the entire world. In portrait mode it's not possible to zoom out far enough to see Hawaii on the left and Tokyo on the right, and so the map ends up centred on Africa with neither location visible. You could modify the above code to handle the wrap-around at the date line if you wanted to.

Calculate distance between latitude and longitude using MapKit

Am trying to calculate distance from one point to another. I am able to find method for that.
CLLocationDistance dist = [loc distanceFromLocation:loc2];
But what it does is calculate distance in a straight line.
What I want is to calculate distance by roadways.
For Example: Lets say If i give from address as Home and To address as Work. I want the distance between Home to Work by roadways. By roadways I get 750meters. But if i calculate by the method distanceFromLocation I get only 400meters.
Can someone help me with an example to calculate distance.
Check out this answer :
CLLocationCoordinate2D pointACoordinate = [pointAAnnotation coordinate];
CLLocation *pointALocation = [[CLLocation alloc] initWithLatitude:pointACoordinate.latitude longitude:pointACoordinate.longitude];
CLLocationCoordinate2D pointBCoordinate = [pointBAnnotation coordinate];
CLLocation *pointBLocation = [[CLLocation alloc] initWithLatitude:pointBCoordinate.latitude longitude:pointBCoordinate.longitude];
float distanceMeters = [pointALocation distanceFromLocation:pointBLocation];
float distanceMiles = (distanceMeters / 1609.344);
Here pointAAnnotation & pointBAnnotation are the two Annotations which you need to calculate distance between them.
Ref : Distance bw two Latitude & Longitude

MapBox RMMapView pixel to coordinates reports wrong lat/lng

Below is the code snippet I use to convert pixel to coordinates and vice versa.
CLLocationCoordinate2D currentLocation = CLLocationCoordinate2DMake(geoPoint.latitude, geoPoint.longitude);
[mapView setCenterCoordinate:currentLocation];
CGPoint centerScreenPoint = [mapView coordinateToPixel:mapView.centerCoordinate];
CLLocationCoordinate2D loc = [mapView pixelToCoordinate:centerScreenPoint];
geoPoint on the first line is the current location reported by CLLocationManager. Although centerScreenPoint gives me 160, 284 which is the center point on iPhone 5, after running this code and dumping the values of currentLocation and loc I get two different coordinates.
How do these points come out different, any ideas?

Display the map scale in mapkit

I am working with mapkit in Xcode 5.1 and am trying to display the map scale in regionDidChangeAnimated. I have no idea now to accomplish this though. I tried to look around and was unsuccessful. Any ideas?
EDIT:
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
CGPoint nePoint = CGPointMake(self.mapView.bounds.origin.x + mapView.bounds.size.width, mapView.bounds.origin.y);
CGPoint swPoint = CGPointMake((self.mapView.bounds.origin.x), (mapView.bounds.origin.y + mapView.bounds.size.height));
CLLocationCoordinate2D neCoord;
neCoord = [self.mapView convertPoint:nePoint toCoordinateFromView:self.mapView];
CLLocationCoordinate2D swCoord;
swCoord = [self.mapView convertPoint:swPoint toCoordinateFromView:self.mapView];
CLLocationDistance distance = [neCoord distanceFromLocation:swCoord];
}
Any reason why I am getting an error with the last line, CLLocationDistance?
Use the methods that translate between the coordinates on the map and the points on the map view, such as convertPoint:toCoordinateFromView:. Use the edge points of your view for this.
Now you have the coordinates - you can calculate the distances between the points with CLLocation's distanceFromLocation:. You can make some assumptions about the width of your view based on the physical properties of, day an iPhone or iPad and calculate the scale.

How to fit a certain bounds consisting of NE and SW coordinates into the visible map view?

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 {
// ????
// }
}

Resources