Manage map initialization sequence better + Fix map/project radio buttons
This commit is contained in:
@@ -72,9 +72,9 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
baseMap(sNewBaseMap, sOldBaseMap) {
|
||||
if(this.map.isStyleLoaded()) {
|
||||
if(sOldBaseMap) this.map.setLayoutProperty(sOldBaseMap, 'visibility', 'none');
|
||||
if(sNewBaseMap) this.map.setLayoutProperty(sNewBaseMap, 'visibility', 'visible');
|
||||
if(this.map?.isStyleLoaded()) {
|
||||
if(sOldBaseMap && this.map.getLayer(sOldBaseMap)) this.map.setLayoutProperty(sOldBaseMap, 'visibility', 'none');
|
||||
if(sNewBaseMap && this.map.getLayer(sNewBaseMap)) this.map.setLayoutProperty(sNewBaseMap, 'visibility', 'visible');
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -190,45 +190,25 @@ export default {
|
||||
const oMarkersPromise = this.spot.get2('markers', {id_project: this.currProject.id});
|
||||
const oTrackPromise = this.spot.get2('geojson', {id_project: this.currProject.id});
|
||||
|
||||
//Get Map Info
|
||||
const aoMarkers = await oMarkersPromise;
|
||||
this.baseMap = null;
|
||||
this.baseMaps = aoMarkers.maps;
|
||||
this.markers.messages = aoMarkers.messages;
|
||||
this.markers.medias = aoMarkers.medias;
|
||||
this.lastUpdate = aoMarkers.last_update;
|
||||
|
||||
//Base maps (raster tiles)
|
||||
let asSources = {};
|
||||
let asLayers = [];
|
||||
for(const asBaseMap of this.baseMaps) {
|
||||
asSources[asBaseMap.codename] = {
|
||||
type: 'raster',
|
||||
tiles: [asBaseMap.pattern],
|
||||
tileSize: asBaseMap.tile_size
|
||||
};
|
||||
asLayers.push({
|
||||
id: asBaseMap.codename,
|
||||
type: 'raster',
|
||||
source: asBaseMap.codename,
|
||||
'layout': {'visibility': 'none'},
|
||||
minZoom: asBaseMap.min_zoom,
|
||||
maxZoom: asBaseMap.max_zoom
|
||||
});
|
||||
}
|
||||
|
||||
//Map
|
||||
//Build Map
|
||||
if(this.map) this.map.remove();
|
||||
this.map = new Map({
|
||||
container: 'map',
|
||||
style: {
|
||||
version: 8,
|
||||
sources: asSources,
|
||||
layers: asLayers
|
||||
sources: {},
|
||||
layers: []
|
||||
},
|
||||
attributionControl: false
|
||||
});
|
||||
const oMarkerImagePromise = this.map.loadImage('images/footprint_mapbox.png');
|
||||
|
||||
//Parse Map Info
|
||||
const aoMarkers = await oMarkersPromise;
|
||||
this.baseMaps = aoMarkers.maps;
|
||||
this.baseMap = this.baseMaps.find((asBM) => asBM.default_map)?.codename ?? null;
|
||||
this.markers.messages = aoMarkers.messages;
|
||||
this.markers.medias = aoMarkers.medias;
|
||||
this.lastUpdate = aoMarkers.last_update;
|
||||
|
||||
//Force wait for load event
|
||||
await new Promise((resolve) => {
|
||||
@@ -236,11 +216,39 @@ export default {
|
||||
else this.map.once('load', resolve);
|
||||
});
|
||||
|
||||
//Default Basemap
|
||||
this.baseMap = this.baseMaps.filter((asBM) => asBM.default_map)[0].codename;
|
||||
//Base maps (raster tiles)
|
||||
for(const asBaseMap of this.baseMaps) {
|
||||
this.map.addSource(asBaseMap.codename, {
|
||||
type: 'raster',
|
||||
tiles: [asBaseMap.pattern],
|
||||
tileSize: asBaseMap.tile_size
|
||||
});
|
||||
this.map.addLayer({
|
||||
id: asBaseMap.codename,
|
||||
type: 'raster',
|
||||
source: asBaseMap.codename,
|
||||
'layout': {'visibility': asBaseMap.codename == this.baseMap ? 'visible' : 'none'},
|
||||
minZoom: asBaseMap.min_zoom,
|
||||
maxZoom: asBaseMap.max_zoom
|
||||
});
|
||||
}
|
||||
|
||||
//Get track
|
||||
//Add track
|
||||
const oTrack = await oTrackPromise;
|
||||
this.addTrack(oTrack);
|
||||
|
||||
//Centering map
|
||||
await this.positionMap(oTrack);
|
||||
|
||||
//Add Markers
|
||||
this.addMarkers();
|
||||
|
||||
//Force wait for idle event
|
||||
await new Promise((resolve) => {
|
||||
this.map.once('idle', resolve);
|
||||
});
|
||||
},
|
||||
addTrack(oTrack) {
|
||||
this.map.addSource('track', {
|
||||
'type': 'geojson',
|
||||
'data': oTrack
|
||||
@@ -248,9 +256,9 @@ export default {
|
||||
|
||||
//Color mapping
|
||||
let asColorMapping = ['match', ['get', 'type']];
|
||||
for(const sHikeType in this.hikes.colors) {
|
||||
for(const [sHikeType, sColor] of Object.entries(this.hikes.colors)) {
|
||||
asColorMapping.push(sHikeType);
|
||||
asColorMapping.push(this.hikes.colors[sHikeType]);
|
||||
asColorMapping.push(sColor);
|
||||
}
|
||||
asColorMapping.push('black'); //fallback value
|
||||
|
||||
@@ -268,9 +276,9 @@ export default {
|
||||
'line-width': this.hikes.width
|
||||
}
|
||||
});
|
||||
|
||||
//Markers
|
||||
this.map.addImage('markerIcon', (await oMarkerImagePromise).data);
|
||||
},
|
||||
async addMarkers() {
|
||||
this.map.addImage('markerIcon', (await this.map.loadImage('images/footprint_mapbox.png')).data);
|
||||
this.map.addSource('markers', {
|
||||
type:'geojson',
|
||||
data: {
|
||||
@@ -305,7 +313,7 @@ export default {
|
||||
//TODO Use same way of displaying markers (so that openMarkerPopup works on all markers)
|
||||
this.markers.medias.forEach(msg => {
|
||||
const $Marker = document.createElement('div');
|
||||
const app = createApp(SpotIconStack, {iconMain: 'message', iconSub:'image'});
|
||||
const app = createApp(SpotIconStack, {iconMain: 'media', iconSub: msg.subtype+'-in'});
|
||||
app.mount($Marker);
|
||||
|
||||
const $Popup = document.createElement('div');
|
||||
@@ -332,21 +340,22 @@ export default {
|
||||
.setPopup(popupElement)
|
||||
.addTo(this.map);
|
||||
});
|
||||
|
||||
//Centering map
|
||||
},
|
||||
async positionMap(oTrack) {
|
||||
let bOpenFeedPanel = !this.mobile;
|
||||
let oBounds = new LngLatBounds();
|
||||
if(
|
||||
|
||||
if( //Blog Mode: Fit to last message
|
||||
this.currProject.mode == this.spot.consts.modes.blog &&
|
||||
this.markers.messages.length > 0 &&
|
||||
this.$parent.hash.items[2] != 'message'
|
||||
) {
|
||||
//Fit to last message
|
||||
|
||||
let oLastMsg = this.markers.messages[this.markers.messages.length - 1];
|
||||
oBounds.extend(new LngLat(oLastMsg.longitude, oLastMsg.latitude));
|
||||
}
|
||||
else {
|
||||
//Fit to track
|
||||
else { //Pre/Histo Mode: Fit to track
|
||||
|
||||
for(const iFeatureId in oTrack.features) {
|
||||
oBounds = oTrack.features[iFeatureId].geometry.coordinates.reduce(
|
||||
(bounds, coord) => {
|
||||
@@ -356,6 +365,7 @@ export default {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const iFeedPanelPadding = bOpenFeedPanel?(getOuterWidth(this.$refs.feed)/2):0;
|
||||
await this.map.fitBounds(
|
||||
oBounds,
|
||||
@@ -373,11 +383,6 @@ export default {
|
||||
|
||||
//Toggle only when map is ready, for the tilt effet
|
||||
this.toggleFeedPanel(bOpenFeedPanel);
|
||||
|
||||
//Force wait for idle event
|
||||
await new Promise((resolve) => {
|
||||
this.map.once('idle', resolve);
|
||||
});
|
||||
},
|
||||
convertMsgToFeatures(oMsg) {
|
||||
return oMsg.map(oMsg => ({
|
||||
@@ -640,9 +645,9 @@ export default {
|
||||
<div class="settings-section">
|
||||
<h1><SpotIcon :icon="'project'" :classes="'fa-fw'" :text="spot.lang('hikes')" /></h1>
|
||||
<div class="settings-section-body">
|
||||
<div class="radio" v-for="project in projects">
|
||||
<input type="radio" :id="project.id" :value="project.codename" v-model="$parent.hash.items[0]" />
|
||||
<label :for="project.id">
|
||||
<div class="radio" v-for="project in projects" :key="'project-'+project.id">
|
||||
<input type="radio" :id="'project-'+project.id" :value="project.codename" v-model="$parent.hash.items[0]" />
|
||||
<label :for="'project-'+project.id">
|
||||
<span>{{ project.name }}</span>
|
||||
<a class="download" :href="project.gpxfilepath" :title="spot.lang('track_download')" @click.stop="()=>{}">
|
||||
<SpotIcon :icon="'download'" :classes="'push-left'" />
|
||||
@@ -654,9 +659,9 @@ export default {
|
||||
<div class="settings-section">
|
||||
<h1><SpotIcon :icon="'map'" :classes="'fa-fw'" :text="spot.lang('maps')" /></h1>
|
||||
<div class="settings-section-body">
|
||||
<div class="radio" v-for="bm in baseMaps">
|
||||
<input type="radio" :id="bm.id_map" :value="bm.codename" v-model="baseMap" />
|
||||
<label :for="bm.id_map">{{ this.spot.lang('map_'+bm.codename) }}</label>
|
||||
<div class="radio" v-for="bm in baseMaps" :key="'map-'+bm.id_map">
|
||||
<input type="radio" :id="'map-'+bm.id_map" :value="bm.codename" v-model="baseMap" />
|
||||
<label :for="'map-'+bm.id_map">{{ this.spot.lang('map_'+bm.codename) }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user