开发者

Finding and returning the distance between two coordinates

I'm sort of a newbie--please don't hate.

The method compiles, but I'm not sure how to actually retrieve the float value (i.e. the distance between the two points) that the method returns (or should return rather).

-(float)findDistanceBetween:(Coordinate *)a and:(Coordinate *)b
{
//distance formula: 
//sqrt( (x2 - x1)^2 + (y2 - y1)^2 )

float resultDistance; 

resultDistance = sqrt( pow((b.latitude - a.latitude), 2) + pow((b.longitude - a.longitude), 2));

return resultDistance;  
}

//Somewhere else...

float theDistanceBetween; 

//Below is incorrect:

theDistanceBetween = [findD开发者_JAVA技巧istanceBetween: location1 and: location2]; 

Thanks


So, if your error is that self is undeclared, that means that you are trying to send -findDistanceBetween:and: from outside the context of the class that declares it.

When you do something like [obj method], that demands a few things:

  1. That obj is an instance of an Objective-C class.
  2. That the class of obj implements -method.

So, if the receiver of your message is self, that means that:

  1. You need to be within the context of a class's implementation for the self to be implicitly declared.

  2. The class you're in needs to be the same one as implements -findDistanceBetween:and:.

Methods are not just a shiny replacement for functions that can be called in any context. They can be called on objects that implement them (technically not "called" in Smalltalk-like languages such as Objective-C, but that's for another time).

I suspect that you have larger design issues as well. What kind of object is -findDistanceBetween:and: meant to be sent to? If it is a utility method in a class that does something bigger, then it should be a class method (+findDistanceBetween:and:), since it does not need to know about any specific instance. If, however, it is a method on Coordinate, then it'd be better expressed as -findDistanceTo:, which would take a coordinate parameter. And then the implementation of that would compare the provided coordinate parameter with self.


findDistanceBetween:and: is an instance method; it's something a particular instance of your class can do.

So you'd call it like:

theDistanceBetween = [self findDistanceBetween: location1 and: location2]; 

Which means "send the message 'findDistanceBetween: location1 and: location2' to the object 'self', and store the result to theDistanceBetween". self just means the current object; it's an object sending a message to itself.


Is findDistanceBetween:and: defined in an @implementation block? Your code should look something like

   // in the .h file

   @interface MyClass : NSObject

   // declaration of the method
   - (float)findDistanceInBetween:(Coordinate *)a and:(Coordinate *)b;
   @end

   // in the .m file

   @implementation MyClass

   // definition of the method
   - (float)findDistanceBetween:(Coordinate *)a and:(Coordinate *)b {
       return sqrt(powf(a.x - b.x, 2.f) + powf(a.y - b.y, 2.f));
   }
   @end

   // then somewhere else that needs to calculate the difference:
   // (assume coord_a and coord_b already exist)

   // create an instance of MyClass
   MyClass *myInstance = [[MyClass alloc] init];

   // send the `findDistanceBetween:and:` message to the instance
   float distance = [myInstance findDistanceBetween:coord_a and:coord_b];

   // when you're done with the instance, you need to clean up
   [myInstance release];

It may make more sense to put these types of methods on the Coordinate class itself so you can just do something like:

   Coordinate *coord_a = <get the coordinate from somewhere>;
   Coordinate *coord_b = <get the coordinate from somewhere>;

   float distance = [coord_a distanceFrom:coord_b];
   float angle = [coord_a angleTo:coord_b];

Don't worry about anyone hating, we were all new at this once. :)


Try to add -(float)findDistanceBetween:(Coordinate *)a and:(Coordinate *)b; to your .h file


As mentioned by Ferruccio above latitude and longitude are in degrees and you method should be returning some form of distance. Below are some methods that will calculate distance as well as bearing between 2 CLLocationCoordinate2Ds.

- (double)degreeToRadian:(double)degree{
return (degree * (M_PI/180.0));
}

- (double)radianToDegree:(double)radian{
return (radian *(180.0/M_PI));
}

-(double) distanceFromCordinate:(CLLocationCoordinate2D)fromCoord to:(CLLocationCoordinate2D)toCoord {
double radiusOfEarth = 6371.0;
double fromLongitude, fromLatitude, toLongitude, toLatitude;
double _deltaLongitude, _deltaLatitude;

double a, c;

fromLongitude = [self degreeToRadian:fromCoord.longitude];
fromLatitude = [self degreeToRadian:fromCoord.latitude];
toLongitude = [self degreeToRadian:toCoord.longitude];
toLatitude = [self degreeToRadian:toCoord.latitude];

_deltaLongitude = toLongitude - fromLongitude;
_deltaLatitude = toLatitude - fromLatitude;

a = (sin(_deltaLatitude/2) * sin(_deltaLatitude/2)) + ( cos(fromLatitude) * cos(toLatitude) * (sin(_deltaLongitude/2) * sin(_deltaLongitude/2)) );
c = 2 * atan2( sqrt(a), sqrt(1-a));
return (radiusOfEarth * c); 
}

- (double)bearingFromCordinate:(CLLocationCoordinate2D)fromCoord to:(CLLocationCoordinate2D)toCoord{
double fromLatitude, toLatitude;    

double _deltaLongitude;

double x, y;

double bearing;

fromLatitude = [self degreeToRadian:fromCoord.latitude];
toLatitude = [self degreeToRadian:toCoord.latitude];

deltaLongitude = [self degreeToRadian:(toCoord.longitude - fromCoord.longitude)];

y = sin(deltaLongitude) * cos(toLatitude);
x = (cos(fromLatitude) * sin(toLatitude)) - (sin(fromLatitude) * cos(toLatitude) * cos(deltaLongitude));
bearing = atan2(y,x);
return fmod(([self radianToDegree:bearing] + 360.0), 360.0) ;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