Commit abcf0b3c authored by Michael Ochmann's avatar Michael Ochmann
Browse files

refactoring; documentation

parent b6bb69bf
......@@ -12,7 +12,7 @@
integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw=="
crossorigin=""></script>
<link rel="apple-touch-icon" href="images/appIcon.png?id=2">
<title>HeightTracker</title>
<title>trakr.</title>
<link rel=stylesheet type=text/css href=app.css>
<link rel=manifest href=../manifest.json>
<script type=module src="javascript/main.js"></script>
......
import GeoPoint from "./GeoPoint.js";
import $ from "./smallQ.js";
import ViewController from "./controllers/ViewController.js";
import Std from "./Std.js";
/**
* entrypoint for the application
*
* @author Michael Ochmann <ochmannm@hochschule-trier.de>
*/
class App {
constructor() {
this.window = new ViewController();
......@@ -13,7 +15,9 @@ class App {
alert("Your browser does not support geo data!");
}
/**
* registers the webworker
*/
static RegisterWorker() {
if ("serviceWorker" in navigator) {
try {
......
/**
* simple data-class for outputting simple GeoJSON
*
* @author Michael Ochmann <ochmannm@hochschule-trier.de>
*/
class GeoJSONCollection {
constructor(track) {
console.log(track);
......
/**
* SINGLETON – provides a thin wrapper for saving to and getting from `navigator.localStorage`
*
* @author Michael Ochmann <ochmannm@hochschule-trier.de>
*/
class Settings {
constructor() {
this.settings = JSON.parse(localStorage.getItem("settings")) || {};
}
/**
* retrieves a value from the settings, returns `defaultValue` if key does not exist
*
* @param key
* @param defaultValue
* @return {*}
*/
get(key, defaultValue = null) {
if (this.settings.hasOwnProperty(key))
return this.settings[key];
......@@ -10,20 +22,38 @@ class Settings {
return defaultValue;
}
/**
* sets a value with key `key` in settings
*
* @param key
* @param value
*/
set(key, value) {
this.settings[key] = value;
this.save();
}
/**
* saves settings to `navigator.localStorage`
*/
save() {
localStorage.setItem("settings", JSON.stringify(this.settings));
}
/**
* deletes everything from `navigator.localStorage`
*/
clear() {
this.settings = {};
localStorage.clear();
}
/**
* returns the instance of this singleton
*
* @return {Settings}
* @constructor
*/
static Instance() {
if (Settings.INSTANCE === null)
Settings.INSTANCE = new Settings();
......
/**
* a "standard library" with useful helper functions
*
* @author Michael Ochmann <ochmannm@hochschule-trier.de>
*/
class Std {
/**
* integer random method
......@@ -30,6 +35,12 @@ class Std {
return (((n - start1) / (stop1 - start1)) * (stop2 - start2)) + start2;
}
/**
* converts a string to binary data
*
* @param {string] inputstring
* @return {Uint8Array}
*/
static StringToBinary(string) {
let byteCharacters = string;
let byteNumbers = new Array(byteCharacters.length);
......
/* controllers */
import UIViewController from "./UIViewController.js";
import MapController from "./MapController.js";
import $ from "../smallQ.js";
import Std from "../Std.js";
import Settings from "../Settings.js";
import MapController from "./MapController.js";
import GeoPoint from "../GeoPoint.js";
/* models */
import GeoPoint from "../GeoPoint.js";
/* others */
import $ from "../smallQ.js";
import Std from "../Std.js";
import Settings from "../Settings.js";
const States = {
HEIGHTMAP : 0,
MAP : 1
};
/**
* viewcontroller for the map/heightmap view
*
* @author Michael Ochmann <ochmannm@hochschule-trier.de>
*/
class HeightMapViewController extends UIViewController {
constructor(view, model) {
super(view, model);
......@@ -40,6 +49,12 @@ class HeightMapViewController extends UIViewController {
});
}
/**
* add a GeoPoint to the model
*
* @param {GeoPoint} geoPoint
* @see HeightMap
*/
addPoint(geoPoint) {
if (geoPoint.constructor.name !== "GeoPoint")
throw new TypeError("an object of type 'GeoPoint' must be passed.");
......@@ -51,6 +66,8 @@ class HeightMapViewController extends UIViewController {
}
/**
* adding eventlisteners and setting up the canvas
*
* @override
*/
viewDidLoad() {
......@@ -94,7 +111,7 @@ class HeightMapViewController extends UIViewController {
let ctx = this.canvas.getContext("2d");
/* scolling the heightmap horizontally in canvas */
/* scrolling the heightmap horizontally in canvas */
this.canvas.addEventListener("touchstart", event => {
this.drag = true;
this.lastX = event.changedTouches[0].clientX;
......@@ -115,17 +132,11 @@ class HeightMapViewController extends UIViewController {
this.drawHeightMap();
});
this.drawHeightMap();
/* if (!this.isCapturing)
return;
this.capture();
/!* capturing new points *!/
HeightMapViewController.MAINLOOP = setInterval(() => {
this.capture();
}, 1000);*/
}
/**
* draws the heightmap, initially and on refresh
*/
drawHeightMap() {
let ctx = this.canvas.getContext("2d");
let height = this.canvas.height;
......@@ -178,7 +189,7 @@ class HeightMapViewController extends UIViewController {
ctx.fillText(`– ${Math.round(this.model.min)}m`, 10, height - 22);
ctx.fillText(`– ${Math.round(this.model.max)}m`, 10, 32);
/* draw "play button" */
/* draw "play button" – just a simple triangle */
if (!this.isCapturing) {
let theight = 100;
let twidth = 80;
......
import UIViewController from "./UIViewController.js";
import $ from "../smallQ.js";
import $ from "../smallQ.js";
/**
* viewcontroller for the OpenStreetMap Map
*
* @author Michael Ochmann <ochmannm@hochschule-trier.de>
*/
class MapController extends UIViewController {
/**
* initializing leaflet
*
* @override
* @link https://leafletjs.com
*/
viewDidLoad() {
if ($("#osm").size() <= 0)
return;
......
import UIViewController from "./UIViewController.js";
import Settings from "../Settings.js";
import $ from "../smallQ.js";
import Settings from "../Settings.js";
import $ from "../smallQ.js";
/**
* the viewcontroller for the settings screen
*
* @author Michael Ochmann <ochmannm@hochschule-trier.de>
*/
class SettingsViewController extends UIViewController {
constructor(view, model) {
super(view, model);
/* Setting up the selectable distances */
this.heights = [5, 50];
for (let h = 100; h < 1000; h += 100)
this.heights.push(h);
......@@ -13,6 +19,10 @@ class SettingsViewController extends UIViewController {
this.heights.push(h);
}
/**
* adding EventListeners
* @override
*/
viewDidLoad() {
$("#selectDistanceInterval").on("change", element => {
Settings.set("distanceInterval", element.value());
......@@ -26,6 +36,10 @@ class SettingsViewController extends UIViewController {
});
}
/**
* @override
* @return {string}
*/
render() {
let selectedDistance = Settings.get("distanceInterval", 100);
let heights = this.heights.map(height => {
......
import UIViewController from "./UIViewController.js";
import $ from "../smallQ.js";
import $ from "../smallQ.js";
/**
* viewcontroller for the list of tracks
*
* @author Michael Ochmann <ochmannm@hochschule-trier.de>
*/
class TracksListController extends UIViewController {
/**
* adding EventListeners
*
* @override
* @event TrackListController:select
*/
viewDidLoad() {
$(".track").click(element => {
if (element.hasClass("del")) {
......@@ -31,6 +40,10 @@ class TracksListController extends UIViewController {
});
}
/**
* @override
* @return {string}
*/
render() {
let tracks = this.model.tracks().map((track, index) => {
return `
......
import $ from "../smallQ.js";
/**
* ViewController superclass, inspired by the react.js MVC model
*
* @abstract
* @author Michael Ochmann <ochmannm@hochschule-trier.de>
*/
class UIViewController {
constructor(container, model = null) {
if (new.target === UIViewController)
......
import UIViewController from "./UIViewController.js";
/* controllers */
import UIViewController from "./UIViewController.js";
import HeightMapViewController from "./HeightMapViewController.js";
import SettingsViewController from "./SettingsViewController.js";
import TracksListController from "./TracksListController.js";
import SettingsViewController from "./SettingsViewController.js";
import TracksListController from "./TracksListController.js";
import HeightMap from "../models/HeightMap.js";
import Tracks from "../models/Tracks.js";
/* models */
import HeightMap from "../models/HeightMap.js";
import Tracks from "../models/Tracks.js";
import Std from "../Std.js";
import Settings from "../Settings.js";
import $ from "../smallQ.js";
import GeoJSONCollection from "../GeoJSONCollection.js";
/* others */
import Std from "../Std.js";
import Settings from "../Settings.js";
import $ from "../smallQ.js";
import GeoJSONCollection from "../GeoJSONCollection.js";
const States = {
TRACKLIST : 0,
......@@ -17,6 +20,11 @@ const States = {
SETTINGS : 2,
};
/**
* main viewcontroller class
*
* @author Michael Ochmann <ochmannm@hochschule-trier.de>
*/
class ViewController extends UIViewController {
constructor() {
super("body");
......@@ -27,6 +35,11 @@ class ViewController extends UIViewController {
this.renderCall();
}
/**
* adding all EventListeners
*
* @override
*/
viewDidLoad() {
$(document).on("TrackListController:select", (item, event) => {
console.log(event);
......@@ -37,7 +50,7 @@ class ViewController extends UIViewController {
$("main").css("height", window.innerHeight - 93);
$("#about").click(event => {
alert("HeighTracker\n\nTracking GEO height of courses\nin a simple webapp\n\n© 2018, Michael Ochmann");
alert(`trakr.\n\nTracking GEO height of courses\nin a simple webapp\n\n© 2018, Michael Ochmann`);
});
$("#settings").click(event => {
......@@ -89,6 +102,10 @@ class ViewController extends UIViewController {
$(".modal").removeClass("show");
}
/**
* @override
* @return {string}
*/
render() {
this.children = [];
let leftButton = "<a></a>";
......@@ -138,6 +155,9 @@ class ViewController extends UIViewController {
`;
}
/**
* should trigger GeoJSON download for current track
*/
download() {
let filename = `${this.tracks.get(this.track).name.toLowerCase().replace(new RegExp(" ", "g"), '_')}.json`;
let text = new GeoJSONCollection(this.tracks.get(this.track)).toString();
......@@ -154,6 +174,11 @@ class ViewController extends UIViewController {
document.body.removeChild(element);
}
/**
* should trigger GeoJSON download for current track
*
* possible fix for iOS, but does also not work, though
*/
downloadIOS() {
let track = this.tracks.get(this.track);
let mediaType = "plain/text";
......
import $ from "../smallQ.js";
import Std from "../Std.js";
import GeoPoint from "../GeoPoint.js";
/**
* model for a single track
*
* @author Michael Ochmann <ochmannm@hochschule-trier.de>
*/
class HeightMap {
constructor(app, trackID) {
this.app = app;
......@@ -29,6 +31,11 @@ class HeightMap {
}
}
/**
* adds a 'GeoPoint` to the model and calculates `min`, `max` and `median` height
*
* @param geoPoint
*/
add(geoPoint) {
if (geoPoint.constructor.name !== "GeoPoint")
throw new TypeError("an object of type 'GeoPoint' must be p1assed.");
......
import $ from "../smallQ.js";
/**
* model for the track-collection
*
* @author Michael Ochmann <ochmannm@hochschule-trier.de>
*/
class Tracks {
constructor() {
this._tracks = JSON.parse(localStorage.getItem("tracks")) || [];
}
/**
* adds a track to the collection
*
* @param track
*/
add(track) {
this._tracks.push(track);
this._save();
}
/**
* updates the `GeoPoints` of a track
*
* @param trackID
* @param points
*/
update(trackID, points) {
this._tracks[trackID].points = points;
this._save();
}
/**
* deletes a track
*
* @param trackID
*/
remove(trackID) {
this._tracks.splice(trackID, 1);
this._save();
}
/**
* return a track
*
* @param trackID
* @return {array}
*/
get(trackID) {
return this._tracks[trackID];
}
/**
* saves the tracklist to `navigator.localStorage`
*
* @private
*/
_save() {
localStorage.setItem("tracks", JSON.stringify(this._tracks))
}
/**
* return all tracks
*
* @return {array}
*/
tracks() {
if (!this._tracks)
return [];
......
/**
* jQuery inspired minimal helper library for DOM-manipulation
*
* @author Michael Ochmann <ochmannm@hochschule-trier.de>
*/
class smallQ {
constructor(selector) {
if (selector.constructor.name !== "String")
......
......@@ -2,12 +2,9 @@ importScripts("./node_modules/workbox-sw/build/workbox-sw.js");
const assets = [
"./",
"./src/javascript/App.js",
"./src/javascript/GeoPoint.js",
"./src/javascript/HeightMap.js",
"./src/javascript/main.js",
"./src/javascript/smallQ.js",
"./src/javascript/Std.js",
"./src/javascript/",
"./src/fonts/",
".src/images/",
"./src/app.css",
"./src/index.html"
];
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment