js高德地图添加点Marker,添加线段Polyline,添加一个区域Polygon(面),绘制GeoJSON数据

高德地图JS API 实例  亲测可用

参考网站=> 阿里云数据可视化平台(下载json用的):http://datav.aliyun.com/portal/school/atlas/area_selector?spm=a2crr.23498931.0.0.685915dd8QQdlv

<script src="//webapi.amap.com/maps?v=1.4.15&key=564abe9d4eef2535f9cc6ab1c1229cfc&plugin=Map3D,AMap.DistrictSearch,AMap.MarkerClusterer,AMap.Object3DLayer,AMap.MouseTool"></script>
 
 

 
 

1.渲染地图

  const [initDataMap, setInitDataMap] = useState({
    centerCity: '拱墅区',
    defaultZoom: 12,
    centerPoint: { lng: 120.165533, lat: 30.329062 },
  });  
  //初始化地图
  const initMap = () => {
    const { centerPoint } = initDataMap;
    const center = [centerPoint.lng, centerPoint.lat];
    const mzooms = [8, 19];
    const mzoom = 12;

    let map = new AMap.Map("AMapBox", {
      zoom: mzoom, //初始化地图层级
      zooms: mzooms,
      rotateEnable: false, // 固定视角
      disableSocket: true,
      center: center,
    });

    mapRef.current = map;
    addAreaCoordinate(map); // 这个是渲染块
  };

2.绘制Marker标记点

  // 绘制点
  const drawMarker = (data: any, map: any) => {
    const infoWindow = new AMap.InfoWindow({
      offset: new AMap.Pixel(5, -30),
      autoMove: true,
      closeWhenClickMap: true,
    });
    let ap: any = []
    data.forEach((item: any) => {
      if (item.lat && item.lng) {
        const ad = [item.lng, item.lat];
        const marker = new AMap.Marker({
          position: ad,
          icon: iconIMg, // 自己的icon
          map: map
        });

        ap.push(marker);
        setMarkerList(ap);

        const content = item.projectName;
        marker.on('click', () => {
          infoWindow.setContent(content);
          infoWindow.open(map, ad);
        });
      }
    });
    map.setFitView();
  }

3.绘制线段Polyline

// 绘制线段
  const polylineInit = (lineArr: any, map: any, callBack: any) => {
    const infoWindowLine = new AMap.InfoWindow({
      offset: new AMap.Pixel(5, -30),
      autoMove: true,
      closeWhenClickMap: true,
    });

    const polyline = new AMap.Polyline({
      path: lineArr.list,          //设置线覆盖物路径
      strokeColor: "#3366FF", //线颜色
      strokeOpacity: 1,       //线透明度
      strokeWeight: 5,        //线宽
      strokeStyle: "solid",   //线样式
      strokeDasharray: [10, 5] //补充线样式
    });
    polyline.setMap(map);

    callBack(polyline);

    const content = `
      <div>
        <div style='border-bottom: 1px solid #F0F0F0; margin-bottom: 4px; padding: 4px 0 4px 0; color: #000000; font-size: 16px; '>${lineArr.roadName}</div>
        <div >所属国企:${lineArr.belongCorpName}</div>
        <div>当前进度:${lineArr.currentStatusStr}</div>
        <a onclick="handleClickDetail(${lineArr.id})">查看详情信息</a>
      <div>
    `

    if (callBackDetail) {
      polyline.on('click', (e: any) => {
        infoWindowLine.setContent(content);
        infoWindowLine.open(map, e.lnglat);
      });
    }
  }
  // 处理绘制线段  可不看嘎嘎···
  const dealPolylineInit = (arr: any, map: any) => {
    // map.clearMap();
     * arr的数据结构
     * @arr的数据结构 
     * arr:[
     *  { ..., locationMark:[{lng:'',lat:''},{},{}]  },
     *  { ..., },
     *  { ..., },
     * ]
     *
    map.remove(polylineList);

    let ad: any = [];
    arr.forEach((item: any) => {
      const st = JSON.parse(item.locationMark);
      st.forEach((element: any) => {
        element.forEach((ele: any) => {
          ele.roadName = item.roadName;
          ele.belongCorpName = item.belongCorpName;
          ele.currentStatusStr = item.currentStatusStr;
          ele.id = item.roadId;
        });
      });
      ad.push(st);
    });
    const flatArr = ad.flat();

    const cloneDeepData = cloneDeep(flatArr);

    const opd: any = [];
    cloneDeepData.forEach((item: any) => {
      let lineArr: any = [];
      const obj: any = {};
      item.forEach((element: any) => {
        const ad = [element.lng, element.lat];
        obj.roadName = element.roadName;
        obj.belongCorpName = element.belongCorpName;
        obj.currentStatusStr = element.currentStatusStr;
        obj.id = element.id
        lineArr.push(ad);
      });
      obj.list = lineArr;
      polylineInit(obj, map, (v: any) => {
        opd.push(v)
      });
    })

    setPolylineList(opd)
  }

