以下内容转载自前端develop的文章《腾讯地图实现地图找房功能》

作者:前端develop

链接:https://juejin.im/post/6844903510614474759#comment

来源:掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

链家实现的效果

分析

地图找房功能使用点聚合来实现的。官网示例如下:https://lbs.qq.com/javascript_v2/sample/overlay-markercluster.html

链家的地图找房主要分为三层。第一层为市区层,比如南山、罗湖等;第二层为片区,比如南头、科技园等;第三层则为小区。

因为第一层,第二层的数据没有那么多,这两个接口都是把所有的数据一次返回给前端。但是第三层的数据量就非常的巨大了,链家采取的是返回部分数据,将前端页面上显示的最大经纬度以及最小经纬度传给后台,后台再将筛选后的数据返回给前端。(接口地址大家可以使用 Chrome 的开发工具进行抓包,这里需要注意的是链家的接口采用 jsonp 的形式,所以需要抓取 JS)

实现

首先需要添加腾讯地图的API,这里推荐使用异步加载的方式。因为项目使用 Vue 进行开发的单页应用,有可能用户并没有进入地图找房的页面,所以这里建议在打开地图找房的页面时添加腾讯地图的API。

异步加载需要避免一个重复加载的问题,即不管用户是第几次打开地图找房,地图的 API 都是同一个。 这里为了降低代码复杂度,没有使用单例模式,具体的代码如下:

const TXMap = {map: undefined, // 地图实例// 异步加载获取apigetApi (funName) {let script = document.createElement('script')script.type = 'text/javascript'script.src = `http://map.qq.com/api/js?v=2.exp&callback=${funName}`document.body.appendChild(script)}
}

可以看到异步加载就是动态加入 script 标签,src 为腾讯地图 api 的地址,src 包含一个 callback 参数,表示 js 加载完毕后会调用 funName 这个函数。添加了地图 api 之后,window 对象会有一个 qq.maps 对象,我们可以用来判断是否已经添加了 api,来避免重复添加 api。

接下来就是实现自定义覆盖物这个方法了。还是参照官方文档:https://lbs.qq.com/javascript_v2/doc/overlay.html

const TXMap = {map: undefined,overlays: [], // 存放所有覆盖物sourceData: [], // 原始数据listener: undefined, // 地图缩放或平移的事件监听器getApi () {}, /* 前面已经声明,此处省略 */// 实现自定义覆盖物drawOverlay (options) {let _this = this // 下面有多个 window 对象的方法,避免 this 的指向问题this.sourceData = options.data // 存放原始数据// 绘制覆盖物之前,清理之前绘制的覆盖物this.clearOverlays()// 如果 initMap 方法已经实现,那么我们可以直接调用,否则需要进行定义if (window.initMap === undefined) {window.initMap = function () {} // 绘制覆盖物的具体实现 // 地图 api 如果没有引入则调用 getApi 方法,否则直接调用 initMap ()window.qq === undefined ? this.getApi('initMap') : window.initMap()} else {window.initMap()}},// 清除自定义覆盖物clearOverlays () {let overlaywhile (overlay = this.overlays.pop()) {overlay.onclick = null // 移除点击事件overlay.parentNode.removeChild(overlay) // 移除 dom 元素}},// 在 Vue 组件的 beforeDestroy 调用,重置地图,移除时间为监听,避免内存泄漏clearMap () {this.map = undefinedif (this.listener) {window.qq.maps.event.removeListener(this.listener)}}
}

这个地图找房的架子到此就搭得差不多了,接下来就看看绘制覆盖物的具体实现了,也就是 initMap 这个方法。

