Merge branch 'master' of C:\Users\dikpater\flightgear-airports\flightgear-airports\.git into NodeJS

This commit is contained in:
Paterson 2020-12-18 21:50:51 +01:00
commit 8274fb882e
28 changed files with 1217 additions and 333 deletions

8
build/installer.nsh Normal file
View File

@ -0,0 +1,8 @@
!macro preInit
SetRegView 64
WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$PROGRAMFILES64\flightgear-airports"
WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$PROGRAMFILES64\flightgear-airports"
SetRegView 32
WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$PROGRAMFILES32\flightgear-airports"
WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$PROGRAMFILES32\flightgear-airports"
!macroend

View File

@ -0,0 +1,106 @@
<!--
Copyright 2020 Keith Paterson
This file is part of FG Airports.
FG Airports is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
FG Airports is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with FG Airports. If not, see http://www.gnu.org/licenses/.
-->
<template>
<div width="100%" v-if="multiarc">
<!--
airlineCodes: 0
heading: 341.34
index: 13
lat: "N59 52.610885"
lon: "W1 17.855144"
name: "Western_Apron_Hanger"
pushBackRoute: 27
radius: 18
type: "gate"
-->
<el-row>
<el-col :span="7">
<span class="demo-input-label">Name :</span>
</el-col>
<el-col :span="15">
<el-input placeholder="Please input" v-model="name"></el-input>
</el-col>
</el-row>
<el-row>
<el-col :span="7">
<span class="demo-input-label">Pushback :</span>
</el-col>
<el-col :span="15">
<el-switch v-model="isPushback"></el-switch>
</el-col>
</el-row>
<el-row>
<el-col :span="7">
<span class="demo-input-label">Direction :</span>
</el-col>
<el-col :span="15">
<el-select v-model="direction" placeholder="Select">
<el-option
v-for="type in options"
:key="type.value"
:label="type.label"
:value="type.value"
></el-option>
</el-select>
</el-col>
</el-row>
</div>
</template>
<script lang="js">
export default {
computed: {
multiarc: function () {
return this.$store.state.Editable.type === 'multiarc'
},
// ga (general aviation), cargo (cargo), gate (commercial passenger traffic),
// mil-fighter (military fighter), mil-cargo (military transport)
options: function () {
return [{value: 'bi-directional', label: 'bi-directional'},
{value: 'forward', label: 'forward'},
{value: 'backward', label: 'backward'}
]
},
name: {
// getter
get: function () {
return this.$store.state.Editable.data.multiarc.name
},
// setter
set: function (newValue) {
this.$store.commit('SET_EDIT_ARC_NAME', newValue)
}
},
isPushback: {
// getter
get: function () {
return this.$store.state.Editable.data.multiarc.isPushBackRoute === '1' ||
Number(this.$store.state.Editable.data.multiarc.isPushBackRoute) === Number(1)
},
// setter
set: function (newValue) {
this.$store.commit('SET_EDIT_PUSHBACK', newValue ? '1' : '0')
}
},
direction: {
// getter
get: function () {
return this.$store.state.Editable.data.multiarc.direction
},
// setter
set: function (newValue) {
this.$store.commit('SET_EDIT_DIRECTION', newValue)
}
}
}
}
</script>

View File

@ -3,7 +3,7 @@
<div class="select-button">
...
</div>
<input type="file" @change="handleFileChange" webkitdirectory directory/>
<input name="hiddenDir" type="file" v-on:change="handleFileChange($event)" webkitdirectory directory tabindex="-1"/>
</label>
</template>
@ -20,10 +20,16 @@
methods: {
handleFileChange (e) {
try {
if (e.target.files && e.target.files.length>0) {
var first = e.target.files[0].webkitRelativePath.split("/")[0];
var webkitdirectoryPath = e.target.files[0].path.split(first)[0] + first;
this.$emit('input', webkitdirectoryPath)
}
} catch (error) {
console.error(error)
}
}
}
}
</script>
@ -39,6 +45,8 @@
text-align: center;
font-weight: bold;
width: 28px;
height: 28px;
}
.directory-select > input[type="file"] {

View File

@ -41,11 +41,7 @@ You should have received a copy of the GNU General Public License along with FG
props: [],
created () {
console.log(LMap)
console.log(LMarker)
console.log(L)
console.log(LEdit)
console.log(L2)
[LMap, LMarker, L, LEdit, L2]
console.log('Created Editlayer')
// console.log(LSymbol)
},
@ -72,6 +68,16 @@ You should have received a copy of the GNU General Public License along with FG
deep: true //add this if u need to watch object properties change etc.
}
);
this.$store.watch(
function (state) {
return state.Editable.data.multiarc;
},
() => { this.editedMultiArc() }
,
{
deep: true //add this if u need to watch object properties change etc.
}
);
this.$store.watch(
function (state) {
return state.Editable.data.parking;
@ -125,13 +131,19 @@ You should have received a copy of the GNU General Public License along with FG
this.icao = icao
this.groundnetLayerGroup = readGroundnetXML(this.$store.state.Settings.settings.airportsDirectory, icao, force)
if (this.groundnetLayerGroup === undefined) {
console.error('ICAO not loaded ' + icao)
console.warn('Groundnet for ICAO not loaded ' + icao)
return
}
if (this.groundnetLayerGroup.getLayers().length === 0) {
console.warn('Groundnet for ICAO not loaded ' + icao)
}
this.groundnetLayerGroup.eachLayer(l => {
if (l instanceof L.TaxiwaySegment) {
l.addListeners()
}
if (l.updateArrows !== undefined) {
l.updateArrows(this.$store.state.Settings.zoom)
}
})
console.log(this.groundnetLayerGroup.maxId)
@ -659,6 +671,7 @@ You should have received a copy of the GNU General Public License along with FG
!this.editing) {
return;
}
console.debug("Edit Type : " + this.$store.state.type);
var arc = this.groundnetLayerGroup.getLayer(this.$store.state.Editable.index);
if (arc && arc instanceof L.Polyline) {
console.log('Edited Arc : ' + this.$store.state.Editable.index);
@ -666,6 +679,27 @@ You should have received a copy of the GNU General Public License along with FG
arc.updateStyle();
}
},
editedMultiArc() {
if (!this.groundnetLayerGroup ||
this.$store.state.Editable.data.multiarc === undefined ||
this.$store.state.Editable.data.multiarc.ids === undefined ||
this.featureLookup===undefined ||
!this.editing) {
return;
}
console.debug("Edit Type : " + this.$store.state.Editable.data.multiarc.ids);
this.$store.state.Editable.data.multiarc.ids.forEach(id => {
console.debug(id);
var arc = this.groundnetLayerGroup.getLayer(id);
if (arc && arc instanceof L.Polyline) {
console.log('Edited Arc : ' + this.$store.state.Editable.index);
arc.options.attributes.direction = this.$store.state.Editable.data.multiarc.direction
arc.options.attributes.name = this.$store.state.Editable.data.multiarc.name
arc.options.attributes.isPushBackRoute = this.$store.state.Editable.data.multiarc.isPushBackRoute
arc.updateStyle();
}
});
},
//Update Node
editedNode() {
if (this.$store.state.Editable.index === undefined ||
@ -825,11 +859,11 @@ You should have received a copy of the GNU General Public License along with FG
this.$parent.mapObject.on('click', this.addParking)
},
removeLayerClick (event) {
console.log(event)
console.debug(event)
this.groundnetLayerGroup.removeLayer(event.target)
},
addParking (event) {
console.log(event.latlng)
console.debug(event.latlng)
if (event.latlng === undefined) {
return
}

View File

@ -30,8 +30,6 @@ You should have received a copy of the GNU General Public License along with FG
<!--<l-marker :lat-lng="marker"></l-marker>-->
<LeafletSidebar ref="sidebar" @editParking="onEditSidebar" @edit="onEdit($event)"></LeafletSidebar>
<AiLayer ref="aiLayer"></AiLayer>
<PavementLayer ref="pavementLayer"></PavementLayer>
<ThresholdLayer ref="thresholdLayer"></ThresholdLayer>
<l-layer-group layerType="overlay" name="airports" ref="airportLayer">
<l-circle
v-for="(item, index) in this.$store.state.Airports.airports"
@ -44,6 +42,9 @@ You should have received a copy of the GNU General Public License along with FG
></l-circle>
</l-layer-group>
<EditLayer ref="editLayer"></EditLayer>
<PavementLayer ref="pavementLayer"></PavementLayer>
<ThresholdLayer ref="thresholdLayer"></ThresholdLayer>
<TowerLayer ref="towerLayer"></TowerLayer>
<ToolLayer ref="toolLayer" @select-poly="onSelectedPolygon"></ToolLayer>
<EditBar ref="editBar" @edit="onEdit($event)"></EditBar>
<ToolBar ref="toolBar"></ToolBar>
@ -60,6 +61,7 @@ You should have received a copy of the GNU General Public License along with FG
import ToolBar from './ToolBar'
import EditLayer from './EditLayer'
import ToolLayer from './ToolLayer'
import TowerLayer from './TowerLayer'
import PavementLayer from './PavementLayer'
import ThresholdLayer from './ThresholdLayer'
@ -75,7 +77,7 @@ You should have received a copy of the GNU General Public License along with FG
})
export default {
name: 'flightgear-map',
components: { LMap, LTileLayer, LMarker, LCircle, LeafletSidebar, AiLayer, EditBar, ToolBar, EditLayer, PavementLayer, LLayerGroup, LControl, ThresholdLayer, ToolLayer },
components: { LMap, LTileLayer, LMarker, LCircle, LeafletSidebar, AiLayer, EditBar, ToolBar, EditLayer, TowerLayer, PavementLayer, LLayerGroup, LControl, ThresholdLayer, ToolLayer },
props: [],
created () {
this.loadingInstance = null
@ -85,7 +87,7 @@ You should have received a copy of the GNU General Public License along with FG
},
(newValue, oldValue) => {
// debugger
console.log('setIcaoLoading ' + oldValue + ' => ' + newValue + ' ' + this.groundnetLoaded + ' ' + this.pavementLoaded + ' ' + this.loadingInstance)
console.log('setIcaoLoading ' + oldValue + ' => ' + newValue + ' groundnetLoaded ' + this.groundnetLoaded + ' pavementLoaded ' + this.pavementLoaded + ' ' + this.loadingInstance)
if (newValue !== oldValue && newValue !== '') {
this.groundnetLoaded = newValue
if ((this.loadingInstance === null || this.loadingInstance === undefined)) {
@ -105,7 +107,7 @@ You should have received a copy of the GNU General Public License along with FG
},
(newValue, oldValue) => {
// debugger
console.log('groundnetLoaded ' + oldValue + ' => ' + newValue + ' ' + this.groundnetLoaded + ' ' + this.pavementLoaded + ' ' + this.loadingInstance)
console.log('groundnetLoaded ' + oldValue + ' => ' + newValue + ' groundnetLoaded ' + this.groundnetLoaded + ' pavementLoaded ' + this.pavementLoaded + ' ' + this.loadingInstance)
if (newValue !== oldValue) {
this.groundnetLoaded = newValue
if (this.groundnetLoaded &&
@ -160,6 +162,9 @@ You should have received a copy of the GNU General Public License along with FG
this.$refs.pavementLayer.load(airportsToLoad[0])
this.$refs.editLayer.load(airportsToLoad[0])
this.$refs.thresholdLayer.load(airportsToLoad[0])
if (this.$refs.towerLayer) {
this.$refs.towerLayer.load(airportsToLoad[0])
}
this.editingAirport = airportsToLoad[0]
})
}
@ -169,7 +174,6 @@ You should have received a copy of the GNU General Public License along with FG
if (this.$refs.airportLayer) {
this.$refs.airportLayer.setVisible(this.zoom < 12)
}
// console.log(this.groundnet)
}
})
@ -208,16 +212,34 @@ You should have received a copy of the GNU General Public License along with FG
if (this.$refs.pavementLayer.getLayer() === e.layer) {
// debugger
var l = this.layersControl._layers.filter(l => l.name === 'APT Layer')
if (l.length > 0 && l[0].layer !== this.$refs.pavementLayer.getLayer()) {
this.layersControl.removeLayer(l[0].layer)
this.layersControl.addOverlay(this.$refs.pavementLayer.getLayer(), 'APT Layer')
}
if (l.length === 0) {
this.layersControl.addOverlay(this.$refs.pavementLayer.getLayer(), 'APT Layer')
}
}
if (this.$refs.thresholdLayer.getLayer() === e.layer) {
l = this.layersControl._layers.filter(l => l.name === 'Threshold Layer')
if (l.length > 0 && l[0].layer !== this.$refs.thresholdLayer.getLayer()) {
this.layersControl.removeLayer(l[0].layer)
this.layersControl.addOverlay(this.$refs.thresholdLayer.getLayer(), 'Threshold Layer')
}
if (l.length === 0) {
this.layersControl.addOverlay(this.$refs.thresholdLayer.getLayer(), 'Threshold Layer')
}
}
if (this.$refs.towerLayer !== undefined && this.$refs.towerLayer.getLayer() === e.layer) {
l = this.layersControl._layers.filter(l => l.name === 'Tower Layer')
if (l.length > 0 && l[0].layer !== this.$refs.towerLayer.getLayer()) {
this.layersControl.removeLayer(l[0].layer)
this.layersControl.addOverlay(this.$refs.towerLayer.getLayer(), 'Tower Layer')
}
if (l.length === 0) {
this.layersControl.addOverlay(this.$refs.towerLayer.getLayer(), 'Tower Layer')
}
}
},
onSelectedPolygon (ring) {
var parkings = this.$refs.editLayer.getParkings(ring)
@ -234,6 +256,7 @@ You should have received a copy of the GNU General Public License along with FG
this.$refs.map.mapObject.options.minZoom = 1
}
this.$refs.editLayer.enableEdit()
this.$refs.towerLayer.enableEdit()
this.$refs.editBar.setEditing(event)
this.$refs.toolBar.setEditing(event)
this.$refs.sidebar.setEditing(event)
@ -317,13 +340,36 @@ You should have received a copy of the GNU General Public License along with FG
if (zoom !== this.$store.state.Settings.zoom) {
this.$store.dispatch('setZoom', zoom)
this.$refs.airportLayer.setVisible(zoom < 12)
if (this.$refs.towerLayer) {
this.$refs.towerLayer.setVisible(this.zoom >= 12)
}
if (this.$refs.thresholdLayer) {
this.$refs.thresholdLayer.setVisible(this.zoom >= 12)
}
this.$refs.pavementLayer.setVisible(zoom >= 12)
}
this.$refs.editLayer.groundnetLayerGroup.eachLayer(function (layer) {
if (layer.updateArrows !== undefined) {
layer.updateArrows(zoom)
}
})
if (this.$refs.thresholdLayer) {
this.$refs.thresholdLayer.zoomUpdated()
}
if (this.$refs.towerLayer) {
this.$refs.towerLayer.zoomUpdated()
}
},
async centerUpdated (center) {
if (center !== this.$store.state.Settings.center) {
this.$store.dispatch('setCenter', center)
this.$refs.airportLayer.setVisible(this.zoom < 12)
if (this.$refs.thresholdLayer) {
this.$refs.thresholdLayer.setVisible(this.zoom >= 12)
}
if (this.$refs.towerLayer) {
this.$refs.towerLayer.setVisible(this.zoom >= 12)
}
this.$refs.pavementLayer.setVisible(this.zoom >= 12)
}
},

