链家实现的效果

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

01. 分析

点聚合效果

看起来这个就是我要实现功能,我尝试地写了一下,发现这个样式比较难改,而且需要一次将所有的数据都请求过来,如果数据量非常大的时候请求需要花费的时间将会非常多,对用户体验也不够友好,所以这个方法并没有继续下去。

后来我独自打开了链家的官网,抓了一下链家的数据,研究出了链家的套路。链家的地图找房主要分为三层。第一层为市区层,比如南山、罗湖等;第二层为片区,比如南头、科技园等;第三层则为小区。

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

开发者工具

PS: Windos 平台可以按 F12 调出开发者工具,Mac 平台则是 Command + Option + I

02. 实现

理论分析完了,接下来就是实现的问题了。看着腾讯地图的 API,我觉得只有自定义覆盖物比较适合这个需求了。因为自定义覆盖物更加灵活,我们可以像写 HTML 一样,绘制出我们需要的样式。

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

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

const TXMap = {

map: undefined, // 地图实例

// 异步加载获取api

getApi (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。

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 overlay

while (overlay = this.overlays.pop()) {

overlay.onclick = null // 移除点击事件

overlay.parentNode.removeChild(overlay) // 移除 dom 元素

}

},

// 在 Vue 组件的 beforeDestroy 调用,重置地图,移除时间为监听,避免内存泄漏

clearMap () {

this.map = undefined

if (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 // 房源数量

}

// 继承 Overlay

window.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 = `

${this.houseCount}套

${this.name}

`

//将dom添加到覆盖物层,overlayMouseTarget的顺序容器 5,此容器包含透明的鼠标相应元素,用于接收Marker的鼠标事件

this.getPanes().overlayMouseTarget.appendChild(div)

// 将 div 添加到 overlays,可以用以后续处理

_this.overlays.push(div)

// 定义覆盖物的点击事件

let center = this.position

this.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

})

03.实现效果

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

实现效果

项目地址放在 GitHub

如果文章对你有所帮助,那么请您点一下❤

由于本人水平有限,如有错误,欢迎大家指正。如果你在操作过程中发现一些没有讲到的错误或者问题,欢迎在评论留言,一起探讨,共同学习进步!

文章会在我的公众号第一时间发布,如果你有兴趣,欢迎关注我的公众号-前端develop

php地图找房代码,腾讯地图实现地图找房功能相关推荐

  1. 百度地图api 导航 代码html,网页嵌入百度地图和调用百度地图api展示拥堵代码

    XX城市路况拥堵图 兰州市实时路况 $(function() { var map = new BMap.Map("mapContainer"); map.centerAndZoom ...

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

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

  3. 腾讯地图html代码,腾讯地图API使用参考.html

    Hello world! #container { /*地图(容器)显示大小*/ width: 1200px; height: 400px; } //地图初始化函数,本例取名为init,开发者可根据实 ...

  4. Android 腾讯位置服务地图简单使用

    文章目录 概述 腾讯位置服务地图SDK 兼容性 创建工程 获取Appkey 配置AppKey 配置工程 代码混淆 权限配置 地图 基础地图 地图类型 个性化地图 3D建筑 行政区划 出现的问题及解决 ...

  5. 发布地图服务属性表_Web3D地图来了!腾讯位置服务正式版发布!

    公众号关注 "菜鸟要飞" 设为 "星标",和10万程序员一起成长! 原文转载自公众号[开发者技术前线] 腾讯位置服务在半年前推出JavaScript API G ...

  6. 腾讯地图小程序服务器配置,腾讯地图实现微信小程序地图定位教程

    前言 目前腾讯位置服务提供路线规划.地图选点.地铁图.城市选择器插件四款插件产品,本篇博客主要针对地图选点功能进行实现. 开通腾讯位置服务 2.登录进入小程序后台,选择 "开发 - 开发工具 ...

  7. 腾讯百度之间地图经纬度的转换

    需求来源 在小程序,或者在软件开发中会有这样的需求,需要请求某个地图的接口,或者两个的接口都需要调用,但是两个地图所展示的同一个地方的经纬度会有所差异,这个时候就需要进行经纬度的转换了. 经纬度的提取 ...

  8. 微信小程序之实现地图定位(使用腾讯位置服务插件)

    一. 腾讯位置服务插件简介 完整的地图能力 腾讯位置服务基于微信提供的小程序插件能力,专注于(围绕)地图功能,打造一系列小程序插件,可以帮助开发者简单.快速的构建小程序,是实现地图功能的最佳伙伴. 目 ...

  9. 微信小程序--放入个性化手绘地图具体步骤(腾讯地图)

    微信小程序–放入个性化手绘地图具体步骤(腾讯地图) 前言:小程序中想要实现个性化手绘地图需要通过H5嵌入的模式进行实现. 1.首先需要一个腾讯地图的账号(微信登录即可),然后选择个性化地图进入(htt ...

  10. 微信小程序使用腾讯位置服务地图选点实现地址的选取|微信小程序腾讯位置服务地图选点请求来源未被授权

    效果图 首先要在微信开放平台的小程序里 添加插件 具体配置,可以参考官方文档 腾讯位置服务地图选点 | 小程序插件 | 微信公众平台 (qq.com) 同时还要申请接口的权限,不然小程序上线的时候不能 ...

最新文章

  1. PLSQL创建Oracle定时任务
  2. 微软批量授权版WINDOWS 10资料(截至到2015年11月,此处无下载地址)
  3. VANSI致力成为全球优质数字资产交易平台的典范
  4. CountDownLatch 初识
  5. 2020 操作系统第一天复习(习题总结)
  6. 2016浙江省赛过山车记
  7. Microsoft Windows Workflow Foundation 入门:开发人员演练
  8. 关于 Node.js scoped module 的一些理解
  9. react常用知识点总结
  10. SDP协议 学习笔记
  11. 3D Slicer源代码编译与调试
  12. [笔记]远程终端API,Terminal Services Administration
  13. VS2010 小技巧
  14. [Python] L1-025. 正整数A+B-PAT团体程序设计天梯赛GPLT
  15. C# Log4Net简单使用方法
  16. 动易sf生成html,动易节点“模板选项”与“分页标签”的关系
  17. Unity学习笔记-uniwebview4-网页与unity通信
  18. 各型号iPhone的屏幕参数 逻辑分辨率 物理分辨率 - iOS Device Display Summary - 更新到iPhone 13系列
  19. WiFi能连上但是上不了网怎么办?
  20. MP4视频播放问题(有声音无图像)分析与解决——FFmpeg视频处理教程

热门文章

  1. Separating Skills and Concepts for Novel Visual Question Answering 论文笔记
  2. 解决 invalid DSN: missing the slash separating the database name
  3. ubuntu20.04下编译仿真智能车racecar的错误解决汇总
  4. 2021年 全网最细大数据学习笔记(一):初识 Hadoop
  5. windows 端口被System进程占用怎么解决?
  6. 抖音运营详细教程,算法解读、平台规则、热门涨粉......丨国仁网络
  7. mall-accounts.json ES测试数据
  8. BIOS int 10H中断介绍
  9. Java深圳工作面试经历(真实经历)!!!
  10. 基本积分表的联想记忆