共计 3840 个字符,预计需要花费 10 分钟才能阅读完成。
本人参与的一个智慧园区的项目,网络地图开发出来的后期效果如下图所示:初次拿到设计图时还没有左上角的全局搜索框,第一步首先是绘制出浮在上层的四张卡片,我是用遍历的方式依次渲染的:
{showCards.map((item, index) => {
let name = cardInfoName[index];
return (
<CardInfo
title={item}
id={index}
key={index}
isLoad={isLoad}
isLoadAlarmList={this.isLoadAlarmList}
cardInfo={cardInfo[name]}
cardLoading={cardLoading[index]}
getSearchKey={this.getSearchKey}
appid={appId}
/>
);
})}
第三张卡片涉及到滚动加载,和后期增加的点击搜索功能,所以增加了 getSearchKey 的方法,其中滚动加载使用的是 react-infinite-scroller,结合 antd 的 TimeLine:
<div className=”timeline”>
{val.length > 0 ? (
<InfiniteScroll
initialLoad={false}
pageStart={0}
loadMore={this.handleInfiniteOnLoad}
useWindow={false}
hasMore={this.state.hasMore}
>
<Timeline>
{val.map((item, index) => {
return (
<Timeline.Item key={index}>
<div onClick={debounce(() => this.goSearch(item.devEUI), 500)}>
<span>{this.formateDate(item.createTime)}</span>
<span className=”alarmType”>
<i className=”iconfont icon-yichang” />
{item.alarmTypeLabel}
</span>
<p>{item.tmnName}</p>
</div>
</Timeline.Item>
);
})}
</Timeline>
</InfiniteScroll>
) : (
<div className=”text-center”>
<i className=”iconfont icon-zanwushuju image-icon” />
<p> 暂无数据 </p>
</div>
)}
</div>
之后,开始高德地图上信息的展示这里涉及到一个百度地图经纬度和 gps 转高德的一个算法,使用的是 coordtransform:
transferLngLats = (bd_lng: number, bd_lat: number, type = ‘gcj-02’) => {
if (‘WGS84’ === type.toUpperCase()) {
return coordtransform.wgs84togcj02(bd_lng, bd_lat);
} else if (‘BD-09’ === type.toUpperCase()) {
return coordtransform.bd09togcj02(bd_lng, bd_lat);
}
return [bd_lng, bd_lat];
};
高德地图上的终端展示方式一共分为 3 种:
单个终端展示
分为在线(正常,告警)、离线,通过不同的图标来区分,点击图标获取对应的终端信息。
①. 获取所有终端所在的位置经纬度,状态,坐标类型等信息,通过坐标类型,把其他类型的经纬度与转换成高德地图类型
②. 遍历每一个终端经纬度,通过高德地图的 new AMap.LngLat 方法将经纬度结合成一个 point,并且通过终端状态,区分将展示的图标的颜色、同时增加 type 属性
③. 通过 new AMap.Icon,把选择好的图标配置好相关尺寸、偏移量等,再使用 new AMap.Marker(使用 extData 属性增加 status 类型,用来存放 type)和之前生成的 point, 将图标用 map.add 放置在地图上
④. 增加 marker 的 click 事件,点击的时候首先展示 loading 弹窗,接着用之前生成的 point 的经纬度和获取到的所有终端位置比对,相等的时候获取到终端 Id
⑤. 根据上述 Id 调接口获取此终端的详细信息,将信息传递给 TerInfo 组件(提前声明 this.terInfoRef = React.createRef() 和 this.terInfoWindow,并且给 TerInfo 组件加上 ref={this.terInfoRef} 属性),把此组件放到信息窗中,并且代替之前的 loading 弹窗, 展示终端的详细信息
把此组件放到信息窗中:`this.terInfoWindow.setContent(ReactDOM.findDOMNode(this.terInfoRef.current));`
其中声明 terInfoWindow:
this.terInfoWindow = new AMap.InfoWindow({
isCustom: true,
closeWhenClickMap: true,
offset: new AMap.Pixel(130, 248), //left top
});
2. 两个以上的终端,位置相邻时候自动聚合的展示
聚合的图标中含有总聚合终端的总数,分为蓝色(正常,离线),橙色(有告警),点击展示当前聚合终端的离线数量和告警数量。
声明聚合信息展示弹窗:
this.clustererWindow = new AMap.InfoWindow({
isCustom: true,
closeWhenClickMap: true,
offset: new AMap.Pixel(136, 65),
});
在单个终端展示的时候,增加了 type 类型,【③. 通过 new AMap.Icon,把选择好的图标配置好相关尺寸、偏移量等,再使用 new AMap.Marker(使用 extData 属性增加 status 类型)和之前生成的 point, 将图标用 map.add 放置在地图上】,之后通过 this.markerClusterer.addMarker(marker),将 marker 放到聚合中。
然后根据之前增加的 status,通过 mark.getExtData().status 来获取终端 type 类型,统计告警终端数和离线终端数(一个终端可以同时属于告警状态和离线状态)
AMap.plugin([‘AMap.MarkerClusterer’], () => {
this.markerClusterer = new AMap.MarkerClusterer(this.map, [], {
gridSize: 20,
minClusterSize: 2,
zoomOnClick: false,
renderCluserMarker: obj => {
const type = !!obj.markers.filter(
mark => mark.getExtData().status === 2 || mark.getExtData().status === 3
).length;
const className = `clusterer ${type ? ‘alarmBg’ : ‘normalBg’}`;
obj.marker.setContent(`<div class=”${className}”>${obj.count}</div>`);
},
});
this.markerClusterer.on(‘click’, obj => {
const totalNum = obj.markers.length;
let alarmNum = 0;
let offlineNum = 0;
obj.markers.forEach(item => {
const status = item.getExtData().status;
if (status === 3) {
alarmNum++;
offlineNum++;
}
if (status === 2) {
alarmNum++;
}
if (status === 0) {
offlineNum++;
}
});
this.clustererWindow.setContent(`<div class=”mapInfo clustererInfo”>
<div class=”info_title”> 汇总情况 </div>
<div class=”li”> 告警终端 : ${alarmNum}</div>
<div class=”li”> 离线终端 : ${offlineNum}</div>
</div>`);
this.clustererWindow.open(this.map, obj.lnglat);
});
});
3. 绑定区域的终端展示
绑定区域的终端,在网络地图上展示该区域的终端汇总信息,如果要查看终端的具体信息,需要点击进入当前地图。
①. 获取所有区域的位置信息,并且转换经纬度为高德的
②. 根据获取到的园区中心点,将此区域的终端总数展示在 marker 里,放置在中心点上;marker 的点击展示弹窗方式与单个终端一致。
③.①中获取到的位置包含区域的各个点经纬度坐标,转化坐标成高德地图上的点,使用 new AMap.Polygon 方法绘制出该区域在地图上的位置。
高德地图上展示的信息主要是这些,其中的状态判断等这里就不一一详述了,接下来开始本地地图部分:
![图片上传中 …]