javascript 为所有缩放级别绘制一个恒定大小的圆圈 Leaflet.js

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22467177/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 23:13:26  来源:igfitidea点击:

Draw a circle of constant size for all zoom levels leaflet.js

javascriptleaflet

提问by aa8y

I am trying to implement something like thisusing leaflet.js, where the size of the circle remains the same on varying zoom levels. For example, if I want to depict the populations in different US counties, I would have circles of different radius represent different ranges of populations. They may overlap when zoomed out completely, but once we start zooming in, they tend to separate. So is there a way to do this using leaflet.js. I saw an issueraised, but I wasn't able to follow if it was fixed or not. Any help would be deeply appreciated.

我想实现像这样使用leaflet.js,其中圆的尺寸保持在不同的缩放级别相同。例如,如果我想描绘美国不同县的人口,我会用不同半径的圆圈代表不同范围的人口。完全缩小时它们可能会重叠,但是一旦我们开始放大,它们就会分开。那么有没有办法使用leaflet.js来做到这一点。我看到了一个问题,但我无法跟进它是否已修复。任何帮助将不胜感激。

采纳答案by 4m1r

I think you're gonna want to do something like this:

我想你会想做这样的事情:

var map = L.map('map').setView([51.505, -0.09], 13);

var circle = L.circle([51.508, -0.11], 500, {
    color: 'red',
    fillColor: '#f03',
    fillOpacity: 0.5
}).addTo(map);

var myZoom = {
  start:  map.getZoom(),
  end: map.getZoom()
};

map.on('zoomstart', function(e) {
   myZoom.start = map.getZoom();
});

map.on('zoomend', function(e) {
    myZoom.end = map.getZoom();
    var diff = myZoom.start - myZoom.end;
    if (diff > 0) {
        circle.setRadius(circle.getRadius() * 2);
    } else if (diff < 0) {
        circle.setRadius(circle.getRadius() / 2);
    }
});

What I've done is simply initialize a map and a circle and created event listeners for the zoomstartand zoomendevents. There's a myZoomobject that records the zoom levels so you can find out whether or not the final zoom is in or out by simple subtraction. In the zoomEndlistener, you check that and change the circle radius based on whether the difference is greater or lesser than 0. We of course do nothing when it's 0. This is where I leave you to get more sophisticated with your results. But, I think this demonstrates how to do it.

我所做的只是初始化地图和圆圈,并为zoomstartzoomend事件创建事件侦听器。有一个myZoom对象会记录缩放级别,因此您可以通过简单的减法来确定最终缩放是放大还是缩小。在zoomEnd侦听器中,您检查并根据差异是大于还是小于 0 更改圆半径。当它为 0 时,我们当然什么都不做。这是我让您对结果进行更复杂处理的地方。但是,我认为这演示了如何做到这一点。

回答by Aaron Schumacher

For circles, just use circleMarkerinstead of circle: http://leafletjs.com/reference.html#circlemarker

对于圈子,只需使用circleMarker而不是circlehttp: //leafletjs.com/reference.html#circlemarker

回答by lucas

Try this if you can't use circle markers for some reason:

如果由于某种原因不能使用圆形标记,请尝试此操作:

// Determine the number of meters per pixel based on map zoom and latitude
const zoom = map.getZoom()
const lat = map.getCenter().lat
const metersPerPixel = 156543.03392 * Math.cos(lat * Math.PI / 180) / Math.pow(2, zoom)

// Multiply that by a factor based on how large the circle should appear on the screen
const radius = metersPerPixel * desiredRadiusInPixels

// Create the circle
const circle = L.circle(this.map.getCenter(), {radius: radius}))

I found the "meters per pixel" formula in this answer: https://gis.stackexchange.com/a/127949/106283

我在这个答案中找到了“每像素米数”公式:https: //gis.stackexchange.com/a/127949/106283

回答by rudak

Otherwise you can do like this, by adapting the exponent of the Math.pow() according to your needs

否则你可以这样做,根据你的需要调整 Math.pow() 的指数

mymap.on('zoomend', function (e) {
    var newRadius = Math.pow((20 - mymap.getZoom()), 4);
    myCircle.setRadius(newRadius);
});