I need to convert kilometers to radians. Is this correct formula?
I need radians for nearsphere in MongoDB.
If I need to convert 5 kilometers to radians I do this:
5/6371
And I get this result (does it seem correct):
0.000784806153
UPDATE
This is not a math issue, I really need to know if I am doing the correct calculations from kilometers to radians to be able to do geospatial queries with MongoDB.
Kilometers to radians or distance and radian conversion
I arrived here, was confused, then I watched some Khan academy videos and it made more sense at that point and then I was able to actually look at equations from other sources to further educate myself.
Here's my train of thought.
I see a diagram about radians and I first think radius from a geolocation point which is wrong.
Instead, imagine the earth cut perfectly in half and just focus on one of the halves.
Now face that half toward you and look at the math diagram.
Think of the math diagram as showing from the center of the earth measuring the edge of the earth based on the arc length, after all the earth is curved so any measurement will be curved on the surface of the earth.
Radians are like degrees in a circle and the arc length is literally the distance between A and B in the math diagram.
To you, its a straight line on a bird's eye view, but really it's just a curve in 3d space along the edge of the earth.
Eureka! A lightbulb went on in my head.
distance = earth radius * radians
Thus with some very easy algebra...
radians = distance / earth radius
km
radians = distance in km / 6371
mi
radians = distance in mi / 3959
Sometimes thinking it through is fun.
Double-check this... https://www.translatorscafe.com/unit-converter/en/length/7-89/kilometer-Earth%E2%80%99s%20equatorial%20radius/
Now in regards to Mongo v3.2 specifically using mongoose in node.js
Despite my best efforts, mongo would not behave correctly as documented for a $geoNear query on a 2d index. never worked
let aggregate = [
{
$geoNear: {
near: { type: 'Point', coordinates: lonLatArray },
spherical: false,
distanceField: 'dist.calculated',
includeLocs: 'dist.location',
maxDistance: distanceInMeters / (6371 * 1000),
query: {
mode: 'nearme',
fcmToken: { $exists: true }
}
}
},
{ $skip: skip },
{ $limit: LIMIT }
];
However, when I changed to a 2dsphere index, it worked perfectly.
let aggregate = [
{
$geoNear: {
near: { type: 'Point', coordinates: lonLatArray },
spherical: true,
distanceField: 'dist.calculated',
includeLocs: 'dist.location',
maxDistance: distanceInMeters,
query: {
mode: 'nearme',
fcmToken: { $exists: true }
}
}
},
{ $skip: skip },
{ $limit: LIMIT }
];
But education never seems like a waste of time.
You are correct.
In spherical geometry you divide the distance with the radius of the sphere.
Mind that you should keep the units. So if you calculate the sphere radius in kilometers then you should use distance in kilometer. If you use miles then you should use Earth radius in miles (approx: 3,963.2).
The equatorial radius of the Earth is approximately 3,963.2 miles or 6,378.1 kilometers.
Note : 1 KM = 0.621371 Mile
Here is some simple formulas for calculation :
100 KM to Miles : (100 * 0.621371)
100 KM to radiant : 100 / 6378.1
100 Miles to radiant : 100 / 3963.2
So if you have data in Kilometers then you must use (100 / 6378.1) and for Miles data you can use (100 / 3963.2)
To convert:
distance to radians: divide the distance by the radius of the sphere (e.g. the Earth) in the same units as the distance measurement.
radians to distance: multiply the radian measure by the radius of the sphere (e.g. the Earth) in the units system that you want to convert the distance to.
for Example: if you want to convert 5 miles in radians, then we need to divide the distance(5 miles) by the radius of the sphere(also in miles), which is 3959. then 5/3959 is 0.0012629451...
Thanks
Related
I'm using the aggregate $geoNear and I don't know if the field distanceField return a value in meters or in another unit
{near : { type: "Point", coordinates: [long,lat] },
distanceField: "dist.calculated",
maxDistance: 50000,
includeLocs:"dist.location",
num: 10, spherical :true }
I only want to know the unit of measurement
Thanks, everyone.
As per documentation:
Specify the distance in meters if the specified point is GeoJSON and in radians if the specified point is legacy coordinate pairs.
So it's in meters in your case since you're specifying a GeoJSON
Is there any way to check whether a google map polygon or circle area is greater than the earth hemisphere so that we can know the geowithin queries will not work properly in mongo queries Link.Or what is the condition where the geo spatial query works perfect.
{
<location field>: {
$geoWithin: {
$geometry: {
type: <"Polygon" or "MultiPolygon"> ,
coordinates: [ <coordinates> ]
}
}
}
}
For egs: Area of a polygon can be calculated by:
google.maps.geometry.spherical.computeArea(e.getPath())
where e is the event object varible when the polygon completed event. but how can we compare those with the earth hemisphere area?
how can we compare those with the earth hemisphere area?
Provided that the Earth radius is about 6371 km, you can just calculate the spherical surface area of the hemisphere:
A = 2πr^2
A = 2π(6371)^2
A = 255032236 square km
If the result of google.maps.geometry.spherical.computeArea(e.getPath()) is greater than the above value, then the area polygon/circle is greater than one of the Earth's hemisphere.
I have a leaflet circle with a radius, how do I convert the radius to nautical miles in javascript?
Note that for Leaflet's circle, the radius corresponds to meters (see L.circle). Then you can convert meters directly into nautical miles.
Note that L.circle is just an approximation:
It's an approximation and starts to diverge from a real circle closer to poles (due to projection distortion).
To draw a gedetically accurate circle, use something like Leaflet.Geodesy.
A quick JS function to convert meters to miles -
function metersToMiles(meters){
if (isNaN(meters)){
console.log("meters is not a number");
return 0;
}
return meters/1852;
}
Also a good thing to note is that the draw tools for leaflet.draw have a way to draw a circle with nautical miles as the unit of measure -
draw: {
circle: {
metric: false,
feet: false,
nautic: true
}
}
leaflet draw documentation link
It looks like there is a "readableDistance" on the L.GeometryUtil object too but I only used the code above so I am not sure how that would work.
Here's the pitch. I have a collection of Circles which have mainly two attributes: location is a Point and radius is a distance in meters.
Users also have a profile.location Point attribute.
In my publications, I want to find all the Circles that the user is "in", ergo the ones he or she is near enough according to each Circle's radius attribute. To sum it up, here's how it would look like:
Meteor.publish('circles', function() {
var curUser = Meteor.users.findOne({_id:this.userId});
if (curUser) {
return Circles.find({
location: {$near:
{$geometry:curUser.profile.location,$maxDistance:self.radius} // HERE
}
}));
}
this.ready();
});
Except self.radius is a completely made-up term on my behalf. But is it possible to achieve something like this?
POST-SOLVING edit:
Thanks to Electric Jesus, I have my matchings working perfectly with polygons, since circles are not GeoJSON types as of yet. (therefore they are not single attributes that can be queried, sort of) So I converted my circles into polygons! Here is a JavaScript function to do this:
function generateGeoJSONCircle(center, radius, numSides) {
var points = [];
var earthRadius = 6371;
var halfsides = numSides / 2;
//angular distance covered on earth's surface
var d = parseFloat(radius / 1000.) / earthRadius;
var lat = (center.coordinates[1] * Math.PI) / 180;
var lon = (center.coordinates[0] * Math.PI) / 180;
for(var i = 0; i < numSides; i++) {
var gpos = {};
var bearing = i * Math.PI / halfsides; //rad
gpos.latitude = Math.asin(Math.sin(lat) * Math.cos(d) + Math.cos(lat) * Math.sin(d) * Math.cos(bearing));
gpos.longitude = ((lon + Math.atan2(Math.sin(bearing) * Math.sin(d) * Math.cos(lat), Math.cos(d) - Math.sin(lat) * Math.sin(gpos.latitude))) * 180) / Math.PI;
gpos.latitude = (gpos.latitude * 180) / Math.PI;
points.push([gpos.longitude, gpos.latitude]);
};
points.push(points[0]);
return {
type: 'Polygon',
coordinates: [ points ]
};
}
Here you go. I don't really know how many sides I should use, so I left an argument for that too. From there, you can use Electric Jesus's answer to get where I was going. Don't forget to put a 2dsphere index on your polygon!
Circles._ensureIndex({'polygonConversion': "2dsphere"});
No, the Geo indexes would never work in a way that you demand it to be dynamic according to a document's 'radius'. You must convert your circles into Polygon geometries and use the $geoIntersects query to find which Circle (Polygon geometry) intersects with your current location/location parameter (Point geometry).
var location = {
longitude: -1.85549,
latitude: 52.9445
}
// create a circle with a Polygon geometry location, with converted coordinates
Circles.insert({name: "My Circle 1", loc: {
type: "Polygon",
coordinates: [[[ ... ]]],
}
});
// finding one or more Circles that intersect with current location.
Circles.find({loc: {
$geoIntersects: {
$geometry: {
type: "Point" coordinates: [location.longitude, location.latitude]
}
}
}});
Mongo's geospatial operators include $centerSphere, which returns documents that are within the bounds of a circle:
Entities.find({
location : {
$geoWithin : {
$centerSphere: [
[ curUser.profile.location.lng , curUser.profile.location.lat ],
radius / 6378100 // convert radians to meters by dividing by the Earth's radius
]
}
}
} );
You can try an additively weighted voronoi diagram. The distance function is the euklidian distance minus the weight. Sites with bigger weights and nearby other sites get sorted into the same cell.
I wanted to test the mapKit and wanted to make my own overlay to display the accuracy of my position.
If i have a zoom factor of for example .005 which radius does my circle around me has to have(If my accuracy is for example 500m)?
Would be great to get some help :)
Thanks a lot.
Look at the documentation for MKCoordinateSpan, which is part of the map's region property. One degree of latitude is always approx. 111 km, so converting the latitudeDelta to meters and then getting to the meters per pixel should be easy. For longitudinal values it is not quite so easy as the distance covered by one degree of longitude varies between 111 km (at the equator) and 0 km (at the poles).
My way to get meters per pixel:
MKMapView *mapView = ...;
CLLocationCoordinate2D coordinate = ...;
MKMapRect mapRect = mapView.visibleMapRect;
CLLocationDistance metersPerMapPoint = MKMetersPerMapPointAtLatitude(coordinate.latitude);
CGFloat metersPerPixel = metersPerMapPoint * mapRect.size.width / mapView.bounds.size.width;
To add to another answer, a difference of one minute of latitude corresponds to one nautical mile: that's how the nautical mile was defined. So, converting to statute miles, 1 nautical mile = 1.1508 statue miles, or 6076.1 ft. or 1852 meters.
When you go to longitude, the size of the longitude circles around the Earth shrink as latitude increases, as was noted on the previous answer. The correct factor is that
1 minute of longitude = (1852 meters)*cos(theta),
where theta is the latitude.
Of course, the Earth is not a perfect sphere, but the simple calculation above would never be off by more than 1%.