|
|
|
@ -122,6 +122,8 @@ const LEAFLET_DEFAULT_CENTER = [31.2304, 121.4737]; |
|
|
|
const AMAP_FALLBACK_MAX_ZOOM = 20; |
|
|
|
const GOOGLE_DETAIL_ZOOM = 21; |
|
|
|
const LEAFLET_MAX_ZOOM = 22; |
|
|
|
const LEAFLET_GOOGLE_MAX_ZOOM = 20; |
|
|
|
const LEAFLET_GOOGLE_TILE_URL = "https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}"; |
|
|
|
const LEAFLET_LINE_ARROW_MAX = 36; |
|
|
|
const LEAFLET_SHOW_LINE_ARROWS = false; |
|
|
|
const LEAFLET_TRAJECTORY_LINE_COLOR = "#1a73e8"; |
|
|
|
@ -179,7 +181,7 @@ export default { |
|
|
|
return !!(this.mapConfig && this.mapConfig.gaodeKey); |
|
|
|
}, |
|
|
|
hasGoogleKey() { |
|
|
|
return !!(this.mapConfig && this.mapConfig.googleKey); |
|
|
|
return true; |
|
|
|
}, |
|
|
|
hasMaptilerKey() { |
|
|
|
return !!(this.mapConfig && this.mapConfig.maptilerKey); |
|
|
|
@ -286,14 +288,10 @@ export default { |
|
|
|
try { |
|
|
|
const response = await getDeviceTrajectoryMapConfig(); |
|
|
|
const data = response && response.data ? response.data : {}; |
|
|
|
if (!data.gaodeKey && !data.googleKey && !data.maptilerKey) { |
|
|
|
this.loadError = this.$t("device.trajectory.message.missingMapKey"); |
|
|
|
return; |
|
|
|
} |
|
|
|
this.mapConfig = data; |
|
|
|
} catch (error) { |
|
|
|
this.mapConfig = null; |
|
|
|
this.loadError = error && error.message ? error.message : this.$t("device.trajectory.message.mapConfigLoadFailed"); |
|
|
|
// Google tiles mode does not depend on map config, keep dialog usable. |
|
|
|
this.mapConfig = {}; |
|
|
|
} |
|
|
|
}, |
|
|
|
async fetchTrajectory() { |
|
|
|
@ -340,9 +338,9 @@ export default { |
|
|
|
return; |
|
|
|
} |
|
|
|
if (this.mapProvider === "google") { |
|
|
|
await this.ensureGoogleMap(); |
|
|
|
await this.ensureLeafletGoogleMap(); |
|
|
|
if (!this.loadError) { |
|
|
|
this.renderGoogleTrajectory(); |
|
|
|
this.renderLeafletTrajectory(); |
|
|
|
} |
|
|
|
return; |
|
|
|
} |
|
|
|
@ -386,6 +384,21 @@ export default { |
|
|
|
this.mapVendor = "leaflet"; |
|
|
|
} else { |
|
|
|
this.mapsApi = mapsApi; |
|
|
|
if (this.tileLayer && typeof this.map.removeLayer === "function") { |
|
|
|
this.map.removeLayer(this.tileLayer); |
|
|
|
} |
|
|
|
this.tileLayer = mapsApi.tileLayer( |
|
|
|
"https://api.maptiler.com/maps/streets/{z}/{x}/{y}{r}.png?key=" + |
|
|
|
encodeURIComponent(this.mapConfig.maptilerKey), |
|
|
|
{ |
|
|
|
attribution: |
|
|
|
'© <a href="https://www.maptiler.com/copyright/" target="_blank">MapTiler</a> © <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>', |
|
|
|
maxZoom: LEAFLET_MAX_ZOOM, |
|
|
|
maxNativeZoom: LEAFLET_MAX_ZOOM, |
|
|
|
detectRetina: true, |
|
|
|
} |
|
|
|
); |
|
|
|
this.tileLayer.addTo(this.map); |
|
|
|
if (typeof this.map.invalidateSize === "function") { |
|
|
|
this.map.invalidateSize(); |
|
|
|
} |
|
|
|
@ -396,6 +409,46 @@ export default { |
|
|
|
this.mapLoading = false; |
|
|
|
} |
|
|
|
}, |
|
|
|
async ensureLeafletGoogleMap() { |
|
|
|
this.mapLoading = true; |
|
|
|
try { |
|
|
|
const mapsApi = await loadLeaflet(); |
|
|
|
if (!this.$refs.map) { |
|
|
|
return; |
|
|
|
} |
|
|
|
if (!this.map || this.mapVendor !== "leaflet") { |
|
|
|
this.destroyMap(); |
|
|
|
this.mapsApi = mapsApi; |
|
|
|
this.map = mapsApi.map(this.$refs.map, { |
|
|
|
center: LEAFLET_DEFAULT_CENTER, |
|
|
|
zoom: LEAFLET_GOOGLE_MAX_ZOOM, |
|
|
|
zoomControl: true, |
|
|
|
}); |
|
|
|
this.tileLayer = mapsApi.tileLayer(LEAFLET_GOOGLE_TILE_URL, { |
|
|
|
maxZoom: LEAFLET_GOOGLE_MAX_ZOOM, |
|
|
|
}); |
|
|
|
this.tileLayer.addTo(this.map); |
|
|
|
this.mapVendor = "leaflet"; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
this.mapsApi = mapsApi; |
|
|
|
if (this.tileLayer && typeof this.map.removeLayer === "function") { |
|
|
|
this.map.removeLayer(this.tileLayer); |
|
|
|
} |
|
|
|
this.tileLayer = mapsApi.tileLayer(LEAFLET_GOOGLE_TILE_URL, { |
|
|
|
maxZoom: LEAFLET_GOOGLE_MAX_ZOOM, |
|
|
|
}); |
|
|
|
this.tileLayer.addTo(this.map); |
|
|
|
if (typeof this.map.invalidateSize === "function") { |
|
|
|
this.map.invalidateSize(); |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
this.loadError = error && error.message ? error.message : this.$t("device.trajectory.message.googleLoadFailed"); |
|
|
|
} finally { |
|
|
|
this.mapLoading = false; |
|
|
|
} |
|
|
|
}, |
|
|
|
renderLeafletTrajectory() { |
|
|
|
if (!this.map || !this.mapsApi || !this.trajectoryPoints.length) { |
|
|
|
return; |
|
|
|
|