I noticed that when you draw a polyline in google maps you set it's width in pixels (strokewidth). Is there a way I could set that in metres instead?
-
Is there any update on this topic? – Paul Noris Nov 14 '22 at 00:31
3 Answers
Unfortunately, I don't know any easy way to do this. The API does not appear to have documentation on this and I assume this feature is unsupported.
One problem is that the pixels represent a different number of meters at different zoom levels within the API. So it would be a dynamic quantity if the zoom levels are changed.
One option might be to compute the width in pixels for representing a given number of meters for a given zoom level. For that, you would have to write your own function based on the scales of the map at each zoom level. That data appear to be available here:
http://webhelp.esri.com/arcgisserver/9.3/java/index.htm#designing_overlay_gm_mve.htm
20 : 1128.497220
19 : 2256.994440
18 : 4513.988880
17 : 9027.977761
16 : 18055.955520
15 : 36111.911040
14 : 72223.822090
13 : 144447.644200
12 : 288895.288400
11 : 577790.576700
10 : 1155581.153000
9 : 2311162.307000
8 : 4622324.614000
7 : 9244649.227000
6 : 18489298.450000
5 : 36978596.910000
4 : 73957193.820000
3 : 147914387.600000
2 : 295828775.300000
1 : 591657550.500000
you can then set the pixel value dynamically depending on the meters you are trying to represent and the current zoom level.
There may still be a problem because the pixel sizes you generate, may not correspond to the screen pixel sizes, depending on how the API deals with screen DPI and resolution

- 612
- 1
- 4
- 9
-
Thanks R Ghosh. I don't know if it's strange or not but I just thought there would be some way to easily do this. They allow specifying circles with a radius in metres... – dreza Jul 15 '13 at 20:03
-
@dreza this feature does not exist in the documentation. Part of the problem is that the stroke weight can not be directly converted to a fixed length in meters. in the extreme corners of the map, the map is extremely stretched (horizontally). At a given point on the map, you could calculate this value, but at any given zoom level, there will be a whole range of values for stroke width to meters. circles are possibly (my guess) allowed to be defined in meters because they can be neatly represented and converted in the spherical geometry. – R Ghosh Jul 19 '13 at 12:27
-
I had this trouble and I decided to do different, so, no polylines but Polygons, like this, you can turn your WGS84 Coordinates into UTM and UTM allows much more, i.e. you can add X meter Right/Left to your position and Y meters ahead and behind. I just wanted to track a tractor with a GPS in the middle of Longitudinal axis and worked! – Gödel77 Dec 11 '14 at 08:39
-
Problem 1) The stroke width can't be more than 32px. Problem 2) the resolution of the map on a Mercator projection is not identical at all latitudes so you can't use fixed values like that. – MrUpsidown Nov 13 '18 at 09:47
Based on this answer, I could get an acceptable result. Even if it is not the best solution.
In my case I used Android with com.google.android.gms:play-services-location:8.4.0
. But the original answer is in JavaScript, so I think it is not difficult to adapt.
LatLng center = <get map center>.
float requiredWidth = 10; // in meters
Projection proj = googleMap.getProjection();
Point pointCenter = proj.toScreenLocation(center); // point in pixels
LatLng neighbor = proj.fromScreenLocation(new Point(pointCenter.x + 1000, pointCenter.y));
float[] distance = new float[1];
Location.distanceBetween(center.latitude, center.longitude, neighbor.latitude, neighbor.longitude, distance); // return distance in meters
float pixelsWidth = requiredWidth / (distance[0] / 1000f); // 10 meters conveted to pixels
myPolyline.setWidth(pixelsWidth);
The difference between my answer and the original is that I create the neighbor with 1000 pixels distance, to get a higher sampling rate and increase precision.
This approach also considers the zoom automatically.

- 2,070
- 2
- 27
- 50
It is not the accurate solution
You can use Scale control of the Leaflet. Basically you get the value of the scale and compute how many meters fit in one pixel.
/**
* Returns number of meters in one pixel.
*
* @return Integer number of meters in one pixel
*/
var _metersInPixel = function () {
var pixels = $('.leaflet-control-scale-line').width();
var distance = $('.leaflet-control-scale-line').first().text();
var testRegExpKm = /(\d+)\skm/;
var testRegExpM = /(\d+)\sm/;
if (testRegExpKm.test(distance)) {
var match = testRegExpKm.exec(distance);
var meters = parseInt(match[1]) * 1000;
} else if (testRegExpM.test(distance)) {
var match = testRegExpM.exec(distance);
var meters = parseInt(match[1]);
} else {
throw "Unable to determine meters to pixels ratio";
}
var metersInPixels = Math.round(meters / parseInt(pixels));
return metersInPixels;
};

- 2,185
- 2
- 21
- 29
-
OK, this is a clever bit of lateral thinking. Do I assume that it will only work if an instance of `L.Control.Scale` is present? – Tom Chadwin Nov 10 '17 at 11:56