283 lines
7.9 KiB
TypeScript
283 lines
7.9 KiB
TypeScript
import { Component, Input, OnChanges, OnInit, Output, SimpleChanges, EventEmitter } from '@angular/core';
|
||
import { BaseService } from 'src/app/shared/services';
|
||
import { throwError } from 'rxjs';
|
||
import AMapLoader from '@amap/amap-jsapi-loader';
|
||
import { amapConf } from '@conf/amap.config';
|
||
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 {
|
||
aMap: any;
|
||
pathSimplifierIns: any;
|
||
geocoder: any;
|
||
navigator: any;
|
||
infoWindow: any;
|
||
markerList: any;
|
||
SimpleMarker: any;
|
||
@Input()
|
||
pathList: any = [];
|
||
@Input()
|
||
selectedIndex = 0;
|
||
@Input()
|
||
mapWidth = '800px';
|
||
@Input() MapList: any;
|
||
@Input()
|
||
mapHeight = '500px';
|
||
|
||
@Output()
|
||
clcikPointEvent = new EventEmitter<any>();
|
||
|
||
@Input()
|
||
pois: any = [];
|
||
private _pois: any = [];
|
||
|
||
constructor(public service: BaseService) {}
|
||
ngOnChanges(changes: SimpleChanges): void {
|
||
if (changes?.pathList?.currentValue && this?.pathSimplifierIns) {
|
||
this.setData(changes.pathList?.currentValue);
|
||
this.setPathIndex(this.selectedIndex);
|
||
}
|
||
if (changes?.MapList?.currentValue && this?.pathSimplifierIns && changes.MapList?.currentValue.length > 0) {
|
||
console.log(this.MapList);
|
||
this.pathList = [
|
||
{
|
||
name: '路线1',
|
||
points: changes.MapList?.currentValue
|
||
}
|
||
];
|
||
this.setData(this.pathList);
|
||
this.setPathIndex(this.selectedIndex);
|
||
this.getPoiByPositon(this.MapList[this.MapList?.length - 1]?.lnglat);
|
||
}
|
||
if (changes?.pois?.currentValue) {
|
||
// console.log(this.pois);
|
||
this._pois = changes?.pois?.currentValue;
|
||
if (this?.markerList && this._pois.length > 0) {
|
||
this.markerList.render(this._pois);
|
||
}
|
||
}
|
||
}
|
||
ngOnInit(): void {
|
||
this.mapInit();
|
||
}
|
||
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.infoWindow = new AMap.InfoWindow({
|
||
offset: new AMap.Pixel(0, -40)
|
||
});
|
||
this.geocoder = new AMap.Geocoder({
|
||
radius: 1000 //范围,默认:500
|
||
});
|
||
// this.service.msgSrv.info('地图加载完成 !');
|
||
this.pathInit();
|
||
this.setPOIS();
|
||
});
|
||
})
|
||
.catch(e => {
|
||
throwError(e);
|
||
});
|
||
}
|
||
|
||
pathInit() {
|
||
this.pathSimplifierIns = new AMapUI.PathSimplifier({
|
||
zIndex: 100,
|
||
//autoSetFitView:false,
|
||
map: this.aMap, //所属的地图实例
|
||
|
||
getPath: function (pathData: any, pathIndex: any) {
|
||
var points = pathData.points,
|
||
lnglatList = [];
|
||
|
||
for (var i = 0, len = points?.length; i < len; i++) {
|
||
lnglatList.push(points[i].lnglat);
|
||
}
|
||
|
||
return lnglatList;
|
||
},
|
||
getHoverTitle: function (pathData: any, pathIndex: any, pointIndex: any) {
|
||
if (pointIndex >= 0) {
|
||
//point
|
||
return pathData.name + ',' + pathData.points[pointIndex].name;
|
||
}
|
||
return '';
|
||
},
|
||
renderOptions: {
|
||
renderAllPointsIfNumberBelow: 10 //绘制路线节点,如不需要可设置为-1
|
||
}
|
||
});
|
||
(window as any).pathSimplifierIns = this.pathSimplifierIns;
|
||
this.setData(this.pathList);
|
||
|
||
if (this.pathList.length > 0) {
|
||
this.setPathIndex(this.selectedIndex);
|
||
}
|
||
|
||
this.pathSimplifierIns.on('pointClick', (e: any, info: any) => {
|
||
this.clcikPointEvent.emit({ e, info });
|
||
console.log('Click: ' + info.pathData.points[info.pointIndex].name);
|
||
});
|
||
}
|
||
|
||
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: any) => {
|
||
return dataItem.position;
|
||
},
|
||
//返回数据项对应的Marker
|
||
getMarker: (dataItem: any, context: any, recycledMarker: any) => {
|
||
//存在可回收利用的marker
|
||
if (recycledMarker) {
|
||
//直接更新内容返回
|
||
recycledMarker.setIconLabel(context.id);
|
||
recycledMarker.setIconStyle(dataItem.iconStyle);
|
||
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: any, context: any, recycledInfoWindow: any) => {
|
||
this.selectedPOI(dataItem);
|
||
return null;
|
||
}
|
||
});
|
||
|
||
if (this._pois?.length > 0) {
|
||
//展示该数据
|
||
this.markerList.render(this._pois);
|
||
}
|
||
});
|
||
}
|
||
|
||
setData(pathList: Array<any>) {
|
||
this.pathSimplifierIns.setData(pathList);
|
||
}
|
||
|
||
setPathIndex(index: number) {
|
||
this.pathSimplifierIns.setSelectedPathIndex(index);
|
||
this.startNav();
|
||
}
|
||
|
||
startNav() {
|
||
if (this.navigator) {
|
||
this.navigator.start();
|
||
} else {
|
||
this.navigator = this.pathSimplifierIns?.createPathNavigator(0, {
|
||
loop: true, //循环播放
|
||
speed: 1000000 //巡航速度,单位千米/小时
|
||
});
|
||
this.navigator?.start();
|
||
}
|
||
}
|
||
|
||
/** 根据经纬度获取地址信息 */
|
||
getPoiByPositon(position: Array<string>) {
|
||
this.geocoder.getAddress(position, (status: any, result: any) => {
|
||
if (status === 'complete' && result.info === 'OK') {
|
||
// result中对应详细地理坐标信息
|
||
this._pois = [...this.pois, { markerLabel: '终', color: 'red', position: position, title: result.regeocode.formattedAddress }];
|
||
if (this.markerList) {
|
||
this.markerList.render(this._pois);
|
||
}
|
||
// this.setPOI({ markerLabel: '终', color: 'red', position: position });
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 选中标点,设置窗口信息
|
||
* @param location
|
||
*/
|
||
selectedPOI(location: any) {
|
||
this.infoWindow.setContent(`地址: <pre>${location.title}</pre>`);
|
||
this.infoWindow.open(this.aMap, location.position);
|
||
this.infoWindow.setPosition(location.position);
|
||
this.aMap.setCenter(location.position);
|
||
}
|
||
|
||
/**
|
||
* 增加标记点
|
||
* @param poi
|
||
*/
|
||
setPOI(poi: POI) {
|
||
AMapUI.loadUI(['overlay/SimpleMarker'], (SimpleMarker: any) => {
|
||
//启动页面
|
||
new SimpleMarker({
|
||
//普通文本
|
||
iconLabel: {
|
||
//普通文本
|
||
innerHTML: poi.markerLabel,
|
||
//设置样式
|
||
style: {
|
||
color: '#fff',
|
||
fontSize: '110%',
|
||
marginTop: '2px'
|
||
}
|
||
},
|
||
iconStyle: poi.color,
|
||
map: this.aMap,
|
||
position: poi.position
|
||
});
|
||
});
|
||
}
|
||
}
|
||
|
||
export interface POI {
|
||
markerLabel: string;
|
||
color: string;
|
||
position: Array<string>;
|
||
}
|