327 lines
9.7 KiB
TypeScript
327 lines
9.7 KiB
TypeScript
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);
|
||
}
|
||
}
|