实现方法:在封装多地图(百度地图、高德地图、腾讯地图)组件时,可以定义一个接口(interface)或一个抽象类(abstract),然后为每个地图API实现这个接口或抽象类,这样我的应用程序就可以通过调用统一的接口与不同的地图API进行交互,而不需要关心底层的逻辑实现的具体细节
// 1 引入
import BMap from 'BMap'; // 百度
import AMap from 'AMap'; // 高德
import * as qq from '@qq/maps' // 腾讯
// 2 定义类型
// 2.1 位置类型
type Position = { // 定义类型
lng: number, // 经度
lat: number // 维度
}
// interface 接口
// 定义百度、高德、腾讯地图API需要实现的方法 且必须实现
// 后期在定义一个工厂类 实现统一调用
// 2.1 百度
interface BaiduMarker extends BMap.Marker { }
interface BaiduMarkerOptions extends BMap.MarkerOptions {
position: Position;
}
// 2.2 高德
interface GaodeMarker extends AMap.Marker { }
interface GaodeMarkerOptions extends AMap.MarkerOptions {
position: Position;
}
// 泛型接口:e<TMarker, TMarkerOptions>允许在定义类型或函数时指定一个占位符类型,然后在使用时提供具体类型 目的:根据传入的类型参数动态地处理不同的地图API
interface MapService<TMarker, TMarkerOptions> {
// 地图初始化
init: (id: string, options?: any) => void;
// 添加撒点
addMarker: (position: Position, options?: TMarkerOptions) => TMarker;
// 移除撒点
removeMarker: (marker: TMarker) => void
}
// 百度地图API
class BaiduMapService implements MapService<BaiduMarker, BaiduMarkerOptions>{
// 定义内部资源类型
private map: BMap.Map
// 初始化
init(id: string, options?: any): void {
this.map = new BMap.Map(id)
if (options) {
// 设置地图中心坐标+级别
const point = new BMap.Point(options.center.lng, options.center.lat);
this.map.centerAndZoom(point, options.zoom);
// 其他设置...
}
}
// 添加撒点
addMarker(position: Position, options?: BaiduMarkerOptions): BaiduMarker {
const marker = new BMap.Marker(new BMap.Point(position.lng, position.lat), options)
this.map.addOverlay(marker)
return marker
}
// 移除撒点
removeMarker(marker: BaiduMarker): void {
this.map.removeOverlay(marker)
}
}
// 高德地图API
class GaodeMapService implements MapService<GaodeMarker, GaodeMarkerOptions>{
private map: AMap.Map
// 初始化
init(id: string, options?: any): void {
this.map = new AMap.Map(id, options)
}
// 添加撒点
addMarker(position: Position, options?: GaodeMarkerOptions): GaodeMarker {
const marker = new AMap.Marker({
position: [position.lng, position.lat],
...options
})
this.map.add(marker)
return marker
}
// 移除撒点
removeMarker(marker: GaodeMarker): void {
this.map.remove(marker)
}
}
class TengxunMapService implements MapService<any, any> {
private map: any; // 腾讯地图的实例类型可能不同
// 初始化
init(id: string, options?: any): void {
this.map = new qq.maps.Map(id, options);
}
// 添加撒点
addMarker(position: Position, options?: any): any {
const marker = new qq.maps.Marker({
position: new qq.maps.LatLny(position.lat, position.lng),
...options
})
this.map.addOverlay(marker)
return marker;
}
// 移除撒点
removeMarker(marker: any): void {
this.map.removeOverlay(marker)
}
}
// 采用工厂类 调用实例
class MapServiceFactory {
static createMapService<TMarker, TMarkerOptions>(type: string): MapService<TMarker, TMarkerOptions> {
switch (type) {
case 'baidu':
return new BaiduMapService() as MapService<TMarker, TMarkerOptions>;
case 'gaode':
return new GaodeMapService() as MapService<TMarker, TMarkerOptions>;
case 'tengxun':
return new TengxunMapService() as MapService<TMarker, TMarkerOptions>;
default:
throw new Error('Unsupported map type')
}
}
}
// 使用
<div id='map-container' > </div>
const options = { /* 地图初始化选项 */ };
const mapService = MapServiceFactory.createMapService('baidu');
mapService.init('map-container', options)
const markers = [/* 标记点数据 */];
markers.forEach(item => {
mapService.addMarker(item.position, item.options);
});