I am attempting to calculate the bearing from an object with geodesic coords given by latitude/longitude and a heading to another object at different latitude/longitude coordinates.
A rough sketch of the problem is
where the triangle represents object one, the arrow represents object one's heading, and the square represents object two.
I am aware this can be done using the haversine formula, as in , but how would one do this while simultaneously taking spheroid earth into consideration.
Related
I need to calculate the minimum distance between a 3D point (latitude, longitude, elevation) and a line (defined as two points).
The elevation is not necessary on the ground, I need to consider flying objects.
I only found an article that explains how to do that on a generic space but my points are defined with lat/lon/altitude(meters).
Thank you for pointing in the right direction, in my case I need to do that in Javascript but couldn't find any library that takes into consideration the altitude.
Point-Line Distance--3-Dimensional
If you want to compare a 3d point to a 2d line, I suppose you mean a "line" on our earth, at elevation 0. Take a look at st_distance in postgis.
If I understand you correctly, that'll give you what you want.
https://postgis.net/docs/ST_Distance.html
What is best strategy to recreate part of a street in iOS SceneKit using .osm XML data?
Please assume part of a street is offered in the OSM XML data and contains the necessary geopoints with latitude and longitude denoting the Nodes to describe the paths/footprints of 6 buildings (i.e. ground floor plans that line the side of a street).
Specifically, what's the best strategy to convert latitude and longitude Nodes in order to locate these building footprints/polygons on the ground floor in a scene within SceneKit iOS? (i.e. running through position 0,0,0)? Thank you.
Very roughly and briefly, based on my own experience with 3D map rendering:
Transform the XML data from lat/long to appropriate coordinates for a 2D map (that is, project it to a plane using a map projection, then apply a 2D affine transform to get it into screen pixel coordinates). Create a 2D map that's wider and taller than the actual screen, because of what's going to happen in step 2:
Using a 3D coordinate system with your map vertical (i.e., set all the Z coordinates to zero), rotate the map so that it reclines at an appropriate shallow angle, as if you're in an aeroplane looking down on it; the angle might be 30 degrees from horizontal. To rotate the map you'll need to create a 3D rotation matrix. The axis of rotation will be the X axis: that is, the horizontal line that is the bottom border of your 2D map. The rotation is exactly the same as what happens when you rotate your laptop screen away from you.
Supply the new 3D coordinates to your rendering system. I haven't used SceneKit but I had a quick look at the documentation and you can use any coordinate system you like, so you will be able to use one that is convenient for the process I have just described: something that uses units the size of a screen pixel at the viewing plane, with Y going upwards, X going right, and Z going away from the viewer.
One final caveat: if you want to add extrusions giving a rough approximation of the 3D building shapes (such data is available in OSM for some areas) note that my scheme requires the tops of buildings, and indeed anything above ground level, to have negative Z coordinates.
Pretty simple. First, convert Your CLLocationCoordinate2D to a MKMapPoint, which is exactly the same as a CGRect. Second, scale down the MKMapPoint by some arbitrary number so it fits in with how you want it on your scene graph, let's say by 200. Since scenekit's coordinate system is centered at (0,0), you'll need to make sure your location is correct. Then just create your scnvector3's with the x/y of he MKMapPoint, and you will be locked to coordinates.
I'm currently developing a small piece of (Java) software that should be able to display maps and the current GPS position within that map.
I'm absolutely new to this, but it is pretty obvious that I'll have to do some kind of coordinate transformation.
I've found "Proj4J", which seems to be able to do a lot for me.
Now, what I have and what I want to do:
I have a bitmap of a map. The projection of this map can be any "well-defined" one, like Lambert or Mercator. I cannot fix this to one projection.
I have GPS coordinates from a "standard" GPS receiver. I believe they are lat/lon in WGS84, is that correct?
Now my questions:
I must map the GPS position to basically "screen coordinates" in my map bitmap. And for that, I assume, reference points are needed for which I know their lat/lon and corresponding pixel positions. Since my map can easily cover a couple of hundred kilometers in range, a linear interpolation between the known points and an arbitrary position is probably not correct for all types of projections, am I right on that?
I've read "Convert long/lat to pixel x/y on a given picure" so far, but this deals with a Mercator projection and I believe a linear approximation will work better than for a Lambert map.
I imagine the whole process is as follows:
"Calibrate" the map, i. e. identify two positions of known lat/lon in the bitmap and thus get their pixel position.
Use the Proj.4-transformation from "lat/lon WGS84" to "map projection" to map those reference points from (1.) into map coordinates.
Take the points from (2.) and map them again to a projection that will allow linear interpolation of the pixel positions, I'll call that the "pixel projection".
Now I have two reference points with coordinates in the "pixel projection" and their corresponding pixel positions.
For a lat/lon value from the GPS receiver do the following:
Convert the position to a map position using the "map projection".
Take the map position from (1.) and convert it to a coordinate using the "pixel projection" from above.
Since all distances in the "pixel projection" are maintained (that is the condition of the pixel projection!), an interpolation of the resulting coordinates from (2.) with the known position of the reference points from above can be made.
Here the big questions:
Is this the way to go, using a final "pixel projection" to allow linear interpolation?
What type of projection would that be and can that be done with Proj.4?
Can the "way back" - I have a pixel position and want lat/lon be accomplished (like "pixel position" -> "pixel projection" -> "map projection" -> "lat/lon")?
Thank you very much,
Jens.
I have a set of x,y coordinates denoting the outlines of the continents in a Miller Projection in MATLAB. I'm trying to figure out the MATLAB mapping toolbox and specifically projinv. The function takes a set of (x,y) coordinates and a projection, and then transforms them into a set of longitude and latitudes.
What I'm confused on is what the units on the (x,y) coordinates should be. The example in the docs seems to convert them into Survey Feet, but I can't find any documentation on how to properly scale the input mapping.
Any suggestions?
Not quite sure what you're asking here...
The Boston roads example in the docs convert units from survey feet into meters, and then passes them into projinv. Thus, (x,y) should be in meters.
Is this what you mean?
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.