How to convert leaflet circle radius to nautical miles? - leaflet

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.

Related

Leaflet - Draw a Circle that fits around a Bounding Box

In Leaflet docs, L.Circle Radius is based on meters, but how can I draw a Circle based on coordinates instead?
More specifically, I want to draw a circle that encompasses a specific bounding box
const myCenter = [37, -122];
const myBoundingBox = {
northEast: [myCenter[0]+2, myCenter[1]+2],
southWest: [myCenter[0]-2, myCenter[1]-2]
};
const circle = L.circle(myCenter, {radius: ??}).addTo(map);
I've figured it out, use map.distance function to get distance in meters between the diagonal points of the bounds
const circleRadius = map.distance(myBoundingBox[northEast], myBoundingBox[southWest])/2
Then just create the circle normally using the radius in meters

How to get the edge of a polygon drawn on map within Leaflet

I am working with Leaflet and Leaflet-Draw in Angular to draw some polygons on the Google Map. How can I implement a listener when the user clicks exactly on the edge of the drawn polygons and get the lat and lng of that edge. I know a similar situation can be implemented with Google Map API like the code below, but I can not find any source to help me implement the same thing in Leaflet.
google.maps.event.addListener(polygon, 'click', function (event) { console.log(event.edge) }
Google Map Documentation: https://developers.google.com/maps/documentation/javascript/reference/polygon#PolyMouseEvent
For those who come across this question: I found a solution myself!
I didn't find anything directly from Leaflet draw library that I could use, so I defined the problem for myself as a trigonometry problem and solve it that way.
I defined a function in which on polygon click, it converts the event.latlng and loops over polygon.getLatLngs()[0] taking a pair of A and B points. A is the first coordinates, B is the next and if it reaches to the end of array, B will be the first point. Then using Collinear Function of 3 points with x, y, I checked if the clicked x, y has a same slope as point A and B.(has to be rounded it up), if so, I would save that A and B point pair with their latLng information and further used it in my project.
Although this method works, I would appreciate if anybody would know a better solution or library built-in function that can be used instead. Thanks!
When the user clicks on the polygon you can loop through all corners and check if he clicked in the near of the corner.
poly.on('click', function(e){
var latlng = e.latlng;
var corners = poly.getLatLngs();
if(!L.LineUtil.isFlat(corners)){ //Convert to a flat array
corners = corners[0];
}
//Convert the point to pixels
var point = mymap.latLngToContainerPoint(latlng);
//Loop through each corner
corners.forEach(function(ll){
//Convert the point to pixels
var point1 = mymap.latLngToContainerPoint(ll);
var distance = Math.sqrt(Math.pow(point1.x - point.x, 2) + Math.pow(point.y - point1.y, 2));
//Check if distance between pixels is smaller then 10
if(distance < 10){
console.log('corner clicked');
}
});
});
This is plain JS you have to convert it self to angular.
A alternativ is to place on each corner a DivMarker or a CircleMarker and fire a event if the marker is clicked.
Looks like: https://geoman.io/leaflet-geoman

Draw circle using latitude and longitude

I want to plot a latitude and longitude using matlab. Using that latitude and longitude as center of the circle, I want to plot a circle of radius 5 Nm.
r = 5/60;
nseg = 100;
x = 25.01;
y = 55.01;
theta = 0 : (2 * pi / nseg) : (2 * pi);
pline_x = r * cos(theta) + x;
pline_y = r * sin(theta) + y;
hold all
geoshow(pline_x, pline_y)
geoshow(x, y)
The circle does not look of what I expected.
Drawing a circle on earth is more complex that it looks like.
Drawing a line or a poly line is simple, because the vertices are defined.
Not so on circle.
a circle is defined by all points having the same distance from center (in meters! not in degrees!!!)
Unfortuantley lat and lon coordinates have not the same scale.
(The distance between two degrees of latidtude is always approx. 111.3 km, while for longitude this is only true at the equator. At the poles the distance between two longitudes approach zero. In Europe the factor is about 0.6. (cos(48deg))
There are two solution, the first is more universal, usefull for nearly all problems.
convert spherical coordinate (of circle center) to cartesian plane with unit = 1m, using a transformation (e.g equidistant transformation, also called equirectangular transf., this transformation works with the cos(centerLat) compensation factor)
calculate points (e.g circle points) in x,y plane using school mathematics.
transform all (x,y) points back to spherical (lat, lon) coordinates, using the inverse transformation of point 1.
Other solution
1. write a function which draws an ellipse in defined rectangle (all cartesian x,y)
2. define bounding of the circle to draw:
2a: calculate north-south diameter of circle/ in degrees: this a bit tricky: the distance is define in meters, you need a transformation to get the latitudeSpan: one degrees of lat is approx 111.3 km (eart circumence / 360.0): With this meters_per_degree value calc the N-S disatcne in degrees.
2b: calculate E-W span in degrees: now more tricky: calculate like 2a, but now divide by cos(centerLatitude) to compensate that E-W distances need more degrees when moving north to have the same meters.
Now draw ellipseInRectangle using N-S and E_W span for heigh and width.
But a circle on a sphere looks on the projected monitor display (or paper) only like a circle in the center of the projection. This shows:
Tissot's Error Ellipse

iphone -- convert MKMapPoint distances to meters

Say I have a square which consists of four CLLocationCoordinate2D points, which are in lat, lon, and I want to find the area of the square in meters. I convert the CLLocationCoordinate2D points into MKMapPoints, and I find the area in X-Y space. However, the area I find is in the units of MKMapPoint, which don't directly translate to meters. How can I translate this area in MKMapPoint-space back into meters?
The MapKit function MKMetersBetweenMapPoints makes this easier.
For example, if you wanted to get the area of the currently displayed region:
MKMapPoint mpTopLeft = mapView.visibleMapRect.origin;
MKMapPoint mpTopRight = MKMapPointMake(
mapView.visibleMapRect.origin.x + mapView.visibleMapRect.size.width,
mapView.visibleMapRect.origin.y);
MKMapPoint mpBottomRight = MKMapPointMake(
mapView.visibleMapRect.origin.x + mapView.visibleMapRect.size.width,
mapView.visibleMapRect.origin.y + mapView.visibleMapRect.size.height);
CLLocationDistance hDist = MKMetersBetweenMapPoints(mpTopLeft, mpTopRight);
CLLocationDistance vDist = MKMetersBetweenMapPoints(mpTopRight, mpBottomRight);
double vmrArea = hDist * vDist;
The documentation states that the function takes "into account the curvature of the Earth."
You can use the Haversine formula to calculate it, assuming that the earth is a perfect sphere.
To understand how lat/lon vs meters works in the context of the earth, you may find it interesting to read about Nautical miles.
You can find some more resources and some sample code by googling objective-c Haversine formula.
Enjoy!

How to display the radius in MKCircle on Map in meters

I need to draw a circle of a radius 1.23 metre on MkMapView using MKCircle.
How would i show that on the map.
I used the following ,
r = 1.23;// in metres.
circle = [MKCircle circleWithCenterCoordinate:location radius:r];
But when i draw it on the map it looks like more than 1km on the MKMapView.
Could someone please tell me how i could represent a circle of radius 1.23 metre on the map??
This is mainly to show the accuracy of the location, so the radius indicates the accuracy of the location.
In the viewForOverlay delegate method, try setting the lineWidth of the MKCircleView to 1.
I think the default width of 0 results in the "road width".
MKCircle class definition says
radius
The radius of the circle, measured in meters from the center point.
So your code should work fine.
Source: http://developer.apple.com/library/ios/#DOCUMENTATION/MapKit/Reference/MKCircle_class/Reference/Reference.html