Groundnet Scan
This commit is contained in:
parent
b81348bdb8
commit
6adffb8878
4
airports.json
Normal file
4
airports.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"type": "FeatureCollection",
|
||||||
|
"features": []
|
||||||
|
}
|
1
airports_DB.json
Normal file
1
airports_DB.json
Normal file
File diff suppressed because one or more lines are too long
0
airports_DB.json~
Normal file
0
airports_DB.json~
Normal file
1555
package-lock.json
generated
1555
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
35
package.json
35
package.json
@ -57,50 +57,62 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
|
"electron-debug": "^3.0.1",
|
||||||
"element-ui": "^2.12.0",
|
"element-ui": "^2.12.0",
|
||||||
|
"file-url": "^3.0.0",
|
||||||
"font-awesome": "^4.7.0",
|
"font-awesome": "^4.7.0",
|
||||||
|
"fs": "0.0.1-security",
|
||||||
|
"idb": "^4.0.5",
|
||||||
"leaflet": "^1.5.1",
|
"leaflet": "^1.5.1",
|
||||||
|
"leaflet-editable": "^1.2.0",
|
||||||
"leaflet-sidebar-v2": "^3.2.1",
|
"leaflet-sidebar-v2": "^3.2.1",
|
||||||
|
"lokijs": "^1.5.8",
|
||||||
|
"mathjs": "^6.2.5",
|
||||||
|
"path": "^0.12.7",
|
||||||
"vue": "^2.5.16",
|
"vue": "^2.5.16",
|
||||||
"vue-electron": "^1.0.6",
|
"vue-electron": "^1.0.6",
|
||||||
|
"vue-idb": "^0.2.0",
|
||||||
"vue-leaflet": "^0.1.0",
|
"vue-leaflet": "^0.1.0",
|
||||||
"vue-router": "^3.0.1",
|
"vue-router": "^3.0.1",
|
||||||
"vue2-leaflet": "^2.2.1",
|
"vue2-leaflet": "^2.2.1",
|
||||||
"vuetify": "^2.1.9",
|
"vuetify": "^2.1.9",
|
||||||
"vuex": "^3.0.1",
|
"vuex": "^3.0.1",
|
||||||
"vuex-electron": "^1.0.0"
|
"vuex-electron": "^1.0.0",
|
||||||
|
"vuex-persistedstate": "^2.7.0",
|
||||||
|
"worker-threads": "^1.0.0",
|
||||||
|
"xamel": "^0.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"ajv": "^6.5.0",
|
"ajv": "^6.5.0",
|
||||||
"babel-core": "^6.26.3",
|
"babel-core": "^6.26.3",
|
||||||
|
"babel-eslint": "^8.2.3",
|
||||||
"babel-loader": "^7.1.4",
|
"babel-loader": "^7.1.4",
|
||||||
|
"babel-plugin-istanbul": "^4.1.6",
|
||||||
"babel-plugin-transform-runtime": "^6.23.0",
|
"babel-plugin-transform-runtime": "^6.23.0",
|
||||||
"babel-preset-env": "^1.7.0",
|
"babel-preset-env": "^1.7.0",
|
||||||
"babel-preset-stage-0": "^6.24.1",
|
"babel-preset-stage-0": "^6.24.1",
|
||||||
"babel-register": "^6.26.0",
|
"babel-register": "^6.26.0",
|
||||||
"babili-webpack-plugin": "^0.1.2",
|
"babili-webpack-plugin": "^0.1.2",
|
||||||
"cfonts": "^2.1.2",
|
"cfonts": "^2.1.2",
|
||||||
|
"chai": "^4.1.2",
|
||||||
"chalk": "^2.4.1",
|
"chalk": "^2.4.1",
|
||||||
"copy-webpack-plugin": "^4.5.1",
|
"copy-webpack-plugin": "^4.5.1",
|
||||||
"cross-env": "^5.1.6",
|
"cross-env": "^5.1.6",
|
||||||
"css-loader": "^0.28.11",
|
"css-loader": "^0.28.11",
|
||||||
"del": "^3.0.0",
|
"del": "^3.0.0",
|
||||||
"devtron": "^1.4.0",
|
"devtron": "^1.4.0",
|
||||||
"electron": "^2.0.4",
|
"electron": "^4.2.12",
|
||||||
"electron-debug": "^1.5.0",
|
"electron-builder": "^21.2.0",
|
||||||
"electron-devtools-installer": "^2.2.4",
|
"electron-devtools-installer": "^2.2.4",
|
||||||
"electron-builder": "^20.19.2",
|
|
||||||
"babel-eslint": "^8.2.3",
|
|
||||||
"eslint": "^4.19.1",
|
"eslint": "^4.19.1",
|
||||||
|
"eslint-config-standard": "^11.0.0",
|
||||||
"eslint-friendly-formatter": "^4.0.1",
|
"eslint-friendly-formatter": "^4.0.1",
|
||||||
"eslint-loader": "^2.0.0",
|
"eslint-loader": "^2.0.0",
|
||||||
"eslint-plugin-html": "^4.0.3",
|
"eslint-plugin-html": "^4.0.3",
|
||||||
"eslint-config-standard": "^11.0.0",
|
|
||||||
"eslint-plugin-import": "^2.12.0",
|
"eslint-plugin-import": "^2.12.0",
|
||||||
"eslint-plugin-node": "^6.0.1",
|
"eslint-plugin-node": "^6.0.1",
|
||||||
"eslint-plugin-promise": "^3.8.0",
|
"eslint-plugin-promise": "^3.8.0",
|
||||||
"eslint-plugin-standard": "^3.1.0",
|
"eslint-plugin-standard": "^3.1.0",
|
||||||
"mini-css-extract-plugin": "0.4.0",
|
|
||||||
"file-loader": "^1.1.11",
|
"file-loader": "^1.1.11",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
"inject-loader": "^4.0.1",
|
"inject-loader": "^4.0.1",
|
||||||
@ -112,23 +124,22 @@
|
|||||||
"karma-sourcemap-loader": "^0.3.7",
|
"karma-sourcemap-loader": "^0.3.7",
|
||||||
"karma-spec-reporter": "^0.0.32",
|
"karma-spec-reporter": "^0.0.32",
|
||||||
"karma-webpack": "^3.0.0",
|
"karma-webpack": "^3.0.0",
|
||||||
"require-dir": "^1.0.0",
|
"mini-css-extract-plugin": "0.4.0",
|
||||||
"spectron": "^3.8.0",
|
|
||||||
"babel-plugin-istanbul": "^4.1.6",
|
|
||||||
"chai": "^4.1.2",
|
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^5.2.0",
|
||||||
"multispinner": "^0.2.1",
|
"multispinner": "^0.2.1",
|
||||||
"node-loader": "^0.6.0",
|
"node-loader": "^0.6.0",
|
||||||
"node-sass": "^4.9.2",
|
"node-sass": "^4.9.2",
|
||||||
|
"require-dir": "^1.0.0",
|
||||||
"sass-loader": "^7.0.3",
|
"sass-loader": "^7.0.3",
|
||||||
|
"spectron": "^3.8.0",
|
||||||
"style-loader": "^0.21.0",
|
"style-loader": "^0.21.0",
|
||||||
"url-loader": "^1.0.1",
|
"url-loader": "^1.0.1",
|
||||||
"vue-html-loader": "^1.2.4",
|
"vue-html-loader": "^1.2.4",
|
||||||
"vue-loader": "^15.2.4",
|
"vue-loader": "^15.2.4",
|
||||||
"vue-style-loader": "^4.1.0",
|
"vue-style-loader": "^4.1.0",
|
||||||
"vue-template-compiler": "^2.5.16",
|
"vue-template-compiler": "^2.5.16",
|
||||||
"webpack-cli": "^3.0.8",
|
|
||||||
"webpack": "^4.15.1",
|
"webpack": "^4.15.1",
|
||||||
|
"webpack-cli": "^3.0.8",
|
||||||
"webpack-dev-server": "^3.1.4",
|
"webpack-dev-server": "^3.1.4",
|
||||||
"webpack-hot-middleware": "^2.22.2",
|
"webpack-hot-middleware": "^2.22.2",
|
||||||
"webpack-merge": "^4.1.3"
|
"webpack-merge": "^4.1.3"
|
||||||
|
@ -6,9 +6,9 @@ import { app, BrowserWindow } from 'electron'
|
|||||||
* Set `__static` path to static files in production
|
* Set `__static` path to static files in production
|
||||||
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
|
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
|
||||||
*/
|
*/
|
||||||
if (process.env.NODE_ENV !== 'development') {
|
// if (process.env.NODE_ENV !== 'development') {
|
||||||
global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
|
// global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
|
||||||
}
|
// }
|
||||||
|
|
||||||
let mainWindow
|
let mainWindow
|
||||||
const winURL = process.env.NODE_ENV === 'development'
|
const winURL = process.env.NODE_ENV === 'development'
|
||||||
@ -22,9 +22,12 @@ function createWindow () {
|
|||||||
mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
height: 563,
|
height: 563,
|
||||||
useContentSize: true,
|
useContentSize: true,
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true,
|
||||||
|
nodeIntegrationInWorker: true
|
||||||
|
},
|
||||||
width: 1000
|
width: 1000
|
||||||
})
|
})
|
||||||
|
|
||||||
mainWindow.loadURL(winURL)
|
mainWindow.loadURL(winURL)
|
||||||
|
|
||||||
mainWindow.on('closed', () => {
|
mainWindow.on('closed', () => {
|
||||||
|
54
src/renderer/components/AirportLayer.vue
Normal file
54
src/renderer/components/AirportLayer.vue
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<template>
|
||||||
|
<section class="edit-layer">
|
||||||
|
<h1>edit-layer Component</h1>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import L from 'leaflet'
|
||||||
|
export default {
|
||||||
|
name: 'edit-layer',
|
||||||
|
props: [],
|
||||||
|
mounted () {
|
||||||
|
this.add()
|
||||||
|
},
|
||||||
|
beforeDestroy () {
|
||||||
|
this.remove()
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
deferredMountedTo (parent) {
|
||||||
|
this.sidebar = L.control.sidebar({
|
||||||
|
autopan: false, // whether to maintain the centered map point when opening the sidebar
|
||||||
|
closeButton: true, // whether t add a close button to the panes
|
||||||
|
container: 'sidebar', // the DOM container or #ID of a predefined sidebar container that should be used
|
||||||
|
position: 'left' // left or right
|
||||||
|
})
|
||||||
|
parent.addControl(this.sidebar)
|
||||||
|
},
|
||||||
|
remove () {
|
||||||
|
if (this.sidebar) {
|
||||||
|
this.$parent.removeLayer(this.sidebar)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
add () {
|
||||||
|
if (this.$parent._isMounted) {
|
||||||
|
this.deferredMountedTo(this.$parent.mapObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.edit-layer {
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
40
src/renderer/components/DirectorySelect.vue
Normal file
40
src/renderer/components/DirectorySelect.vue
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<template>
|
||||||
|
<label class="directory-select">
|
||||||
|
<div class="select-button">
|
||||||
|
...
|
||||||
|
</div>
|
||||||
|
<input type="file" @change="handleFileChange" webkitdirectory directory/>
|
||||||
|
</label>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
value: File
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
handleFileChange (e) {
|
||||||
|
this.$emit('input', e.target.files[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.directory-select > .select-button {
|
||||||
|
padding: 0rem;
|
||||||
|
|
||||||
|
color: white;
|
||||||
|
background-color: #2EA169;
|
||||||
|
|
||||||
|
border-radius: .3rem;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory-select > input[type="file"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
54
src/renderer/components/EditLayer.vue
Normal file
54
src/renderer/components/EditLayer.vue
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<template>
|
||||||
|
<section class="edit-layer">
|
||||||
|
<h1>edit-layer Component</h1>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import L from 'leaflet'
|
||||||
|
export default {
|
||||||
|
name: 'edit-layer',
|
||||||
|
props: [],
|
||||||
|
mounted () {
|
||||||
|
this.add()
|
||||||
|
},
|
||||||
|
beforeDestroy () {
|
||||||
|
this.remove()
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
deferredMountedTo (parent) {
|
||||||
|
this.sidebar = L.control.sidebar({
|
||||||
|
autopan: false, // whether to maintain the centered map point when opening the sidebar
|
||||||
|
closeButton: true, // whether t add a close button to the panes
|
||||||
|
container: 'sidebar', // the DOM container or #ID of a predefined sidebar container that should be used
|
||||||
|
position: 'left' // left or right
|
||||||
|
})
|
||||||
|
parent.addControl(this.sidebar)
|
||||||
|
},
|
||||||
|
remove () {
|
||||||
|
if (this.sidebar) {
|
||||||
|
this.$parent.removeLayer(this.sidebar)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
add () {
|
||||||
|
if (this.$parent._isMounted) {
|
||||||
|
this.deferredMountedTo(this.$parent.mapObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.edit-layer {
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
41
src/renderer/components/FileSelect.vue
Normal file
41
src/renderer/components/FileSelect.vue
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<template>
|
||||||
|
<label class="file-select">
|
||||||
|
<div class="select-button">
|
||||||
|
<span v-if="value">Selected File: {{value.name}}</span>
|
||||||
|
<span v-else>Select File</span>
|
||||||
|
</div>
|
||||||
|
<input type="file" @change="handleFileChange"/>
|
||||||
|
</label>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
value: File
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
handleFileChange (e) {
|
||||||
|
this.$emit('input', e.target.files[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.file-select > .select-button {
|
||||||
|
padding: 1rem;
|
||||||
|
|
||||||
|
color: white;
|
||||||
|
background-color: #2EA169;
|
||||||
|
|
||||||
|
border-radius: .3rem;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-select > input[type="file"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
@ -3,6 +3,7 @@
|
|||||||
<l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
|
<l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
|
||||||
<l-marker :lat-lng="marker"></l-marker>
|
<l-marker :lat-lng="marker"></l-marker>
|
||||||
<LeafletSidebar></LeafletSidebar>
|
<LeafletSidebar></LeafletSidebar>
|
||||||
|
<EditLayer></EditLayer>
|
||||||
</l-map>
|
</l-map>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -10,6 +11,7 @@
|
|||||||
import 'leaflet/dist/leaflet.css'
|
import 'leaflet/dist/leaflet.css'
|
||||||
import { LMap, LTileLayer, LMarker } from 'vue2-leaflet'
|
import { LMap, LTileLayer, LMarker } from 'vue2-leaflet'
|
||||||
import LeafletSidebar from './LeafletSidebar'
|
import LeafletSidebar from './LeafletSidebar'
|
||||||
|
import EditLayer from './EditLayer'
|
||||||
import L from 'leaflet'
|
import L from 'leaflet'
|
||||||
|
|
||||||
// https://github.com/KoRiGaN/Vue2Leaflet/issues/103
|
// https://github.com/KoRiGaN/Vue2Leaflet/issues/103
|
||||||
@ -22,7 +24,7 @@
|
|||||||
})
|
})
|
||||||
export default {
|
export default {
|
||||||
name: 'flightgear-map',
|
name: 'flightgear-map',
|
||||||
components: { LMap, LTileLayer, LMarker, LeafletSidebar },
|
components: { LMap, LTileLayer, LMarker, LeafletSidebar, EditLayer },
|
||||||
props: [],
|
props: [],
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div class="title">Information</div>
|
|
||||||
<div class="items">
|
|
||||||
<div class="item">
|
|
||||||
<div class="name">Path:</div>
|
|
||||||
<div class="value">{{ path }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<div class="name">Route Name:</div>
|
|
||||||
<div class="value">{{ name }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<div class="name">Vue.js:</div>
|
|
||||||
<div class="value">{{ vue }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<div class="name">Electron:</div>
|
|
||||||
<div class="value">{{ electron }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<div class="name">Node:</div>
|
|
||||||
<div class="value">{{ node }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<div class="name">Platform:</div>
|
|
||||||
<div class="value">{{ platform }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
electron: process.versions.electron,
|
|
||||||
name: this.$route.name,
|
|
||||||
node: process.versions.node,
|
|
||||||
path: this.$route.path,
|
|
||||||
platform: require('os').platform(),
|
|
||||||
vue: require('vue/package.json').version
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.title {
|
|
||||||
color: #888;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: initial;
|
|
||||||
letter-spacing: .25px;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.items { margin-top: 8px; }
|
|
||||||
|
|
||||||
.item {
|
|
||||||
display: flex;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item .name {
|
|
||||||
color: #6a6a6a;
|
|
||||||
margin-right: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item .value {
|
|
||||||
color: #35495e;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -4,8 +4,7 @@
|
|||||||
<div class="leaflet-sidebar-tabs">
|
<div class="leaflet-sidebar-tabs">
|
||||||
<ul role="tablist"> <!-- top aligned tabs -->
|
<ul role="tablist"> <!-- top aligned tabs -->
|
||||||
<li><a href="#home" role="tab"><i class="fa fa-bars"></i></a></li>
|
<li><a href="#home" role="tab"><i class="fa fa-bars"></i></a></li>
|
||||||
<li><a href="#messages" role="tab"><i class="fa fa-envelope"></i></a></li>
|
<li><a href="#scan" role="tab"><i class="fa fa-search"></i></a></li>
|
||||||
<li><a href="#profile" role="tab"><i class="fa fa-user"></i></a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul role="tablist"> <!-- bottom aligned tabs -->
|
<ul role="tablist"> <!-- bottom aligned tabs -->
|
||||||
@ -22,14 +21,11 @@
|
|||||||
</h1>
|
</h1>
|
||||||
<p>A responsive sidebar for mapping libraries</p>
|
<p>A responsive sidebar for mapping libraries</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="leaflet-sidebar-pane" id="scan">
|
||||||
<div class="leaflet-sidebar-pane" id="messages">
|
<RunScan></RunScan>
|
||||||
<h1 class="leaflet-sidebar-header">Messages<div class="leaflet-sidebar-close"><i class="fa fa-caret-left"></i></div></h1>
|
|
||||||
<el-select v-model="value" placeholder="Select"><el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="leaflet-sidebar-pane" id="settings">
|
||||||
<div class="leaflet-sidebar-pane" id="profile">
|
<SettingsPanel></SettingsPanel>
|
||||||
<h1 class="leaflet-sidebar-header">Profile<div class="leaflet-sidebar-close"><i class="fa fa-caret-left"></i></div></h1>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -41,10 +37,12 @@
|
|||||||
import {} from 'leaflet-sidebar-v2'
|
import {} from 'leaflet-sidebar-v2'
|
||||||
import L from 'leaflet'
|
import L from 'leaflet'
|
||||||
import SettingsPanel from './SettingsPanel'
|
import SettingsPanel from './SettingsPanel'
|
||||||
|
import RunScan from './RunScan'
|
||||||
|
import FileSelect from './FileSelect'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'leaflet-sidebar',
|
name: 'leaflet-sidebar',
|
||||||
components: { SettingsPanel },
|
components: { SettingsPanel, RunScan, FileSelect },
|
||||||
props: [],
|
props: [],
|
||||||
mounted () {
|
mounted () {
|
||||||
this.add()
|
this.add()
|
||||||
@ -54,25 +52,6 @@
|
|||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
message: 'BLBL',
|
|
||||||
checkbox: true,
|
|
||||||
options: [{
|
|
||||||
value: 'Option1',
|
|
||||||
label: 'Option1'
|
|
||||||
}, {
|
|
||||||
value: 'Option2',
|
|
||||||
label: 'Option2'
|
|
||||||
}, {
|
|
||||||
value: 'Option3',
|
|
||||||
label: 'Option3'
|
|
||||||
}, {
|
|
||||||
value: 'Option4',
|
|
||||||
label: 'Option4'
|
|
||||||
}, {
|
|
||||||
value: 'Option5',
|
|
||||||
label: 'Option5'
|
|
||||||
}],
|
|
||||||
value: ''
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -84,20 +63,6 @@
|
|||||||
position: 'left' // left or right
|
position: 'left' // left or right
|
||||||
})
|
})
|
||||||
parent.addControl(this.sidebar)
|
parent.addControl(this.sidebar)
|
||||||
|
|
||||||
this.sidebar.addPanel({
|
|
||||||
id: 'properties',
|
|
||||||
tab: '<i class="fa fa-road vertical-center"/>',
|
|
||||||
title: 'Properties',
|
|
||||||
pane: '<div id="properties-tab"></div>'
|
|
||||||
})
|
|
||||||
|
|
||||||
this.sidebar.addPanel({
|
|
||||||
id: 'settings',
|
|
||||||
tab: '<i class="fa fa-gear vertical-center"/>',
|
|
||||||
title: 'Settings',
|
|
||||||
pane: '<div id="settings-div"></div>'
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
remove () {
|
remove () {
|
||||||
if (this.sidebar) {
|
if (this.sidebar) {
|
||||||
@ -108,6 +73,8 @@
|
|||||||
if (this.$parent._isMounted) {
|
if (this.$parent._isMounted) {
|
||||||
this.deferredMountedTo(this.$parent.mapObject)
|
this.deferredMountedTo(this.$parent.mapObject)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
scan () {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
104
src/renderer/components/RunScan.vue
Normal file
104
src/renderer/components/RunScan.vue
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-container direction='vertical'>
|
||||||
|
<el-button @click="scanAPT()">Scan APT File</el-button>
|
||||||
|
<el-button @click="scanGroundnets()">Scan Groundnet Files</el-button>
|
||||||
|
<el-button @click="scanTraffic()">Scan Traffic Files</el-button>
|
||||||
|
</el-container>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
// import scanner from '../utils/scan'
|
||||||
|
import fileUrl from 'file-url'
|
||||||
|
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'run-scan',
|
||||||
|
components: {},
|
||||||
|
props: [],
|
||||||
|
mounted () {
|
||||||
|
},
|
||||||
|
beforeDestroy () {
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
scanAPT () {
|
||||||
|
try {
|
||||||
|
const winURL = process.env.NODE_ENV === 'development'
|
||||||
|
? `http://localhost:9080/src/renderer/utils/worker.js`
|
||||||
|
: `file://${__dirname}/worker.js`
|
||||||
|
console.log('make a worker: ', path.resolve(__dirname, 'worker.js'))
|
||||||
|
|
||||||
|
const worker = new Worker(winURL)
|
||||||
|
console.log(fileUrl('src/renderer/utils/worker.js'))
|
||||||
|
|
||||||
|
// var worker = new Worker(fileUrl('src/renderer/utils/worker.js'))
|
||||||
|
worker.postMessage('scanapt')
|
||||||
|
// the reply
|
||||||
|
worker.onmessage = function (e) {
|
||||||
|
if (e.data === 'DONE') {
|
||||||
|
console.log('DONE')
|
||||||
|
}
|
||||||
|
console.log(e.data)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scanGroundnets () {
|
||||||
|
try {
|
||||||
|
const winURL = process.env.NODE_ENV === 'development'
|
||||||
|
? `http://localhost:9080/src/renderer/utils/worker.js`
|
||||||
|
: `file://${__dirname}/worker.js`
|
||||||
|
console.log('make a worker: ', path.resolve(__dirname, 'worker.js'))
|
||||||
|
|
||||||
|
const worker = new Worker(winURL)
|
||||||
|
console.log(fileUrl('src/renderer/utils/worker.js'))
|
||||||
|
|
||||||
|
// var worker = new Worker(fileUrl('src/renderer/utils/worker.js'))
|
||||||
|
worker.postMessage('scan')
|
||||||
|
// the reply
|
||||||
|
worker.onmessage = function (e) {
|
||||||
|
if (e.data === 'DONE') {
|
||||||
|
console.log('DONE')
|
||||||
|
}
|
||||||
|
console.log(e.data)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scanTraffic () {
|
||||||
|
// let flightgearDirectory = this.$store.state.settings.flightgearDirectory
|
||||||
|
try {
|
||||||
|
const winURL = process.env.NODE_ENV === 'development'
|
||||||
|
? `http://localhost:9080/src/renderer/utils/worker.js`
|
||||||
|
: `file://${__dirname}/worker.js`
|
||||||
|
console.log('make a worker: ', path.resolve(__dirname, 'worker.js'))
|
||||||
|
|
||||||
|
const worker = new Worker(winURL)
|
||||||
|
console.log(fileUrl('src/renderer/utils/worker.js'))
|
||||||
|
|
||||||
|
// var worker = new Worker(fileUrl('src/renderer/utils/worker.js'))
|
||||||
|
worker.postMessage('scanai')
|
||||||
|
// the reply
|
||||||
|
worker.onmessage = function (e) {
|
||||||
|
if (e.data === 'DONE') {
|
||||||
|
console.log('DONE')
|
||||||
|
}
|
||||||
|
console.log(e.data)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,34 +1,62 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1 class="leaflet-sidebar-header">
|
||||||
|
Settings
|
||||||
|
<div class="leaflet-sidebar-close">
|
||||||
|
<i class="fa fa-caret-left"></i>
|
||||||
|
</div>
|
||||||
|
</h1>
|
||||||
|
<div id="panel" width="100%">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="7">Flightgear Directory</el-col>
|
||||||
|
<el-col :span="15">{{ flightgear_directory }}</el-col>
|
||||||
|
<el-col :span="2">
|
||||||
|
<directory-select @input="directorySelect"></directory-select>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="js">
|
<script lang="js">
|
||||||
|
import FileSelect from './FileSelect'
|
||||||
|
import DirectorySelect from './DirectorySelect'
|
||||||
export default {
|
export default {
|
||||||
name: 'settings-panel',
|
name: 'settings-panel',
|
||||||
|
components: { DirectorySelect, FileSelect },
|
||||||
props: [],
|
props: [],
|
||||||
mounted () {
|
mounted () {
|
||||||
if (this.$parent._isMounted) {
|
|
||||||
this.$parent.sidebar.addPanel({
|
|
||||||
id: 'settings',
|
|
||||||
tab: '<i class="fa fa-gear vertical-center"/>',
|
|
||||||
title: 'Settings',
|
|
||||||
pane: '<div id="settings-div"></div>'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
selected: 'Undefined'
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
buttonClick: function () {
|
||||||
|
this.$store.commit('TOGGLE_HYDRATED')
|
||||||
|
},
|
||||||
|
directorySelect: function (flightgearDirectory) {
|
||||||
|
console.log(flightgearDirectory)
|
||||||
|
this.$store.commit('SETTINGS_DIRECTORY', flightgearDirectory.path)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
hydrated: function () {
|
||||||
|
return this.$store.state.hydrated
|
||||||
|
},
|
||||||
|
flightgear_directory: function () {
|
||||||
|
return this.$store.state.settings.flightgearDirectory
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style>
|
||||||
|
.el-row {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.el-col {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
19
src/renderer/db/index.js
Normal file
19
src/renderer/db/index.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import VueIdb from 'vue-idb'
|
||||||
|
|
||||||
|
Vue.use(VueIdb)
|
||||||
|
|
||||||
|
export default new VueIdb({
|
||||||
|
database: 'test',
|
||||||
|
schemas: [
|
||||||
|
{ tests: 'id, label, created_at, updated_at' }
|
||||||
|
],
|
||||||
|
options: {
|
||||||
|
tests: { type: 'list', primary: 'id', label: 'title', updated_at: 'updated_at' }
|
||||||
|
},
|
||||||
|
apis: {
|
||||||
|
bigs: {
|
||||||
|
all: () => axios.get('/dev/data/data.json')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
24
src/renderer/store/index copy.js
Normal file
24
src/renderer/store/index copy.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
|
import L from 'leaflet'
|
||||||
|
|
||||||
|
import { createPersistedState, createSharedMutations } from 'vuex-electron'
|
||||||
|
|
||||||
|
import modules from './modules'
|
||||||
|
|
||||||
|
Vue.use(Vuex)
|
||||||
|
|
||||||
|
export default new Vuex.Store({
|
||||||
|
modules,
|
||||||
|
plugins: [
|
||||||
|
createPersistedState(),
|
||||||
|
createSharedMutations()
|
||||||
|
],
|
||||||
|
strict: process.env.NODE_ENV !== 'production',
|
||||||
|
state: { zoom: 13,
|
||||||
|
center: L.latLng(47.413220, -1.219482),
|
||||||
|
url: 'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
|
||||||
|
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
|
||||||
|
marker: L.latLng(47.413220, -1.219482)}
|
||||||
|
})
|
@ -1,24 +1,25 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
|
// import from 'electron-settings'
|
||||||
import L from 'leaflet'
|
import createPersistedState from 'vuex-persistedstate'
|
||||||
|
|
||||||
import { createPersistedState, createSharedMutations } from 'vuex-electron'
|
|
||||||
|
|
||||||
import modules from './modules'
|
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
modules,
|
state: {
|
||||||
plugins: [
|
settings: { flightgearDirectory: '.' }
|
||||||
createPersistedState(),
|
},
|
||||||
createSharedMutations()
|
actions: {
|
||||||
],
|
},
|
||||||
strict: process.env.NODE_ENV !== 'production',
|
mutations: {
|
||||||
state: { zoom: 13,
|
'DELETE_INDEXED_DB' () {},
|
||||||
center: L.latLng(47.413220, -1.219482),
|
'SETTINGS_DIRECTORY' (state, flightgearDirectory) {
|
||||||
url: 'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
|
state.settings.flightgearDirectory = flightgearDirectory
|
||||||
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
|
}
|
||||||
marker: L.latLng(47.413220, -1.219482)}
|
},
|
||||||
|
getters: {
|
||||||
|
hydrated: state => state.hydrated
|
||||||
|
},
|
||||||
|
plugins: [createPersistedState()],
|
||||||
|
strict: true
|
||||||
})
|
})
|
||||||
|
25
src/renderer/store/modules/Airports.js
Normal file
25
src/renderer/store/modules/Airports.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
const state = {
|
||||||
|
main: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const mutations = {
|
||||||
|
DECREMENT_MAIN_COUNTER (state) {
|
||||||
|
state.main--
|
||||||
|
},
|
||||||
|
INCREMENT_MAIN_COUNTER (state) {
|
||||||
|
state.main++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
someAsyncTask ({ commit }) {
|
||||||
|
// do something async
|
||||||
|
commit('INCREMENT_MAIN_COUNTER')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
state,
|
||||||
|
mutations,
|
||||||
|
actions
|
||||||
|
}
|
25
src/renderer/store/modules/Settings.js
Normal file
25
src/renderer/store/modules/Settings.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
const state = {
|
||||||
|
flightgearPath: ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const mutations = {
|
||||||
|
DECREMENT_MAIN_COUNTER (state) {
|
||||||
|
state.main--
|
||||||
|
},
|
||||||
|
INCREMENT_MAIN_COUNTER (state) {
|
||||||
|
state.main++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
someAsyncTask ({ commit }) {
|
||||||
|
// do something async
|
||||||
|
commit('INCREMENT_MAIN_COUNTER')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
state,
|
||||||
|
mutations,
|
||||||
|
actions
|
||||||
|
}
|
22
src/renderer/txml/LICENSE.txt
Normal file
22
src/renderer/txml/LICENSE.txt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Tobias Nickel
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
149
src/renderer/txml/README.md.txt
Normal file
149
src/renderer/txml/README.md.txt
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
# tXml
|
||||||
|
a very small and probably the fastest xml parser in pure javascript.
|
||||||
|
|
||||||
|
This lib only provides one single method. **tXml()**
|
||||||
|
|
||||||
|
1. this code is about 230 lines, can be easily extended.
|
||||||
|
2. this code is 0.9kb minified + gzipped.
|
||||||
|
3. this code is 5 - 10 times faster then sax/xml2js.
|
||||||
|
4. this code can running in a worker.
|
||||||
|
5. this code is parsing at average the same speed as native DOMParser + potential to be faster.
|
||||||
|
6. this code is easy to read and good for study.
|
||||||
|
7. this code creates a domObject with minimal footprint, that is easy to traverse.
|
||||||
|
8. this code has proven in different projects, like RSS reader, openStreetmap, websites.
|
||||||
|
9. this code can even parse handwritten XML that contains various errors.
|
||||||
|
10. this code is working in client and server.
|
||||||
|
11. this code is 100% covered by unit tests.
|
||||||
|
|
||||||
|
so, there are good reasons to give tXml.js a try.
|
||||||
|
|
||||||
|
## XML - features
|
||||||
|
1. tags
|
||||||
|
2. childTags
|
||||||
|
3. text-nodes
|
||||||
|
4. white-spaces
|
||||||
|
5. attributes with single and double quotes
|
||||||
|
6. attributes without value
|
||||||
|
7. xmlComments (ignored)
|
||||||
|
8. embedded CSS and Javascript
|
||||||
|
9. HTML singleTag elements br, img, link, meta, hr
|
||||||
|
10. doctype definitions
|
||||||
|
11. xml namespaces
|
||||||
|
12. sync API for a sync process
|
||||||
|
13. getElementsById/-Class direct on the xmlString
|
||||||
|
14. simplify, similar to PHP's [SimpleXML](http://php.net/manual/en/book.simplexml.php)
|
||||||
|
15. filter, similar to underscore, as a alternative to CSS selectors
|
||||||
|
16. monomorphism for fast processing and fewer if statements (a node always has tagName:'', attributes:{} and children:[])
|
||||||
|
|
||||||
|
17. streamSupport ! ! !
|
||||||
|
|
||||||
|
## Try Online
|
||||||
|
you can to some test without installing online: [tnickel.de](http://tnickel.de/2017/04/02/txml-online/)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
In browser you load it how ever you want. For example as tag: <script src="tXml.js"></script>.
|
||||||
|
|
||||||
|
In node and browseryfy, run **"npm install txml"** in your project.
|
||||||
|
and then in your script you require it by "var tXml = require('txml');
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
|
||||||
|
### **tXml** *(XML-string, options)*
|
||||||
|
1. **XML string** is the XML to parse.
|
||||||
|
2. **options** is optional
|
||||||
|
**searchId** an ID of some object. that can be queried. Using this is incredible fast.
|
||||||
|
**filter** a method, to filter for interesting nodes, use it like Array.filter.
|
||||||
|
**simplify** to simplify the object, to an easier access
|
||||||
|
|
||||||
|
|
||||||
|
EXAMPLE 1: tXml("<user is='great'><name>Tobias</name><familyName>Nickel</familyName><profession>Software Developer</profession><location>Shanghai / China</location></user>");
|
||||||
|
```js
|
||||||
|
// will return an object like:
|
||||||
|
[{
|
||||||
|
"tagName": "user",
|
||||||
|
"attributes": {
|
||||||
|
"is": "great"
|
||||||
|
},
|
||||||
|
"children": [{
|
||||||
|
"tagName": "name",
|
||||||
|
"children": [ "Tobias" ]
|
||||||
|
}, {
|
||||||
|
"tagName": "familyName",
|
||||||
|
"children": [ "Nickel" ]
|
||||||
|
}, {
|
||||||
|
"tagName": "profession",
|
||||||
|
"children": [ "Software Developer" ]
|
||||||
|
}, {
|
||||||
|
"tagName": "location",
|
||||||
|
"children": [ "Shanghai / China" ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
EXAMLPLE 2: tXml("<user is='great'><name>Tobias</name><familyName>Nickel</familyName><profession>Software Developer</profession><location>Shanghai / China</location></user>",{simplify:1});
|
||||||
|
|
||||||
|
```js
|
||||||
|
// will return an object like:
|
||||||
|
{
|
||||||
|
"user": {
|
||||||
|
"name": "Tobias",
|
||||||
|
"familyName": "Nickel",
|
||||||
|
"profession": "Software Developer",
|
||||||
|
"location": "Shanghai / China",
|
||||||
|
"_attributes": {
|
||||||
|
"is": "great"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### **tXml.simpify** *(tXml_DOM_Object)*
|
||||||
|
this method is used with the simplify parameter;
|
||||||
|
1. **tXml_DOM_Object** the object to simplify.
|
||||||
|
|
||||||
|
### **tXml.filter** *(tXml_DOM_Object, f)*
|
||||||
|
this method is used with the filter parameter, it is used like Array.filter.
|
||||||
|
1. **tXml_DOM_Object** the object to filter.
|
||||||
|
2. **f** a function that returns true if you want this elements in the result set.
|
||||||
|
|
||||||
|
### **tXml.getElementById** (xml,id)
|
||||||
|
to find an element by ID. if you are only interested for the information on, a specific node, this is easy and fast, because not the entire xml need to get parsed to a tDOM Object. returns the element not simplified, you can do with tXml.simplify()
|
||||||
|
1. **xml** the xml string to search in.
|
||||||
|
2. **id** the id of the element to find
|
||||||
|
|
||||||
|
|
||||||
|
### **tXml.getElementsByClassName** (xml,className)
|
||||||
|
find the elements with the given class, without parsing the entire xml into a tDOM. so it is very fast and convenient. returns a list of elements.
|
||||||
|
1. **xml** the xml string to search in.
|
||||||
|
2. **className** the className of the element to find
|
||||||
|
|
||||||
|
|
||||||
|
### **txml.parseStream** (stream, offset)
|
||||||
|
1. stream is the stream or fileName,
|
||||||
|
2. offset requires you to set short before the first item.
|
||||||
|
usually files begin with simething like "<!DOCTYPE osm><osm>"
|
||||||
|
so the offset need to be before the first item starts so that
|
||||||
|
between that item and the offset is no "<" character.
|
||||||
|
alternatively, pass astring, containing this preample.
|
||||||
|
return stream, triggers even "xml" to get notified when a complete node has been parsed.
|
||||||
|
is usefull for huge files, OSM-world, wikipedia-dump.
|
||||||
|
|
||||||
|
### **txml.transformStream** (offset)
|
||||||
|
2. offset optional you to set short before the first item.
|
||||||
|
usually files begin with simething like "<!DOCTYPE osm><osm>"
|
||||||
|
so the offset need to be before the first item starts so that
|
||||||
|
between that item and the offset is no "<" character.
|
||||||
|
alternatively, pass astring, containing this preample.
|
||||||
|
return transformStream.
|
||||||
|
```js
|
||||||
|
const xmlStream = fs.createReadStream('your.xml').pipe(txml.transformStream())
|
||||||
|
for await(let element of xmlStream) {
|
||||||
|
// your logic here ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Developer
|
||||||
|
[Tobias Nickel](http://tnickel.de/) German software developer in Shanghai.
|
||||||
|
![alt text](https://avatars1.githubusercontent.com/u/4189801?s=150)
|
7
src/renderer/txml/tXml.min.js
vendored
Normal file
7
src/renderer/txml/tXml.min.js
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
function tXml(a,c){function d(){for(var c=[];a[b];)if(60==a.charCodeAt(b)){if(47===a.charCodeAt(b+1)){b=a.indexOf(">",b);b+1&&(b+=1);break}else if(33===a.charCodeAt(b+1)){if(45==a.charCodeAt(b+2)){for(;-1!==b&&(62!==a.charCodeAt(b)||45!=a.charCodeAt(b-1)||45!=a.charCodeAt(b-2)||-1==b);)b=a.indexOf(">",b+1);-1===b&&(b=a.length)}else for(b+=2;62!==a.charCodeAt(b)&&a[b];)b++;b++;continue}var d=g();c.push(d)}else d=b,b=a.indexOf("<",b)-1,-2===b&&(b=a.length),d=a.slice(d,b+1),0<d.trim().length&&c.push(d),
|
||||||
|
b++;return c}function k(){for(var c=b;-1===m.indexOf(a[b])&&a[b];)b++;return a.slice(c,b)}function g(){b++;for(var c=k(),g={},f=[];62!==a.charCodeAt(b)&&a[b];){var e=a.charCodeAt(b);if(64<e&&91>e||96<e&&123>e){var h=k();for(e=a.charCodeAt(b);e&&39!==e&&34!==e&&!(64<e&&91>e||96<e&&123>e)&&62!==e;)b++,e=a.charCodeAt(b);if(39===e||34===e){e=a[b];var l=++b;b=a.indexOf(e,l);e=a.slice(l,b);if(-1===b)return{tagName:c,attributes:g,children:f}}else e=null,b--;g[h]=e}b++}47!==a.charCodeAt(b-1)?"script"==c?
|
||||||
|
(f=b+1,b=a.indexOf("\x3c/script>",b),f=[a.slice(f,b-1)],b+=9):"style"==c?(f=b+1,b=a.indexOf("</style>",b),f=[a.slice(f,b-1)],b+=8):-1==n.indexOf(c)&&(b++,f=d(h)):b++;return{tagName:c,attributes:g,children:f}}function f(){var b=(new RegExp("\\s"+c.attrName+"\\s*=['\"]"+c.attrValue+"['\"]")).exec(a);return b?b.index:-1}c=c||{};var b=c.pos||0,m="\n\t>/= ",n=c.noChildNodes||["img","br","input","meta","link"],h=null;if(void 0!==c.attrValue)for(c.attrName=c.attrName||"id",h=[];-1!==(b=f());)b=a.lastIndexOf("<",
|
||||||
|
b),-1!==b&&h.push(g()),a=a.substr(b),b=0;else h=c.parseNode?g():d();c.filter&&(h=tXml.filter(h,c.filter));c.setPos&&(h.pos=b);return h}tXml.simplify=function(a){var c={};if(!a.length)return"";if(1===a.length&&"string"==typeof a[0])return a[0];a.forEach(function(a){if("object"===typeof a){c[a.tagName]||(c[a.tagName]=[]);var d=tXml.simplify(a.children||[]);c[a.tagName].push(d);a.attributes&&(d._attributes=a.attributes)}});for(var d in c)1==c[d].length&&(c[d]=c[d][0]);return c};
|
||||||
|
tXml.filter=function(a,c){var d=[];a.forEach(function(a){"object"===typeof a&&c(a)&&d.push(a);a.children&&(a=tXml.filter(a.children,c),d=d.concat(a))});return d};
|
||||||
|
tXml.stringify=function(a){function c(a){if(a)for(var g=0;g<a.length;g++)if("string"==typeof a[g])d+=a[g].trim();else{var f=void 0,b=a[g];d+="<"+b.tagName;for(f in b.attributes)d=null===b.attributes[f]?d+(" "+f):-1===b.attributes[f].indexOf('"')?d+(" "+f+'="'+b.attributes[f].trim()+'"'):d+(" "+f+"='"+b.attributes[f].trim()+"'");d+=">";c(b.children);d+="</"+b.tagName+">"}}var d="";c(a);return d};
|
||||||
|
tXml.toContentString=function(a){if(Array.isArray(a)){var c="";a.forEach(function(a){c+=" "+tXml.toContentString(a);c=c.trim()});return c}return"object"===typeof a?tXml.toContentString(a.children):" "+a};tXml.getElementById=function(a,c,d){a=tXml(a,{attrValue:c});return d?tXml.simplify(a):a[0]};tXml.getElementsByClassName=function(a,c,d){a=tXml(a,{attrName:"class",attrValue:"[a-zA-Z0-9-s ]*"+c+"[a-zA-Z0-9-s ]*"});return d?tXml.simplify(a):a};
|
95
src/renderer/utils/airports copy.js
Normal file
95
src/renderer/utils/airports copy.js
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
const loki = require('lokijs');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
var db = new loki('airports_DB.json');
|
||||||
|
var features = null;
|
||||||
|
|
||||||
|
export async function init() {
|
||||||
|
var promise = new Promise(function (resolve, reject) {
|
||||||
|
console.log("Init " + (features == null));
|
||||||
|
if (features == null) {
|
||||||
|
console.log("Loading DB");
|
||||||
|
db.loadDatabase({}, function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error("Error loading DB");
|
||||||
|
console.error(err);
|
||||||
|
db.addCollection('features', {
|
||||||
|
unique: ["properties.icao"], autoupdate: true
|
||||||
|
});
|
||||||
|
features = db.getCollection('features');
|
||||||
|
}
|
||||||
|
features = db.getCollection('features');
|
||||||
|
if( features == null ){
|
||||||
|
db.addCollection('features', {
|
||||||
|
unique: ["properties.icao"], autoupdate: true
|
||||||
|
});
|
||||||
|
features = db.getCollection('features');
|
||||||
|
}
|
||||||
|
console.log("Loaded " + features.count() + " features");
|
||||||
|
resolve(features);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resolve(features);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAirport(apts, icao) {
|
||||||
|
console.log("Getting Airport " + icao);
|
||||||
|
var results = apts.where(function (f) {
|
||||||
|
return f.properties['icao'] === icao;
|
||||||
|
});
|
||||||
|
var feature;
|
||||||
|
if (results.length == 0) {
|
||||||
|
feature = {
|
||||||
|
"type": "Feature",
|
||||||
|
'properties': { 'icao': icao, 'twr': false, 'threshold': false, 'flights': 0 },
|
||||||
|
'geometry': {
|
||||||
|
"type": "Point"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
feature = apts.insert(feature);
|
||||||
|
// apts.update(feature);
|
||||||
|
console.log("Added New");
|
||||||
|
console.log(JSON.stringify(feature));
|
||||||
|
return feature;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.debug("retrieved " + JSON.stringify(results[0]));
|
||||||
|
return results[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export function save() {
|
||||||
|
if (!features || !features.data)
|
||||||
|
return;
|
||||||
|
var mappedData = features.data.map(function (f) {
|
||||||
|
delete f.meta;
|
||||||
|
delete f.$loki;
|
||||||
|
if(f.properties.airlines) {
|
||||||
|
f.properties.airlines = f.properties.airlines.join(' ');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
f.properties.airlines = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return f;
|
||||||
|
});
|
||||||
|
|
||||||
|
mappedData = mappedData.filter(feature => feature.properties['twr'] || feature.properties['threshold']);
|
||||||
|
|
||||||
|
//console.log(mappedData);
|
||||||
|
var featureCollection = { type: "FeatureCollection", features: mappedData };
|
||||||
|
|
||||||
|
let data = JSON.stringify(featureCollection, null, 2);
|
||||||
|
fs.writeFileSync('airports.json', data);
|
||||||
|
db.saveDatabase(function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
143
src/renderer/utils/airports.js
Normal file
143
src/renderer/utils/airports.js
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
var features = null;
|
||||||
|
|
||||||
|
async function initDB() {
|
||||||
|
var promise = new Promise(function (resolve, reject) {
|
||||||
|
console.log("Init " + (features == null));
|
||||||
|
if (features == null) {
|
||||||
|
console.log("Loading DB");
|
||||||
|
console.log(this.indexedDB);
|
||||||
|
// var deleteRequest = indexedDB.deleteDatabase("flightgear");
|
||||||
|
// deleteRequest.onerror = function (event) {
|
||||||
|
// console.log(event);
|
||||||
|
// reject(event);
|
||||||
|
// };
|
||||||
|
// deleteRequest.onsuccess = function (event) {
|
||||||
|
// console.log(event);
|
||||||
|
// };
|
||||||
|
|
||||||
|
var request = this.indexedDB.open("flightgear", 2);
|
||||||
|
request.onerror = function (event) {
|
||||||
|
reject(event);
|
||||||
|
};
|
||||||
|
request.onsuccess = function (event) {
|
||||||
|
console.log('Opened DB ' + event);
|
||||||
|
|
||||||
|
features = request.result;
|
||||||
|
resolve(features);
|
||||||
|
};
|
||||||
|
request.onupgradeneeded = function (event) {
|
||||||
|
var db = event.target.result;
|
||||||
|
console.log("Migrate " + event);
|
||||||
|
|
||||||
|
// Create an objectStore to hold information about our customers. We're
|
||||||
|
// going to use "ssn" as our key path because it's guaranteed to be
|
||||||
|
// unique.
|
||||||
|
if (event.oldVersion < 1) {
|
||||||
|
// Version 1 is the first version of the database.
|
||||||
|
var objectStore = db.createObjectStore("airports", { keyPath: "properties.icao" });
|
||||||
|
}
|
||||||
|
if (event.oldVersion < 2) {
|
||||||
|
// Version 1 is the first version of the database.
|
||||||
|
var objectStore = event.target.transaction.objectStore("airports");
|
||||||
|
var indexNames = objectStore.indexNames;
|
||||||
|
var desiredKeyPathForMyIndex = "properties.icao";
|
||||||
|
console.log(indexNames);
|
||||||
|
|
||||||
|
if(indexNames.contains('myIndexName')) {
|
||||||
|
var myIndex = objectStore.index('myIndexName');
|
||||||
|
var currentKeyPath = myIndex.keyPath;
|
||||||
|
if(currentKeyPath != desiredKeyPathForMyIndex) {
|
||||||
|
objectStore.deleteIndex('myIndexName');
|
||||||
|
objectStore.createIndex('myIndexName', desiredKeyPathForMyIndex);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
objectStore.createIndex('myIndexName', desiredKeyPathForMyIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
// db.loadDatabase({}, function (err) {
|
||||||
|
// if (err) {
|
||||||
|
// console.error("Error loading DB");
|
||||||
|
// console.error(err);
|
||||||
|
// db.addCollection('features', {
|
||||||
|
// unique: ["properties.icao"], autoupdate: true
|
||||||
|
// });
|
||||||
|
// features = db.getCollection('features');
|
||||||
|
// }
|
||||||
|
// features = db.getCollection('features');
|
||||||
|
// if( features == null ){
|
||||||
|
// db.addCollection('features', {
|
||||||
|
// unique: ["properties.icao"], autoupdate: true
|
||||||
|
// });
|
||||||
|
// features = db.getCollection('features');
|
||||||
|
// }
|
||||||
|
// console.log("Loaded " + features.count() + " features");
|
||||||
|
// resolve(features);
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resolve(features);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAirport(apts, icao) {
|
||||||
|
console.log("Getting Airport " + icao);
|
||||||
|
var results = apts.where(function (f) {
|
||||||
|
return f.properties['icao'] === icao;
|
||||||
|
});
|
||||||
|
var feature;
|
||||||
|
if (results.length == 0) {
|
||||||
|
feature = {
|
||||||
|
"type": "Feature",
|
||||||
|
'properties': { 'icao': icao, 'twr': false, 'threshold': false, 'flights': 0 },
|
||||||
|
'geometry': {
|
||||||
|
"type": "Point"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
feature = apts.insert(feature);
|
||||||
|
// apts.update(feature);
|
||||||
|
console.log("Added New");
|
||||||
|
console.log(JSON.stringify(feature));
|
||||||
|
return feature;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.debug("retrieved " + JSON.stringify(results[0]));
|
||||||
|
return results[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
if (!features || !features.data)
|
||||||
|
return;
|
||||||
|
var mappedData = features.data.map(function (f) {
|
||||||
|
delete f.meta;
|
||||||
|
delete f.$loki;
|
||||||
|
if (f.properties.airlines) {
|
||||||
|
f.properties.airlines = f.properties.airlines.join(' ');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
f.properties.airlines = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return f;
|
||||||
|
});
|
||||||
|
|
||||||
|
mappedData = mappedData.filter(feature => feature.properties['twr'] || feature.properties['threshold']);
|
||||||
|
|
||||||
|
//console.log(mappedData);
|
||||||
|
var featureCollection = { type: "FeatureCollection", features: mappedData };
|
||||||
|
|
||||||
|
let data = JSON.stringify(featureCollection, null, 2);
|
||||||
|
fs.writeFileSync('airports.json', data);
|
||||||
|
// db.saveDatabase(function (err) {
|
||||||
|
// if (err) {
|
||||||
|
// console.error(err);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
}
|
50
src/renderer/utils/apt copy.js
Normal file
50
src/renderer/utils/apt copy.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
const lineReader = require('readline');
|
||||||
|
const fs = require('fs');
|
||||||
|
const airports = require('./airports');
|
||||||
|
|
||||||
|
var scanMethods = {
|
||||||
|
1: (l, apts) => {
|
||||||
|
console.log('Airport:', l);
|
||||||
|
|
||||||
|
var airportFeature = airports.getAirport(apts, l[4]);
|
||||||
|
console.log(JSON.stringify(airportFeature));
|
||||||
|
airportFeature.properties.name = l.slice(5).join(' ').replace('\t', ' ');
|
||||||
|
console.debug(airportFeature.properties.name);
|
||||||
|
// apts.update(airportFeature);
|
||||||
|
},
|
||||||
|
99: (l) => {
|
||||||
|
console.log('Finished');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function scan (f, apts) {
|
||||||
|
console.log(f);
|
||||||
|
lineReader.createInterface({
|
||||||
|
input: fs.createReadStream(f)
|
||||||
|
}).on('line', function (line) {
|
||||||
|
var fields = line.split(/[ ]+/);
|
||||||
|
// var fields = line.match('([0-9]+)');
|
||||||
|
if (fields == null)
|
||||||
|
return;
|
||||||
|
var scanMethod = scanMethods[fields[0]];
|
||||||
|
if (scanMethod != null) {
|
||||||
|
scanMethod(fields, apts);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (fields[0] == '99') {
|
||||||
|
lineReader.close();
|
||||||
|
}
|
||||||
|
// console.log('Ignored:', line);
|
||||||
|
}
|
||||||
|
}).on('error', function (err) {
|
||||||
|
console.log(err);
|
||||||
|
lr.close();
|
||||||
|
}).on('close', function () {
|
||||||
|
console.log("End");
|
||||||
|
airports.save();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// export default { scan, name }
|
||||||
|
|
90
src/renderer/utils/apt.js
Normal file
90
src/renderer/utils/apt.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
const lineReader = require('readline');
|
||||||
|
|
||||||
|
var scanMethods = {
|
||||||
|
1: (l, apts) => {
|
||||||
|
console.log('Airport:', l);
|
||||||
|
saveName(apts, l[4], l.slice(5).join(' ').replace('\t', ' '));
|
||||||
|
},
|
||||||
|
99: (l) => {
|
||||||
|
console.log('Finished');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function saveName(features, icao, name) {
|
||||||
|
var promise = new Promise(function (resolve, reject) {
|
||||||
|
|
||||||
|
var transaction = features.transaction("airports", "readwrite");
|
||||||
|
var objectStore = transaction.objectStore("airports");
|
||||||
|
var objectStoreRequest = objectStore.get(icao);
|
||||||
|
|
||||||
|
objectStoreRequest.onsuccess = function (event) {
|
||||||
|
console.log(event);
|
||||||
|
var feature = objectStoreRequest.result;
|
||||||
|
if (!feature) {
|
||||||
|
feature = {
|
||||||
|
"type": "Feature",
|
||||||
|
'properties': { 'icao': icao, 'twr': false, 'threshold': false, 'flights': 0, airlines: [] },
|
||||||
|
'geometry': {
|
||||||
|
"type": "Point"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
feature.properties.name = name;
|
||||||
|
feature.properties.icao = icao;
|
||||||
|
console.log("ICAO : " + feature.properties.icao);
|
||||||
|
// Create another request that inserts the item back into the database
|
||||||
|
var updateAirportRequest = objectStore.put(feature);
|
||||||
|
|
||||||
|
// Log the transaction that originated this request
|
||||||
|
console.log("The transaction that originated this request is " + updateAirportRequest.updateAirportRequest);
|
||||||
|
|
||||||
|
// When this new request succeeds, run the displayData() function again to update the display
|
||||||
|
updateAirportRequest.onsuccess = function () {
|
||||||
|
console.log("Stored");
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
updateAirportRequest.onerror = function (event) {
|
||||||
|
console.log("Error " + event);
|
||||||
|
reject(event);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
objectStoreRequest.onerror = function (event) {
|
||||||
|
console.log("Error " + event);
|
||||||
|
reject(event);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function scanAPTIntoDB(f, apts) {
|
||||||
|
console.log(f);
|
||||||
|
lineReader.createInterface({
|
||||||
|
input: fs.createReadStream(f)
|
||||||
|
}).on('line', function (line) {
|
||||||
|
var fields = line.split(/[ ]+/);
|
||||||
|
// var fields = line.match('([0-9]+)');
|
||||||
|
if (fields == null)
|
||||||
|
return;
|
||||||
|
var scanMethod = scanMethods[fields[0]];
|
||||||
|
if (scanMethod != null) {
|
||||||
|
scanMethod(fields, apts);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (fields[0] == '99') {
|
||||||
|
lineReader.close();
|
||||||
|
}
|
||||||
|
// console.log('Ignored:', line);
|
||||||
|
}
|
||||||
|
}).on('error', function (err) {
|
||||||
|
console.log(err);
|
||||||
|
lr.close();
|
||||||
|
}).on('close', function () {
|
||||||
|
console.log("End");
|
||||||
|
apts.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// export default { scan, name }
|
||||||
|
|
386
src/renderer/utils/scan.js
Normal file
386
src/renderer/utils/scan.js
Normal file
@ -0,0 +1,386 @@
|
|||||||
|
|
||||||
|
/* eslint-disable */
|
||||||
|
// const fs = require('fs');
|
||||||
|
// const path = require('path');
|
||||||
|
// const math = require('mathjs');
|
||||||
|
// const util = require('util');
|
||||||
|
// const airports = require('./airports.js');
|
||||||
|
// const homedir = require('os').homedir();
|
||||||
|
// const apt = require('apt.js');
|
||||||
|
|
||||||
|
async function asyncForEach(array, callback) {
|
||||||
|
console.log("Len " + array.length);
|
||||||
|
for (let index = 0; index < array.length; index++) {
|
||||||
|
try {
|
||||||
|
var res = await callback(array[index], index, array);
|
||||||
|
console.log("Index " + index + " " + res);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function scanAPT_Old(p) {
|
||||||
|
return airports.init().then(features => {
|
||||||
|
var d = path.join(homedir, 'Documents/apt.dat');
|
||||||
|
console.log(d);
|
||||||
|
apt.scan(d, features);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function waitFor(milliseconds) {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function scanGroundnetFiles(p, features) {
|
||||||
|
var promise = new Promise(function (resolve, reject) {
|
||||||
|
try {
|
||||||
|
console.log('Start Groundnets ' + p);
|
||||||
|
var files = traverseDir(p);
|
||||||
|
console.log(files);
|
||||||
|
|
||||||
|
asyncForEach(files, async f => {
|
||||||
|
//await waitFor(5000);
|
||||||
|
try {
|
||||||
|
var text = await readGroundnet(f, features);
|
||||||
|
console.log(text);
|
||||||
|
resolve(text);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
}).then(t => {
|
||||||
|
console.log("Finished");
|
||||||
|
features.close();
|
||||||
|
resolve();
|
||||||
|
}).catch(reason => {
|
||||||
|
console.log("Crashed");
|
||||||
|
console.log(reason);
|
||||||
|
features.close()
|
||||||
|
});
|
||||||
|
|
||||||
|
//walkDir(p, f => { readGroundnet(f, features) });
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function scanTrafficIntoDB(p, features) {
|
||||||
|
try {
|
||||||
|
console.log('Start Traffic ' + p + ' ' + features);
|
||||||
|
var objectStore = features.transaction("airports").objectStore("airports");
|
||||||
|
|
||||||
|
objectStore.openCursor().onsuccess = function (event) {
|
||||||
|
var cursor = event.target.result;
|
||||||
|
if (cursor) {
|
||||||
|
feature.value.properties.flights = 0
|
||||||
|
feature.value.properties.airlines = [];
|
||||||
|
console.log("Name for SSN " + cursor.key + " is " + cursor.value.name);
|
||||||
|
cursor.continue();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log("No more entries!");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
walkDir(p, f => { readAI(f, features) });
|
||||||
|
console.log("Closing");
|
||||||
|
features.close();
|
||||||
|
console.log("End Traffic");
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function traverseDir(dir) {
|
||||||
|
var result = [];
|
||||||
|
fs.readdirSync(dir).forEach(file => {
|
||||||
|
let fullPath = path.join(dir, file);
|
||||||
|
if (fs.lstatSync(fullPath).isDirectory()) {
|
||||||
|
console.log(fullPath);
|
||||||
|
var children = traverseDir(fullPath);
|
||||||
|
result = result.concat(children);
|
||||||
|
} else {
|
||||||
|
console.log(fullPath);
|
||||||
|
result.push(fullPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function walkDir(dir, callback) {
|
||||||
|
fs.readdirSync(dir).forEach(f => {
|
||||||
|
try {
|
||||||
|
let dirPath = path.join(dir, f);
|
||||||
|
let isDirectory = fs.statSync(dirPath).isDirectory();
|
||||||
|
isDirectory ?
|
||||||
|
walkDir(dirPath, callback) : callback(path.join(dir, f));
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function readAI(f, apts) {
|
||||||
|
try {
|
||||||
|
console.log(path.basename(f));
|
||||||
|
// Reset
|
||||||
|
var airline = path.basename(f).match('([^.]+)');
|
||||||
|
if (airline == null)
|
||||||
|
return;
|
||||||
|
var xmlSource = fs.readFileSync(f, 'utf8').toString();
|
||||||
|
console.debug("read " + path.basename(f));
|
||||||
|
// var doc = new domParser().parseFromString(xmlSource );
|
||||||
|
// console.log("parsed ");
|
||||||
|
// var flights = xpath.select("/trafficlist/flight", doc);
|
||||||
|
// console.log("selected flight ");
|
||||||
|
// console.log(flights);
|
||||||
|
var dat = tXml(xmlSource);
|
||||||
|
// console.log(dat);
|
||||||
|
console.log(dat[0].children[0]);
|
||||||
|
|
||||||
|
var flightNodes = dat[0].children[0].children.filter(e => e.tagName === 'flight');
|
||||||
|
flightNodes = tXml.simplify(flightNodes);
|
||||||
|
|
||||||
|
console.log(flightNodes.flight);
|
||||||
|
|
||||||
|
console.log("Departure flights " + flightNodes.flight.length);
|
||||||
|
|
||||||
|
var merged = new Array();
|
||||||
|
|
||||||
|
flightNodes.flight.map(n => {
|
||||||
|
merged.push(n.departure.port);
|
||||||
|
merged.push(n.arrival.port);
|
||||||
|
}).sort();
|
||||||
|
|
||||||
|
var counts = {};
|
||||||
|
for (var i = 0; i < merged.length; i++) {
|
||||||
|
counts[merged[i]] = 1 + (counts[merged[i]] || 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var key in counts) {
|
||||||
|
store(key, airline[0], counts[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// var flights = xpath.select("/trafficlist/flight/departure/port/text()", doc);
|
||||||
|
// console.log(nodes);
|
||||||
|
// console.log(nodes);
|
||||||
|
// nodes = xpath.select("/trafficlist/flight/arrival/port/text()", doc);
|
||||||
|
// console.log(nodes);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store airline info into DB
|
||||||
|
* @param {*} icao
|
||||||
|
* @param {*} airline
|
||||||
|
* @param {*} value
|
||||||
|
*/
|
||||||
|
|
||||||
|
function store(icao, airline, value) {
|
||||||
|
var promise = new Promise(function (resolve, reject) {
|
||||||
|
console.log("Airport " + icao + " has " + value + " flights");
|
||||||
|
// Make a request to get a record by key from the object store
|
||||||
|
var transaction = features.transaction("airports", "readwrite");
|
||||||
|
var objectStore = transaction.objectStore("airports");
|
||||||
|
var objectStoreRequest = objectStore.get(icao);
|
||||||
|
|
||||||
|
objectStoreRequest.onsuccess = function (event) {
|
||||||
|
console.log(event);
|
||||||
|
var feature = objectStoreRequest.result;
|
||||||
|
if (!feature) {
|
||||||
|
feature = createFeature(icao);
|
||||||
|
}
|
||||||
|
feature.properties.flights += value;
|
||||||
|
console.log("Airline " + airline);
|
||||||
|
feature.properties.airlines.push(airline);
|
||||||
|
feature.properties.airlines.sort();
|
||||||
|
console.log("ICAO : " + feature.properties.icao + " Flights : " + feature.properties.flights);
|
||||||
|
// Create another request that inserts the item back into the database
|
||||||
|
var updateAirportRequest = objectStore.put(feature);
|
||||||
|
|
||||||
|
// Log the transaction that originated this request
|
||||||
|
console.log("The transaction that originated this request is " + updateAirportRequest);
|
||||||
|
|
||||||
|
// When this new request succeeds, run the displayData() function again to update the display
|
||||||
|
updateAirportRequest.onsuccess = function () {
|
||||||
|
console.log("Stored");
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
updateAirportRequest.onerror = function (event) {
|
||||||
|
console.log("Error storing " + event);
|
||||||
|
reject(event);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
objectStoreRequest.onerror = function (event) {
|
||||||
|
console.log("Error " + event);
|
||||||
|
reject(event);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read a groundnet xml file
|
||||||
|
* @param {*} f
|
||||||
|
* @param {*} apts
|
||||||
|
*/
|
||||||
|
|
||||||
|
async function readGroundnet(f, features) {
|
||||||
|
var promise = new Promise(function (resolve, reject) {
|
||||||
|
try {
|
||||||
|
var filename = path.basename(f).match('^([^.]+)\\.([^.]+)\\.([^.]+)');
|
||||||
|
if (filename == null) {
|
||||||
|
resolve("File didn't match");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log('Parsing ' + f);
|
||||||
|
fs.readFile(f, 'utf8', (err, data) => {
|
||||||
|
if (err) {
|
||||||
|
console.log('Error reading file ' + err);
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
console.log(data);
|
||||||
|
var dat = tXml.simplify(tXml(data));
|
||||||
|
console.log('Simplified ' + filename);
|
||||||
|
|
||||||
|
if (dat['?xml']) {
|
||||||
|
console.log("parsed " + f);
|
||||||
|
|
||||||
|
var transaction = features.transaction("airports", "readonly");
|
||||||
|
// report on the success of the transaction completing, when everything is done
|
||||||
|
transaction.oncomplete = function (event) {
|
||||||
|
console.log('Read Transaction complete ' + event);
|
||||||
|
};
|
||||||
|
|
||||||
|
transaction.onerror = function (event) {
|
||||||
|
console.log('Transaction error ' + event);
|
||||||
|
};
|
||||||
|
var objectStore = transaction.objectStore("airports");
|
||||||
|
var objectStoreRequest = objectStore.get(filename[1]);
|
||||||
|
|
||||||
|
objectStoreRequest.onsuccess = function (event) {
|
||||||
|
console.log(dat['?xml'].groundnet);
|
||||||
|
var feature = event.result;
|
||||||
|
console.log("Got Airport : " + feature);
|
||||||
|
if (!feature) {
|
||||||
|
feature = createFeature(filename[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filename[2] == 'threshold') {
|
||||||
|
try {
|
||||||
|
console.log('threshold : ' + filename[1]);
|
||||||
|
var nodes = dat['?xml'].PropertyList.runway;
|
||||||
|
if (nodes.threshold == 0) {
|
||||||
|
console.log("No Runway");
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
nodes.forEach(r => {
|
||||||
|
var lat1 = parseFloat(r.threshold[0].lat);
|
||||||
|
var lon1 = parseFloat(r.threshold[0].lon);
|
||||||
|
var lat2 = parseFloat(r.threshold[1].lat);
|
||||||
|
var lon2 = parseFloat(r.threshold[1].lon);
|
||||||
|
if (!feature.geometry.coordinates) {
|
||||||
|
feature.geometry.coordinates = [mean(lon1, lon2), mean(lat1, lat2)];
|
||||||
|
console.log(feature.geometry.coordinates);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
feature.properties['threshold'] = true;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
} else if (filename[2] == 'twr') {
|
||||||
|
try {
|
||||||
|
console.log('twr : ' + filename[1]);
|
||||||
|
var nodes = dat['?xml'].PropertyList.tower.twr;
|
||||||
|
if (nodes.length == 0) {
|
||||||
|
console.log("No Tower");
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
var lat = parseFloat(nodes.lat);
|
||||||
|
var lon = parseFloat(nodes.lon);
|
||||||
|
feature.properties['twr'] = true;
|
||||||
|
feature.geometry.coordinates = [lon, lat];
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
} else if (filename[2] == 'groundnet') {
|
||||||
|
console.log('groundnet : ' + filename[1]);
|
||||||
|
var nodes = dat['?xml'].groundnet.TaxiNodes;
|
||||||
|
feature['properties']['groundnet'] = nodes ? true : false;
|
||||||
|
var nodes = dat['?xml'].groundnet.Parking;
|
||||||
|
feature['properties']['parking'] = nodes ? true : false;
|
||||||
|
} else if (filename[2] == 'ils') {
|
||||||
|
console.log('ils : ' + filename[1]);
|
||||||
|
if (dat['?xml'].PropertyList.runways) {
|
||||||
|
var nodes = dat['?xml'].PropertyList.runways.ils;
|
||||||
|
feature.properties['ils'] = nodes !== undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var transaction = features.transaction("airports", "readwrite");
|
||||||
|
// report on the success of the transaction completing, when everything is done
|
||||||
|
transaction.oncomplete = function (event) {
|
||||||
|
console.log('Write Transaction complete ' + event);
|
||||||
|
resolve("Stored " + filename[1]);
|
||||||
|
};
|
||||||
|
|
||||||
|
transaction.onerror = function (event) {
|
||||||
|
console.log('Transaction error ' + event);
|
||||||
|
};
|
||||||
|
var objectStore = transaction.objectStore("airports");
|
||||||
|
var updateAirportRequest = objectStore.put(feature);
|
||||||
|
|
||||||
|
// Log the transaction that originated this request
|
||||||
|
console.log("The transaction that originated this request is " + updateAirportRequest.transaction);
|
||||||
|
|
||||||
|
// When this new request succeeds, run the displayData() function again to update the display
|
||||||
|
updateAirportRequest.onsuccess = function () {
|
||||||
|
console.log("Stored");
|
||||||
|
};
|
||||||
|
updateAirportRequest.onerror = function (event) {
|
||||||
|
console.log("Error storing " + event);
|
||||||
|
reject(event);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
objectStoreRequest.onerror = function (event) {
|
||||||
|
console.log("Read Errpr : " + event);
|
||||||
|
resolve(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resolve('No root');
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFeature(icao) {
|
||||||
|
return {
|
||||||
|
"type": "Feature",
|
||||||
|
'properties': { 'icao': icao, 'twr': false, 'threshold': false, 'flights': 0, airlines: [] },
|
||||||
|
'geometry': {
|
||||||
|
"type": "Point"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mean(coord1, coord2) {
|
||||||
|
|
||||||
|
return (coord1 + coord2) / 2;
|
||||||
|
}
|
||||||
|
// export default { scanAPT, scanTraffic, scanGroundnet }
|
81
src/renderer/utils/worker.js
Normal file
81
src/renderer/utils/worker.js
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
const winURL = process.env.NODE_ENV === 'development'
|
||||||
|
? `http://localhost:9080/src/renderer/utils/`
|
||||||
|
: `file://D:/GIT/flightgear-airports/src/renderer/utils/`
|
||||||
|
|
||||||
|
var scanner = importScripts(`${winURL}scan.js`);
|
||||||
|
var apt = importScripts(`${winURL}apt.js`);
|
||||||
|
var path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const homedir = require('os').homedir();
|
||||||
|
var airports = importScripts(`${winURL}airports.js`);
|
||||||
|
importScripts('../txml/tXml.min.js');
|
||||||
|
|
||||||
|
function errorReceiver(event) {
|
||||||
|
throw event.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
onmessage = function (event) {
|
||||||
|
postMessage('scanStarted');
|
||||||
|
console.log(event.data);
|
||||||
|
if (event.data === 'scan') {
|
||||||
|
scanGroundnet().then(result => {
|
||||||
|
console.log("DONE Scanning");
|
||||||
|
postMessage('DONE', 'this');
|
||||||
|
// event.origin.webContents.send('scanFinished');
|
||||||
|
}
|
||||||
|
).catch(result => {
|
||||||
|
console.log('Crashed');
|
||||||
|
console.log(result);
|
||||||
|
});
|
||||||
|
} else if (event.data === 'scanai') {
|
||||||
|
scanai().then(result => {
|
||||||
|
console.log("DONE Scanning");
|
||||||
|
postMessage('DONE');
|
||||||
|
// event.origin.webContents.send('scanFinished');
|
||||||
|
}
|
||||||
|
).catch(result => {
|
||||||
|
console.log('Crashed');
|
||||||
|
console.log(result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (event.data === 'scanapt') {
|
||||||
|
scanAPT().then(result => {
|
||||||
|
console.log("DONE Scanning");
|
||||||
|
postMessage('DONE');
|
||||||
|
// event.origin.webContents.send('scanFinished');
|
||||||
|
}
|
||||||
|
).catch(result => {
|
||||||
|
console.log('Crashed');
|
||||||
|
console.log(result);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function scanGroundnet() {
|
||||||
|
var promise = new Promise(function (resolve, reject) {
|
||||||
|
return initDB().then(features => {
|
||||||
|
var d = path.join(homedir, '/Documents/Flightgear/main/Airports/A');
|
||||||
|
scanGroundnetFiles(d, features);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function scanai() {
|
||||||
|
return initDB().then(features => {
|
||||||
|
scanTrafficIntoDB("C:/GIT/fgmeta/fgdata/AI/Traffic", features);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function scanAPT() {
|
||||||
|
return initDB().then(features => {
|
||||||
|
var d = path.join(homedir, 'Documents/apt.dat');
|
||||||
|
scanAPTIntoDB(d, features);
|
||||||
|
features.close();
|
||||||
|
console.log("Closed DB");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user