You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Leaflet实现按地址数量比例显示的带数字城市圆形标记

问题描述

我已经在地图上为每个地址添加了标记,但界面十分杂乱。我的目标是为每个城市创建一个圆形标记,圆内显示该城市的地址数量,且圆的大小与地址数量成正比。CSV文件中每条地址都包含独立的城市和国家字段,恳请各位提供帮助,提前致谢。

let map = L.map('map', {
      minZoom: 2,
      maxZoom: 9
});

map.setView([48.54272537231445, 16.105000228881836], 8);

L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);


  // 从data.csv读取标记数据
jQuery.get('addresses.csv', function(csvString) {
    // 将字符串转换为对象数组
    let data = Papa.parse(csvString, {header: true, dynamicTyping: true}).data;

    // 遍历数据,为每一行创建标记并添加到地图
    for (let i in data) {
      let row = data[i];

      let marker = L.marker([row.Latitude, row.Longitude], {
        opacity: 1
      }).bindPopup(row.Title);
      
      marker.addTo(map);
    }

});
解决方案

Leaflet.markercluster正好是解决这个问题的工具,具体实现如下:

JavaScript 代码

// 从addresses.csv读取标记数据
jQuery.get('addresses.csv', function (csvString) {
  // 将字符串转换为对象数组
  let data = Papa.parse(csvString, { header: true, dynamicTyping: true }).data;

  let markers = new L.MarkerClusterGroup({
    iconCreateFunction: function (cluster) {
      let groupBounds = cluster.getBounds();
      // 计算聚合中心
      let clusterCenter = groupBounds.getCenter();
      // 将聚合中心坐标转换为像素
      let clusterCenterPoint = map.latLngToContainerPoint(clusterCenter);
      // 将边界右上角坐标转换为像素
      let northeastPoint = map.latLngToContainerPoint(groupBounds.getNorthEast());
      // 计算像素间距离
      let distanceInPx = clusterCenterPoint.distanceTo(northeastPoint);

      let html = '<div>' + cluster.getChildCount() + '</div>';
      return L.divIcon({
        html: html,
        className: 'mycluster',
        iconSize: L.point(distanceInPx, distanceInPx),
      });
    },
    spiderfyOnMaxZoom: false,
    showCoverageOnHover: true,
    zoomToBoundsOnClick: false,
  });

  // 遍历数据,为每一行创建标记并添加到聚合组
  for (let i in data) {
    let row = data[i];

    if (row.Latitude != null && row.Longitude != null) {
      let marker = L.marker(
        new L.LatLng(row.Latitude, row.Longitude),
        {}
      ).bindPopup(row.Latitude + " " + row.Longitude);
      markers.addLayer(marker);
    }
  }
  map.addLayer(markers);
});

(注:修正了原代码中判断条件的重复错误,将重复的row.Latitude != null改为row.Longitude != null)

CSS 样式

.mycluster {
    display: flex !important;
    justify-content: center;
    align-items: center;
    font-size: 24px;
    background: rgba(39, 133, 245, 0.3);
    border-radius: 50%;
    color: black;
}

效果说明

该实现会将同一区域的地址标记聚合为圆形标记,圆内显示该区域的地址数量,且圆的大小会根据地址数量动态调整;鼠标悬停时会显示聚合区域的范围,点击不会自动缩放至区域边界。

内容的提问来源于stack exchange,提问作者Marko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 20:44:51