【vue-baidu-map】自动填充搜索显示信息窗

该文描述了一个使用BMapAPI在Vue应用中实现的功能,包括地图初始化、点击获取经纬度、逆地址解析以填充搜索框,以及在搜索后弹出信息窗口显示经纬度坐标。用户可以点击地图上的任意位置,或者通过搜索关键字来获取地理位置信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自动填充搜索显示信息窗

 

需求

1. 点击地图任一点展示信息窗

2. 自动填充搜索调用逆地址解析,匹配到的点弹出信息窗。

实现

第一步:初始化数据

data() {
  return {
    point:null,
    BMap: null,
    map: null,

    keyword: '',
    infoWindowShow:false,
    longitude:'',
    latitude:'',
  };
},

第二步:地图初始化、搜索、获取经纬度、信息窗口

//地图初始化
mapReady({ BMap, map }) {
  this.BMap=BMap
  this.map=map
  this.point = new BMap.Point(113.27, 23.13); // 选择一个经纬度作为中心点
  map.centerAndZoom(this.point, 12); //设置地图中心点和缩放级别
},

//逆地址解析
search() {
  let myGeo = new this.BMap.Geocoder()
  myGeo.getPoint(this.keyword,(point)=>{
    if(point){
      this.map.centerAndZoom(point,15)
      this.latitude=point.lat
      this.longitude=point.lng
      this.infoWindowShow=true
    }
  })
},

//点击获取经纬度
getLocation(e){
  this.longitude=e.point.lng
  this.latitude=e.point.lat
  this.infoWindowShow=true
},

//信息窗口关闭
infoWindowClose(){
  this.latitude=''
  this.longitude=''
  this.infoWindowShow=false
},

第三步:设置样式

.search-view {
  width: 300px;
  height: 300px;
  margin-top: 50px;
}
.search-box {
  display: flex;
  align-items: center;
}
.complete {
  width: 210px;
  margin-right:15px
}

第四步:搜索框和弹窗

<baidu-map class="search-view"  @ready="mapReady" @click="getLocation">
  <!-- 搜索框 -->
  <bm-control :offset="{width: '10px', height: '10px'}">
    <bm-auto-complete v-model="keyword" :sugStyle="{zIndex: 999999}">
      <el-input class="complete" v-model="keyword"></el-input>
    </bm-auto-complete>
    <el-button type="primary" @click="search">搜索</el-button>
  </bm-control>

  <!-- 弹框 -->
  <bm-info-window :position="{lng: longitude, lat: latitude}" :show="infoWindowShow" @clickclose="infoWindowClose">
      <p>纬度:{{this.latitude}}</p>
      <p>经度:{{this.longitude}}</p>
  </bm-info-window>
</baidu-map>

