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

Google Map绘制图形下载不完整问题求助(JS+PHP实现)

问题:Google地图下载的多边形无法闭合

我使用Google Map JavaScript API在地图上绘制多边形,通过downloadMap函数下载绘制区域。整体功能正常,但下载的图形无法闭合所有顶点,几乎所有创建的形状都出现该情况。

问题原因

Google静态地图API的path参数要求多边形的起点和终点必须完全相同,才能正确渲染闭合的多边形。当前代码仅提取了多边形的所有顶点,但没有将第一个顶点重复添加到路径末尾,导致静态地图无法识别为闭合图形。

修复方案

在构建静态地图的path参数时,手动将多边形的第一个顶点追加到路径数组的最后,确保起点与终点一致。

修改后的核心代码

重点修改downloadMap函数中处理多边形路径的部分:

function downloadMap() {
  var center = map.getCenter();
  var zoom = map.getZoom();
  var scale = 2;
  var size = map.getDiv().clientWidth + 'x' + map.getDiv().clientHeight;
  var mapTypeId = map.getMapTypeId();

 var url = 'https://maps.googleapis.com/maps/api/staticmap?key=KEY&center=' + center.lat() + ',' + center.lng() + '&zoom=' + zoom + '&size=' + size + '&scale=' + scale + '&maptype=' + mapTypeId;

  // Add polygons to the URL
  for (var i = 0; i < shapes.length; i++) {
    if (shapes[i].type === google.maps.drawing.OverlayType.POLYGON) {
      var path = shapes[i].getPath();
      var polygons = [];

      for (var j = 0; j < path.getLength(); j++) {
        polygons.push(path.getAt(j).toUrlValue());
      }

      // 修复:添加第一个顶点到末尾,确保多边形闭合
      if (polygons.length > 0) {
        polygons.push(polygons[0]);
        url += '&path=' + polygons.join('|');
      }
    }
  }

  fetch(url)
    .then(response => response.blob())
    .then(blob => {
      const form = new FormData();
      form.append('image', blob, 'map.png');

      // Send image data to server to save it
      fetch('save_map.php', {
        method: 'POST',
        body: form
      })
      .then(response => response.text())
      .then(result => console.log(result))
      .catch(error => console.error(error));
    })
    .catch(error => console.error(error));
}

完整代码示例

JavaScript代码

var map;
var drawingManager;
var selectedShape;
var shapes = [];

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 0, lng: 0},
    zoom: 2
  });

  drawingManager = new google.maps.drawing.DrawingManager({
    drawingControlOptions: {
      position: google.maps.ControlPosition.TOP_CENTER,
      drawingModes: ['polygon']
    }
  });

  drawingManager.setMap(map);

  google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
    if (e.type != google.maps.drawing.OverlayType.MARKER) {
      drawingManager.setDrawingMode(null);

      var newShape = e.overlay;
      newShape.type = e.type;
      shapes.push(newShape);

      selectedShape = newShape;

      var area = google.maps.geometry.spherical.computeArea(selectedShape.getPath());
      $('#area').text('Area: ' + area.toFixed(2) + ' sq m');

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

  $('#clear').click(function() {
    clearSelection();
    clearShapes();
    $('#area').text('');
  });

  $('#download').click(function() {
    downloadMap();
  });

  google.maps.event.addListenerOnce(map, 'idle', function() {
    downloadMap();
  });
}

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

function clearSelection() {
  if (selectedShape) {
    selectedShape.setEditable(false);
    selectedShape = null;
  }
}

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

function downloadMap() {
  var center = map.getCenter();
  var zoom = map.getZoom();
  var scale = 2;
  var size = map.getDiv().clientWidth + 'x' + map.getDiv().clientHeight;
  var mapTypeId = map.getMapTypeId();

 var url = 'https://maps.googleapis.com/maps/api/staticmap?key=KEY&center=' + center.lat() + ',' + center.lng() + '&zoom=' + zoom + '&size=' + size + '&scale=' + scale + '&maptype=' + mapTypeId;

  for (var i = 0; i < shapes.length; i++) {
    if (shapes[i].type === google.maps.drawing.OverlayType.POLYGON) {
      var path = shapes[i].getPath();
      var polygons = [];

      for (var j = 0; j < path.getLength(); j++) {
        polygons.push(path.getAt(j).toUrlValue());
      }

      // 确保多边形闭合:重复第一个顶点到末尾
      if (polygons.length > 0) {
        polygons.push(polygons[0]);
        url += '&path=' + polygons.join('|');
      }
    }
  }

  fetch(url)
    .then(response => response.blob())
    .then(blob => {
      const form = new FormData();
      form.append('image', blob, 'map.png');

      fetch('save_map.php', {
        method: 'POST',
        body: form
      })
      .then(response => response.text())
      .then(result => console.log(result))
      .catch(error => console.error(error));
    })
    .catch(error => console.error(error));
}

CSS代码

html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
#map {
  height: 100%;
}

HTML代码

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=drawing"></script>

<div id="map"></div>
<div id="area"></div>
<button id="clear">Clear</button>
<button id="download">Download</button>

PHP保存代码(save_map.php)

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $image = $_FILES['image'];
  $directory = 'maps';
  if (!file_exists($directory)) {
    mkdir($directory, 0777, true);
  }
  $filename = $directory . '/map_' . time() . '.png';

  if (move_uploaded_file($image['tmp_name'], $filename)) {
    echo 'Map saved successfully.';
  } else {
    echo 'Error saving map.';
  }
} else {
  echo 'Invalid request.';
}
?>

内容的提问来源于stack exchange,提问作者TSCAmerica.com

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 08:35:32