Newer
Older
Nanping_sponge_GCGL / src / components / GisMap / index.js
@liyingjing liyingjing on 25 Oct 2023 13 KB 海绵工程管理
(() => {
    (function (global, factory) {
      if (typeof exports === 'object') {
        // if (typeof global.AMap == 'undefined') return null;
  
        module.exports = factory(AMap);
      } else {
        if (typeof global.AMap == 'undefined') return null;
        global.GaoDeMapUtils = factory(AMap);
      }
    }(typeof window !== "undefined" ? window : this, function (AMap) {
      //默认初始化参数
      const DEFAULT_CONFIG = Object.freeze({
        center: [124.360332940076, 43.1641831166625],
        zooms: [1, 20],
        zoom: 13.5,
        viewMode: '3D',
        mapStyle: 'amap://styles/grey',
        pitch: 10,
      })
  
      const FEATURE_TYPE = Object.freeze({
        BUFFER: 'buffer',
        DRAW:'draw'
      })
  
      const OVERLAY_TYPE = Object.freeze({
        MARKER: 'AMap.Marker',
        POLYLINE: 'AMap.Polyline',
        POLYGON: 'AMap.Polygon',
        RECTANGLE: 'AMap.Rectangle',
        CIRCLE: 'AMap.Circle',
      })
  
      return class GaoDeMapUtils {
  
        //绘制功能默认样式
        static MOUSE_TOOLS = Object.freeze({
          POLYLINE: {
            key: 'polyline',
            isBuffer: true,
            units:'米',
            textOffset:[-20,-20],
            defaultOptions: {
              strokeColor: "#3366FF",
              strokeOpacity: 1,
              strokeWeight: 6,
              // 线样式还支持 'dashed'
              strokeStyle: "solid",
            },
          },
          POLYGON: {
            key: 'polygon',
            isBuffer: true,
            units:'平方米',
            textOffset:[20,20],
            defaultOptions: {
              strokeColor: "#FF33FF",
              strokeWeight: 6,
              strokeOpacity: 0.2,
              fillColor: '#1791fc',
              fillOpacity: 0.4,
              // 线样式还支持 'dashed'
              strokeStyle: "dashed",
              // strokeStyle是dashed时有效
              strokeDasharray: [30, 10],
            }
          },
          RECTANGLE: {
            key: 'rectangle',
            isBuffer: true,
            defaultOptions: {
              strokeColor: 'red',
              strokeOpacity: 0.5,
              strokeWeight: 6,
              fillColor: 'blue',
              fillOpacity: 0.5,
              // strokeStyle还支持 solid
              strokeStyle: 'solid',
              // strokeDasharray: [30,10],
            }
          },
          CIRCLE: {
            key: 'circle',
            isBuffer: true,
            defaultOptions: {
              strokeColor: "#FF33FF",
              strokeWeight: 6,
              strokeOpacity: 0.2,
              fillColor: '#1791fc',
              fillOpacity: 0.4,
              strokeStyle: 'solid',
              // 线样式还支持 'dashed'
              // strokeDasharray: [30,10],
            }
          },
          MARKER: {
            key: 'marker',
            isBuffer: true,
            defaultOptions: {
              icon: 'https://a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png',
              anchor: 'bottom-center',
            }
          },
          MEASURE_AREA: {
            key: 'measureArea',
            defaultOptions: {
              strokeColor: "#FF33FF",
              strokeWeight: 6,
              strokeOpacity: 0.2,
              fillColor: '#1791fc',
              fillOpacity: 0.4,
              // 线样式还支持 'dashed'
              strokeStyle: "dashed",
              // strokeStyle是dashed时有效
              strokeDasharray: [30, 10],
            }
          },
          MEASURE_LINE: {
            key: 'rule',
            defaultOptions: {
              strokeColor: "#FF33FF",
              strokeWeight: 6,
              strokeOpacity: 0.2,
              strokeStyle: "dashed",
            }
          }
        })
  
        //存储所有由高德api实例化对象
        _gdObjects = {
          map: null,
          popup: null,
          geometrys: [],
          mouseTool: null
        };
  
        // constructor(container, options = {}) {
        //   this.init(container, options.init);
        // }
  
  
        constructor(container, options = {}, map) {
          if(!!map){
            this._gdObjects.map = map
          }else{
            this._gdObjects.map = this.init(container, options.init);
          }
        }
  
        init (container, options = {}) {
          if (!!!container || !!!document.getElementById(container)) throw new Error(`id为:${container}容器的容器无法被初始化,请检查`);
          return new AMap.Map(container, Object.assign({}, DEFAULT_CONFIG, options));
        }
  
        // init (container, options = {}) {
        //   if (!!!container || !!!document.getElementById(container)) throw new Error(`id为:${container}容器的容器无法被初始化,请检查`);
        //   this._gdObjects.map = new AMap.Map(container, Object.assign({}, DEFAULT_CONFIG, options));
        // }
  
        //绘制功能
        draw (type, style) {
          let self = this;
          GaoDeMapUtils.isMouseTools(type);
          let plugins = ['AMap.MouseTool'];
          plugins = plugins.filter(plugin => !!!window[plugin]);
          return new Promise((res, rej) => {
            self._gdObjects.map.plugin(plugins, () => {
              if (!!!self._gdObjects.mouseTool) self._gdObjects.mouseTool = new AMap.MouseTool(self._gdObjects.map);
              self._gdObjects.mouseTool.on('draw', (event) => {
                let geojson = GaoDeMapUtils.overlayToGeoJSON(event.obj);
                let number = 0;
                if(!!event.obj.getLength) number = event.obj.getLength();
                if(!!event.obj.getArea) number = event.obj.getArea();
                self.closeDraw(false);
                if(!!type.units){
                  let center = turf.coordAll(turf.center(geojson))[0];
                  let text = GaoDeMapUtils.setOverlayText(center,number + type.units,type.textOffset);
                  text.gdType = FEATURE_TYPE.DRAW;
                  self._gdObjects.geometrys.push(text);
                  self._gdObjects.map.add(text);
                }
                res(geojson,number);
              })
              self._gdObjects.mouseTool[type.key](Object.assign({}, type.defaultOptions, style));
            })
          })
        }
  
        drawBuffer (type, style, scope) {
          if (!!!turf) throw new Error(`当前未检测到turf环境依赖,请添加后再次调用该方法`);
          let self = this;
          let plugins = ['AMap.GeoJSON'];
          plugins = plugins.filter(plugin => !!!window[plugin]);
          return new Promise((res, rej) => {
            self._gdObjects.map.plugin(plugins, () => {
              self.draw(type, style).then((geojson,number) => {
                let geometry = turf.buffer(geojson.features[0], scope, { units: 'kilometers' });
                let buffer = turf.featureCollection([geometry]);
                let bufferId = GaoDeMapUtils.uniqueId();
                let area = 0;
                let geoOverlay = new AMap.GeoJSON({
                  geoJSON: buffer,
                  getPolygon: (geo, lnglats) => {
                    let type_ = GaoDeMapUtils.MOUSE_TOOLS.POLYGON;
                    let polygon = new AMap.Polygon({ path: lnglats, ...Object.assign({}, type_.defaultOptions, style) });
                    polygon.gdID = bufferId;
                    polygon.gdType = FEATURE_TYPE.BUFFER;
                    let center = turf.coordAll(turf.center(buffer))[0];
                    let text = GaoDeMapUtils.setOverlayText(center,polygon.getArea() + type_.units,type_.textOffset);
                    text.gdType = FEATURE_TYPE.BUFFER;
                    text.gdID = bufferId;
                    self._gdObjects.geometrys.push(text);
                    self._gdObjects.map.add(text);
                    self._gdObjects.geometrys.push(polygon);
                    area = polygon.getArea();
                    return polygon;
                  }
                });
                geoOverlay.gdID = bufferId;
                self._gdObjects.map.add(geoOverlay);
                res({ geojson, buffer, bufferId,drawC:number,bufferC:area});
              })
            })
          })
        }
  
        geojsonToMap (geojson, style) {
          let self = this;
          if (!!!geojson.features || !!!geojson.features.length) throw new Error(`参数有误!请调整参数后再次调用;geojson:${geojson}`);
          let plugins = ['AMap.GeoJSON'];
          plugins = plugins.filter(plugin => !!!window[plugin]);
          return new Promise((res, rej) => {
            self._gdObjects.map.plugin(plugins, () => {
              let id = GaoDeMapUtils.uniqueId();
              let geoOverlay = new AMap.GeoJSON({
                geoJSON: geojson,
                getPolygon: (geo, lnglats) => {
                  let polygon = new AMap.Polygon({path: lnglats, ...Object.assign({}, GaoDeMapUtils.MOUSE_TOOLS.POLYGON.defaultOptions, style)});
                  let center = turf.coordAll(turf.center(geo))[0];
                  let type = GaoDeMapUtils.MOUSE_TOOLS.POLYGON;
                  let text = GaoDeMapUtils.setOverlayText(center, polygon.getArea() + type.units,type.textOffset);
                  polygon.gdID = id;
                  text.gdID = id;
                  self._gdObjects.geometrys.push(polygon);
                  self._gdObjects.geometrys.push(text);
                  self._gdObjects.map.add(text);
                  return polygon;
                },
                getMarker: (geo, lnglats) => {
                  let marker = new AMap.Marker({ position: lnglats, ...Object.assign({}, GaoDeMapUtils.MOUSE_TOOLS.MARKER.defaultOptions, style) });
                  marker.gdID = id;
                  self._gdObjects.geometrys.push(marker);
                  return marker;
                },
                getPolyline: (geo, lnglats) => {
                  let polyline = new AMap.Polyline({ path: lnglats, ...Object.assign({}, GaoDeMapUtils.MOUSE_TOOLS.POLYLINE.defaultOptions, style) });
                  let center = turf.coordAll(turf.center(geo))[0];
                  let type = GaoDeMapUtils.MOUSE_TOOLS.POLYLINE;
                  let text = GaoDeMapUtils.setOverlayText(center, polyline.getLength() + type.units,type.textOffset);
                  polyline.gdID = id;
                  text.gdID = id;
                  self._gdObjects.geometrys.push(polyline);
                  self._gdObjects.geometrys.push(text);
                  self._gdObjects.map.add(text);
                  return polyline;
                }
              });
              self._gdObjects.map.add(geoOverlay);
              res({ id, geometrys: geoOverlay.getOverlays() })
            })
          });
        }
  
        closeDraw (clear = true) {
          let self = this;
          if (self._gdObjects.mouseTool) {
            self._gdObjects.mouseTool.close(clear);
            self.removeFeaturesByTypes([FEATURE_TYPE.DRAW]);
          }
          if (clear) self.removeFeaturesByTypes([FEATURE_TYPE.BUFFER]);
        }
  
        removeFeaturesByIds (ids = []) {
          let self = this;
          let geometrys = self._gdObjects.geometrys.filter(i => !!!ids.length || ids.includes(i.gdID));
          if (!!!geometrys.length) return;
          self._gdObjects.map.remove(geometrys);
          self._gdObjects.geometrys = self._gdObjects.geometrys.filter(i => !!!ids.includes(i.gdID));
        }
  
        removeFeaturesByTypes (types = []) {
          let self = this;
          let geometrys = self._gdObjects.geometrys.filter(i => !!!types.length || types.includes(i.gdType));
          if (!!!geometrys.length) return;
          self._gdObjects.map.remove(geometrys);
          self._gdObjects.geometrys = self._gdObjects.geometrys.filter(i => !!!types.includes(i.gdType));
        }
  
        static isMouseTools (type) {
          let mouseTool = Object.keys(GaoDeMapUtils.MOUSE_TOOLS).filter(key => GaoDeMapUtils.MOUSE_TOOLS[key] == type)[0];
          if (!!!mouseTool) throw new Error(`当前type对象无法被识别请通过GaoDeMapUtils.MOUSE_TOOLS属性设置该参数`);
        }
  
        static overlayToGeoJSON (overlay) {
          if (!!!turf) throw new Error(`当前未检测到turf环境依赖,请添加后再次调用该方法`);
          return {
            [OVERLAY_TYPE.MARKER]: () => turf.featureCollection([turf.point(overlay.getPosition().toArray())]),
            [OVERLAY_TYPE.POLYLINE]: () => turf.featureCollection([turf.lineString(overlay.getPath().map(path => path.toString().split(",").map(item => Number(item))))]),
            [OVERLAY_TYPE.POLYGON]: () => turf.featureCollection([overlay.toGeoJSON()]),
            [OVERLAY_TYPE.CIRCLE]: () => turf.featureCollection([turf.circle(overlay.getCenter().toJSON(), overlay.getRadius() * 0.001, { steps: overlay.getRadius(), units: 'kilometers' })]),
            [OVERLAY_TYPE.RECTANGLE]: () => {
              let { northEas, southWest } = overlay.getBounds();
              return turf.featureCollection([turf.bboxPolygon([southWest.lng, northEas.lat, northEas.lng, southWest.lat])]);
            },
          }[overlay.CLASS_NAME]();
        }
  
        static setOverlayText(position,text,offset = [-20, -20]){
          return new AMap.Text({
            position:new AMap.LngLat(...position),
            text,
            offset: new AMap.Pixel(...offset)
          })
        }
  
        static uniqueId () {
          return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
        }
      }
    }))
  })();