<think>好的,用户想做一个基于Vue2和ElementUI的网页,调用百度地图API实现开车和步行的导航规划,支持手动输入和点击地图选择起点终点,后端用Spring Boot和MySQL,还要坐标转换和样式优化。页面布局要左边表单,右边地图,整体美观。 首先,得确认百度地图API的接入步骤。用户需要注册百度开发者账号,创建应用获取AK密钥,这对前端调用API是必须的。然后,前端部分需要引入百度地图的JS库,在Vue中初始化地图。考虑到Vue2,可能需要用到vue-baidu-map这个第三方库,或者直接通过script标签引入。不过用户可能更倾向于直接使用原生的方式,避免额外的依赖。 接下来是页面布局。使用ElementUI的布局组件,比如el-row和el-col,左边表单占4份,右边地图占20份,这样左右结构就出来了。表单部分需要两个输入框,分别绑定起点和终点,以及一个下拉选择导航方式,还有按钮触发导航。同时,点击地图的事件处理,获取点击的经纬度,并转换为地址名称,填充到起点或终点输入框中。这里可能需要逆地理编码服务。 坐标转换的问题,因为百度地图用的是BD09坐标系,而标准的GPS坐标是WGS84,如果需要从其他来源获取坐标并显示在地图上,就得转换。不过如果数据全部来自百度地图本身,可能不需要转换。但用户提到要详细实现坐标转换,可能需要集成一个转换工具,比如使用第三方库coordtransform,或者在后端处理转换逻辑。 后端部分,Spring Boot需要提供保存历史记录和坐标转换的接口。数据库设计可能需要一个表来存储起点、终点、导航方式、时间等信息。JPA或者MyBatis都可以,这里用JPA更快捷。坐标转换的接口接收原始坐标和目标类型,返回转换后的结果,可能需要调用百度官方的转换API,或者使用算法自行转换,但要注意合规性。 前端的地图样式优化,可以使用百度地图的自定义样式功能,调整地图的颜色、标签显示等,使界面更美观。同时,路线规划的结果需要用不同的颜色区分开车和步行,添加信息口显示详细信息。 代码部分,前端的核心是初始化地图,处理点击事件,调用路线规划服务,绘制路线覆盖物。后端则需要处理坐标转换和历史记录的存储。需要注意异步请求的处理,比如使用axios发送请求,处理响应数据,更新前端状态。 测试环节,需要检查百度地图的AK是否正确,跨域问题是否解决,后端接口是否正常响应,数据库连接是否配置正确。前端的事件绑定是否正确,比如点击地图是否触发函数,路线绘制是否正常,样式是否应用成功。 可能遇到的问题包括:百度地图API的加载顺序,Vue组件生命周期中初始化地图的时机,坐标转换的准确性,路线规划服务的回调函数处理,以及前后端数据格式的一致性。需要逐一排查,确保各功能模块协同工作。 最后,页面美观方面,利用ElementUI的表单组件和布局,合理调整边距、颜色,使左右分区清晰,操作流畅。地图部分可能需要设置高度为100vh,或者固定高度,避免布局错乱。</think>我将分步骤为您构建这个系统。由于篇幅限制,这里展示核心代码实现(需根据实际AK和配置调整): 一、前端实现(Vue2 + ElementUI) ```vue <!-- MapContainer.vue --> <template> <el-row class="container"> <!-- 左侧控制面板 --> <el-col :span="4" class="control-panel"> <el-form label-width="80px"> <!-- 起点输入 --> <el-form-item label="起点"> <el-input v-model="startPoint" placeholder="点击地图选择或输入"> <el-button slot="append" @click="swapPoints">⇅</el-button> </el-input> </el-form-item> <!-- 终点输入 --> <el-form-item label="终点"> <el-input v-model="endPoint"></el-input> </el-form-item> <!-- 导航方式选择 --> <el-select v-model="routeType" placeholder="选择导航方式"> <el-option label="驾车" value="driving"></el-option> <el-option label="步行" value="walking"></el-option> </el-select> <!-- 操作按钮 --> <el-button type="primary" @click="planRoute">开始导航</el-button> <el-button @click="clearAll">清空</el-button> </el-form> <!-- 路线结果展示 --> <div class="route-result"> <h3>路线详情</h3> <div v-html="routeDetails"></div> </div> </el-col> <!-- 右侧地图容器 --> <el-col :span="20"> <div id="mapContainer" class="map-wrapper"></div> </el-col> </el-row> </template> <script> export default { data() { return { map: null, // 地图实例 startPoint: '', // 起点信息 endPoint: '', // 终点信息 routeType: 'driving', // 导航类型 routeDetails: '', // 路线详情 overlays: [] // 地图覆盖物 } }, mounted() { this.initBaiduMap() }, methods: { // 初始化地图 initBaiduMap() { const ak = '您的百度地图AK' // 需到百度地图开放平台申请 const script = document.createElement('script') script.src = `https://api.map.baidu.com/api?v=3.0&ak=${ak}&callback=initMap` document.head.appendChild(script) window.initMap = () => { this.map = new BMap.Map('mapContainer', { enableMapClick: false // 禁用默认底图点击 }) this.map.centerAndZoom(new BMap.Point(116.404, 39.915), 11) this.map.enableScrollWheelZoom(true) this.addMapControls() this.bindMapEvents() } }, // 添加地图控件 addMapControls() { this.map.addControl(new BMap.NavigationControl({ type: BMAP_NAVIGATION_CONTROL_LARGE })) this.map.addControl(new BMap.ScaleControl()) }, // 绑定地图事件 bindMapEvents() { // 地图点击事件 this.map.addEventListener('click', (e) => { this.reverseGeocode(e.point).then(address => { if (!this.startPoint) { this.startPoint = address } else { this.endPoint = address } }) }) }, // 路线规划 async planRoute() { this.clearOverlays() // 坐标转换(确保使用百度坐标系) const start = await this.geocode(this.startPoint) const end = await this.geocode(this.endPoint) const route = this.routeType === 'driving' ? new BMap.DrivingRoute(this.map, { renderOptions: { map: this.map, autoViewport: true } }) : new BMap.WalkingRoute(this.map, { renderOptions: { map: this.map, autoViewport: true } }) route.search(start, end) route.setSearchCompleteCallback(result => { if (route.getStatus() === BMAP_STATUS_SUCCESS) { this.processRouteResult(result) } }) }, // 处理路线结果 processRouteResult(result) { const plan = result.getPlan(0) this.routeDetails = ` <p>总距离:${plan.getDistance(true)}</p> <p>预计时间:${plan.getDuration(true)}</p> ` // 绘制路线 const route = plan.getRoute(0) this.map.addOverlay(new BMap.Polyline(route.getPath(), { strokeColor: this.routeType === 'driving' ? '#3388ff' : '#00cc66', strokeWeight: 4 })) }, // 坐标转换服务(WGS84转BD09) async convertCoordinate(lng, lat) { try { const res = await this.$http.post('/api/convert-coord', { lng, lat, from: 1, // 1:WGS84 to: 5 // 5:BD09 }) return new BMap.Point(res.data.lng, res.data.lat) } catch (error) { console.error('坐标转换失败:', error) } }, // 其他工具方法... } } </script> <style scoped> .container { height: 100vh; } .map-wrapper { height: 100vh; } .control-panel { padding: 20px; background: #f5f7fa; height: 100vh; overflow-y: auto; } .route-result { margin-top: 20px; padding: 15px; background: #fff; border-radius: 4px; } </style> ``` 二、后端实现(Spring Boot) 1. 坐标转换接口: ```java // CoordController.java @RestController @RequestMapping("/api") public class CoordController { @PostMapping("/convert-coord") public ResponseEntity<?> convertCoordinate( @RequestParam double lng, @RequestParam double lat, @RequestParam int from, @RequestParam int to) { // 调用百度坐标转换服务(需自行实现) Map<String, Double> result = CoordinateConverter.convert(lng, lat, from, to); return ResponseEntity.ok(result); } } // CoordinateConverter.java(示例算法) public class CoordinateConverter { private static final double X_PI = Math.PI * 3000.0 / 180.0; public static Map<String, Double> convert(double lng, double lat, int from, int to) { // 实际应调用百度官方坐标转换API // 这里演示WGS84转BD09的简单算法(精度有限,建议使用官方服务) double[] gcj = wgs84ToGcj02(lng, lat); double[] bd = gcj02ToBd09(gcj[0], gcj[1]); return Map.of("lng", bd[0], "lat", bd[1]); } private static double[] wgs84ToGcj02(double lng, double lat) { // 实现坐标转换算法... } private static double[] gcj02ToBd09(double lng, double lat) { double z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * X_PI); double theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * X_PI); return new double[]{ z * Math.cos(theta) + 0.0065, z * Math.sin(theta) + 0.006 }; } } ``` 三、数据库设计(MySQL) ```sql CREATE TABLE navigation_history ( id INT PRIMARY KEY AUTO_INCREMENT, start_point VARCHAR(255), end_point VARCHAR(255), route_type VARCHAR(20), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); ``` 四、优化建议: 1. 地图样式优化:使用百度地图个性化样式功能 ```javascript // 在初始化地图后添加: this.map.setMapStyleV2({ styleId: '您的自定义样式ID' // 通过百度地图控制台创建 }) ``` 2. 添加路线动画: ```javascript // 在绘制路线时添加: const polyline = new BMap.Polyline(path, { strokeColor: '#3388ff', strokeWeight: 4, enableEditing: false, enableClicking: false }) polyline.addEventListener('mouseover', () => { polyline.setStrokeColor('#ff0000') }) polyline.addEventListener('mouseout', () => { polyline.setStrokeColor('#3388ff') }) ``` 完整实现需要: 1. 申请百度地图开发者AK 2. 配置Spring Boot数据库连接 3. 添加异常处理 4. 实现完整的坐标转换服务 5. 配置前端代理解决跨域问题 建议分步骤实施: 1. 先完成基础地图显示 2. 实现点击选址功能 3. 添加路线规划 4. 集成坐标转换 5. 最后进行样式优化 遇到具体实现问题可进一步沟通调整代码细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宾果的救星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值