Calculate location by distance from other location - ios

I know there are tons of questions (and answers) on how to get the distance between two CLLocations. But I didn't find one single hint on how to do this the other way round.
Here's the concrete situation: I have one CLLocation, one distance (let's say 200 meters) and one direction. Now I need to know how to calculate the location that is 200 meters away (in a specified direction) from the first location. I don't know what could be the best format for the direction. Maybe the best would be in degrees (north = 0, east = 90, south = 180, west = 270).
In a nutshell, I need a method that could be defined like
-(CLLocation*)locationWithDistance:(int)meters inDirection:(int)degrees fromLocation:(CLLocation*)origin;
Thanks a lot for your help.

For more accurate method use this formula in the link
http://www.movable-type.co.uk/scripts/latlong.html
Please find the section "Destination point given distance and bearing from start point". Apply it in your code

There is C code already written to do exactly that. It is posted on github here. There is a degrees and radians version of the function in UtilitiesGeo.c/.h files. It could have been written with an Objective-C style but I wanted it to be portable to any C based project.
/*-------------------------------------------------------------------------
* Given a starting lat/lon point on earth, distance (in meters)
* and bearing, calculates destination coordinates lat2/lon2.
*
* all params in degrees
*-------------------------------------------------------------------------*/
void destCoordsInDegrees(double lat1, double lon1,
double distanceMeters, double bearing,
double* lat2, double* lon2);

Related

How do I determine if a lat/lon pair falls within the radius of another lat/lon pair?

Here's an example of what I want to figure out:
Device A is at 40.7128 / -74.0060 (lat/lon)
Location B is at 40.730610 / -73.935242
Radius = 10 miles
And the question:
Is Device A within the radius around Location B?
I don't care about the language or technology, just want to get the job done. I know some Python, JS, and Java.
Anyone know a good/efficient way to approach this?
I would calculate the distance between the two points and check if it's inferior to the radius.
This thread gives some ideas on how to implement it in python: Getting distance between two points based on latitude/longitude

Anonymising/aggregating lat/long coordinates

I'm looking to display coordinates on a map. The coordinates are at a relatively fine resolution (3 decimal places), but I need to anonymise and aggregate them to a coarser resolution.
All the approaches I've seen run the risk of the coarse coordinates being the same as, or very close to, the original coordinates, since they rely on rounding or adding random noise to the original.
For example, with rounding:
53.401, -2.899 -> 53.4, -2.9 # less than 100m
With adding 'noise', e.g.:
lat = 53.456
// 'fuzz' in range -0.1 to 0.1
rnd = (Math.random() * 2 - 1) * 0.1
newLat = lat + (Math.random() * 2 - 1) * 0.1
However if rnd is close to 0, then the coordinates don't 'move' much.
Is there a (simple) way to 'move' a coordinate in a random way a certain (minimum) distance from it's original location?
I've looked at other answers here but they don't seem to solve this issue of the new coordinates overlapping with the original coordinates:
Rounding Lat and Long to Show Approximate Location in Google Maps
Is there any easy way to make GPS coordinates coarse?
To add random noise, you could displace every point by a fixed distance in a random direction. On a flat projection, for a radius r:
angle = Math.random() * 2 * PI
newLat = lat + (r * sin(angle))
newLon = lon + (r * cos(angle))
That would guarantee a fixed displacement (r) for every point, in an unpredictable direction.
Alternatively, you could anonymise by joining to a polygon at a coarser grain, and then plot the data by the polygon rather than the points. It could be as simple as a grid on a flat projection. Or something more sophisticated such as the Australian Statistical Geography Standard which offers multiple choices, the most granular being a "mesh block" which they guarantee to always contain 30-60 dwellings.
All the approaches I've seen run the risk of the coarse coordinates
being the same as, or very close to, the original coordinates, since
they rely on rounding or adding random noise to the original.
Could you explain, what's the risk that you are concerned about here? Yes, the coarse coordinate might happen to be the same, but it is still anonymized - whoever sees the coarse data would not know if it is coincidentally close or not. All they know is that the actual location is within some distance R_max from the coarse location.
Re the other solution,
displace every point by a fixed distance in a random direction
I would say it is much worse: here it would be easy to discover the fixed displacement distance by knowing just a single original location. Then, for any "coarse" location, we would know the original is on thin unfilled circle centered on the "coarse" location - much worse than the filled circle or rectangle in the original solution.
At the very least, I would use random radius, maybe don't allow it to be zero, if you are concerned about coincidental collision (but you should not be). E.g. this varies the radius from r_max / 2 to r_max:
r = (Math.random() + 1) * r_max / 2;
and then you can use this random radius with Schepo's solution.

Determining highway direction in here maps

Does Here map iOS sdk provides Highway direction?
Example: While driving on US Highways/Interstate, Here map is providing information like I-5 or WA-14.
Can we get which highway/interstate direction we are heading into. Like I-5 N or WA-14 S.
You can allways use course infromation taken from currentPosition(NMAGeoPositon object) of the NMAPositionManager.
Swift
NMAPositionManager.sharedInstance().currentPosition?.course
or Objective-C
[NMAPositionManager sharedPositioningManager].currentPosition.course
Valid course values are in the range [0, 360), with 0 degrees representing north and values increasing clockwise. Thus, east is 90 degrees, south is 180 degrees, and so on. Will be NMAGeoPositionUnknownValue if unknown.
Also it can be obtained from waypoint course.
calculatedRoute.waypoints[idx].course;
or aliases 'start', 'destination' can be used
calculatedRoute.start.course;
calculatedRoute.destination.course;
Another one is to use mapOrientation of maneuver
calculatedRoute.maneuvers[idx].mapOrientation
The angle (from north) at the start of the maneuver, in degrees. Zero represents true-north, with increasing values representing a clockwise progression of map orientation.