window.initMap = function () {if (_this.map === undefined) {// 地图对象为undefined时, 需要进行地图的绘制_this.map = new window.qq.maps.Map(document.getElementById(options.containerId), {// 初始化地图中心center: new window.qq.maps.LatLng(options.lat || 22.702, options.lng || 114.09),// 初始化缩放级别zoom: options.zoom || 10,// 地图最小缩放级别minZoom: 10,// 停用缩放控件zoomControl: false,// 停用地图类型控件mapTypeControl: false})// idle 事件, 地图缩放或平移之后触发该事件_this.listener = window.qq.maps.event.addListener(_this.map, 'idle', () => {// 获取当前地图可视范围的最大最小经纬度let bounds = _this.map.getBounds()// 获取当前地图的缩放级别let zoom = _this.map.getZoom()// 调用 Vue 组件对 idle 事件的处理函数options.callback && options.callback(bounds, zoom)})}// 自定义覆盖物if (window.CustomOverlay === undefined) {window.CustomOverlay = function (lat, lng, name, houseCount) {// 调用地图 api 计算出覆盖物的位置this.position = new window.qq.maps.LatLng(lat, lng)this.name = name // 区域名this.houseCount = houseCount // 房源数量}// 继承 Overlaywindow.CustomOverlay.prototype = new window.qq.maps.Overlay()// 自定义覆盖物构造函数,定义覆盖为的 DOM 结构,DOM 结构,样式大家可以根据需求自己绘制window.CustomOverlay.prototype.construct = function () {let div = this.div = document.createElement('div')div.className = 'my-overlay' // 覆盖物类名// 覆盖物 html 结构this.div.innerHTML = `<p class="count" >${this.houseCount}<span>套</span></p><p class="name">${this.name}</p>`//将dom添加到覆盖物层,overlayMouseTarget的顺序容器 5,此容器包含透明的鼠标相应元素,用于接收Marker的鼠标事件this.getPanes().overlayMouseTarget.appendChild(div)// 将 div 添加到 overlays,可以用以后续处理_this.overlays.push(div)// 定义覆盖物的点击事件let center = this.positionthis.div.onclick = function () {// 点击之后对地图进行缩放以及平移let zoom = _this.map.getZoom()if (zoom < 13) {_this.map.setCenter(center)_this.map.setZoom(13)} else if (zoom >= 13 && zoom < 15) {_this.map.setCenter(center)_this.map.setZoom(15)}}}// 实现 draw 接口来绘制 DOM 元素window.CustomOverlay.prototype.draw = function () {let overlayProjection = this.getProjection()// 获取覆盖物容器的相对像素坐标let pixel = overlayProjection.fromLatLngToDivPixel(this.position)let divStyle = this.div.style// 根据 DOM 元素调整定位的位置divStyle.top = pixel.y - 53 + 'px'divStyle.left = pixel.x - 30 + 'px'}}// 根据接口数据绘制覆盖物if (_this.sourceData.length > 0) {_this.sourceData.map(item => {let customOverlay = new window.CustomOverlay(item.latitude, item.longitude, item.name, item.house_count)customOverlay.setMap(_this.map)})}
}

至此,地图找房对绘制覆盖物方法的封装就完成了,接下来只需要将 TXMap 暴露出去,然后在 Vue 组件中进行引入,之后再向下面的方法使用即可

TXMap.drawOverlay({containerId: 'map-box',data: res.data
})

实现效果

这个例子用了链家的数据做了两层,大家可以根据自己的需要进行修改。

项目地址: GitHub

产品推广

本文实现地图找房功能使用的是我们2D版JSAPI,目前我们已经上线3D版地图API-JavaScript API GL。

对应上文功能的3D版地图API文档链接:
点聚合、自定义覆盖物

腾讯地图点聚合开发-实现地图找房功能相关推荐

  1. Java开发导入腾讯地图描点_腾讯地图点聚合开发-实现地图找房功能

    链家实现的效果 分析 链家的地图找房主要分为三层.第一层为市区层,比如南山.罗湖等:第二层为片区,比如南头.科技园等:第三层则为小区. 因为第一层,第二层的数据没有那么多,这两个接口都是把所有的数据一 ...

  2. 腾讯地图点聚合应用之地图找房

    链家实现的效果 分析 地图找房功能使用点聚合来实现的.官网示例如下:https://lbs.qq.com/javascript_v2/sample/overlay-markercluster.html ...

  3. 腾讯地图实现地图找房功能

    链家实现的效果 最近接到一个需求,需要使用鹅厂地图实现类似链家网的地图找房功能,然后我去网上看了一下,基本上使用的都是百度地图.于是我打算自己稍微封装一下,可以在使用的时候更加的方便. 01. 分析 ...

  4. vue百度地图三级缩放,实现地图找房功能,vue-baidu-map

    文章目录 前言 一.安装vue-baidu-map 二.使用步骤(只记录使用方法) 1.实现效果 2.实现功能 总结 前言 使用vue-baidu-map实现三级地图缩放实现地图找房功能,在第三级使用 ...

  5. 百度地图完全模仿链家找房,三级下钻联动聚合,画圈找房!

    废话不多说,说一下功能点,具体有需要请下载源码直接运行观看! 主要功能点 1.以北京为基础,区->街道->小区,三级下钻联动. 2.根据地图视野动态加载相应点位,以此来提高性能. 3.画圈 ...

  6. 百度地图——地图找房功能

            代码地址:https://github.com/huiyan-fe/BMapGLLib  HouseSearchService层 package cn.itcast.baidumap. ...

  7. 小程序实现地图找房功能

    思路解析:使用小程序的 map 地图组件 ,markers 标记点数据集合 用来生产地图上的标记,用callout 或者label 实现气泡,本文使用的是callout ,最后如何实现点击气泡更新下方 ...

  8. Java仿腾讯视频流媒体点播网站开发实战(二)- 功能模块与实体设计

    一.系统整体模块设计图 简单介绍一下架构设计,随着大数据的广泛应用,在现如今的系统之中,尤其是作为流媒体视频播放网站,统计网站用户的行为,分析用户的行为,以及对用户行为的采集无疑是很重要的一个系统要素 ...

  9. IOS开发百度地图API入门到精通-用点生成路线,导航,气泡响应

    (转)IOS开发百度地图API入门到精通-用点生成路线,导航,气泡响应 IOS百度地图API开发自定义气泡,点击气泡自动生成路线,以及拖拽 IOS百度地图开发POISearch搜索附近停车场,附近加油 ...

  10. IOS开发百度地图API

    IOS百度地图API开发自定义气泡,点击气泡自动生成路线,以及拖拽 IOS百度地图开发POISearch搜索附近停车场,附近加油站 IOS百度地图视角跳到用户当前位置 IOS百度地图开发实时路况 IO ...

最新文章

  1. c++文件读取空格_程序员术与道:术—C语言对文件进行处理,文件处理的基本操作...
  2. /etc/fstab文件损坏怎么办
  3. 这个赛道能超车几次?
  4. r语言和python-R语言和Python哪个适合生物信息学?
  5. DevExpress v19.1新版亮点——WinForms篇(五)
  6. mysql 数据表操作 存储引擎介绍
  7. vs mono linux,[.NET][C#.NET]走跳在Linux的人生(八).NET Core与Mono执行
  8. 第一个 Rails App 从安装到创建(windows版本)
  9. 关于es6的一些文章
  10. java修饰方法_java接口中方法、属性修饰符详解
  11. 电商促销PSD分层海报设计流程,设计师收好
  12. Oracle备份与还原(exp和imp),导出导入
  13. Pdftk - The PDF Toolkit
  14. 数据库树形结构,EasyUI Tree 树
  15. C++指针、空指针、野指针使用的一些总结
  16. 3dmax简单制作方法
  17. 内点法介绍(Interior Point Method)
  18. (附源码)Springboot通用办事流程管理软件 毕业设计 211819
  19. jq onclick 定义_jq中的onclick绑定事件
  20. 零基础云计算学习路线,到底什么是云计算?

热门文章

  1. Separating Skills and Concepts for Novel Visual Question Answering 论文笔记
  2. PHP 生成 ppt,php在线编辑器fckedìtor应用.ppt
  3. 摄影用光、构图基础知识
  4. 设置双击打开.ipynb文件
  5. wegame显示密保服务器,wegame英雄联盟怎么选定大区
  6. hget和get redis_redis hget阻塞 使用redis时遇到的问题 - Redis - 服务器之家
  7. CAD图纸的缩放——范围缩放
  8. python图像清晰度计算_Python 做图片清晰度识别
  9. 微信公众号微信网页开发网页授权/回调自定义参数问题处理方法。
  10. i219v微星 驱动_MSI微星