企业官网里,"联系我们"页要显示公司位置、连锁门店页要展示附近门店、外卖型网站要计算配送距离——这些都离不开地图能力。国内常用的高德地图、百度地图都提供了完善的 JS SDK 和 Web 服务 API,集成并不复杂,但要想用得顺手,得理清几个核心概念:地图渲染、地理编码、逆地理编码、周边搜索。本篇带你逐一打通。
一、地图渲染与标注
地图集成的第一步是把地图"画"到页面上。以高德地图为例,引入 JS SDK 后,创建一个容器 div,用 AMap.Map 初始化地图实例,设置中心点和缩放级别。然后在地图上添加标注点(Marker)标记公司位置,点击标注弹出信息窗口展示地址详情。
<!-- 引入高德地图JS API -->
<script src="https://webapi.amap.com/maps?v=2.0&key=你的key"></script>
<div id="mapContainer" style="width:100%;height:420px"></div>
<script>
// 初始化地图,中心点为尧图公司坐标
const map = new AMap.Map('mapContainer', {
zoom: 16, // 缩放级别(3-18)
center: [113.685221, 34.753968], // 经纬度:郑州航海东路
mapStyle: 'amap://styles/whitesmoke' // 浅色主题,配合国风页面
});
// 添加标注点
const marker = new AMap.Marker({
position: [113.685221, 34.753968],
title: '郑州尧图企业管理咨询有限公司'
});
map.add(marker);
// 点击标注弹出信息窗
const info = new AMap.InfoWindow({
content: '<div style="padding:12px">' +
'<h4>尧图网站开发</h4>' +
'<p>地址:河南省郑州市航海东路1346号A座</p>' +
'<p>电话:0371-8888-6677</p>' +
'</div>',
offset: new AMap.Pixel(0, -30)
});
marker.on('click', () => info.open(map, marker.getPosition()));
</script>
地图样式要与网站整体风格协调。尧图在国风主题站点里偏好用浅色地图底图(whitesmoke),避免鲜艳的默认底图喧宾夺主。另外,移动端地图要处理触摸交互——默认拖动地图会与页面滚动冲突,可以设 touchZoom: true、dragEnable: true 让用户主动操作地图时才响应手势。
二、地理编码与逆地理编码
地理编码是把"文字地址"转换成"经纬度坐标",逆地理编码则相反。这两个能力在门店管理后台特别有用:运营人员录入门店地址后,系统自动转成坐标存库,前端展示时直接用坐标定位,无需手动标注。尧图的门店管理模块就是这么做的。
// 地理编码:地址 → 坐标
function addressToCoord(address) {
return new Promise((resolve) => {
const geocoder = new AMap.Geocoder({ city: '郑州' });
geocoder.getLocation(address, (status, result) => {
if (status === 'complete' && result.geocodes.length) {
const { lng, lat } = result.geocodes[0].location;
resolve({ lng, lat }); // 返回坐标
} else {
resolve(null); // 解析失败
}
});
});
}
// 逆地理编码:坐标 → 地址
function coordToAddress(lng, lat) {
return new Promise((resolve) => {
const geocoder = new AMap.Geocoder();
geocoder.getAddress([lng, lat], (status, result) => {
if (status === 'complete' && result.regeocode) {
resolve(result.regeocode.formattedAddress);
}
});
});
}
// 后台录入门店:地址自动转坐标
async function saveStore(name, address) {
const coord = await addressToCoord(address);
if (!coord) return fail('地址解析失败,请检查地址是否准确');
db.insert('stores', {
name, address,
lng: coord.lng,
lat: coord.lat
});
return success('门店已保存');
}
地理编码的准确度取决于地址的规范程度。"航海东路1346号A座"能精确定位,但只填"航海东路附近"可能解析到整条路的随机位置。尧图建议录入时引导用户填到门牌号,并在解析后回显地图标注让用户确认,避免坐标偏差。
三、周边搜索与导航跳转
门店列表页常需要"搜索附近门店"功能。做法是先获取用户当前位置(浏览器 navigator.geolocation),再用地图 API 的周边搜索能力找出指定半径内的门店,按距离排序展示。点击门店可直接跳转到地图 App 导航。
// 获取用户位置并搜索附近门店
async function findNearbyStores() {
// 1. 获取用户当前位置
const position = await new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject);
});
const userLng = position.coords.longitude;
const userLat = position.coords.latitude;
// 2. 查询数据库中所有门店,计算距离
const stores = db.query('SELECT * FROM stores');
const nearby = stores.map(store => {
const distance = getDistance(userLat, userLng, store.lat, store.lng);
return { ...store, distance };
}).filter(s => s.distance <= 5000) // 5公里内
.sort((a, b) => a.distance - b.distance);
return nearby;
}
// 两点距离计算(Haversine公式,单位:米)
function getDistance(lat1, lng1, lat2, lng2) {
const R = 6371000; // 地球半径(米)
const dLat = (lat2 - lat1) * Math.PI / 180;
const dLng = (lng2 - lng1) * Math.PI / 180;
const a = Math.sin(dLat/2)**2 +
Math.cos(lat1*Math.PI/180) * Math.cos(lat2*Math.PI/180) *
Math.sin(dLng/2)**2;
return Math.round(R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)));
}
// 点击门店跳转高德导航
function navigateTo(lng, lat) {
window.location.href =
`https://uri.amap.com/navigation?to=${lng},${lat},尧图门店&mode=car`;
}
获取用户位置需要 HTTPS 环境且用户授权,尧图建议加一个"手动选择城市"的兜底入口——用户拒绝授权或浏览器不支持时,仍能通过选择城市查看门店。导航跳转用高德的 URI 协议,会自动唤起手机上的地图 App,比内嵌导航体验更好。这些地图能力的组合运用,能让企业官网的"线下连接"能力大幅提升。