如何在Google Maps API v3中创建指定米级尺寸的网格
实现按指定尺寸(米)生成Google Maps网格
要实现指定网格尺寸(如5米)的功能,核心是将米数转换成对应位置的经纬度差值(不同纬度下,经度1度对应的实际距离不同),再基于这个差值计算网格数量并生成网格。以下是具体实现方案和代码修改:
关键工具函数
首先实现工具函数,计算指定位置上,指定米数对应的经纬度差值:
// 计算指定位置下,X米对应的经度/纬度差值 function getLatLngDeltaInMeters(position, meters) { // 计算纬度方向偏移meters后的坐标 var latOffset = google.maps.geometry.spherical.computeOffset(position, meters, 0); // 计算经度方向偏移meters后的坐标 var lngOffset = google.maps.geometry.spherical.computeOffset(position, meters, 90); return { latDelta: Math.abs(latOffset.lat() - position.lat()), lngDelta: Math.abs(lngOffset.lng() - position.lng()) }; }
注意:加载Google Maps API时需引入几何库,URL需加上
&libraries=geometry参数,例如:<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"></script>
修改用户输入逻辑
更新addSecondMarker函数,替换原有的网格数量输入,改为让用户输入网格的宽度和高度(单位:米):
function addSecondMarker(location) { marker2 = new google.maps.Marker({ position: location, map: map, title: 'Target Location' }); markers.push(marker2); // 让用户输入网格尺寸 var gridWidth = prompt("Enter grid width in meters (e.g., 5):"); gridWidth = parseFloat(gridWidth); var gridHeight = prompt("Enter grid height in meters (e.g., 5):"); gridHeight = parseFloat(gridHeight); if (isNaN(gridWidth) || gridWidth <= 0 || isNaN(gridHeight) || gridHeight <= 0) { alert("Invalid input. Please enter positive numbers for grid dimensions."); return; } updateButtonClasses("grid_generation", "btn-success", "btn-success"); makeGridBySize(gridWidth, gridHeight); gridGenerated = true; }
实现按尺寸生成网格的函数
新增makeGridBySize函数,替代原makeGrid函数实现按指定尺寸生成网格:
function makeGridBySize(gridWidthMeters, gridHeightMeters) { if (markers.length < 2) { alert("Please add at least two markers before creating the grid."); return; } var bounds = new google.maps.LatLngBounds(); markers.forEach(function(marker) { bounds.extend(marker.getPosition()); }); // 取区域中心点作为基准计算经纬度差值 var center = bounds.getCenter(); var latLngDelta = getLatLngDeltaInMeters(center, 1); // 计算每个网格对应的经纬度差 var gridLatDelta = gridHeightMeters * latLngDelta.latDelta; var gridLngDelta = gridWidthMeters * latLngDelta.lngDelta; // 计算区域内可容纳的网格行列数 var totalLatDist = bounds.getNorthEast().lat() - bounds.getSouthWest().lat(); var totalLngDist = bounds.getNorthEast().lng() - bounds.getSouthWest().lng(); var rowCount = Math.floor(totalLatDist / gridLatDelta); var colCount = Math.floor(totalLngDist / gridLngDelta); // 确保至少有一行一列 rowCount = rowCount <= 0 ? 1 : rowCount; colCount = colCount <= 0 ? 1 : colCount; // 添加起始标记 fixedMarker = new google.maps.Marker({ position: new google.maps.LatLng(bounds.getNorthEast().lat() - (gridLatDelta / 2), bounds.getSouthWest().lng() + (gridLngDelta / 2)), map: map, title: 'Start Point', label: { color: 'white', fontWeight: 'bold', text: 'Start Point', }, }); // 生成网格矩形 for (var i = 0; i < rowCount; i++) { for (var j = 0; j < colCount; j++) { var buttonBounds = new google.maps.LatLngBounds( new google.maps.LatLng(bounds.getNorthEast().lat() - (gridLatDelta * (i + 1)), bounds.getSouthWest().lng() + (gridLngDelta * j)), new google.maps.LatLng(bounds.getNorthEast().lat() - (gridLatDelta * i), bounds.getSouthWest().lng() + (gridLngDelta * (j + 1))) ); rectangle = new google.maps.Rectangle({ strokeOpacity: 0.3, strokeWeight: 1, fillOpacity: 0, map: map, bounds: buttonBounds }); attachRectangleClickEvent(rectangle, bounds.getNorthEast().lat() - (gridLatDelta * i) - gridLatDelta / 2, bounds.getSouthWest().lng() + (gridLngDelta * j) + gridLngDelta / 2); } } marker1.setMap(null); marker2.setMap(null); }
兼容两种模式(可选)
如果需要同时支持“输入网格数量”和“指定网格尺寸”两种模式,可在addSecondMarker中增加选择逻辑:
function addSecondMarker(location) { // 原有创建marker2的代码... marker2 = new google.maps.Marker({ position: location, map: map, title: 'Target Location' }); markers.push(marker2); var mode = prompt("Choose grid generation mode:\n1. Enter grid quantity (e.g., 3 for 3x3)\n2. Enter grid size in meters"); if (mode === "1") { // 原有按数量生成的逻辑 var quantity = prompt("Enter the quantity for the grid (e.g., 3 for a 3x3 grid):"); quantity = parseInt(quantity); if (isNaN(quantity) || quantity <= 0) { alert("Invalid input. Please enter a positive number."); return; } makeGrid(quantity); } else if (mode === "2") { // 按尺寸生成的逻辑 var gridWidth = prompt("Enter grid width in meters (e.g., 5):"); gridWidth = parseFloat(gridWidth); var gridHeight = prompt("Enter grid height in meters (e.g., 5):"); gridHeight = parseFloat(gridHeight); if (isNaN(gridWidth) || gridWidth <= 0 || isNaN(gridHeight) || gridHeight <= 0) { alert("Invalid input. Please enter positive numbers."); return; } makeGridBySize(gridWidth, gridHeight); } else { alert("Invalid mode selection."); return; } updateButtonClasses("grid_generation", "btn-success", "btn-success"); gridGenerated = true; }
内容的提问来源于stack exchange,提问作者Vinayak M
相关产品推荐
相关产品推荐

