Switch to parceljs, add intial map stuff

This commit is contained in:
Adam Goldsmith 2018-07-19 11:01:31 -04:00
parent 635a85aeab
commit 8ac715b787
7 changed files with 3816 additions and 2541 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
/.tern-port
/node_modules/
/dist/
.tern-port

6217
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 B

View File

@ -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
View 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
View 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());
});