support baidu map

This commit is contained in:
MaysWind
2023-06-17 13:40:34 +08:00
parent 530ef6b83e
commit 3bae6e749a
7 changed files with 230 additions and 89 deletions
+5
View File
@@ -13,6 +13,7 @@ import { mapStores } from 'pinia';
import { useTokensStore } from '@/stores/token.js'; import { useTokensStore } from '@/stores/token.js';
import { useExchangeRatesStore } from '@/stores/exchangeRates.js'; import { useExchangeRatesStore } from '@/stores/exchangeRates.js';
import { loadMapAssets } from '@/lib/map.js';
import { isModalShowing, setAppFontSize } from '@/lib/ui.mobile.js'; import { isModalShowing, setAppFontSize } from '@/lib/ui.mobile.js';
export default { export default {
@@ -142,6 +143,10 @@ export default {
this.setThemeColorMeta(isDarkMode); this.setThemeColorMeta(isDarkMode);
}); });
}); });
document.addEventListener('DOMContentLoaded', () => {
loadMapAssets();
});
}, },
methods: { methods: {
isiOSHomeScreenMode() { isiOSHomeScreenMode() {
+64 -81
View File
@@ -8,15 +8,15 @@
<f7-link :text="$t('Done')" @click="save"></f7-link> <f7-link :text="$t('Done')" @click="save"></f7-link>
</div> </div>
</f7-toolbar> </f7-toolbar>
<f7-page-content class="no-margin-vertical no-padding-vertical" v-if="knownMapProvider"> <f7-page-content class="no-margin-vertical no-padding-vertical" v-if="mapHolder && dependencyLoaded">
<div ref="map" style="height: 400px; width: 100%"></div> <div ref="map" style="height: 400px; width: 100%"></div>
</f7-page-content> </f7-page-content>
<f7-page-content class="no-margin-top no-padding-top" v-else-if="!knownMapProvider"> <f7-page-content class="no-margin-top no-padding-top" v-else-if="!mapHolder || !dependencyLoaded">
<div class="display-flex padding justify-content-space-between align-items-center"> <div class="display-flex padding justify-content-space-between align-items-center">
<div class="ebk-sheet-title"><b>{{ $t('Unsupported Map Provider') }}</b></div> <div class="ebk-sheet-title"><b>{{ mapErrorTitle }}</b></div>
</div> </div>
<div class="padding-horizontal padding-bottom"> <div class="padding-horizontal padding-bottom">
<p class="no-margin">{{ $t('Please refresh the page and try again. If the error is still displayed, make sure that server map settings are set correctly.') }}</p> <p class="no-margin">{{ mapErrorContent }}</p>
<div class="margin-top text-align-center"> <div class="margin-top text-align-center">
<f7-link @click="close" :text="$t('Close')"></f7-link> <f7-link @click="close" :text="$t('Close')"></f7-link>
</div> </div>
@@ -26,6 +26,14 @@
</template> </template>
<script> <script>
import {
createMapHolder,
initMapInstance,
setMapCenterTo,
setMapCenterMarker,
removeMapCenterMarker
} from '@/lib/map.js';
export default { export default {
props: [ props: [
'modelValue', 'modelValue',
@@ -36,23 +44,34 @@ export default {
'update:show' 'update:show'
], ],
data() { data() {
let knownMapProvider = false;
if (this.$settings.getMapProvider() === 'openstreetmap') {
knownMapProvider = true;
}
return { return {
knownMapProvider: knownMapProvider, mapHolder: createMapHolder(),
leaflet: null, initCenter: {
tileLayer: null, latitude: 0,
zoomControl: null, longitude: 0,
attribution: null, },
marker: null,
initCenter: [ 0, 0 ],
zoomLevel: 1 zoomLevel: 1
} }
}, },
computed: {
dependencyLoaded() {
return this.mapHolder && this.mapHolder.dependencyLoaded;
},
mapErrorTitle() {
if (!this.mapHolder) {
return this.$t('Unsupported Map Provider');
}
if (!this.dependencyLoaded) {
return this.$t('Cannot Initialize Map');
}
return '';
},
mapErrorContent() {
return this.$t('Please refresh the page and try again. If the error is still displayed, make sure that server map settings are set correctly.');
}
},
methods: { methods: {
save() { save() {
this.$emit('update:show', false); this.$emit('update:show', false);
@@ -61,85 +80,49 @@ export default {
let isFirstInit = false; let isFirstInit = false;
let centerChanged = false; let centerChanged = false;
if (!this.mapHolder || !this.mapHolder.dependencyLoaded) {
return;
}
if (this.modelValue && (this.modelValue.longitude || this.modelValue.latitude)) { if (this.modelValue && (this.modelValue.longitude || this.modelValue.latitude)) {
if (this.initCenter[0] !== this.modelValue.latitude || this.initCenter[1] !== this.modelValue.longitude) { if (this.initCenter.latitude !== this.modelValue.latitude || this.initCenter.longitude !== this.modelValue.longitude) {
this.initCenter[0] = this.modelValue.latitude; this.initCenter.latitude = this.modelValue.latitude;
this.initCenter[1] = this.modelValue.longitude; this.initCenter.longitude = this.modelValue.longitude;
this.zoomLevel = 14; this.zoomLevel = this.mapHolder.defaultZoomLevel;
centerChanged = true; centerChanged = true;
} }
} else if (!this.modelValue || (!this.modelValue.longitude && !this.modelValue.latitude)) { } else if (!this.modelValue || (!this.modelValue.longitude && !this.modelValue.latitude)) {
if (this.initCenter[0] || this.initCenter[1]) { if (this.initCenter.latitude || this.initCenter.longitude) {
this.initCenter[0] = 0; this.initCenter.latitude = 0;
this.initCenter[1] = 0; this.initCenter.longitude = 0;
this.zoomLevel = 1; this.zoomLevel = this.mapHolder.minZoomLevel;
centerChanged = true; centerChanged = true;
} }
} }
if (this.knownMapProvider && this.$settings.getMapProvider() === 'openstreetmap') { if (!this.mapHolder.inited) {
if (!this.leaflet) { initMapInstance(this.mapHolder, this.$refs.map, {
const mapContainer = this.$refs.map; text: {
zoomIn: this.$t('Zoom in'),
this.leaflet = this.$map.leaflet.map(mapContainer, { zoomOut: this.$t('Zoom out'),
attributionControl: false, }
zoomControl: false });
});
const mapTileImageUrl = this.$map.generateOpenStreetMapTileImageUrl();
this.tileLayer = this.$map.leaflet.tileLayer(mapTileImageUrl.url, {
subdomains: mapTileImageUrl.subDomains,
maxZoom: 19
});
this.tileLayer.addTo(this.leaflet);
this.zoomControl = this.$map.leaflet.control.zoom({
zoomInTitle: this.$t('Zoom in'),
zoomOutTitle: this.$t('Zoom out'),
});
this.zoomControl.addTo(this.leaflet);
this.attribution = this.$map.leaflet.control.attribution({
prefix: false
});
this.attribution.addAttribution('&copy; <a href="http://www.openstreetmap.org/copyright" class="external" target="_blank">OpenStreetMap</a>');
this.attribution.addTo(this.leaflet);
if (this.mapHolder.inited) {
isFirstInit = true; isFirstInit = true;
} }
}
if (isFirstInit || centerChanged) { if (isFirstInit || centerChanged) {
this.leaflet.setView(this.initCenter, this.zoomLevel); setMapCenterTo(this.mapHolder, this.initCenter, this.zoomLevel);
} }
if (centerChanged && this.zoomLevel > 1) { if (centerChanged && this.zoomLevel > this.mapHolder.minZoomLevel) {
if (!this.marker) { setMapCenterMarker(this.mapHolder, this.initCenter);
const markerIcon = this.$map.leaflet.icon({ } else if (centerChanged && this.zoomLevel <= this.mapHolder.minZoomLevel) {
iconUrl: 'img/map-marker-icon.png', removeMapCenterMarker(this.mapHolder);
iconRetinaUrl: 'img/map-marker-icon-2x.png',
iconSize: [25, 32],
iconAnchor: [12, 32],
shadowUrl: 'img/map-marker-shadow.png',
shadowSize: [41, 32]
});
this.marker = this.$map.leaflet.marker(this.initCenter, {
icon: markerIcon
});
this.marker.addTo(this.leaflet);
} else {
this.marker.setLatLng(this.initCenter);
}
} else if (centerChanged && this.zoomLevel <= 1) {
if (this.marker) {
this.marker.remove();
this.marker = null;
}
}
} else {
this.knownMapProvider = false;
} }
}, },
onSheetClosed() { onSheetClosed() {
+156
View File
@@ -0,0 +1,156 @@
import services from "./services.js";
import settings from "./settings.js";
const leafletHolder = {
leaflet: null
};
function loadLeafletMapAssets() {
return Promise.all([
import('leaflet/dist/leaflet.css'),
import('leaflet/dist/leaflet-src.esm.js').then(leaflet => leafletHolder.leaflet = leaflet)
]);
}
function createLeafletMapInstance(mapHolder, mapContainer, options) {
if (!leafletHolder.leaflet) {
return null;
}
const leaflet = leafletHolder.leaflet;
const leafletInstance = leaflet.map(mapContainer, {
attributionControl: false,
zoomControl: false
});
const mapTileImageUrl = services.generateOpenStreetMapTileImageUrl();
const tileLayer = leaflet.tileLayer(mapTileImageUrl.url, {
subdomains: mapTileImageUrl.subDomains,
maxZoom: 19
});
tileLayer.addTo(leafletInstance);
const zoomControl = leaflet.control.zoom({
zoomInTitle: options.text.zoomIn,
zoomOutTitle: options.text.zoomOut
});
zoomControl.addTo(leafletInstance);
const attribution = leaflet.control.attribution({
prefix: false
});
attribution.addAttribution('&copy; <a href="http://www.openstreetmap.org/copyright" class="external" target="_blank">OpenStreetMap</a>');
attribution.addTo(leafletInstance);
mapHolder.leafletInstance = leafletInstance;
mapHolder.leafletTileLayer = tileLayer;
mapHolder.leafletZoomControl = zoomControl;
mapHolder.leafletAttribution = attribution;
mapHolder.inited = true;
}
function setLeafletMapCenterTo(mapHolder, center, zoomLevel) {
if (!mapHolder.leafletInstance) {
return;
}
mapHolder.leafletInstance.setView([ center.latitude, center.longitude ], zoomLevel);
}
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 ]);
}
}
function removeLeafletMapCenterMaker(mapHolder) {
if (!mapHolder.leafletInstance || mapHolder.leafletCenterMarker) {
mapHolder.leafletCenterMarker.remove();
mapHolder.leafletCenterMarker = null;
}
}
export function loadMapAssets() {
if (settings.getMapProvider() === 'openstreetmap') {
return loadLeafletMapAssets();
}
}
export function createMapHolder() {
if (settings.getMapProvider() === 'openstreetmap') {
return {
mapProvider: 'openstreetmap',
dependencyLoaded: !!leafletHolder.leaflet,
inited: false,
defaultZoomLevel: 14,
minZoomLevel: 1,
leafletInstance: null,
leafletTileLayer: null,
leafletZoomControl: null,
leafletAttribution: null,
leafletCenterMarker: null
}
} else {
return null;
}
}
export function initMapInstance(mapHolder, mapContainer, options) {
if (!mapHolder) {
return;
}
if (mapHolder.mapProvider === 'openstreetmap') {
createLeafletMapInstance(mapHolder, mapContainer, options);
}
}
export function setMapCenterTo(mapHolder, center, zoomLevel) {
if (!mapHolder) {
return;
}
if (mapHolder.mapProvider === 'openstreetmap') {
setLeafletMapCenterTo(mapHolder, center, zoomLevel);
}
}
export function setMapCenterMarker(mapHolder, position) {
if (!mapHolder) {
return;
}
if (mapHolder.mapProvider === 'openstreetmap') {
setLeafletMapCenterMaker(mapHolder, position);
}
}
export function removeMapCenterMarker(mapHolder) {
if (!mapHolder) {
return;
}
if (mapHolder.mapProvider === 'openstreetmap') {
removeLeafletMapCenterMaker(mapHolder);
}
}
+1
View File
@@ -892,6 +892,7 @@ export default {
'Update Geographic Location': 'Update Geographic Location', 'Update Geographic Location': 'Update Geographic Location',
'Clear Geographic Location': 'Clear Geographic Location', 'Clear Geographic Location': 'Clear Geographic Location',
'Unable to get current position': 'Unable to get current position', 'Unable to get current position': 'Unable to get current position',
'Cannot Initialize Map': 'Cannot Initialize Map',
'Unsupported Map Provider': 'Unsupported Map Provider', 'Unsupported Map Provider': 'Unsupported Map Provider',
'Please refresh the page and try again. If the error is still displayed, make sure that server map settings are set correctly.': 'Please refresh the page and try again. If the error is still displayed, make sure that server map settings are set correctly.', 'Please refresh the page and try again. If the error is still displayed, make sure that server map settings are set correctly.': 'Please refresh the page and try again. If the error is still displayed, make sure that server map settings are set correctly.',
'Tags': 'Tags', 'Tags': 'Tags',
+1
View File
@@ -892,6 +892,7 @@ export default {
'Update Geographic Location': '更新地理位置', 'Update Geographic Location': '更新地理位置',
'Clear Geographic Location': '清除地理位置', 'Clear Geographic Location': '清除地理位置',
'Unable to get current position': '无法获取当前地理位置', 'Unable to get current position': '无法获取当前地理位置',
'Cannot Initialize Map': '无法初始化地图',
'Unsupported Map Provider': '不支持的地图提供方', 'Unsupported Map Provider': '不支持的地图提供方',
'Please refresh the page and try again. If the error is still displayed, make sure that server map settings are set correctly.': '请刷新页面并重试。如果仍然显示错误,请确保正确设置了服务器地图设置。', 'Please refresh the page and try again. If the error is still displayed, make sure that server map settings are set correctly.': '请刷新页面并重试。如果仍然显示错误,请确保正确设置了服务器地图设置。',
'Tags': '标签', 'Tags': '标签',
-7
View File
@@ -75,9 +75,6 @@ import 'line-awesome/dist/line-awesome/css/line-awesome.css';
import VueDatePicker from '@vuepic/vue-datepicker'; import VueDatePicker from '@vuepic/vue-datepicker';
import '@vuepic/vue-datepicker/dist/main.css'; import '@vuepic/vue-datepicker/dist/main.css';
import * as Leaflet from 'leaflet/dist/leaflet-src.esm.js';
import 'leaflet/dist/leaflet.css';
import datetimeConstants from '@/consts/datetime.js'; import datetimeConstants from '@/consts/datetime.js';
import version from '@/lib/version.js'; import version from '@/lib/version.js';
@@ -345,10 +342,6 @@ app.config.globalProperties.$locale = {
getDisplayCurrency: (value, currencyCode, notConvertValue) => getDisplayCurrency(value, currencyCode, notConvertValue, i18n.global.t), getDisplayCurrency: (value, currencyCode, notConvertValue) => getDisplayCurrency(value, currencyCode, notConvertValue, i18n.global.t),
initLocale: initLocale initLocale: initLocale
}; };
app.config.globalProperties.$map = {
leaflet: Leaflet,
generateOpenStreetMapTileImageUrl: services.generateOpenStreetMapTileImageUrl
};
app.config.globalProperties.$tIf = (text, isTranslate) => transateIf(text, isTranslate, i18n.global.t); app.config.globalProperties.$tIf = (text, isTranslate) => transateIf(text, isTranslate, i18n.global.t);
app.config.globalProperties.$alert = (message, confirmCallback) => showAlert(message, confirmCallback, i18n.global.t); app.config.globalProperties.$alert = (message, confirmCallback) => showAlert(message, confirmCallback, i18n.global.t);
+3 -1
View File
@@ -108,7 +108,9 @@ export default defineConfig(async () => {
chunkFileNames: 'js/[name]-[hash].js', chunkFileNames: 'js/[name]-[hash].js',
entryFileNames: 'js/[name]-[hash].js', entryFileNames: 'js/[name]-[hash].js',
manualChunks: function (id) { manualChunks: function (id) {
if (/[\\/]node_modules[\\/]/i.test(id)) { if (/[\\/]node_modules[\\/]leaflet[\\/]/i.test(id)) {
return 'leaflet';
} else if (/[\\/]node_modules[\\/]/i.test(id)) {
return 'vendor'; return 'vendor';
} }
} }