WIP: Migrate Map to Vue
This commit is contained in:
parent
2d9233fabb
commit
87b8f9e9ba
203
package-lock.json
generated
203
package-lock.json
generated
@ -1015,6 +1015,22 @@
|
|||||||
"regenerator-runtime": "^0.12.0"
|
"regenerator-runtime": "^0.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@babel/runtime-corejs2": {
|
||||||
|
"version": "7.5.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.5.4.tgz",
|
||||||
|
"integrity": "sha512-sHv74OzyZ18d6tjHU0HmlVES3+l+lydkOMTiKsJSTGWcTBpIMfXLEgduahlJrQjknW9RCQAqLIEdLOHjBmq/hg==",
|
||||||
|
"requires": {
|
||||||
|
"core-js": "^2.6.5",
|
||||||
|
"regenerator-runtime": "^0.13.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"regenerator-runtime": {
|
||||||
|
"version": "0.13.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz",
|
||||||
|
"integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"@babel/template": {
|
"@babel/template": {
|
||||||
"version": "7.2.2",
|
"version": "7.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz",
|
||||||
@ -1126,6 +1142,103 @@
|
|||||||
"physical-cpu-count": "^2.0.0"
|
"physical-cpu-count": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@turf/bbox": {
|
||||||
|
"version": "5.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@turf/bbox/-/bbox-5.1.5.tgz",
|
||||||
|
"integrity": "sha1-MFHfUUrUxQ9KT5uKLRX9i2hA7aM=",
|
||||||
|
"requires": {
|
||||||
|
"@turf/helpers": "^5.1.5",
|
||||||
|
"@turf/meta": "^5.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@turf/boolean-point-in-polygon": {
|
||||||
|
"version": "5.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@turf/boolean-point-in-polygon/-/boolean-point-in-polygon-5.1.5.tgz",
|
||||||
|
"integrity": "sha1-8BzBlNHgMKVIv9qYHLpDz9YpQbc=",
|
||||||
|
"requires": {
|
||||||
|
"@turf/helpers": "^5.1.5",
|
||||||
|
"@turf/invariant": "^5.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@turf/center": {
|
||||||
|
"version": "5.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@turf/center/-/center-5.1.5.tgz",
|
||||||
|
"integrity": "sha1-RKss2VT2PA03dX9xWKmcPvURS4A=",
|
||||||
|
"requires": {
|
||||||
|
"@turf/bbox": "^5.1.5",
|
||||||
|
"@turf/helpers": "^5.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@turf/clone": {
|
||||||
|
"version": "5.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@turf/clone/-/clone-5.1.5.tgz",
|
||||||
|
"integrity": "sha1-JT6NNUdxgZduM636tQoPAqfw42c=",
|
||||||
|
"requires": {
|
||||||
|
"@turf/helpers": "^5.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@turf/distance": {
|
||||||
|
"version": "5.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@turf/distance/-/distance-5.1.5.tgz",
|
||||||
|
"integrity": "sha1-Oc8YIEu/h1h9cH5gmmARiQkVZAk=",
|
||||||
|
"requires": {
|
||||||
|
"@turf/helpers": "^5.1.5",
|
||||||
|
"@turf/invariant": "^5.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@turf/explode": {
|
||||||
|
"version": "5.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@turf/explode/-/explode-5.1.5.tgz",
|
||||||
|
"integrity": "sha1-sSsvd0AEobSPYrqVsgocZVo94Rg=",
|
||||||
|
"requires": {
|
||||||
|
"@turf/helpers": "^5.1.5",
|
||||||
|
"@turf/meta": "^5.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@turf/helpers": {
|
||||||
|
"version": "5.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-5.1.5.tgz",
|
||||||
|
"integrity": "sha1-FTQFInq5M9AEpbuWQantmZ/L4M8="
|
||||||
|
},
|
||||||
|
"@turf/invariant": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-5.2.0.tgz",
|
||||||
|
"integrity": "sha1-8BUP9ykLOFd7c9CIt5MsHuCqkKc=",
|
||||||
|
"requires": {
|
||||||
|
"@turf/helpers": "^5.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@turf/meta": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@turf/meta/-/meta-5.2.0.tgz",
|
||||||
|
"integrity": "sha1-OxrUhe4MOwsXdRMqMsOE1T5LpT0=",
|
||||||
|
"requires": {
|
||||||
|
"@turf/helpers": "^5.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@turf/nearest-point": {
|
||||||
|
"version": "5.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@turf/nearest-point/-/nearest-point-5.1.5.tgz",
|
||||||
|
"integrity": "sha1-EgUN5Bw5hEMiTHl43g9iE5ANNPs=",
|
||||||
|
"requires": {
|
||||||
|
"@turf/clone": "^5.1.5",
|
||||||
|
"@turf/distance": "^5.1.5",
|
||||||
|
"@turf/helpers": "^5.1.5",
|
||||||
|
"@turf/meta": "^5.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@turf/point-on-feature": {
|
||||||
|
"version": "5.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@turf/point-on-feature/-/point-on-feature-5.1.5.tgz",
|
||||||
|
"integrity": "sha1-MMfwMkMCd8ZBjZbSieRba/shP+c=",
|
||||||
|
"requires": {
|
||||||
|
"@turf/boolean-point-in-polygon": "^5.1.5",
|
||||||
|
"@turf/center": "^5.1.5",
|
||||||
|
"@turf/explode": "^5.1.5",
|
||||||
|
"@turf/helpers": "^5.1.5",
|
||||||
|
"@turf/nearest-point": "^5.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/q": {
|
"@types/q": {
|
||||||
"version": "1.5.2",
|
"version": "1.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
|
||||||
@ -1929,6 +2042,11 @@
|
|||||||
"upath": "^1.1.1"
|
"upath": "^1.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"chroma-js": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-jTwQiT859RTFN/vIf7s+Vl/Z2LcMrvMv3WUFmd/4u76AdlFC0NTNgqEEFPcRiHmAswPsMiQEDZLM8vX8qXpZNQ=="
|
||||||
|
},
|
||||||
"cipher-base": {
|
"cipher-base": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
|
||||||
@ -2142,8 +2260,7 @@
|
|||||||
"core-js": {
|
"core-js": {
|
||||||
"version": "2.6.9",
|
"version": "2.6.9",
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz",
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz",
|
||||||
"integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==",
|
"integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"core-util-is": {
|
"core-util-is": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@ -2623,6 +2740,11 @@
|
|||||||
"node-addon-api": "^1.6.0"
|
"node-addon-api": "^1.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"debounce-promise": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/debounce-promise/-/debounce-promise-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-rZHcgBkbYavBeD9ej6sP56XfG53d51CD4dnaw989YX/nZ/ZJfgRx/9ePKmTNiUiyQvh4mtrMoS3OAWW+yoYtpg=="
|
||||||
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||||
@ -2750,6 +2872,15 @@
|
|||||||
"randombytes": "^2.0.0"
|
"randombytes": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"distinct-colors": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/distinct-colors/-/distinct-colors-1.0.4.tgz",
|
||||||
|
"integrity": "sha1-Z9/KV5S8qVDAHSUaUqozWG5a97Q=",
|
||||||
|
"requires": {
|
||||||
|
"chroma-js": "^1.1.1",
|
||||||
|
"mout": "^0.11.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dom-serializer": {
|
"dom-serializer": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
|
||||||
@ -4740,6 +4871,11 @@
|
|||||||
"integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==",
|
"integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"merge-descriptors": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||||
|
},
|
||||||
"merge-source-map": {
|
"merge-source-map": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz",
|
||||||
@ -4886,6 +5022,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mout": {
|
||||||
|
"version": "0.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mout/-/mout-0.11.1.tgz",
|
||||||
|
"integrity": "sha1-ujYR318OWx/7/QEWa48C0fX6K5k="
|
||||||
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
@ -5144,6 +5285,11 @@
|
|||||||
"rbush": "2.0.2"
|
"rbush": "2.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ol-tilecache": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ol-tilecache/-/ol-tilecache-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-oA+UM8juw775gVm0ZgH5WIV9DnDhfLYWnY7zxkpIR8FDZaoFiPa0idG+GFRdRokeCqMoeoNMSD8aRguFbDE9XA=="
|
||||||
|
},
|
||||||
"on-finished": {
|
"on-finished": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||||
@ -5321,6 +5467,21 @@
|
|||||||
"safe-buffer": "^5.1.1"
|
"safe-buffer": "^5.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"parse-color": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-e3SLlag/A/FqlPU15S1/PZRlhhk=",
|
||||||
|
"requires": {
|
||||||
|
"color-convert": "~0.5.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": {
|
||||||
|
"version": "0.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz",
|
||||||
|
"integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"parse-json": {
|
"parse-json": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
|
||||||
@ -6329,6 +6490,14 @@
|
|||||||
"inherits": "^2.0.1"
|
"inherits": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"rxjs": {
|
||||||
|
"version": "6.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz",
|
||||||
|
"integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^1.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"safe-buffer": {
|
"safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
@ -7028,6 +7197,11 @@
|
|||||||
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
|
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"tslib": {
|
||||||
|
"version": "1.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
|
||||||
|
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
|
||||||
|
},
|
||||||
"tty-browserify": {
|
"tty-browserify": {
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
|
||||||
@ -7294,8 +7468,7 @@
|
|||||||
"uuid": {
|
"uuid": {
|
||||||
"version": "3.3.2",
|
"version": "3.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
|
||||||
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
|
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"v8-compile-cache": {
|
"v8-compile-cache": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
@ -7358,6 +7531,23 @@
|
|||||||
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"vuelayers": {
|
||||||
|
"version": "0.11.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/vuelayers/-/vuelayers-0.11.4.tgz",
|
||||||
|
"integrity": "sha512-6asCq2vDCPM4mS60NGeEBGKiVVJZ/GACYtu7UUVPkhtdmvI7bSzKjKuv0cTQkwcgh6YRtqzAIzML0l9fwb4AQw==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime-corejs2": "^7.1.2",
|
||||||
|
"@turf/point-on-feature": "^5.1.5",
|
||||||
|
"debounce-promise": "^3.1.0",
|
||||||
|
"merge-descriptors": "^1.0.1",
|
||||||
|
"ol": "^5.3.1",
|
||||||
|
"ol-tilecache": "^3.0.1",
|
||||||
|
"parse-color": "^1.0.0",
|
||||||
|
"rxjs": "^6.3.3",
|
||||||
|
"uuid": "^3.3.2",
|
||||||
|
"whatwg-fetch": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"w3c-hr-time": {
|
"w3c-hr-time": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",
|
||||||
@ -7391,6 +7581,11 @@
|
|||||||
"iconv-lite": "0.4.24"
|
"iconv-lite": "0.4.24"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"whatwg-fetch": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q=="
|
||||||
|
},
|
||||||
"whatwg-mimetype": {
|
"whatwg-mimetype": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
|
||||||
|
@ -5,9 +5,11 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"aprs-parser": "^1.0.4",
|
"aprs-parser": "^1.0.4",
|
||||||
|
"distinct-colors": "^1.0.4",
|
||||||
"ol": "^5.3.3",
|
"ol": "^5.3.3",
|
||||||
"vue": "^2.6.10",
|
"vue": "^2.6.10",
|
||||||
"vue-hot-reload-api": "^2.3.3",
|
"vue-hot-reload-api": "^2.3.3",
|
||||||
|
"vuelayers": "^0.11.4",
|
||||||
"ws": "^5.2.2"
|
"ws": "^5.2.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
203
src/Map.vue
Normal file
203
src/Map.vue
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
<template>
|
||||||
|
<vl-map data-projection="EPSG:4326">
|
||||||
|
<vl-view :zoom="10" :center="[-72.15, 43.9]">
|
||||||
|
<vl-layer-tile>
|
||||||
|
<vl-source-osm> </vl-source-osm>
|
||||||
|
</vl-layer-tile>
|
||||||
|
<vl-layer-group>
|
||||||
|
<vl-layer-vector v-for="(gpxURL, name) in routes" :key="name">
|
||||||
|
<vl-source-vector :url="gpxURL" :format-factory="gpxFormatFactory">
|
||||||
|
</vl-source-vector>
|
||||||
|
</vl-layer-vector>
|
||||||
|
<vl-style-stroke color="hsl(200, 90%, 30%)" :width="5">
|
||||||
|
</vl-style-stroke>
|
||||||
|
</vl-layer-group>
|
||||||
|
|
||||||
|
<vl-layer-group>
|
||||||
|
<vl-layer-group
|
||||||
|
v-for="(packets, callsign, idx) in paths"
|
||||||
|
:key="callsign"
|
||||||
|
>
|
||||||
|
<!--Paths -->
|
||||||
|
<vl-layer-vector>
|
||||||
|
<vl-source-vector>
|
||||||
|
<vl-feature>
|
||||||
|
<vl-geom-line-string :coordinates="packetsToPoints(packets)">
|
||||||
|
</vl-geom-line-string>
|
||||||
|
</vl-feature>
|
||||||
|
</vl-source-vector>
|
||||||
|
<vl-style-box>
|
||||||
|
<vl-style-stroke :color="stationColors[idx].hex()" :width="2">
|
||||||
|
</vl-style-stroke>
|
||||||
|
</vl-style-box>
|
||||||
|
</vl-layer-vector>
|
||||||
|
|
||||||
|
<!-- Points -->
|
||||||
|
<vl-layer-vector>
|
||||||
|
<vl-source-vector>
|
||||||
|
<vl-feature>
|
||||||
|
<vl-geom-multi-point :coordinates="packetsToPoints(packets)">
|
||||||
|
</vl-geom-multi-point>
|
||||||
|
</vl-feature>
|
||||||
|
</vl-source-vector>
|
||||||
|
<vl-style-box>
|
||||||
|
<vl-style-circle :radius="3">
|
||||||
|
<vl-style-fill :color="stationColors[idx].hex()">
|
||||||
|
</vl-style-fill>
|
||||||
|
</vl-style-circle>
|
||||||
|
</vl-style-box>
|
||||||
|
</vl-layer-vector>
|
||||||
|
</vl-layer-group>
|
||||||
|
</vl-layer-group>
|
||||||
|
</vl-view>
|
||||||
|
</vl-map>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { APRSParser } from "aprs-parser";
|
||||||
|
import distinctColors from "distinct-colors";
|
||||||
|
|
||||||
|
import { Control } from "ol/control";
|
||||||
|
import { GPX } from "ol/format";
|
||||||
|
|
||||||
|
import Vue from "vue";
|
||||||
|
import VueLayers from "vuelayers";
|
||||||
|
import "vuelayers/lib/style.css";
|
||||||
|
|
||||||
|
Vue.use(VueLayers);
|
||||||
|
|
||||||
|
import route_data from "gpx/*.gpx";
|
||||||
|
import { readFileSync } from "fs";
|
||||||
|
const packetLog = readFileSync(__dirname + "/../IS_packets.txt", "utf-8");
|
||||||
|
|
||||||
|
function parsePackets(packetLog) {
|
||||||
|
let parser = new APRSParser();
|
||||||
|
return (
|
||||||
|
packetLog
|
||||||
|
.trim()
|
||||||
|
.split("\n")
|
||||||
|
// parse to Date and APRS packet
|
||||||
|
.map(line => {
|
||||||
|
let packet = parser.parse(line.slice(29));
|
||||||
|
packet.date = new Date(line.slice(0, 18));
|
||||||
|
return packet;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
packets: parsePackets(packetLog),
|
||||||
|
routes: route_data
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
gpxFormatFactory(options) {
|
||||||
|
return new GPX(options);
|
||||||
|
},
|
||||||
|
|
||||||
|
packetsToPoints(packets) {
|
||||||
|
return packets.map(packet => [
|
||||||
|
packet.data.longitude,
|
||||||
|
packet.data.latitude
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
paths() {
|
||||||
|
return (
|
||||||
|
this.packets
|
||||||
|
.filter(
|
||||||
|
packet =>
|
||||||
|
packet.date > new Date("2018-07-13") &&
|
||||||
|
packet.date < new Date("2018-07-14")
|
||||||
|
)
|
||||||
|
// filter to just positional data
|
||||||
|
.filter(packet => "data" in packet && "latitude" in packet.data)
|
||||||
|
// join into Arrays of points
|
||||||
|
.reduce((acc, packet) => {
|
||||||
|
let callsign = packet.from.toString().trim();
|
||||||
|
if (!(callsign in acc)) acc[callsign] = [];
|
||||||
|
acc[callsign].push(packet);
|
||||||
|
return acc;
|
||||||
|
}, {})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
stationColors() {
|
||||||
|
return distinctColors({
|
||||||
|
count: Object.keys(this.paths).length,
|
||||||
|
lightMin: 20,
|
||||||
|
lightMax: 80
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-control.layer-toggles {
|
||||||
|
top: 0.5em;
|
||||||
|
right: 0.5em;
|
||||||
|
background-color: rgba(70, 115, 164, 0.7);
|
||||||
|
color: #eee;
|
||||||
|
white-space: nowrap;
|
||||||
|
max-height: calc(100vh - 1em);
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layer-toggles > div {
|
||||||
|
margin: 0.5em;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-control.layer-toggles:hover {
|
||||||
|
background-color: rgba(0, 60, 136, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.layer-toggles > div > label {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand + span::before {
|
||||||
|
content: "\25B6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand:checked + span::before {
|
||||||
|
content: "\25BC";
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand ~ .collapsible-content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand:checked ~ .collapsible-content {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsible-content {
|
||||||
|
margin-left: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsible-content > label {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
48
src/map.css
48
src/map.css
@ -1,48 +0,0 @@
|
|||||||
html, body {
|
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.map {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.ol-control.layer-toggles {
|
|
||||||
top: 0.5em;
|
|
||||||
right: 0.5em;
|
|
||||||
background-color: rgba(70, 115, 164, 0.7);
|
|
||||||
color: #eee;
|
|
||||||
white-space: nowrap;
|
|
||||||
max-height: calc(100vh - 1em);
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
.layer-toggles > div {
|
|
||||||
margin: 0.5em;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
.ol-control.layer-toggles:hover {
|
|
||||||
background-color: rgba(0,60,136,0.7);
|
|
||||||
}
|
|
||||||
.layer-toggles > div > label {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.expand {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.expand + span::before {
|
|
||||||
content: '\25B6';
|
|
||||||
}
|
|
||||||
.expand:checked + span::before {
|
|
||||||
content: '\25BC';
|
|
||||||
}
|
|
||||||
.expand ~ .collapsible-content {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.expand:checked ~ .collapsible-content {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.collapsible-content {
|
|
||||||
margin-left: 0.8em;
|
|
||||||
}
|
|
||||||
.collapsible-content > label {
|
|
||||||
display: block;
|
|
||||||
}
|
|
11
src/map.html
11
src/map.html
@ -1,11 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" type="text/css" href="map.css">
|
|
||||||
<title>OpenLayers example</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="map" class="map"></div>
|
|
||||||
<script src="./map.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
314
src/map.js
314
src/map.js
@ -1,314 +0,0 @@
|
|||||||
import 'ol/ol.css';
|
|
||||||
import {Map as olMap, View} from 'ol';
|
|
||||||
import {Control} from 'ol/control';
|
|
||||||
import {Group as LayerGroup, Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
|
|
||||||
import {OSM, Vector as VectorSource} from 'ol/source';
|
|
||||||
import {GPX} from 'ol/format';
|
|
||||||
import Feature from 'ol/Feature';
|
|
||||||
import {fromLonLat} from 'ol/proj';
|
|
||||||
import {Circle as CircleStyle, Icon, Fill, Stroke, Style, Text} from 'ol/style';
|
|
||||||
import Projection from 'ol/proj/Projection';
|
|
||||||
import {LineString, Point} from 'ol/geom';
|
|
||||||
|
|
||||||
import {readFileSync} from 'fs';
|
|
||||||
const packetLog = readFileSync(__dirname + '/../IS_packets.txt', 'utf-8');
|
|
||||||
|
|
||||||
import {APRSParser} from 'aprs-parser';
|
|
||||||
|
|
||||||
let tile_layer = new TileLayer({source: new OSM()});
|
|
||||||
|
|
||||||
import route_data from 'gpx/*.gpx';
|
|
||||||
|
|
||||||
let routes = new LayerGroup({
|
|
||||||
title: "Routes",
|
|
||||||
layers: Object.keys(route_data).map(name => new VectorLayer({
|
|
||||||
title: name.replace(/_/g, " "),
|
|
||||||
source: new VectorSource({
|
|
||||||
url: route_data[name],
|
|
||||||
format: new GPX()
|
|
||||||
}),
|
|
||||||
style: new Style({
|
|
||||||
stroke: new Stroke(
|
|
||||||
{color: 'hsl(200, 90%, 30%)', width: 5}
|
|
||||||
)})
|
|
||||||
}))
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
let map = new olMap({
|
|
||||||
target: 'map',
|
|
||||||
layers: [
|
|
||||||
tile_layer,
|
|
||||||
routes
|
|
||||||
],
|
|
||||||
view: new View({
|
|
||||||
center: fromLonLat([-72.15, 43.90]),
|
|
||||||
zoom: 10
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
class ColorGenerator {
|
|
||||||
constructor(count) {
|
|
||||||
let mult = Math.floor(360 / count);
|
|
||||||
this.hues = Array.from(Array(count).keys()).map(x => x * mult);
|
|
||||||
|
|
||||||
// Shuffle (this is not a great shuffle, but I don't care)
|
|
||||||
this.hues.forEach((current, index, arr) => {
|
|
||||||
let randomIndex = Math.floor(Math.random() * index);
|
|
||||||
[arr[index], arr[randomIndex]] = [arr[randomIndex], arr[index]];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
get() {
|
|
||||||
return this.hues.pop();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function transformGeometry(geometry) {
|
|
||||||
return geometry.transform(new Projection({code: "EPSG:4326"}),
|
|
||||||
tile_layer.getSource().getProjection());
|
|
||||||
}
|
|
||||||
|
|
||||||
function plotPaths(packets) {
|
|
||||||
let path_layers = new LayerGroup({title: "Station Paths"});
|
|
||||||
map.addLayer(path_layers);
|
|
||||||
|
|
||||||
let paths = packets
|
|
||||||
.filter(packet => packet.date > new Date("2018-07-14") && packet.date < new Date("2018-07-15"))
|
|
||||||
// filter to just positional data
|
|
||||||
.filter(packet => 'data' in packet && 'latitude' in packet.data)
|
|
||||||
// join into Arrays of points
|
|
||||||
.reduce((acc, packet) => {
|
|
||||||
let callsign = packet.from.toString().trim();
|
|
||||||
if (!acc.has(callsign)) acc.set(callsign, []);
|
|
||||||
acc.get(callsign).push([packet.data.longitude, packet.data.latitude, packet]);
|
|
||||||
return acc;
|
|
||||||
}, new Map());
|
|
||||||
|
|
||||||
let colorGen = new ColorGenerator(paths.size);
|
|
||||||
|
|
||||||
// plot on map
|
|
||||||
paths.forEach((points, callsign) => {
|
|
||||||
let color = 'hsl(' + colorGen.get() + ', 75%, 50%)';
|
|
||||||
let path_layer = new VectorLayer({
|
|
||||||
title: "Path",
|
|
||||||
source: new VectorSource({features: [
|
|
||||||
new Feature({geometry: transformGeometry(new LineString(points))})
|
|
||||||
]}),
|
|
||||||
style: new Style({stroke: new Stroke({color: color, width: 2})})
|
|
||||||
});
|
|
||||||
|
|
||||||
let points_layer = new VectorLayer({
|
|
||||||
title: "Points",
|
|
||||||
source: new VectorSource({
|
|
||||||
features: points.map(point => new Feature({
|
|
||||||
geometry: transformGeometry(new Point(point)),
|
|
||||||
packet: point[3] // TODO: this seems a bit bad
|
|
||||||
}))
|
|
||||||
}),
|
|
||||||
style: new Style({
|
|
||||||
image: new CircleStyle({
|
|
||||||
radius: 4,
|
|
||||||
fill: new Fill({color: color})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
let callsign_layer = new LayerGroup({
|
|
||||||
title: callsign,
|
|
||||||
layers: [path_layer, points_layer]
|
|
||||||
});
|
|
||||||
path_layers.getLayers().push(callsign_layer);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function plotPacketPaths(packets) {
|
|
||||||
function pathToString(path) {
|
|
||||||
return path
|
|
||||||
.filter(station => !station.call.match(/WIDE[12]|qA?|UV[123]|.*\*$|UNCAN/))
|
|
||||||
.map(station => station.toString().trim().replace(/\*$/, ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
let digiCalls =
|
|
||||||
new Set(packets
|
|
||||||
.map(packet => pathToString(packet.via))
|
|
||||||
.reduce((acc, stations) => acc.concat(stations)));
|
|
||||||
|
|
||||||
let digiPos = packets
|
|
||||||
// filter to digis
|
|
||||||
.filter(packet => digiCalls.has(packet.from.toString().trim()))
|
|
||||||
// filter to just positional data
|
|
||||||
.filter(packet => 'data' in packet && 'latitude' in packet.data)
|
|
||||||
// convert to callsign -> position mapping
|
|
||||||
.reduce((stations, packet) =>
|
|
||||||
stations.set(packet.from.toString().trim(),
|
|
||||||
[packet.data.longitude, packet.data.latitude]),
|
|
||||||
new Map());
|
|
||||||
|
|
||||||
let colorGen = new ColorGenerator(digiPos.size);
|
|
||||||
let colorMap = Array.from(digiPos.keys()).reduce(
|
|
||||||
(acc, callsign, index) =>
|
|
||||||
acc.set(callsign, colorGen.hues[index]), new Map());
|
|
||||||
|
|
||||||
// plot digis
|
|
||||||
// TODO: icons
|
|
||||||
let digi_style = new Style({
|
|
||||||
image: new CircleStyle({
|
|
||||||
radius: 5,
|
|
||||||
fill: new Fill({color: 'grey'})
|
|
||||||
}),
|
|
||||||
text: new Text({
|
|
||||||
font: 'bold 11px "Open Sans", "Arial Unicode MS", "sans-serif"',
|
|
||||||
overflow: true,
|
|
||||||
fill: new Fill({color: 'black'})
|
|
||||||
})
|
|
||||||
});
|
|
||||||
let digi_layer = new VectorLayer({
|
|
||||||
title: "Digipeater Labels",
|
|
||||||
zIndex: 1, // TODO: probably not the best way to do this
|
|
||||||
source: new VectorSource({
|
|
||||||
features: Array.from(digiPos.keys()).map(callsign =>
|
|
||||||
new Feature({
|
|
||||||
geometry: transformGeometry(new Point(digiPos.get(callsign))),
|
|
||||||
callsign: callsign
|
|
||||||
})
|
|
||||||
)}),
|
|
||||||
style: feature => {
|
|
||||||
digi_style.setText(new Text({
|
|
||||||
text: feature.get('callsign'),
|
|
||||||
offsetY: 12
|
|
||||||
}));
|
|
||||||
return digi_style;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
map.addLayer(digi_layer);
|
|
||||||
|
|
||||||
let packet_path_layers = new LayerGroup({title: "Packet Paths"});
|
|
||||||
let layers_map = new Map();
|
|
||||||
map.addLayer(packet_path_layers);
|
|
||||||
packets
|
|
||||||
.filter(packet => packet.date > new Date("2018-07-14") && packet.date < new Date("2018-07-15"))
|
|
||||||
// filter by callsign
|
|
||||||
//.filter(packet => packet.from.toString() === "W1HS-9")
|
|
||||||
// filter to just positional data
|
|
||||||
.filter(packet => 'data' in packet && 'latitude' in packet.data)
|
|
||||||
.forEach(packet => {
|
|
||||||
pathToString(packet.via)
|
|
||||||
.forEach((station, index, stations) => {
|
|
||||||
if (digiPos.get(station) === undefined) {
|
|
||||||
console.log(station);
|
|
||||||
}
|
|
||||||
|
|
||||||
// first point in path is originating station
|
|
||||||
let previous = (index === 0) ?
|
|
||||||
[packet.data.longitude, packet.data.latitude] :
|
|
||||||
digiPos.get(stations[index - 1]) || [0, 0];
|
|
||||||
|
|
||||||
let pathFeature = new Feature(transformGeometry(
|
|
||||||
new LineString([previous, digiPos.get(station) || [0, 0]])));
|
|
||||||
|
|
||||||
// TODO: want to color per station that hears it, probably means
|
|
||||||
// making a lot more features
|
|
||||||
let color = colorMap.get(station);
|
|
||||||
pathFeature.setStyle(new Style({
|
|
||||||
stroke: new Stroke(
|
|
||||||
{color: 'hsl(' + color + ', 60%, 60%)', width: 2}
|
|
||||||
)}));
|
|
||||||
|
|
||||||
if (!layers_map.has(station)) {
|
|
||||||
layers_map.set(station, new VectorLayer({
|
|
||||||
title: station,
|
|
||||||
source: new VectorSource(),
|
|
||||||
renderMode: 'image'
|
|
||||||
}));
|
|
||||||
packet_path_layers.getLayers().push(layers_map.get(station));
|
|
||||||
}
|
|
||||||
layers_map.get(station).getSource().addFeature(pathFeature);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function layer_toggle(layer) {
|
|
||||||
if (layer.toggle_element === undefined) {
|
|
||||||
layer.toggle_element = document.createElement('label');
|
|
||||||
|
|
||||||
let checkbox = layer.toggle_element.appendChild(
|
|
||||||
document.createElement('input'));
|
|
||||||
checkbox.type = "checkbox";
|
|
||||||
checkbox.checked = layer.getVisible();
|
|
||||||
checkbox.addEventListener('change', event => {
|
|
||||||
layer.setVisible(event.target.checked);
|
|
||||||
});
|
|
||||||
layer.toggle_element.appendChild(
|
|
||||||
document.createTextNode(layer.get('title')));
|
|
||||||
}
|
|
||||||
return layer.toggle_element;
|
|
||||||
}
|
|
||||||
|
|
||||||
function layer_toggles(layer, parentElement) {
|
|
||||||
if (layer instanceof LayerGroup) {
|
|
||||||
if (layer.group_toggle === undefined) {
|
|
||||||
let label = layer.group_toggle = parentElement.appendChild(
|
|
||||||
document.createElement('label'));
|
|
||||||
let input = label.appendChild(document.createElement('input'));
|
|
||||||
input.type = 'checkbox';
|
|
||||||
input.className = "expand";
|
|
||||||
label.appendChild(document.createElement('span'));
|
|
||||||
|
|
||||||
label.appendChild(layer_toggle(layer)); // whole LayerGroup
|
|
||||||
|
|
||||||
let child_toggle_element = label.appendChild(
|
|
||||||
document.createElement('input'));
|
|
||||||
child_toggle_element.type = 'checkbox';
|
|
||||||
child_toggle_element.checked = true;
|
|
||||||
child_toggle_element.addEventListener('change', event => {
|
|
||||||
layer.getLayers().forEach(subLayer => {
|
|
||||||
subLayer.setVisible(event.target.checked);
|
|
||||||
subLayer.toggle_element.querySelector("input").checked =
|
|
||||||
event.target.checked;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
let container = label.appendChild(document.createElement('div'));
|
|
||||||
container.className = 'collapsible-content';
|
|
||||||
layer.getLayers().forEach(
|
|
||||||
subLayer => layer_toggles(subLayer, container));
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
parentElement.appendChild(layer_toggle(layer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function render_layer_toggles(event, element) {
|
|
||||||
event.map.getLayers().getArray()
|
|
||||||
.filter(layer => layer.get('title') !== undefined)
|
|
||||||
.forEach(layer => layer_toggles(layer, element));
|
|
||||||
}
|
|
||||||
|
|
||||||
(function makeLayerToogleControl() {
|
|
||||||
let element = document.createElement('div');
|
|
||||||
element.className = 'layer-toggles ol-unselectable ol-control';
|
|
||||||
let inner = element.appendChild(document.createElement('div'));
|
|
||||||
|
|
||||||
let control = new Control(
|
|
||||||
{element: element,
|
|
||||||
render: event => render_layer_toggles(event, inner)});
|
|
||||||
map.addControl(control);
|
|
||||||
})();
|
|
||||||
|
|
||||||
|
|
||||||
function parsePackets(packetLog) {
|
|
||||||
let parser = new APRSParser();
|
|
||||||
return packetLog.trim().split("\n")
|
|
||||||
// parse to Date and APRS packet
|
|
||||||
.map(line => {
|
|
||||||
let packet = parser.parse(line.slice(29));
|
|
||||||
packet.date = new Date(line.slice(0,18));
|
|
||||||
return packet;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let packets = parsePackets(packetLog);
|
|
||||||
plotPaths(packets);
|
|
||||||
plotPacketPaths(packets);
|
|
Loading…
Reference in New Issue
Block a user