如何在 TypeScript 中的 webpack 中使用 seznam mapy?
Seznam mapy(mapy.cz)是谷歌地图的优秀捷克免费替代品,提供简单的 API https://api.mapy.cz/。但是如何在 TypeScript 中使用它们?在使用 webpack 打包的应用程序中?
答案#1
Seznam 地图 (SMap) 不支持 TypeScript,也不想支持。Seznam 地图论坛
地图不能从你的 npm 包中提供,必须即时加载。我准备了一个工厂、一个助手以及一个创建地图的示例。
- 工厂加载地图脚本,当所有内容准备就绪时,它会调用回调函数 afterInit()
- Helper 可以创建由地图对象使用的地图和对象
- 地图创建示例
- 官方文档链接 https://api.mapy.cz/
import SeznamMapHelper from "./SeznamMapHelper";
// Declare global Loader and SMap
declare global {
interface Window { Loader: any; SMap: any}
}
export default class SeznamMapFactory {
// Helper for simple creating seznam mapy objects
private _mapHelper?: SeznamMapHelper;
public init(afterInit?: ()=>void) {
afterInit = afterInit || (() => void 0);
if (!window.Loader) {
$.getScript('https://api.mapy.cz/loader.js', ()=> {
window.Loader.async = true;
window.Loader.load(null, null, afterInit?.bind(this));
});
} else {
afterInit();
}
}
public get helper(): SeznamMapHelper {
if (!window.Loader) {
throw Error('Seznam maps: Loader is not initialised. Please init() first.');
}
if (!this._mapHelper) {
this._mapHelper = new SeznamMapHelper;
}
return this._mapHelper;
}
}
辅助类,用于创建被SMap对象使用的对象(地图图层、标记等)。辅助类应根据您的需求进行改进。
// Declare types for Seznam Mapy
declare global {
interface Window { Loader: any; SMap: any}
}
export type TLayer = {
setClusterer: (clusterer: TClusterer) => TLayer,
addMarker: (marker: TMarker|TMarker[]) => TLayer,
enable: () => void,
disable: () => void,
redraw: (full: boolean) => void,
getId: () => string,
};
export type TClusterer = {};
export type TMarker = {
click: () => void,
getId: () => void,
decorate: (type: any, item: TCard)=>void,
};
export type TCard = {
setSize: (x:number, y:number)=>TCard,
getHeader: ()=>Element,
getFooter: ()=>Element,
getBody: ()=>Element,
}
export type TMap = {
addDefaultLayer: ([...any])=>TLayer,
addLayer: (layer: TLayer)=>TLayer,
addDefaultControls: ()=>TMap,
enable: ()=>TMap,
}
export default class SeznamMapHelper {
public createCoords(gpsLat: number, gpsLng: number): {x:number, y:number} {
return window.SMap.Coords.fromWGS84(gpsLng, gpsLat); // Seznam map has swapped coords, really.
}
public createMap(
el: Element,
gpsLat: number,
gpsLng: number,
zoom: number = 10
): TMap {
const center = this.createCoords(gpsLat, gpsLng);
return new window.SMap(el, center, zoom);
}
public createDefaultMap(el: Element, gpsLat: number = 50.12655, gpsLng: number = 14.41790): TMap {
const map = this.createMap(el, gpsLat, gpsLng, 10);
map.addDefaultLayer(window.SMap.DEF_BASE).enable();
map.addDefaultControls();
return map;
}
public createMarkerLayer(): TLayer {
return new window.SMap.Layer.Marker();
}
public createClusterer(map: TMap): TClusterer {
return new window.SMap.Marker.Clusterer(map);
}
public createMarker(
gpsLat: number,
gpsLng: number,
id: string|number|undefined = undefined,
title: string = '',
url: string|null = null
): TMarker {
const options: any = { title: title };
if (url) {
options.url = url;
}
return new window.SMap.Marker(this.createCoords(gpsLat, gpsLng), id, options);
}
public createCard(marker: TMarker, header: string, body: string, footer:string = '', x: number = 200, y:number = 200): TCard {
const card: TCard = new window.SMap.Card();
card.setSize(x, y);
card.getHeader().innerHTML = header;
card.getBody().innerHTML = body;
card.getFooter().innerHTML = footer;
marker.decorate(window.SMap.Marker.Feature.Card, card);
return card;
}
}
创建地图的示例:
let map: any; // SMap object
let mapContainter = document.getElementById("map"); // Html element to put a map
const mapFactory = new SeznamMapFactory(); // factory object
this.mapFactory.init( () => { // async load of scripts
map = mapFactory.helper.createDefaultMap(mapContainter); // after load we can use maps
// other map stuff - markers, layers, etc.
}