4.绘制区域Polygon

坐标转换函数:https://www.cnblogs.com/dreamtt/p/15294332.html

  const addPolygon = (data: any, map: any) => {
    const ad = data.map((item: any) => {
      return item.map((ite: any) => {
        return ite.map((it: any) => {
          const point: any = wgs_gcj_encrypts(it[1], it[0]);  // 坐标转换函,请看博客第一条
          return [point?.lon?.toFixed(7) * 1, point?.lat?.toFixed(7) * 1]
        })
      })
    })

    const polygon = new AMap.Polygon({
      path: ad,
      fillColor: '#ccebc5',
      strokeOpacity: 1,
      fillOpacity: 0.5,
      strokeColor: '#2b8cbe',
      strokeWeight: 2,
      // strokeStyle: 'dashed',
      strokeDasharray: [5, 10],
      zIndex: 3,
    });
    polygon.on('mouseover', () => {
      polygon.setOptions({
        fillOpacity: 0.7,
        fillColor: '#7bccc4'
      })
    })
    polygon.on('mouseout', () => {
      polygon.setOptions({
        fillOpacity: 0.5,
        fillColor: '#ccebc5'

      })
    })
    map.add(polygon);
    map.setFitView(polygon);//视口自适应
  }
  
const addAreaCoordinate = (map: any) => {
    const obj = gs_json || '';
    const points: any[] = [];
    obj?.features[0]?.geometry?.coordinates[0][0].map((item: any) => {
      points.push(new AMap.LngLat(item[0], item[1]));
    });

    const polygon = new AMap.Polygon({
      path: points,
      color: '#1CB9FF',
      weight: 3,
      opacity: 0.5,
      fillColor: '#1CB9FF',
      fillOpacity: 0.05,
    });

    map.add(polygon);
    map.setFitView(polygon);//视口自适应
    
    // 批量渲染区域(面)
    // const obj = geojson330105 || '';
    // obj?.features?.map((item: any) => {
    //   addPolygon( item.geometry?.coordinates, map)
    // });

  }

5.绘制GeoJSON数据

  // 初始化绘制 GeoJson  数据
  const initGeoJson = (map: any) => {
    const geojson = new AMap.GeoJSON({
      geoJSON: configJSON,
      // 还可以自定义getMarker和getPolyline  
      // 面
      getPolygon: (geojson: any, lnglats: any) => {
        return new AMap.Polygon({
          path: lnglats,
          fillOpacity: 0,
          strokeColor: '#000',
          fillColor: 'rgba(255,255,255,0)',
          strokeWeight: 0.25,
          zIndex: 5,
        });
      },
      //  线
      // getPolyline: (geojson: any, lnglats: any) => {
      //   return new AMap.Polyline({
      //     path: lnglats_new,
      //     strokeColor: "#000", //线颜色
      //     strokeOpacity: 0.5,       //线透明度
      //     strokeWeight: 0.25,        //线宽
      //     strokeDasharray: [10, 5], //补充线样式
      //     isOutline: true,
      //     outlineColor: "#000000",
      //     borderWeight: 3,
      //     // 折线样式还支持 'dashed'
      //     strokeStyle: "solid",
      //     // strokeStyle是dashed时有效
      //     lineJoin: "round",
      //     lineCap: "round",
      //     zIndex: 50,
      //   });
      // },
      // 点
      // getMarker: function (geojson, lnglats) {
      //       //用来绘制点
      //     },
    });

    map.add(geojson);

  }

