all repos — onyx @ c75b07fc3208cab7ce8c5ac6a2d1d22ef4b4a99d

minimal map annotation and location data sharing tool

fix modal and start planning polygon creation
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEkFh6dA+k/6CXFXU4O3+8IhROY5gFAmL4nIMACgkQO3+8IhRO
Y5jeHw/9EoclXsF9p3pUKXk9NV7c1evP/tjVbP7T1sU+4n3Ttl6UAQacEM7ltYtr
7AISOL3SixRHSuiphCWtP8ayTFXzZRHHp/hZtRcuaP+uJ/hviowgRgLlFHuyEyqe
SVBCIVdzCPb2tGuwGHOMoi5wtCKwa1t2kExS49NPGw1NhVwUuhq8GT82ikHlP7fP
N9Ip4aOUdLosbYP3d0hUa0zM1iegptMstEPJZq6rua7aGCmLaRTPB8QCwEhK/qaa
EFfDKdwN0hCl2D9BckCPE3AClB8fzaU9nVk22gN9/oTvERQdVb1K6LDkHa2uA2xF
UhGf1mADDjfblv+6UvjvW6xmnL1H1G4ELRCgQ400k7gJpK0f7vx3jhvYej6o1neB
5Q1jx7Yp9iWc7508WxAw07RY5W6zZCyVAbNh76kM73szTCDrBD4O9X3eZ0SvNYWU
mN8PJ/ncCYRjogRUafbGHaFbDFbOTg2pDBahbsEnmWp8y9KHMMHv+KfyplU6HTlu
q4WrFfH74bP6wK2nGFs7RSKhezAACXR0pkYd/KY2bBpatoou6RIatKShmioxEu34
0jPpzuolNfR9qonUC5J46q6IRnPClzDmXakipnmVr8CIlZMTMtRETUlNEk+kXS9m
dbM59Gf3ebLr5gAuMLjyh3yDsokRHglsGybwe+TJHAqorhWhbxo=
=h+hM
-----END PGP SIGNATURE-----
commit

c75b07fc3208cab7ce8c5ac6a2d1d22ef4b4a99d

parent

0bb6f69fa4cb96947bf308ebb3cedc5889891f00

M site/index.htmlstatic/index.html

@@ -2,11 +2,11 @@ <!DOCTYPE html>

<html lang='en'> <head> <meta charset='utf-8'> -<meta name='description' content='ONYX map annotation tool'/> +<meta name='description' content='map annotation tool'/> <meta name='viewport' content='width=device-width,initial-scale=1'> -<link rel='stylesheet' type='text/css' href='/static/style.css'> +<link rel='stylesheet' type='text/css' href='./style.css'> <!--<link rel='shortcut icon' href='/img/favicon.png'>--> -<title>ONYX - Scry/Pendulum</title> +<title>ONYX/scry</title> </head> <body> <noscript>

@@ -34,18 +34,18 @@ <div class="modalHeader">

<button class="closeBtn" id="createOverlay-closeBtn">x</button> <h2 id="createOverlay-title"></h2> </div> - <div id="createOverlay-content"> + <form id="createOverlay-content"> <label for="createOverlay-name">Name</label><br/> - <input type="text" id="createOverlay-name"><br/> + <input type="text" id="createOverlay-name" required ><br/> <label for="createOverlay-desc">Description</label><br/> - <textarea id="createOverlay-desc"></textarea><br/> + <textarea id="createOverlay-desc" required></textarea><br/> <div id="radius-container"> <label for="createOverlay-radius">Radius (meters)</label><br/> - <input type="number" step="1" id="createOverlay-radius" value="500"><br/> + <input type="number" step="1" id="createOverlay-radius" value="500" required><br/> </div> - <button id="createOverlay-submitBtn">OK</button> - </div> + <button type="submit" id="createOverlay-submitBtn">OK</button> + </form> </div> <div id="cancel-container">

