vue3使用百度地图API,实现租房的市区覆盖物

 在index.html中引入百度地图API

<script type="text/javascript" src="https://api.map.baidu.com/api?v=1.0&&type=webgl&ak=你的秘钥">

 在vue3中引用

<template>
  <div id="container" style="width: 100vw;height:100vh"></div> 
</template>

<script setup>
import {ref,onMounted,inject} from "vue"

let axios=inject("$axios")

const BMapGL = window.BMapGL;


onMounted(() => {
    getTu()
})

const getTu = () => {
    const cityname = JSON.parse(sessionStorage.getItem('cityName'))
    console.log(cityname);
    const name = cityname.name
    const code = cityname.code
    const map = new BMapGL.Map("container");
    //创建地址解析器实例
    var myGeo = new BMapGL.Geocoder();
    myGeo.getPoint(name, function (point) {
      if (point) {
        // 地图初始化,同时设置地图展示级别
        map.centerAndZoom(point, 11);
        // 5.添加控件
        const scaleCtrl = new BMapGL.ScaleControl();  // 添加比例尺控件
        map.addControl(scaleCtrl);
        const zoomCtrl = new BMapGL.ZoomControl();  // 添加缩放控件
        map.addControl(zoomCtrl);
        renderOverlays(code, map)
      }
    }, name)
  }
   // 房源覆盖物的样式
   const labelStyle =ref( {
    border: 0,
    background: "rgba(12, 181, 106, 0.9)",
    color: 'black'
  })
  // 封装渲染房源覆盖物的方法
  const renderOverlays = async (code,map) => {
    // 调用接口获取房源数据
    // console.log(code,map);
    const {data} = await axios.get('http://shiyansong.cn:8080/area/map?id=' + code);
    console.log(data);
    const { type, nextZoom } = getTypeAndZoom(map);
    data.body.forEach(item => {
      createOverlays(item, type, nextZoom, map)
    })
  }
  // 封装计算类型和获取地图缩放级别的方法
  const getTypeAndZoom = (map) => {
    // 获取当前地图的缩放级别
    // let map = new BMapGL.Map("container");
    const zoom = map.getZoom();
    // console.log(1, zoom)
    let type, nextZoom;
    if (zoom >= 0 && zoom < 12) { // 区
      type = 'circle'
      // 下一次的缩放级别
      nextZoom = 13;
    } else if (zoom >= 12 & zoom < 14) { // 镇
      type = 'circle'
      // 下一次的缩放级别
      nextZoom = 15;
    } else if (zoom >= 14 && zoom < 16) { // 小区
      type = 'rect';
    }
    return { type, nextZoom, map }
  }
   // 封装创建覆盖物的方法
   const createOverlays = (data, type, zoom, map) => {
    // 为每一条数据创建房源覆盖物
    const { label: areaName, value, coord: { longitude, latitude }, count } = data;
    // 根据指定经纬度创建坐标点
    const areaPoint = new BMapGL.Point(longitude, latitude)
    if (type === 'circle') { // 区、镇
      createCircle(areaPoint, areaName, value, count, zoom, map)
    } else {
      createRect(areaPoint, areaName, value, count, map);
    }
  }
  
  // 创建区镇的覆盖物
  const createCircle = (areaPoint, areaName, value, count, zoom, map) => {
    // 1. 创建文房源覆盖物
    const label = new BMapGL.Label('', { // 创建文本儿标注
      position: areaPoint, // 设置文本标注的坐标
      offset: new BMapGL.Size(10, 20) // 设置文本标注的偏移量
    })
    // 2. 给label对象添加一个唯一标识
    label.id = value;
    // 3. 调用setContent方法设置文本标注的内容
    label.setContent(`
      <div class="bubble">
        <p class="name">${areaName}</p>
        <p>${count}套</p>
      </div>
    `)
    // 4. 将标注添加到地图中
    map.addOverlay(label);
    // 5. 修改文本标注的样式
    label.setStyle(labelStyle.value)
    // 6.监听标注事件
    label.addEventListener('click', () => {
      renderOverlays(label.id, map)
      // 7. 以当前点为中心放大地图
      map.centerAndZoom(areaPoint, zoom)
      // 8. 调用clearOverlay方法清除所有覆盖物
      map.clearOverlays();
    })
  }
  // 创建小区的覆盖物
  const createRect = (areaPoint, areaName, value, count, map) => {
    // 1. 创建文房源覆盖物
    const label = new BMapGL.Label('', { // 创建文本儿标注
      position: areaPoint, // 设置文本标注的坐标
      offset: new BMapGL.Size(10, 20) // 设置文本标注的偏移量
    })
    // 2. 调用setContent方法设置文本标注的内容
    label.setContent(`
        <div class="housewrapper">
          <span class="housename">${areaName}</span>
          <span class="housecount">${count}套</span>
          <i class="arrow"></i>
        </div>
      `)
    // 3. 将标注添加到地图中
    map.addOverlay(label);
    // 4. 修改文本标注的样式
    label.setStyle(labelStyle.value)
    // 5.监听标注事件
    label.addEventListener('click', (ev) => {
      console.log('点击了小区的覆盖物')
      getHouseList(value)
      // 获取到经纬度
      const { lng, lat } = ev.target.point.latLng;
      // 将经纬度转换成像素坐标
      const { x, y } = map.pointToPixel(new BMapGL.Point(lng, lat))
      // 调用panBy方法移动地图到中心位置
      map.panBy(
        (window.innerWidth / 2) - x,
        (window.innerHeight - 330) / 2 - y
      )
    })
    // 给地图添加移动事件隐藏房源列表
    map.addEventListener('movestart', () => {
      setIsShow(false);
    })
  }
   // 封装获取小区的房源数据的方法
   const getHouseList = async id => {
    const {data} = await axios.get('http://shiyansong.cn:8080/houses?cityId=' + id);
    // setHouseList(data.body.list)
    // 将isShow的值设置成true,执行动画显示房源列表
    // setIsShow(true)
  }
   // 封装渲染小区房源数据的方法
   const renderHouseList = () => {
    // return (
    //   houseList.map(item => (
    //     <li className='house-list-item' key={item.houseCode}>
    //       <img src={"http://shiyansong.cn:8080" + item.houseImg} alt="" />
    //       <div className="right">
    //         <h3 className="title">{item.title}</h3>
    //         <div className="desc">{item.desc}</div>
    //         {
    //           item.tags.map((tag, index) => (
    //             <span key={tag} className={['tag', 'tag' + (index + 1)].join(' ')}>{tag}</span>
    //           ))
    //         }
    //         <div className="price-wrapper">
    //           <span className='price'>{item.price}</span>
    //           <span>元/月</span>
    //         </div>
    //       </div>
    //     </li>
    //   ))
    // )
  }


