import * as maptalks from "maptalks";
// import {
// RoutePlayer,
// getAllPointsArr,
// } from "^/assets/js/maptalks.routeplayer.es.js";
import { RoutePlayer } from "^/assets/js/maptalks.routeplayer.js";
import convertor from "chncrs";
import { createInfoWindow } from "^/composables/infoWindow";
import type {
WSCarCoordinate,
WSCarStatus,
CarMarkerData,
Coordinate,
LineColor,
InfoWindowCallback,
ChangeModeCallback,
AnimateiHstoryCarPath,
InfoWindowData,
MarkerLocation,
BaseParameterData,
DispatchMarker,
AreaData,
} from "@/map";
import { infoWindowData } from "^/hook/infoWindow";
import utils from "^u/utils";
// 警车基础配置参数对象
import POLICE_CAR_CONFIG from "../../config/config";
import dispatchSvg from "^/assets/svg/icons/调度点-dispatch.svg";
import type { ElSkeleton } from "element-plus";
const HBmap_base_config = (
cssFilter: string,
spatialReference: any,
tileSystem: any[]
) => ({
urlTemplate: POLICE_CAR_CONFIG.MAP_URL,
// 替换url中的子域 ?不是很理解
subdomains: ["a", "b", "c", "d"],
cssFilter,
// 图片没出来 站位用的
placeholder: true,
// 平铺图像的 crossOrigin 跨域
crossOrigin: "anonymous",
// offset: offset as unknown as number[],
//设置瓦片图层的空间参考spatialReference默认就是3857,googlemap的分辨率
spatialReference,
//tileSystem 控制瓦片的x,y以及行列,后两个是origin原点位置(很重要)
tileSystem,
// 是否启用此地图上光标样式图层的命中检测,禁用它以提高性能。(鼠标检测)
hitDetect: false,
});
const GAODEmap_base_config = (
cssFilter: string,
spatialReference: any,
tileSystem: any[]
) => ({
// urlTemplate:
// "http://wprd{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&z={z}&x=&y={y}&scl=1<ype=11",
// // 替换url中的子域 ?不是很理解
// subdomains: ["01", "02", "03", "04"],
urlTemplate:
"http://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x=&y={y}&z={z}",
subdomains: ["0", "1", "2", "3"],
cssFilter,
// 图片没出来 站位用的
placeholder: true,
// 平铺图像的 crossOrigin 跨域
crossOrigin: "anonymous",
// offset: offset as unknown as number[],
//设置瓦片图层的空间参考spatialReference默认就是3857,googlemap的分辨率
spatialReference,
//tileSystem 控制瓦片的x,y以及行列,后两个是origin原点位置(很重要)
tileSystem,
// 是否启用此地图上光标样式图层的命中检测,禁用它以提高性能。(鼠标检测)
hitDetect: false,
});
// 高德卫星图
const GAODEmap_satellite_base_config = (
cssFilter: string,
spatialReference: any,
tileSystem: any[]
) => ({
// urlTemplate:
// "http://wprd{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&z={z}&x=&y={y}&scl=1<ype=11",
// // 替换url中的子域 ?不是很理解
// subdomains: ["01", "02", "03", "04"],
urlTemplate:
"https://webst01.is.autonavi.com/appmaptile?lang=zh_cn&style=6&x=&y={y}&z={z}",
subdomains: ["0", "1", "2", "3"],
cssFilter,
// 图片没出来 站位用的
placeholder: true,
// 平铺图像的 crossOrigin 跨域
crossOrigin: "anonymous",
// offset: offset as unknown as number[],
//设置瓦片图层的空间参考spatialReference默认就是3857,googlemap的分辨率
spatialReference,
//tileSystem 控制瓦片的x,y以及行列,后两个是origin原点位置(很重要)
tileSystem,
// 是否启用此地图上光标样式图层的命中检测,禁用它以提高性能。(鼠标检测)
hitDetect: false,
});
interface Extentable {
getExtent(): maptalks.Extent;
}
// 颜色转换
const colorToRGB = (color: string, opt: number) => {
let color1, color2, color3;
color = "" + color;
if (typeof color !== "string") return;
if (color.charAt(0) == "#") {
color = color.substring(1);
}
if (color.length == 3) {
color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
}
if (/^[0-9a-fA-F]{6}$/.test(color)) {
color1 = parseInt(color.substr(0, 2), 16);
color2 = parseInt(color.substr(2, 2), 16);
color3 = parseInt(color.substr(4, 2), 16);
return "rgba(" + color1 + "," + color2 + "," + color3 + "," + opt + ")";
}
},
// 总体瓦片偏移,[dx, dy],对来自不同坐标系的瓦片源很有用,例如(wgs84 和 gcj02)
// 底图不能重叠 这个是因为百度地图用的是bd09ll坐标系,
// 天地图是cgcs2000坐标系,两个坐标系有偏转造成的。
offset = (z: number) => {
if (!this.map) return;
const center = this.map.getCenter();
const transformCenter = convertor.transform(
center.toArray(),
"gcj02",
"wgs84"
);
targetCoordinate.set(transformCenter[0], transformCenter[1]);
return this.map
.coordToPoint(center, z, POINT0)
.sub(this.map.coordToPoint(targetCoordinate, z, POINT1))
.round()
.toArray();
};
// 全局绑定HBMap实例对象
let self: HBMap;
// 海博地图Base对象
export class HBMap {
// map对象
map: maptalks.Map;
// 地图基础瓦片图层
baseLayer: maptalks.TileLayer[] = [];
// 点位图层
markerLayer: maptalks.VectorLayer;
// 轨迹图层
trakLayer: maptalks.VectorLayer;
// 调度图层 no
dispatchLayer: maptalks.VectorLayer;
// 区域图层 no
areaLayer: maptalks.VectorLayer | null | undefined;
// 网格图层 no
gridLayer: maptalks.VectorLayer;
// 车辆全量信息
carsArr: CarMarkerData[] = [];
// 车辆全量信息Map集合 yes
carsMap: Map<string, CarMarkerData> = new Map();
// 当前跟踪对象 yes
followCarArr: string[] = [];
// 当前点击车辆marker对象 yes
currentCarMarker: CarMarkerData | null = null;
// 全局所有车辆跟踪 no
carFocus: boolean = false;
// 选择点位模式 no
coordinateLocationMode: boolean = false;
// 当前点位信息 no
DispatchMarkerMap: Map<string, MarkerLocation> = new Map();
// 弹窗点击事件回调
infoWindowCallback: InfoWindowCallback<CarMarkerData> | null = null;
// 画点完毕回调
changeModeCallback: ChangeModeCallback | null = null;
/** 初始点位 */
// eslint-disable-next-line no-loss-of-precision
static InitialCoordinate: Coordinate = [120.38422855590826, 36.1354355861087];
// [120.377365, 36.066538];
/** 初始缩放等级 */
static InitialZoom = 12.3;
/** 点击车辆 缩放比例 */
static InitialCarZoom = 15;
/** 构造Coordinate */
static Coordinate = maptalks.Coordinate;
/** 弹窗最多个数 */
static infoWindowNum = 5;
constructor(
renderer: HTMLElement,
infoWindowCallback: InfoWindowCallback<CarMarkerData> | null,
changeModeCallback: ChangeModeCallback | null
) {
const center = HBMap.InitialCoordinate;
self = this;
/**
* WGS84:World Geodetic System 1984,是为GPS全球定位系统使用而建立的坐标系统
*
* EPSG:4326 (WGS84) WGS84 是目前最流行的地理坐标系统。
* 在国际上,每个坐标系统都会被分配一个 EPSG 代码,
* EPSG:4326 就是 WGS84 的代码。GPS是基于WGS84的,
* 所以通常我们得到的坐标数据都是WGS84的。
* 一般我们在存储数据时,仍然按WGS84存储
*
* EPSG:3857 (Pseudo-Mercator) 伪墨卡托投影,也被称为球体墨卡托,
* Web Mercator它是基于墨卡托投影的,把 WGS84坐标系投影到正方形
*
*/
//与map一样,支持更详细的设置resolutions,fullExtent等
const spatialReference = { projection: "EPSG:3857" },
// 精确位置 [1, 1, -20037508.3427890,-20037508.3427890]
tileSystem = [1, -1, -20037508.34, 20037508.34],
// 滤镜 grayscale(1%) sepia(10%) hue-rotate(26.3deg) invert(0%) contrast(131%) saturate(63%)
cssFilter = "grayscale(30%) sepia(10%) brightness(80%)",
// 添加瓦片纠偏
targetCoordinate = new maptalks.Coordinate(0, 0),
POINT0 = new maptalks.Point(0, 0),
POINT1 = new maptalks.Point(0, 0);
// 基础瓦片图层
this.baseLayer[0] = new maptalks.TileLayer(
"base",
// HBmap_base_config(cssFilter, spatialReference, tileSystem)
GAODEmap_base_config(cssFilter, spatialReference, tileSystem)
// GAODEmap_satellite_base_config(cssFilter, spatialReference, tileSystem)
) as maptalks.TileLayer;
// 基础瓦片卫星图层
this.baseLayer[1] = new maptalks.TileLayer(
"base",
// HBmap_base_config(cssFilter, spatialReference, tileSystem),
// GAODEmap_base_config(cssFilter, spatialReference, tileSystem),
GAODEmap_satellite_base_config(cssFilter, spatialReference, tileSystem)
);
// 巡逻图层
this.markerLayer = new maptalks.VectorLayer("patrol", null, {
hitDetect: false,
zIndex: 10,
// enableAltitude: true, // enable altitude
// altitudeProperty: "altitude",
});
// 历史动画轨迹图层
this.trakLayer = new maptalks.VectorLayer("trak", null, {
hitDetect: false,
zIndex: 9,
});
// 调度图层
this.dispatchLayer = new maptalks.VectorLayer("dispatch", null, {
hitDetect: false,
zIndex: 8,
});
// // 区域图层
// this.areaLayer = new maptalks.VectorLayer("area", null, {
// hitDetect: false,
// zIndex: 3,
// });
// 网格图层
this.gridLayer = new maptalks.VectorLayer("grid", null, {
hitDetect: false,
zIndex: 2,
});
// 初始化地图实例
this.map = new maptalks.Map(renderer, {
// 是否在地图上显示属性控件。如果为真,属性显示 maptalks 信息;
// 如果对象,您可以指定位置或您的基本内容,以及两者;
attribution: false,
// 地图的初始中心
center,
// 缩放等级
zoom: HBMap.InitialZoom,
minZoom: 11.5,
maxZoom: 19,
// 地图的空间参考,默认使用 EPSG:3857 投影,分辨率由 google map/osm 使用
spatialReference,
// 鹰眼
// overviewControl: true,
// 标尺
scaleControl: {
position: "bottom-right",
maxWidth: 100,
metric: true, // metric 米 nautical 海里 imperial 英寸
imperial: false,
},
// 是否允许地图通过双击事件缩放
doubleClickZoom: false,
// 默认为真。如果为 true,则可以通过右键单击或 ctrl + 左键单击来拖动地
// 图行旋转
dragRotate: false,
// 默认为真。如果为 true,则可以通过右键单击或 ctrl + 左键单击将地图拖动
// 到俯仰
dragPitch: false,
// 如果为 true,地图将被拖动到同时俯仰和旋转
dragRotatePitch: false,
// 基础瓦片层
baseLayer: this.baseLayer[0],
// 最初将添加到地图的图层
layers: [
this.markerLayer,
this.trakLayer,
this.dispatchLayer,
this.gridLayer,
// this.areaLayer,
],
});
// 默认为真。拖动或触摸结束时继续动画平移
this.map.config("panAnimation", false);
// 默认为真。当拖动或触摸旋转结束时继续动画旋转
this.map.config("rotateAnimation", false);
// 默认为真。是否启用此地图上光标样式的图层命中检测,禁用它以提高性能
this.map.config("hitDetect", false);
// this.map.setPitch(30);
// this.map.setBearing(5);
// this.map.setFov(1);
// 赋值弹窗回调函数
this.infoWindowCallback = infoWindowCallback;
this.changeModeCallback = changeModeCallback;
}
/** 根据carCode获取当前点位坐标 */
getCoordinatesByCarCode(carCode: string) {
const marker = this.carsMap.get(carCode);
// console.log("getCoordinatesByCarCode", marker);
if (marker) {
return marker.carGeo;
}
return null;
}
/** 切换地图为卫星图 */
changeBaseLayer(type: string) {
switch (type) {
case "base":
this.map.setBaseLayer(this.baseLayer[0]);
break;
case "satellite":
this.map.setBaseLayer(this.baseLayer[1]);
break;
default:
break;
}
}
/** 选择点位坐标 */
setDispatchMarkerCoordinateMode(
flag: boolean | undefined
): boolean | undefined {
console.log("setDispatchMarkerCoordinateMode");
if (typeof flag !== "undefined") {
this.coordinateLocationMode = flag;
return undefined;
}
this.coordinateLocationMode = !this.coordinateLocationMode;
if (this.coordinateLocationMode) {
// 绑定地图右键点击事件
this.map.once("click", this.contextmenuEvent);
console.log("contextmenu");
} else {
this.map.off("click", this.contextmenuEvent);
}
return this.coordinateLocationMode;
}
/** 右击时间回调 */
contextmenuEvent({ coordinate }: any) {
// console.log("setDispatchMarkerCoordinateMode", self.coordinateLocationMode);
const dispatchId = utils.getUUID(),
DispatchMarker = { dispatchId: dispatchId, coordinate, marker: null };
// 创建调度点位
if (self.coordinateLocationMode) {
if (self.changeModeCallback) {
// 判断是否为 undefined undefined代表主动回复不打点默认状态
if (
typeof self.changeModeCallback({
dispatchId,
coordinate,
}) !== "undefined"
) {
self.setDispatchMarkerCoordinateLocation(DispatchMarker);
}
}
}
}
/** 回显调度点位 */
setDispatchMarker(
dispatchId: string,
coordinate: Coordinate
): DispatchMarker {
const DispatchMarker = { dispatchId, coordinate, marker: null };
this.setDispatchMarkerCoordinateLocation(DispatchMarker);
return DispatchMarker;
}
/** 新建调度点位 */
setDispatchMarkerCoordinateLocation(dispatchData: MarkerLocation) {
const dispatchMarker = self.DispatchMarkerMap.get(dispatchData.dispatchId);
// console.log(
// "setDispatchMarkerCoordinateLocation",
// dispatchMarker,
// dispatchData
// );
if (!dispatchMarker) {
// 新建点位
const DispatchMarker = new maptalks.Marker(dispatchData.coordinate, {
id: dispatchData.dispatchId,
zIndex: 15,
symbol: [
{
markerFile: dispatchSvg,
markerHeight: 60,
markerWidth: 60,
markerOpacity: 1,
markerVerticalAlignment: "middle",
},
],
}),
option = {
content: `<div class="icon">终</div><div>经度:${
(dispatchData.coordinate && dispatchData.coordinate[0]) ||
dispatchData.coordinate?.x
} 纬度:${
(dispatchData.coordinate && dispatchData.coordinate[1]) ||
dispatchData.coordinate?.y
}</div>`,
className: "maptalks-tooltip-address",
dy: -65,
},
// 创建自定义ui组件
UI = this.createCustomUIComponent(),
toolTip = new UI(dispatchData.coordinate, option);
UI.mergeOptions(option);
toolTip.addTo(this.map).show();
DispatchMarker.addTo(this.dispatchLayer);
self.DispatchMarkerMap.set(dispatchData.dispatchId, {
...dispatchData,
toolTip,
marker: DispatchMarker,
});
} else {
// console.log("dispatchMarker.marker", dispatchMarker.marker);
dispatchMarker.marker?.remove();
dispatchMarker.toolTip?.remove();
self.DispatchMarkerMap.delete(dispatchData.dispatchId);
}
}
/** 更新车辆标记并更新最新方位角 */
private updateDrawCar(
{
carCode,
carTypeId,
carMarker,
infoWindowData,
existCamera,
existCarGeo,
infoWindowVisiable,
}: CarMarkerData,
data: WSCarCoordinate | WSCarStatus,
azimuth: number
): maptalks.Marker {
// 更改点位
if (carMarker) {
if ("carGeo" in data) {
data.carGeo && carMarker.setCoordinates(data.carGeo);
}
}
// 判断是否要重绘消息弹窗
if (typeof infoWindowVisiable === "boolean" && infoWindowVisiable) {
// 绘制消息弹窗
createInfoWindow({
carCode,
pointInfo: {
...infoWindowData,
coordinate: (data as WSCarCoordinate).carGeo,
existCamera,
existCarGeo,
},
eventFunction: (type, carCode) => {
if (this.infoWindowCallback) {
const marker = this.carsMap.get(carCode as string);
if (marker) {
this.infoWindowCallback(type, marker);
}
}
},
});
}
// 更改点位信息
// console.log(
// "markerFile",
// workStatus,
// utils.getCarStatusSvg(carTypeId, workStatus)
// );
const updateConfig: any = [
{
markerRotation: -azimuth,
},
];
if ("workStatus" in data) {
updateConfig[0].markerFile = utils.getCarStatusSvg(
carTypeId,
data.workStatus as string
);
// console.log(
// 222,
// data.workStatus,
// utils.getCarStatusSvg(carTypeId, data.workStatus)
// );
}
carMarker!.updateSymbol(updateConfig);
return carMarker!;
}
/** 批量更新车辆标记 */
bathUpdateDrawCar(data: WSCarCoordinate | WSCarStatus) {
// 存储全量车辆信息 间隔相同时间 请求全量数据
if (Array.isArray(data)) {
// 使用map更新单个点位
} else if (data !== null && Object.keys(data).length) {
const marker = this.carsMap.get(data.carCode);
if (marker) {
// 最新方位角(我也不知道为啥是取负 正数会显示镜像的方位)
let newAzimuth: number = 0;
// 包含点位 计算方位角
if ("carGeo" in data) {
newAzimuth = this.getAzimuth(
marker.carGeo, // 旧点位
data.carGeo as Coordinate // 新点位
);
// 状态变更 隐藏调度弹窗
} else if ("workStatus" in data) {
// 无坐标 取坐标角数组最后一位
} else newAzimuth = marker.azimuth && marker.azimuth.slice(-1)[0];
// console.log("azimuth Arr", data);
this.carsMap.set(
data.carCode,
Object.assign(marker, {
...data,
carMarker: this.updateDrawCar(marker, data, newAzimuth),
azimuth: [...marker.azimuth, newAzimuth],
})
);
}
}
}
/** 创建新的ui组件 调度 */
createCustomUIComponent() {
class MyUI extends maptalks.ui.UIComponent {
constructor(coordinate: Coordinate, options: BaseParameterData) {
super(options);
this._coordinate = new maptalks.Coordinate(coordinate);
}
// 创建dom元素
buildOn() {
const dom = document.createElement("div");
dom.className = this.options.className;
dom.innerHTML = this.options["content"];
return dom;
}
getOffset() {
const size = this.getSize();
return new maptalks.Point(-size.width / 2, -size.height / 2);
}
getEvents() {
return {
zoomend: this._flash,
};
}
onRemove() {
if (this._flashTimeout) {
clearTimeout(this._flashTimeout);
}
}
_flash() {
this.hide();
this._flashTimeout = setTimeout(() => {
this.show(this._coordinate);
}, 200) as unknown as number;
}
}
return MyUI;
}
/** 批量更新车辆状态 */
bathUpdateMarkerStatus(data: WSCarStatus | WSCarStatus) {
if ("workStatus" in data) {
const { carCode, workStatus } = data;
const marker = this.carsMap.get(carCode);
if (marker) {
// eslint-disable-next-line prefer-const
let { carMarker, carNum, toolTip, showTip, carGeo } = marker;
switch (workStatus) {
case "DISPATCH":
// console.log("DISPATCH 123");
// eslint-disable-next-line no-case-declarations
const option = {
content: `<div>${carNum || "-"} 调度中</div>`,
className: "maptalks-tooltip",
dy: 45,
},
// 创建自定义ui组件
UI = this.createCustomUIComponent(),
ui = new UI(carGeo, option);
UI.mergeOptions(option);
ui.addTo(this.map).show();
carMarker!.closeInfoWindow();
toolTip = ui;
showTip = true;
break;
default:
if (toolTip) {
toolTip.hide();
toolTip = null;
showTip = false;
}
break;
}
this.carsMap.set(
carCode,
Object.assign(marker, {
carMarker: this.updateDrawCar(
marker,
data,
marker.azimuth && marker.azimuth.slice(-1)[0]
),
toolTip,
showTip,
})
);
}
} else if ("status" in data) {
const { carCode, status } = data;
const marker = this.carsMap.get(carCode);
console.log("ENABLED DISABLED", marker);
if (marker) {
if (status == "ENABLED") {
// 关闭或展示
marker.carMarker?.show();
// 显示轨迹
marker.line?.show();
this.carsMap.set(
carCode,
Object.assign(marker, {
show: true,
enabled: true,
})
);
} else {
// 关闭或展示
marker.carMarker?.hide();
// 显示轨迹
marker.line?.hide();
this.carsMap.set(
carCode,
Object.assign(marker, {
show: false,
enabled: false,
})
);
}
}
}
}
/** 绘制历史动画轨迹 */
drawTrakLine(
{ carCode, carGeo }: WSCarCoordinate,
{ shadowColor, lineColor }: LineColor = {
shadowColor: "#FFA300",
lineColor: "#FFA300",
}
): maptalks.LineString | null {
const marker = this.carsMap.get(carCode);
// console.log("drawTrakLine", marker, carCode);
if (marker) {
const line = new maptalks.LineString(
(carGeo as Coordinate[]).map((item) => item),
{
zIndex: 9,
symbol: {
shadowColor,
shadowBlur: 14,
lineColor,
lineWidth: 8,
lineDasharray: [0, 0],
},
}
);
line.addTo(this.trakLayer);
this.carsMap.set(carCode, {
...marker,
line,
});
return line;
}
return null;
}
/** 绘制车辆历史标记点 */
drawHistoryCar(carCode: string, carGeo: Coordinate) {
const marker = this.carsMap.get(carCode);
if (marker) {
// 创建一个Marker对象
const carMarker = new maptalks.Marker(carGeo, {
symbol: [
{
markerFile: utils.getCarStatusSvg(marker.carTypeId, "OFFLINE"),
markerHeight: 60,
markerWidth: 60,
markerOpacity: 1,
markerVerticalAlignment: "middle",
},
],
}).addTo(this.trakLayer);
this.carsMap.set(carCode, {
...marker,
carMarker,
});
}
}
/** 插入车辆点线动画 */
playHistoryAnimateVideo(carCode: string, route: any): null | RoutePlayer {
const marker = this.carsMap.get(carCode);
if (marker) {
const player = new RoutePlayer(route, this.map, {
maxTrailLine: 10,
});
this.carsMap.set(carCode, {
...marker,
carHistoryVideo: player,
});
return player;
}
return null;
}
/** 绘制车其他标记点 */
drawOtherHistoryMarkers(carGeos: Coordinate[]) {
for (let i = 0; i < carGeos.length; i++) {
let markerFile: any = "ONLINE";
// 开始
if (i === 0) {
markerFile = utils.getCarStatusSvg(-1, "START");
// 结束
} else if (i === carGeos.length - 1) {
markerFile = utils.getCarStatusSvg(-1, "END");
// 停留
} else {
markerFile = utils.getCarStatusSvg(-1, "PAUSE");
}
const car = new maptalks.Marker(carGeos[i], {
id: i,
zIndex: 9,
symbol:
i === 0 || i === carGeos.length - 1
? {
markerFile,
markerHeight: 40,
markerWidth: 40,
markerOpacity: 1,
markerVerticalAlignment: "top",
markerDx: 3,
markerDy: -10,
}
: {
markerFile,
markerHeight: 80,
markerWidth: 80,
markerOpacity: 0.9,
markerVerticalAlignment: "middle",
markerDx: -12,
markerDy: -10,
},
});
car.addTo(this.trakLayer);
}
}
/** 绘制车辆历史路线 */
// drawHistoryCarPath({
// carCode,
// carGeos = [],
// lineColor = "#000",
// }: AnimateiHstoryCarPath) {
// const marker = this.carsMap.get(carCode);
// if (marker) {
// // 创建一个Path对象
// const linePath = new maptalks.Path(
// carGeos.length ? carGeos : marker.line?.getCoordinates(),
// {
// symbol: {
// lineColor,
// lineWidth: 2,
// },
// }
// ).addTo(this.trakLayer);
// this.carsMap.set(carCode, {
// ...marker,
// linePath,
// });
// }
// }
/** 执行车辆历史路线动画 */
// takeHistoryCarAnimate(carCode: string, duration: number) {
// const marker = this.carsMap.get(carCode);
// if (marker) {
// // 执行Marker的animate动画方法
// marker.carMarker!.animate({
// path: marker.linePath, // 设置路径为刚刚创建的Path对象
// duration, // 动画持续时间为5000毫秒
// easing: "linear", // 动画缓动函数为线性
// repeat: false, // 动画循环执行
// autoRotate: true, // 自动旋转方向
// });
// }
// }
/** 车辆展示或关闭弹框 */
/**
* @description:
* @param carCode {string} :车辆标识
* @param carMarker {maptalks} :车辆点位
* @response: DISABLED 启用禁用状态
* DISCOORDINATE 该车不存在或无点位
* @return {*}
*/
async showCarInfoWindow(
carCode: string,
carMarker: maptalks.Marker | null
): Promise<boolean | string> {
const marker = this.carsMap.get(carCode);
console.log("能不能获取到", this.carsMap, carCode);
if (marker) {
// 如果当前为打开自定义组件ui时终止
if (marker.showTip) return true;
// 如果为跟踪点位 添加到跟踪数组中 存在着不添加
if (marker.follow) {
!this.followCarArr.includes(marker.carCode) &&
this.followCarArr.push(marker.carCode);
return true;
}
// 判断车辆启用禁用状态
if (!marker.enabled) return "DISABLED";
// 创建点位弹窗
(carMarker || marker.carMarker!).setInfoWindow({
// 如果您不希望地图进行平移动画以适应打开的窗口,请将其设置为 false。
autoPan: true,
// 自动打开所有者事件的信息窗口,例如“单击”将通过单击或右键单击窗口所有者打开信息窗口。
autoOpenOn: null,
// UI是否为全局单个UI,设置为true则同一时间只显示一个UI
single: false,
// 如果您想要自定义信息窗口、自定义 html 代码或将 HTMLElement 设置为内容,请将其设置为 true。
custom: true,
// 信息窗口的内容。
content: "",
visible: true,
dx: -130,
dy: -160,
animation: "fade",
});
// console.log("marker", marker);
// 获取当前点位上的弹窗对象
const infoW = (carMarker || marker.carMarker!).getInfoWindow();
// 写入弹窗内容
this.infoWindowContent(infoW, marker.carCode);
// 如果没有当前点击marker值 赋值
if (!this.currentCarMarker) {
(carMarker || marker.carMarker!).openInfoWindow();
this.currentCarMarker = marker;
// 获取弹窗展示的信息
let info = await infoWindowData(
carCode,
this.getCoordinatesByCarCode(carCode)
);
// console.log("1231231213 infoWindowData",marker)
info = {
...info,
existCamera: marker?.existCamera,
existCarGeo: marker?.existCarGeo,
};
console.log("单机弹窗", info);
// 放入对应点位对象
this.setInfoWindowData(carCode, info);
// 绘制消息弹窗
createInfoWindow({
carCode,
pointInfo: info,
eventFunction: (type, carCode) => {
if (this.infoWindowCallback) {
const marker = this.carsMap.get(carCode as string);
if (marker) {
this.infoWindowCallback(type, marker);
}
}
},
});
this.updateInfoWindowVisiable(carCode, true);
// 定位车辆
this.map.animateTo(
{
center: marker.carGeo,
zoom: HBMap.InitialCarZoom,
},
{
duration: 2 * 1000,
}
);
// 相同代表点击同一个marker
} else if (this.currentCarMarker.carCode === marker.carCode) {
// 更新点位消息弹窗状态
this.updateInfoWindowVisiable(carCode, false);
// 再删除弹窗
setTimeout(
() => (carMarker || marker.carMarker!).removeInfoWindow(),
0
);
this.currentCarMarker = null;
// 定位车辆
this.map.animateTo(
{
center: HBMap.InitialCoordinate,
zoom: HBMap.InitialZoom,
},
{
duration: 2 * 1000,
}
);
// 否则是关闭一个已经打开的弹窗 打开一个新marker弹窗
} else {
// 其中 先判断上一个点位对象是否在跟踪数组中 不存在则关闭上一个弹窗
if (!this.followCarArr.includes(this.currentCarMarker.carCode)) {
// console.log(1231231123);
// 更新点位消息弹窗状态
this.updateInfoWindowVisiable(this.currentCarMarker?.carCode, false);
this.currentCarMarker?.carMarker?.removeInfoWindow();
}
// 更新点位消息弹窗状态
// setTimeout(async () => {
(carMarker || marker.carMarker!).openInfoWindow();
this.currentCarMarker = marker;
// 获取弹窗展示的信息
let info = await infoWindowData(
carCode,
this.getCoordinatesByCarCode(carCode)
);
info = {
...info,
existCamera: marker?.existCamera,
existCarGeo: marker?.existCarGeo,
};
// 放入对应点位对象
this.setInfoWindowData(carCode, info);
// 绘制消息弹窗
createInfoWindow({
carCode,
pointInfo: info,
eventFunction: (type, carCode) => {
if (this.infoWindowCallback) {
const marker = this.carsMap.get(carCode as string);
if (marker) {
this.infoWindowCallback(type, marker);
}
}
},
});
this.updateInfoWindowVisiable(carCode, true);
// 定位车辆
this.map.animateTo(
{
center: marker.carGeo,
zoom: HBMap.InitialCarZoom,
},
{
duration: 2 * 1000,
}
);
// }, 1000);
}
return true;
} else return "DISCOORDINATE";
}
/** 绘制车辆标记 */
private drawCar({
carCode,
carTypeId,
carGeo,
workStatus,
azimuth,
}: CarMarkerData): maptalks.Marker {
// console.log(
// "drawCar",
// workStatus,
// utils.getCarStatusSvg(carTypeId, workStatus || "OFFLINE")
// );
const that = this,
car = new maptalks.Marker(carGeo, {
id: carCode,
zIndex: 15,
symbol: [
{
markerFile: utils.getCarStatusSvg(
carTypeId,
workStatus || "OFFLINE"
),
markerHeight: 60,
markerWidth: 60,
markerOpacity: 1,
markerVerticalAlignment: "middle",
markerRotation: azimuth.concat().pop(),
},
// {
// markerHeight: 60,
// markerWidth: 60,
// markerFill: "rgba(255, 255, 255, 0)",
// markerType: "ellipse",
// markerLineWidth: 0,
// },
],
properties: {
altitude: 400,
},
});
car.addTo(this.markerLayer);
car.on("click", async function (e) {
// 不为跟踪点位 不同点位点击需要进行弹窗重绘
that.showCarInfoWindow(e.target._id, car);
});
// 显示车牌
// car.on("mouseenter", async function (e) {
// const marker = that.carsMap.get(e.target._id);
// if (marker) {
// if (marker.toolTip2) {
// marker.toolTip2.show(new maptalks.Coordinate(marker.carGeo));
// } else {
// const toolTip2 = new maptalks.ui.ToolTip(`${marker.carNum || "-"}`, {
// width: 70,
// height: 30,
// showTimeout: 60 * 1000,
// animationDuration: 2000,
// animation: "scale | fade",
// // autoPan: true, 不能加这个煞笔属性 艹卡了我一下午
// // 自动打开所有者事件的信息窗口,例如“单击”将通过单击或右键单击窗口所有者打开信息窗口。
// // cssName: "marker-tooltip-car-num",
// // UI是否为全局单个UI,设置为true则同一时间只显示一个UI
// single: false,
// dx: -35,
// dy: 35,
// });
// toolTip2.setStyle("marker-tooltip-car-num");
// toolTip2.addTo(marker.carMarker!);
// toolTip2.show(new maptalks.Coordinate(marker.carGeo));
// that.carsMap.set(e.target._id, {
// ...marker,
// toolTip2,
// });
// }
// }
// });
// // 隐藏车牌
// car.on("mouseout", async function (e) {
// const marker = that.carsMap.get(carCode);
// if (marker) {
// marker.toolTip2!.hide();
// }
// });
return car;
}
/** 批量绘制车辆标记 */
bathDrawCar(carsArr: Array<CarMarkerData>): void {
// 存储全量车辆信息
console.log("bathDrawCar", carsArr);
for (let i = 0; i < carsArr.length; i++) {
const carData = {
...carsArr[i],
};
console.log("carData", carData);
carsArr[i] = Object.assign(carData, {
carMarker: this.drawCar(carData),
});
// 隐藏禁用的车辆
if (!carsArr[i].enabled) carsArr[i].carMarker?.hide();
this.carsMap.set(carsArr[i].carCode, carData);
// console.log("!carsArr[i].enabled", !carsArr[i].enabled);
// console.log("bathDrawCar carsArr[i]", carsArr[i], this.carsMap);
}
// this.carsArr = carsArr;
}
/** 添加指定carCode车辆信息 */
addNewCarMapObject(car: CarMarkerData) {
const { carCode } = car;
this.carsMap.set(carCode, car);
}
/** 点位消息窗口是否打开 */
updateInfoWindowVisiable(carCode: string, visiable: boolean) {
const marker = this.carsMap.get(carCode);
if (marker) {
this.carsMap.set(carCode, {
...marker,
infoWindowVisiable: visiable,
});
}
}
/** 点位赋值消息窗口信息 */
setInfoWindowData(carCode: string, infoWindowData: InfoWindowData) {
const marker = this.carsMap.get(carCode);
if (marker) {
this.carsMap.set(carCode, {
...marker,
infoWindowData,
});
}
}
/** 重绘消息窗口 */
infoWindowContent(ifoWindow: maptalks.ui.InfoWindow, carCode: string) {
return (
ifoWindow &&
ifoWindow.setContent(`<div id="info-content-${carCode}"></div>`)
);
}
/** 跟踪车辆消息窗口 */
drawTrackCarinfoWindow(carCode: string, carInfo: any) {
const marker = this.carsMap.get(carCode),
that = this;
if (marker) {
marker?.carMarker?.setInfoWindow({
// 如果您不希望地图进行平移动画以适应打开的窗口,请将其设置为 false。
autoPan: false,
zIndex: 16,
// 自动打开所有者事件的信息窗口,例如“单击”将通过单击或右键单击窗口所有者打开信息窗口。
autoOpenOn: null,
// UI是否为全局单个UI,设置为true则同一时间只显示一个UI
single: false,
// 如果您想要自定义信息窗口、自定义 html 代码或将 HTMLElement 设置为内容,请将其设置为 true。
custom: true,
// 信息窗口的内容。
content: "",
dx: -130,
dy: -160,
animation: "fade",
});
// 获取当前点位上的弹窗对象
// 写入弹窗内容
that.infoWindowContent(marker?.carMarker?.getInfoWindow()!, carCode);
marker?.carMarker?.openInfoWindow();
// console.log("carInfo carInfo", carInfo);
createInfoWindow({
carCode,
pointInfo: {
...carInfo,
existCamera: marker?.existCamera,
existCarGeo: marker?.existCarGeo,
},
eventFunction: (type, carCode) => {
if (this.infoWindowCallback) {
const marker = this.carsMap.get(carCode as string);
if (marker) {
this.infoWindowCallback(type, marker);
}
}
},
});
// 更新点位消息弹窗状态
that.updateInfoWindowVisiable(carCode, true);
}
}
/** 初始化跟踪车辆轨迹点位数组 */
initTrckCarCoordinateArr(
carCode: string,
coordinates: Coordinate[]
): Coordinate[] | null {
const marker = this.carsMap.get(carCode as string);
if (marker) {
marker.trakCollection = coordinates;
this.carsMap.set(carCode, marker);
return coordinates;
}
return null;
}
/** 查找跟踪车辆轨迹点位数组 */
getTrckCarCoordinateArr(carCode: string): Coordinate[] | [] {
const marker = this.carsMap.get(carCode);
// console.log("getTrckCarCoordinateArr", marker, this.carsMap);
return marker ? marker.trakCollection : [];
}
/** 更新跟踪车辆轨迹点位数组 */
updateTrckCarCoordinateArr({
carCode,
carGeo,
}: WSCarCoordinate): Coordinate[] | null {
const marker = this.carsMap.get(carCode as string);
if (marker) {
marker.trakCollection.push(carGeo as Coordinate);
this.carsMap.set(carCode as string, marker);
return marker.trakCollection;
}
return null;
}
/** 混合更新跟踪车辆轨迹点位数组 */
updateMixTrckCarCoordinateArr({
carCode,
carGeo,
uploadTime,
}: WSCarCoordinate): Coordinate[] | null {
const marker = this.carsMap.get(carCode);
// console.log(
// ` updateMixTrckCarCoordinateArr`,
// carCode,
// uploadTime,
// this.carsMap,
// marker
// );
if (marker) {
if (
Array.isArray((carGeo as Coordinate[])[0]) &&
Array.isArray(uploadTime as string[])
) {
const trakCollection = marker.trakCollection.concat(
carGeo as Coordinate[]
);
// console.log("marker.uploadTime", marker.uploadTime);
const uploadTimeTemp = (
Array.isArray(marker.uploadTime)
? marker.uploadTime
: [marker.uploadTime]
).concat(uploadTime as string[]);
this.carsMap.set(carCode, {
...marker,
trakCollection,
uploadTime: uploadTimeTemp,
});
return trakCollection;
} else {
const trakCollection = [
...marker.trakCollection,
carGeo,
] as Coordinate[];
let uploadTimeArr = [];
if (Array.isArray(marker.uploadTime)) {
uploadTimeArr = [...marker.uploadTime, uploadTime] as string[];
} else uploadTimeArr.push(uploadTime);
this.carsMap.set(carCode, {
...marker,
trakCollection,
uploadTime: uploadTimeArr as string[],
});
// console.log("updateMixTrckCarCoordinateArr", this.carsMap.get(carCode));
return trakCollection;
}
}
return null;
}
/** 清空跟踪车辆轨迹点位数组 */
clearTrckCarCoordinateArr(carCode: string) {
const marker = this.carsMap.get(carCode as string);
if (marker) {
this.carsMap.set(carCode as string, {
...marker,
trakCollection: [],
});
}
}
/** 更新轨迹 */
updateTrakLine({ carCode, carGeo }: WSCarCoordinate): void {
const marker = this.carsMap.get(carCode);
if (marker) {
const { line } = marker;
line?.setCoordinates(carGeo as Coordinate[]);
// console.log("updateTrakLine carGeo", carGeo);
}
}
/** 清除轨迹 */
clearTrakLine(carCode: string): void {
const marker = this.carsMap.get(carCode);
if (marker) {
const { line } = marker;
line?.remove();
this.carsMap.set(carCode, { ...marker, line: null });
}
}
/** 聚焦 */
focusOnMarker(points: Coordinate, duration: number, focus: boolean = false) {
// console.log("focusOnMarker", this.carFocus, points);
if (!focus) return;
this.map.animateTo(
{
center: points,
zoom: this.map.getZoom(),
},
{
duration,
}
);
}
/** 获取当前跟踪车辆信息 */
getMapObjectById(carCode: string): CarMarkerData | null {
return this.carsMap.get(carCode) ?? null;
}
/** 已知两点计算角标 */
// getAzimuth(prvCoordinate: Coordinate, curCoordinate: Coordinate): number {
// // console.log("getAzimuth", prvCoordinate, curCoordinate);
// let azimuth = 0;
// const [lat1, lon1] = prvCoordinate,
// [lat2, lon2] = curCoordinate,
// dlat = lat2 - lat1,
// dlon = lon2 - lon1;
// if (dlon === 0) {
// azimuth = dlat > 0 ? 90 : -90;
// } else if (dlat === 0) {
// azimuth = dlon > 0 ? 0 : 270;
// } else {
// azimuth = (Math.atan(dlat / dlon) * 180) / Math.PI;
// if (dlon < 0) {
// azimuth += 180;
// } else if (dlon >= 0 && dlat < 0) {
// azimuth += 360;
// }
// }
// return azimuth;
// }
getAzimuth([lon1, lat1]: Coordinate, [lon2, lat2]: Coordinate) {
const lon1_rad = (lon1 * Math.PI) / 180;
const lat1_rad = (lat1 * Math.PI) / 180;
const lon2_rad = (lon2 * Math.PI) / 180;
const lat2_rad = (lat2 * Math.PI) / 180;
const tan_y = Math.tan(lat2_rad - lat1_rad);
const tan_x =
Math.sin(lon2_rad - lon1_rad) * Math.cos(lat1_rad) -
Math.cos(lon2_rad - lon1_rad) *
Math.sin(lat1_rad) *
Math.cos(lat2_rad - lat1_rad);
let azimuth = Math.atan2(
Math.sin(lon2_rad - lon1_rad) * Math.cos(lat2_rad),
Math.cos(lat1_rad) * Math.sin(lat2_rad) -
Math.sin(lat1_rad) * Math.cos(lat2_rad) * Math.cos(lon2_rad - lon1_rad)
);
azimuth = (azimuth * 180) / Math.PI;
return azimuth;
}
/** 关闭跟踪车辆弹窗 */
closeTrackCarinfoWindow(carCode: string) {
const marker = this.carsMap.get(carCode);
// // console.log("closeTrackCarinfoWindow", marker);
if (marker) {
const infoW = marker?.carMarker?.getInfoWindow();
marker?.carMarker?.closeInfoWindow();
// 在删除弹窗dom
setTimeout(() => infoW?.remove(), 0);
}
}
/** 设置车辆跟踪状态 */
updateCarMarkerFollowStatus(carCode: string): boolean {
if (
this.followCarArr.length >= HBMap.infoWindowNum &&
!this.followCarArr.includes(carCode)
)
return false;
const marker = this.carsMap.get(carCode);
if (marker) {
this.carsMap.set(carCode, {
...marker,
follow: !marker.follow,
});
const newMarker = this.carsMap.get(carCode)!;
// 变更跟随模式时 更新当前点击对象
this.currentCarMarker = newMarker;
// 更新最新跟踪数组
if (newMarker.follow && !this.followCarArr.includes(carCode))
this.followCarArr.push(carCode);
else
this.followCarArr.splice(
this.followCarArr.findIndex((f) => f === carCode),
1
);
// 如果当前跟踪车辆大约两台 取消跟随某辆车状态
// this.carFocus = this.followCarArr.length < 2;
// // console.log("this.carsMap.get(carCode)", newMarker);
}
return true;
}
/** 改变车辆map属性变化 */
setCarMapProperty(carCode: string, property: any): void {
const marker = this.carsMap.get(carCode);
if (marker) {
this.carsMap.set(carCode, Object.assign(marker, property));
}
}
/** 改变车辆marker显隐 */
async setCarMarkerVisiable(carTypeArr: number[]) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const [key, value] of this.carsMap.entries()) {
let inArr = false;
const marker = this.carsMap.get(value.carCode);
carTypeArr.forEach((type) => type === value.carTypeId && (inArr = true));
if (inArr) {
if (marker) {
// 关闭或展示
marker.carMarker?.show();
// 显示轨迹
marker.line?.show();
// 如果为跟踪状态 需要重新绑定
if (marker.follow) {
// 获取当前点位上的弹窗对象
const infoW = marker.carMarker?.getInfoWindow(),
carCode = marker.carCode;
if (infoW) {
marker.carMarker?.openInfoWindow();
// // 写入弹窗内容
this.infoWindowContent(infoW, carCode);
// 如果没有当前点击marker值 赋值
marker.carMarker?.openInfoWindow();
this.currentCarMarker = marker;
// 获取弹窗展示的信息
let info = await infoWindowData(
carCode,
this.getCoordinatesByCarCode(carCode)
);
info = {
...info,
existCamera: marker?.existCamera,
existCarGeo: marker?.existCarGeo,
};
// 放入对应点位对象
this.setInfoWindowData(carCode, info);
// console.log(11111);
// 绘制消息弹窗
createInfoWindow({
carCode,
pointInfo: info,
eventFunction: (type) => {
if (this.infoWindowCallback) {
if (marker) {
this.infoWindowCallback(type, marker);
}
}
},
});
}
}
this.carsMap.set(
value.carCode,
Object.assign(marker, {
show: true,
})
);
}
} else {
if (marker) {
// 关闭或展示
marker.carMarker?.hide();
// 隐藏轨迹
marker.line?.hide();
this.carsMap.set(
value.carCode,
Object.assign(marker, {
show: false,
})
);
}
}
}
}
/** 根据carCode获取点位 */
getCoordinateByCarCode(carCode: string) {
const marker = this.carsMap.get(carCode);
return marker ? marker.carGeo : [];
}
/** 清空carCode轨迹数组 */
clearTrakCollectionByCarCode(carCode: string) {
const marker = this.carsMap.get(carCode);
if (marker) {
this.carsMap.set(carCode, {
...marker,
trakCollection: [],
});
}
}
/** 根据carCode获取轨迹数组 */
getTrakCollectionByCarCode(carCode: string): Coordinate[] | Coordinate {
const marker = this.carsMap.get(carCode);
// console.log("getTrakCollectionByCarCode", marker);
if (marker) {
return marker.trakCollection.length
? marker.trakCollection || []
: marker.carGeo;
}
return [];
}
/** 添加独立tooltip */
addToolTip(polygon: maptalks.Polygon, name: string) {
const toolTip = new maptalks.ui.ToolTip(name, {
width: 100,
height: 30,
animation: "scale | fade",
// autoPan: true,
// 自动打开所有者事件的信息窗口,例如“单击”将通过单击或右键单击窗口所有者打开信息窗口。
// cssName: "marker-tooltip-car-num",
// UI是否为全局单个UI,设置为true则同一时间只显示一个UI
single: false,
dx: -35,
dy: -55,
});
toolTip.setStyle("marker-tooltip-grid");
toolTip.addTo(polygon);
return toolTip;
}
/**
* 地图上划区域
* @param {Array} points
* @param {Object} config 用来设置区域样式
* @param {String} eventType 时间类型 格式 'mousedown mouseup click dblclick contextmenu touchstart touchend mouseenter mouseout'
* @param {Function} onEvent 时间总处理方法
*/
// points: Coordinate[] = [],
// config: BaseParameterData,
// eventType: string | null,
// onEvent: maptalks.EvenableHandlerFun | null
drawArea({ points = [], config = {}, onEvent = null }: AreaData) {
// const areaArr: maptalks.Polygon[] = [];
let isFocus: boolean = false;
points.forEach((point) => {
const area = new maptalks.Polygon(point.geo as Coordinate[], {
...config,
id: point.id,
}),
toolTip = this.addToolTip(area, point.name);
area
.addTo(this.areaLayer!)
.on("click", (e) => {
if (onEvent) {
onEvent(e, point, "click");
}
})
.on("dblclick", (e) => {
isFocus = !isFocus;
if (isFocus) {
this.map?.fitExtent(area.getExtent(), 1);
} else {
this.map.setZoom(HBMap.InitialZoom);
}
if (onEvent) {
onEvent(e, point, "dblclick");
}
})
.on("mouseenter", (e) => {
console.log("mouseenter", e);
toolTip.show();
area.updateSymbol({
polygonOpacity: 0.4,
});
})
.on("mouseout", (e) => {
console.log("mouseenter", e);
toolTip.hide();
area.updateSymbol({
polygonOpacity: 0.1,
});
});
// areaArr.push(area);
});
}
/**
* 地图上划区域
* @param {Array} points
* @param {Object} config 用来设置区域border样式
* @param {String} eventType 时间类型 格式 'mousedown mouseup click dblclick contextmenu touchstart touchend mouseenter mouseout'
* @param {Function} onEvent 时间总处理方法
*/
drawAreaBorder({
points = [],
config = {},
eventType = null,
onEvent = null,
}: AreaData): maptalks.LineString[] {
const lineArr: maptalks.LineString[] = [];
console.log("points", points);
points.forEach((point) => {
// console.log(123123, point);
lineArr.push(
new maptalks.LineString(point.geo as Coordinate[], {
...config,
id: `line-${point.id}`,
properties: {
altitude: new Array(point.geo.length).fill(
config?.properties?.altitude || 0
),
},
}).on(eventType ? eventType : "click", (e) => {
console.log("drawAreaBorder", lineArr);
if (onEvent) {
onEvent(e, point);
}
})
);
});
console.log("this.areaLayer this.areaLayer", this.areaLayer);
if (!this.areaLayer) {
this.areaLayer = new maptalks.VectorLayer("area", lineArr, {
enableAltitude: true,
drawAltitude: {
polygonFill: "#489bfb",
polygonOpacity: 0.3,
lineWidth: 0,
},
zindex: 3,
});
this.areaLayer.addTo(this.map);
} else {
this.areaLayer.addGeometry(lineArr);
}
return lineArr;
}
/** 删除当前添加的下级网格 */
removeVectorLayerGeometrys(
removeGeometry: maptalks.Geometry | maptalks.Geometry[]
) {
this.areaLayer!.removeGeometry(removeGeometry);
}
/** 清除所有网格 */
clearAllAreas() {
this.areaLayer?.clear();
this.map?.removeLayer(this.areaLayer!);
this.areaLayer = null;
}
// ------------------------------------------------------------------------------------
/** 清除交互后 ImageData 缓存 */
clearMapCache() {
setTimeout(() => {
const layers = this.map.getLayers();
layers.forEach((layer) => {
layer.getRenderer().clearImageData();
});
}, 100);
}
/** 设置车辆标记位置 */
moveCar(point: number[]) {
this.car.setCoordinates(point);
}
/** 地图自适应展示图形 */
fitExtent(geo: Extentable, zoomOffset = 0) {
this.map.fitExtent(geo.getExtent(), zoomOffset);
}
}
评论 (0)