@@ -87,7 +87,7 @@ </div>

</div> <!--</div>--> </body> -<link rel='stylesheet' type="text/css" href="/static/leaflet.css"> -<script src="/static/leaflet.js"></script> -<script src="/static/onyx-scry.js"></script> +<link rel='stylesheet' type="text/css" href="./leaflet.css"> +<script src="./leaflet.js"></script> +<script src="./onyx-scry.js"></script> </html>
M src/10-overlay.tssrc/10-overlay.ts

@@ -82,6 +82,17 @@ this.self = L.polygon(points, options);

} } +class Path extends OverlayBase { + constructor() { + super("", "", [ ], {}); + this.self = L.polyline([]); + } + + insertPoint(pt: Point) { + this.self.addLatLng(pt); + } +} + class OverlayState { markers: Marker[]; circles: Circle[];
A src/12-textUtils.ts

@@ -0,0 +1,13 @@

+class TextUtils { + static decodeHTML(text: string): string { + const textArea = document.createElement('textarea'); + textArea.innerHTML = text; + return textArea.value; + } + + static encodeHTML(text: string): string { + const textArea = document.createElement('textarea'); + textArea.innerText = text; + return textArea.innerHTML; + } +}
M src/20-createOverlayModal.tssrc/20-createOverlayModal.ts

@@ -51,15 +51,30 @@ modal.style.display = v ? "block" : "none";

} } + clearInputs(): void { + const name = document.getElementById("createOverlay-name") as HTMLInputElement; + const desc = document.getElementById("createOverlay-desc") as HTMLInputElement; + const radius = document.getElementById("createOverlay-radius") as HTMLInputElement; + + if (name?.value) { + name.value = ""; + } + if (desc?.value) { + desc.value = ""; + } + if (Number(radius?.value) != 500) { + radius.value = "500"; + } + } + setState(state: OverlayType, args: any): void { const _this = this; const title = this.title() const radiusContainer = _this.radiusContainer(); - const radius = _this.radiusField(); - const name = _this.nameField(); - const desc = _this.descField(); const submitBtn = _this.submitBtn(); + _this.clearInputs(); + if (radiusContainer) { radiusContainer.style.display = state == OverlayType.CIRCLE ? "block" : "none"; }

@@ -72,6 +87,8 @@ }

