好客租房173-地图找房createCircle方法

简介: 好客租房173-地图找房createCircle方法

1复用之前创建覆盖物的代码逻辑

在覆盖物的单击事件中 调用renderOverLays(id)方法

图片.png

import React from 'react'
// 导入axios
import axios from 'axios'
// 导入封装好的 NavHeader 组件
import NavHeader from '../../components/NavHeader'
// 导入样式
// import './index.scss'
import styles from './index.module.css'
// 解决脚手架中全局变量访问的问题
const BMapGL = window.BMapGL
// 覆盖物样式
const labelStyle = {
  cursor: 'pointer',
  border: '0px solid rgb(255, 0, 0)',
  padding: '0px',
  whiteSpace: 'nowrap',
  fontSize: '12px',
  color: 'rgb(255, 255, 255)',
  textAlign: 'center'
}
export default class Map extends React.Component {
  componentDidMount() {
    this.initMap()
  }
  // 初始化地图
  initMap() {
    // 获取当前定位城市
    const { label, value } = JSON.parse(localStorage.getItem('hkzf_city'))
    // console.log(label, value)
    // 初始化地图实例
    const map = new BMapGL.Map('container')
    // 作用:能够在其他方法中通过 this 来获取到地图对象
    this.map = map
    // 创建地址解析器实例
    const myGeo = new BMapGL.Geocoder()
    // 将地址解析结果显示在地图上,并调整地图视野
    myGeo.getPoint(
      label,
      async point => {
        if (point) {
          //  初始化地图
          map.centerAndZoom(point, 11)
          // 添加常用控件
          map.addControl(new BMapGL.NavigationControl())
          map.addControl(new BMapGL.ScaleControl())
          // 调用 renderOverlays 方法
          this.renderOverlays(value)
          /* 
            渲染所有区覆盖物
          */
          /* const res = await axios.get(
            `http://localhost:8080/area/map?id=${value}`
          )
          res.data.body.forEach(item => {
            // 为每一条数据创建覆盖物
            const {
              coord: { longitude, latitude },
              label: areaName,
              count,
              value
            } = item
            // 创建坐标对象
            const areaPoint = new BMapGL.Point(longitude, latitude)
            // 创建覆盖物
            const label = new BMapGL.Label('', {
              position: areaPoint,
              offset: new BMapGL.Size(-35, -35)
            })
            // 给 label 对象添加一个唯一标识
            label.id = value
            // 设置房源覆盖物内容
            label.setContent(`
              <div class="${styles.bubble}">
                <p class="${styles.name}">${areaName}</p>
                <p>${count}套</p>
              </div>
            `)
            // 设置样式
            label.setStyle(labelStyle)
            // 添加单击事件
            label.addEventListener('click', () => {
              console.log('房源覆盖物被点击了', label.id)
              // 放大地图,以当前点击的覆盖物为中心放大地图
              map.centerAndZoom(areaPoint, 13)
              // 解决清除覆盖物时,百度地图API的JS文件自身报错的问题
              setTimeout(() => {
                // 清除当前覆盖物信息
                map.clearOverlays()
              }, 0)
            })
            // 添加覆盖物到地图中
            map.addOverlay(label)
          }) */
        }
      },
      label
    )
  }
  // 渲染覆盖物入口
  // 1 接收区域 id 参数,获取该区域下的房源数据
  // 2 获取房源类型以及下级地图缩放级别
  async renderOverlays(id) {
    const res = await axios.get(`http://localhost:8080/area/map?id=${id}`)
    // console.log('renderOverlays 获取到的数据:', res)
    const data = res.data.body
    // 调用 getTypeAndZoom 方法获取级别和类型
    const { nextZoom, type } = this.getTypeAndZoom()
    data.forEach(item => {
      // 创建覆盖物
      this.createOverlays(item, nextZoom, type)
    })
  }
  // 计算要绘制的覆盖物类型和下一个缩放级别
  // 区   -> 11 ,范围:>=10 <12
  // 镇   -> 13 ,范围:>=12 <14
  // 小区 -> 15 ,范围:>=14 <16
  getTypeAndZoom() {
    // 调用地图的 getZoom() 方法,来获取当前缩放级别
    const zoom = this.map.getZoom()
    let nextZoom, type
    // console.log('当前地图缩放级别:', zoom)
    if (zoom >= 10 && zoom < 12) {
      // 区
      // 下一个缩放级别
      nextZoom = 13
      // circle 表示绘制圆形覆盖物(区、镇)
      type = 'circle'
    } else if (zoom >= 12 && zoom < 14) {
      // 镇
      nextZoom = 15
      type = 'circle'
    } else if (zoom >= 14 && zoom < 16) {
      // 小区
      type = 'rect'
    }
    return {
      nextZoom,
      type
    }
  }
  // 创建覆盖物
  createOverlays(data, zoom, type) {
    const {
      coord: { longitude, latitude },
      label: areaName,
      count,
      value
    } = data
    // 创建坐标对象
    const areaPoint = new BMapGL.Point(longitude, latitude)
    if (type === 'circle') {
      // 区或镇
      this.createCircle(areaPoint, areaName, count, value, zoom)
    } else {
      // 小区
      this.createRect(areaPoint, areaName, count, value)
    }
  }
  // 创建区、镇覆盖物
  createCircle(point, name, count, id, zoom) {
    // 创建覆盖物
    const label = new BMapGL.Label('', {
      position: point,
      offset: new BMapGL.Size(-35, -35)
    })
    // 给 label 对象添加一个唯一标识
    label.id = id
    // 设置房源覆盖物内容
    label.setContent(`
      <div class="${styles.bubble}">
        <p class="${styles.name}">${name}</p>
        <p>${count}套</p>
      </div>
    `)
    // 设置样式
    label.setStyle(labelStyle)
    // 添加单击事件
    label.addEventListener('click', () => {
      // 调用 renderOverlays 方法,获取该区域下的房源数据
      this.renderOverlays(id)
      // 放大地图,以当前点击的覆盖物为中心放大地图
      this.map.centerAndZoom(point, zoom)
      // 解决清除覆盖物时,百度地图API的JS文件自身报错的问题
      setTimeout(() => {
        // 清除当前覆盖物信息
        this.map.clearOverlays()
      }, 0)
    })
    // 添加覆盖物到地图中
    this.map.addOverlay(label)
  }
  // 创建小区覆盖物
  /* 
    <div class="${styles.rect}">
      <span class="${styles.housename}">${name}</span>
      <span class="${styles.housenum}">${num}套</span>
      <i class="${styles.arrow}"></i>
    </div>
  */
  createRect(point, name, count, id) {
    // 创建覆盖物
    const label = new BMapGL.Label('', {
      position: point,
      offset: new BMapGL.Size(-50, -28)
    })
    // 给 label 对象添加一个唯一标识
    label.id = id
    // 设置房源覆盖物内容
    label.setContent(`
      <div class="${styles.rect}">
        <span class="${styles.housename}">${name}</span>
        <span class="${styles.housenum}">${count}套</span>
        <i class="${styles.arrow}"></i>
      </div>
    `)
    // 设置样式
    label.setStyle(labelStyle)
    // 添加单击事件
    label.addEventListener('click', () => {
      console.log('小区被点击了')
    })
    // 添加覆盖物到地图中
    this.map.addOverlay(label)
  }
  render() {
    return (
      <div className={styles.map}>
        {/* 顶部导航栏组件 */}
        <NavHeader>地图找房</NavHeader>
        {/* 地图容器元素 */}
        <div id="container" className={styles.container} />
      </div>
    )
  }
}

