| | |
| | | import AMapLoader from '@amap/amap-jsapi-loader'; |
| | | import _ from 'lodash'; |
| | | |
| | | import { defaultsDeep } from 'lodash-es'; |
| | | export type AMapInstance = typeof AMap; |
| | | export type GaoDePosition = [number, number]; |
| | | export type GaoDeMapOption = { |
| | |
| | | version?: string; |
| | | plugins?: string[]; |
| | | container: string | HTMLDivElement; |
| | | aMapOption?: Partial<AMap.MapOptions>; |
| | | aMapOption?: Partial<AMap.MapOptions> & Record<string, any>; |
| | | }; |
| | | |
| | | export type GaoDeMarkerOption = { |
| | | icon: { |
| | | url: string; |
| | | /** @description 选中时的图片 */ |
| | | selectUrl?: string; |
| | | size: number; |
| | | }; |
| | | click?: (e: any, labelMarker: AMap.LabelMarker) => void; |
| | | }; |
| | | export type LabelMarkerData = { |
| | | position: GaoDePosition; |
| | | |
| | | title?: string; |
| | | textColor?: string; |
| | | extData?: any; |
| | | }; |
| | | export type MarkerLayerOption = { |
| | | // 设置 allowCollision:true,可以让标注避让用户的标注 |
| | | layerOpt?: AMap.LabelsLayerOptions; |
| | | markerOpt: GaoDeMarkerOption; |
| | | }; |
| | | |
| | | export class GaoDeMap { |
| | | map: AMap.Map; |
| | | AMap: AMapInstance; |
| | | private viewBound: AMap.Bounds; |
| | | async init(option: GaoDeMapOption) { |
| | | const gaoDeOption = _.defaultsDeep(option, { |
| | | const gaoDeOption = defaultsDeep(option, { |
| | | key: '3627ed9deaac2622e26a7169f0c36b1b', // 申请好的Web端开发者Key,首次调用 load 时必填 |
| | | version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15 |
| | | plugins: [ |
| | |
| | | // 'AMap.MarkerCluster', |
| | | // 'AMap.InfoWindow', |
| | | ], // 需要使用的的插件列表,如比例尺'AMap.Scale'等 |
| | | |
| | | // AMapUI:{ |
| | | // version: '1.1', |
| | | // }, |
| | | aMapOption: { |
| | | viewMode: '2D', //默认使用 2D 模式 |
| | | zoom: 5, //地图级别 |
| | |
| | | } as Partial<AMap.MapOptions>, |
| | | } as Partial<GaoDeMapOption>) as GaoDeMapOption; |
| | | try { |
| | | const AMap = await AMapLoader.load({ |
| | | this.AMap = await AMapLoader.load({ |
| | | key: gaoDeOption.key, |
| | | version: gaoDeOption.version, |
| | | plugins: gaoDeOption.plugins, |
| | | }); |
| | | this.map = new AMap.Map(gaoDeOption.container, gaoDeOption.aMapOption); |
| | | |
| | | this.map = new this.AMap.Map(gaoDeOption.container, gaoDeOption.aMapOption); |
| | | this.setStyle(); |
| | | } catch (error) { |
| | | // console.error(error); |
| | | } |
| | | } |
| | | constructor() {} |
| | | |
| | | private setStyle() { |
| | | const container = this.map.getContainer() as any; |
| | | /** |
| | | * 隐藏高德相关标志 |
| | | */ |
| | | container.querySelector('.amap-logo').style.opacity = 0; |
| | | container.querySelector('.amap-copyright').style.opacity = 0; |
| | | } |
| | | |
| | | zoomToRect(southWest: GaoDePosition, northEast: GaoDePosition) { |
| | | if (!this.viewBound) { |
| | |
| | | this.map.setBounds(this.viewBound); |
| | | } |
| | | |
| | | applyBasicPlugins() { |
| | | // const scale = new AMap.Scale(); |
| | | // this.map.addControl(scale) |
| | | // const toolbar = new AMap.ToolBar(); |
| | | // this.map.addControl(toolbar) |
| | | } |
| | | |
| | | applyBasicPlugins(){ |
| | | // const scale = new AMap.Scale(); |
| | | // this.map.addControl(scale) |
| | | // const toolbar = new AMap.ToolBar(); |
| | | // this.map.addControl(toolbar) |
| | | } |
| | | addMarkerLayer(dataList: LabelMarkerData[], option: MarkerLayerOption) { |
| | | const markerLayerOption = defaultsDeep(option, { |
| | | layerOpt: { |
| | | zooms: [3, 20], |
| | | zIndex: 1000, |
| | | allowCollision: false, |
| | | }, |
| | | } as MarkerLayerOption) as MarkerLayerOption; |
| | | |
| | | const layer = new AMap.LabelsLayer(markerLayerOption.layerOpt); |
| | | const { markerOpt } = markerLayerOption; |
| | | const { icon } = markerOpt; |
| | | |
| | | const convertData = (dataList ?? []).map<AMap.LabelMarkerOptions>((item) => { |
| | | return { |
| | | // name: '自提点9', |
| | | position: item.position, |
| | | zIndex: 2, |
| | | opacity: 1, |
| | | icon: { |
| | | // 图标类型,现阶段只支持 image 类型 |
| | | type: 'image', |
| | | // 图片 url |
| | | image: icon.url, |
| | | // 图片尺寸 |
| | | size: [icon.size, icon.size], |
| | | // 图片相对 position 的锚点,默认为 bottom-center |
| | | anchor: 'center', |
| | | }, |
| | | text: { |
| | | content: item.title, |
| | | direction: 'right', |
| | | offset: [-5, -5], |
| | | style: { |
| | | fontSize: 10, |
| | | fontWeight: 'normal', |
| | | fillColor: item.textColor, |
| | | strokeColor: '#fff', |
| | | strokeWidth: 2, |
| | | fold: true, |
| | | padding: '2, 5', |
| | | }, |
| | | }, |
| | | extData: item.extData, |
| | | }; |
| | | }); |
| | | |
| | | const markerList = convertData.map((item) => { |
| | | const label = new AMap.LabelMarker(item); |
| | | |
| | | label.on('click', (e) => { |
| | | if (icon.selectUrl) { |
| | | setTimeout(() => { |
| | | label.setIcon({ |
| | | image: icon.selectUrl, |
| | | }); |
| | | }, 30); |
| | | } |
| | | markerOpt.click?.(e, label); |
| | | }); |
| | | return label; |
| | | }); |
| | | |
| | | layer.add(markerList); |
| | | this.map.add(layer); |
| | | } |
| | | } |