@orca-fe/x-map
Version:
155 lines (154 loc) • 5.36 kB
JavaScript
import BaseInstance from './BaseInstance';
import AMapViewport from './AMapViewport';
// @ts-expect-error
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let { AMap } = window;
/**
* 高德地图接口
*/
class AMapInstance extends BaseInstance {
constructor() {
super(...arguments);
this.viewport = new AMapViewport();
this.resize = () => { };
}
init(id, options) {
const viewMode = '3D';
const { viewport } = options;
const mapOption = {
resizeEnable: true,
mapStyle: 'amap://styles/normal',
zooms: [1, 20],
animateEnable: false,
expandZoomRange: true,
animation: viewMode !== '3D',
viewMode,
};
if (AMap == null) {
// @ts-expect-error
({ AMap } = window);
}
this.dom = typeof id === 'string' ? document.getElementById(id) : id;
this.map = new AMap.Map(id, Object.assign(Object.assign({}, mapOption), { center: new AMap.LngLat(viewport.lng, viewport.lat), zoom: viewport.zoom + 1 }));
this.map.on('camerachange', ({ camera }) => {
const { lng, lat } = this.getCenter();
const { fov, near, far, height, pitch, rotation, aspect, position } = camera;
this.viewport.syncWithMapCamera({
aspect,
// AMap 定义 rotation 为顺时针方向,而 Mapbox 为逆时针
// @see https://docs.mapbox.com/mapbox-gl-js/api/#map#getbearing
bearing: 360 - rotation,
far,
fov,
cameraHeight: height,
near,
pitch,
// AMap 定义的缩放等级 与 Mapbox 相差 1
zoom: this.map.getZoom() - 1,
center: [lng, lat],
offsetOrigin: [position.x, position.y],
});
this.emit('camerachange');
});
// 设置光照 主要用于3D地图
return new Promise((resolve) => {
AMap.plugin(['Map3D'], () => {
// 异步同时加载多个插件
this.map.AmbientLight = new AMap.Lights.AmbientLight([1, 1, 1], 1);
this.map.DirectionLight = new AMap.Lights.DirectionLight([0.1, 0.1, 1], [1, 1, 1], 1);
resolve();
this.emit('load');
});
});
}
destroy() {
super.destroy();
try {
this.map.destroy();
}
catch (e) {
/* 临时屏蔽destroy的错误 */
}
delete this.map;
this.emit('unloaded');
}
lnglatToPixel([lng, lat]) {
const { x, y } = this.map.lngLatToContainer(new AMap.LngLat(lng, lat));
return [x, y];
}
pixelToLnglat([x, y]) {
const { lng, lat } = this.map.containerToLngLat(new AMap.Pixel(x, y));
return [lng, lat];
}
changeTheme(theme) {
this.map.setMapStyle(`amap://styles/${theme}`);
}
getZoom() {
return this.map.getZoom();
}
setZoom(zoom) {
return this.map.setZoom(zoom + 1);
}
setZoomAndCenter(zoom, [lng, lat]) {
const center = new AMap.LngLat(lng, lat);
const { animateEnable } = this.map.getStatus();
this.map.setStatus({ animateEnable: false });
this.map.setZoomAndCenter(zoom + 1, center);
this.map.setStatus({ animateEnable });
}
zoomIn() {
this.map.zoomIn();
}
zoomOut() {
this.map.zoomOut();
}
// setBounds = ({ maxLng, minLng, maxLat, minLat }) => {
// this.map.setBounds(new AMap.Bounds(new AMap.LngLat(minLng, maxLat), new AMap.LngLat(maxLng, minLat)));
// };
//
// getBounds = () => {
// const { bounds, northeast, southwest } = this.map.getBounds();
// if (bounds) return path2Bounds(bounds.map(({ lng, lat }) => [lng, lat]));
// return path2Bounds([northeast, southwest].map(({ lng, lat }) => [lng, lat]));
// };
panTo([lng, lat]) {
this.map.panTo(new AMap.LngLat(lng - (lng % 0.000001), lat - (lat % 0.000001)));
}
getCenter() {
return this.map.getCenter();
}
setCenter([lng, lat]) {
const { map } = this;
const { animateEnable } = map.getStatus();
if (animateEnable)
map.setStatus({ animateEnable: false });
map.setCenter(new AMap.LngLat(lng, lat));
map.setStatus({ animateEnable });
}
getPitch() {
return this.map.getPitch();
}
setPitch(pitch) {
this.map.setPitch(pitch);
}
/**
* 设置旋转角度
*/
setRotate(deg) {
this.map.setRotation(-deg);
}
/**
* 获取旋转角度
*/
getRotate() {
return this.map.getRotation();
}
getMatrix() {
const { projectionMatrix, viewMatrix } = this.viewport;
// const mat = mat4.create();
// mat4.multiply(mat, mat, projectionMatrix as unknown as Float32Array);
// mat4.multiply(mat, mat, viewMatrix as unknown as Float32Array);
return [projectionMatrix, viewMatrix];
}
}
export default AMapInstance;