How to generate random LAT & LNG inside an area, given the center and the radius

In my project my users can choose to be put in a random position inside a given, circular area.
I have the latitude and longitude of the center and the radius: how can I calculate the latitude and longitude of a random point inside the given area?
(I use PHP but examples in any language will fit anyway)
You need two randomly generated numbers.
Thinking about this using rectangular (Cartesian) (x,y) coordinates is somewhat unnatural for the problem space. Given a radius, it's somewhat difficult to think about how to directly compute an (Δx,Δy) delta that falls within the circle defined by the center and radius.
Better to use polar coordinates to analyze the problem - in which the dimensions are (r1, Θ). Compute one random distance, bounded by the radius. Compute a random angle, from 0 to 360 degrees. Then convert the (r,Θ) to Cartesian (Δx,Δy), where the Cartesian quantities are simply offsets from your circle center, using the simple trigonometry relations.
Δx = r * cos(Θ)
Δy = r * sin(Θ)
Then your new point is simply
xnew = x + Δx
ynew = y + Δy
This works for small r, in which case the geometry of the earth can be approximated by Euclidean (flat plane) geometry.
As r becomes larger, the curvature of the earth means that the Euclidean approximation does not match the reality of the situation. In that case you will need to use the formulas for geodesic distance, which take into account the 3d curvature of the earth. This begins to make sense, let's say, above distances of 100 km. Of course it depends on the degree of accuracy you need, but I'm assuming you have quite a bit of wiggle room.
In 3d-geometry, you once again need to compute 2 quantities - the angle and the distance. The distance is again bound by your r radius, except in this case the distance is measured on the surface of the earth, and is known as a "great circle distance". Randomly generate a number less than or equal to your r, for the first quantity.
The great-circle geometry relation
d = R Δσ
...states that d, a great-circle distance, is proportional to the radius of the sphere and the central angle subtended by two points on the surface of the sphere. "central angle" refers to an angle described by three points, with the center of the sphere at the vertex, and the other two points on the surface of the sphere.
In your problem, this d must be a random quantity bound by your original 'r'. Calculating a d then gives you the central angle, in other words Δσ , since the R for the earth is known (about 6371.01 km).
That gives you the absolute (random) distance along the great circle, away from your original lat/long. Now you need the direction, quantified by an angle, describing the N/S/E/W direction of travel from your original point. Again, use a 0-360 degree random number, where zero represents due east, if you like.
The change in latitude can be calculated by d sin(Θ) , the change in longitude by d cos(Θ). That gives the great-circle distance in the same dimensions as r (presumably km), but you want lat/long degrees, so you'll need to convert. To get from latitudinal distance to degrees is easy: it's about 111.32 km per degree regardless of latitude. The conversion from longitudinal distance to longitudinal degrees is more complicated, because the longitudinal lines are closer to each other nearer the poles. So you need to use some more complex formulae to compute the change in longitude corresponding to the selected d (great distance) and angle. Remember you may need to hop over the +/- 180° barrier. (The designers of the F22 Raptor warplane forgot this, and their airplanes nearly crashed when attempting to cross the 180th meridian.)
Because of the error that may accumulate in successive approximations, you will want to check that the new point fits your constraints. Use the formula
Δσ = arccos( cos(Δlat) - cos(lat1)*cos(lat2)*(1 - cos(Δlong) ) .
where Δlat is the change in latitude, etc.
This gives you Δσ , the central angle between the new and old lat/long points. Verify that the central angle you've calcuated here is the same as the central angle you randomly selected previously. In other words verify that the computed d (great-circle-distance) between the calculated points is the same as the great circle distance you randomly selected. If the computed d varies from your selected d, you can use numerical approximation to improve the accuracy, altering the latitude or longitude slightly until it meets your criterion.
This can simply be done by calculating a random bearing (between 0 and 2*pi) and a random distance between 0 and your desired maximum radius. Then compute the new (random) lat/lon using the random bearing/range from your given lat/lon center point. See the section 'Destination point given distance and bearing from start point' at this web site: http://www.movable-type.co.uk/scripts/latlong.html
Note: the formula given expects all angles as radians (including lat/lon). The resulting lat/lon with be in radians also so you will need to convert to degrees.

Given a latitude, longitude and heading, how can I determine the lat/lon that is x meters from that point?

I have a series of lat/lon which represents the center of some object. I need to draw a line through this point that is x meters on either side of the center and it needs to be perpendicular to the heading (imagine a capital T)
Ultimately I want to get the lat/lon of this line's endpoints.
Thanks!
The basic calculation is in this similar question's answer: Calculate second point knowing the starting point and distance. Calculate the points for the two headings perpendicular to the main heading the distance away you want.
Have a look at: Core Location extensions for bearing and distance
With those extensions and two points on the initial line you should be able to get the bearing, add/subtract pi/2 and find points to either side like this:
double bearing = [bottomOfT bearingInRadiansTowardsLocation:topOfT];
CLLocation *left = [topOfT newLocationAtDistance:meters
alongBearingradians:bearing+M_PI/2];
CLLocation *right = [topOfT newLocationAtDistance:meters
alongBearingradians:bearing-M_PI/2];

Resources