mirror of
				https://bitbucket.org/s_l_teichmann/mtsatellite
				synced 2025-10-30 23:55:38 +01:00 
			
		
		
		
	Layers for POI in web client and list of players.
This commit is contained in:
		| @@ -15,6 +15,56 @@ | ||||
|             <v-list-item-title>Players</v-list-item-title> | ||||
|           </v-list-item-content> | ||||
|         </v-list-item> | ||||
|         <v-list-item> | ||||
|           <v-list-item-action> | ||||
|             <v-checkbox v-model="buildingsLayer"></v-checkbox> | ||||
|           </v-list-item-action> | ||||
|           <v-list-item-content> | ||||
|             <v-list-item-title> | ||||
|               Buildings</v-list-item-title> | ||||
|           </v-list-item-content> | ||||
|         </v-list-item> | ||||
|         <v-list-item> | ||||
|           <v-list-item-action> | ||||
|             <v-checkbox v-model="poiLayer"></v-checkbox> | ||||
|           </v-list-item-action> | ||||
|           <v-list-item-content> | ||||
|             <v-list-item-title>Points of Interest</v-list-item-title> | ||||
|           </v-list-item-content> | ||||
|         </v-list-item> | ||||
|         <v-list-item> | ||||
|           <v-list-item-action> | ||||
|             <v-checkbox v-model="travelnetLayer"></v-checkbox> | ||||
|           </v-list-item-action> | ||||
|           <v-list-item-content> | ||||
|             <v-list-item-title>Travelnet</v-list-item-title> | ||||
|           </v-list-item-content> | ||||
|         </v-list-item> | ||||
|         <v-list-item> | ||||
|           <v-list-item-action> | ||||
|             <v-checkbox v-model="otherLayer"></v-checkbox> | ||||
|           </v-list-item-action> | ||||
|           <v-list-item-content> | ||||
|             <v-list-item-title>Other</v-list-item-title> | ||||
|           </v-list-item-content> | ||||
|         </v-list-item> | ||||
|         <v-divider></v-divider> | ||||
|         <v-list-item> | ||||
|           <v-list-item-content> | ||||
|             <v-list-item-title style="font-weight:bold;">Players</v-list-item-title> | ||||
|           </v-list-item-content> | ||||
|         </v-list-item> | ||||
|         <v-list-item | ||||
|           v-for="(item, i) in players" | ||||
|           :key="i" | ||||
|         > | ||||
|           <v-list-item-content> | ||||
|             <v-list-item-title v-text="item.properties.name" /> | ||||
|           </v-list-item-content> | ||||
|           <v-list-item-action v-if="playersLayer"> | ||||
|             <v-icon @click.stop="goToPlayer(item)">fa-crosshairs</v-icon> | ||||
|           </v-list-item-action> | ||||
|         </v-list-item> | ||||
|       </v-list> | ||||
|     </v-navigation-drawer> | ||||
|     <v-app-bar :clipped-left="true" fixed app> | ||||
| @@ -120,11 +170,19 @@ export default { | ||||
|   mounted() { | ||||
|     fetch("players").then(response => response.json().then((data) => { | ||||
|       this.$store.commit("setPlayers", data); | ||||
|     })) | ||||
|     })); | ||||
|     fetch("poi").then(response => response.json().then((data) => { | ||||
|       this.$store.commit("setPointFeatures", data); | ||||
|     })); | ||||
|   }, | ||||
|   methods: { | ||||
|     refreshContent() { | ||||
|       this.$store.dispatch("manualUpdate"); | ||||
|     }, | ||||
|     goToPlayer(player) { | ||||
|       console.log(player); | ||||
|       const coords = [player.geometry.coordinates[1], player.geometry.coordinates[0]]; | ||||
|       this.$store.commit("setMapCenter", coords) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,27 @@ | ||||
| <template> | ||||
|   <v-container fluid style="height: 100%; padding: 0px"> | ||||
|     <l-map @mousemove="update" ref="map" style="height: 100%" :zoom="zoom" :center="center" :worldCopyJump="worldCopyJump" :crs="crs" :options="mapOptions"> | ||||
|     <l-map @mousemove="update" ref="map" style="height: 100%" :zoom="zoom" :center="mapCenter" :worldCopyJump="worldCopyJump" :crs="crs" :options="mapOptions"> | ||||
|       <l-tile-layer ref="baseLayer" :url="url" :attribution="attribution" :tms="tms" continuousWorld="false" minZoom=0 :noWrap="noWrap" :options="layerOptions"></l-tile-layer> | ||||
|       <l-marker-cluster v-if="buildingsLayer" :options="buildingClusterOptions"> | ||||
|         <l-marker v-for="f in buildingFeatures" :key="f.id" :lat-lng="f.pos" :icon="iconBlue"> | ||||
|           <l-popup>{{f.text}}</l-popup> | ||||
|         </l-marker> | ||||
|       </l-marker-cluster> | ||||
|       <l-marker-cluster v-if="travelnetLayer" :options="travelnetClusterOptions"> | ||||
|         <l-marker v-for="f in travelnetFeatures" :key="f.id" :lat-lng="f.pos" :icon="iconYellow"> | ||||
|           <l-popup>{{f.text}}</l-popup> | ||||
|         </l-marker> | ||||
|       </l-marker-cluster> | ||||
|       <l-marker-cluster v-if="poiLayer" :options="poiClusterOptions"> | ||||
|         <l-marker v-for="f in poiFeatures" :key="f.id" :lat-lng="f.pos" :icon="iconRed"> | ||||
|           <l-popup>{{f.text}}</l-popup> | ||||
|         </l-marker> | ||||
|       </l-marker-cluster> | ||||
|       <l-marker-cluster v-if="otherLayer" :options="otherClusterOptions"> | ||||
|         <l-marker v-for="f in otherFeatures" :key="f.id" :lat-lng="f.pos" :icon="iconGreen"> | ||||
|           <l-popup>{{f.text}}</l-popup> | ||||
|         </l-marker> | ||||
|       </l-marker-cluster> | ||||
|       <div v-if="playersLayer"> | ||||
|         <l-marker v-for="p in players" :key="p.name" :lat-lng="flipCoordinates(p.geometry.coordinates)" :icon="iconPlayer"> | ||||
|           <l-popup>{{p.properties.name}}</l-popup> | ||||
| @@ -44,29 +64,107 @@ export default { | ||||
|       url: 'map/{z}/{x}/{y}.png', | ||||
|       zoom: 3, | ||||
|       noWrap: true, | ||||
|       center: [0,0], | ||||
|       worldCopyJump: false, | ||||
|       crs: ownCRS, | ||||
|       tms: true, | ||||
|       attribution: process.env.VUE_APP_TITLE, | ||||
|       features: [], | ||||
|       iconPlayer: new L.Icon({ | ||||
|         iconUrl: require('@/assets/marker-player.png'), | ||||
|         iconSize: [25, 41], | ||||
|         iconAnchor: [12, 41], | ||||
|       iconPlayer:  L.divIcon({ | ||||
|         html: '<div class="divIconOrange"></div><div class="iconFontPlayer"><i class="fas fa-walking"></i> </div>', | ||||
|         popupAnchor: [1, -34], | ||||
|         iconSize: L.point(0, 0) | ||||
|       }), | ||||
|       iconBlue: L.divIcon({ | ||||
|         html: '<div class="divIconBlue"></div><div class="iconFont"><i class="fas fa-building"></i> </div>', | ||||
|         popupAnchor: [1, -34], | ||||
|         iconSize: L.point(0, 0) | ||||
|       }), | ||||
|       iconRed: L.divIcon({ | ||||
|         html: '<div class="divIconRed"></div><div class="iconFont"><i class="fas fa-hand-pointer"></i> </div>', | ||||
|         popupAnchor: [1, -34], | ||||
|         iconSize: L.point(0, 0) | ||||
|       }), | ||||
|       iconYellow: L.divIcon({ | ||||
|         html: '<div class="divIconYellow"></div><div class="iconFont"><i class="fas fa-route"></i> </div>', | ||||
|         popupAnchor: [1, -34], | ||||
|         iconSize: L.point(0, 0) | ||||
|       }), | ||||
|       iconGreen: L.divIcon({ | ||||
|         html: '<div class="divIconGreen"></div><div class="iconFont"><i class="fas fa-bullseye"></i> </div>', | ||||
|         popupAnchor: [1, -34], | ||||
|         iconSize: L.point(0, 0) | ||||
|       }), | ||||
|       buildingClusterOptions: { | ||||
|         maxClusterRadius: 50, | ||||
|         iconCreateFunction: (cluster) => { | ||||
|           return L.divIcon({ html: '<div class="divIconBlue"></div><div class="myMarkerCluster">' + | ||||
|                   cluster.getChildCount() + | ||||
|                   '</div>', | ||||
|           iconSize: L.point(0, 0) }); | ||||
|         }, | ||||
|       }, | ||||
|       travelnetClusterOptions: { | ||||
|         maxClusterRadius: 50, | ||||
|         iconCreateFunction: (cluster) => { | ||||
|           return L.divIcon({ html: '<div class="divIconYellow"></div><div class="myMarkerCluster">' + | ||||
|                   cluster.getChildCount() + | ||||
|                   '</div>', | ||||
|           iconSize: L.point(0, 0) }); | ||||
|         }, | ||||
|       }, | ||||
|       poiClusterOptions: { | ||||
|         maxClusterRadius: 50, | ||||
|         iconCreateFunction: (cluster) => { | ||||
|           return L.divIcon({ html: '<div class="divIconRed"></div><div class="myMarkerCluster">' + | ||||
|                   cluster.getChildCount() + | ||||
|                   '</div>', | ||||
|           iconSize: L.point(0, 0) }); | ||||
|         }, | ||||
|       }, | ||||
|       otherClusterOptions: { | ||||
|         maxClusterRadius: 50, | ||||
|         iconCreateFunction: (cluster) => { | ||||
|           return L.divIcon({ html: '<div class="divIconGreen"></div><div class="myMarkerCluster">' + | ||||
|                   cluster.getChildCount() + | ||||
|                   '</div>', | ||||
|           iconSize: L.point(0, 0) }); | ||||
|         }, | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     buildingFeatures() { | ||||
|       return this.$store.state.pointFeatures.filter(f => f.type === 'Building'); | ||||
|     }, | ||||
|     travelnetFeatures() { | ||||
|       return this.$store.state.pointFeatures.filter(f => f.type === 'Travelnet') | ||||
|     }, | ||||
|     poiFeatures() { | ||||
|       return this.$store.state.pointFeatures.filter(f => f.type === 'Point of Interest') | ||||
|     }, | ||||
|     otherFeatures() { | ||||
|       return this.$store.state.pointFeatures.filter(f => f.type === 'Other') | ||||
|     }, | ||||
|     players() { | ||||
|       console.log(this.$store.state.players); | ||||
|       return this.$store.state.players; | ||||
|     }, | ||||
|     ...mapState({ | ||||
|       mapCenter: state => state.mapCenter, | ||||
|       features: state => state.pointFeatures, | ||||
|       autoUpdate: state => state.autoUpdate, | ||||
|       playersLayer: state => state.playersLayer, | ||||
|       buildingsLayer: state => state.buildingsLayer, | ||||
|       poiLayer: state => state.poiLayer, | ||||
|       travelnetLayer: state => state.travelnetLayer, | ||||
|       otherLayer: state => state.otherLayer, | ||||
|     }), | ||||
|   }, | ||||
|   mounted() { | ||||
|     this.$nextTick(function () { | ||||
|     console.log(this.$refs.baseLayer); | ||||
|       }) | ||||
|   }, | ||||
|   methods: { | ||||
|     update(evt) { | ||||
|       this.$store.commit('updateCoordinates', [evt.latlng.lat, evt.latlng.lng]) | ||||
| @@ -83,4 +181,89 @@ export default { | ||||
|   color: #f5f5f5; | ||||
|   background-color: #424242; | ||||
| } | ||||
| .iconFontPlayer { | ||||
|   font-size: medium; | ||||
|   width: 17px; | ||||
|   height: 17px; | ||||
|   color: rgb(58, 58, 58); | ||||
|   position: absolute; | ||||
|   top: -41px; | ||||
|   left: -9px; | ||||
|   font-weight: bold; | ||||
|   text-align: center; | ||||
|   border: 0px solid #666; | ||||
| } | ||||
| .iconFont { | ||||
|   width: 17px; | ||||
|   height: 17px; | ||||
|   color: rgb(58, 58, 58); | ||||
|   position: absolute; | ||||
|   top: -38px; | ||||
|   left: -9px; | ||||
|   font-weight: bold; | ||||
|   text-align: center; | ||||
|   border: 0px solid #666; | ||||
| } | ||||
| .myMarkerCluster { | ||||
|   border-radius: 49%; | ||||
|   width: 18px; | ||||
|   height: 18px; | ||||
|   background-color: #616160; | ||||
|   color: white; | ||||
|   position: absolute; | ||||
|   top: -38px; | ||||
|   left: -10px; | ||||
|   font-weight: bold; | ||||
|   text-align: center; | ||||
| } | ||||
| .divIconBlue { | ||||
|   width: 24px; | ||||
|   height: 40px; | ||||
|   position: absolute; | ||||
|   top: -42px; | ||||
|   left: -13px; | ||||
|   line-height: 40px; | ||||
|   background-image: url("@/assets/marker-icon-blue.png"); | ||||
|   text-align: center; | ||||
| } | ||||
| .divIconYellow { | ||||
|   width: 24px; | ||||
|   height: 40px; | ||||
|   position: absolute; | ||||
|   top: -42px; | ||||
|   left: -13px; | ||||
|   line-height: 40px; | ||||
|   background-image: url("@/assets/marker-icon-yellow.png"); | ||||
|   text-align: center; | ||||
| } | ||||
| .divIconRed { | ||||
|   width: 24px; | ||||
|   height: 40px; | ||||
|   position: absolute; | ||||
|   top: -42px; | ||||
|   left: -13px; | ||||
|   line-height: 40px; | ||||
|   background-image: url("@/assets/marker-icon-red.png"); | ||||
|   text-align: center; | ||||
| } | ||||
| .divIconGreen { | ||||
|   width: 24px; | ||||
|   height: 40px; | ||||
|   position: absolute; | ||||
|   top: -42px; | ||||
|   left: -13px; | ||||
|   line-height: 40px; | ||||
|   background-image: url("@/assets/marker-icon-green.png"); | ||||
|   text-align: center; | ||||
| } | ||||
| .divIconOrange { | ||||
|   width: 24px; | ||||
|   height: 40px; | ||||
|   position: absolute; | ||||
|   top: -42px; | ||||
|   left: -13px; | ||||
|   line-height: 40px; | ||||
|   background-image: url("@/assets/marker-icon-orange.png"); | ||||
|   text-align: center; | ||||
| } | ||||
| </style> | ||||
|   | ||||
| @@ -13,7 +13,9 @@ export default new Vuex.Store({ | ||||
| 		poiLayer: true, | ||||
| 		travelnetLayer: true, | ||||
| 		otherLayer: true, | ||||
| 		players: [] | ||||
| 		players: [], | ||||
| 		mapCenter: [0, 0], | ||||
| 		pointFeatures: [], | ||||
| 	}, | ||||
| 	 | ||||
| 	mutations: { | ||||
| @@ -44,6 +46,12 @@ export default new Vuex.Store({ | ||||
| 		setPlayerState(state, value) { | ||||
| 			const p = state.players.find(p => p.name === value.name) | ||||
| 			p.online = value.state; | ||||
| 		}, | ||||
| 		setMapCenter(state, value) { | ||||
| 			state.mapCenter = value; | ||||
| 		}, | ||||
| 		setPointFeatures(state, value) { | ||||
| 			state.pointFeatures = value; | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| @@ -73,6 +81,9 @@ export default new Vuex.Store({ | ||||
| 				fetch("players").then(response => response.json().then((data) => { | ||||
| 					commit("setPlayers", data); | ||||
| 				})); | ||||
| 				fetch("poi").then(response => response.json().then((data) => { | ||||
| 					commit("setPointFeatures", data); | ||||
| 				})); | ||||
|     }, | ||||
|  | ||||
| 		runAutoUpdate: function({ commit, state, dispatch}) { | ||||
| @@ -121,6 +132,20 @@ export default new Vuex.Store({ | ||||
| 					commit('setPlayers', msg.players); | ||||
| 				} | ||||
|  | ||||
| 				if (msg.poi) { | ||||
| 					console.log(msg.poi) | ||||
| 					let points = []; | ||||
| 					for (let i = 0; i < msg.poi.length; i++) { | ||||
| 						points.push({ | ||||
| 							id: i, | ||||
| 							pos: [msg.poi[i].pos.x, msg.poi[i].pos.z], | ||||
| 							text: msg.poi[i].text, | ||||
| 							type: msg.poi[i].type, | ||||
| 						}); | ||||
| 					} | ||||
| 					commit("setPointFeatures", points); | ||||
| 				} | ||||
|  | ||||
| 				var tilesData = msg.tiles; | ||||
| 				if (!tilesData) { | ||||
| 					return; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user