6.完整的代码------(react写的,但不影响cv)

import React, { useRef, forwardRef, useImperativeHandle, useEffect, useState } from 'react';
//antd
// 第三方组件
//@ts-ignore
import AMap from 'AMap';
import { cloneDeep } from 'lodash';
import gs_json from '@/assets/json/gongshu.json'; // 地图区域的json数据
import configJSON from '@/assets/json/config.json'; // 地图区域的json数据  // 标准的地图GeoJSON
import iconIMg from '@/assets/productizationimg/local.png'

const AMapModal = forwardRef((props: any, ref: any) => {
  const { roadMapData, projectMapData, isShowLanLat, callBackDetail } = props;
  const mapRef = useRef<any>();
  const [markerList, setMarkerList] = useState<any>([]);
  const [polylineList, setPolylineList] = useState<any>([]);

  const [initDataMap, setInitDataMap] = useState({
    centerCity: '拱墅区',
    defaultZoom: 12,
    centerPoint: { lng: 120.165533, lat: 30.329062 },
  });

  //@ts-ignore
  window.document.handleClickDetail = function (id: any) {
    if (callBackDetail) {
      callBackDetail(id);
    }
  };

  // 根据levelCode向地图中画一个区域轮廓
  const addAreaCoordinate = (map: any) => {
    const obj = gs_json || '';
    const points: any[] = [];
    obj?.features[0]?.geometry?.coordinates[0][0].map((item: any) => {
      points.push(new AMap.LngLat(item[0], item[1]));
    });

    const polygon = new AMap.Polygon({
      path: points,
      color: '#1CB9FF',
      weight: 3,
      opacity: 0.5,
      fillColor: '#1CB9FF',
      fillOpacity: 0.05,
    });

    map.add(polygon);
    map.setFitView(polygon);//视口自适应

  }

  // 绘制点
  const drawMarker = (data: any, map: any) => {
    const infoWindow = new AMap.InfoWindow({
      offset: new AMap.Pixel(5, -30),
      autoMove: true,
      closeWhenClickMap: true,
    });
    let ap: any = []
    data.forEach((item: any) => {
      if (item.lat && item.lng) {
        const ad = [item.lng, item.lat];
        const marker = new AMap.Marker({
          position: ad,
          icon: iconIMg,
          map: map
        });

        ap.push(marker);
        setMarkerList(ap);

        const content = item.projectName;
        marker.on('click', () => {
          infoWindow.setContent(content);
          infoWindow.open(map, ad);
        });
      }
    });
    map.setFitView();
  }


  // 绘制线段
  const polylineInit = (lineArr: any, map: any, callBack: any) => {
    const infoWindowLine = new AMap.InfoWindow({
      offset: new AMap.Pixel(5, -30),
      autoMove: true,
      closeWhenClickMap: true,
    });

    const polyline = new AMap.Polyline({
      path: lineArr.list,          //设置线覆盖物路径
      strokeColor: "#3366FF", //线颜色
      strokeOpacity: 1,       //线透明度
      strokeWeight: 5,        //线宽
      strokeStyle: "solid",   //线样式
      strokeDasharray: [10, 5] //补充线样式
    });
    polyline.setMap(map);

    callBack(polyline);

    const content = `
      <div>
        <div style='border-bottom: 1px solid #F0F0F0; margin-bottom: 4px; padding: 4px 0 4px 0; color: #000000; font-size: 16px; '>${lineArr.roadName}</div>
        <div >所属国企:${lineArr.belongCorpName}</div>
        <div>当前进度:${lineArr.currentStatusStr}</div>
        <a onclick="handleClickDetail(${lineArr.id})">查看详情信息</a>
      <div>
    `

    if (callBackDetail) {
      polyline.on('click', (e: any) => {
        infoWindowLine.setContent(content);
        infoWindowLine.open(map, e.lnglat);
      });
    }
  }
  // 处理绘制线段
  const dealPolylineInit = (arr: any, map: any) => {
    // map.clearMap();
     * arr的数据结构
     * @arr的数据结构 
     * arr:[
     *  { ..., locationMark:[{lng:'',lat:''},{},{}]  },
     *  { ..., },
     *  { ..., },
     * ]
     *
    map.remove(polylineList); // 清除线段的

    let ad: any = [];
    arr.forEach((item: any) => {
      const st = JSON.parse(item.locationMark);
      st.forEach((element: any) => {
        element.forEach((ele: any) => {
          ele.roadName = item.roadName;
          ele.belongCorpName = item.belongCorpName;
          ele.currentStatusStr = item.currentStatusStr;
          ele.id = item.roadId;
        });
      });
      ad.push(st);
    });
    const flatArr = ad.flat();

    const cloneDeepData = cloneDeep(flatArr);

    const opd: any = [];
    cloneDeepData.forEach((item: any) => {
      let lineArr: any = [];
      const obj: any = {};
      item.forEach((element: any) => {
        const ad = [element.lng, element.lat];
        obj.roadName = element.roadName;
        obj.belongCorpName = element.belongCorpName;
        obj.currentStatusStr = element.currentStatusStr;
        obj.id = element.id
        lineArr.push(ad);
      });
      obj.list = lineArr;
      polylineInit(obj, map, (v: any) => {
        opd.push(v)
      });
    })

    setPolylineList(opd)
  }
                             
  // 初始化绘制 GeoJson  数据
  const initGeoJson = (map: any) => {
    const geojson = new AMap.GeoJSON({
      geoJSON: configJSON,
      // 还可以自定义getMarker和getPolyline  
      // 面
      getPolygon: (geojson: any, lnglats: any) => {
        return new AMap.Polygon({
          path: lnglats,
          fillOpacity: 0,
          strokeColor: '#000',
          fillColor: 'rgba(255,255,255,0)',
          strokeWeight: 0.25,
          zIndex: 5,
        });
      },
      //  线
      // getPolyline: (geojson: any, lnglats: any) => {
      //   return new AMap.Polyline({
      //     path: lnglats_new,
      //     strokeColor: "#000", //线颜色
      //     strokeOpacity: 0.5,       //线透明度
      //     strokeWeight: 0.25,        //线宽
      //     strokeDasharray: [10, 5], //补充线样式
      //     isOutline: true,
      //     outlineColor: "#000000",
      //     borderWeight: 3,
      //     // 折线样式还支持 'dashed'
      //     strokeStyle: "solid",
      //     // strokeStyle是dashed时有效
      //     lineJoin: "round",
      //     lineCap: "round",
      //     zIndex: 50,
      //   });
      // },
      // 点
      // getMarker: function (geojson, lnglats) {
      //       //用来绘制点
      //     },
    });

    map.add(geojson);

  }

  const initMap = () => {
    const { centerPoint } = initDataMap;
    const center = [centerPoint.lng, centerPoint.lat];
    const mzooms = [8, 19];
    const mzoom = 12;

    let map = new AMap.Map("AMapBox", {
      zoom: mzoom, //初始化地图层级
      zooms: mzooms,
      rotateEnable: false, // 固定视角
      disableSocket: true,
      center: center,
    });

    mapRef.current = map;
    addAreaCoordinate(map);
    initGeoJson(map);
  };

  useEffect(() => {
    initMap();
  }, []);
  // 地图道路线更新
  useEffect(() => {
    dealPolylineInit(roadMapData, mapRef.current);
  }, [roadMapData]);
  // 地图点更新
  useEffect(() => {
    if (isShowLanLat == 1) {
      drawMarker(projectMapData, mapRef.current);
    } else {
      if (mapRef.current) {
        mapRef.current.remove(markerList);// 清除markerList点位
      }

    }
  }, [isShowLanLat, projectMapData]);

  return (
    <div>
      <div id='AMapBox' style={{ width: '100%', height: 640 }}></div>
    </div>
  );
})


export default AMapModal

 

posted @ 2023-03-02 20:10  有只橘猫  阅读(2814)  评论(0编辑  收藏  举报