diff --git a/conf/ezbookkeeping.ini b/conf/ezbookkeeping.ini index d60f4867..4ca5612e 100644 --- a/conf/ezbookkeeping.ini +++ b/conf/ezbookkeeping.ini @@ -111,12 +111,15 @@ enable_register = true enable_export = true [map] -# Map provider, supports "openstreetmap", "baidumap". Leave blank if you want to disable map +# Map provider, supports "openstreetmap", "googlemap", "baidumap" Leave blank if you want to disable map map_provider = openstreetmap # Set to true to use the ezbookkeeping server to proxy map data requests, for "openstreetmap" map_data_fetch_proxy = false +# For "googlemap" only, Google map API key, please visit https://developers.google.com/maps/get-started for more information +google_map_api_key = + # For "baidumap" only, Baidu map javascript api application key, please visit https://lbsyun.baidu.com/index.php?title=jspopular3.0/guide/getkey for more information baidu_map_ak = diff --git a/pkg/middlewares/server_settings_cookie.go b/pkg/middlewares/server_settings_cookie.go index 362c8ea1..2f4a430d 100644 --- a/pkg/middlewares/server_settings_cookie.go +++ b/pkg/middlewares/server_settings_cookie.go @@ -23,6 +23,10 @@ func ServerSettingsCookie(config *settings.Config) core.MiddlewareHandlerFunc { settingsArr = append(settingsArr, buildBooleanSetting("mp", config.EnableMapDataFetchProxy)) } + if config.GoogleMapAPIKey != "" { + settingsArr = append(settingsArr, buildStringSetting("gmak", config.GoogleMapAPIKey)) + } + if config.BaiduMapAK != "" { settingsArr = append(settingsArr, buildStringSetting("bmak", config.BaiduMapAK)) } diff --git a/pkg/settings/setting.go b/pkg/settings/setting.go index e1bd87a2..2b20a8b6 100644 --- a/pkg/settings/setting.go +++ b/pkg/settings/setting.go @@ -65,6 +65,7 @@ const ( // Map provider types const ( OpenStreetMapProvider string = "openstreetmap" + GoogleMapProvider string = "googlemap" BaiduMapProvider string = "baidumap" ) @@ -177,6 +178,7 @@ type Config struct { // Map MapProvider string + GoogleMapAPIKey string BaiduMapAK string EnableMapDataFetchProxy bool @@ -438,6 +440,8 @@ func loadMapConfiguration(config *Config, configFile *ini.File, sectionName stri config.MapProvider = "" } else if getConfigItemStringValue(configFile, sectionName, "map_provider") == OpenStreetMapProvider { config.MapProvider = OpenStreetMapProvider + } else if getConfigItemStringValue(configFile, sectionName, "map_provider") == GoogleMapProvider { + config.MapProvider = GoogleMapProvider } else if getConfigItemStringValue(configFile, sectionName, "map_provider") == BaiduMapProvider { config.MapProvider = BaiduMapProvider } else { @@ -445,6 +449,7 @@ func loadMapConfiguration(config *Config, configFile *ini.File, sectionName stri } config.EnableMapDataFetchProxy = getConfigItemBoolValue(configFile, sectionName, "map_data_fetch_proxy", false) + config.GoogleMapAPIKey = getConfigItemStringValue(configFile, sectionName, "google_map_api_key") config.BaiduMapAK = getConfigItemStringValue(configFile, sectionName, "baidu_map_ak") return nil diff --git a/src/MobileApp.vue b/src/MobileApp.vue index a4d34bdb..a153b41d 100644 --- a/src/MobileApp.vue +++ b/src/MobileApp.vue @@ -145,7 +145,8 @@ export default { }); document.addEventListener('DOMContentLoaded', () => { - loadMapAssets(); + const languageInfo = this.$locale.getCurrentLanguageInfo(); + loadMapAssets(languageInfo ? languageInfo.code : null); }); }, methods: { diff --git a/src/components/mobile/MapSheet.vue b/src/components/mobile/MapSheet.vue index 94be5ba8..b598a7fe 100644 --- a/src/components/mobile/MapSheet.vue +++ b/src/components/mobile/MapSheet.vue @@ -8,10 +8,10 @@ - +
- +
{{ mapErrorTitle }}
@@ -44,8 +44,12 @@ export default { 'update:show' ], data() { + this.mapHolder = createMapHolder(); + return { - mapHolder: createMapHolder(), + mapSupported: !!this.mapHolder, + mapDependencyLoaded: this.mapHolder.dependencyLoaded, + mapInited: false, initCenter: { latitude: 0, longitude: 0, @@ -54,15 +58,12 @@ export default { } }, computed: { - dependencyLoaded() { - return this.mapHolder && this.mapHolder.dependencyLoaded; - }, mapErrorTitle() { - if (!this.mapHolder) { + if (!this.mapSupported) { return this.$t('Unsupported Map Provider'); } - if (!this.dependencyLoaded) { + if (!this.mapDependencyLoaded) { return this.$t('Cannot Initialize Map'); } @@ -80,7 +81,7 @@ export default { let isFirstInit = false; let centerChanged = false; - if (!this.mapHolder || !this.mapHolder.dependencyLoaded) { + if (!this.mapSupported || !this.mapDependencyLoaded) { return; } @@ -104,6 +105,8 @@ export default { if (!this.mapHolder.inited) { initMapInstance(this.mapHolder, this.$refs.map, { + initCenter: this.initCenter, + zoomLevel: this.zoomLevel, text: { zoomIn: this.$t('Zoom in'), zoomOut: this.$t('Zoom out'), diff --git a/src/consts/api.js b/src/consts/api.js index 93e0039b..78a59358 100644 --- a/src/consts/api.js +++ b/src/consts/api.js @@ -1,9 +1,11 @@ const baseApiUrlPath = '/api'; const baseProxyUrlPath = '/proxy'; +const googleMapJavascriptUrl = 'https://maps.googleapis.com/maps/api/js'; const baiduMapJavascriptUrl = 'https://api.map.baidu.com/api?v=3.0'; export default { baseApiUrlPath: baseApiUrlPath, baseProxyUrlPath: baseProxyUrlPath, + googleMapJavascriptUrl: googleMapJavascriptUrl, baiduMapJavascriptUrl: baiduMapJavascriptUrl } diff --git a/src/lib/map/googlemap.js b/src/lib/map/googlemap.js new file mode 100644 index 00000000..dd118623 --- /dev/null +++ b/src/lib/map/googlemap.js @@ -0,0 +1,109 @@ +import { asyncLoadAssets } from "@/lib/misc.js"; +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 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; +} diff --git a/src/lib/map/index.js b/src/lib/map/index.js index d04ff5f5..242645de 100644 --- a/src/lib/map/index.js +++ b/src/lib/map/index.js @@ -9,6 +9,15 @@ import { removeLeafletMapCenterMaker } from './openstreetmap.js'; +import { + loadGoogleMapAssets, + createGoogleMapHolder, + createGoogleMapInstance, + setGoogleMapCenterTo, + setGoogleMapCenterMaker, + removeGoogleMapCenterMaker +} from './googlemap.js'; + import { loadBaiduMapAssets, createBaiduMapHolder, @@ -18,17 +27,21 @@ import { removeBaiduMapCenterMaker } from './baidumap.js'; -export function loadMapAssets() { +export function loadMapAssets(language) { if (settings.getMapProvider() === 'openstreetmap') { - return loadLeafletMapAssets(); + return loadLeafletMapAssets(language); + } else if (settings.getMapProvider() === 'googlemap') { + return loadGoogleMapAssets(language); } else if (settings.getMapProvider() === 'baidumap') { - return loadBaiduMapAssets(); + return loadBaiduMapAssets(language); } } export function createMapHolder() { if (settings.getMapProvider() === 'openstreetmap') { return createLeafletMapHolder(); + } else if (settings.getMapProvider() === 'googlemap') { + return createGoogleMapHolder(); } else if (settings.getMapProvider() === 'baidumap') { return createBaiduMapHolder(); } else { @@ -43,6 +56,8 @@ export function initMapInstance(mapHolder, mapContainer, options) { if (mapHolder.mapProvider === 'openstreetmap') { createLeafletMapInstance(mapHolder, mapContainer, options); + } else if (mapHolder.mapProvider === 'googlemap') { + createGoogleMapInstance(mapHolder, mapContainer, options); } else if (mapHolder.mapProvider === 'baidumap') { createBaiduMapInstance(mapHolder, mapContainer, options); } @@ -55,6 +70,8 @@ export function setMapCenterTo(mapHolder, center, zoomLevel) { if (mapHolder.mapProvider === 'openstreetmap') { setLeafletMapCenterTo(mapHolder, center, zoomLevel); + } else if (mapHolder.mapProvider === 'googlemap') { + setGoogleMapCenterTo(mapHolder, center, zoomLevel); } else if (mapHolder.mapProvider === 'baidumap') { setBaiduMapCenterTo(mapHolder, center, zoomLevel); } @@ -67,6 +84,8 @@ export function setMapCenterMarker(mapHolder, position) { if (mapHolder.mapProvider === 'openstreetmap') { setLeafletMapCenterMaker(mapHolder, position); + } else if (mapHolder.mapProvider === 'googlemap') { + setGoogleMapCenterMaker(mapHolder, position); } else if (mapHolder.mapProvider === 'baidumap') { setBaiduMapCenterMaker(mapHolder, position); } @@ -79,6 +98,8 @@ export function removeMapCenterMarker(mapHolder) { if (mapHolder.mapProvider === 'openstreetmap') { removeLeafletMapCenterMaker(mapHolder); + } else if (mapHolder.mapProvider === 'googlemap') { + removeGoogleMapCenterMaker(mapHolder); } else if (mapHolder.mapProvider === 'baidumap') { removeBaiduMapCenterMaker(mapHolder); } diff --git a/src/lib/services.js b/src/lib/services.js index 467e8eca..10f705b4 100644 --- a/src/lib/services.js +++ b/src/lib/services.js @@ -411,6 +411,13 @@ export default { }; } }, + generateGoogleMapJavascriptUrl: (language, callbackFnName) => { + if (language) { + return `${api.googleMapJavascriptUrl}?key=${settings.getGoogleMapAPIKey()}&language=${language}&callback=${callbackFnName}`; + } else { + return `${api.googleMapJavascriptUrl}?key=${settings.getGoogleMapAPIKey()}&callback=${callbackFnName}`; + } + }, generateBaiduMapJavascriptUrl: (callbackFnName) => { return `${api.baiduMapJavascriptUrl}&ak=${settings.getBaiduMapAK()}&callback=${callbackFnName}`; } diff --git a/src/lib/settings.js b/src/lib/settings.js index 917ea3ab..c771a81c 100644 --- a/src/lib/settings.js +++ b/src/lib/settings.js @@ -169,6 +169,7 @@ export default { isDataExportingEnabled: () => getServerSetting('e') === '1', getMapProvider: () => getServerSetting('m'), isMapDataFetchProxyEnabled: () => getServerSetting('mp') === '1', + getGoogleMapAPIKey: () => getServerSetting('gmak'), getBaiduMapAK: () => getServerSetting('bmak'), clearSettings: clearSettings };