View File

@ -1,7 +1,18 @@
<!--
Copyright 2020 Keith Paterson
This file is part of FG Airports.
FG Airports is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
FG Airports is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with FG Airports. If not, see http://www.gnu.org/licenses/.
-->
<template>
<div class="leaflet-sidebar-pane" id="home">
<h1 class="leaflet-sidebar-header">
Help
{{version}}
<div class="leaflet-sidebar-close"><i class="fa fa-caret-left"></i></div>
</h1>
<h2>Setup</h2>
@ -15,22 +26,20 @@
<h2>World view</h2>
<p>
When zoomed out you will see circles. Their size corresponds with the number of flights.
Blue means Ok. Yellow to little parking. Red no groundnet.
Blue means Ok. Yellow to little parking in comparison to the number of flights. Red no groundnet.
</p>
<h2>Edit view</h2>
<p>
</p>
<ul>
<li>Button with ICAO code opens the Airport data in the edit tab.</li>
<li>The top 4 buttons in the button bar are for zooming. </li>
<li>Upload sends the current airport to groundweb.</li>
<li>Edit switches into edit mode</li>
<li>Undo undos all changes or all changes during session</li>
<li>Save, saves the groundnet</li>
<li>Draw taxiline</li>
<li>Check triggers the groundnet check.</li>
<li>Draw bi directional taxiline</li>
<li>Draw uni directional taxiline</li>
<li>Draw pushback.</li>
<li>Add parking</li>
<li>Remove element, removes the currently selected element</li>
<li>Check triggers the groundnet check.</li>
</ul>
</div>
</template>
@ -51,7 +60,9 @@
},
computed: {
version: function () {
return ' Flightgear Airports ' + require('electron').remote.app.getVersion()
}
}
}
</script>

View File

