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

Google Maps JS API v3:如何检测并显示多边形边的长度

解决Google Maps多边形边长度显示问题

嘿,我来帮你搞定多边形每条边的长度显示需求!你已经能计算并显示面积了,其实边长度的实现思路类似,只是需要遍历多边形的每一条边,计算长度后在边的中点位置显示标签。下面是具体的实现方案和修改后的完整代码:

核心思路

  • 给每个多边形单独存储对应的边长度标签,避免不同多边形的标签混乱
  • 遍历多边形的所有顶点,计算每两个相邻顶点(包括最后一个和第一个顶点,因为多边形是闭合的)之间的距离
  • 在每条边的中点位置创建MapLabel来显示长度
  • 在多边形顶点编辑(insert_at/set_at)时,同步更新面积和所有边的长度标签

修改后的完整代码

var labels = []; 
var allOverlays = []; 
var selectedShape;

function setSelection(shape) { 
  selectedShape = shape; 
  shape.setEditable(true); 
} 

function initMap() { 
  var options = { 
    zoom: 14, 
    center: {lat: 52.250618, lng: 20.9774} 
  } 
  var map = new google.maps.Map(document.getElementById('map'), options); 

  var drawingManager = new google.maps.drawing.DrawingManager({ 
    markerOptions: { draggable: false }, // 修正原代码拼写错误:markerOption → markerOptions
    polygonOptions: { 
      draggable: false, 
      fillColor: '#5C6BC0', 
      fillOpacity: 0.45, 
      strokeWeight: 2, // 增加边框宽度,方便定位边的位置
      editable: true, 
      zIndex: 1 
    }, 
    drawingControl: true, 
    drawingControlOptions: { 
      position: google.maps.ControlPosition.TOP_CENTER, 
      drawingModes: ['circle', 'polygon'] 
    }, 
    circleOptions: { 
      fillColor: '#5C6BC0', 
      fillOpacity: 0.45, 
      strokeWeight: 0, 
      editable: true, 
      zIndex: 1 
    }, 
    map: map 
  }); 

  // 新增:清理多边形的边标签
  function removeEdgeLabels(polygon) {
    if (polygon.edgeLabels) {
      polygon.edgeLabels.forEach(label => label.setMap(null));
      polygon.edgeLabels = [];
    }
  }

  // 新增:更新多边形的边长度标签
  function updateEdgeLengthLabels(polygon) {
    removeEdgeLabels(polygon);
    var path = polygon.getPath();
    var points = path.getArray();
    var edgeLabels = [];

    // 遍历所有边(包括最后一个点到第一个点的闭合边)
    for (var i = 0; i < points.length; i++) {
      var point1 = points[i];
      var point2 = points[(i + 1) % points.length]; // 处理闭合边逻辑

      // 计算边的长度(单位:米)
      var length = google.maps.geometry.spherical.computeDistanceBetween(point1, point2).toFixed(0);
      // 计算边的中点位置
      var midPoint = google.maps.geometry.spherical.interpolate(point1, point2, 0.5);

      // 创建边长度标签
      var edgeLabel = new MapLabel({
        map: map,
        fontSize: 16,
        align: 'center',
        text: length + 'm',
        position: midPoint,
        strokeColor: '#fff',
        strokeWeight: 2 // 增加白色描边,避免标签和背景混淆
      });
      edgeLabels.push(edgeLabel);
    }
    polygon.edgeLabels = edgeLabels;
  }

  function attachPolygonInfoWindow(polygon) { 
    var path = polygon.getPath(); 
    var points = path.getArray(); 
    var area = google.maps.geometry.spherical.computeArea(path.getArray()).toFixed(0); 
    var bounds = new google.maps.LatLngBounds(); 

    for (var i = 0; i < points.length; i++) { 
      bounds.extend(points[i]); 
    } 
    var boundsCenter = bounds.getCenter(); 

    // 更新面积标签
    removePolygonInfoWindow();
    var mapLabel = new MapLabel({ 
      map: map, 
      fontSize: 20, 
      align: 'left' 
    }); 
    labels.push(mapLabel); 
    showPolygonInfoWindow(labels, boundsCenter, area);

    // 更新边长度标签
    updateEdgeLengthLabels(polygon);
  } 

  function showPolygonInfoWindow(arr, position, text) { 
    arr.forEach((el) => { 
      el.set('position', position); 
      el.set('text', text + 'm²') // 修正单位符号:m2 → m²
    }) 
  } 

  function removePolygonInfoWindow() { 
    for (var i = 0; i < labels.length; i++) { 
      labels[i].setMap(null); 
    } 
    labels = []; 
  } 

  google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) { 
    allOverlays.push(e); 
    if (e.type != google.maps.drawing.OverlayType.MARKER) { 
      drawingManager.setDrawingMode(null); 
      var newShape = e.overlay; 
      newShape.type = e.type; 
      // 给多边形添加存储边标签的属性
      if (newShape.type === "polygon") {
        newShape.edgeLabels = [];
      }

      google.maps.event.addListener(newShape, 'click', function() { 
        setSelection(newShape); 
      }); 

      if (newShape.type == "polygon") { 
        var path = newShape.getPath(); 
        google.maps.event.addListener(path, 'insert_at', function() { 
          attachPolygonInfoWindow(newShape); 
        }); 
        google.maps.event.addListener(path, 'set_at', function() { 
          attachPolygonInfoWindow(newShape); 
        }); 
        attachPolygonInfoWindow(newShape); 
      } 
      setSelection(newShape); 
    } 
  }); 
} 

initMap(); 
<div id="map" style="width: 100%; height: 600px;"></div>
<script src="https://maps.google.com/maps/api/js?sensor=false&libraries=drawing,geometry"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/googlemaps/js-map-label/gh-pages/src/maplabel.js"></script>

关键修改点说明

  1. 新增updateEdgeLengthLabels函数:负责计算每条边的长度、获取中点,创建对应标签,同时会先清理该多边形之前的旧标签,避免重复显示。
  2. 多边形专属标签存储:给每个多边形添加edgeLabels属性,单独管理自己的边标签,不会和其他多边形的标签冲突。
  3. 精准中点计算:用google.maps.geometry.spherical.interpolate方法,传入两个顶点和0.5(表示中间位置),精准获取边的中点。
  4. 标签可读性优化:给边长度标签添加白色描边,避免和地图背景或多边形填充色混淆;同时修正了面积单位的符号,更规范。
  5. 原代码小错误修正:把markerOption改为正确的markerOptions,避免绘图管理器的marker配置失效。

现在你运行修改后的代码,绘制多边形或者编辑顶点时,不仅会显示面积,每条边的中点也会显示对应的长度啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:38:06