Switch to parceljs, add intial map stuff
This commit is contained in:
parent
635a85aeab
commit
8ac715b787
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
/.tern-port
|
||||
/node_modules/
|
||||
/dist/
|
||||
.tern-port
|
||||
|
6217
package-lock.json
generated
6217
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
@ -5,23 +5,20 @@
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"aprs-parser": "^1.0.4",
|
||||
"ol": "^5.0.3",
|
||||
"ws": "^5.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webpack": "^4.16.1",
|
||||
"webpack-cli": "^3.0.8",
|
||||
"webpack-serve": "^2.0.2"
|
||||
"parcel": "^1.9.7"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"monkeyPatch": "sed -i '8s| APRSIS| //APRSIS|' node_modules/aprs-parser/lib/index.js",
|
||||
"serve": "node src/server.js",
|
||||
|
||||
"prestart": "npm run monkeyPatch",
|
||||
"start": "node_modules/.bin/webpack-serve --content src",
|
||||
|
||||
"start": "node_modules/.bin/parcel src/index.html",
|
||||
"prebuild": "npm run monkeyPatch",
|
||||
"build": "NODE_ENV=production node node_modules/.bin/webpack && cp src/index.html dist/index.html"
|
||||
"build": "node_modules/.bin/parcel build src/index.html"
|
||||
},
|
||||
"author": "Adam Goldsmith <contact@adamgoldsmith.name>",
|
||||
"license": "ISC"
|
||||
|
BIN
src/arrow.png
Normal file
BIN
src/arrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 398 B |
@ -1,6 +1,6 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<script src="main.js"></script>
|
||||
<script src="./index.js"></script>
|
||||
<style>
|
||||
table.stations {
|
||||
border-collapse: collapse;
|
||||
@ -29,5 +29,6 @@
|
||||
<div class="wrapper">
|
||||
<table class="stations">
|
||||
</table>
|
||||
<a href="map.html">Map</a>
|
||||
</div>
|
||||
</body>
|
||||
|
19
src/map.html
Normal file
19
src/map.html
Normal file
@ -0,0 +1,19 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<style>
|
||||
html, body {
|
||||
height: 100%
|
||||
}
|
||||
.map {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<title>OpenLayers example</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" class="map"></div>
|
||||
<script src="./map.js"></script>
|
||||
</body>
|
||||
</html>
|
106
src/map.js
Normal file
106
src/map.js
Normal file
@ -0,0 +1,106 @@
|
||||
import 'ol/ol.css';
|
||||
import {Map as olMap, View} from 'ol';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
|
||||
import {OSM, Vector as VectorSource} from 'ol/source';
|
||||
import Feature from 'ol/Feature';
|
||||
import {fromLonLat} from 'ol/proj';
|
||||
import {Icon, Stroke, Style} from 'ol/style';
|
||||
import Projection from 'ol/proj/Projection';
|
||||
import {LineString, Point} from 'ol/geom';
|
||||
|
||||
import {readFileSync} from 'fs';
|
||||
const packets = readFileSync(__dirname + '/../IS_packets.txt', 'utf-8');
|
||||
|
||||
import {APRSParser} from 'aprs-parser';
|
||||
|
||||
import icon from "./arrow.png";
|
||||
|
||||
let parser = new APRSParser();
|
||||
|
||||
let tile_layer = new TileLayer({source: new OSM()});
|
||||
let vector_layer = new VectorLayer({
|
||||
source: new VectorSource()
|
||||
});
|
||||
|
||||
let map = new olMap({
|
||||
target: 'map',
|
||||
layers: [
|
||||
tile_layer,
|
||||
vector_layer
|
||||
],
|
||||
view: new View({
|
||||
center: fromLonLat([-72.15, 43.90]),
|
||||
zoom: 10
|
||||
})
|
||||
});
|
||||
|
||||
let colorGen = {
|
||||
hues: null,
|
||||
get: function (totalNum) {
|
||||
if (this.hues === null) {
|
||||
let mult = Math.floor(360 / totalNum);
|
||||
this.hues = Array.from(Array(totalNum).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]];
|
||||
});
|
||||
}
|
||||
return this.hues.pop();
|
||||
}
|
||||
};
|
||||
|
||||
let lines = packets.split("\n");
|
||||
lines
|
||||
// restrict to just prouty times
|
||||
.filter(line => {
|
||||
let date = new Date(line.slice(0,18));
|
||||
return date > new Date("2018-07-14") && date < new Date("2018-07-15");
|
||||
})
|
||||
// parse to APRS packet
|
||||
.map(line => parser.parse(line.slice(29)))
|
||||
// filter by callsign
|
||||
.filter(packet => (packet.from !== undefined) &&
|
||||
(packet.from.toString() === "W1HS-9"))
|
||||
// filter to just positional data
|
||||
.filter(packet => 'data' in packet && 'latitude' in packet.data)
|
||||
// join into Arrays of points
|
||||
.reduce((acc, packet) => {
|
||||
if (!acc.has(packet.from.toString())) acc.set(packet.from.toString(), []);
|
||||
acc.get(packet.from.toString()).push([packet.data.longitude,
|
||||
packet.data.latitude]);
|
||||
return acc;
|
||||
}, new Map())
|
||||
// plot on map
|
||||
.forEach((points, callsign, map) => {
|
||||
let pathFeature = new Feature(new LineString(points));
|
||||
let styles = [
|
||||
new Style({stroke: new Stroke(
|
||||
{color: 'hsl(' + colorGen.get(map.size) + ', 75%, 50%)', width: 2})})];
|
||||
|
||||
pathFeature.getGeometry().forEachSegment((start, end) => {
|
||||
let dx = end[0] - start[0];
|
||||
let dy = end[1] - start[1];
|
||||
let rotation = Math.atan2(dy, dx);
|
||||
// arrows
|
||||
styles.push(new Style({
|
||||
geometry: new Point(end),
|
||||
image: new Icon({
|
||||
src: icon,
|
||||
anchor: [0.75, 0.5],
|
||||
rotateWithView: true,
|
||||
rotation: -rotation
|
||||
})
|
||||
}));
|
||||
});
|
||||
|
||||
pathFeature.setStyle(styles);
|
||||
|
||||
vector_layer.getSource().addFeature(pathFeature);
|
||||
pathFeature.getGeometry().transform(new Projection({code: "EPSG:4326"}),
|
||||
tile_layer.getSource().getProjection());
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user