天天看點

vue 高德地圖 多個标記點_react+高德地圖實作熱力地圖及海量點加載

之前研究過研究過百度地圖配合echarts實作熱力地圖和大量标注點加載,有興趣可檢視部落格https://www.cnblogs.com/class1/p/13691867.html。結果效果不是太理想,進而轉戰高德地圖。

最終效果圖先展示一波。

vue 高德地圖 多個标記點_react+高德地圖實作熱力地圖及海量點加載

圖上效果圖的實作主要有五點:

一,高德地圖的引入。

引入地圖,和百度地圖一樣,還是要申請自己使用的key值,網上講解很多,這裡不再細述。有了key值以後,在全局的入口html檔案中引入高德地圖,我使用的是antd pro架構,入口檔案是document.ejs。如果不想申請key值,直接複制粘貼下面的就可以行。

然後直接在項目裡建立頁面檔案,寫你的地圖就完了,非常友善。這裡我建立的地圖檔案命名為guidemap.js.

二,熱力地圖的實作。

關鍵部分代碼:

// 建立地圖,gaoDe為地圖容器标簽的id名const map = new AMap.Map('gaoDe', {         resizeEnable: true,   // 允許縮放地圖      center: [108.5, 34.3],  // 地圖中心點經緯度      zoom: 4   // 地圖的等級,範圍是3~18級    });    let heatmap;    map.plugin(["AMap.Heatmap"], function () {      // 初始化heatmap對象      heatmap = new AMap.Heatmap(map, {        radius: 25, // 給定半徑        opacity: [0, 0.8],        gradient:{    // 熱力值的顔色設定,範圍是0-1,可以分段設定顔色            0.5: 'blue',            0.65: 'rgb(117,211,248)',            0.7: 'rgb(0, 255, 0)',            0.9: '#ffea00',            1.0: 'red'        }      });      heatmap.setDataSet({        data: gaoData,  // heatmapData 熱力地圖的資料,這裡的資料格式 [ {"lng": 116.191031,"lat": 39.988585,"count": 10},{...}]        max: 10   // 熱力最大範圍值      })    });
           

效果圖如下:

vue 高德地圖 多個标記點_react+高德地圖實作熱力地圖及海量點加載

三,控件的添加。

關鍵部分代碼:

