Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert radius in metres to pixels in mapbox leaflet?

I am working on an application where I am trying to run some algorithms on a map and calculate coords but they are slightly off because I am running the calculations on latitude and longitudes and the final results are getting distorted.

Now I am trying to convert all coordinates to EPSG3857 Web Mercator coordinates like so:

var crs = L.CRS.EPSG3857;
var zoom = terrainAnalysisMap.getZoom();

markerToPoint = crs.latLngToPoint(marker.getLatLng(), zoom);
markerOnRadiusToPoint = crs.latLngToPoint(markerOnRadius.getLatLng(), zoom);

Now I also have a radius which I will have to convert from metres to pixels but I cannot figure out how. How much is 1 metre in pixels? I mean it would depend on the zoom level too, right? So how to go about converting radius to pixels in mapbox and leaflet?

like image 256
Rohan Avatar asked Jun 08 '15 07:06

Rohan


3 Answers

If you happen to have the latitude of the place where you are looking to convert the radius to pixels, you can make use of the "Meters per pixel" function described at http://wiki.openstreetmap.org/wiki/Zoom_levels. Here's my javascript implementation:

var metersPerPixel = function(latitude, zoomLevel) {
  var earthCircumference = 40075017;
  var latitudeRadians = latitude * (Math.PI/180);
  return earthCircumference * Math.cos(latitudeRadians) / Math.pow(2, zoomLevel + 8);
};

var pixelValue = function(latitude, meters, zoomLevel) {
  return meters / metersPerPixel(latitude, zoomLevel);
};
like image 133
Brian Nguyen Avatar answered Nov 15 '22 00:11

Brian Nguyen


A meter is a meter, no matter what your zoom level is. What you need is to convert a meter into degrees since long/lat is a polar coordinate system. With the circumference of Earth being 40,075 km, you get 0.00000898315 deg/m which you need to multiply with the size of the object (1 m) to get the degrees which you have to add to your coordinate to get a point which intersects with the radius of the circle that you want to draw.

But usually, it's easier to just draw a circle with a radius of 10 px around the center coordinate (after you transformed it from world to screen) making sure that the circle is always the same size, no matter of the zoom level. That way, people won't have a problem to see and/or click it.

[EDIT] Your question is related to Parametric equation to place a leaflet marker on the circumference of a circle is not precise?

My suggestion is to forget about world coordinates for the drag/drop problem. Obviously, you already have a circle (which means you must know the center point and the radius in pixels - otherwise, you couldn't draw it).

What you need is to implement the dragging of the marker only in screen coordinates. That should be pretty simple to implement.

When the user releases the mouse, all you have to do is to take the screen coordinate and convert it into long/lat once.

One problem to keep in mind: If you're using something like Mercator projection, the coordinates will be off as you get closer to the poles. To solve this, you need to work with an ellipse (wider than tall) instead of a circle.

like image 26
Aaron Digulla Avatar answered Nov 14 '22 23:11

Aaron Digulla


I have done this once using this array for pixel/realworld-meter translation

pixelMeterSizes: {
    10: 1 / 10,
    11: 1 / 9,
    12: 1 / 8,
    13: 1 / 7,
    14: 1/ 5,
    15: 1 / 4.773,
    16: 1 / 2.387,
    17: 1 / 1.193,
    18: 1 / 0.596,
    19: 1 / 0.298
}

Notice, that above a zoomlevel of 15, i simplified things, because the symbols were getting too small and would not be visible anymore.

I used this as a basic reference http://wiki.openstreetmap.org/wiki/Zoom_levels.

This worked quite good for me, but i am not sure what will happen when dealing with high res displays and such. Guess it could fail in those scenarios.

like image 41
Hinrich Avatar answered Nov 14 '22 22:11

Hinrich