</script>

<style lang="scss" scoped>
.map-wrapper {
    height: 100%;
    display: flex;
    flex-direction: column;
  
    .container {
      flex: 1;
    }
  }
  
  .bubble {
    display: inline-block;
    position: absolute;
    width: 70px;
    height: 70px;
    background: rgba(12, 181, 106, 0.9);
    border: 2px solid #fff;
    border-radius: 50%;
    font-size: 12px;
    text-align: center;
    line-height: 1;
    overflow: hidden;
  
    .name {
      padding: 18px 0 6px
    }
  }
  .housewrapper {
    position: absolute;
    padding: 0 3px;
    width: 100px;
    height: 20px;
    line-height: 19px;
    background:rgba(12, 181, 106, 0.9);
    border-radius: 3px;
    text-align: center;
    .housename {
        display: inline-block;
        width: 70px;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        vertical-align: middle;
    }
    .housecount {
        display: inline-block;
        width: 20px;
    }
    .arrow {
        display: block;
        margin: 0 auto;
        width: 0;
        height: 0;
        border: 4px solid transparent;
        border-top-color: #00a75b;
    }
  }
  // 小区房源列表
  .house-container {
    position: fixed;
    bottom: 0;
    left: 0;
    z-index: 99;
    display: flex;
    flex-direction: column;
    width: 100%;
    max-height: 330px;
    transform: translate3d(0, 100%, 0);
    background: #fff;
    transition: all 1s;
    &.show-house {
        transform: translate3d(0, 0, 0);
    }
    .house-title-wrapper {
        padding: 0 10px;
        height: 44px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        background: #C0C0C2;
        h3 {
            font-size: 16px;
        }
        span {
            padding-right: 5px;
            color: #1e1e1e;
        }
    }
    .house-list-wrapper {
        flex: 1;
        overflow: auto;
        .house-list {
            padding: 0 10px;
            .house-list-item {
                padding: 20px 0;
                display: flex;
                border-bottom: 1px solid #e5e5e5;
                img {
                    width: 106px;
                    height: 80px;
                }
                .right {
                    margin-left: 10px;
                    flex: 1;
                    overflow: hidden;
                    .title {
                        overflow: hidden;
                        white-space: nowrap;
                        text-overflow: ellipsis;
                        color: #394043;
                    }
                    .desc {
                        margin: 5px 0;
                        font-size: 12px;
                        color: #afb2b3;
                    }
                    .tag {
                        padding: 4px 5px;
                        margin-right: 5px;
                        font-size: 12px;
                        border-radius: 2px;
                        &.tag1 {
                            background: #e1f5f8;
                            color: #39becd;
                        }
                        &.tag2 {
                            background: #e1f5fd;
                            color: #3fc28c;
                        }
                        &.tag3 {
                            background: #e6f2ff;
                            color: #5aabfd;
                        }
                    }
                    .price-wrapper {
                        margin-top: 5px;
                        color: #fa5741;
                        .price {
                            font-size: 16px;
                            font-weight: bolder;
                        }
                    }
                }
            }
        }
    }
  }

</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值