Mapkit coordinates of point on a line - objective-c

I have a CLLocationCoordinate2D (c1) and a CLLocation (l1), so I have lat/long values for each point and I can calculate the distance in meters between them using:
[c1 distanceFromLocation:l1]
How can I find the coordinates of a point (c2) 100 meters closer to l1 than c1 (along the same bearing)?
I have calculated it using basic trig using the following:
used the difference in latitude and longitude to calculate the hypotenuse and angle
used the ratio between the distance to cl and the distance to c2 to get the hypotenuse of a triangle ending at c2
used cos and sin to calculate the longitude and latitude of c2
But this seems like a hacky way of doing it as it doesn't take into account of curvature and seems to be using latitude and longitude in a way they are not supposed to be used. It does seem to work over short distances though.

After a bit of research, I found a basic formula for calculating curved distance between two points on the earth's surface:
dlon = lon2 - lon1
dlat = lat2 - lat1
a = { sin(dlat/2) }^2 + [ cos(lat1) * cos(lat2) * { sin(dlon/2) }^2 ]
c = 2 * arcsin(min(1,sqrt(a)))
d = R * c

Although Rickay's answer was helpful, I eventually used the following excellent library which has many useful functions for Core Location calculations: https://github.com/100grams/CoreLocationUtils

Related

Compute the length difference out of a longitude latitude double

Given two gps coordinates the length difference can be calculated by using the haversine formula. But what about the other way around:
Compute the length difference in meter for a given Lat/Long double
Compute the Lat/Long double for a given length in meters
I know this is not exactly possible since it differs from the point on the earth you are, but is it possible to approximate this or something similiar? This does not have to be very precise.
If your displacements aren't too great (less than a few KM), use the quick and dirty estimate that 111,111 meters in the y direction is 1 degree (of latitude) and 111,111 * cos(latitude) meters in the x direction is 1 degree (of longitude).
Alternatively:
//Position, decimal degrees
lat = 51.0
lon = 0.0
//Earth’s radius, sphere
R=6378137
//offsets in meters
distanceNorth = 100
distanceEast = 100
//Coordinate offsets in radians
dLat = distanceNorth/R
dLon = distanceEast/(R*Cos(Pi*lat/180))
//OffsetPosition, decimal degrees
latO = lat + dLat * 180/Pi
lonO = lon + dLon * 180/Pi
This should return:
latO = 51,00089832
lonO = 0,001427437

How can I create SQL Server Geography polygons that are of a specific size?

I want to create a group of polygons for a city that are 80km x 80km. Given a starting Lat and Long, my thought is I can add 80km to that point so that I get 4 points to create the polygon.
(x,y) -> (x+80km, y) -> (x+80km, y+80km) -> (x, y+80km) -> (x,y)
Where I'm having difficulty is finding a way to calculate the point +80km. I've found the SQL Server Spatial Tools and there is a function
SqlGeography LocateAlongGeog(SqlGeography g, double distance)
But so far I haven't been able to figure out how to use it. I will continue to play with this but if there are any other approaches I can take, or if anyone knows how to properly use this function, I'd be grateful.
Longitude is a "great circle" measure, i.e. if you draw a circle representing a particular longitude round the Earth, it's always a circle whose centre is the centre of the Earth - so to circumnavigate the Earth at a constant longitude, you always travel the same distance:
2 * PI * 6378 /* 6378 is the radius of the Earth in km */
So, moving North (i.e travelling along the same longitude) 80 km will increase your latitude by:
360 * 80 / (2 * PI * 6378)
Latitude is trickier cos the distance travelled when you circumnavigate the Earth at the same latitude changes depending on the latitude at which you're travelling: however, the formula is simple and I looked it up at: http://www.newton.dep.anl.gov/askasci/env99/env086.htm
2 * PI * 6378 * COS(LAT) /* where LAT is your Latitude */
So, if you are at latitude LAT, and move 80km East, you will increase your longitude by:
360 * 80 / (2 * PI * 6378 * COS(LAT))
Couple of things to note:
a) 6378 is only accurate to the nearest km
b) The East/West between your two Northerly points will not be precisely 80km - not significantly different for Latitudes between about 80 degrees North and 80 degrees South - as long as you're not looking for high-precision pinpoint accuracy (which I'm guessing with base measurements of 80 km you're not) it'll do just nicely (and point nicelt at Bing or Google, say)
c) SQL calculates trigonometry functions using radians not degrees - so in SQL your cosine will need to be:
COS(PI * LAT / 180)
HTH and makes some sort of sense

How to calculate a longitude and latitude at a given distance along a great circle?

