migrate map code to typescript

This commit is contained in:
MaysWind
2025-01-05 03:10:41 +08:00
parent a46399cbaf
commit 16fa77eb09
17 changed files with 919 additions and 912 deletions
+2 -2
View File
@@ -29,7 +29,7 @@ import { useExchangeRatesStore } from '@/stores/exchangeRates.js';
import { APPLICATION_LOGO_PATH } from '@/consts/asset.ts';
import { ThemeType } from '@/core/theme.ts';
import { isProduction } from '@/lib/version.ts';
import { loadMapAssets } from '@/lib/map/index.js';
import { initMapProvider } from '@/lib/map/index.ts';
import { getSystemTheme, setExpenseAndIncomeAmountColor } from '@/lib/ui/common.ts';
export default {
@@ -113,7 +113,7 @@ export default {
mounted() {
document.addEventListener('DOMContentLoaded', () => {
const languageInfo = this.$locale.getCurrentLanguageInfo();
loadMapAssets(languageInfo ? languageInfo.alternativeLanguageTag : null);
initMapProvider(languageInfo ? languageInfo.alternativeLanguageTag : null);
});
}
}
+2 -2
View File
@@ -19,7 +19,7 @@ import { APPLICATION_LOGO_PATH } from '@/consts/asset.ts';
import { ThemeType } from '@/core/theme.ts';
import { isProduction } from '@/lib/version.ts';
import { getTheme, isEnableAnimate } from '@/lib/settings.ts';
import { loadMapAssets } from '@/lib/map/index.js';
import { initMapProvider } from '@/lib/map/index.ts';
import { setExpenseAndIncomeAmountColor } from '@/lib/ui/common.ts';
import { isModalShowing, setAppFontSize } from '@/lib/ui/mobile.js';
@@ -194,7 +194,7 @@ export default {
document.addEventListener('DOMContentLoaded', () => {
const languageInfo = this.$locale.getCurrentLanguageInfo();
loadMapAssets(languageInfo ? languageInfo.alternativeLanguageTag : null);
initMapProvider(languageInfo ? languageInfo.alternativeLanguageTag : null);
});
},
methods: {
+99 -101
View File
@@ -8,112 +8,110 @@
v-if="!mapSupported || !mapDependencyLoaded"></slot>
</template>
<script>
import {
copyObjectTo
} from '@/lib/common.ts';
import {
createMapHolder,
initMapInstance,
setMapCenterTo,
setMapCenterMarker,
removeMapCenterMarker
} from '@/lib/map/index.js';
<script setup lang="ts">
import { type Ref, ref, computed, useTemplateRef } from 'vue';
export default {
props: [
'height',
'mapClass',
'mapStyle',
'geoLocation'
],
expose: [
'init'
],
data() {
this.mapHolder = createMapHolder();
import { useI18n } from '@/lib/i18n.js';
return {
mapSupported: !!this.mapHolder,
mapDependencyLoaded: this.mapHolder && this.mapHolder.dependencyLoaded,
mapInited: false,
initCenter: {
latitude: 0,
longitude: 0,
},
zoomLevel: 1
import { copyObjectTo } from '@/lib/common.ts';
import type { MapInstance, MapPosition } from '@/lib/map/base.ts';
import { createMapInstance } from '@/lib/map/index.ts';
const props = defineProps<{
height?: string;
mapClass?: string;
mapStyle?: Record<string, string>;
geoLocation?: MapPosition;
}>();
const { tt, getCurrentLanguageInfo } = useI18n();
const mapContainer: Ref<HTMLElement> = useTemplateRef('mapContainer');
const mapInstance: Ref<MapInstance> = ref(createMapInstance());
const initCenter: Ref<MapPosition> = ref({
latitude: 0,
longitude: 0
});
const zoomLevel: Ref<number> = ref(1);
const mapSupported = computed<boolean>(() => {
return !!mapInstance.value;
});
const mapDependencyLoaded = computed<boolean>(() => {
return mapInstance.value && mapInstance.value.dependencyLoaded;
});
const finalMapStyle = computed<Record<string, string>>(() => {
const styles = copyObjectTo(props.mapStyle, {});
if (props.height) {
styles.height = props.height;
}
if (!mapSupported.value || !mapDependencyLoaded.value) {
styles.height = '0';
}
return styles;
});
function init() {
let isFirstInit = false;
let centerChanged = false;
if (!mapSupported.value || !mapDependencyLoaded.value) {
return;
}
if (props.geoLocation && (props.geoLocation.longitude || props.geoLocation.latitude)) {
if (initCenter.value.latitude !== props.geoLocation.latitude || initCenter.value.longitude !== props.geoLocation.longitude) {
initCenter.value.latitude = props.geoLocation.latitude;
initCenter.value.longitude = props.geoLocation.longitude;
zoomLevel.value = mapInstance.value.defaultZoomLevel;
centerChanged = true;
}
},
computed: {
finalMapStyle() {
const styles = copyObjectTo(this.mapStyle, {});
} else if (!props.geoLocation || (!props.geoLocation.longitude && !props.geoLocation.latitude)) {
if (initCenter.value.latitude || initCenter.value.longitude) {
initCenter.value.latitude = 0;
initCenter.value.longitude = 0;
zoomLevel.value = mapInstance.value.minZoomLevel;
if (this.height) {
styles.height = this.height;
}
if (!this.mapSupported || !this.mapDependencyLoaded) {
styles.height = '0';
}
return styles;
}
},
methods: {
init() {
let isFirstInit = false;
let centerChanged = false;
if (!this.mapSupported || !this.mapDependencyLoaded) {
return;
}
if (this.geoLocation && (this.geoLocation.longitude || this.geoLocation.latitude)) {
if (this.initCenter.latitude !== this.geoLocation.latitude || this.initCenter.longitude !== this.geoLocation.longitude) {
this.initCenter.latitude = this.geoLocation.latitude;
this.initCenter.longitude = this.geoLocation.longitude;
this.zoomLevel = this.mapHolder.defaultZoomLevel;
centerChanged = true;
}
} else if (!this.geoLocation || (!this.geoLocation.longitude && !this.geoLocation.latitude)) {
if (this.initCenter.latitude || this.initCenter.longitude) {
this.initCenter.latitude = 0;
this.initCenter.longitude = 0;
this.zoomLevel = this.mapHolder.minZoomLevel;
centerChanged = true;
}
}
if (!this.mapHolder.inited) {
const languageInfo = this.$locale.getCurrentLanguageInfo();
initMapInstance(this.mapHolder, this.$refs.mapContainer, {
language: languageInfo ? languageInfo.alternativeLanguageTag : null,
initCenter: this.initCenter,
zoomLevel: this.zoomLevel,
text: {
zoomIn: this.$t('Zoom in'),
zoomOut: this.$t('Zoom out'),
}
});
if (this.mapHolder.inited) {
isFirstInit = true;
}
}
if (isFirstInit || centerChanged) {
setMapCenterTo(this.mapHolder, this.initCenter, this.zoomLevel);
}
if (centerChanged && this.zoomLevel > this.mapHolder.minZoomLevel) {
setMapCenterMarker(this.mapHolder, this.initCenter);
} else if (centerChanged && this.zoomLevel <= this.mapHolder.minZoomLevel) {
removeMapCenterMarker(this.mapHolder);
}
centerChanged = true;
}
}
if (!mapInstance.value.inited) {
const languageInfo = getCurrentLanguageInfo();
mapInstance.value.initMapInstance(mapContainer.value, {
language: languageInfo?.alternativeLanguageTag,
initCenter: initCenter.value,
zoomLevel: zoomLevel.value,
text: {
zoomIn: tt('Zoom in'),
zoomOut: tt('Zoom out'),
}
});
if (mapInstance.value.inited) {
isFirstInit = true;
}
}
if (isFirstInit || centerChanged) {
mapInstance.value.setMapCenterTo(initCenter.value, zoomLevel.value);
}
if (centerChanged && zoomLevel.value > mapInstance.value.minZoomLevel) {
mapInstance.value.setMapCenterMarker(initCenter.value);
} else if (centerChanged && zoomLevel.value <= mapInstance.value.minZoomLevel) {
mapInstance.value.removeMapCenterMarker();
}
}
defineExpose({
init
});
</script>
+7 -7
View File
@@ -1,23 +1,23 @@
export interface PresetLeafletTileSource {
export interface LeafletTileSource {
readonly tileUrlFormat: string;
readonly tileUrlSubDomains: string;
readonly tileUrlExtraParams?: PresetLeafletTileSourceExtraParam[];
readonly tileUrlExtraParams?: LeafletTileSourceExtraParam[];
readonly annotationUrlFormat?: string;
readonly annotationUrlSubDomains?: string;
readonly annotationUrlExtraParams?: PresetLeafletTileSourceExtraParam[];
readonly annotationUrlExtraParams?: LeafletTileSourceExtraParam[];
readonly minZoom: number;
readonly maxZoom: number;
readonly defaultZoomLevel: number;
readonly website: string;
readonly attribution: string;
readonly website?: string;
readonly attribution?: string;
}
export interface PresetLeafletTileSourceExtraParam {
export interface LeafletTileSourceExtraParam {
readonly paramName: string;
readonly paramValueType: string;
}
export const LEAFLET_TILE_SOURCES: Record<string, PresetLeafletTileSource> = {
export const LEAFLET_TILE_SOURCES: Record<string, LeafletTileSource> = {
'openstreetmap': {
tileUrlFormat: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
tileUrlSubDomains: 'abc',
-173
View File
@@ -1,173 +0,0 @@
import { asyncLoadAssets } from '@/lib/misc.ts';
import services from '@/lib/services.js';
import {
getAmapSecurityVerificationMethod,
getAmapApiExternalProxyUrl,
getAmapApplicationSecret
} from '@/lib/server_settings.ts';
import logger from '@/lib/logger.ts';
const amapHolder = {
AMap: null
};
export function getAmapWebsite() {
return 'https://www.amap.com';
}
export function loadAmapAssets() {
if (amapHolder.AMap) {
return;
}
if (!window._AMapSecurityConfig) {
const amapSecurityConfig = {};
if (getAmapSecurityVerificationMethod() === 'internalproxy') {
amapSecurityConfig.serviceHost = services.generateAmapApiInternalProxyUrl();
} else if (getAmapSecurityVerificationMethod() === 'externalproxy') {
amapSecurityConfig.serviceHost = getAmapApiExternalProxyUrl();
} else if (getAmapSecurityVerificationMethod() === 'plaintext') {
amapSecurityConfig.securityJsCode = getAmapApplicationSecret();
}
window._AMapSecurityConfig = amapSecurityConfig;
}
if (!window.onAMapCallback) {
window.onAMapCallback = () => {
amapHolder.AMap = window.AMap;
};
}
return asyncLoadAssets('js', services.generateAmapJavascriptUrl('onAMapCallback'));
}
export function createAmapHolder() {
return {
mapProvider: 'amap',
dependencyLoaded: !!amapHolder.AMap,
inited: false,
defaultZoomLevel: 14,
minZoomLevel: 1,
amapInstance: null,
amapToolbar: null,
amapCenterPosition: null,
amapCenterMarker: null
};
}
export function createAmapInstance(mapHolder, mapContainer, options) {
if (!amapHolder.AMap) {
return null;
}
const AMap = amapHolder.AMap;
const amapInstance = new AMap.Map(mapContainer, {
zoom: options.zoomLevel,
center: [ options.initCenter.longitude, options.initCenter.latitude ],
zooms: [ 1, 19 ],
jogEnable: false
});
const amapToolbar = new AMap.ToolBar({
position: 'LT'
});
amapInstance.addControl(amapToolbar);
mapHolder.amapInstance = amapInstance;
mapHolder.amapToolbar = amapToolbar;
mapHolder.inited = true;
}
export function setAmapCenterTo(mapHolder, center, zoomLevel) {
if (!amapHolder.AMap || !mapHolder.amapInstance) {
return;
}
const AMap = amapHolder.AMap;
if (amapHolder.amapCenterPosition
&& amapHolder.amapCenterPosition.originalLongitude === center.longitude
&& amapHolder.amapCenterPosition.originalLatitude === center.latitude
&& amapHolder.amapCenterPosition.convertedLongitude
&& amapHolder.amapCenterPosition.convertedLatitude
) {
mapHolder.amapInstance.setZoomAndCenter(zoomLevel, new AMap.LngLat(amapHolder.amapCenterPosition.convertedLongitude, amapHolder.amapCenterPosition.convertedLatitude));
return;
}
amapHolder.amapCenterPosition = {
originalLongitude: center.longitude,
originalLatitude: center.latitude,
convertedLongitude: null,
convertedLatitude: null
};
const centerPoint = new AMap.LngLat(center.longitude, center.latitude);
AMap.convertFrom(centerPoint, 'gps', (status, result) => {
let convertedCenterPoint = centerPoint;
if (result.info !== 'ok' || !result.locations) {
logger.warn('amap geo position convert failed');
} else {
convertedCenterPoint = result.locations[0];
amapHolder.amapCenterPosition.convertedLongitude = convertedCenterPoint.getLng();
amapHolder.amapCenterPosition.convertedLatitude = convertedCenterPoint.getLat();
}
mapHolder.amapInstance.setZoomAndCenter(zoomLevel, convertedCenterPoint);
});
}
export function setAmapCenterMaker(mapHolder, position) {
if (!amapHolder.AMap || !mapHolder.amapInstance) {
return;
}
const AMap = amapHolder.AMap;
const setMaker = function (point) {
if (!mapHolder.amapCenterMarker) {
mapHolder.amapCenterMarker = new AMap.Marker({
position: point
});
mapHolder.amapInstance.add(mapHolder.amapCenterMarker);
} else {
mapHolder.amapCenterMarker.setPosition(point);
}
}
if (amapHolder.amapCenterPosition
&& amapHolder.amapCenterPosition.originalLongitude === position.longitude
&& amapHolder.amapCenterPosition.originalLatitude === position.latitude
&& amapHolder.amapCenterPosition.convertedLongitude
&& amapHolder.amapCenterPosition.convertedLatitude
) {
setMaker(new AMap.LngLat(amapHolder.amapCenterPosition.convertedLongitude, amapHolder.amapCenterPosition.convertedLatitude));
return;
}
const markerPoint = new AMap.LngLat(position.longitude, position.latitude);
AMap.convertFrom(markerPoint, 'gps', (status, result) => {
let convertedMarkPoint = markerPoint;
if (result.info !== 'ok' || !result.locations) {
logger.warn('amap geo position convert failed');
} else {
convertedMarkPoint = result.locations[0];
}
setMaker(convertedMarkPoint);
});
}
export function removeAmapCenterMaker(mapHolder) {
if (!mapHolder.amapInstance || !mapHolder.amapCenterMarker) {
return;
}
mapHolder.amapInstance.remove(mapHolder.amapCenterMarker);
mapHolder.amapCenterMarker = null;
}
+192
View File
@@ -0,0 +1,192 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
import type { MapProvider, MapInstance, MapInstanceInitOptions, MapPosition } from './base.ts';
import { asyncLoadAssets } from '@/lib/misc.ts';
import services from '@/lib/services.js';
import {
getAmapSecurityVerificationMethod,
getAmapApiExternalProxyUrl,
getAmapApplicationSecret
} from '@/lib/server_settings.ts';
import logger from '@/lib/logger.ts';
export class AmapMapProvider implements MapProvider {
public static AMap: unknown = null;
public getWebsite(): string {
return 'https://www.amap.com';
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public asyncLoadAssets(language: string): Promise<unknown> {
if (AmapMapProvider.AMap) {
return Promise.resolve();
}
if (!window._AMapSecurityConfig) {
const amapSecurityConfig = {};
if (getAmapSecurityVerificationMethod() === 'internalproxy') {
amapSecurityConfig.serviceHost = services.generateAmapApiInternalProxyUrl();
} else if (getAmapSecurityVerificationMethod() === 'externalproxy') {
amapSecurityConfig.serviceHost = getAmapApiExternalProxyUrl();
} else if (getAmapSecurityVerificationMethod() === 'plaintext') {
amapSecurityConfig.securityJsCode = getAmapApplicationSecret();
}
window._AMapSecurityConfig = amapSecurityConfig;
}
if (!window.onAMapCallback) {
window.onAMapCallback = () => {
AmapMapProvider.AMap = window.AMap;
};
}
return asyncLoadAssets('js', services.generateAmapJavascriptUrl('onAMapCallback'));
}
public createMapInstance(): MapInstance | null {
return new AmapMapInstance();
}
}
export class AmapMapInstance implements MapInstance {
public dependencyLoaded: boolean = false;
public inited: boolean = false;
public readonly defaultZoomLevel: number = 14;
public readonly minZoomLevel: number = 1;
private amapInstance: unknown = null;
private amapToolbar: unknown = null;
private amapCenterPosition: unknown = null;
private amapCenterMarker: unknown | null;
constructor() {
this.dependencyLoaded = !!AmapMapProvider.AMap;
}
public initMapInstance(mapContainer: HTMLElement, options: MapInstanceInitOptions): void {
if (!AmapMapProvider.AMap) {
return;
}
const AMap = AmapMapProvider.AMap;
const amapInstance = new AMap.Map(mapContainer, {
zoom: options.zoomLevel,
center: [ options.initCenter.longitude, options.initCenter.latitude ],
zooms: [ 1, 19 ],
jogEnable: false
});
const amapToolbar = new AMap.ToolBar({
position: 'LT'
});
amapInstance.addControl(amapToolbar);
this.amapInstance = amapInstance;
this.amapToolbar = amapToolbar;
this.inited = true;
}
public setMapCenterTo(center: MapPosition, zoomLevel: number): void {
if (!AmapMapProvider.AMap || !this.amapInstance) {
return;
}
const AMap = AmapMapProvider.AMap;
if (this.amapCenterPosition
&& this.amapCenterPosition.originalLongitude === center.longitude
&& this.amapCenterPosition.originalLatitude === center.latitude
&& this.amapCenterPosition.convertedLongitude
&& this.amapCenterPosition.convertedLatitude
) {
this.amapInstance.setZoomAndCenter(zoomLevel, new AMap.LngLat(this.amapCenterPosition.convertedLongitude, this.amapCenterPosition.convertedLatitude));
return;
}
this.amapCenterPosition = {
originalLongitude: center.longitude,
originalLatitude: center.latitude,
convertedLongitude: null,
convertedLatitude: null
};
const centerPoint = new AMap.LngLat(center.longitude, center.latitude);
AMap.convertFrom(centerPoint, 'gps', (status, result) => {
let convertedCenterPoint = centerPoint;
if (result.info !== 'ok' || !result.locations) {
logger.warn('amap geo position convert failed');
} else {
convertedCenterPoint = result.locations[0];
this.amapCenterPosition.convertedLongitude = convertedCenterPoint.getLng();
this.amapCenterPosition.convertedLatitude = convertedCenterPoint.getLat();
}
this.amapInstance.setZoomAndCenter(zoomLevel, convertedCenterPoint);
});
}
public setMapCenterMarker(position: MapPosition): void {
if (!AmapMapProvider.AMap || !this.amapInstance) {
return;
}
const AMap = AmapMapProvider.AMap;
if (this.amapCenterPosition
&& this.amapCenterPosition.originalLongitude === position.longitude
&& this.amapCenterPosition.originalLatitude === position.latitude
&& this.amapCenterPosition.convertedLongitude
&& this.amapCenterPosition.convertedLatitude
) {
this.setMaker(new AMap.LngLat(this.amapCenterPosition.convertedLongitude, this.amapCenterPosition.convertedLatitude));
return;
}
const markerPoint = new AMap.LngLat(position.longitude, position.latitude);
AMap.convertFrom(markerPoint, 'gps', (status, result) => {
let convertedMarkPoint = markerPoint;
if (result.info !== 'ok' || !result.locations) {
logger.warn('amap geo position convert failed');
} else {
convertedMarkPoint = result.locations[0];
}
this.setMaker(convertedMarkPoint);
});
}
public removeMapCenterMarker(): void {
if (!this.amapInstance || !this.amapCenterMarker) {
return;
}
this.amapInstance.remove(this.amapCenterMarker);
this.amapCenterMarker = null;
}
private setMaker(point: unknown): void {
if (!AmapMapProvider.AMap || !this.amapInstance) {
return;
}
const AMap = AmapMapProvider.AMap;
if (!this.amapCenterMarker) {
this.amapCenterMarker = new AMap.Marker({
position: point
});
this.amapInstance.add(this.amapCenterMarker);
} else {
this.amapCenterMarker.setPosition(point);
}
}
}
-166
View File
@@ -1,166 +0,0 @@
import { asyncLoadAssets } from '@/lib/misc.ts';
import services from '@/lib/services.js';
import logger from '@/lib/logger.ts';
const baiduMapHolder = {
BMap: null,
BMAP_NAVIGATION_CONTROL_ZOOM: window.BMAP_NAVIGATION_CONTROL_ZOOM || 3,
BMAP_ANCHOR_TOP_LEFT: window.BMAP_ANCHOR_TOP_LEFT || 0,
COORDINATES_WGS84: window.COORDINATES_WGS84 || 1,
COORDINATES_BD09: window.COORDINATES_BD09 || 5
};
export function getBaiduMapWebsite() {
return 'https://map.baidu.com';
}
export function loadBaiduMapAssets() {
if (baiduMapHolder.BMap) {
return;
}
if (!window.onBMapCallback) {
window.onBMapCallback = () => {
baiduMapHolder.BMap = window.BMap;
};
}
return asyncLoadAssets('js', services.generateBaiduMapJavascriptUrl('onBMapCallback'));
}
export function createBaiduMapHolder() {
return {
mapProvider: 'baidumap',
dependencyLoaded: !!baiduMapHolder.BMap,
inited: false,
defaultZoomLevel: 15,
minZoomLevel: 1,
baiduMapInstance: null,
baiduMapConverter: null,
baiduMapNavigationControl: null,
baiduMapCenterPosition: null,
baiduMapCenterMarker: null
};
}
export function createBaiduMapInstance(mapHolder, mapContainer, options) {
if (!baiduMapHolder.BMap) {
return null;
}
const BMap = baiduMapHolder.BMap;
const baiduMapInstance = new BMap.Map(mapContainer, {
maxZoom: 19
});
baiduMapInstance.enableScrollWheelZoom();
const baiduMapNavigationControl = new BMap.NavigationControl({
type: baiduMapHolder.BMAP_NAVIGATION_CONTROL_ZOOM,
anchor: baiduMapHolder.BMAP_ANCHOR_TOP_LEFT
});
baiduMapInstance.addControl(baiduMapNavigationControl);
baiduMapInstance.centerAndZoom(new BMap.Point(options.initCenter.longitude, options.initCenter.latitude), options.zoomLevel);
mapHolder.baiduMapInstance = baiduMapInstance;
mapHolder.baiduMapConverter = new BMap.Convertor();
mapHolder.baiduMapNavigationControl = baiduMapNavigationControl;
mapHolder.inited = true;
}
export function setBaiduMapCenterTo(mapHolder, center, zoomLevel) {
if (!baiduMapHolder.BMap || !mapHolder.baiduMapInstance) {
return;
}
const BMap = baiduMapHolder.BMap;
if (baiduMapHolder.baiduMapCenterPosition
&& baiduMapHolder.baiduMapCenterPosition.originalLongitude === center.longitude
&& baiduMapHolder.baiduMapCenterPosition.originalLatitude === center.latitude
&& baiduMapHolder.baiduMapCenterPosition.convertedLongitude
&& baiduMapHolder.baiduMapCenterPosition.convertedLatitude
) {
mapHolder.baiduMapInstance.centerAndZoom(new BMap.Point(baiduMapHolder.baiduMapCenterPosition.convertedLongitude, baiduMapHolder.baiduMapCenterPosition.convertedLatitude), zoomLevel);
return;
}
baiduMapHolder.baiduMapCenterPosition = {
originalLongitude: center.longitude,
originalLatitude: center.latitude,
convertedLongitude: null,
convertedLatitude: null
};
const centerPoint = new BMap.Point(center.longitude, center.latitude);
if (mapHolder.baiduMapConverter) {
mapHolder.baiduMapConverter.translate([ centerPoint ], baiduMapHolder.COORDINATES_WGS84, baiduMapHolder.COORDINATES_BD09, data => {
let convertedCenterPoint = centerPoint;
if (data.status !== 0 || !data.points) {
logger.warn('baidu map geo position convert failed');
} else {
convertedCenterPoint = data.points[0];
baiduMapHolder.baiduMapCenterPosition.convertedLongitude = convertedCenterPoint.lng;
baiduMapHolder.baiduMapCenterPosition.convertedLatitude = convertedCenterPoint.lat;
}
mapHolder.baiduMapInstance.centerAndZoom(convertedCenterPoint, zoomLevel);
});
} else {
mapHolder.baiduMapInstance.centerAndZoom(centerPoint, zoomLevel);
}
}
export function setBaiduMapCenterMaker(mapHolder, position) {
if (!baiduMapHolder.BMap || !mapHolder.baiduMapInstance) {
return;
}
const BMap = baiduMapHolder.BMap;
const setMaker = function (point) {
if (!mapHolder.baiduMapCenterMarker) {
mapHolder.baiduMapCenterMarker = new BMap.Marker(point);
mapHolder.baiduMapInstance.addOverlay(mapHolder.baiduMapCenterMarker);
} else {
mapHolder.baiduMapCenterMarker.setPosition(point);
}
}
if (baiduMapHolder.baiduMapCenterPosition
&& baiduMapHolder.baiduMapCenterPosition.originalLongitude === position.longitude
&& baiduMapHolder.baiduMapCenterPosition.originalLatitude === position.latitude
&& baiduMapHolder.baiduMapCenterPosition.convertedLongitude
&& baiduMapHolder.baiduMapCenterPosition.convertedLatitude
) {
setMaker(new BMap.Point(baiduMapHolder.baiduMapCenterPosition.convertedLongitude, baiduMapHolder.baiduMapCenterPosition.convertedLatitude));
return;
}
const markerPoint = new BMap.Point(position.longitude, position.latitude);
if (mapHolder.baiduMapConverter) {
mapHolder.baiduMapConverter.translate([ markerPoint ], baiduMapHolder.COORDINATES_WGS84, baiduMapHolder.COORDINATES_BD09, data => {
let convertedMarkPoint = markerPoint;
if (data.status !== 0 || !data.points) {
logger.warn('baidu map geo position convert failed');
} else {
convertedMarkPoint = data.points[0];
}
setMaker(convertedMarkPoint);
});
} else {
setMaker(markerPoint);
}
}
export function removeBaiduMapCenterMaker(mapHolder) {
if (!mapHolder.baiduMapInstance || !mapHolder.baiduMapCenterMarker) {
return;
}
mapHolder.baiduMapInstance.removeOverlay(mapHolder.baiduMapCenterMarker);
mapHolder.baiduMapCenterMarker = null;
}
+189
View File
@@ -0,0 +1,189 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
import type { MapProvider, MapInstance, MapInstanceInitOptions, MapPosition } from './base.ts';
import { asyncLoadAssets } from '@/lib/misc.ts';
import services from '@/lib/services.js';
import logger from '@/lib/logger.ts';
export class BaiduMapProvider implements MapProvider {
public static BMap: unknown = null;
public static BMAP_NAVIGATION_CONTROL_ZOOM: unknown = window.BMAP_NAVIGATION_CONTROL_ZOOM || 3;
public static BMAP_ANCHOR_TOP_LEFT: unknown = window.BMAP_ANCHOR_TOP_LEFT || 0;
public static COORDINATES_WGS84: unknown = window.COORDINATES_WGS84 || 1;
public static COORDINATES_BD09: unknown = window.COORDINATES_BD09 || 5;
public getWebsite(): string {
return 'https://map.baidu.com';
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public asyncLoadAssets(language: string): Promise<unknown> {
if (BaiduMapProvider.BMap) {
return Promise.resolve();
}
if (!window.onBMapCallback) {
window.onBMapCallback = () => {
BaiduMapProvider.BMap = window.BMap;
BaiduMapProvider.BMAP_NAVIGATION_CONTROL_ZOOM = window.BMAP_NAVIGATION_CONTROL_ZOOM || 3;
BaiduMapProvider.BMAP_ANCHOR_TOP_LEFT = window.BMAP_ANCHOR_TOP_LEFT || 0;
BaiduMapProvider.COORDINATES_WGS84 = window.COORDINATES_WGS84 || 1;
BaiduMapProvider.COORDINATES_BD09 = window.COORDINATES_BD09 || 5;
};
}
return asyncLoadAssets('js', services.generateBaiduMapJavascriptUrl('onBMapCallback'));
}
public createMapInstance(): MapInstance | null {
return new BaiduMapInstance();
}
}
export class BaiduMapInstance implements MapInstance {
public dependencyLoaded: boolean = false;
public inited: boolean = false;
public readonly defaultZoomLevel: number = 15;
public readonly minZoomLevel: number = 1;
private baiduMapInstance: unknown = null;
private baiduMapConverter: unknown = null;
private baiduMapNavigationControl: unknown = null;
private baiduMapCenterPosition: unknown = null;
private baiduMapCenterMarker: unknown | null;
constructor() {
this.dependencyLoaded = !!BaiduMapProvider.BMap;
}
public initMapInstance(mapContainer: HTMLElement, options: MapInstanceInitOptions): void {
if (!BaiduMapProvider.BMap) {
return;
}
const BMap = BaiduMapProvider.BMap;
const baiduMapInstance = new BMap.Map(mapContainer, {
maxZoom: 19
});
baiduMapInstance.enableScrollWheelZoom();
const baiduMapNavigationControl = new BMap.NavigationControl({
type: BaiduMapProvider.BMAP_NAVIGATION_CONTROL_ZOOM,
anchor: BaiduMapProvider.BMAP_ANCHOR_TOP_LEFT
});
baiduMapInstance.addControl(baiduMapNavigationControl);
baiduMapInstance.centerAndZoom(new BMap.Point(options.initCenter.longitude, options.initCenter.latitude), options.zoomLevel);
this.baiduMapInstance = baiduMapInstance;
this.baiduMapConverter = new BMap.Convertor();
this.baiduMapNavigationControl = baiduMapNavigationControl;
this.inited = true;
}
public setMapCenterTo(center: MapPosition, zoomLevel: number): void {
if (!BaiduMapProvider.BMap || !this.baiduMapInstance) {
return;
}
const BMap = BaiduMapProvider.BMap;
if (this.baiduMapCenterPosition
&& this.baiduMapCenterPosition.originalLongitude === center.longitude
&& this.baiduMapCenterPosition.originalLatitude === center.latitude
&& this.baiduMapCenterPosition.convertedLongitude
&& this.baiduMapCenterPosition.convertedLatitude
) {
this.baiduMapInstance.centerAndZoom(new BMap.Point(this.baiduMapCenterPosition.convertedLongitude, this.baiduMapCenterPosition.convertedLatitude), zoomLevel);
return;
}
this.baiduMapCenterPosition = {
originalLongitude: center.longitude,
originalLatitude: center.latitude,
convertedLongitude: null,
convertedLatitude: null
};
const centerPoint = new BMap.Point(center.longitude, center.latitude);
if (this.baiduMapConverter) {
this.baiduMapConverter.translate([ centerPoint ], BaiduMapProvider.COORDINATES_WGS84, BaiduMapProvider.COORDINATES_BD09, data => {
let convertedCenterPoint = centerPoint;
if (data.status !== 0 || !data.points) {
logger.warn('baidu map geo position convert failed');
} else {
convertedCenterPoint = data.points[0];
this.baiduMapCenterPosition.convertedLongitude = convertedCenterPoint.lng;
this.baiduMapCenterPosition.convertedLatitude = convertedCenterPoint.lat;
}
this.baiduMapInstance.centerAndZoom(convertedCenterPoint, zoomLevel);
});
} else {
this.baiduMapInstance.centerAndZoom(centerPoint, zoomLevel);
}
}
public setMapCenterMarker(position: MapPosition): void {
if (!BaiduMapProvider.BMap || !this.baiduMapInstance) {
return;
}
const BMap = BaiduMapProvider.BMap;
if (this.baiduMapCenterPosition
&& this.baiduMapCenterPosition.originalLongitude === position.longitude
&& this.baiduMapCenterPosition.originalLatitude === position.latitude
&& this.baiduMapCenterPosition.convertedLongitude
&& this.baiduMapCenterPosition.convertedLatitude
) {
this.setMaker(new BMap.Point(this.baiduMapCenterPosition.convertedLongitude, this.baiduMapCenterPosition.convertedLatitude));
return;
}
const markerPoint = new BMap.Point(position.longitude, position.latitude);
if (this.baiduMapConverter) {
this.baiduMapConverter.translate([ markerPoint ], BaiduMapProvider.COORDINATES_WGS84, BaiduMapProvider.COORDINATES_BD09, data => {
let convertedMarkPoint = markerPoint;
if (data.status !== 0 || !data.points) {
logger.warn('baidu map geo position convert failed');
} else {
convertedMarkPoint = data.points[0];
}
this.setMaker(convertedMarkPoint);
});
} else {
this.setMaker(markerPoint);
}
}
public removeMapCenterMarker(): void {
if (!this.baiduMapInstance || !this.baiduMapCenterMarker) {
return;
}
this.baiduMapInstance.removeOverlay(this.baiduMapCenterMarker);
this.baiduMapCenterMarker = null;
}
private setMaker(point: unknown): void {
if (!BaiduMapProvider.BMap || !this.baiduMapInstance) {
return;
}
const BMap = BaiduMapProvider.BMap;
if (!this.baiduMapCenterMarker) {
this.baiduMapCenterMarker = new BMap.Marker(point);
this.baiduMapInstance.addOverlay(this.baiduMapCenterMarker);
} else {
this.baiduMapCenterMarker.setPosition(point);
}
}
}
+31
View File
@@ -0,0 +1,31 @@
export interface MapProvider {
getWebsite(): string;
asyncLoadAssets(language: string): Promise<unknown>;
createMapInstance(): MapInstance | null;
}
export interface MapInstance {
dependencyLoaded: boolean;
inited: boolean;
readonly defaultZoomLevel: number;
readonly minZoomLevel: number;
initMapInstance(mapContainer: HTMLElement, options: MapInstanceInitOptions): void;
setMapCenterTo(center: MapPosition, zoomLevel: number): void;
setMapCenterMarker(position: MapPosition): void;
removeMapCenterMarker(): void;
}
export interface MapInstanceInitOptions {
readonly language?: string;
readonly initCenter: MapPosition;
readonly zoomLevel: number;
readonly text: {
readonly zoomIn: string;
readonly zoomOut: string;
}
}
export interface MapPosition {
latitude: number;
longitude: number;
}
-113
View File
@@ -1,113 +0,0 @@
import { asyncLoadAssets } from '@/lib/misc.ts';
import services from '@/lib/services.js';
const googleMapHolder = {
googleMap: null,
ControlPosition: {
LEFT_TOP: (window.google && window.google.maps && window.google.maps.ControlPosition) ? window.google.maps.ControlPosition.LEFT_TOP : 5
}
};
export function getGoogleMapWebsite() {
return 'https://maps.google.com';
}
export function loadGoogleMapAssets(language) {
if (googleMapHolder.googleMap) {
return;
}
if (!window.onGoogleMapCallback) {
window.onGoogleMapCallback = () => {
if (window.google) {
googleMapHolder.googleMap = window.google.maps;
}
};
}
return asyncLoadAssets('js', services.generateGoogleMapJavascriptUrl(language, 'onGoogleMapCallback'));
}
export function createGoogleMapHolder() {
return {
mapProvider: 'googlemap',
dependencyLoaded: !!googleMapHolder.googleMap,
inited: false,
defaultZoomLevel: 14,
minZoomLevel: 1,
googleMapInstance: null,
googleMapCenterMarker: null
};
}
export function createGoogleMapInstance(mapHolder, mapContainer, options) {
if (!googleMapHolder.googleMap) {
return null;
}
const googleMap = googleMapHolder.googleMap;
mapHolder.googleMapInstance = new googleMap.Map(mapContainer, {
zoom: options.zoomLevel,
center: {
lat: options.initCenter.latitude,
lng: options.initCenter.longitude
},
maxZoom: 19,
zoomControl: true,
mapTypeControl: false,
scaleControl: false,
streetViewControl: false,
rotateControl: false,
fullscreenControl: false,
gestureHandling: 'greedy',
zoomControlOptions: {
position: googleMapHolder.ControlPosition.LEFT_TOP
}
});
mapHolder.inited = true;
}
export function setGoogleMapCenterTo(mapHolder, center, zoomLevel) {
if (!googleMapHolder.googleMap || !mapHolder.googleMapInstance) {
return;
}
mapHolder.googleMapInstance.setCenter({
lat: center.latitude,
lng: center.longitude
});
mapHolder.googleMapInstance.setZoom(zoomLevel);
}
export function setGoogleMapCenterMaker(mapHolder, position) {
if (!googleMapHolder.googleMap || !mapHolder.googleMapInstance) {
return;
}
const googleMap = googleMapHolder.googleMap;
if (!mapHolder.googleMapCenterMarker) {
mapHolder.googleMapCenterMarker = new googleMap.Marker({
position: {
lat: position.latitude,
lng: position.longitude
},
map: mapHolder.googleMapInstance
});
} else {
mapHolder.googleMapCenterMarker.setPosition({
lat: position.latitude,
lng: position.longitude
});
}
}
export function removeGoogleMapCenterMaker(mapHolder) {
if (!mapHolder.googleMapInstance || !mapHolder.googleMapCenterMarker) {
return;
}
mapHolder.googleMapCenterMarker.setMap(null);
mapHolder.googleMapCenterMarker = null;
}
+125
View File
@@ -0,0 +1,125 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
import type { MapProvider, MapInstance, MapInstanceInitOptions, MapPosition } from './base.ts';
import { asyncLoadAssets } from '@/lib/misc.ts';
import services from '@/lib/services.js';
export class GoogleMapProvider implements MapProvider {
public static GoogleMap: unknown = null;
public static ControlPosition = {
LEFT_TOP: (window.google && window.google.maps && window.google.maps.ControlPosition) ? window.google.maps.ControlPosition.LEFT_TOP : 5
};
public getWebsite(): string {
return 'https://maps.google.com';
}
public asyncLoadAssets(language: string): Promise<unknown> {
if (GoogleMapProvider.GoogleMap) {
return Promise.resolve();
}
if (!window.onGoogleMapCallback) {
window.onGoogleMapCallback = () => {
if (window.google) {
GoogleMapProvider.GoogleMap = window.google.maps;
GoogleMapProvider.ControlPosition.LEFT_TOP = (window.google && window.google.maps && window.google.maps.ControlPosition) ? window.google.maps.ControlPosition.LEFT_TOP : 5;
}
};
}
return asyncLoadAssets('js', services.generateGoogleMapJavascriptUrl(language, 'onGoogleMapCallback'));
}
public createMapInstance(): MapInstance | null {
return new GoogleMapInstance();
}
}
export class GoogleMapInstance implements MapInstance {
public dependencyLoaded: boolean = false;
public inited: boolean = false;
public readonly defaultZoomLevel: number = 14;
public readonly minZoomLevel: number = 1;
private googleMapInstance: unknown = null;
private googleMapCenterMarker: unknown | null;
constructor() {
this.dependencyLoaded = !!GoogleMapProvider.GoogleMap;
}
public initMapInstance(mapContainer: HTMLElement, options: MapInstanceInitOptions): void {
if (!GoogleMapProvider.GoogleMap) {
return;
}
const googleMap = GoogleMapProvider.GoogleMap;
this.googleMapInstance = new googleMap.Map(mapContainer, {
zoom: options.zoomLevel,
center: {
lat: options.initCenter.latitude,
lng: options.initCenter.longitude
},
maxZoom: 19,
zoomControl: true,
mapTypeControl: false,
scaleControl: false,
streetViewControl: false,
rotateControl: false,
fullscreenControl: false,
gestureHandling: 'greedy',
zoomControlOptions: {
position: GoogleMapProvider.ControlPosition.LEFT_TOP
}
});
this.inited = true;
}
public setMapCenterTo(center: MapPosition, zoomLevel: number): void {
if (!GoogleMapProvider.GoogleMap || !this.googleMapInstance) {
return;
}
this.googleMapInstance.setCenter({
lat: center.latitude,
lng: center.longitude
});
this.googleMapInstance.setZoom(zoomLevel);
}
public setMapCenterMarker(position: MapPosition): void {
if (!GoogleMapProvider.GoogleMap || !this.googleMapInstance) {
return;
}
const googleMap = GoogleMapProvider.GoogleMap;
if (!this.googleMapCenterMarker) {
this.googleMapCenterMarker = new googleMap.Marker({
position: {
lat: position.latitude,
lng: position.longitude
},
map: this.googleMapInstance
});
} else {
this.googleMapCenterMarker.setPosition({
lat: position.latitude,
lng: position.longitude
});
}
}
public removeMapCenterMarker(): void {
if (!this.googleMapInstance || !this.googleMapCenterMarker) {
return;
}
this.googleMapCenterMarker.setMap(null);
this.googleMapCenterMarker = null;
}
}
-147
View File
@@ -1,147 +0,0 @@
import { LEAFLET_TILE_SOURCES } from '@/consts/map.ts';
import {
getMapProvider
} from '@/lib/server_settings.ts';
import {
loadLeafletMapAssets,
createLeafletMapHolder,
createLeafletMapInstance,
setLeafletMapCenterTo,
setLeafletMapCenterMaker,
removeLeafletMapCenterMaker
} from './leaflet.js';
import {
getGoogleMapWebsite,
loadGoogleMapAssets,
createGoogleMapHolder,
createGoogleMapInstance,
setGoogleMapCenterTo,
setGoogleMapCenterMaker,
removeGoogleMapCenterMaker
} from './googlemap.js';
import {
getBaiduMapWebsite,
loadBaiduMapAssets,
createBaiduMapHolder,
createBaiduMapInstance,
setBaiduMapCenterTo,
setBaiduMapCenterMaker,
removeBaiduMapCenterMaker
} from './baidumap.js';
import {
getAmapWebsite,
loadAmapAssets,
createAmapHolder,
createAmapInstance,
setAmapCenterTo,
setAmapCenterMaker,
removeAmapCenterMaker
} from './amap.js';
export function getMapWebsite() {
if (getMapProvider() === 'custom') {
return '';
} else if (LEAFLET_TILE_SOURCES[getMapProvider()]) {
return LEAFLET_TILE_SOURCES[getMapProvider()].website;
} else if (getMapProvider() === 'googlemap') {
return getGoogleMapWebsite();
} else if (getMapProvider() === 'baidumap') {
return getBaiduMapWebsite();
} else if (getMapProvider() === 'amap') {
return getAmapWebsite();
}
}
export function loadMapAssets(language) {
if (LEAFLET_TILE_SOURCES[getMapProvider()] || getMapProvider() === 'custom') {
return loadLeafletMapAssets(language);
} else if (getMapProvider() === 'googlemap') {
return loadGoogleMapAssets(language);
} else if (getMapProvider() === 'baidumap') {
return loadBaiduMapAssets(language);
} else if (getMapProvider() === 'amap') {
return loadAmapAssets(language);
}
}
export function createMapHolder() {
if (LEAFLET_TILE_SOURCES[getMapProvider()] || getMapProvider() === 'custom') {
return createLeafletMapHolder(getMapProvider());
} else if (getMapProvider() === 'googlemap') {
return createGoogleMapHolder(getMapProvider());
} else if (getMapProvider() === 'baidumap') {
return createBaiduMapHolder(getMapProvider());
} else if (getMapProvider() === 'amap') {
return createAmapHolder(getMapProvider());
} else {
return null;
}
}
export function initMapInstance(mapHolder, mapContainer, options) {
if (!mapHolder) {
return;
}
if (LEAFLET_TILE_SOURCES[getMapProvider()] || getMapProvider() === 'custom') {
createLeafletMapInstance(mapHolder, mapContainer, options);
} else if (mapHolder.mapProvider === 'googlemap') {
createGoogleMapInstance(mapHolder, mapContainer, options);
} else if (mapHolder.mapProvider === 'baidumap') {
createBaiduMapInstance(mapHolder, mapContainer, options);
} else if (mapHolder.mapProvider === 'amap') {
createAmapInstance(mapHolder, mapContainer, options);
}
}
export function setMapCenterTo(mapHolder, center, zoomLevel) {
if (!mapHolder) {
return;
}
if (LEAFLET_TILE_SOURCES[getMapProvider()] || getMapProvider() === 'custom') {
setLeafletMapCenterTo(mapHolder, center, zoomLevel);
} else if (mapHolder.mapProvider === 'googlemap') {
setGoogleMapCenterTo(mapHolder, center, zoomLevel);
} else if (mapHolder.mapProvider === 'baidumap') {
setBaiduMapCenterTo(mapHolder, center, zoomLevel);
} else if (mapHolder.mapProvider === 'amap') {
setAmapCenterTo(mapHolder, center, zoomLevel);
}
}
export function setMapCenterMarker(mapHolder, position) {
if (!mapHolder) {
return;
}
if (LEAFLET_TILE_SOURCES[getMapProvider()] || getMapProvider() === 'custom') {
setLeafletMapCenterMaker(mapHolder, position);
} else if (mapHolder.mapProvider === 'googlemap') {
setGoogleMapCenterMaker(mapHolder, position);
} else if (mapHolder.mapProvider === 'baidumap') {
setBaiduMapCenterMaker(mapHolder, position);
} else if (mapHolder.mapProvider === 'amap') {
setAmapCenterMaker(mapHolder, position);
}
}
export function removeMapCenterMarker(mapHolder) {
if (!mapHolder) {
return;
}
if (LEAFLET_TILE_SOURCES[getMapProvider()] || getMapProvider() === 'custom') {
removeLeafletMapCenterMaker(mapHolder);
} else if (mapHolder.mapProvider === 'googlemap') {
removeGoogleMapCenterMaker(mapHolder);
} else if (mapHolder.mapProvider === 'baidumap') {
removeBaiduMapCenterMaker(mapHolder);
} else if (mapHolder.mapProvider === 'amap') {
removeAmapCenterMaker(mapHolder);
}
}
+36
View File
@@ -0,0 +1,36 @@
import { LEAFLET_TILE_SOURCES } from '@/consts/map.ts';
import { getMapProvider } from '@/lib/server_settings.ts';
import type { MapProvider, MapInstance } from './base.ts';
import { LeafletMapProvider } from './leaflet.ts';
import { GoogleMapProvider } from './googlemap.ts';
import { BaiduMapProvider } from './baidumap.ts';
import { AmapMapProvider } from './amap.ts';
let mapProvider: MapProvider | null = null;
export function initMapProvider(language: string): void {
const mapProviderType = getMapProvider();
if (LEAFLET_TILE_SOURCES[mapProviderType] || mapProviderType === 'custom') {
mapProvider = new LeafletMapProvider(mapProviderType);
} else if (mapProviderType === 'googlemap') {
mapProvider = new GoogleMapProvider();
} else if (mapProviderType === 'baidumap') {
mapProvider = new BaiduMapProvider();
} else if (mapProviderType === 'amap') {
mapProvider = new AmapMapProvider();
}
if (mapProvider) {
mapProvider.asyncLoadAssets(language);
}
}
export function getMapWebsite(): string {
return mapProvider?.getWebsite() || '';
}
export function createMapInstance(): MapInstance | null {
return mapProvider?.createMapInstance() || null;
}
-199
View File
@@ -1,199 +0,0 @@
import { LEAFLET_TILE_SOURCES } from '@/consts/map.ts';
import {
isMapDataFetchProxyEnabled,
getCustomMapTileLayerUrl,
getCustomMapAnnotationLayerUrl,
isCustomMapAnnotationLayerDataFetchProxyEnabled,
getCustomMapMinZoomLevel,
getCustomMapMaxZoomLevel,
getCustomMapDefaultZoomLevel,
getTomTomMapAPIKey,
getTianDiTuMapAPIKey
} from '@/lib/server_settings.ts';
import services from '@/lib/services.js';
const leafletHolder = {
leaflet: null
};
export function loadLeafletMapAssets() {
return Promise.all([
import('leaflet/dist/leaflet.css'),
import('leaflet/dist/leaflet-src.esm.js').then(leaflet => leafletHolder.leaflet = leaflet)
]);
}
export function createLeafletMapHolder(mapProvider) {
const mapTileSource = LEAFLET_TILE_SOURCES[mapProvider];
if (mapProvider !== 'custom' && !mapTileSource) {
return null;
}
return {
mapProvider: mapProvider,
dependencyLoaded: !!leafletHolder.leaflet,
inited: false,
defaultZoomLevel: mapProvider !== 'custom' ? mapTileSource.defaultZoomLevel : getCustomMapDefaultZoomLevel(),
minZoomLevel: mapProvider !== 'custom' ? mapTileSource.minZoom : getCustomMapMinZoomLevel(),
leafletInstance: null,
leafletTileLayer: null,
leafletAnnotationLayer: null,
leafletZoomControl: null,
leafletAttribution: null,
leafletCenterMarker: null
};
}
export function createLeafletMapInstance(mapHolder, mapContainer, options) {
if (!leafletHolder.leaflet) {
return null;
}
const leaflet = leafletHolder.leaflet;
const leafletInstance = leaflet.map(mapContainer, {
center: [ options.initCenter.latitude, options.initCenter.longitude ],
zoom: options.zoomLevel,
attributionControl: false,
zoomControl: false
});
let mapTileSource = null;
if (mapHolder.mapProvider !== 'custom') {
mapTileSource = Object.assign({}, LEAFLET_TILE_SOURCES[mapHolder.mapProvider]);
} else {
mapTileSource = createCustomMapSource();
}
if (isMapDataFetchProxyEnabled()) {
mapTileSource.tileUrlFormat = services.generateMapProxyTileImageUrl(mapHolder.mapProvider, options.language);
mapTileSource.tileUrlSubDomains = '';
} else if (mapTileSource.tileUrlExtraParams) {
mapTileSource.tileUrlFormat = getFinalUrlFormat(mapTileSource.tileUrlFormat, mapTileSource.tileUrlExtraParams, options);
}
const tileLayer = leaflet.tileLayer(mapTileSource.tileUrlFormat, {
subdomains: mapTileSource.tileUrlSubDomains,
maxZoom: mapTileSource.maxZoom,
minZoom: mapTileSource.minZoom
});
tileLayer.addTo(leafletInstance);
if (mapTileSource.annotationUrlFormat || (mapHolder.mapProvider === 'custom' && isCustomMapAnnotationLayerDataFetchProxyEnabled())) {
if (isMapDataFetchProxyEnabled()) {
mapTileSource.annotationUrlFormat = services.generateMapProxyAnnotationImageUrl(mapHolder.mapProvider, options.language);
mapTileSource.annotationUrlSubDomains = '';
} else if (mapTileSource.annotationUrlExtraParams) {
mapTileSource.annotationUrlFormat = getFinalUrlFormat(mapTileSource.annotationUrlFormat, mapTileSource.annotationUrlExtraParams, options);
}
const annotationLayer = leaflet.tileLayer(mapTileSource.annotationUrlFormat, {
subdomains: mapTileSource.annotationUrlSubDomains,
maxZoom: mapTileSource.maxZoom,
minZoom: mapTileSource.minZoom
});
annotationLayer.addTo(leafletInstance);
mapHolder.leafletAnnotationLayer = annotationLayer;
}
const zoomControl = leaflet.control.zoom({
zoomInTitle: options.text.zoomIn,
zoomOutTitle: options.text.zoomOut
});
zoomControl.addTo(leafletInstance);
if (mapTileSource.attribution) {
const attribution = leaflet.control.attribution({
prefix: false
});
attribution.addAttribution(mapTileSource.attribution);
attribution.addTo(leafletInstance);
mapHolder.leafletAttribution = attribution;
}
mapHolder.leafletInstance = leafletInstance;
mapHolder.leafletTileLayer = tileLayer;
mapHolder.leafletZoomControl = zoomControl;
mapHolder.inited = true;
}
export function setLeafletMapCenterTo(mapHolder, center, zoomLevel) {
if (!mapHolder.leafletInstance) {
return;
}
mapHolder.leafletInstance.setView([ center.latitude, center.longitude ], zoomLevel);
}
export function setLeafletMapCenterMaker(mapHolder, position) {
if (!leafletHolder.leaflet || !mapHolder.leafletInstance) {
return;
}
const leaflet = leafletHolder.leaflet;
if (!mapHolder.leafletCenterMarker) {
const markerIcon = leaflet.icon({
iconUrl: 'img/map-marker-icon.png',
iconRetinaUrl: 'img/map-marker-icon-2x.png',
iconSize: [25, 32],
iconAnchor: [12, 32],
shadowUrl: 'img/map-marker-shadow.png',
shadowSize: [41, 32]
});
mapHolder.leafletCenterMarker = leaflet.marker([ position.latitude, position.longitude ], {
icon: markerIcon
});
mapHolder.leafletCenterMarker.addTo(mapHolder.leafletInstance);
} else {
mapHolder.leafletCenterMarker.setLatLng([ position.latitude, position.longitude ]);
}
}
export function removeLeafletMapCenterMaker(mapHolder) {
if (!mapHolder.leafletInstance || !mapHolder.leafletCenterMarker) {
return;
}
mapHolder.leafletCenterMarker.remove();
mapHolder.leafletCenterMarker = null;
}
function createCustomMapSource() {
return {
tileUrlFormat: getCustomMapTileLayerUrl(),
tileUrlSubDomains: '',
annotationUrlFormat: getCustomMapAnnotationLayerUrl(),
annotationUrlSubDomains: '',
minZoom: getCustomMapMinZoomLevel(),
maxZoom: getCustomMapMaxZoomLevel(),
defaultZoomLevel: getCustomMapDefaultZoomLevel()
};
}
function getFinalUrlFormat(urlFormat, urlExtraParams, options) {
const params = [];
for (let i = 0; i < urlExtraParams.length; i++) {
const param = urlExtraParams[i];
if (param.paramValueType === 'tomtom_key') {
params.push(param.paramName + '=' + getTomTomMapAPIKey());
} else if (param.paramValueType === 'tianditu_key') {
params.push(param.paramName + '=' + getTianDiTuMapAPIKey());
} else if (param.paramValueType === 'language' && options.language) {
params.push(param.paramName + '=' + options.language);
}
}
if (params.length) {
if (urlFormat.indexOf('?') >= 0) {
urlFormat = urlFormat + '&' + params.join('&');
} else {
urlFormat = urlFormat + '?' + params.join('&');
}
}
return urlFormat;
}
+234
View File
@@ -0,0 +1,234 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
import { type LeafletTileSource, type LeafletTileSourceExtraParam, LEAFLET_TILE_SOURCES } from '@/consts/map.ts';
import type { MapProvider, MapInstance, MapInstanceInitOptions, MapPosition } from './base.ts';
import {
isMapDataFetchProxyEnabled,
getCustomMapTileLayerUrl,
getCustomMapAnnotationLayerUrl,
isCustomMapAnnotationLayerDataFetchProxyEnabled,
getCustomMapMinZoomLevel,
getCustomMapMaxZoomLevel,
getCustomMapDefaultZoomLevel,
getTomTomMapAPIKey,
getTianDiTuMapAPIKey
} from '@/lib/server_settings.ts';
import services from '@/lib/services.js';
export class LeafletMapProvider implements MapProvider {
public static Leaflet: unknown = null;
private readonly mapProvider: string;
public constructor(mapProvider: string) {
this.mapProvider = mapProvider;
}
public getWebsite(): string {
if (this.mapProvider === 'custom') {
return '';
} else if (LEAFLET_TILE_SOURCES[this.mapProvider]) {
return LEAFLET_TILE_SOURCES[this.mapProvider].website || '';
} else {
return '';
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public asyncLoadAssets(language: string): Promise<unknown> {
return Promise.all([
import('leaflet/dist/leaflet.css'),
import('leaflet/dist/leaflet-src.esm.js').then(leaflet => LeafletMapProvider.Leaflet = leaflet)
]);
}
public createMapInstance(): MapInstance | null {
const mapTileSource = LEAFLET_TILE_SOURCES[this.mapProvider];
if (this.mapProvider !== 'custom' && !mapTileSource) {
return null;
}
return new LeafletMapInstance(this.mapProvider, mapTileSource);
}
}
export class LeafletMapInstance implements MapInstance {
public dependencyLoaded: boolean = false;
public inited: boolean = false;
public readonly defaultZoomLevel: number;
public readonly minZoomLevel: number;
private readonly mapProvider: string;
private readonly presetMapTileSource: LeafletTileSource;
private leafletInstance: unknown | null;
private leafletTileLayer: unknown | null;
private leafletAnnotationLayer: unknown | null;
private leafletZoomControl: unknown | null;
private leafletAttribution: unknown | null;
private leafletCenterMarker: unknown | null;
constructor(mapProvider: string, mapTileSource: LeafletTileSource) {
this.dependencyLoaded = !!LeafletMapProvider.Leaflet;
this.mapProvider = mapProvider;
this.presetMapTileSource = mapTileSource;
this.defaultZoomLevel = this.presetMapTileSource?.defaultZoomLevel || getCustomMapDefaultZoomLevel();
this.minZoomLevel = this.presetMapTileSource?.minZoom || getCustomMapMinZoomLevel();
}
public initMapInstance(mapContainer: HTMLElement, options: MapInstanceInitOptions): void {
if (!LeafletMapProvider.Leaflet) {
return;
}
const leaflet = LeafletMapProvider.Leaflet;
const leafletInstance = leaflet.map(mapContainer, {
center: [ options.initCenter.latitude, options.initCenter.longitude ],
zoom: options.zoomLevel,
attributionControl: false,
zoomControl: false
});
let tileUrlFormat, tileUrlSubDomains, annotationUrlFormat, annotationUrlSubDomains: string | undefined;
let minZoom, maxZoom: number;
if (this.mapProvider !== 'custom') {
tileUrlFormat = this.presetMapTileSource?.tileUrlFormat;
tileUrlSubDomains = this.presetMapTileSource?.tileUrlSubDomains;
annotationUrlFormat = this.presetMapTileSource?.annotationUrlFormat;
annotationUrlSubDomains = this.presetMapTileSource?.annotationUrlSubDomains;
minZoom = this.presetMapTileSource?.minZoom;
maxZoom = this.presetMapTileSource?.maxZoom;
} else {
tileUrlFormat = getCustomMapTileLayerUrl();
annotationUrlFormat = getCustomMapAnnotationLayerUrl();
minZoom = getCustomMapMinZoomLevel();
maxZoom = getCustomMapMaxZoomLevel();
}
if (isMapDataFetchProxyEnabled()) {
tileUrlFormat = services.generateMapProxyTileImageUrl(this.mapProvider, options.language);
tileUrlSubDomains = '';
} else if (this.presetMapTileSource && this.presetMapTileSource.tileUrlExtraParams) {
tileUrlFormat = this.getFinalUrlFormat(this.presetMapTileSource.tileUrlFormat as string, this.presetMapTileSource.tileUrlExtraParams, options);
}
const tileLayer = leaflet.tileLayer(tileUrlFormat, {
subdomains: tileUrlSubDomains,
maxZoom: maxZoom,
minZoom: minZoom
});
tileLayer.addTo(leafletInstance);
if (annotationUrlFormat || (this.mapProvider === 'custom' && isCustomMapAnnotationLayerDataFetchProxyEnabled())) {
if (isMapDataFetchProxyEnabled()) {
annotationUrlFormat = services.generateMapProxyAnnotationImageUrl(this.mapProvider, options.language);
annotationUrlSubDomains = '';
} else if (this.presetMapTileSource && this.presetMapTileSource.annotationUrlExtraParams) {
annotationUrlFormat = this.getFinalUrlFormat(this.presetMapTileSource.annotationUrlFormat as string, this.presetMapTileSource.annotationUrlExtraParams, options);
}
const annotationLayer = leaflet.tileLayer(annotationUrlFormat, {
subdomains: annotationUrlSubDomains,
maxZoom: maxZoom,
minZoom: minZoom
});
annotationLayer.addTo(leafletInstance);
this.leafletAnnotationLayer = annotationLayer;
}
const zoomControl = leaflet.control.zoom({
zoomInTitle: options.text.zoomIn,
zoomOutTitle: options.text.zoomOut
});
zoomControl.addTo(leafletInstance);
if (this.presetMapTileSource && this.presetMapTileSource.attribution) {
const attribution = leaflet.control.attribution({
prefix: false
});
attribution.addAttribution(this.presetMapTileSource.attribution);
attribution.addTo(leafletInstance);
this.leafletAttribution = attribution;
}
this.leafletInstance = leafletInstance;
this.leafletTileLayer = tileLayer;
this.leafletZoomControl = zoomControl;
this.inited = true;
}
public setMapCenterTo(center: MapPosition, zoomLevel: number): void {
if (!this.leafletInstance) {
return;
}
this.leafletInstance.setView([ center.latitude, center.longitude ], zoomLevel);
}
public setMapCenterMarker(position: MapPosition): void {
if (!LeafletMapProvider.Leaflet || !this.leafletInstance) {
return;
}
const leaflet = LeafletMapProvider.Leaflet;
if (!this.leafletCenterMarker) {
const markerIcon = leaflet.icon({
iconUrl: 'img/map-marker-icon.png',
iconRetinaUrl: 'img/map-marker-icon-2x.png',
iconSize: [25, 32],
iconAnchor: [12, 32],
shadowUrl: 'img/map-marker-shadow.png',
shadowSize: [41, 32]
});
this.leafletCenterMarker = leaflet.marker([ position.latitude, position.longitude ], {
icon: markerIcon
});
this.leafletCenterMarker.addTo(this.leafletInstance);
} else {
this.leafletCenterMarker.setLatLng([ position.latitude, position.longitude ]);
}
}
public removeMapCenterMarker(): void {
if (!this.leafletInstance || !this.leafletCenterMarker) {
return;
}
this.leafletCenterMarker.remove();
this.leafletCenterMarker = null;
}
private getFinalUrlFormat(urlFormat: string, urlExtraParams: LeafletTileSourceExtraParam[], options: MapInstanceInitOptions) {
const params: string[] = [];
for (let i = 0; i < urlExtraParams.length; i++) {
const param = urlExtraParams[i];
if (param.paramValueType === 'tomtom_key') {
params.push(param.paramName + '=' + getTomTomMapAPIKey());
} else if (param.paramValueType === 'tianditu_key') {
params.push(param.paramName + '=' + getTianDiTuMapAPIKey());
} else if (param.paramValueType === 'language' && options.language) {
params.push(param.paramName + '=' + options.language);
}
}
if (params.length) {
if (urlFormat.indexOf('?') >= 0) {
urlFormat = urlFormat + '&' + params.join('&');
} else {
urlFormat = urlFormat + '?' + params.join('&');
}
}
return urlFormat;
}
}
+1 -1
View File
@@ -125,7 +125,7 @@ import { useUserStore } from '@/stores/user.js';
import { useExchangeRatesStore } from '@/stores/exchangeRates.js';
import { getMapProvider } from '@/lib/server_settings.ts';
import { getMapWebsite } from '@/lib/map/index.js';
import { getMapWebsite } from '@/lib/map/index.ts';
import { getLicense, getThirdPartyLicenses } from '@/lib/licenses.ts';
export default {
+1 -1
View File
@@ -63,7 +63,7 @@ import { useUserStore } from '@/stores/user.js';
import { useExchangeRatesStore } from '@/stores/exchangeRates.js';
import { getMapProvider } from '@/lib/server_settings.ts';
import { getMapWebsite } from '@/lib/map/index.js';
import { getMapWebsite } from '@/lib/map/index.ts';
import { getLicense, getThirdPartyLicenses } from '@/lib/licenses.ts';
export default {