如何用PHP+MySQL实现经纬度相同的Google Maps标记在同一info_window展示
问题根源
- 现有逻辑为每一条数据库记录生成独立标记,相同经纬度的标记会完全重叠,点击时仅能触发最上层标记的点击事件
markers数组和infoWindowContent数组索引不匹配,infoWindowContent仅包含存在重复的坐标记录,会导致点击非重复坐标的标记时出现内容错位甚至报错- 没有对相同经纬度的地点信息做合并处理,自然无法在同一个信息窗口展示全部数据
修复方案
在PHP侧先按经纬度分组,将相同坐标的所有地点信息整合,每个经纬度仅生成一个标记,对应信息窗口拼接该坐标下所有地点的内容。
修改后的完整代码
PHP部分
<?php require_once "dbcon.php"; // 按经纬度分组,整合同坐标所有地点数据 $locationsByCoord = []; $result = $conn->query("SELECT * FROM locations"); if($result->num_rows > 0){ while($row = $result->fetch_assoc()){ $coordKey = $row['latitude'] . '_' . $row['longitude']; if(!isset($locationsByCoord[$coordKey])){ $locationsByCoord[$coordKey] = [ 'lat' => $row['latitude'], 'lng' => $row['longitude'], 'icon' => $row['icon'], // 同坐标可统一用同一个图标,有特殊需求可自行调整 'items' => [] ]; } $locationsByCoord[$coordKey]['items'][] = [ 'name' => $row['name'], 'info' => $row['info'] ]; } } ?>
Javascript部分
<script> function initMap() { var map; var bounds = new google.maps.LatLngBounds(); var mapOptions = { mapTypeId: 'roadmap' }; // 初始化地图 map = new google.maps.Map(document.getElementById("mapCanvas"), mapOptions); map.setTilt(100); // 整合后的标记和信息窗口内容 var markers = [ <?php foreach($locationsByCoord as $coord){ $itemsHtml = ''; foreach($coord['items'] as $item){ $itemsHtml .= '<h3>'.addslashes($item['name']).'</h3><p>'.addslashes($item['info']).'</p>'; } $infoContent = '<div class="info_content">'.$itemsHtml.'</div>'; echo '["'.addslashes($infoContent).'", '.$coord['lat'].', '.$coord['lng'].', "'.$coord['icon'].'"],'; } ?> ]; // 添加标记到地图 var infoWindow = new google.maps.InfoWindow(), marker, i; for( i = 0; i < markers.length; i++ ) { var position = new google.maps.LatLng(markers[i][1], markers[i][2]); bounds.extend(position); marker = new google.maps.Marker({ position: position, map: map, icon: markers[i][3], title: '共' + markers.length + '个地点' // 可自定义鼠标悬浮提示 }); // 绑定点击事件 google.maps.event.addListener(marker, 'click', (function(marker, i) { return function() { infoWindow.setContent(markers[i][0]); infoWindow.open(map, marker); } })(marker, i)); map.fitBounds(bounds); } // 设置缩放级别 var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) { this.setZoom(14); google.maps.event.removeListener(boundsListener); }); } google.maps.event.addDomListener(window, 'load', initMap); </script>
注意事项
- 代码中使用
addslashes转义地点名称和描述内容,避免特殊字符导致JS语法错误,如果内容包含HTML标签可根据需求调整转义逻辑 - 同坐标的标记图标默认取该分组第一条记录的图标,如有不同需求可自行修改分组逻辑
- 如果需要区分同坐标的不同地点,可在信息窗口中添加编号、分类等标识
内容的提问来源于stack exchange,提问作者Joenel Espejo
相关产品推荐
相关产品推荐

