| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- import NetService from '@/services/net.service'
- import { injectable, Service } from '@/services/service'
- import AMapLoader from '@amap/amap-jsapi-loader'
- import { useNotification } from 'naive-ui'
- import useStore from '@/pages/store/index'
- import carIcon from '@/assets/img/39.svg'
- @injectable
- export default class MapService extends Service {
- private netService = new NetService()
- private notification = useNotification()
- private store = useStore()
- private key = ''
- public Maps = null as Any
- public AMaps = null as Any
- public marks = {} as Any
- private getAllRings(feature: { geometry: { coordinates: Any[]; }; }) {
- const coords = feature.geometry.coordinates
- const rings = []
- for (let i = 0, len = coords.length; i < len; i++) {
- rings.push(coords[i][0])
- }
- return rings
- }
- private getLongestRing(feature: { geometry: { coordinates: Any[]; }; }) {
- const rings = this.getAllRings(feature)
- rings.sort((a, b) => b.length - a.length)
- return rings[0]
- }
- private colorRandom() {
- const r = Math.floor(Math.random() * 256)
- const g = Math.floor(Math.random() * 256)
- const b = Math.floor(Math.random() * 256)
- return `#${r.toString(16)}${g.toString(16)}${b.toString(16)}`
- }
- // 添加标点
- public addMark(position: number[], icon?: string, size?: { w: number, h: number }) {
- if (!this.Maps && !this.AMaps) return
- const mark = new this.AMaps!.Marker({
- position,
- cursor: 'pointer',
- icon: new this.AMaps.Icon({
- image: icon || carIcon,
- imageSize: new this.AMaps.Size(size?.w || 24, size?.h || 24)
- }),
- autoRotation: true,
- offset: new this.AMaps.Pixel(-5, -20),
- angle: 0,
- anchor: 'center',
- extData: '1'// 设置自定义属性
- })
- this.Maps.add(mark)
- return mark
- }
- // 添加路线
- public addLine(path: number[][], color?: string, width?: number) {
- if (!this.Maps && !this.AMaps) return
- const polyline = new this.AMaps.Polyline({
- path,
- strokeWeight: width || 5,
- borderWeight: width || 5, // 线条宽度,默认为 1
- strokeColor: color || 'red', // 线条颜色
- lineJoin: 'bevel', // 折线拐点连接处样式
- geodesic: true
- })
- this.Maps.add(polyline)
- return polyline
- }
- // 初始化地图
- public _initMap(zoom: number) {
- window._AMapSecurityConfig = {
- securityJsCode: '184c86be3bbd9a8a941bcaaf6b09c7cd'
- }
- return new Promise<void>((resolve, reject) => {
- AMapLoader.load({
- key: '0c5c83112cafefa77154769b4433c3df',
- version: '2.0',
- plugins: [ 'AMap.DistrictSearch', 'AMap.Weather', 'AMap.Bounds', 'AMap.Driving' ],
- AMapUI: {
- version: '1.1',
- plugins: [ 'geo/DistrictExplorer' ]
- }
- }).then((AMap) => {
- const map = new AMap.Map('container', { // 设置地图容器id
- zoom, // 设置当前显示级别
- expandZoomRange: true, // 开启显示范围设置
- zooms: [ 9, 20 ], // 最小显示级别为7,最大显示级别为20
- center: [ 103.062334, 30.012488 ], // 设置地图中心点位置
- mapStyle: 'amap://styles/grey'
- })
- // 限制位置 getBounds()
- const bounds = new AMap.Bounds(
- [ 103.395136, 30.936781 ], // 右上角经纬度 northEast
- [ 101.93598, 28.845463 ] // 左下角经纬度 southWest
- )
- map.setLimitBounds(bounds)
- // 天气
- const weather = new AMap.Weather()
- weather.getLive('雅安市', (err: any, data: Any) => {
- console.log('天气', err, data)
- if (err) {
- this.notification.warning({
- content: '天气获取失败',
- duration: 2000
- })
- return
- }
- this.store.setWeather(data)
- })
- // 镂空雅安 511800 adcode
- AMapUI.loadUI([ 'geo/DistrictExplorer' ], (DistrictExplorer: any) => {
- const districtExplorer = new DistrictExplorer({ map })
- districtExplorer.loadMultiAreaNodes([ 100000, 511800 ], (error: any, areaNodes: string | any[]) => {
- const countryNode = areaNodes[0]
- const cityNodes = areaNodes.slice(1)
- const path = []
- // 首先放置背景区域,这里是大陆的边界
- path.push(this.getLongestRing(countryNode.getParentFeature()))
- for (let i = 0, len = cityNodes.length; i < len; i++) {
- // 逐个放置需要镂空的市级区域
- path.push(...this.getAllRings(cityNodes[i].getParentFeature()))
- }
- // 绘制带环多边形
- const polygon = new AMap.Polygon({
- bubble: true,
- lineJoin: 'round',
- strokeColor: '#030E25', // 线颜色
- strokeOpacity: 1, // 线透明度
- strokeWeight: 1, // 线宽
- fillColor: '#030E25', // 填充色
- fillOpacity: 1, // 填充透明度
- map,
- path
- })
- })
- })
- this.Maps = map
- this.AMaps = AMap
- resolve()
- }).catch((er) => reject(er))
- })
- }
- // 初始化marks集合
- public _initMarks(key: string, checked: string[], item?: any) {
- this.key = key
- this.marks[key] = {}
- for (let k = 0; k < checked.length; k++) {
- const el = checked[k]
- const icon = item.option.find((er: { value: string }) => er.value === el)?.icon
- const newIcon = this.getIcon(icon)
- if (!this.marks[key][el]) this.marks[key][el] = {}
- if (key === 'homePage' && el !== 'bus') {
- // homePageMark
- this.getMarkData(el).then((res) => {
- // line 需要单独处理
- if (!res.length) return
- if (el === 'line') {
- for (let j = 0; j < res.length; j++) {
- const es = res[j]
- console.log('线还需要不同的Id')
- // 区分上下行
- // const upLinePaths = es.child.filter((ed: { direction: number }) => ed.direction === 1).sort((a: { stationNo: number }, b: { stationNo: number }) => a.stationNo - b.stationNo).map((ec: { lon: string; lat: string }) => ([ +ec.lon, +ec.lat ]))
- // const downLinePaths = es.child.filter((ed: { direction: number }) => ed.direction === 2).sort((a: { stationNo: number }, b: { stationNo: number }) => a.stationNo - b.stationNo).map((ec: { lon: string; lat: string }) => ([ +ec.lon, +ec.lat ]))
- // console.log('上行', upLinePaths)
- // console.log('下行', downLinePaths)
- // const color = this.colorRandom()
- // this.marks[this.key][el][es.paramId] = { markMap: this.addLine(upLinePaths, color) }
- // this.marks[this.key][el][es.paramId] = { markMap: this.addLine(downLinePaths, color) }
- }
- } else {
- for (let z = 0; z < res.length; z++) {
- const ez = res[z]
- this.marks[this.key][el][ez.paramId] = { ...ez, markMap: this.addMark([ +ez.lon, +ez.lat ], newIcon) }
- }
- }
- })
- }
- }
- }
- // 获取标点数据
- async getMarkData(type: string) {
- // line 线路 station 中途站点 maintenanceStation维修站 powerCharge充电桩 busStation场站
- const { data } = await this.netService.get(`/busLine/getMapElement?typeList=${type}`)
- return data || []
- }
- // 动态图标
- getIcon(imgName:string) {
- const url = new URL(`../../assets/img/${imgName}.svg`, import.meta.url).href
- return url
- }
- public destory() {
- if (Object.keys(this.marks).length) this.marks = {}
- if (this.Maps) this.Maps.destory()
- this.Maps = null
- this.AMaps = null
- }
- }
|