diff --git a/src/renderer/components/AirlineItem.vue b/src/renderer/components/AirlineItem.vue new file mode 100644 index 0000000..3bc4f35 --- /dev/null +++ b/src/renderer/components/AirlineItem.vue @@ -0,0 +1,95 @@ + + + + + + + + diff --git a/src/renderer/components/AirportEdit.vue b/src/renderer/components/AirportEdit.vue index 9c504ed..96928cb 100644 --- a/src/renderer/components/AirportEdit.vue +++ b/src/renderer/components/AirportEdit.vue @@ -16,12 +16,13 @@ You should have received a copy of the GNU General Public License along with FG title="Add Airline" :visible.sync="dialogVisible" width="40%" - :before-close="handleClose"> + :before-close="handleClose" + > Add an selectable airline to {{ icao }} {{ name }} - + Cancel Confirm @@ -31,116 +32,143 @@ You should have received a copy of the GNU General Public License along with FG title="Import File" :visible.sync="showImportFile" width="20%" - :before-close="handleClose"> - Beware wip will be overwritten - - - - - - - - - + :before-close="handleClose" + > + Beware wip will be overwritten + + + + + + + + + Cancel Confirm

{{ icao }} {{ name }}

-
- - - - - - - - - - - - - - - - Airlines : - - {{item.value}} - - - - - +
+ + + + + + + + + + + + + + + + Airlines : + + {{ + item.value + }} + + + + +
- - -
- - - - Add + + +
+ + + + Add
-
- - - - - Traffic : + + + + + + Traffic : Flights : {{ flights }} - GIT/Terrasync : + GIT/Terrasync : Parking Positions : {{ parking }} Groundnet Nodes : - {{groundnet}} + {{ groundnet }} - Work : + Work : Work Parking Positions : {{ wipparking }} Work Groundnet Nodes : - {{wipgroundnet}} + {{ wipgroundnet }} Saved : - {{date}} + {{ date }} Uploaded : - {{upload_date}} + {{ upload_date }} - -
+ + + + +
@@ -149,8 +177,9 @@ You should have received a copy of the GNU General Public License along with FG import FileSelect from './FileSelect' import Frequency from './Frequency' import ParkingList from './ParkingList' + import TrafficList from './TrafficList' import Upload from './Upload' - + const fs = require('fs') const path = require('path') @@ -159,7 +188,7 @@ export default { return {showImportFile: false, activeTab: 'first', editing: false, uploadVisible: false, dialogVisible: false, airlineCode: '', fileImport: null} }, components: { - EditButton, FileSelect, Frequency, ParkingList, Upload + EditButton, FileSelect, Frequency, ParkingList, TrafficList, Upload }, methods: { fileImportFileName (f) { @@ -291,10 +320,10 @@ export default { + + diff --git a/src/renderer/loaders/groundnet_loader.js b/src/renderer/loaders/groundnet_loader.js index 5a068c3..feb90fd 100644 --- a/src/renderer/loaders/groundnet_loader.js +++ b/src/renderer/loaders/groundnet_loader.js @@ -23,9 +23,9 @@ function addFrequencies (type, value) { value.split(' ').forEach(frequencyValue => { if( value.length > 0) { var frequency = {type: type, value: frequencyValue}; - frequencies.push(frequency); + frequencies.push(frequency); } - }) + }) } exports.addFeature = function (feature) { @@ -38,10 +38,10 @@ exports.listSaves = function (fDir, icao) { var ret = files .filter(f => f.includes(icao) ) .filter(f => f.includes('groundnet') ) - .map(f => { + .map(f => { try { var fileDate = fs.lstatSync(path.join(directory, f)); - return {file: f, mtime: `${fileDate.mtime}`, mtimeMs: `${fileDate.mtimeMs}`}; + return {file: f, mtime: `${fileDate.mtime}`, mtimeMs: `${fileDate.mtimeMs}`}; } catch (error) { console.error(error); } @@ -99,7 +99,7 @@ exports.readGroundnetXML = function (fDir, icao, f) { addFrequencies('UNICOM', unicom); store.default.dispatch('setFrequencies', frequencies); - + var parkingNodes = xml.find('groundnet/parkingList/Parking'); console.debug("Parking Nodes length" + parkingNodes.length); @@ -118,9 +118,9 @@ exports.readGroundnetXML = function (fDir, icao, f) { layerGroup.maxId = Math.max(layerGroup.maxId, Number(n.attr('index'))) features.push(circle); }).sort(); - - store.default.dispatch('setParkings', parkingNodes.map( - p => ({index: Number(p.attrs.index), name: String(p.attrs.name), number: String(p.attrs.number), type: String(p.attrs.type)} + + store.default.dispatch('setParkings', parkingNodes.map( + p => ({index: Number(p.attrs.index), radius: Number(p.attrs.radius), name: String(p.attrs.name), number: String(p.attrs.number), type: String(p.attrs.type)} )).sort((p1, p2) => { if (p1.name === p2.name) { return p1.number?p1.number.localeCompare(p2.number):-1; @@ -134,7 +134,7 @@ exports.readGroundnetXML = function (fDir, icao, f) { //attrs.lat //console.log(n.attr('lat') + " " + n.attr('lon')); try { - var latlon = convert(n.attr('lat') + " " + n.attr('lon')); + var latlon = convert(n.attr('lat') + " " + n.attr('lon')); } catch (error) { console.warn(n.attr('lat') + " " + n.attr('lon')); convert(n.attr('lat') + " " + n.attr('lon')); @@ -186,7 +186,7 @@ exports.readGroundnetXML = function (fDir, icao, f) { if (element instanceof L.Polyline && element.end === n.attr('begin') && element.begin === n.attr('end')) { element.bidirectional = true; element.options.attributes.direction = 'bi-directional' - bidirectional = true; + bidirectional = true; element.updateStyle(); } }); @@ -194,11 +194,11 @@ exports.readGroundnetXML = function (fDir, icao, f) { if (!bidirectional) { var beginlatlon = convert(beginNode.attr('lat') + " " + beginNode.attr('lon')); var endlatlon = convert(endNode.attr('lat') + " " + endNode.attr('lon')); - + var pane = 'route-pane'; if(n.attr('isPushBackRoute') === '1') { pane = 'pushback-pane'; - } + } var polyline = new L.Polyline([[beginlatlon.decimalLatitude, beginlatlon.decimalLongitude], [endlatlon.decimalLatitude, endlatlon.decimalLongitude]], { pane: pane, attributes: {} }).addTo(layerGroup); extendTaxiSegment(polyline); diff --git a/src/renderer/loaders/traffic_loader.js b/src/renderer/loaders/traffic_loader.js new file mode 100644 index 0000000..05d7814 --- /dev/null +++ b/src/renderer/loaders/traffic_loader.js @@ -0,0 +1,122 @@ +/* +Copyright 2021 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 store = require('../store'); + +const util = require('util'); + +exports.readTrafficXML = function (f) { + try { + var ret = []; + var xmlTraffic = fs.readFileSync(f, 'utf8').toString(); + xamel.parse(xmlTraffic, function (err, xml) { + console.debug("parsed " + path.basename(f)); + if (err !== null) { + console.error("Error in " + airline); + throw err; + } + + var requiredAircraft = xml.find('trafficlist/aircraft'); + console.log("Aircraft " + requiredAircraft.length); + + ret.concat(requiredAircraft); + var flights = xml.find('trafficlist/flight'); + console.log("Flights " + flights.length); + ret.concat(flights); + console.log(ret.length); + ret = ret.concat(flights.map(flightMapper)).concat(requiredAircraft.map(aircraftMapper)) + return ret; + }); + return ret; + } catch (error) { + console.error(error); + } +}; + +/* +* + Hebridean_1047 + HBR_BN_2 + VFR + + EGPU + + + 50 + + EGEO + + + WEEK + +*/ + +function flightMapper(params) { + return { + id: `${btoa(buildId(params))}`, + callsign: params.find('callsign').text(), + arrival: { + port: params.find('arrival/port').text(), + time: params.find('arrival/time').text() + }, + departure: { + port: params.find('departure/port').text(), + time: params.find('departure/time').text() + } + }; +} + +function buildId(params) { + return `${params.find('callsign').text()}_`+ + `${params.find('arrival/port').text()}_`+ + `${params.find('arrival/time').text()}_`+ + `${params.find('departure/port').text()}_` + + `${params.find('departure/time').text()}`; +} + +/* + + Aircraft/BN-2/BN-2-Hebridean.xml + HBR + HBR + EGEO + HBR_BN_2 + BN2 + 0 + 8 + gate + turboprop_transport + G-HEBO + false + +*/ + +function aircraftMapper(params) { + return { + model: params.find('model').text(), + livery: params.find('livery').text(), + airline: params.find('airline').text(), + 'home-port': params.find('home-port').text(), + 'required-aircraft': params.find('required-aircraft').text(), + actype: params.find('actype').text(), + offset: params.find('offset').text(), + radius: params.find('radius').text(), + flighttype: params.find('flighttype').text(), + 'performance-class': params.find('performance-class').text(), + 'registration': params.find('registration').text(), + 'heavy': params.find('heavy').text(), + }; +} \ No newline at end of file diff --git a/src/renderer/loaders/traffic_writer.js b/src/renderer/loaders/traffic_writer.js new file mode 100644 index 0000000..08a762e --- /dev/null +++ b/src/renderer/loaders/traffic_writer.js @@ -0,0 +1,180 @@ +/* +Copyright 2021 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'); + +const store = require('../store'); + +const util = require('util'); + +const mathjs = require('mathjs'); + +var builder = require('xmlbuilder'); + +var parkingStats = (acc, cur) => { + if (!acc[cur.radius]) { + acc[cur.radius] = { count: 0, radius: cur.radius } + } + acc[cur.radius].count += 1 + return acc +}; + +/** + + + + Aircraft/BN-2/BN-2-Hebridean.xml + HBR + HBR + EGEO + HBR_BN_2 + BN2 + 0 + 8 + gate + turboprop_transport + G-HEBS + false + + + Hebridean_1047 + HBR_BN_2 + VFR + + EGPU + + + 50 + + EGEO + + + WEEK + + + */ + +var writeTrafficXML = function (fDir, parkings, aircraft) { + try { + var icao = store.default.state.Airports.currentAirport.icao; + var aircraftList = aircraft; + + try { fs.mkdirSync(path.join(fDir), { recursive: true }) } catch (err) { } + try { fs.mkdirSync(path.join(fDir, 'TST'), { recursive: true }) } catch (err) { } + + var f = path.join(fDir, 'TST', icao + '.xml'); + + + var parkingData = parkings.reduce(parkingStats, {}); + + /* + * + + Hebridean_1001 + HBR_BN_2 + VFR + + EGEO + + + 50 + + EGEY + + + WEEK + + */ + + var flightMapper = function (pStat) { + var ret = []; + var blockSize = Math.min( pStat[1].count/6, 6); + for (let index = 0; index < pStat[1].count; index++) { + var aircraft = this[index]; + var minutes = `${Math.floor(index/blockSize)}`.padStart(2, '0'); + var seconds = `${index}`.padStart(2, '0'); + for (let weekday = 0; weekday < 7; weekday++) { + ret.push({ + callsign: `Test_${index}_${weekday}`, + 'required-aircraft': aircraft['required-aircraft'], + fltrules: 'VFR', + departure: { + port: icao, + time: `${weekday}/12:${minutes}:${seconds}` + }, + 'cruise-alt': 50, + arrival: { + port: icao, + time: `${weekday}/13:${minutes}:${seconds}` + }, + repeat: 'WEEK' + }); + } + } + return ret; + } + + /* + + Aircraft/BN-2/BN-2-Hebridean.xml + HBR + HBR + EGEO + HBR_BN_2 + BN2 + 0 + 8 + gate + turboprop_transport + G-HEBO + false + + + */ + var aircraftMapper = function (pStat) { + var ret = []; + if (typeof this === 'undefined') { + return; + } + var possibleAircraft = this.filter(a => a.radius <= pStat[1].radius); + + for (let index = 0; index < pStat[1].count; index++) { + var aircraft = possibleAircraft[Math.floor(Math.random() * possibleAircraft.length)]; + aircraft['required-aircraft'] = `GG-${index}`; + aircraft.registration = `GG-${index}`; + aircraft['home-port'] = icao; + ret.push(aircraft); + } + return ret; + } + + + var aircraftList = Object.entries(parkingData).flatMap(aircraftMapper, aircraft).sort(); + var flightList = Object.entries(parkingData).flatMap(flightMapper, aircraftList).sort(); + + var xmlObj = { trafficList: { aircraft: aircraftList, flight: flightList } }; + + var xmlString = builder.create(xmlObj).end({ pretty: true }); + fs.writeFileSync(f, xmlString); + console.debug(xmlString); + } catch (error) { + console.error(error); + } + return; +} + + +export { writeTrafficXML as writeTrafficXML }; \ No newline at end of file diff --git a/src/renderer/store/modules/Parkings.js b/src/renderer/store/modules/Parkings.js index 287664e..0f5a3c8 100644 --- a/src/renderer/store/modules/Parkings.js +++ b/src/renderer/store/modules/Parkings.js @@ -43,7 +43,7 @@ const mutations = { const actions = { async addParking (context, p) { - context.commit('ADD_FREADD_PARKINGQUENCY', p) + context.commit('ADD_PARKING', p) }, async updatedParking (context, p) { context.commit('UPDATE_PARKING', p)