How to create MKCoordinateRegion .
NSString *latitudeString = [locationString substringToIndex:startRange.location];
NSString *longtitudeString = [locationString substringWithRange:NSMakeRange(startRange.location+2,((endRange.location-1)-(startRange.location+2)))];
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake((int)latitudeString, (int)longtitudeString);
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coord, 500, 500);`
I get the error "Invalid Region center:+392128672.00000000, +392128704.00000000 span:+0.00448287, -0.01195557"
Remove the type casting. Use below code.
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake([latitudeString doubleValue], [longtitudeString doubleValue]);
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coord, 500, 500);
If you store your latitude and longitude in a string like this:
NSString *latitudeString = #"12.2323";
You should convert it to a float, like this:
CGFloat latitude = [latitudeString floatValue];
And after that, you can this in your
CLLocationCoordinate2DMake
method, it should work. And the problem comes from, that the latitude can only between -90 and 90, the longitude between -180 and 180 (degree), and your numbers are way bigger than that.
Related
I have to calculate the distance between two locations in iOS and objective c. My one location is fixed at a point and when I walk I have to calculate a distance between my current position and the fixed point. I have used distanceFromLocation method but I am not getting the closer distance value. I have gone through a few articles and a few StackOverflow solutions but none gave me proper result.
Below is the code I used and in the code currentLocation and destinationLocation are properties to hold latitude and longitude of the locations. The destinationLocation is always a fixed location and currentLocation keep on changing when I walk. There are few UILabels to print current and fixed latitude and longitude values. I have to calculate the distance every time between these two points. When I move half or less meter it shows me a large distance which is inconsistent as well. Could you please help me what mistake am I doing here? Is there any other way to achieve this? Thanks!
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
CLLocation *newLocation = locations.lastObject;
self.currentLocation = [[CLLocation alloc] initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.longitude];
if(self.destinationLocation == nil){
self.destinationLocation = [[CLLocation alloc] initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.longitude];
self.destinationLatitude.text = [NSString stringWithFormat:#"%.8f", self.destinationLocation.coordinate.latitude];
self.destinationLongitude.text = [NSString stringWithFormat:#"%.8f", self.destinationLocation.coordinate.longitude];
}
self.currentLatitude.text = [NSString stringWithFormat:#"%.8f", self.currentLocation.coordinate.latitude];
self.currentLongitude.text = [NSString stringWithFormat:#"%.8f", self.currentLocation.coordinate.longitude];
CLLocationDistance distance = [self.currentLocation distanceFromLocation:self.destinationLocation];
self.gpsDistanceMeasurement.text = [NSString stringWithFormat:#"%.2f m", distance];
}
you can use haversine formula to calculate the distance between two points
swift 3.x
let Source = CLLocationCoordinate2D.init(latitude: lat, longitude: long)
let Destination = CLLocationCoordinate2D.init(latitude: lat, longitude: long)
func DistanceCalculator(Source:CLLocationCoordinate2D,Destination:CLLocationCoordinate2D) -> Double
{
// HaverSine Formula to calculate Diastance On Sphere Refrences//https://www.movable-type.co.uk/scripts/latlong.html
// Angle = sin2(∆Ø/2) + cosØ1 * cosØ2 * sin2(∆ø/2)
// constant = 2 * atan2(√angle,√1-angle)
// distance = R * c
let Earth_Radius:Double = 6371 * 1000
let LatDelta = self.DegreeToRad(Degree: (Destination.latitude - Source.latitude))
let LongDelta = self.DegreeToRad(Degree: (Destination.longitude - Source.longitude))
let latRad = self.DegreeToRad(Degree: Source.latitude)
let longRad = self.DegreeToRad(Degree: Destination.latitude)
let Angle = (sin(LatDelta/2) * sin(LatDelta/2)) + (cos(latRad) * cos(longRad) * sin(LongDelta/2) * sin(LongDelta/2))
let constant = 2 * atan2(sqrt(Angle),sqrt(1-Angle))
let Distance = Earth_Radius * constant
return Distance
}
func DegreeToRad(Degree:Double) -> Double
{
return Degree * (Double.pi / 180)
}
I am trying to search in a text file (available on a url) , there is latitude, longitude and other information separated by commas.
I need to search lat lon which is nearest to user's selected lat lon in app.
Code is done to read that file and search but it do not work perfectly.
Please let me know , how should I approach in this type of situation.
1)File get updated in real time , so I need to call url and read file every time user select location and click to get information.
2)And then search for nearest lat lon to the user's selected lat lon.
NSDICTIONARY DATA GETTING :-
(
{
"altitude_m" = "90.0";
engName = “Station 1”;
grkName = "\U039d\U03ad\U03b1 \U039c\U03ac\U03ba\U03c1\U03b7 \U0391\U03c4\U03c4\U03b9\U03ba\U03ae\U03c2";
"humidity_P" = "50.0";
lat = "38.058873";
"local_time" = "16:20";
lon = "23.976741";
"pressure_hPA" = "1019.9";
"rain_mm" = "0.0";
"tem_C" = "17.2";
"wind_Gusts_khm" = "51.5";
"wind_degrees" = "22.5";
"wind_kmh" = "25.7";
}
{
"altitude_m" = "90.0";
engName = “Station 2”;
grkName = "\U039d\U03ad\U03b1 \U039c\U03ac\U03ba\U03c1\U03b7 \U0391\U03c4\U03c4\U03b9\U03ba\U03ae\U03c2";
"humidity_P" = "50.0";
lat = "38.048873";
"local_time" = "16:20";
lon = "23.876741";
"pressure_hPA" = "1019.9";
"rain_mm" = "0.0";
"tem_C" = "17.2";
"wind_Gusts_khm" = "51.5";
"wind_degrees" = "22.5";
"wind_kmh" = "25.7";
}
{
"altitude_m" = "90.0";
engName = “Station 3”;
grkName = "\U039d\U03ad\U03b1 \U039c\U03ac\U03ba\U03c1\U03b7 \U0391\U03c4\U03c4\U03b9\U03ba\U03ae\U03c2";
"humidity_P" = "50.0";
lat = "38.059873";
"local_time" = "16:20";
lon = "23.986741";
"pressure_hPA" = "1019.9";
"rain_mm" = "0.0";
"tem_C" = "17.2";
"wind_Gusts_khm" = "51.5";
"wind_degrees" = "22.5";
"wind_kmh" = "25.7";
}
// MATCHING FUNCTION :-
-(void)matchLAtLongNow: (NSString *)latitude :(NSString *)longitude {
CLLocationCoordinate2D pinlocation;
pinlocation.latitude = [latitude doubleValue];
pinlocation.longitude = [longitude doubleValue];
float minLat = pinlocation.latitude - (searchDistance / 69);
float maxLat = pinlocation.latitude + (searchDistance / 69);
float minLon = pinlocation.longitude - searchDistance / fabs(cos(deg2rad(pinlocation.latitude))*69);
float maxLon = pinlocation.longitude + searchDistance / fabs(cos(deg2rad(pinlocation.longitude))*69);
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"lat <= %f AND lat >= %f AND lon <= %f AND lon >= %f",
maxLat, minLat, maxLon, minLon];
MatchedTxtArray = [myArray filteredArrayUsingPredicate:applePred];
}
//GETTING ERROR
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber _fastCStringContents]: unrecognized selector sent to instance 0x175426460'
* First throw call stack:
NSDictionaries return NSNumbers. Check where you call matchAtLongNow: You probably have NSNumbers where you're expecting strings.
It sounds like you need a geo search, as opposed inclusion within some thresholds. I'd reformulate to something like this:
NSArray *objects; // this is your parsed file, an array of dictionaries
CLLocation *userLocation; // this is your user location
// sort the dictionary in order of distance to the userLocation
NSArray *sortedObjects = [objects sortedArrayUsingComparator:^(NSDictionary *objA,NSDictionary *objB) {
CLLocationDistance distanceA = [self distanceToObject:objA from:userLocation];
CLLocationDistance distanceB = [self distanceToObject:objB from:userLocation];
return (NSComparisonResult)(distanceB-distanceA);
}];
sortedObjects will contain the dictionaries sorted from nearest to farthest from the userLocation We just need a function that produces the distance from the lat/lon values in the dictionary to the userLocation...
- (CLLocationDistance)distanceToObject:(NSDictionary *)object from:(CLLocation *)location {
CLLocationDegrees latitude = [object[#"lat"] doubleValue];
CLLocationDegrees longitude = [object[#"lob"] doubleValue];
CLLocation *objectLocation = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
return [objectLocation distanceFromLocation:location];
}
i am working on a project in which i have to show the distance of multiple locations from user's locations. locations are based on latitude and longitude.
i am using the following code to get the distance between two locations is shows nearly same distance
CLLocation *locA = [[CLLocation alloc] initWithLatitude:28.6379 longitude: 77.2432];
CLLocation *locB = [[CLLocation alloc] initWithLatitude:28.6562 longitude:77.2410];
CLLocationDistance distance = [locA distanceFromLocation:locB];
NSLog(#"Distance is %f",distance);
float i = distance/1000;
NSLog(#"distance between two places is %f KM", i);
but now i am struct to get the distance of multiple locations from my location: locaA.
for example i take NSarray for latitude and longitude as
NSArray * latArray = [[NSArray alloc]initWithObjects:#"28.6129",#"28.6020",#"28.5244", nil];
NSArray * longArray = [[NSArray alloc]initWithObjects:#"77.2295",#"77.2478",#"77.1855", nil];
Please help me to resolve it
Take locaA as user's location
You can use below method to find distance
#define DEG2RAD(degrees) (degrees * 0.01745327)
double currentLatitudeRad = DEG2RAD(currentLatitude);
double currentLongitudeRad = DEG2RAD(currentLongitude);
double destinationLatitudeRad = DEG2RAD(destinationLatitude);
double destinationLongitudeRad = DEG2RAD(destinationLongitude);
double distance = acos(sin(currentLatitudeRad) * sin(destinationLatitudeRad) + cos(currentLatitudeRad) * cos(destinationLatitudeRad) * cos(currentLongitudeRad - destinationLongitudeRad)) * 6880.1295896;
Here, currentLatitude and currentLongitude is user's location. destinationLatitude and destinationLongitude is each object from your array "latArray" and "longArray" which you can iterate via for loop. distance is the distance between user's location and locations in array. Obtained distance will be in kilometres.
CLLocation *currentLocation = ... // This is a reference to your current location as a CLLocation
NSArray *arrayOfOtherCLLocationObjects = ... // This is an array that contains all of the other points you want to calculate the distance to as CLLocations
NSMutableArray *distancesFromCurrentLocation = [[NSMutableArray alloc] initWithCapacity:arrayOfOtherCLLocationObjects.count]; // We will add all of the calculated distances to this array
for (CLLocation *location in arrayOfOtherCLLocationObjects) // Iterate through each location object
{
CLLocationDistance distance = [location distanceFromLocation:currentLocation]; // Calculate distance
[distancesFromCurrentLocation addObject:#(distance)]; // Append distance to array. You need to wrap the distance object as an NSNumber so you can append it to the array.
}
// At this point, you have the distance for each location point in the array distancesFromCurrentLocation
Swift version:
let currentLocation: CLLocation = //current location
let otherLocations: [CLLocation] = //the locations you want to know their distance to currentLocation
let distances = otherLocations.map { $0.distanceFromLocation(currentLocation) }
I want to display the visible markers only in the visible region of the screen, but I get only -180 values. Same result on simulator and iPad device.
Code:
GMSVisibleRegion visibleRegion = [mapView.projection visibleRegion];
GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc]initWithRegion:visibleRegion];
[mapView animateWithCameraUpdate:[GMSCameraUpdate fitBounds:bounds]];
CLLocationCoordinate2D northEast = bounds.northEast;
CLLocationCoordinate2D northWest = CLLocationCoordinate2DMake(bounds.northEast.latitude, bounds.southWest.longitude);
CLLocationCoordinate2D southEast = CLLocationCoordinate2DMake(bounds.southWest.latitude, bounds.northEast.longitude);
CLLocationCoordinate2D southWest = bounds.southWest;
NSLog(#"NORTH-EST: %.5f",northEast.latitude);
NSLog(#"NORTH-EST: %.5f",northEast.longitude);
NSLog(#"NORTH-WEST: %.5f",northWest.latitude);
NSLog(#"NORTH-WEST: %.5f",northWest.longitude);
NSLog(#"South-EST: %.5f",southEast.longitude);
NSLog(#"South-EST: %.5f",southEast.latitude);
NSLog(#"SOUTH-WEST: %.5f",southWest.latitude);
NSLog(#"SOUTH-WEST: %.5f",southWest.longitude);
Log:
Printing description of visibleRegion:
(GMSVisibleRegion) visibleRegion = {
nearLeft = (latitude = -180, longitude = -180)
nearRight = (latitude = -180, longitude = -180)
farLeft = (latitude = -180, longitude = -180)
farRight = (latitude = -180, longitude = -180)
}
Found the solution for this problem:
Source code:
GMSVisibleRegion visibleRegion = [mapView.projection visibleRegion];
GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc]initWithRegion:visibleRegion];
CLLocationCoordinate2D northEast = bounds.northEast;
CLLocationCoordinate2D southWest = bounds.southWest;
The visibleRegion only works on a real device IOS Device NOT on the simulator.
I have an array full of longitudes and latitudes. I have two double variables with my users location. I'd like to test the distance between my user's locations against my array to see which location is the closest. How do I do this?
This will get the distance between 2 location but stuggeling to understand
how I'd test it against an array of locations.
CLLocation *startLocation = [[CLLocation alloc] initWithLatitude:userlatitude longitude:userlongitude];
CLLocation *endLocation = [[CLLocation alloc] initWithLatitude:annotation.coordinate.latitude longitude:annotation.coordinate.longitude];
CLLocationDistance distance = [startLocation distanceFromLocation:endLocation];
You just need to iterate through the array checking the distances.
NSArray *locations = //your array of CLLocation objects
CLLocation *currentLocation = //current device Location
CLLocation *closestLocation;
CLLocationDistance smallestDistance = DOUBLE_MAX;
for (CLLocation *location in locations) {
CLLocationDistance distance = [currentLocation distanceFromLocation:location];
if (distance < smallestDistance) {
smallestDistance = distance;
closestLocation = location;
}
}
At the end of the loop you will have the smallest distance and the closest location.
#Fogmeister
I think this is a mistake which must be set right about DBL_MAX and an assignment.
First : Use DBL_MAX instead of DOUBLE_MAX.
DBL_MAX is a #define variable in math.h.
It's the value of maximum representable finite floating-point (double) number.
Second : In your condition, your assignment is wrong :
if (distance < smallestDistance) {
distance = smallestDistance;
closestLocation = location;
}
You must do :
if (distance < smallestDistance) {
smallestDistance = distance;
closestLocation = location;
}
The difference is that will be assign distance value into smallestDistance, and not the opposite.
The final result :
NSArray *locations = //your array of CLLocation objects
CLLocation *currentLocation = //current device Location
CLLocation *closestLocation;
CLLocationDistance smallestDistance = DBL_MAX; // set the max value
for (CLLocation *location in locations) {
CLLocationDistance distance = [currentLocation distanceFromLocation:location];
if (distance < smallestDistance) {
smallestDistance = distance;
closestLocation = location;
}
}
NSLog(#"smallestDistance = %f", smallestDistance);
Can you confirm that is correct ?