I want to overlay great circle arcs between airports on a map using longitudes and latitudes.
I can already get the distance and bearing from the initial and final coordinates but now I need to produce the points on the curve to plot through.
What I would like is a formula which takes the origin, destination, and a distance, and returns the latitude/longitude of the point that lies at that distance on the path between the origin and the destination.
I'm currently approximating the earth by a sphere and using radians -- eventually I'll add in spheroid corrections.
currlat = oldlat + d * sin (angle)/ (radius);
currlon = oldlon + d * cos (angle)/ (radius * cos(oldlat));
where d is distance travelled and angle is in radians. This is assuming circumference of earth at 40000km both at equator and through the poles. You can convert in radians...
Also it assumes the angle (direction) is with reference to equator line.
Obviously this needs spheroid corrections.
if you go south sin values will turn negative and north it will go positive. If you go west cos will turn negative and east it will turn positive.
d * sin(angle) and d * cos(angle) gives you the change. and you just calculate the new lat/long on that basis scaling up against circumference of earth.

How to find latitude and longitude

I have latitude and longitude of a point.I have to find out the latitude and longitude of another point from a relative distance from the known point.For example point A has some location with latitude and longitude.What is the latitude and longitude after moving 1000m south and 500m west from point A.Is there any direct equation to find this? Thanks in advance
Note the accepted answer is basically the flat earth projection equations:
x = δlon * EarthRadius * cos( lat )
y = δlat * EarthRadius
For better accuracy over larger distances, you should compute the final lat/lon from a typical bearing/range calculation. See the section Destination point given distance and bearing from start point at this website: http://www.movable-type.co.uk/scripts/latlong.html
Instead of looking up an equation you can calculate as follows. Let R be the radius of the Earth. Let a be the current latitude and b be the current longitude. Then if you move δx metres east (negative for west) then δy metres south, calculating the new longitude can be done as follows.
Intersecting a horizontal plane with the Earth at the current latitude will give you a circle of radius R*cos(a). So to convert δx to the change in longitude, you get something like
δlong = δx * 2π / (2π * R * cos(a)) = δx / (R * cos (a))
The change in latitude is easier, since it doesn't depend on the current position. You're always moving around a great circle through the two poles. Then δlat = δy / R. (Of course you need to mod out by 2 π at some point).

transform k m into gps Coordinates

I have to see if some GPS coordinates are in a circle that I create.when I say I am creating that circle I' refering to this: I have lat1, long1,
my actual location and I want to test if there is any data surrounding this location but
not far then 1km. I am trying to use circle inequation : (x2-a2)2+(y2-b2)2 <R2 where a=lat1, b=long1 and R=radius. I know that R=1km but how do I transform 1km into data that can be compared to GPS coordinates? and x, y are every value from a collection that are testet to see if they fit.
Lat/Lng coordinates don't work with the Phytagoras Formula, as Earth is a sphere, and not flat...
Take a look at this manual:
http://www.movable-type.co.uk/scripts/latlong.html
You need the distance equation, to see if the distance between the lat/lng you have and the lat/lng of the center of the circle is smaller than R.
It's not that simple. You can't generally use the euclidean distance. This is how i think you could do it:
The correct way
The correct way to do this would be to calculate the great circle distance (the shortest walking distance on the surface), which I never really understood, but it's pretty easy to google (and adamk already gave you a link to it).
The lazy way
Assume that your points are not too close to the poles and that they are close to each other. Then you can use the latitude and longitude as if they were euclidean coordinates. (this is basically some cylindrical projection). 1 degree of latitude will then be (earth_circumference / 360) long and 1 degree of longitude will be (cos(lat) * earth_circumference / 360) long.
the complete code would look something like this:
double distance_lazy(double lat1, double lon1, double lat2, double lon2){
double xDist = (lat2 - lat1) * EARTH_CIRCUMFERENCE / 360.0;
double yDist = cos(lat1) * (lon2 - lon1) * EARTH_CIRCUMFERENCE / 360.0;
return sqrt(xDist^2 + yDist^2);
}
If your distances will be only a few km from each other, this should work pretty ok for the whole europe ... something like that.
The "weird definition" way
Another thing you can say is, that "distance" is the length straight line between the points, even though it goes through the earth. Then this would become calculating the 3D coordinates of a point and then their euclidean distance
double distance_straight_line(double lat1, double lon1, double lat2, double lon2){
double x1 = cos(lat1) * cos(lon1) * EARTH_RADIUS;
double y1 = sin(lat1) * cos(lon1) * EARTH_RADIUS;
double z1 = sin(lon1) * EARTH_RADIUS;
double x2 = cos(lat2) * cos(lon2) * EARTH_RADIUS;
double y2 = sin(lat2) * cos(lon2) * EARTH_RADIUS;
double z2 = sin(lon2) * EARTH_RADIUS;
return sqrt((x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2);
}
Again this will work as expected for points close to each other, this time they can be anywhere in the world. If you give it points far from each other, the output will be correct, but prety useless (unless you are very good at digging).
Hope it helps.