位置服务(二):基于点聚合管理设备
业务背景
在通常的物联网场景中,我们经过使用位置服务来管理自己的设备,
比如一个充电桩平台,要在一个大屏上显示某个区域有多少个充电桩。
在比如,要显示某一个区域有多少个骑手,从而对一个区域的骑手进行动态地调整。
这些的原理其实都是使用物联网技术的链接远程服务器,发送设备的坐标,然后在地图上描点,显示出来。
下面我们就来设计一个简单的地图大盘,来显示一个区域的车辆。这些车辆在地图显示的区域比较大时,会聚合显示,当地图显示的区域下的时候,每一辆车都会单独显示。
大致的效果是这样子的
当地图显示的区域比较大时,点是聚合起来的
当地图显示的区域比较小时,点是单独显示的
实现思路
实现的思路其实是比较简单的
- 初始化一个地图
- 调用后端接口获取设备坐标
- 在地图描点
- 设置点聚合与点的样式
- 定期请求服务设备的坐标点
- 设备定期上报坐标点
具体编码与解析
初始化地图
初始化地图很简单,上一篇文章我们已经讲解过,这里再多做累述。直接给出代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>基本点聚合功能</title>
<style>
html,
body {
margin: 0;
padding: 0;
overflow: hidden;
height: 100%;
}
#mapContainer {
position: relative;
height: 100%;
width: 100%;
}
</style>
</head>
<script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77"></script>
<body onload="init()">
<div id='mapContainer'></div>
<script>
var map;
function init() {
var drawContainer = document.getElementById('mapContainer');
var center = new TMap.LatLng(39.984104, 116.307503);//设置中心点坐标
map = new TMap.Map(drawContainer, {
zoom: 9,
pitch: 40,
center: center,
draggable: true,
scrollable: true,
mapStyleId: "style 1"
});
}
</script>
</body>
</html>
这里我们设置地图的中心经纬度为39.984104, 116.307503
北京的一个点
调用后端接口获取设备坐标
调用接口获取设备的坐标点
这里可以是用websocket 让服务器主动来推送数据,也可以让客户端使用http来请求数据。
$.ajax.get('${api_url}',function(res){})
最终我们得到的是一个经纬度的数组。
这里提供一个示例
geometries: [{ // 点数组
position: new TMap.LatLng(39.953416, 116.480945)
},
{
position: new TMap.LatLng(39.984104, 116.407503)
},
{
position: new TMap.LatLng(39.908802, 116.497502)
},
{
position: new TMap.LatLng(40.040417, 116.373514)
},
{
position: new TMap.LatLng(39.953416, 116.380945)
},
{
position: new TMap.LatLng(39.984104, 116.307503)
},
{
position: new TMap.LatLng(39.908802, 116.397502)
},
{
position: new TMap.LatLng(40.040417, 116.273514)
},
]
在地图描点
在地图描点才是今天我们要说的重点,
之前有说过,在地图描一个点,可以使用marker
, 但这种描点,都是单独显示的,无法聚合。
下面我们再介绍另外一种描点大,添加覆盖物的方法。
TMap.MarkerCluster
类
关于该类的方法使用,官方有详细的解释。这里我也为大家一一解释一下。
https://lbs.qq.com/javascript_v2/doc/markercluster.html
是一个类
参数是一个对象。
包含以下几个参数
名称 | 类型 | 说明 |
---|---|---|
map | Map | 被作用的地图元素 |
minimumClusterSize | Number | 最小的集合点数 |
markers | MVCArray | 标记点 |
zoomOnClick | Boolean | 点击已经聚合的标记点实现聚合分离 |
gridSize | Number | 聚合计算范围 |
averageCenter | Boolean | 居中对齐 |
maxZoom | Number | 最大18 最小4 |
实体的方法有这些
方法 | 返回值 | 说明 |
---|---|---|
getMarkers() | MVCArray | 获取标记点集合 |
addMarker(marker:Marker) | none | 增加一个标记点 |
addMarkers(markers:Arrary |
none | 增加多个标记点 |
removeMarker(marker:Marker) | none | 删除一个标记点 |
removeMarkers(markers:Array |
none | 删除多个标记点 |
clearMarkers() | none | 清除所有标记点 |
set(key:String, value) | none | 设置属性 |
根据文档的描述,我们来写一下这部分的代码
var markerCluster = new TMap.MarkerCluster({
id: 'cluster',
map: map,
enableDefaultStyle: true, // 启用默认样式
minimumClusterSize: 2, // 形成聚合簇的最小个数
geometries, // 设备的坐标点
zoomOnClick: true, // 点击簇时放大至簇内点分离
gridSize: 60, // 聚合算法的可聚合距离
averageCenter: false, // 每个聚和簇的中心是否应该是聚类中所有标记的平均值
maxZoom: 10 // 采用聚合策略的最大缩放级别
});
设置完成后,就能看到下面的效果了。
默认的点聚合的样式太low了,如果我们要想自定义一套聚合的样式,改怎么做那?
我们可以是用这个方法
setMarkerClusterOption("styles", Styles[this.value] ? Styles[this.value] : null);
具体做法是这样的
var imgPath = "./images/";
var Styles = {
"People": [{
icon: new MarkerImage(imgPath + "people35.png", new Size(35, 35), new Point(0, 0), new Point(16, 0)),
text: new MarkerDecoration('<font style="color:#ff00ff;font-size:10px;font-weight:bold;">{num}</font>', new Point(0, 5))
}],
"Conversation": [{
icon: new MarkerImage(imgPath + "conv30.png", new Size(30, 27), new Point(0, 0), new Point(3, 0)),
text: new MarkerDecoration('<font style="color:#ff00ff;font-size:10px;font-weight:bold;">{num}</font>', new Point(0, -2))
}]
};
function setMarkerClusterOption(key, value) {
markerClusterer.set(key, value);
}
var stylesSelect = $("styles");
Event.addDomListener(stylesSelect, "change", function() {
setMarkerClusterOption("styles", Styles[this.value] ? Styles[this.value] : null);
});
最主要的几个参数是 这两个
icon: new MarkerImage(imgPath + "people35.png", new Size(35, 35), new Point(0, 0), new Point(16, 0)),
text: new MarkerDecoration('<font style="color:#ff00ff;font-size:10px;font-weight:bold;">{num}</font>', new Point(0, 5))
一个是聚合的图标,一个是要显示的文本。
图标要使用 new MarkerImage
来生成, 可以设置大小,偏移坐标。
文本使用 new MarkerDecoration
来生成。可以设置css样式。
具体的效果是这样的
案例的地址
https://lbs.qq.com/javascript_v2/sample/overlay-markercluster.html
写在后面
基于位置服务来管理设备,是非常方便快捷的。
后面我再给大家分享如何点击这些marker,显示设备的情况。如电量,状态,速度。
- 分享
- 举报
-
浏览量:5076次2021-03-31 17:33:56
-
浏览量:2833次2020-10-23 17:43:11
-
浏览量:3359次2020-08-13 14:29:28
-
浏览量:1641次2022-01-31 09:00:12
-
浏览量:1302次2023-03-20 10:56:09
-
浏览量:3299次2020-08-01 22:09:06
-
浏览量:5023次2021-07-30 15:32:45
-
浏览量:1233次2022-12-09 11:09:03
-
浏览量:2245次2020-07-18 18:11:19
-
浏览量:3135次2020-07-13 19:23:12
-
浏览量:2578次2018-01-06 16:05:51
-
浏览量:1790次2020-08-21 14:40:54
-
浏览量:4503次2021-09-22 13:39:35
-
浏览量:1137次2023-08-10 14:03:57
-
浏览量:3935次2020-12-09 10:49:28
-
浏览量:1470次2018-08-19 10:41:46
-
浏览量:1728次2023-08-15 19:14:23
-
浏览量:1982次2020-08-11 20:59:52
-
2022-01-07 09:00:27
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
这把我C
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明