高德地圖上展示終端資訊

weixin_33806914發表於2019-02-13

本人蔘與的一個智慧園區的專案,網路地圖開發出來的後期效果如下圖所示:
clipboard.png
初次拿到設計圖時還沒有左上角的全域性搜尋框,第一步首先是繪製出浮在上層的四張卡片,我是用遍歷的方式依次渲染的:

        {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}
            />
          );
        })}

clipboard.png

第三張卡片涉及到滾動載入,和後期增加的點選搜尋功能,所以增加了getSearchKey的方法,其中滾動載入使用的是react-infinite-scroller,結合antd的TimeLine:
clipboard.png

 <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種
clipboard.png

  1. 單個終端展示

分為線上(正常,告警)、離線,通過不同的圖示來區分,點選圖示獲取對應的終端資訊。
①.獲取所有終端所在的位置經緯度,狀態,座標型別等資訊,通過座標型別,把其他型別的經緯度與轉換成高德地圖型別
②.遍歷每一個終端經緯度,通過高德地圖的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.兩個以上的終端,位置相鄰時候自動聚合的展示

clipboard.png

聚合的圖示中含有總聚合終端的總數,分為藍色(正常,離線),橙色(有告警),點選展示當前聚合終端的離線數量和告警數量。
宣告聚合資訊展示彈窗:

    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.繫結區域的終端展示
clipboard.png
繫結區域的終端,在網路地圖上展示該區域的終端彙總資訊,如果要檢視終端的具體資訊,需要點選進入當前地圖。

①.獲取所有區域的位置資訊,並且轉換經緯度為高德的
②.根據獲取到的園區中心點,將此區域的終端總數展示在marker裡,放置在中心點上;marker的點選展示彈窗方式與單個終端一致。
③.①中獲取到的位置包含區域的各個點經緯度座標,轉化座標成高德地圖上的點,使用new AMap.Polygon方法繪製出該區域在地圖上的位置。

高德地圖上展示的資訊主要是這些,其中的狀態判斷等這裡就不一一詳述了,接下來開始本地地圖部分:

![圖片上傳中...]

相關文章