const scale = new AMap.Scale({        visible: true,        offset: new AMap.Pixel(70,20),   // 控件的偏移位置      });      map.addControl(scale);   // 添加比例尺控件      map.addControl(new AMap.ToolBar());   // 添加縮放控件
           

因為是熱力圖,一般圖上會有個熱力标尺,但是高德地圖沒有,可以将高德地圖引入echarts圖表中,通過配置項加熱力标尺(visualMap屬性)。但是考慮到高德地圖的功能比較完備,為了一個屬性引入echarts,太大費周章。今天我決定手寫個熱力标尺:

10

這個是在react項目裡寫的html,css樣式這麼寫沒問題的。

看下添加的控件效果:這個手寫的熱力标尺毫無違和感是不是。

vue 高德地圖 多個标記點_react+高德地圖實作熱力地圖及海量點加載

四,海量點标記的添加。

// 海量點标記    const mass = new AMap.MassMarks(massData, {      opacity: 0.8,      zIndex: 111,      cursor: 'pointer',      style: {        url: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',   // 點标注用的圖檔,可自定義        anchor: new AMap.Pixel(6, 6),   // 位置偏移        size: new AMap.Size(15, 15)   // 标注的大小      }    });  mass.setMap(map);
           

此時就是頁面标注點和熱力圖結合了,但是标注點還沒有添加資訊窗,點選是沒有效果的。如果标注點不是太多,也可以不用海量點,直接建立mark,每一個依次添加就行

const allLength=gaoData.length;    // 擷取标注點的個數     for(let i = 0; i < allLength; i += 1){    // 把每個點都添加在地圖上     const marker = new AMap.Marker({        position: [gaoData[i].lng, gaoData[i].lat],      map:map       });     }
           

五,點标記的資訊窗的添加。

點标記應該和上面的四合起來用的。如果是海量點,加資訊窗如下:

const mass = new AMap.MassMarks(massData, {      opacity: 0.8,      zIndex: 111,      cursor: 'pointer',      style: {        url: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',        anchor: new AMap.Pixel(6, 6),        size: new AMap.Size(15, 15)      }    });   //  這部分是label标簽,使用label就是這樣寫的,使用這部分就要注釋掉下面資訊窗的代碼    // var marker = new AMap.Marker({content: ' ', map: map});    // mass.on('mouseover', function (e) {    //   marker.setPosition(e.data.lnglat);    //   marker.setLabel({content: e.data.lnglat})    // });    const infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(0, -10)});    mass.on('click', function (e) {      infoWindow.setContent(`
           

标題:熱點詳細資訊 地理位置:${e.data.lnglat.lng}, ${e.data.lnglat.lat} 最近三個月熱力值:${e.data.val}

`); infoWindow.open(map, e.data.lnglat); }); mass.setMap(map);

這個是使用label标簽的效果,滑鼠放在mark标注上就展示目前點的地理位置坐标:

vue 高德地圖 多個标記點_react+高德地圖實作熱力地圖及海量點加載

如果點數不多這裡提供了兩種寫法:

const allLength=gaoData.length;    for(let i = 0; i < allLength; i += 1){      const marker = new AMap.Marker({        position: [gaoData[i].lng, gaoData[i].lat],        map:map      });      const infoWindow = new AMap.InfoWindow({        anchor: 'bottom-center',        content:`
           

這是資訊窗體!這是資訊窗體!

${gaoData[i].lng}

` , }); // 滑鼠點選marker彈出自定義的資訊窗體 marker.on('click', function () { infoWindow.open(map,[gaoData[i].lng, gaoData[i].lat]) }); }

var infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(0, -30)});    const allLength=gaoData.length;    function markerClick(e) {      infoWindow.setContent(e.target.content);      infoWindow.open(map, e.target.getPosition());    }    for(let i = 0; i < allLength; i += 1){      const marker = new AMap.Marker({        position: [gaoData[i].lng, gaoData[i].lat],        map:map      });      marker.content = '我是第' + (i + 1) + '個Marker';      marker.on('click', markerClick);    }
           

最後附上完整的代碼:

// guidemap.jsimport React, { Component,Fragment } from 'react';const {AMap} = window;class Guide extends Component {  constructor(props) {    super(props);    this.state = {      data: props.data,    };  }  componentDidMount() {      this.getCharts();  }  // eslint-disable-next-line no-unused-vars  componentWillReceiveProps(nextProps, nextContext) {    if (nextProps.data.length > 0) {      this.setState({        data: nextProps.data,      });      setTimeout(() => {        this.getCharts();      }, 500);    }  }  getCharts = () => {    const { data } = this.state;    const gaoData=[];    const massData=[];    // eslint-disable-next-line array-callback-return      data.map(item=>{        gaoData.push({ lng:item.longitude, lat:item.latitude, count:item.number})        massData.push({lnglat:[item.longitude,item.latitude],val:item.number})      });    console.log("高德地圖",gaoData);    const map = new AMap.Map('gaoDe', {      resizeEnable: true,      center: [108.5, 34.3],      zoom: 4    });    let heatmap;    map.plugin(["AMap.Heatmap","AMap.Scale",'AMap.ToolBar',], function () {      // 初始化heatmap對象      heatmap = new AMap.Heatmap(map, {        radius: 25, // 給定半徑        opacity: [0, 0.8],        gradient:{            0.5: 'blue',            0.65: 'rgb(117,211,248)',            0.7: 'rgb(0, 255, 0)',            0.9: '#ffea00',            1.0: 'red'        }      });      heatmap.setDataSet({        data: gaoData,// heatmapData        max: 10      });      const scale = new AMap.Scale({        visible: true,        offset: new AMap.Pixel(70,20),      });      map.addControl(scale);      map.addControl(new AMap.ToolBar());    });  // 海量點标記    const mass = new AMap.MassMarks(massData, {      opacity: 0.8,      zIndex: 111,      cursor: 'pointer',      style: {        url: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',        anchor: new AMap.Pixel(6, 6),        size: new AMap.Size(15, 15)      }    });    // var marker = new AMap.Marker({content: ' ', map: map});    // mass.on('mouseover', function (e) {    //   marker.setPosition(e.data.lnglat);    //   marker.setLabel({content: e.data.lnglat})    // });    const infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(0, -10)});    mass.on('click', function (e) {      infoWindow.setContent(`
           

标題:熱點詳細資訊 地理位置:${e.data.lnglat.lng}, ${e.data.lnglat.lat} 最近三個月熱力值:${e.data.val}

`); infoWindow.open(map, e.data.lnglat); }); mass.setMap(map); // map.setFitView();// 自适應所有的點 // 點不多,添加mark和資訊窗(方案一) // const allLength=gaoData.length; // for(let i = 0; i < allLength; i += 1){ // const marker = new AMap.Marker({ // position: [gaoData[i].lng, gaoData[i].lat], // map:map // }); // // const infoWindow = new AMap.InfoWindow({ // anchor: 'bottom-center', // content:`

這是資訊窗體!這是資訊窗體!

${gaoData[i].lng}

` , // }); // // 滑鼠點選marker彈出自定義的資訊窗體 // marker.on('click', function () { // infoWindow.open(map,[gaoData[i].lng, gaoData[i].lat]) // }); // } // 點不多,添加mark和資訊窗(方案二) // var infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(0, -30)}); // const allLength=gaoData.length; // function markerClick(e) { // infoWindow.setContent(e.target.content); // infoWindow.open(map, e.target.getPosition()); // } // for(let i = 0; i < allLength; i += 1){ // const marker = new AMap.Marker({ // position: [gaoData[i].lng, gaoData[i].lat], // map:map // }); // marker.content = '我是第' + (i + 1) + '個Marker'; // marker.on('click', markerClick); // } }; render(){ return (

{' '}

10

); }}export default Guide;

然後在其他頁面引入這個地圖:

import Guidemap from './guidemap';  //引入自己寫好的熱力地圖const arry=[  {longitude:120.328789,latitude:34.876575,number:10}, {longitude:120.328789,latitude:34.876575,number:10},];              //直接在頁面引入标簽使用  arry的資料格式你可以有自己的格式,不過你的格式改了的話,guide.js參數使用也得自己改下。
           

繼續閱讀