@ -38,6 +38,7 @@ You should have received a copy of the GNU General Public License along with FG
<div class="leaflet-sidebar-close"><i class="fa fa-caret-left"></i></div>
</h1>
<ParkingEdit></ParkingEdit>
<ArcEditMulti></ArcEditMulti>
<ArcEdit></ArcEdit>
<NodeEdit></NodeEdit>
<ParkingGroupEdit ref="parkingGroupEdit" @editParking="(msg) => $emit('editParking', msg)"></ParkingGroupEdit>
@ -74,6 +75,7 @@ You should have received a copy of the GNU General Public License along with FG
import L from 'leaflet'
import AirportEdit from './AirportEdit'
import ArcEdit from './ArcEdit'
import ArcEditMulti from './ArcEditMulti'
import CheckPanel from './CheckPanel'
import FileSelect from './FileSelect'
import Help from './Help'
@ -89,7 +91,7 @@ You should have received a copy of the GNU General Public License along with FG
export default {
name: 'leaflet-sidebar',
components: { Help, AirportEdit, ArcEdit, CheckPanel, NodeEdit, ParkingEdit, ParkingGroupEdit, RunScan, FileSelect, SettingsPanel, Search, Upload, WorkInProgress },
components: { Help, AirportEdit, ArcEdit, ArcEditMulti, CheckPanel, NodeEdit, ParkingEdit, ParkingGroupEdit, RunScan, FileSelect, SettingsPanel, Search, Upload, WorkInProgress },
props: [],
created () {
window.addEventListener('keydown', this.doCommand)

View File

@ -11,17 +11,25 @@
<el-col :span="22" class="label">Airports Directory</el-col>
</el-row>
<el-row>
<el-col :span="20" class="file-label">{{ airports_directory }}</el-col>
<el-col :span="4">
<directory-select @input="airportsDirectorySelect"></directory-select>
<el-col :span="22" v-bind:class="{ invalid: !airports_directory_ok, file_label: airports_directory_ok}">{{ airports_directory }}</el-col>
<el-col :span="2">
<el-popover
placement="top-start"
title="E-Mail"
width="200"
trigger="hover"
content="The work directory. Best is a copy from groundweb"
>
<directory-select @input="airportsDirectorySelect" slot="reference"></directory-select>
</el-popover>
</el-col>
</el-row>
<el-row>
<el-col :span="22" class="label">Flightgear Data Directory</el-col>
</el-row>
<el-row>
<el-col :span="20" class="file-label">{{ flightgear_directory }}</el-col>
<el-col :span="4">
<el-col :span="22" v-bind:class="{ invalid: !flightgear_directory_ok, file_label: flightgear_directory_ok}">{{ flightgear_directory }}</el-col>
<el-col :span="2">
<el-popover
placement="top-start"
title="E-Mail"
@ -34,20 +42,24 @@
</el-col>
</el-row>
<el-row>
<el-col :span="7" class="label">Traffic Directory</el-col>
<el-col :span="15" v-bind:class="{ invalid: !Traffic_directory_ok}">{{ Traffic_directory }}</el-col>
<el-col :span="22" class="label">Traffic Directory</el-col>
</el-row>
<el-row>
<el-col :span="22" v-bind:class="{ invalid: !Traffic_directory_ok, file_label: Traffic_directory_ok}">{{ Traffic_directory }}</el-col>
<el-col :span="2">
</el-col>
</el-row>
<el-row>
<el-col :span="7" class="label">APT File</el-col>
<el-col :span="15" v-bind:class="{invalid: !apt_file_ok}" >{{ apt_file }}</el-col>
<el-col :span="22" class="label">APT File</el-col>
</el-row>
<el-row>
<el-col :span="22" v-bind:class="{invalid: !apt_file_ok}" >{{ apt_file }}</el-col>
<el-col :span="2">
</el-col>
</el-row>
<el-row>
<el-col :span="7" class="label">Export Directory</el-col>
<el-col :span="15" class="file-label">{{ test_directory }}</el-col>
<el-col :span="15" v-bind:class="{invalid: !test_directory_ok, file_label: test_directory_ok}">{{ test_directory }}</el-col>
<el-col :span="2">
<directory-select @input="testDirectorySelect"></directory-select>
</el-col>
@ -194,6 +206,14 @@
flightgear_directory: function () {
return this.$store.state.Settings.settings.flightgearDirectory
},
flightgear_directory_ok: function () {
try {
fs.accessSync(this.$store.state.Settings.settings.flightgearDirectory)
return true
} catch (error) {
return false
}
},
AI_directory: function () {
return this.$store.state.Settings.settings.flightgearDirectory_ai
},
@ -222,9 +242,25 @@
airports_directory: function () {
return this.$store.state.Settings.settings.airportsDirectory
},
airports_directory_ok: function () {
try {
fs.accessSync(this.$store.state.Settings.settings.airportsDirectory)
return true
} catch (error) {
return false
}
},
test_directory: function () {
return this.$store.state.Settings.settings.testDirectory
},
test_directory_ok: function () {
try {
fs.accessSync(this.$store.state.Settings.settings.testDirectory)
return true
} catch (error) {
return false
}
},
scanLogging: {
// getter
get: function () {
@ -247,14 +283,14 @@
border-radius: 4px;
}
.label {
padding: 10px;
padding: 5px;
font-weight: bold;
}
.file-label {
padding: 10px;
.file_label {
padding: 5px;
}
.invalid {
padding: 10px;
padding: 5px;
background-color: red;
}

View File

@ -31,6 +31,10 @@
load (icao) {
// Callback for add
this.layerGroup = readThresholdXML(this.$store.state.Settings.settings.airportsDirectory, icao, this.read)
if (!this.layerGroup) {
console.warn('Threshold for ICAO not loaded ' + icao)
return
}
this.layerGroup.addTo(this.$parent.mapObject)
this.visible = true
this.icao = icao
@ -58,13 +62,21 @@
this.visible = visible
}
}
},
zoomUpdated () {
this.layerGroup.eachLayer(l => {
if (l instanceof L.Threshold) {
l.updateIcon(this.$parent.mapObject)
}
})
}
},
computed: {
edit: function () {
console.log('Zoom : ' + this.$store.state.Settings.zoom)
if (this.$store.state.Settings.zoom > 12) {
console.log()
console.log('Zoom above 12')
}
}
}

View File

@ -0,0 +1,104 @@
<!--
Copyright 2020 Keith Paterson
This file is part of FG Airports.
FG Airports is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
FG Airports is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with FG Airports. If not, see http://www.gnu.org/licenses/.
-->
<template></template>
<script lang="js">
import { LMap, LMarker } from 'vue2-leaflet'
import L from 'leaflet'
import LEdit from 'leaflet-editable/src/Leaflet.Editable.js'
import {readTowerXML} from '../loaders/tower_loader'
export default {
name: 'tower-layer',
props: [],
created () {
console.debug([LMap, LMarker, L, LEdit])
},
mounted () {
},
beforeDestroy () {
this.remove()
},
data () {
return {
}
},
methods: {
getLayer () {
return this.layerGroup
},
load (icao) {
// Callback for add
this.layerGroup = readTowerXML(this.$store.state.Settings.settings.airportsDirectory, icao, this.read)
if (!this.layerGroup) {
console.warn('Tower for ICAO not loaded ' + icao)
return
}
this.layerGroup.addTo(this.$parent.mapObject)
this.visible = true
this.icao = icao
},
deferredMountedTo (parent) {
},
remove () {
if (this.layerGroup) {
this.$parent.removeLayer(this.layerGroup)
}
},
add () {
if (this.$parent._isMounted) {
this.deferredMountedTo(this.$parent.mapObject)
}
},
enableEdit () {
this.layerGroup.eachLayer(l => {
if (l instanceof L.TowerMarker) {
l.enableEdit(this.$parent.mapObject)
}
})
},
save () {
},
setVisible (visible) {
if (this.layerGroup !== undefined) {
if (visible !== this.visible) {
if (visible) {
this.layerGroup.addTo(this.$parent.mapObject)
} else {
this.layerGroup.removeFrom(this.$parent.mapObject)
}
this.visible = visible
}
}
},
zoomUpdated () {
this.layerGroup.eachLayer(l => {
if (l instanceof L.TowerMarker) {
l.updateIcon(this.$parent.mapObject)
}
})
}
},
computed: {
edit: function () {
console.log('Zoom : ' + this.$store.state.Settings.zoom)
if (this.$store.state.Settings.zoom > 12) {
console.log()
}
}
}
}
</script>
<style scoped lang="scss">
</style>

View File

@ -4,6 +4,7 @@ const Vue = require('vue');
var L = require('leaflet');
const store = require('../store');
const util = require('util');
const assign = require('core-js/fn/object/assign');
const extendTaxiSegment = function (taxiwaySegment) {
taxiwaySegment.__proto__.begin;
@ -36,7 +37,7 @@ const extendTaxiSegment = function (taxiwaySegment) {
this.editLayer = editLayer;
this._latlngs[0].glueindex = this.begin;
this._latlngs.slice(-1)[0].glueindex = this.end;
if(this.featureLookup) {
if (this.featureLookup) {
if (typeof this.featureLookup[this.begin] === 'undefined') {
this.featureLookup[this.begin] = new Array();
}
@ -53,13 +54,13 @@ const extendTaxiSegment = function (taxiwaySegment) {
this.updateStyle();
};
taxiwaySegment.__proto__.selectVertex = function (index) {
this.getLatLngs().forEach( element => {
this.getLatLngs().forEach(element => {
if (Number(element.glueindex) === index) {
if (element.__vertex._icon != null) {
element.__vertex.__proto__.deselect = function () {
if (this._icon != null) {
this._icon.style.setProperty('background-color','white');
this._icon.style.setProperty('color','white');
this._icon.style.setProperty('background-color', 'white');
this._icon.style.setProperty('color', 'white');
} else if (this.icon != null) {
if (this.icon.style != null) {
this.icon.style['background-color'] = 'white';
@ -74,8 +75,8 @@ const extendTaxiSegment = function (taxiwaySegment) {
}
}
}
element.__vertex._icon.style.setProperty('background-color','red');
element.__vertex._icon.style.setProperty('color','red');
element.__vertex._icon.style.setProperty('background-color', 'red');
element.__vertex._icon.style.setProperty('color', 'red');
} else if (element.__vertex !== undefined && element.__vertex.icon != null) {
if (element.__vertex.icon.style != null) {
element.__vertex.icon.style['background-color'] = 'red';
@ -95,8 +96,8 @@ const extendTaxiSegment = function (taxiwaySegment) {
taxiwaySegment.__proto__.deselect = function () {
this.options.attributes.selected = false;
this.updateStyle();
this.getLatLngs().forEach( element => {
if (element.__vertex!==undefined) {
this.getLatLngs().forEach(element => {
if (element.__vertex !== undefined) {
if (element.__vertex._icon != null) {
element.__vertex._icon.style['background-color'] = 'white';
} else if (element.__vertex.icon != null) {
@ -124,7 +125,8 @@ const extendTaxiSegment = function (taxiwaySegment) {
});
}
event.target.select();
console.log("Click : " + event.target);
console.debug("Click : " + util.inspect(event.originalEvent));
if (!event.originalEvent.ctrlKey) {
if (store.default.state.Editable.data.arc === undefined ||
store.default.state.Editable.data.arc !== event.target.options.attributes) {
if (event.target.options.attributes === undefined) {
@ -137,17 +139,58 @@ const extendTaxiSegment = function (taxiwaySegment) {
event.target.options.attributes.selected = true;
store.default.dispatch('setArc', event.target.options.attributes);
}
} else {
var arcs = event.target.expandArc(event.target.options.attributes);
var multiarc = {name: '', index: 900719925474099, ids: [] ,isPushBackRoute: null, direction: null};
if (store.default.state.Editable.data.multiarc === undefined ||
store.default.state.Editable.data.multiarc !== event.target.options.attributes) {
if (event.target.options.attributes === undefined) {
event.target.options.attributes = {};
}
event.target.options.attributes.index = event.target._leaflet_id;
this.editLayer.featureLookup[event.target._leaflet_id] = [];
this.featureLookup[event.target._leaflet_id].push(this);
event.target.options.attributes.selected = true;
//multiarc.name = JSON.parse(JSON.stringify(event.target.options.attributes.name));
//multiarc.isPushBackRoute = JSON.parse(JSON.stringify(event.target.options.attributes.isPushBackRoute));
//multiarc.direction = JSON.parse(JSON.stringify(event.target.options.attributes.direction));
if(event.target.options.attributes.name!==undefined) {
multiarc.name = assign(event.target.options.attributes.name);
}
multiarc.isPushBackRoute = assign(event.target.options.attributes.isPushBackRoute);
multiarc.direction = assign(event.target.options.attributes.direction);
this.editLayer.featureLookup[900719925474099] = [];
multiarc.ids = [];
//TODO
store.default.dispatch('setMultiArc', multiarc);
}
var editLayer = this.editLayer;
arcs.forEach(id => {
console.debug(id);
var arc = editLayer.groundnetLayerGroup.getLayer(id);
if (arc && arc instanceof L.Polyline) {
editLayer.featureLookup[900719925474099].push(arc);
arc.select();
}
});
store.default.dispatch('setMultiArcIds', arcs);
}
});
this.on('editable:drawing:move', function (event) {
if (dragIndex >= 0) {
this.selectVertex(dragIndex);
console.log('GlueDrag : '+ dragIndex + '\t' + event.target.dragIndex);
console.log('GlueDrag : ' + dragIndex + '\t' + event.target.dragIndex);
this.follow(dragIndex, event);
}
});
this.on('editable:middlemarker:mousedown', event => {
console.debug('editable:middlemarker:mousedown');
} ),
}),
this.on('editable:vertex:new', event => {
console.debug('editable:vertex:new ' + event.vertex.getIndex() + '\t' + event.vertex.getLastIndex() + '\t');
// Find nearest node
@ -157,7 +200,7 @@ const extendTaxiSegment = function (taxiwaySegment) {
taxiwaySegment.options.attributes = { direction: 'bi-directional' };
}
taxiwaySegment.updateStyle();
if(event.vertex.getIndex() !== 0 && event.vertex.getIndex() !== event.vertex.getLastIndex()) {
if (event.vertex.getIndex() !== 0 && event.vertex.getIndex() !== event.vertex.getLastIndex()) {
var nextIndex = ++taxiwaySegment.editLayer.groundnetLayerGroup.maxId;
var splitOffNodes = taxiwaySegment.getLatLngs().splice(-1);
var remainingNodes = taxiwaySegment.getLatLngs();
@ -170,7 +213,7 @@ const extendTaxiSegment = function (taxiwaySegment) {
taxiwaySegment.setLatLngs(remainingNodes);
//taxiwaySegment.editor.refresh();
//taxiwaySegment.editor.reset();
if( splitOffNodes.length>1) {
if (splitOffNodes.length > 1) {
var polyline = new L.Polyline(splitOffNodes, { attributes: {} });
polyline.addTo(taxiwaySegment.editLayer.$parent.$parent.$refs.map.mapObject);
polyline.addTo(taxiwaySegment.editLayer.groundnetLayerGroup);
@ -251,7 +294,7 @@ const extendTaxiSegment = function (taxiwaySegment) {
if (Number(store.default.state.Editable.index) >= 0 &&
this.featureLookup[store.default.state.Editable.index] !== undefined) {
this.featureLookup[store.default.state.Editable.index].forEach(element => {
if(element.deselect !== undefined) {
if (element.deselect !== undefined) {
element.deselect();
}
});
@ -282,7 +325,7 @@ const extendTaxiSegment = function (taxiwaySegment) {
if (Number(store.default.state.Editable.index) >= 0 &&
this.featureLookup[store.default.state.Editable.index] !== undefined) {
this.featureLookup[store.default.state.Editable.index].forEach(element => {
if(element.deselect !== undefined) {
if (element.deselect !== undefined) {
element.deselect();
}
});
@ -316,11 +359,11 @@ const extendTaxiSegment = function (taxiwaySegment) {
if (parking.length > 0) {
parking[0].selectParking();
} else {
if( Number(event.vertex.latlng.glueindex) !== store.default.state.Editable.index) {
if (Number(event.vertex.latlng.glueindex) !== store.default.state.Editable.index) {
if (Number(store.default.state.Editable.index) >= 0 &&
this.featureLookup[store.default.state.Editable.index] !== undefined) {
this.featureLookup[store.default.state.Editable.index].forEach(element => {
if(element.deselect !== undefined) {
if (element.deselect !== undefined) {
element.deselect();
}
});
@ -329,7 +372,7 @@ const extendTaxiSegment = function (taxiwaySegment) {
}
var lines = this.featureLookup[event.vertex.latlng.glueindex].filter(n => n instanceof L.Polyline);
Vue.default.nextTick(function () {
lines.forEach( line => {
lines.forEach(line => {
line.selectVertex(store.default.state.Editable.index)
});
})
@ -339,6 +382,56 @@ const extendTaxiSegment = function (taxiwaySegment) {
}
});
};
taxiwaySegment.__proto__.expandArc = function (attributes) {
var isPushBackRoute = attributes.isPushBackRoute;
var ids = [];
var walkedNodes = [];
var segmentIds = [];
console.debug('start Walk');
ids = ids.concat(this.walkPushbackRoute(attributes.begin, walkedNodes, isPushBackRoute));
ids = ids.concat(this.walkPushbackRoute(attributes.end, walkedNodes, isPushBackRoute));
return ids;
}
taxiwaySegment.__proto__.walkPushbackRoute = function (index, walkedNodes, isPushBackRoute) {
console.debug('Walk Level');
walkedNodes.push(index)
var segmentIds = [];
var polyLines = this.featureLookup[index].filter(n => n instanceof L.Polyline);
if (polyLines===undefined || polyLines.length>2) {
console.debug('Walk ' + index + '\t' + polyLines.length);
return;
}
polyLines.forEach(l => {
segmentIds.push(l._leaflet_id);
console.debug('Walk Next ' + index + '\t' +
(walkedNodes.indexOf(index)<0) + '\t'+
l.begin + '\t'+
(walkedNodes.indexOf(Number(l.begin))<0) + '\t'+
l.end + '\t'+
(walkedNodes.indexOf(Number(l.end))<0) + '\t'+
l.options.attributes.direction + '\t' +
l.options.attributes.begin + '\t' +
l.options.attributes.end);
console.debug('Walk isPushBackRoute ' + l.options.attributes.isPushBackRoute + '\t' + isPushBackRoute + '\t' + (l.options.attributes.isPushBackRoute === isPushBackRoute));
if(l.options.attributes.isPushBackRoute === isPushBackRoute ) {
console.debug(Number(l.begin) === index && walkedNodes.indexOf(Number(l.end)) < 0);
if (Number(l.begin) === index && walkedNodes.indexOf(Number(l.end)) < 0) {
console.debug( 'Walk forward ' + l.options.attributes.direction );
segmentIds = segmentIds.concat(this.walkPushbackRoute(Number(l.end), walkedNodes, isPushBackRoute))
}
console.debug(Number(l.end) === index && walkedNodes.indexOf(Number(l.begin)) < 0);
if (Number(l.end) === index && walkedNodes.indexOf(Number(l.begin)) < 0 ) {
console.debug( 'Walk backward ' + l.options.attributes.direction );
segmentIds = segmentIds.concat(this.walkPushbackRoute(Number(l.begin), walkedNodes, isPushBackRoute))
}
}
});
return segmentIds;
}
/**
*
*/
@ -392,8 +485,38 @@ const extendTaxiSegment = function (taxiwaySegment) {
})
};
taxiwaySegment.__proto__.updateArrows = function (zoom) {
if( this._map === null) {
return;
}
if (this.options.attributes.direction === 'forward') {
this.setText(null);
if (zoom <= 16) {
this.setText(' >', { repeat: true, offset: 6, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 15px serif;' } })
} else if (zoom <= 19 ) {
this.setText(' > ', { repeat: true, offset: 7, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 20px serif;' } })
} else {
this.setText(' > ', { repeat: true, offset: 10, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 30px serif;' } })
}
} else if (this.options.attributes.direction === 'backward') {
this.setText(null);
if (zoom <= 16) {
this.setText(' <', { repeat: true, offset: 6, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 15px serif;' } })
} else if (zoom <= 19 ) {
this.setText(' < ', { repeat: true, offset: 7, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 20px serif;' } })
} else {
this.setText(' < ', { repeat: true, offset: 10, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 30px serif;' } })
}
} else {
this.setText(null);
}
}
taxiwaySegment.__proto__.updateStyle = function () {
var style = {};
if(!this.options.attributes) {
return;
}
if (this.options.attributes.selected) {
style.color = 'red';
} else if (this.options.attributes.isPushBackRoute) {
@ -403,13 +526,13 @@ const extendTaxiSegment = function (taxiwaySegment) {
style.color = '#3388ff';
}
this.setStyle(style);
if(this._map !== null) {
if (this._map !== null) {
if (this.options.attributes.direction === 'forward') {
this.setText(null);
this.setText(' > ', { repeat: true, offset: 10, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 30px serif;' } })
} else if (this.options.attributes.direction === 'backward') {
this.setText(null);
this.setText(' < ', { repeat: true, offset: 10, attributes: { fill: 'red', style: 'vertical-align: bottom; font-weight: bold; font: bold 30px serif;' } })
this.setText(' < ', { repeat: true, offset: 10, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 30px serif;' } })
} else {
this.setText(null);
}

View File

@ -1,141 +1,85 @@
/*
Copyright 2020 Keith Paterson
This file is part of FG Airports.
FG Airports is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
FG Airports is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with FG Airports. If not, see http://www.gnu.org/licenses/.
*/
/* eslint-disable */
const convert = require('geo-coordinates-parser');
const leaflet = require('leaflet');
const turf = require('@turf/turf');
const util = require('util');
const store = require('../store');
const fs = require('fs');
const path = require('path');
var $ = require('jquery');
L.Threshold = L.Circle.extend({
select() {
var style = {};
style['color'] = 'red';
this.setStyle(style);
},
addListeners: function () {
this.on('editable:drawing:move', function (event) {
console.log("Move : ", event);
console.log("Move : ", event.latlng);
// Is it the edit vertex (Middle) moving?
if(event.target.editor._resizeLatLng.__vertex._icon !== event.sourceTarget._element){
event.target.setLatLng(event.latlng);
event.target.updateVertexFromDirection();
this.follow(event.target.id, event);
}
else if(event.target.editor._resizeLatLng.__vertex._icon === event.sourceTarget._element) {
event.target.updateDirectionFromVertex();
event.target.updateVertexFromDirection();
}
});
/*
this.on('editable:vertex:drag', function (event) {
console.log("Drag : ", event);
});
*/
this.on('click', function (event) {
console.log("Click : " + event.target);
store.default.dispatch('setParking', event.target.options.attributes);
this.select();
this.unwatch = store.default.watch(
function (state) {
return state.Editable.data.parking;
},
() => {
if (event.target instanceof L.Threshold) {
event.target.setStyle({color : '#3388ff'});
this.unwatch();
}
}
,
{
deep: true //add this if u need to watch object properties change etc.
}
);
});
this.on('editable:vertex:clicked', function (event) {
console.log(this.featureLookup[event.vertex.glueindex]);
if(event.target.editor._resizeLatLng.__vertex._icon !== event.sourceTarget._element){
event.vertex._icon.style['background-color'] = 'red';
store.default.dispatch('setParking', event.target.options.attributes);
this.unwatch = store.default.watch(
function (state) {
return state.Editable.data.parking;
},
() => {
event.target.setStyle({color : '#3388ff'});
this.unwatch();
}
,
{
deep: true //add this if u need to watch object properties change etc.
}
);
/**http://wiki.openstreetmap.org/wiki/Zoom_levels*/
L.Threshold = L.Marker.extend({
options: {
zIndexOffset: 20000,
},
stripSVG: function(fName) {
var rx = /<\s*svg[^>]*>([\s\S]*)<\s*\/svg[^>]*>/gm;
var svg = fs.readFileSync(path.join(__static, '/', fName), 'utf8');
var svg2 = rx.exec(svg);
return svg2[0];
},
updateIcon : function(map) {
console.debug(`Lat Lng Threshold ${this.getLatLng()}`);
if(map !== null) {
var metersPP = this.metersPerPixel(map.getCenter().lat, map.getZoom());
console.debug('Old Meters per pixel ' + this.metersPP);
console.debug('New Meters per pixel ' + metersPP);
if(this._metersPP != metersPP) {
var pixelSize = (this.iconSize/2) / metersPP;
var scale = pixelSize/this.iconSize;
var offset = 0;//-(this.iconSize/2);
this.setIcon(L.divIcon({
iconSize: 64,
className: 'threshold-marker-icon',
html: `<div style=\'transform: translateX(${offset}px) translateY(${offset}px) scale(${scale}) rotate(${this.options.heading}deg); border: 1px red\'>${this.svg}</div>`,
}));
this.update(this.getLatLng());
console.debug();
this.setLatLng(this.getLatLng());
this._metersPP = metersPP;
}
});
this.on('editable:disable', function (event) {
event.target.removeDirection();
});
},
updateStyle: function () {
},
turfToLatLng: function (turfPoint) {
return {lat: turfPoint.geometry.coordinates[1], lng: turfPoint.geometry.coordinates[0]};
},
extensions: function (editLayer) {
this.createDirection();
if (typeof this.featureLookup[this.id] === 'undefined') {
this.featureLookup[this.id] = [];
}
this.featureLookup[this.id].push(this);
},
onAdd : function(map) {
var metersPP = this.metersPerPixel(map.getCenter().lat, map.getZoom());
this.updateIcon(map);
},
metersPerPixel: function (latitude, zoomLevel) {
var earthCircumference = 40075017;
var latitudeRadians = latitude * (Math.PI / 180);
return earthCircumference * Math.cos(latitudeRadians) / Math.pow(2, zoomLevel + 8);
},
_getLatRadius: function () {
return this._mRadius;
pixelValue: function (latitude, meters, zoomLevel) {
return meters / metersPerPixel(latitude, zoomLevel);
},
_getLngRadius: function () {
return this._mRadius;
},
});
var threshold = function (n, layerGroup) {
//console.log(n.attr('lat') + " " + n.attr('lon'));
L.Threshold.addInitHook(function(){
this.svg = this.stripSVG('FGA_THR.svg');
this.iconSize = 500;
});
//Builds a marker for a ai or multiplayer aircraft
var threshold = function (n, options) {
var latlon = convert(n.find('lat/text()').text() + " " + n.find('lon/text()').text());
//console.log(latlon.decimalLatitude);
//console.log(convert(n.attr('lat') + " " + n.attr('lon')).decimalLongitude);
const circle = new L.Threshold([latlon.decimalLatitude, latlon.decimalLongitude], { radius: 10, attributes: {} });
circle.on('editable:enable', function (event) {
// event.target.createDirection();
});
/*
<Parking index="2"
type="gate"
name="A6"
number=""
lat="N44 52.799"
lon="W93 11.947"
heading="-147.51"
radius="18"
pushBackRoute="541"
airlineCodes="VIR,KAL,DAL,KLM" />
*/
//circle.attributes = { type: n.attr('type'), name: n.attr('name'), radius: Number(n.attr('radius')), airlineCodes: n.attr('airlineCodes'), heading: Number(n.attr('heading')) };
var heading = n.find('hdg-deg/text()').text();
$.each( n.attrs, function( key, value ) {
console.log( '$', circle.id, key , value);
if(isNaN(value))
circle.options.attributes[ key ] = value;
else
circle.options.attributes[ key ] = Number( value);
});
circle.addTo(layerGroup);
return circle;
var marker = new L.Threshold([latlon.decimalLatitude, latlon.decimalLongitude], {heading: heading});
return marker;
}
module.exports = threshold;

View File

@ -0,0 +1,84 @@
/*
Copyright 2020 Keith Paterson
This file is part of FG Airports.
FG Airports is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
FG Airports is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with FG Airports. If not, see http://www.gnu.org/licenses/.
*/
/* eslint-disable */
const convert = require('geo-coordinates-parser');
const fs = require('fs');
const path = require('path');
/**http://wiki.openstreetmap.org/wiki/Zoom_levels*/
L.TowerMarker = L.Marker.extend({
options: {
zIndexOffset: 10000,
},
initialize: function (latlng, options) {
L.Marker.prototype.initialize(latlng, options);
L.Util.setOptions(this, options);
this.svg = this.stripSVG('tower.svg');
this.isDragging = false;
},
updateProperties: function(properties) {
this.heading = properties.heading;
this.updateIcon();
},
stripSVG: function(fName) {
var rx = /<\s*svg[^>]*>([\s\S]*)<\s*\/svg[^>]*>/gm;
var svg = fs.readFileSync(path.join(__static, '/', fName), 'utf8');
var svg2 = rx.exec(svg);
return svg2[0];
},
updateIcon : function(map) {
if(map !== null) {
var metersPP = this.metersPerPixel(map.getCenter().lat, map.getZoom());
if(this._metersPP != metersPP) {
console.debug('Meters per pixel ' + metersPP);
var pixelSize = 32 / metersPP;
var scale = pixelSize/64;
var offset = -(64/2);
this.setIcon(L.divIcon({
iconSize: 64,
className: 'tower-marker-icon',
html: `<div style=\'transform: translateX(${offset}px) translateY(${offset}px) scale(${scale}); border: 1px red\'>${this.svg}</div>`,
}));
this._metersPP = metersPP;
}
}
},
onAdd : function(map) {
var metersPP = this.metersPerPixel(map.getCenter().lat, map.getZoom());
console.debug('Meters per pixel ' + metersPP);
this.updateIcon(map);
},
metersPerPixel: function (latitude, zoomLevel) {
var earthCircumference = 40075017;
var latitudeRadians = latitude * (Math.PI / 180);
return earthCircumference * Math.cos(latitudeRadians) / Math.pow(2, zoomLevel + 8);
},
pixelValue: function (latitude, meters, zoomLevel) {
return meters / metersPerPixel(latitude, zoomLevel);
},
});
//Builds a marker for a ai or multiplayer aircraft
var tower = function (n, options) {
var latlon = convert(n.find('lat/text()').text() + " " + n.find('lon/text()').text());
return new L.TowerMarker([latlon.decimalLatitude, latlon.decimalLongitude], options);
}
module.exports = tower;

View File

@ -60,6 +60,11 @@ function walkPushbackRoute (index, walkedNodes, pushBackNodes) {
exports.writeGroundnetXML = function (fDir, icao, featureList) {
try {
try { fs.mkdirSync(path.join(fDir), { recursive: true })} catch (err) { }
try { fs.mkdirSync(path.join(fDir, icao[0]),{ recursive: true })} catch (err) { }
try { fs.mkdirSync(path.join(fDir, icao[0], icao[1]), { recursive: true })} catch (err) { }
try { fs.mkdirSync(path.join(fDir, icao[0], icao[1], icao[2]), { recursive: true })} catch (err) { }
var f = path.join(fDir, icao[0], icao[1], icao[2], icao + '.groundnet.new.xml');
var fBak = path.join(fDir, icao[0], icao[1], icao[2], icao + '.groundnet.bak.xml');
@ -201,7 +206,12 @@ var mapParkings = function (o) {
console.debug(o.options.attributes.airlineCodes);
parking['@airlineCodes'] = o.options.attributes.airlineCodes;
}
if(o.options.attributes.number) {
if(o.options.attributes.number !== undefined &&
typeof o.options.attributes.number === 'number' || (
typeof o.options.attributes.number === 'string' &&
o.options.attributes.number.trim() !== ''
)
) {
console.debug(o.options.attributes.number);
parking['@number'] = o.options.attributes.number;
}

View File

@ -50,8 +50,16 @@ exports.readThresholdXML = function (fDir, icao, force) {
thresholdNodes.map(n => {
var circle = threshold(n, layerGroup);
features.push(circle);
var icon = threshold(n);
icon.addTo(layerGroup);
var latlon = convert(n.find('lat/text()').text() + " " + n.find('lon/text()').text());
/*
var marker = new L.Circle([latlon.decimalLatitude, latlon.decimalLongitude], 5);
marker.addTo(layerGroup);
*/
// features.push(circle);
}).sort();
return layerGroup;

View File

@ -0,0 +1,83 @@
/*
Copyright 2020 Keith Paterson
This file is part of FG Airports.
FG Airports is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
FG Airports is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with FG Airports. If not, see http://www.gnu.org/licenses/.
*/
/* eslint-disable */
const fs = require('fs');
const path = require('path');
var xamel = require('xamel');
const convert = require('geo-coordinates-parser');
const store = require('../store');
const util = require('util');
const tower = require('./Tower.js');
var $ = require('jquery');
exports.readTowerXML = function (fDir, icao, force) {
try {
var layerGroup = L.layerGroup();
layerGroup.maxId = 0;
var f = path.join(fDir, icao[0], icao[1], icao[2], icao + '.twr.xml');
var fNew = path.join(fDir, icao[0], icao[1], icao[2], icao + '.twr.new.xml');
if (f == null || !fs.existsSync(f))
return;
if (fNew != null && fs.existsSync(fNew) && !force) {
f = fNew;
}
var features = new Array();
// map.on("editable:vertex:new", function (event) {
// log.console("Add vertex " + event);
// });
var xmlGroundnet = fs.readFileSync(f, 'utf8').toString();
xamel.parse(xmlGroundnet, function (err, xml) {
console.debug("parsed " + path.basename(f));
if (err !== null) {
console.error("Error in " + airline);
throw err;
}
var towerNodes = xml.find('PropertyList/tower/twr');
console.log("Tower " + towerNodes.length);
var merged = new Array();
var nodesLookup = {};
featureLookup = [];
towerNodes.map(n => {
var towerIcon = tower(n, layerGroup);
towerIcon.addTo(layerGroup);
var latlon = convert(n.find('lat/text()').text() + " " + n.find('lon/text()').text());
/*
var marker = new L.Circle([latlon.decimalLatitude, latlon.decimalLongitude], 5);
marker.addTo(layerGroup);
*/
features.push(towerIcon);
}).sort();
return layerGroup;
});
// var jsonAirports = JSON.parse(geoJSON);
// return jsonAirports;
} catch (error) {
console.error(error);
}
return layerGroup;
};

View File

@ -1,15 +1,28 @@
/**
Copyright 2020 Keith Paterson
This file is part of FG Airports.
FG Airports is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
FG Airports is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with FG Airports. If not, see http://www.gnu.org/licenses/.
*/
import Vue from 'vue'
const state = {
type: 'none',
index: 'none',
editing: false,
data: {airports: {}, parking: {}, arc: {}, node: {}, runway: {}}
data: {airports: {}, parking: {}, arc: {}, multiarc: {}, node: {}, runway: {}}
}
const SET_EDIT_AIRPORT = 'SET_EDIT_AIRPORT'
const SET_EDIT_PARKING = 'SET_EDIT_PARKING'
const SET_EDIT_ARC = 'SET_EDIT_ARC'
const SET_EDIT_MULTI_ARC = 'SET_EDIT_MULTI_ARC'
const SET_EDIT_RUNWAY = 'SET_EDIT_RUNWAY'
const mutations = {
@ -62,6 +75,34 @@ const mutations = {
Vue.set(state, 'index', arc.index)
Vue.set(state, 'type', 'arc')
},
SET_EDIT_MULTI_ARC (state, arc) {
if (arc === undefined) {
return
}
if (!state.data || state.type !== 'multiarc') {
Vue.set(state, 'data', {multiarc: {}})
}
Vue.set(state.data.multiarc, 'isPushBackRoute', arc.isPushBackRoute)
Vue.set(state.data.multiarc, 'direction', arc.direction)
if (state.data.multiarc.name === undefined) {
Vue.set(state.data.multiarc, 'name', '')
}
Vue.set(state, 'index', arc.index)
Vue.set(state, 'type', 'multiarc')
},
'SET_EDIT_MULTI_ARC_IDS' (state, arcs) {
if (arcs === undefined) {
return
}
if (!state.data || state.type !== 'multiarc') {
return
}
if (state.data.multiarc.ids === undefined) {
state.data.multiarc.ids = []
}
state.data.multiarc.ids = state.data.multiarc.ids.concat(arcs.filter(n => n).filter((v, i, a) => a.indexOf(v) === i))
},
'SET_EDIT_PARKING_NAME' (state, parkingName) {
Vue.set(state.data.parking, 'name', parkingName)
},
@ -91,13 +132,25 @@ const mutations = {
Vue.set(state.data.parking, 'coords', coords)
},
'SET_EDIT_ARC_NAME' (state, arcName) {
if (state.type === 'arc') {
Vue.set(state.data.arc, 'name', arcName)
} else {
Vue.set(state.data.multiarc, 'name', arcName)
}
},
'SET_EDIT_PUSHBACK' (state, isPushBackRoute) {
if (state.type === 'arc') {
Vue.set(state.data.arc, 'isPushBackRoute', Number(isPushBackRoute))
} else {
Vue.set(state.data.multiarc, 'isPushBackRoute', Number(isPushBackRoute))
}
},
'SET_EDIT_DIRECTION' (state, direction) {
if (state.type === 'arc') {
Vue.set(state.data.arc, 'direction', direction)
} else {
Vue.set(state.data.multiarc, 'direction', direction)
}
},
'SET_EDIT_HOLDPOINTTYPE' (state, holdPointType) {
Vue.set(state.data.node, 'holdPointType', holdPointType)
@ -132,6 +185,12 @@ const actions = {
async setArc (context, arc) {
context.commit(SET_EDIT_ARC, arc)
},
async setMultiArc (context, arc) {
context.commit(SET_EDIT_MULTI_ARC, arc)
},
async setMultiArcIds (context, arc) {
context.commit('SET_EDIT_MULTI_ARC_IDS', arc)
},
async setNode (context, node) {
context.commit('SET_EDIT_NODE', node.attributes)
context.commit('SET_EDIT_NODE_COORDS', node.lat.toFixed(6) + ' ' + node.lng.toFixed(6))

View File

@ -31,9 +31,15 @@ const actions = {
context.commit('SET_ICAO_LOADING', p)
},
async setGroundnetLoaded (context, p) {
if (typeof p !== 'boolean') {
console.error('Not Boolean')
}
context.commit('SET_GROUNDNET_LOADED', p)
},
async setPavementLoaded (context, p) {
if (typeof p !== 'boolean') {
console.error('Not Boolean')
}
context.commit('SET_PAVEMENT_LOADED', p)
}
}

View File

@ -186,6 +186,9 @@ function scanTrafficIntoDB(p, features) {
function traverseDir(dir) {
var result = [];
if(!fs.existsSync(dir)) {
return result;
}
fs.readdirSync(dir).forEach(file => {
let fullPath = path.join(dir, file);
if (fs.lstatSync(fullPath).isDirectory()) {

2
static/FGA_ACT_A_GA.svg Normal file
View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="150mm" height="150mm" version="1.1" viewBox="0 0 150 150" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-1.6394e-5 -147)"><g transform="translate(-512.5 -153)"><path d="m587.5 347.75c-0.32736 0-0.75863 2.023-0.97757 3.043 0 0-8.7023-0.47356-8.7023 0.14107 0 0.61461 8.733 0.36873 8.733 0.36873 0.0812 0.14151 0.22163 0.15914 0.368 0.18528v0.21306c-0.57176 0.16009-1.4739 0.31231-2.5099 0.41186-1.036 0.0995-1.1332 0.93371-1.1332 0.93371-0.70455 4.8918-0.96276 10.026-1.2071 14.632-0.012 0.0118-0.0165 1.6e-4 -0.0369 9e-3l-20.112 2e-3 -27.221 1.9869c-2.1208 0.16639-2.2014 1.5529-2.2014 3.2272v8.0906l29.858 3.5196 19.67 0.0146c1.2567 9.6974 3.6713 28.109 3.6713 28.109l-12.803 2.1075c-0.75926 0.18181-1.8746 0.23703-2.1181 1.0313-0.3756 1.9795-0.35641 4.2182-0.24741 6.0605 0.0369 0.68858 0.16248 1.2114 0.8672 1.354l13.439 2.401c0.39078 0.0865 0.49893-0.13326 0.58873-0.48422l1.3408-4.2669s-0.081 7.3888 0.73272 9.0111c0.81369-1.6224 0.73271-9.0111 0.73271-9.0111l1.3412 4.2669c0.0898 0.35096 0.19795 0.57077 0.58874 0.48422l13.439-2.401c0.70472-0.14253 0.83032-0.6654 0.8672-1.354 0.10899-1.8424 0.12819-4.081-0.24741-6.0605-0.24351-0.79425-1.3589-0.84947-2.1181-1.0313l-12.803-2.1075s2.4149-18.412 3.6716-28.109l19.67-0.0146 29.859-3.5196v-8.0906c5.8e-4 -1.6743-0.081-3.0608-2.2018-3.2272l-27.221-1.9869-20.112-2e-3c-0.0204-9e-3 -0.0249 3e-3 -0.0369-9e-3 -0.2443-4.6057-0.50251-9.7399-1.2071-14.632 0 0-0.0972-0.83417-1.1332-0.93371-1.036-0.0996-1.9381-0.25177-2.5099-0.41186v-0.21307c0.14636-0.0262 0.28682-0.0438 0.368-0.18528 0 0 8.733 0.24589 8.733-0.36873s-8.7023-0.14106-8.7023-0.14106c-0.21894-1.0201-0.65058-3.0431-0.97793-3.0431zm0 9.0766c0.34605 0 0.71407-1.3e-4 0.71408 0.5394v2.36c0 0.54212-0.36803 0.54196-0.71408 0.54196-0.34606 0-0.7192 1.6e-4 -0.7192-0.54196v-2.36c-1e-5 -0.53953 0.37314-0.5394 0.7192-0.5394zm-12.73 16.475c0.34605 0 0.71407-1.3e-4 0.71407 0.5394v2.36c0 0.54211-0.36802 0.54196-0.71407 0.54196-0.34606 0-0.7192 1.5e-4 -0.7192-0.54196v-2.36c0-0.53953 0.37314-0.5394 0.7192-0.5394zm25.474 0c0.34606 0 0.71408-1.3e-4 0.71408 0.5394v2.36c0 0.54211-0.36802 0.54196-0.71408 0.54196-0.34605 0-0.71919 1.5e-4 -0.71919-0.54196v-2.36c-1e-5 -0.53953 0.37314-0.5394 0.71919-0.5394z" fill="#3296ff"/><circle cx="587.5" cy="375" r="74.595" fill="none" stroke="#3296ff" stroke-linecap="square" stroke-linejoin="round" stroke-width=".811" style="paint-order:normal"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="280mm" height="282.66mm" version="1.1" viewBox="0 0 280 282.66" xmlns="http://www.w3.org/2000/svg"><g transform="translate(35 -7.171)"><g transform="translate(-7.6294e-6 7.3444)"><g transform="matrix(4.5516 0 0 4.5516 -372.53 -527.39)" fill="#3296ff"><path transform="matrix(.26458 0 0 .26458 -7.9725e-5 4.7925e-5)" d="m396.53 449.99c-6.703 0-12.091 16.285-12.119 29.002l-0.17578 54.354-2.8828 7.209-14.512-0.18945c0.6477-4.764 1.2976-11.043-1.4473-15.457l-0.0469-1.3477 14.395 0.83985 0.16797-1.9668-14.578 0.97461c0-1.4239-1.0254-4.1602-2.3457-4.1602-1.4366 0-2.2472 2.4804-2.4375 4.1211l-14.088-1.1582-4e-3 2.4609 14.047-0.9668-0.1914 1.3164c-2.3109 4.8272-1.8613 10.199-0.92774 15.412-46.681 3.307-70.422 5.1355-71.252 5.2051-0.82972 0.0695-1.8463 0.90433-1.9707 2.293-0.0556 0.59954-0.16605 0.90065-0.33008 0.90039-0.16479-1e-3 -0.35633 0.0276-0.57422 0.082-0.21808 0.0533-0.43767 0.32575-0.6582 0.81641-0.67616 2.9741-0.27076 5.9302-0.0977 8.7734 0.0552 0.10885 12.16 0.73137 36.314 1.8672 24.156 1.1349 36.316 1.7029 36.48 1.7031 0.16403 3.7e-4 6.0384 0.17301 24.84 0.20703l2.123 5.0859c-0.0302 21.998 0.0965 58.62 7.0059 86.129-15.285 2.3628-23.055 3.6526-23.314 3.8594-2.0877 2.7596-2.3172 6.879-1.8203 9.998 0.0556 1e-3 4.4001 0.33632 13.033 1.0059l13.115 0.92578c0.10923-0.0544 1.4785-2.0469 1.4785-2.0469 0.21947 1.7517 0.2277 5.2639 2.7734 5.2676h2e-3c2.5457-4e-3 2.552-3.5159 2.7715-5.2676 0 0 1.3693 1.9924 1.4785 2.0469l13.115-0.92578c8.6331-0.66954 12.978-1.0047 13.033-1.0059 0.49693-3.119 0.26734-7.2384-1.8203-9.998-0.25928-0.20674-8.0293-1.4966-23.314-3.8594 6.9093-27.509 7.0361-64.131 7.0059-86.129l2.123-5.0859c18.801-0.034 24.678-0.20666 24.842-0.20703 0.16404-2.3e-4 12.323-0.56825 36.479-1.7031 24.155-1.1358 36.259-1.7583 36.314-1.8672 0.17311-2.8432 0.5785-5.7993-0.0976-8.7734-0.22035-0.49066-0.44013-0.76312-0.65821-0.81641-0.21807-0.0544-0.40943-0.0832-0.57421-0.082-0.16404 2.6e-4 -0.27257-0.30085-0.32813-0.90039-0.12435-1.3886-1.141-2.2234-1.9707-2.293-0.82972-0.0695-24.573-1.8981-71.254-5.2051 0.93358-5.2134 1.3832-10.585-0.92773-15.412l-0.19141-1.3164 14.047 0.9668-4e-3 -2.4609-14.088 1.1582c-0.19049-1.6407-1.0009-4.1211-2.4375-4.1211-1.3203 0-2.3457 2.7363-2.3457 4.1602l-14.576-0.97461 0.16602 1.9668 14.395-0.83985-0.0469 1.3477c-2.7449 4.4137-2.095 10.693-1.4473 15.457l-14.512 0.18945-2.8809-7.209-0.17578-54.354c0-12.782-5.4181-29.002-12.121-29.002zm-2.207 19.031h1.6133v4.8184h-1.6133zm2.8008 0h1.6133v4.8184h-1.6133zm-20.578 81.467h2.7774v7.1152h-2.7774zm3.8789 0h2.7773v7.1152h-2.7773zm29.434 0h2.7774v7.1152h-2.7774zm3.8789 0h2.7773v7.1152h-2.7773z" fill="#3296ff"/></g><circle cx="105" cy="139.83" r="139.18" fill="none" stroke="#3296ff" stroke-linecap="square" stroke-linejoin="round" stroke-width="1.6438" style="paint-order:normal"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="280mm" height="311.54mm" version="1.1" viewBox="0 0 280 311.54" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-6.4969e-6 14.543)"><circle cx="140" cy="141.28" r="139.36" fill="none" stroke="#3296ff" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="4.3333" stroke-width="1.2759" style="paint-order:normal"/><path d="m152.63 24.911c-0.0267-25.744-10.66-39.454-12.634-39.454h1e-5c-1.9741 0-12.608 13.71-12.634 39.454l0.0182 79.957-1.6403 1.3481s-84.993 49.186-89.398 51.752-4.5756 5.1873-4.5756 5.1873-7.5179 14.841-7.7484 15.302c-0.23052 0.4615-0.27144 1.1507-0.27144 1.1507l0.1078 2.3443s6.6825-7.4591 6.8393-7.6432c0.1568-0.18415 0.32861-0.34095 0.7442-0.33769 0.41558 3e-3 1.0215 0.0362 1.4196-0.32729 0.93562-1.1932 2.1371-2.6676 3.9093-3.1924 1.7722-0.52482 39.634-11.689 59.608-17.581l31.015-1.8624v47.86l-0.95849 1.5429h-1.3832c-0.24979-1.7755-0.85068-1.9326-0.85068-1.9326l-11.633 0.12468s-1.2585 0.79803-1.2585 6.6315c0 10.609 1.3118 13.973 1.3118 13.973s0.30131 0.16754 1.2416 0.16754l2.5625 10.064s0.46106 0.0701 0.9494 0.0701l1.7637 5.2665 0.71822-0.0351 1.3923-5.3548c0.55067 0 0.99225-0.16884 0.99225-0.16884l0.0714-0.44288 9.2212 6.0198 5.3548 27.175s-33.731 22.555-34.623 23.158c-0.89108 0.60283-1.4159 2.6639-1.565 4.3768l-0.65199 7.4952 38.872-12.307 1.0494 5.3873 1.1104-5.3873 38.871 12.307-0.65198-7.4952c-0.14909-1.7129-0.67393-3.774-1.565-4.3768-0.8911-0.60285-34.623-23.158-34.623-23.158l5.3561-27.175 9.2199-6.0198 0.0714 0.44288s0.4429 0.16884 0.99356 0.16884l1.391 5.3548 0.71822 0.0351 1.765-5.2665c0.48833 0 0.9481-0.0701 0.9481-0.0701l2.5625-10.064c0.9403 0 1.2416-0.16754 1.2416-0.16754s1.3118-3.3645 1.3118-13.973c0-5.8335-1.2585-6.6315-1.2585-6.6315l-11.633-0.12468s-0.6009 0.15707-0.8507 1.9326h-1.3832l-0.95719-1.5429v-47.86l31.013 1.8624c19.974 5.8921 57.836 17.057 59.608 17.581 1.7722 0.5248 2.9749 1.9992 3.9106 3.1924 0.39808 0.36352 1.0027 0.33031 1.4182 0.32729 0.4156-3e-3 0.58741 0.15355 0.74421 0.33769 0.1568 0.18415 6.8393 7.6432 6.8393 7.6432l0.10781-2.3443s-0.0397-0.68921-0.27015-1.1507c-0.23051-0.4615-7.7497-15.302-7.7497-15.302s-0.16886-2.6209-4.5743-5.1873c-4.4054-2.5664-89.399-51.752-89.399-51.752l-1.639-1.3481 0.0169-79.957m-34.454 111.65c0.78911 0 1.6055 0.23981 1.6053 1.2949v6.738c2.3e-4 0.93982-0.81617 1.2949-1.6053 1.2949-0.78909 0-1.6053-0.35505-1.6053-1.2949v-6.738c0-1.0551 0.81618-1.2949 1.6053-1.2949zm5.0002 0c0.78909 0 1.6055 0.23981 1.6053 1.2949v6.738c2.4e-4 0.93982-0.81619 1.2949-1.6053 1.2949s-1.6053-0.35505-1.6053-1.2949v-6.738c0-1.0551 0.81618-1.2949 1.6053-1.2949zm33.577 0c0.78909 0 1.6053 0.23981 1.6053 1.2949v6.738c0 0.93982-0.81618 1.2949-1.6053 1.2949-0.7891 0-1.6055-0.35505-1.6053-1.2949v-6.738c-2.4e-4 -1.055 0.81618-1.2949 1.6053-1.2949zm5.0002 0c0.78909 1e-5 1.6053 0.2398 1.6053 1.2949v6.738c0 0.93982-0.81618 1.2949-1.6053 1.2949s-1.6055-0.35505-1.6053-1.2949v-6.738c-2.4e-4 -1.0551 0.81619-1.2949 1.6053-1.2949z" fill="#3296ff"/></g></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

3
static/FGA_ACT_C.svg Normal file
View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="360mm" height="369.09mm" version="1.1" viewBox="0 0 360 369.09" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><g transform="translate(75 36.046)"><g transform="translate(-65.5 -28.331)"><path d="m170.5-0.026086c-7.0846 9.35e-6 -19.026 24.031-19.062 58.205l0.0362 54.388-1.9176 10.818s-0.10598 1.4555-0.99653 1.9124-25.868 13.39-25.868 13.39c0.89235-6.9871 2.094-27.847-0.25947-27.847h-15.911c-3.162 1e-5 -2.337 31.287-0.34733 31.287h1.0188l1.163 3.968-94.45 48.717c-4.8538 2.6647-11.085 6.7435-12.179 12.611l-1.7264 14.181v2.7208l1.8819-8.6075c0.26207-1.101 1.0968-1.7912 2.1833-2.0856l48.418-14.553 1.5222 5.4184 1.2943-6.2934 32.906-10.202 1.2591 4.6033 1.4023-5.4184-0.02378-0.0238 17.489-5.4184h13.63v0.0238l1.1754 4.6751 1.1268-4.6989 27.248-0.014 0.0594 84.392c0.23612 14.268 3.6729 28.282 6.066 42.28 0 0-0.48489 3.4026-4.915 6.2216 0 0-36.324 23.321-38.756 24.91-2.4318 1.5884-3.5142 3.8978-3.5142 8.6897l0.0961 5.1067 52.194-11.616c1.3933 6.3589 5.2092 17.812 5.3703 18.305 0.16114 0.49226 0.88696 1.043 0.88696 1.043s0.44043 0.31323 0.75567 0.31323h1.486c0.31524 0 0.75567-0.31323 0.75567-0.31323s0.72582-0.55079 0.88695-1.043c0.16114-0.49225 3.977-11.946 5.3703-18.305l52.194 11.616 0.0956-5.1067c0-4.7918-1.0819-7.1013-3.5137-8.6897s-38.756-24.91-38.756-24.91c-4.4301-2.8189-4.915-6.2216-4.915-6.2216 2.3931-13.998 5.8299-28.012 6.066-42.28l0.06-84.392 27.248 0.014 1.1273 4.6989 1.1748-4.6751v-0.0238h13.63l17.49 5.4184-0.0238 0.0238 1.4023 5.4184 1.2586-4.6033 32.906 10.202 1.2948 6.2934 1.5222-5.4184 48.418 14.553c1.0865 0.29433 1.9212 0.98458 2.1833 2.0856l1.8824 8.6075v-2.7208l-1.7263-14.181c-1.0936-5.8671-7.3253-9.946-12.179-12.611l-94.45-48.717 1.163-3.968h1.0188c1.9896 0 2.8147-31.287-0.34734-31.287h-15.911c-2.3535 0-1.1518 20.86-0.25947 27.847 0 0-24.977-12.933-25.867-13.39-0.89055-0.45697-0.99705-1.9124-0.99705-1.9124l-1.9176-10.818 0.0362-54.388c-0.03593-34.174-11.977-58.205-19.062-58.205zm-2.373 45.661c0.8389 4.8e-5 1.0544 0.39604 1.0544 1.0673v3.692c0 0.68329-0.21552 1.0792-1.0544 1.0792-0.8389-6e-6 -1.0441-0.39594-1.0441-1.0792v-3.692c0-0.6713 0.20519-1.0673 1.0441-1.0673zm4.7454 0c0.8389 4.8e-5 1.0446 0.39604 1.0446 1.0673v3.692c0 0.68329-0.2057 1.0792-1.0446 1.0792-0.8389-6e-6 -1.0539-0.39594-1.0539-1.0792v-3.692c0-0.6713 0.215-1.0673 1.0539-1.0673zm-46.369 122.62c0.87915-2e-3 1.44 0.52759 1.44 1.4746v5.0349c0 0.82604-0.55805 1.4757-1.44 1.4757-0.88197 0-1.4379-0.64964-1.4379-1.4757v-5.0349c-2e-5 -0.93514 0.55878-1.4724 1.4379-1.4746zm87.992 0c0.87916 2e-3 1.4385 0.5395 1.4385 1.4746v5.0349c0 0.82604-0.55649 1.4757-1.4385 1.4757s-1.44-0.64964-1.44-1.4757v-5.0349c5e-5 -0.94705 0.56085-1.4766 1.44-1.4746zm-81.29 0.0476c0.87915-2e-3 1.4394 0.52759 1.4395 1.4746v5.0349c0 0.82603-0.55752 1.4757-1.4395 1.4757s-1.4385-0.64964-1.4385-1.4757v-5.0349c-2e-5 -0.93514 0.5593-1.4724 1.4385-1.4746zm74.589 0c0.87915 2e-3 1.4385 0.5395 1.4384 1.4746v5.0349c0 0.82603-0.55649 1.4757-1.4384 1.4757-0.88197 0-1.44-0.64964-1.44-1.4757v-5.0349c5e-5 -0.94705 0.56085-1.4766 1.44-1.4746z" fill="#3296ff" fill-rule="evenodd"/><circle cx="170.5" cy="172.29" r="179.31" fill="none" stroke="#3296ff" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="3" stroke-width="1.371" style="paint-order:normal"/></g></g></svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

2
static/FGA_ACT_D.svg Normal file
View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="5203mm" height="5463.5mm" version="1.1" viewBox="0 0 5203 5463.5" xmlns="http://www.w3.org/2000/svg"><g transform="translate(2496.5 2583.2)"><path d="m103.62-2580.1c-130.08 0-255.75 434.93-255.75 588.23l-0.125 1240.4s-55.621 87.016-114.96 127.88c-59.342 40.86-294.12 203.78-294.12 203.78l12.788-24.751s2e-4 -204.6 0-255.75c-1e-4 -51.151-12.788-63.938-25.575-63.938-12.787 1e-4 -204.6 0-204.6 0-25.575 0-38.363 12.788-38.363 63.938 0 0-0.399 257.75 0 281.33 0.399 23.577 12.788 51.151 12.788 51.151h25.575l-0.62501 98.405s-1405.1 961.43-1444.4 988.54c-39.261 27.115-51.15 42.459-51.15 63.938v217.39l575.44-242.96 869.56-306.9 179.03-51.151 498.74-62.464s-0.736 1167.2-0.02 1290.1c0.706 122.92 63.489 432.48 63.489 432.48l-702.87 539.38-38.363 51.15v166.24l869.78-212.97 12.563 46.73 25.575 89.513 12.788 102.3 12.788 38.363 12.788-38.363 12.788-102.3 25.575-89.513 12.563-46.73 869.78 212.97v-166.24l-38.363-51.15-702.87-539.38s62.783-309.56 63.488-432.48c0.711-122.92-0.05-1290.1-0.05-1290.1l498.77 62.464 179.03 51.151 869.56 306.9 575.44 242.96v-217.39c0-21.479-11.889-36.823-51.151-63.938-39.261-27.115-1444.4-988.54-1444.4-988.54l-0.60001-98.405h25.575s12.389-27.573 12.788-51.151c0.399-23.577 0-281.33 0-281.33 0-51.15-12.788-63.938-38.363-63.938 0 0-191.81 1e-4 -204.6 0-12.788-1e-4 -25.575 12.788-25.575 63.938-2e-4 51.151 0 255.75 0 255.75l12.788 24.751s-234.77-162.92-294.12-203.78c-59.342-40.86-114.99-127.88-114.99-127.88l-0.104-1240.4c-1e-4 -153.3-125.68-588.23-255.75-588.23zm-38.363 409.2c6.347 2e-4 12.787 5.5342 12.787 11.064v67.809c0 5.4289-6.4405 10.865-12.787 10.864-6.3906 2e-4 -12.788-5.4355-12.788-10.864v-67.809c1e-4 -5.5302 6.3971-11.013 12.788-11.064zm76.726 0c6.3906 0.05 12.788 5.5342 12.788 11.064v67.809c-1e-4 5.4289-6.397 10.865-12.788 10.864-6.347 2e-4 -12.788-5.4355-12.788-10.864v-67.809c0-5.5302 6.4406-11.064 12.788-11.064zm-575.44 2186.7h25.575c6.347 2.01e-4 12.788 6.393 12.788 12.788v76.726c0 6.3929-6.4406 12.788-12.788 12.788h-25.575c-6.3906 1e-4 -12.787-6.3947-12.788-12.788v-76.726c1e-4 -6.3947 6.397-12.736 12.788-12.788zm115.09 0h25.575c6.347 2.01e-4 12.788 6.393 12.788 12.788v76.726c0 6.3929-6.4406 12.788-12.788 12.788h-25.575c-6.3906 1e-4 -12.787-6.3947-12.788-12.788v-76.726c2e-4 -6.3947 6.3971-12.736 12.788-12.788zm818.41 0h25.575c6.3907 0.05 12.788 6.393 12.788 12.788v76.726c-2e-4 6.3929-6.397 12.788-12.788 12.788h-25.575c-6.347 1e-4 -12.788-6.3947-12.788-12.788v-76.726c0-6.3947 6.4406-12.787 12.788-12.788zm115.09 0h25.575c6.3906 0.05 12.788 6.393 12.788 12.788v76.726c-1e-4 6.3929-6.3971 12.788-12.788 12.788h-25.575c-6.347 1e-4 -12.788-6.3947-12.788-12.788v-76.726c0-6.3947 6.4406-12.787 12.788-12.788zm-1048.6 140.66h25.575c6.347 1e-4 12.788 6.3929 12.788 12.787v76.726c0 6.3929-6.4406 12.788-12.788 12.788h-25.575c-6.3906 1e-4 -12.787-6.3947-12.788-12.788v-76.726c1e-4 -6.3946 6.397-12.736 12.788-12.787zm115.09 0h25.575c6.347 1e-4 12.788 6.3929 12.788 12.787v76.726c0 6.3929-6.4406 12.788-12.788 12.788h-25.575c-6.3906 1e-4 -12.787-6.3947-12.788-12.788v-76.726c2e-4 -6.3946 6.3971-12.736 12.788-12.787zm818.41 0h25.575c6.3907 0.05 12.788 6.3929 12.788 12.787v76.726c-2e-4 6.3929-6.397 12.788-12.788 12.788h-25.575c-6.347 1e-4 -12.788-6.3947-12.788-12.788v-76.726c0-6.3946 6.4406-12.787 12.788-12.787zm115.09 0h25.575c6.3906 0.05 12.788 6.3929 12.788 12.787v76.726c-1e-4 6.3929-6.3971 12.788-12.788 12.788h-25.575c-6.347 1e-4 -12.788-6.3947-12.788-12.788v-76.726c0-6.3946 6.4406-12.787 12.788-12.787z" fill="#3296ff" fill-rule="evenodd"/><circle cx="105" cy="135.8" r="2582.6" fill="none" stroke="#3296ff" stroke-linecap="square" stroke-linejoin="round" stroke-width="37.746" style="paint-order:normal"/></g></svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

2
static/FGA_ACT_E.svg Normal file
View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="660mm" height="735.62mm" version="1.1" viewBox="0 0 660 735.62" xmlns="http://www.w3.org/2000/svg"><g transform="translate(227.07 219.31)"><g transform="translate(-220.16 -219.35)"><path d="m323.98 0.041596c-12.621 1.1404-32.35 58.556-32.35 95.304v172.91l-46.402 31.844c1.7124-7.7226 3.623-25.137-0.66208-43.984h-33.315c-3.6679 12.285-5.2993 33.094 0.0391 51.47l3.3026 0.0898 3.0428 11.261c-67.538 46.949-135.82 92.856-204.08 138.75-2.0153 1.3847-2.119 1.8573-2.119 1.8573l-11.437 22.93v8.1344l26.342-17.935 71.254-28.565 34-11.466 0.69527 3.201 1.5605-3.992 51.247-17.319 1.0976 3.6346 1.041-4.3845 29.414-9.9624 21.011-3.2655 0.82027 6e-3 1.3632 4.7322 1.7772-4.7341 50.009-0.0273s-0.0109 126.27 0 148.94c0.0156 32.451 7.5281 73.581 8.5445 79.039s3.3484 11.282-3.1483 16.589c-6.4967 5.3071-71.763 58.406-77.1 62.77-5.3362 4.364-4.9704 10.253-4.7556 11.913s1.9276 15.884 1.9276 15.884l98.173-36.949 7.8414 28.559 1.7675 4e-3 7.8414-28.559 98.171 36.949s1.7128-14.223 1.9276-15.884 0.58251-7.5514-4.7536-11.915c-5.3362-4.3639-70.605-57.461-77.102-62.768-6.4967-5.3071-4.1647-11.131-3.1483-16.589s8.5308-46.587 8.5464-79.039c0.0109-22.668 0-148.94 0-148.94l50.007 0.0273 1.7773 4.7341 1.3632-4.7322 0.82222-8e-3 21.011 3.2674 29.413 9.9624 1.041 4.3826 1.0976-3.6326 51.249 17.319 1.5605 3.992 0.69331-3.201 34.002 11.464 71.252 28.567 26.344 17.935-2e-3 -8.1344-11.435-22.93s-0.1057-0.47265-2.121-1.8573c-68.258-45.89-136.54-91.8-204.08-138.75l3.0409-11.259 3.3045-0.0918c5.3383-18.376 3.705-39.185 0.0371-51.47h-33.315c-4.2851 18.847-2.3726 36.264-0.66013 43.986l-46.402-31.846v-172.91c0-36.748-19.762-94.167-32.383-95.308zm-4.3806 54.566h2.0546c0.8995-7e-6 1.2851 0.38391 1.2851 1.2812v7.5582c-4e-5 0.89669-0.38558 1.2812-1.2851 1.2812h-2.0546c-0.89949-9e-6 -1.2246-0.38449-1.2206-1.2812v-7.5582c-4e-3 -0.89728 0.32117-1.2812 1.2206-1.2812zm6.6422 0h2.0546c0.8995-7e-6 1.2851 0.38391 1.2851 1.2812v7.5582c-4e-5 0.89669-0.38558 1.2812-1.2851 1.2812h-2.0546c-0.89948-9e-6 -1.2246-0.38449-1.2206-1.2812v-7.5582c-4e-3 -0.89728 0.32117-1.2812 1.2206-1.2812zm43.543 294.97h2.5057c0.89954-6e-5 1.2851 0.38451 1.2851 1.2812v8.8394c2e-5 0.89668-0.38553 1.2812-1.2851 1.2812h-2.5057c-0.89957-5e-5 -1.2852-0.38456-1.2851-1.2812v-8.8394c-7e-5 -0.89676 0.38559-1.2813 1.2851-1.2812zm13.968 0h2.5057c0.89954-6e-5 1.2851 0.38451 1.2851 1.2812v8.8394c2e-5 0.89668-0.38553 1.2812-1.2851 1.2812h-2.5057c-0.89958-5e-5 -1.2852-0.38456-1.2851-1.2812v-8.8394c-7e-5 -0.89676 0.38559-1.2813 1.2851-1.2812zm-122 0.0488h2.5057c0.89954-6e-5 1.2851 0.38451 1.2851 1.2812v8.8394c2e-5 0.89667-0.38553 1.2812-1.2851 1.2812h-2.5057c-0.89957-5e-5 -1.2852-0.38456-1.2851-1.2812v-8.8394c-8e-5 -0.89675 0.38559-1.2813 1.2851-1.2812zm13.97 0h2.5057c0.89955-6e-5 1.2851 0.38451 1.2851 1.2812v8.8394c2e-5 0.89667-0.38553 1.2812-1.2851 1.2812h-2.5057c-0.89957-5e-5 -1.2852-0.38456-1.2851-1.2812v-8.8394c-7e-5 -0.89675 0.38558-1.2813 1.2851-1.2812zm94.048 13.818h2.5057c0.89954-6e-5 1.2851 0.38451 1.2851 1.2812v8.8394c2e-5 0.89668-0.38552 1.2812-1.2851 1.2812h-2.5057c-0.89957-5e-5 -1.2852-0.38456-1.2851-1.2812v-8.8394c-7e-5 -0.89675 0.38559-1.2813 1.2851-1.2812zm13.97 0h2.5057c0.89954-6e-5 1.2851 0.38451 1.2851 1.2812v8.8394c2e-5 0.89668-0.38553 1.2812-1.2851 1.2812h-2.5057c-0.89957-5e-5 -1.2852-0.38456-1.2851-1.2812v-8.8394c-7e-5 -0.89675 0.38559-1.2813 1.2851-1.2812zm-122 0.0488h2.5057c0.89955-6e-5 1.2851 0.38451 1.2851 1.2812v8.8394c2e-5 0.89667-0.38553 1.2812-1.2851 1.2812h-2.5057c-0.89957-5e-5 -1.2852-0.38456-1.2851-1.2812v-8.8394c-7e-5 -0.89675 0.38559-1.2813 1.2851-1.2812zm13.97 0h2.5057c0.89954-6e-5 1.2851 0.38451 1.2851 1.2812v8.8394c2e-5 0.89667-0.38553 1.2812-1.2851 1.2812h-2.5057c-0.89957-5e-5 -1.2852-0.38456-1.2851-1.2812v-8.8394c-7e-5 -0.89675 0.38558-1.2813 1.2851-1.2812zm97.866 6.2614h8.8667zm-108.03 0.0488h8.8667zm104.23 7.5406h2.5057c0.89954-6e-5 1.2851 0.38451 1.2851 1.2812v8.8394c2e-5 0.89667-0.38552 1.2792-1.2851 1.2792h-2.5057c-0.89957-5e-5 -1.2852-0.38261-1.2851-1.2792v-8.8394c-7e-5 -0.89675 0.38559-1.2813 1.2851-1.2812zm13.97 0h2.5057c0.89954-6e-5 1.2831 0.38451 1.2831 1.2812v8.8394c2e-5 0.89667-0.38357 1.2792-1.2831 1.2792h-2.5057c-0.89957-5e-5 -1.2852-0.38261-1.2851-1.2792v-8.8394c-7e-5 -0.89675 0.38559-1.2813 1.2851-1.2812zm-122 0.0488h2.5057c0.89955-6e-5 1.2851 0.38451 1.2851 1.2812v8.8394c1e-5 0.89667-0.38553 1.2812-1.2851 1.2812h-2.5057c-0.89957-5e-5 -1.2852-0.38456-1.2851-1.2812v-8.8394c-7e-5 -0.89675 0.38559-1.2813 1.2851-1.2812zm13.97 0h2.5057c0.89954-6e-5 1.2851 0.38451 1.2851 1.2812v8.8394c2e-5 0.89667-0.38553 1.2812-1.2851 1.2812h-2.5057c-0.89957-5e-5 -1.2852-0.38456-1.2851-1.2812v-8.8394c-7e-5 -0.89675 0.38558-1.2813 1.2851-1.2812z" fill="#3296ff"/><circle cx="323.1" cy="368.73" r="328.11" fill="none" stroke="#3296ff" stroke-width="3.7896" style="paint-order:normal"/></g></g></svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

17
static/FGA_ACT_F.svg Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="211.67mm" height="211.67mm" version="1.1" viewBox="0 0 211.67 211.67" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(953.33 -995.17)">
<path d="m-742.19 1101c0 27.929-11.095 54.714-30.844 74.463-19.749 19.749-46.534 30.844-74.463 30.844-27.929 0-54.714-11.095-74.463-30.844-19.749-19.749-30.844-46.534-30.844-74.463 0-27.929 11.095-54.714 30.844-74.463 19.749-19.749 46.534-30.844 74.463-30.844 27.929 0 54.714 11.095 74.463 30.844 19.749 19.749 30.844 46.534 30.844 74.463z" fill="none" stroke="#3296ff" stroke-linejoin="round" stroke-width="1.0531"/>
<path d="m-847.5 1004.7c-7.4097 0-9.4794 27.242-9.4556 35.842v13.103l-1.2407 2.0809-2.6718 3.1116-5.7373 4.7856-15.217 12.445c0.26327-2.4217 0.81772-10.57-0.18346-11.848l-8.6782 0.072c-0.70678 0.8906-1.6381 10.501 0.13788 15.728h1.1029l0.38829 1.823-21.816 16.071c0.5494-2.3946 1.2496-11.314 0.25043-13.182l-8.8583 0.014c-1.0492 4.8589-1.1533 10.88-0.0459 15.696l1.2043 0.04 0.50012 2.5271s-28.608 21.118-31.045 22.91c-2.4373 1.7913-3.8489 5.5589-3.8729 8.2254-0.0241 2.6665-0.0401 5.2116-0.0401 5.2116l35.659-15.492 0.65645 4.4375 1.1948-5.2253 9.3938-3.722 0.4792 5.7045 1.5361-6.4857 9.1575-3.7024 0.83374 5.6914 1.1619-6.4791 8.8095-3.6302 0.53827 2.4748 1.0438-3.1115 9.1247-2.9869 0.64327 2.4748 0.93875-2.9147 12.853-3.4791 0.32163 5.0153 1.4704 10.352 0.033 19.858c0.17362 4.5575 0.64186 9.1069 1.287 13.621l1.477 6.7877c0.23946 1.6304-0.74861 3.3195-1.8528 4.424 0 0-27.318 20.921-28.298 21.678-0.98046 0.7565-1.2339 2.0863-1.2339 2.0863l-2.2479 10.338 25.84-9.5902 11.73-4.0193 2.1403 6.7961 0.58694 6.9848 0.58694-6.9848 2.1403-6.7961 11.73 4.0193 25.84 9.5902-2.2479-10.338s-0.25346-1.3298-1.2339-2.0863c-0.98047-0.7566-28.298-21.678-28.298-21.678-1.1042-1.1045-2.0923-2.7936-1.8528-4.4239l1.477-6.7877c0.64515-4.5145 1.1134-9.0639 1.287-13.621l0.033-19.858 1.4705-10.352 0.32163-5.0153 12.853 3.4791 0.93876 2.9147 0.64326-2.4748 9.1247 2.9869 1.0438 3.1115 0.53826-2.4748 8.8095 3.6302 1.1619 6.4791 0.83375-5.6914 9.1575 3.7024 1.5361 6.4857 0.4792-5.7045 9.3938 3.722 1.1948 5.2253 0.65644-4.4375 35.659 15.492s-0.016-2.5452-0.0401-5.2117-1.4357-6.4341-3.8729-8.2254c-2.4373-1.7912-31.045-22.91-31.045-22.91l0.50013-2.5271 1.2043-0.04c1.1074-4.816 1.0033-10.837-0.0459-15.696l-8.8583-0.014c-0.99921 1.8687-0.29898 10.788 0.25042 13.182l-21.816-16.071 0.3883-1.8229h1.1029c1.776-5.2277 0.84466-14.838 0.13787-15.728l-8.6782-0.072c-1.0012 1.2776-0.44672 9.4259-0.18345 11.848l-15.217-12.445-5.7373-4.7856-2.6718-3.1116-1.2407-2.0809v-13.103c0.0237-8.6006-2.046-35.842-9.4556-35.842zm-2.0804 12.256h1.3916v3.5317h-1.3916zm2.8227 0h1.4048v3.5317h-1.4048zm-19.766 73.142h1.3982v3.5317h-1.3982zm3.5777 0h1.3917v3.5317h-1.3917zm29.501 0h1.3916v3.5317h-1.3916zm3.5645 0h1.4048v3.5317h-1.4048zm-36.643 4.2932h1.3982v3.5251h-1.3982zm3.5777 0h1.3917v3.5251h-1.3917zm29.501 0h1.3916v3.5251h-1.3916zm3.5645 0h1.4048v3.5251h-1.4048zm-27.426 2.0481h1.3983v3.5186h-1.3983zm14.015 0h1.4048v3.5186h-1.4048zm-9.919 0.01h1.3983v3.5251h-1.3983zm14.015 0h1.4048v3.5251h-1.4048zm-18.112 4.4901h1.3983v3.5251h-1.3983zm4.0962 0h1.3983v3.5251h-1.3983zm9.919 0h1.4048v3.5251h-1.4048zm4.0963 0h1.4048v3.5251h-1.4048zm-18.112 4.5033h1.3983v3.5316h-1.3983zm4.0962 0h1.3983v3.5316h-1.3983zm9.919 0h1.4048v3.5316h-1.4048zm4.0963 0h1.4048v3.5316h-1.4048z" fill="#3296ff"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

89
static/FGA_THR.svg Normal file
View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
version="1.1"
viewBox="0 0 64 64"
id="svg16"
sodipodi:docname="FGA_THR.svg"
inkscape:version="0.92.1 r15371">
<metadata
id="metadata22">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs20" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1147"
id="namedview18"
showgrid="false"
inkscape:zoom="4"
inkscape:cx="-31.957369"
inkscape:cy="57.205794"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg16"
units="px" />
<g
transform="matrix(0.48381287,0,0,0.48380165,-18.79736,-39.8415)"
id="g14">
<g
transform="matrix(1.0265,0,0,1.0265,-2.7864,-3.9408)"
id="g12"
style="fill-rule:evenodd">
<path
transform="matrix(0.26458,0,0,0.26458,38.854,82.354)"
d="m 294.7,489.09 -44.15,-72.041 -44.803,72.281 c 14.546,2.7042 29.306,4.1868 44.131,4.209 15.063,-0.066 30.057,-1.6154 44.822,-4.4492 z"
style="paint-order:normal"
id="path2"
inkscape:connector-curvature="0" />
<path
transform="matrix(0.26458,0,0,0.26458,38.854,82.354)"
d="M 318.85,483.12 250.557,371.68 181.289,483.43 c 1.3922,0.41046 2.7334,0.92574 4.1367,1.3125 6.7072,1.8521 13.5,3.3069 20.328,4.5762 l 44.803,-72.281 44.15,72.041 c 6.3642,-1.2214 12.699,-2.6112 18.957,-4.3398 1.7592,-0.47721 3.4438,-1.1087 5.1855,-1.623 z"
style="fill:#fffc00;paint-order:normal"
id="path4"
inkscape:connector-curvature="0" />
<path
transform="matrix(0.26458,0,0,0.26458,38.854,82.354)"
d="m 7.793,274.15 c 9.8503,98.716 78.612,181.32 173.49,209.29 l 69.268,-111.75 68.293,111.44 c 94.698,-27.966 163.41,-110.38 173.36,-208.98 z"
style="paint-order:normal"
id="path6"
inkscape:connector-curvature="0" />
<path
d="m 105,84.064 a 64.436,64.436 0 0 0 -6.9536,0.45217 v 63.984 H 91.068 v -62.829 a 64.436,64.436 0 0 0 -3.4644,0.79478 v 62.034 h -6.9784 v -59.598 a 64.436,64.436 0 0 0 -3.4644,1.5503 v 58.048 h -6.9784 v -54.219 a 64.436,64.436 0 0 0 -3.4644,2.4774 v 51.742 h -6.9784 v -45.829 a 64.436,64.436 0 0 0 -3.4644,3.7192 v 42.11 h -6.9784 v -32.27 a 64.436,64.436 0 0 0 -3.4644,6.8011 v 25.469 H 40.564 a 64.436,64.436 0 0 0 0.08992,2.5476 h 128.65 a 64.436,64.436 0 0 0 0.12764,-2.5476 h -5.2684 v -25.336 a 64.436,64.436 0 0 0 -3.4644,-6.8952 v 32.232 h -6.9784 v -42.046 a 64.436,64.436 0 0 0 -3.4644,-3.7445 v 45.79 h -6.9784 v -51.738 a 64.436,64.436 0 0 0 -3.4644,-2.4035 v 54.141 h -6.9784 v -58.023 a 64.436,64.436 0 0 0 -3.4644,-1.5885 v 59.611 h -6.9784 v -61.978 a 64.436,64.436 0 0 0 -3.4644,-0.8847 v 62.863 h -6.9784 v -64.035 a 64.436,64.436 0 0 0 -6.9536,-0.40049 z"
style="paint-order:normal"
id="path8"
inkscape:connector-curvature="0" />
<path
d="m 86.789,198.81 18.357,-29.616 18.149,29.615 h 7.3544 l -25.503,-41.615 -25.796,41.617 h 7.4388"
style="fill:#fffc00;paint-order:normal"
id="path10"
inkscape:connector-curvature="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

78
static/tower.svg Normal file
View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
viewBox="0 0 16.933333 16.933334"
version="1.1"
id="svg8"
inkscape:version="0.92.1 r15371"
sodipodi:docname="tower.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="12.8125"
inkscape:cx="31.843902"
inkscape:cy="32"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="true"
units="px"
inkscape:window-width="1920"
inkscape:window-height="1013"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid4489" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-280.06665)">
<path
style="fill:none;stroke:#000000;stroke-width:0.47822458px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 0.37724475,288.43079 3.66477855,-8.09956 h 8.9225597 l 3.569025,8.20209 -3.569025,8.20208 H 4.0420233 Z"
id="path4487"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 2.6458333,288.53332 2.9104166,-5.55625 h 5.8208331 l 2.645833,5.55625 -2.381249,5.82083 H 5.2916666 Z"
id="path4503"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 7.6729166,286.94582 -0.79375,1.5875 0.79375,1.32291 h 1.5875 l 0.7937504,-1.32291 -0.7937504,-1.5875 z"
id="path4505"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB