本人蔘與的一個智慧園區的專案,網路地圖開發出來的後期效果如下圖所示:
初次拿到設計圖時還沒有左上角的全域性搜尋框,第一步首先是繪製出浮在上層的四張卡片,我是用遍歷的方式依次渲染的:
{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方法繪製出該區域在地圖上的位置。
高德地圖上展示的資訊主要是這些,其中的狀態判斷等這裡就不一一詳述了,接下來開始本地地圖部分:
![圖片上傳中...]