Files
bbq/src/app/shared/components/amap/amap-path-simplifier/amap-path-simplifier.component.ts
Taric Xin 859da91fac edit
2022-04-12 20:36:42 +08:00

327 lines
9.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import AMapLoader from '@amap/amap-jsapi-loader';
import { Component, Input, OnChanges, OnInit, Output, SimpleChanges, EventEmitter, OnDestroy } from '@angular/core';
import { amapConf } from '@conf/amap.config';
import { InputNumber } from '@delon/util';
import { throwError } from 'rxjs';
import { BaseService } from 'src/app/shared/services';
import { AmapService, InfoItem, MapList, PathList, POI } from '../amap.service';
declare var AMap: any;
declare var AMapUI: any;
declare var Loca: any;
const CONFIG = amapConf;
@Component({
selector: 'amap-path-simplifier',
templateUrl: './amap-path-simplifier.component.html',
styleUrls: ['./amap-path-simplifier.component.less']
})
export class AmapPathSimplifierComponent implements OnInit, OnChanges, OnDestroy {
aMap: any;
pathSimplifierIns: any;
geocoder: any;
navigator: any;
infoWindow: any;
markerList: any;
SimpleMarker: any;
// 简单路径信息
@Input()
mapList: MapList[] = [];
// 完整路线图信息
@Input()
pathList: PathList[] = [];
// 当前选中路线图下标
@Input()
selectedIndex = 0;
// 巡航倍数
@InputNumber()
navSpeed = 1;
// 标点数组
@Input()
pois: POI[] = [];
private _pois: any = [];
@Input()
mapWidth = '800px';
@Input()
mapHeight = '500px';
@Output()
readonly clcikPointEvent = new EventEmitter<any>();
constructor(public service: BaseService, private amapService: AmapService) {
this.mapInit();
}
ngOnChanges(changes: SimpleChanges): void {
// 路线图变更: 设置路线图, 指定路线图
if (changes?.pathList?.currentValue && this?.pathSimplifierIns) {
this.setData(changes.pathList?.currentValue);
this.setPathIndex(this.selectedIndex);
}
// 路径信息变更: 更新路线图, 设置路线图, 指定路线图, 获取终点地址信息并标点
if (changes?.mapList?.currentValue) {
// console.log(this.mapList);
this.pathList = [
{
name: '路线1',
points: changes.mapList?.currentValue
}
];
if (this?.pathSimplifierIns) {
this.setData(this.pathList);
if (changes.mapList?.currentValue.length > 0) {
this.setPathIndex(this.selectedIndex);
this.getPoiByPositon('起', this.mapList[0]?.lnglat, '时间:' + this.amapService.formatTime(this.mapList[0]?.time));
this.getPoiByPositon(
'终',
this.mapList[this.mapList?.length - 1]?.lnglat,
'时间:' + this.amapService.formatTime(this.mapList[this.mapList?.length - 1]?.time)
);
}
}
}
// 标点列表变更: 更新标点数据, 绘画标点
if (changes?.pois?.currentValue) {
console.log(changes?.pois?.currentValue);
this._pois = changes?.pois?.currentValue;
if (this?.markerList && this._pois.length > 0) {
this.markerList.render(this._pois);
}
}
}
ngOnInit(): void {}
ngOnDestroy(): void {
// 销毁地图数据
if (this.aMap) {
this.aMap.destroy();
}
}
/** 地图初始化 */
mapInit() {
AMapLoader.load({
key: CONFIG.key,
version: CONFIG.version,
plugins: [
// 需要使用的的插件列表,如比例尺'AMap.Scale'等
'AMap.PathSimplifier',
'AMap.InfoWindow',
'AMap.Geocoder'
],
AMapUI: {
version: CONFIG.AMapUIVersion,
plugins: ['misc/PathSimplifier'] // 需要加载的 AMapUI ui插件
}
})
.then(AMap => {
this.aMap = new AMap.Map('container', {
zoom: 10
});
this.aMap.on('complete', () => {
// this.service.msgSrv.info('地图加载完成 !');
// 信息窗口
this.infoWindow = new AMap.InfoWindow({
offset: new AMap.Pixel(0, -40)
});
// 初始化定位工具
this.geocoder = new AMap.Geocoder({
radius: 500 //范围默认500
});
this.pathInit();
this.setPOIS();
});
})
.catch(e => {
throwError(e);
});
}
/** 初始化路径工具 */
pathInit() {
this.pathSimplifierIns = new AMapUI.PathSimplifier({
zIndex: 100,
//autoSetFitView:false,
map: this.aMap,
// 重组路径数据
getPath: (pathData: PathList, pathIndex: number) => pathData.points.map(points => points.lnglat),
// 鼠标悬浮事件
getHoverTitle: (pathData: PathList, pathIndex: number, pointIndex: number) => '',
renderOptions: {
renderAllPointsIfNumberBelow: 20 //绘制路线节点,如不需要可设置为-1
}
});
this.setData(this.pathList);
if (this.pathList.length > 0) {
this.setPathIndex(this.selectedIndex);
this.getPoiByPositon('起', this.mapList[0]?.lnglat, '时间:' + this.amapService.formatTime(this.mapList[0]?.time));
this.getPoiByPositon(
'终',
this.mapList[this.mapList?.length - 1]?.lnglat,
'时间:' + this.amapService.formatTime(this.mapList[this.mapList?.length - 1]?.time)
);
}
this.pathSimplifierIns.on('pointClick', (e: any, info: any) => {
this.clcikPointEvent.emit({ e, info });
// 弹出信息窗口
if (info) {
this.geocoder.getAddress(info.pathData.points[info.pointIndex].lnglat, (status: any, result: any) => {
if (status === 'complete' && result.info === 'OK') {
// result中对应详细地理坐标信息
this.selectedPOI({
position: info.pathData.points[info.pointIndex].lnglat,
content: `
<label style="font-weight: bold;">${result.regeocode.formattedAddress}<label/><br/>
<label style="font-weight: 400;">车速: ${info.pathData.points[info.pointIndex].name}<label/><br/>
<label style="font-weight: 400;">时间: ${this.amapService.formatTime(info.pathData.points[info.pointIndex].time)}<label/>
`
});
}
});
}
});
}
/** 初始化标点工具 */
setPOIS() {
AMapUI.loadUI(['misc/MarkerList', 'overlay/SimpleMarker'], (MarkerList: any, SimpleMarker: any) => {
this.markerList = new MarkerList({
//关联的map对象
map: this.aMap,
//返回数据项的位置信息需要是AMap.LngLat实例或者是经纬度数组比如[116.789806, 39.904989]
getPosition: (dataItem: POI) => dataItem.position,
//返回数据项对应的Marker
getMarker: (dataItem: POI, context: any, recycledMarker: any) => {
//存在可回收利用的marker
// if (recycledMarker) {
// //直接更新内容返回
// recycledMarker.setIconLabel(context.id);
// recycledMarker.setIconStyle(dataItem.color);
// return recycledMarker;
// }
this.SimpleMarker = SimpleMarker;
//返回一个新的Marker
return new SimpleMarker({
//普通文本
iconLabel: {
//普通文本
innerHTML: dataItem.markerLabel,
//设置样式
style: {
color: '#fff',
fontSize: '110%',
marginTop: '2px'
}
},
iconStyle: dataItem.color,
map: this.aMap,
position: dataItem.position
});
},
//返回数据项对应的infoWindow
getInfoWindow: (dataItem: POI, context: any, recycledInfoWindow: any) => {
this.selectedPOI(dataItem);
return null;
}
});
if (this._pois?.length > 0) {
console.log(this._pois);
//展示该数据
this.markerList.render(this._pois);
}
});
}
/**
* 设置路线图数据
* @param pathList
*/
setData(pathList: PathList[]) {
this.pathSimplifierIns.setData(pathList);
}
/**
* 指定路线图
* @param index
*/
setPathIndex(index: number) {
this.pathSimplifierIns.setSelectedPathIndex(index);
this.startNav();
}
/**
* 开启巡航
*/
startNav() {
this.navigator = this.pathSimplifierIns?.createPathNavigator(this.selectedIndex, {
loop: true, //循环播放
speed: 50000 * this.navSpeed //巡航速度,单位千米/小时
});
this.navigator?.start();
}
changeMultiple(multiple: number) {
if (multiple <= 0) {
this.navSpeed = 1;
return;
} else {
this.navSpeed = multiple;
this.resetNav();
}
}
/** 重置巡航 */
resetNav() {
if (this.navigator) {
this.navigator.destroy();
setTimeout(() => {
this.startNav();
}, 200);
} else {
this.startNav();
}
}
/** 根据标点经纬度获取地址信息 */
getPoiByPositon(label: string, position: string[], time: string) {
this.geocoder.getAddress(position, (status: any, result: any) => {
if (status === 'complete' && result.info === 'OK') {
// result中对应详细地理坐标信息
this._pois = [
...this.pois,
{ markerLabel: label, color: 'red', position, title: result.regeocode.formattedAddress, time }
];
if (this.markerList) {
this.markerList.render(this._pois);
}
}
});
}
/**
* 选中标点,设置窗口信息
*
* @param infoItem
*/
selectedPOI(infoItem: InfoItem) {
this.infoWindow.setContent(
infoItem.content ||
`
<label style="font-weight: bold;">${infoItem.title}</label><br/>
东经:${infoItem.position?.[0]}, 北纬:${infoItem.position?.[1]}<br/>
${infoItem.time}
`
);
this.infoWindow.open(this.aMap, infoItem.position);
this.infoWindow.setPosition(infoItem.position);
// 地图定位居中
this.aMap.setCenter(infoItem.position);
}
}