运行结果

图片.png

相关文章
|
Java
Java多线程父线程向子线程传值解决方案 1
Java多线程父线程向子线程传值解决方案
583 0
|
6月前
|
NoSQL 算法 安全
redis分布式锁在高并发场景下的方案设计与性能提升
本文探讨了Redis分布式锁在主从架构下失效的问题及其解决方案。首先通过CAP理论分析,Redis遵循AP原则,导致锁可能失效。针对此问题,提出两种解决方案:Zookeeper分布式锁(追求CP一致性)和Redlock算法(基于多个Redis实例提升可靠性)。文章还讨论了可能遇到的“坑”,如加从节点引发超卖问题、建议Redis节点数为奇数以及持久化策略对锁的影响。最后,从性能优化角度出发,介绍了减少锁粒度和分段锁的策略,并结合实际场景(如下单重复提交、支付与取消订单冲突)展示了分布式锁的应用方法。
509 3
|
前端开发 Java API
Apache Seata(incubating) 首个版本重磅发布!
2.1.0 是 Seata 进入 Apache 基金会的第一个 Release Version。此次发布将 io.seata 包名更改为 org.apache.seata。除了按原有的 Roadmap 技术演进外,2.1.0 进行了大量兼容性工作,实现了 API、数据和协议的兼容。用户无需修改原有的 API 和配置,即可实现到 Apache 版本的平滑升级。
371 105
Apache Seata(incubating) 首个版本重磅发布!
|
自然语言处理 网络架构 索引
Elasticsearch7.1之cerebro使用(一)
Elasticsearch7.1之cerebro使用(一)
227 1
|
算法 前端开发 NoSQL
追忆四年前:一段关于我被外企CTO用登录注册吊打的不堪往事
是的,诸位没有看错,这篇文章的要讲述的并不是我吊打面试官,而是一段我被面试官吊打的陈年往事,这段痛苦的记忆在我脑海中长久不衰,也是一个我内心曾多次不愿面对的事实,各位看官可以准备好一小把瓜子,听我将这则旧事缓缓道来~
635 59
追忆四年前:一段关于我被外企CTO用登录注册吊打的不堪往事
|
10月前
|
存储 数据采集 数据可视化
Pandas数据应用:医疗数据分析
Pandas是Python中强大的数据操作和分析库,广泛应用于医疗数据分析。本文介绍了使用Pandas进行医疗数据分析的常见问题及解决方案,涵盖数据导入、预处理、清洗、转换、可视化等方面。通过解决文件路径错误、编码不匹配、缺失值处理、异常值识别、分类变量编码等问题,结合Matplotlib等工具实现数据可视化,并提供了解决常见报错的方法。掌握这些技巧可以提高医疗数据分析的效率和准确性。
315 22
|
存储 监控 安全
智慧社区可视化解决方案:科技引领社区服务与管理新篇章
智慧社区通过现代科技整合区域资源,提升治理和服务水平,为居民提供便捷、高效、安全的生活环境。其特点包括科技赋能、资源整合和以人为本,旨在实现社区现代化管理,提高居民满意度。未来将应用更多创新技术,推动社区治理现代化。
534 16
|
机器学习/深度学习 数据挖掘 物联网
【专栏】机器学习如何通过预测性维护、负载预测、动态冷却管理和能源效率优化提升数据中心能效
【4月更文挑战第27天】随着信息技术发展,数据中心能耗问题日益突出,占全球电力消耗一定比例。为提高能效,业界探索利用机器学习进行优化。本文讨论了机器学习如何通过预测性维护、负载预测、动态冷却管理和能源效率优化提升数据中心能效。然而,数据质量、模型解释性和规模化扩展是当前挑战。未来,随着技术进步和物联网发展,数据中心能效管理将更智能自动化,机器学习将在实现绿色高效发展中发挥关键作用。
340 5
|
10月前
|
人工智能 自然语言处理 Java
Spring Cloud Alibaba AI 入门与实践
本文将介绍 Spring Cloud Alibaba AI 的基本概念、主要特性和功能,并演示如何完成一个在线聊天和在线画图的 AI 应用。
2993 8