mirror of
https://bitbucket.org/s_l_teichmann/mtsatellite
synced 2025-02-01 18:50:21 +01:00
Layers for POI in web client and list of players.
This commit is contained in:
parent
5de40d6df3
commit
c01ff0bdbf
@ -15,6 +15,56 @@
|
|||||||
<v-list-item-title>Players</v-list-item-title>
|
<v-list-item-title>Players</v-list-item-title>
|
||||||
</v-list-item-content>
|
</v-list-item-content>
|
||||||
</v-list-item>
|
</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-list>
|
||||||
</v-navigation-drawer>
|
</v-navigation-drawer>
|
||||||
<v-app-bar :clipped-left="true" fixed app>
|
<v-app-bar :clipped-left="true" fixed app>
|
||||||
@ -120,11 +170,19 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
fetch("players").then(response => response.json().then((data) => {
|
fetch("players").then(response => response.json().then((data) => {
|
||||||
this.$store.commit("setPlayers", data);
|
this.$store.commit("setPlayers", data);
|
||||||
}))
|
}));
|
||||||
|
fetch("poi").then(response => response.json().then((data) => {
|
||||||
|
this.$store.commit("setPointFeatures", data);
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
refreshContent() {
|
refreshContent() {
|
||||||
this.$store.dispatch("manualUpdate");
|
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>
|
<template>
|
||||||
<v-container fluid style="height: 100%; padding: 0px">
|
<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-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">
|
<div v-if="playersLayer">
|
||||||
<l-marker v-for="p in players" :key="p.name" :lat-lng="flipCoordinates(p.geometry.coordinates)" :icon="iconPlayer">
|
<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>
|
<l-popup>{{p.properties.name}}</l-popup>
|
||||||
@ -44,29 +64,107 @@ export default {
|
|||||||
url: 'map/{z}/{x}/{y}.png',
|
url: 'map/{z}/{x}/{y}.png',
|
||||||
zoom: 3,
|
zoom: 3,
|
||||||
noWrap: true,
|
noWrap: true,
|
||||||
center: [0,0],
|
|
||||||
worldCopyJump: false,
|
worldCopyJump: false,
|
||||||
crs: ownCRS,
|
crs: ownCRS,
|
||||||
tms: true,
|
tms: true,
|
||||||
attribution: process.env.VUE_APP_TITLE,
|
attribution: process.env.VUE_APP_TITLE,
|
||||||
features: [],
|
features: [],
|
||||||
iconPlayer: new L.Icon({
|
iconPlayer: L.divIcon({
|
||||||
iconUrl: require('@/assets/marker-player.png'),
|
html: '<div class="divIconOrange"></div><div class="iconFontPlayer"><i class="fas fa-walking"></i> </div>',
|
||||||
iconSize: [25, 41],
|
|
||||||
iconAnchor: [12, 41],
|
|
||||||
popupAnchor: [1, -34],
|
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: {
|
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() {
|
players() {
|
||||||
|
console.log(this.$store.state.players);
|
||||||
return this.$store.state.players;
|
return this.$store.state.players;
|
||||||
},
|
},
|
||||||
...mapState({
|
...mapState({
|
||||||
|
mapCenter: state => state.mapCenter,
|
||||||
|
features: state => state.pointFeatures,
|
||||||
autoUpdate: state => state.autoUpdate,
|
autoUpdate: state => state.autoUpdate,
|
||||||
playersLayer: state => state.playersLayer,
|
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: {
|
methods: {
|
||||||
update(evt) {
|
update(evt) {
|
||||||
this.$store.commit('updateCoordinates', [evt.latlng.lat, evt.latlng.lng])
|
this.$store.commit('updateCoordinates', [evt.latlng.lat, evt.latlng.lng])
|
||||||
@ -83,4 +181,89 @@ export default {
|
|||||||
color: #f5f5f5;
|
color: #f5f5f5;
|
||||||
background-color: #424242;
|
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>
|
</style>
|
||||||
|
@ -13,7 +13,9 @@ export default new Vuex.Store({
|
|||||||
poiLayer: true,
|
poiLayer: true,
|
||||||
travelnetLayer: true,
|
travelnetLayer: true,
|
||||||
otherLayer: true,
|
otherLayer: true,
|
||||||
players: []
|
players: [],
|
||||||
|
mapCenter: [0, 0],
|
||||||
|
pointFeatures: [],
|
||||||
},
|
},
|
||||||
|
|
||||||
mutations: {
|
mutations: {
|
||||||
@ -44,6 +46,12 @@ export default new Vuex.Store({
|
|||||||
setPlayerState(state, value) {
|
setPlayerState(state, value) {
|
||||||
const p = state.players.find(p => p.name === value.name)
|
const p = state.players.find(p => p.name === value.name)
|
||||||
p.online = value.state;
|
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) => {
|
fetch("players").then(response => response.json().then((data) => {
|
||||||
commit("setPlayers", data);
|
commit("setPlayers", data);
|
||||||
}));
|
}));
|
||||||
|
fetch("poi").then(response => response.json().then((data) => {
|
||||||
|
commit("setPointFeatures", data);
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
runAutoUpdate: function({ commit, state, dispatch}) {
|
runAutoUpdate: function({ commit, state, dispatch}) {
|
||||||
@ -121,6 +132,20 @@ export default new Vuex.Store({
|
|||||||
commit('setPlayers', msg.players);
|
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;
|
var tilesData = msg.tiles;
|
||||||
if (!tilesData) {
|
if (!tilesData) {
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user