fix modal and start planning polygon creation
This commit is contained in:
parent
0bb6f69fa4
commit
c75b07fc32
7 changed files with 102 additions and 332 deletions
|
@ -82,6 +82,17 @@ class Polygon extends OverlayBase {
|
|||
}
|
||||
}
|
||||
|
||||
class Path extends OverlayBase {
|
||||
constructor() {
|
||||
super("", "", [ ], {});
|
||||
this.self = L.polyline([]);
|
||||
}
|
||||
|
||||
insertPoint(pt: Point) {
|
||||
this.self.addLatLng(pt);
|
||||
}
|
||||
}
|
||||
|
||||
class OverlayState {
|
||||
markers: Marker[];
|
||||
circles: Circle[];
|
||||
|
|
13
src/12-textUtils.ts
Normal file
13
src/12-textUtils.ts
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -51,15 +51,30 @@ class CreateOverlayModal {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ class CreateOverlayModal {
|
|||
|
||||
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 @@ class CreateOverlayModal {
|
|||
}
|
||||
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);
|
||||
|
|
|
@ -102,7 +102,7 @@ class MapHandler {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,11 +2,11 @@
|
|||
<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 @@
|
|||
<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>-->
|
||||
</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>
|
|
@ -54,6 +54,15 @@ class Polygon extends OverlayBase {
|
|||
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 @@ class TileLayerWrapper {
|
|||
}
|
||||
}
|
||||
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 @@ class CreateOverlayModal {
|
|||
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 @@ class CreateOverlayModal {
|
|||
}
|
||||
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 @@ class CreateOverlayModal {
|
|||
}
|
||||
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 @@ class MapHandler {
|
|||
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) {
|
||||
|
|
|
@ -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: "© 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();
|
Loading…
Reference in a new issue