if (submitBtn) { submitBtn.onclick = () => { + const name = TextUtils.encodeHTML(_this.nameField()); + const desc = TextUtils.encodeHTML(_this.descField()); const point = new Marker(name, desc, args.latlng, {title: name, alt: name}); point.add(args.map); args.overlays.markers.push(point);

@@ -85,6 +102,9 @@ title.innerHTML = "Add Circle";

} if (submitBtn) { submitBtn.onclick = () => { + const radius = _this.radiusField(); + const name = TextUtils.encodeHTML(_this.nameField()); + const desc = TextUtils.encodeHTML(_this.descField()); const circle = new Circle(name, desc, args.latlng, {radius: Number(radius) || 500}); circle.add(args.map); args.overlays.circles.push(circle);
M src/30-handlers.tssrc/40-handlers.ts

@@ -102,7 +102,7 @@

static overlayClear(e: any): void { const self = MapHandler.instance; if (self) { - OverlayState.clear(self.overlays, self.map); + self.overlays = OverlayState.clear(self.overlays, self.map); } }
M static/onyx-scry.jsstatic/onyx-scry.js

@@ -54,6 +54,15 @@ super(name, desc, points, options);

this.self = L.polygon(points, options); } } +class Path extends OverlayBase { + constructor() { + super("", "", [], {}); + this.self = L.polyline([]); + } + insertPoint(pt) { + this.self.addLatLng(pt); + } +} class OverlayState { constructor() { this.markers = [];

@@ -141,6 +150,18 @@ }

} } TileLayerWrapper.layers = new Array(); +class TextUtils { + static decodeHTML(text) { + const textArea = document.createElement('textarea'); + textArea.innerHTML = text; + return textArea.value; + } + static encodeHTML(text) { + const textArea = document.createElement('textarea'); + textArea.innerText = text; + return textArea.innerHTML; + } +} class CreateOverlayModal { constructor() { const _this = this;

@@ -186,14 +207,26 @@ if (modal) {

modal.style.display = v ? "block" : "none"; } } + clearInputs() { + const name = document.getElementById("createOverlay-name"); + const desc = document.getElementById("createOverlay-desc"); + const radius = document.getElementById("createOverlay-radius"); + if (name === null || name === void 0 ? void 0 : name.value) { + name.value = ""; + } + if (desc === null || desc === void 0 ? void 0 : desc.value) { + desc.value = ""; + } + if (Number(radius === null || radius === void 0 ? void 0 : radius.value) != 500) { + radius.value = "500"; + } + } setState(state, args) { const _this = this; const title = this.title(); const radiusContainer = _this.radiusContainer(); - const radius = _this.radiusField(); - const name = _this.nameField(); - const desc = _this.descField(); const submitBtn = _this.submitBtn(); + _this.clearInputs(); if (radiusContainer) { radiusContainer.style.display = state == OverlayType.CIRCLE ? "block" : "none"; }

@@ -204,6 +237,8 @@ title.innerHTML = "Add Marker";

} if (submitBtn) { submitBtn.onclick = () => { + const name = TextUtils.encodeHTML(_this.nameField()); + const desc = TextUtils.encodeHTML(_this.descField()); const point = new Marker(name, desc, args.latlng, { title: name, alt: name }); point.add(args.map); args.overlays.markers.push(point);

@@ -217,6 +252,9 @@ title.innerHTML = "Add Circle";

} if (submitBtn) { submitBtn.onclick = () => { + const radius = _this.radiusField(); + const name = TextUtils.encodeHTML(_this.nameField()); + const desc = TextUtils.encodeHTML(_this.descField()); const circle = new Circle(name, desc, args.latlng, { radius: Number(radius) || 500 }); circle.add(args.map); args.overlays.circles.push(circle);

@@ -327,7 +365,7 @@ }

static overlayClear(e) { const self = MapHandler.instance; if (self) { - OverlayState.clear(self.overlays, self.map); + self.overlays = OverlayState.clear(self.overlays, self.map); } } static swapTiles(e) {
D static/pendulum.js

@@ -1,312 +0,0 @@

-"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -var Point = /** @class */ (function () { - function Point() { - this.lat = 0.00; - this.lng = 0.00; - } - return Point; -}()); -var OverlayType; -(function (OverlayType) { - OverlayType[OverlayType["POINT"] = 0] = "POINT"; - OverlayType[OverlayType["CIRCLE"] = 1] = "CIRCLE"; - OverlayType[OverlayType["POLYGON"] = 2] = "POLYGON"; -})(OverlayType || (OverlayType = {})); -var OverlayData = /** @class */ (function () { - function OverlayData(type, name, desc, points, options) { - this.type = type; - this.name = name; - this.desc = desc; - this.points = points; - this.options = options; - } - return OverlayData; -}()); -var OverlayBase = /** @class */ (function () { - function OverlayBase(name, desc, points, options) { - this.name = name; - this.desc = desc; - this.points = points; - this.options = options; - } - OverlayBase.prototype.add = function (map) { - this.self.addTo(map); - }; - OverlayBase.prototype.remove = function (map) { - this.self.removeFrom(map); - }; - return OverlayBase; -}()); -var Marker = /** @class */ (function (_super) { - __extends(Marker, _super); - function Marker(name, desc, point, options) { - var _this_1 = _super.call(this, name, desc, [point], options) || this; - _this_1.self = L.marker(point); - _this_1.self.bindPopup("<h3>" + name + "</h3><p>" + desc + "</p>"); - return _this_1; - } - return Marker; -}(OverlayBase)); -var Circle = /** @class */ (function (_super) { - __extends(Circle, _super); - function Circle(name, desc, point, options) { - var _this_1 = _super.call(this, name, desc, [point], options) || this; - _this_1.self = L.circle(point, options); - return _this_1; - } - return Circle; -}(OverlayBase)); -var Polygon = /** @class */ (function (_super) { - __extends(Polygon, _super); - function Polygon(name, desc, points, options) { - var _this_1 = _super.call(this, name, desc, points, options) || this; - _this_1.self = L.polygon(points, options); - return _this_1; - } - return Polygon; -}(OverlayBase)); -var OverlayState = /** @class */ (function () { - function OverlayState() { - this.markers = []; - this.circles = []; - this.polygons = []; - } - OverlayState.load = function () { - var store = localStorage.getItem("overlay_state"); - if (store) { - var model = JSON.parse(store); - return { - markers: model.markers.map(function (m) { return OverlayState.fromData(m); }), - circles: model.circles.map(function (c) { return OverlayState.fromData(c); }), - polygons: model.polygons.map(function (p) { return OverlayState.fromData(p); }) - }; - } - else { - return new OverlayState(); - } - }; - OverlayState.save = function (overlayState) { - localStorage.setItem("overlay_state", JSON.stringify({ - markers: overlayState.markers.map(function (m) { return OverlayState.toData(m); }), - circles: overlayState.circles.map(function (c) { return OverlayState.toData(c); }), - polygons: overlayState.polygons.map(function (p) { return OverlayState.toData(p); }) - })); - }; - OverlayState.clear = function (overlayState, map) { - overlayState.markers.forEach(function (m) { return m.remove(map); }); - overlayState.circles.forEach(function (c) { return c.remove(map); }); - overlayState.polygons.forEach(function (p) { return p.remove(map); }); - return new OverlayState(); - }; - OverlayState.toData = function (source) { - var type = OverlayType.POINT; - if (source.points.length > 1) { - type = OverlayType.POLYGON; - } - else if (source.options.radius) { - type = OverlayType.CIRCLE; - } - return new OverlayData(type, source.name, source.desc, source.points, source.options); - }; - OverlayState.fromData = function (data) { - switch (data.type) { - case OverlayType.POINT: - return new Marker(data.name, data.desc, data.points[0], data.options); - case OverlayType.CIRCLE: - return new Circle(data.name, data.desc, data.points[0], data.options); - case OverlayType.POLYGON: - return new Polygon(data.name, data.desc, data.points, data.options); - } - }; - return OverlayState; -}()); -var TileLayerWrapper = /** @class */ (function () { - function TileLayerWrapper(name, self) { - this.visible = false; - this.self = self; - this.name = name; - } - TileLayerWrapper.constructLayer = function (name, self) { - var wrapper = new TileLayerWrapper(name, self); - TileLayerWrapper.layers.push(wrapper); - return wrapper; - }; - TileLayerWrapper.getActiveLayer = function () { - for (var _i = 0, _a = TileLayerWrapper.layers; _i < _a.length; _i++) { - var l = _a[_i]; - if (l.visible == true) { - return l; - } - } - return null; - }; - TileLayerWrapper.enableOnly = function (self, map) { - for (var _i = 0, _a = TileLayerWrapper.layers; _i < _a.length; _i++) { - var l = _a[_i]; - if (l.visible) { - l.self.removeFrom(map); - l.visible = false; - } - if (l.name == self.name) { - l.self.addTo(map); - l.visible = true; - } - } - }; - TileLayerWrapper.layers = new Array(); - return TileLayerWrapper; -}()); -var Modal = /** @class */ (function () { - function Modal() { - var _this = this; - var closeBtn = document.getElementById("modalCloseBtn"); - if (closeBtn) { - closeBtn.onclick = function () { _this.setVisible(false); }; - } - } - Modal.prototype.self = function () { - return document.getElementById("modal-container"); - }; - Modal.prototype.title = function () { - return document.getElementById("modal-title"); - }; - Modal.prototype.content = function () { - return document.getElementById("modal-content"); - }; - Modal.prototype.submitBtn = function () { - return document.getElementById("modal-submitBtn"); - }; - Modal.prototype.nameField = function () { - var _a, _b; - return (_b = (_a = document.getElementById("modal-name")) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : ""; - }; - Modal.prototype.descField = function () { - var _a, _b; - return (_b = (_a = document.getElementById("modal-desc")) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : ""; - }; - Modal.prototype.visible = function () { - var _a; - return ((_a = this.self()) === null || _a === void 0 ? void 0 : _a.style.display) != "none"; - }; - Modal.prototype.setVisible = function (v) { - var modal = this.self(); - if (modal) { - modal.style.display = v ? "block" : "none"; - } - }; - Modal.prototype.setState = function (state, args) { - var _this = this; - switch (state) { - case OverlayType.POINT: - var title = this.title(); - if (title) { - title.innerHTML = "Add Marker"; - } - fetch("/static/pointModal.html") - .then(function (r) { return r.text(); }) - .then(function (t) { - var content = _this.content(); - if (content) { - content.innerHTML = t; - } - var submitBtn = _this.submitBtn(); - if (submitBtn) { - submitBtn.onclick = function () { - var name = _this.nameField(); - var desc = _this.descField(); - var point = new Marker(name, desc, args.latlng, { title: name, alt: name }); - point.add(args.map); - args.overlays.markers.push(point); - _this.setVisible(false); - }; - } - }); - break; - case OverlayType.CIRCLE: - break; - case OverlayType.POLYGON: - break; - } - }; - return Modal; -}()); -var MapHandlers = /** @class */ (function () { - function MapHandlers() { - } - return MapHandlers; -}()); -function init() { - var _a; - var overlays = (_a = OverlayState.load()) !== null && _a !== void 0 ? _a : new OverlayState(); - var map = L.map('map').setView([35.6653, -105.9507], 13); - var streetLayer = TileLayerWrapper.constructLayer("streetLayer", L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { - maxZoom: 19, - attribution: '© OpenStreetMap' - })); - var satelliteLayer = TileLayerWrapper.constructLayer("satelliteLayer", L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { - maxZoom: 19, - attribution: "&copy; Esri" - })); - TileLayerWrapper.enableOnly(streetLayer, map); - overlays.markers.forEach(function (m) { return m.add(map); }); - overlays.circles.forEach(function (m) { return m.add(map); }); - overlays.polygons.forEach(function (m) { return m.add(map); }); - var modal = new Modal(); - var addMarkerHandler = function (e) { - modal.setVisible(true); - modal.setState(OverlayType.POINT, { - latlng: e.latlng, - map: map, - overlays: overlays - }); - map.off("click", addMarkerHandler); - }; - var addMarkerBtn = document.getElementById("addPoint-btn"); - if (addMarkerBtn) { - addMarkerBtn.onclick = function (e) { - try { - map.off("click", addMarkerHandler); - } - finally { - map.on("click", addMarkerHandler); - } - }; - } - var saveBtn = document.getElementById("save-btn"); - if (saveBtn) { - saveBtn.onclick = function (e) { - OverlayState.save(overlays); - }; - } - var clearBtn = document.getElementById("clear-btn"); - if (clearBtn) { - clearBtn.onclick = function (e) { - overlays = OverlayState.clear(overlays, map); - }; - } - var tilesBtn = document.getElementById("tiles-btn"); - if (tilesBtn) { - tilesBtn.onclick = function (e) { - if (TileLayerWrapper.getActiveLayer() == satelliteLayer) { - TileLayerWrapper.enableOnly(streetLayer, map); - } - else { - TileLayerWrapper.enableOnly(satelliteLayer, map); - } - }; - } -} -init();