add polygon support and use cancel/okCancel modals

This commit is contained in:
Iris Lightshard 2022-08-14 20:44:00 -06:00
parent c80313085e
commit fbd1d515d3
Signed by: Iris Lightshard
GPG key ID: 3B7FBC22144E6398
11 changed files with 524 additions and 30 deletions

View file

@ -79,17 +79,28 @@ class Polygon extends OverlayBase {
constructor(name: string, desc: string, points: Point[], options: any) { constructor(name: string, desc: string, points: Point[], options: any) {
super(name, desc, points, options); super(name, desc, points, options);
this.self = L.polygon(points, options); this.self = L.polygon(points, options);
this.self.bindPopup(`<h3>${name}</h3><p>${desc}</p>`);
} }
} }
class Path extends OverlayBase { class Polyline extends OverlayBase {
constructor() { constructor() {
super("", "", [ ], {}); super("", "", [ ], {});
this.self = L.polyline([]); this.self = L.polyline([]);
} }
insertPoint(pt: Point) { insertPoint(pt: Point): void {
this.self.addLatLng(pt); this.self.addLatLng(pt);
this.points.push(pt);
}
clearPoints(): void {
this.points = [];
this.self.setLatLngs([]);
}
numPoints(): number {
return this.self.getLatLngs().length;
} }
} }
@ -97,11 +108,13 @@ class OverlayState {
markers: Marker[]; markers: Marker[];
circles: Circle[]; circles: Circle[];
polygons: Polygon[]; polygons: Polygon[];
polyline: Polyline;
constructor() { constructor() {
this.markers = []; this.markers = [];
this.circles = []; this.circles = [];
this.polygons = []; this.polygons = [];
this.polyline = new Polyline();
} }
static load(): OverlayState { static load(): OverlayState {
@ -112,6 +125,7 @@ class OverlayState {
markers: model.markers.map((m: OverlayData) => OverlayState.fromData(m)), markers: model.markers.map((m: OverlayData) => OverlayState.fromData(m)),
circles: model.circles.map((c: OverlayData) => OverlayState.fromData(c)), circles: model.circles.map((c: OverlayData) => OverlayState.fromData(c)),
polygons: model.polygons.map((p: OverlayData) => OverlayState.fromData(p)), polygons: model.polygons.map((p: OverlayData) => OverlayState.fromData(p)),
polyline: new Polyline(),
} as OverlayState } as OverlayState
} else { } else {
return new OverlayState(); return new OverlayState();

View file

@ -1,11 +1,13 @@
class TextUtils { class TextUtils {
static decodeHTML(text: string): string { static decodeHTML(text: string): string {
return text;
const textArea = document.createElement('textarea'); const textArea = document.createElement('textarea');
textArea.innerHTML = text; textArea.innerHTML = text;
return textArea.value; return textArea.value;
} }
static encodeHTML(text: string): string { static encodeHTML(text: string): string {
return text;
const textArea = document.createElement('textarea'); const textArea = document.createElement('textarea');
textArea.innerText = text; textArea.innerText = text;
return textArea.innerHTML; return textArea.innerHTML;

View file

@ -89,6 +89,9 @@ class CreateOverlayModal {
submitBtn.onclick = () => { submitBtn.onclick = () => {
const name = TextUtils.encodeHTML(_this.nameField()); const name = TextUtils.encodeHTML(_this.nameField());
const desc = TextUtils.encodeHTML(_this.descField()); const desc = TextUtils.encodeHTML(_this.descField());
if (name.trim().length < 1 || desc.trim().length < 1) {
return;
}
const point = new Marker(name, desc, args.latlng, {title: name, alt: name}); const point = new Marker(name, desc, args.latlng, {title: name, alt: name});
point.add(args.map); point.add(args.map);
args.overlays.markers.push(point); args.overlays.markers.push(point);
@ -105,6 +108,9 @@ class CreateOverlayModal {
const radius = _this.radiusField(); const radius = _this.radiusField();
const name = TextUtils.encodeHTML(_this.nameField()); const name = TextUtils.encodeHTML(_this.nameField());
const desc = TextUtils.encodeHTML(_this.descField()); const desc = TextUtils.encodeHTML(_this.descField());
if (name.trim().length < 1 || desc.trim().length < 1) {
return;
}
const circle = new Circle(name, desc, args.latlng, {radius: Number(radius) || 500}); const circle = new Circle(name, desc, args.latlng, {radius: Number(radius) || 500});
circle.add(args.map); circle.add(args.map);
args.overlays.circles.push(circle); args.overlays.circles.push(circle);
@ -113,6 +119,22 @@ class CreateOverlayModal {
} }
break; break;
case OverlayType.POLYGON: case OverlayType.POLYGON:
if (title) {
title.innerHTML = "Add Polygon";
}
if (submitBtn) {
submitBtn.onclick = () => {
const name = TextUtils.encodeHTML(_this.nameField());
const desc = TextUtils.encodeHTML(_this.descField());
if (name.trim().length < 1 || desc.trim().length < 1) {
return;
}
const polygon = new Polygon(name, desc, args.points, {});
polygon.add(args.map);
args.overlays.polygons.push(polygon);
_this.setVisible(false);
}
}
break; break;
} }
} }

31
src/21-cancelModal.ts Normal file
View file

@ -0,0 +1,31 @@
class CancelModal {
self(): HTMLElement | null {
return document.getElementById("cancel-container");
}
cancelMsg(): HTMLElement | null {
return document.getElementById("cancel-msg");
}
cancelBtn(): HTMLElement | null {
return document.getElementById("cancel-btn");
}
visible(): boolean {
return this.self()?.style.display != "none";
}
setVisible(v: boolean): void {
const modal = this.self();
if (modal) {
modal.style.display = v ? "block" : "none";
}
}
setMsg(s: string): void {
const msg = this.cancelMsg();
if (msg) {
msg.innerText = s;
}
}
}

35
src/22-okCancelModal.ts Normal file
View file

@ -0,0 +1,35 @@
class OKCancelModal {
self(): HTMLElement | null {
return document.getElementById("confirm-container");
}
confirmMsg(): HTMLElement | null {
return document.getElementById("confirm-msg");
}
okBtn(): HTMLElement | null {
return document.getElementById("yes-btn");
}
cancelBtn(): HTMLElement | null {
return document.getElementById("no-btn");
}
visible(): boolean {
return this.self()?.style.display != "none";
}
setVisible(v: boolean): void {
const modal = this.self();
if (modal) {
modal.style.display = v ? "block" : "none";
}
}
setMsg(s: string): void {
const msg = this.confirmMsg();
if (msg) {
msg.innerText = s;
}
}
}

View file

@ -1,11 +1,21 @@
class ModalCollection { class ModalCollection {
createOverlay: CreateOverlayModal; createOverlay: CreateOverlayModal;
cancel: CancelModal;
okCancel: OKCancelModal;
constructor(createOverlay: CreateOverlayModal) { constructor(
createOverlay: CreateOverlayModal,
cancel: CancelModal,
okCancel: OKCancelModal
) {
this.createOverlay = createOverlay; this.createOverlay = createOverlay;
this.cancel = cancel;
this.okCancel = okCancel;
} }
closeAll(): void { closeAll(): void {
this.createOverlay.setVisible(false); this.createOverlay.setVisible(false);
this.cancel.setVisible(false);
this.okCancel.setVisible(false);
} }
} }

View file

@ -34,14 +34,21 @@ class MapHandler {
if (addPointBtn) { if (addPointBtn) {
addPointBtn.classList.remove("activeBtn"); addPointBtn.classList.remove("activeBtn");
} }
self.map.off("click", this.addMarker); self.map.off("click", MapHandler.addMarker);
} catch {} } catch {}
try { try {
const addCircleBtn = document.getElementById("addCircle-btn"); const addCircleBtn = document.getElementById("addCircle-btn");
if (addCircleBtn) { if (addCircleBtn) {
addCircleBtn.classList.remove("activeBtn"); addCircleBtn.classList.remove("activeBtn");
} }
self.map.off("click", this.addCircle); self.map.off("click", MapHandler.addCircle);
} catch {}
try {
const addPolygonBtn = document.getElementById("addPolygon-btn");
if (addPolygonBtn) {
addPolygonBtn.classList.remove("activeBtn");
}
self.map.off("click", MapHandler.polygonAddPoint);
} catch {} } catch {}
} }
} }
@ -49,26 +56,43 @@ class MapHandler {
static addMarker(e: any): void { static addMarker(e: any): void {
const self = MapHandler.instance; const self = MapHandler.instance;
if (self) { if (self) {
self.modals.createOverlay.setVisible(true); self.modals.cancel.setVisible(false);
self.modals.createOverlay.setState(OverlayType.POINT, { self.modals.createOverlay.setState(OverlayType.POINT, {
latlng: e.latlng, latlng: e.latlng,
map: self.map, map: self.map,
overlays: self.overlays, overlays: self.overlays,
}); });
MapHandler.resetMapClick(); MapHandler.resetMapClick();
self.modals.createOverlay.setVisible(true);
} }
} }
static addCircle(e: any): void { static addCircle(e: any): void {
const self = MapHandler.instance; const self = MapHandler.instance;
if (self) { if (self) {
self.modals.createOverlay.setVisible(true); self.modals.cancel.setVisible(false);
self.modals.createOverlay.setState(OverlayType.CIRCLE, { self.modals.createOverlay.setState(OverlayType.CIRCLE, {
latlng: e.latlng, latlng: e.latlng,
map: self.map, map: self.map,
overlays: self.overlays, overlays: self.overlays,
}); });
MapHandler.resetMapClick(); MapHandler.resetMapClick();
self.modals.createOverlay.setVisible(true);
}
}
static addPolygon(e: any): void {
const self = MapHandler.instance;
if (self) {
self.modals.okCancel.setVisible(false);
self.modals.createOverlay.setState(OverlayType.POLYGON, {
points: self.overlays.polyline.points,
map: self.map,
overlays: self.overlays,
});
MapHandler.resetMapClick();
self.overlays.polyline.clearPoints();
self.modals.createOverlay.setVisible(true);
} }
} }
@ -79,6 +103,16 @@ class MapHandler {
MapHandler.resetMapClick(); MapHandler.resetMapClick();
(e.target as HTMLElement).classList.add("activeBtn"); (e.target as HTMLElement).classList.add("activeBtn");
self.map.on("click", MapHandler.addCircle); self.map.on("click", MapHandler.addCircle);
const cancelBtn = self.modals.cancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = ()=> {
self.modals.closeAll();
MapHandler.resetMapClick();
};
}
self.modals.cancel.setMsg("Placing circle");
self.modals.cancel.setVisible(true);
} }
} }
@ -89,20 +123,116 @@ class MapHandler {
MapHandler.resetMapClick(); MapHandler.resetMapClick();
(e.target as HTMLElement).classList.add("activeBtn"); (e.target as HTMLElement).classList.add("activeBtn");
self.map.on("click", MapHandler.addMarker); self.map.on("click", MapHandler.addMarker);
const cancelBtn = self.modals.cancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = ()=> {
self.modals.closeAll();
MapHandler.resetMapClick();
};
}
self.modals.cancel.setMsg("Placing marker");
self.modals.cancel.setVisible(true);
}
}
static polygonCollect(e: any): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
MapHandler.resetMapClick();
(e.target as HTMLElement).classList.add("activeBtn");
// show cancel -- on cancel, clear polyline and reset map handling
const cancelBtn = self.modals.cancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = MapHandler.polygonClearPoints;
}
self.modals.cancel.setMsg("Creating polygon");
self.modals.cancel.setVisible(true);
self.map.on("click", MapHandler.polygonAddPoint);
}
}
static polygonClearPoints(e: any): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
self.overlays.polyline.clearPoints();
MapHandler.resetMapClick();
}
}
static polygonAddPoint(e: any): void {
const self = MapHandler.instance;
if (self) {
self.overlays.polyline.insertPoint(e.latlng);
if (self.overlays.polyline.numPoints() >= 3) {
self.modals.cancel.setVisible(false);
const okBtn = self.modals.okCancel.okBtn();
if (okBtn) {
okBtn.onclick = MapHandler.addPolygon;
}
const cancelBtn = self.modals.okCancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = MapHandler.polygonClearPoints;
}
self.modals.okCancel.setMsg("Creating polygon");
self.modals.okCancel.setVisible(true);
}
} }
} }
static overlaySave(e: any): void { static overlaySave(e: any): void {
const self = MapHandler.instance; const self = MapHandler.instance;
if (self) { if (self) {
OverlayState.save(self.overlays); self.modals.closeAll();
MapHandler.resetMapClick();
(e.target as HTMLElement).classList.add("activeBtn");
self.modals.okCancel.setMsg("Save current map overlays?");
const okBtn = self.modals.okCancel.okBtn();
if (okBtn) {
okBtn.onclick = ()=> {
OverlayState.save(self.overlays);
self.modals.okCancel.setVisible(false);
// show info modal "Save complete"
}
}
const cancelBtn = self.modals.okCancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = () => {
self.modals.okCancel.setVisible(false);
}
}
self.modals.okCancel.setVisible(true);
} }
} }
static overlayClear(e: any): void { static overlayClear(e: any): void {
const self = MapHandler.instance; const self = MapHandler.instance;
if (self) { if (self) {
self.overlays = OverlayState.clear(self.overlays, self.map); self.modals.closeAll();
MapHandler.resetMapClick();
(e.target as HTMLElement).classList.add("activeBtn");
self.modals.okCancel.setMsg("Clear all map overlays (will not affect saved data)?");
const okBtn = self.modals.okCancel.okBtn();
if (okBtn) {
okBtn.onclick = ()=> {
self.overlays = OverlayState.clear(self.overlays, self.map);
self.modals.okCancel.setVisible(false);
}
}
const cancelBtn = self.modals.okCancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = () => {
self.modals.okCancel.setVisible(false);
}
}
self.modals.okCancel.setVisible(true);
} }
} }

View file

@ -26,14 +26,18 @@ function init(): void {
overlays.markers.forEach(m=>m.add(map)); overlays.markers.forEach(m=>m.add(map));
overlays.circles.forEach(m=>m.add(map)); overlays.circles.forEach(m=>m.add(map));
overlays.polygons.forEach(m=>m.add(map)); overlays.polygons.forEach(m=>m.add(map));
const createOverlayModal = new CreateOverlayModal(); overlays.polyline.add(map);
const modals = new ModalCollection( const modals = new ModalCollection(
createOverlayModal); new CreateOverlayModal(),
new CancelModal(),
new OKCancelModal());
MapHandler.init(map, overlays, TileLayerWrapper.layers, modals); MapHandler.init(map, overlays, TileLayerWrapper.layers, modals);
MapHandler.setButtonClick("addPoint-btn", MapHandler.markerCollect); MapHandler.setButtonClick("addPoint-btn", MapHandler.markerCollect);
MapHandler.setButtonClick("addCircle-btn", MapHandler.circleCollect); MapHandler.setButtonClick("addCircle-btn", MapHandler.circleCollect);
MapHandler.setButtonClick("addPolygon-btn", MapHandler.polygonCollect);
MapHandler.setButtonClick("save-btn", MapHandler.overlaySave); MapHandler.setButtonClick("save-btn", MapHandler.overlaySave);
MapHandler.setButtonClick("clear-btn", MapHandler.overlayClear); MapHandler.setButtonClick("clear-btn", MapHandler.overlayClear);

View file

@ -22,8 +22,8 @@
<button id="addCircle-btn">&compfn;</button> <button id="addCircle-btn">&compfn;</button>
<button id="addPolygon-btn">&diamond;</button> <button id="addPolygon-btn">&diamond;</button>
<div id="subControls"> <div id="subControls">
<button id="tiles-btn">&Colon;</button>
<button id="save-btn">&darr;</button> <button id="save-btn">&darr;</button>
<button id="tiles-btn">&Colon;</button>
<button id="clear-btn">&olarr;</button> <button id="clear-btn">&olarr;</button>
<button id="menu-btn">&equiv;</button> <button id="menu-btn">&equiv;</button>
</div> </div>
@ -49,20 +49,23 @@
</div> </div>
<div id="cancel-container"> <div id="cancel-container">
<span id="cancel-msg"></span>
<div class="multiBtn-container">
<button class="negative-btn" id="cancel-btn">Cancel</button> <button class="negative-btn" id="cancel-btn">Cancel</button>
</div>
</div> </div>
<div id="info-container"> <div id="info-container">
<button class="closeBtn" id="info-closeBtn">x</button> <button class="closeBtn" id="info-closeBtn">x</button>
<div class="info-content> <div class="info-content">
</div> </div>
</div> </div>
<div id="confirm-container"> <div id="confirm-container">
<span id="confirm-msg"></span> <span id="confirm-msg"></span>
<div class="multiBtn-container"> <div class="multiBtn-container">
<button class="positive-btn" id="yes-btn">Yes</button> <button class="positive-btn" id="yes-btn">OK</button>
<button class="negative-btn" id="no-btn">No</button> <button class="negative-btn" id="no-btn">Cancel</button>
</div> </div>
</div> </div>

View file

@ -52,15 +52,24 @@ class Polygon extends OverlayBase {
constructor(name, desc, points, options) { constructor(name, desc, points, options) {
super(name, desc, points, options); super(name, desc, points, options);
this.self = L.polygon(points, options); this.self = L.polygon(points, options);
this.self.bindPopup(`<h3>${name}</h3><p>${desc}</p>`);
} }
} }
class Path extends OverlayBase { class Polyline extends OverlayBase {
constructor() { constructor() {
super("", "", [], {}); super("", "", [], {});
this.self = L.polyline([]); this.self = L.polyline([]);
} }
insertPoint(pt) { insertPoint(pt) {
this.self.addLatLng(pt); this.self.addLatLng(pt);
this.points.push(pt);
}
clearPoints() {
this.points = [];
this.self.setLatLngs([]);
}
numPoints() {
return this.self.getLatLngs().length;
} }
} }
class OverlayState { class OverlayState {
@ -68,6 +77,7 @@ class OverlayState {
this.markers = []; this.markers = [];
this.circles = []; this.circles = [];
this.polygons = []; this.polygons = [];
this.polyline = new Polyline();
} }
static load() { static load() {
const store = localStorage.getItem("overlay_state"); const store = localStorage.getItem("overlay_state");
@ -77,6 +87,7 @@ class OverlayState {
markers: model.markers.map((m) => OverlayState.fromData(m)), markers: model.markers.map((m) => OverlayState.fromData(m)),
circles: model.circles.map((c) => OverlayState.fromData(c)), circles: model.circles.map((c) => OverlayState.fromData(c)),
polygons: model.polygons.map((p) => OverlayState.fromData(p)), polygons: model.polygons.map((p) => OverlayState.fromData(p)),
polyline: new Polyline(),
}; };
} }
else { else {
@ -239,6 +250,9 @@ class CreateOverlayModal {
submitBtn.onclick = () => { submitBtn.onclick = () => {
const name = TextUtils.encodeHTML(_this.nameField()); const name = TextUtils.encodeHTML(_this.nameField());
const desc = TextUtils.encodeHTML(_this.descField()); const desc = TextUtils.encodeHTML(_this.descField());
if (name.trim().length < 1 || desc.trim().length < 1) {
return;
}
const point = new Marker(name, desc, args.latlng, { title: name, alt: name }); const point = new Marker(name, desc, args.latlng, { title: name, alt: name });
point.add(args.map); point.add(args.map);
args.overlays.markers.push(point); args.overlays.markers.push(point);
@ -255,6 +269,9 @@ class CreateOverlayModal {
const radius = _this.radiusField(); const radius = _this.radiusField();
const name = TextUtils.encodeHTML(_this.nameField()); const name = TextUtils.encodeHTML(_this.nameField());
const desc = TextUtils.encodeHTML(_this.descField()); const desc = TextUtils.encodeHTML(_this.descField());
if (name.trim().length < 1 || desc.trim().length < 1) {
return;
}
const circle = new Circle(name, desc, args.latlng, { radius: Number(radius) || 500 }); const circle = new Circle(name, desc, args.latlng, { radius: Number(radius) || 500 });
circle.add(args.map); circle.add(args.map);
args.overlays.circles.push(circle); args.overlays.circles.push(circle);
@ -263,16 +280,93 @@ class CreateOverlayModal {
} }
break; break;
case OverlayType.POLYGON: case OverlayType.POLYGON:
if (title) {
title.innerHTML = "Add Polygon";
}
if (submitBtn) {
submitBtn.onclick = () => {
const name = TextUtils.encodeHTML(_this.nameField());
const desc = TextUtils.encodeHTML(_this.descField());
if (name.trim().length < 1 || desc.trim().length < 1) {
return;
}
const polygon = new Polygon(name, desc, args.points, {});
polygon.add(args.map);
args.overlays.polygons.push(polygon);
_this.setVisible(false);
};
}
break; break;
} }
} }
} }
class CancelModal {
self() {
return document.getElementById("cancel-container");
}
cancelMsg() {
return document.getElementById("cancel-msg");
}
cancelBtn() {
return document.getElementById("cancel-btn");
}
visible() {
var _a;
return ((_a = this.self()) === null || _a === void 0 ? void 0 : _a.style.display) != "none";
}
setVisible(v) {
const modal = this.self();
if (modal) {
modal.style.display = v ? "block" : "none";
}
}
setMsg(s) {
const msg = this.cancelMsg();
if (msg) {
msg.innerText = s;
}
}
}
class OKCancelModal {
self() {
return document.getElementById("confirm-container");
}
confirmMsg() {
return document.getElementById("confirm-msg");
}
okBtn() {
return document.getElementById("yes-btn");
}
cancelBtn() {
return document.getElementById("no-btn");
}
visible() {
var _a;
return ((_a = this.self()) === null || _a === void 0 ? void 0 : _a.style.display) != "none";
}
setVisible(v) {
const modal = this.self();
if (modal) {
modal.style.display = v ? "block" : "none";
}
}
setMsg(s) {
const msg = this.confirmMsg();
if (msg) {
msg.innerText = s;
}
}
}
class ModalCollection { class ModalCollection {
constructor(createOverlay) { constructor(createOverlay, cancel, okCancel) {
this.createOverlay = createOverlay; this.createOverlay = createOverlay;
this.cancel = cancel;
this.okCancel = okCancel;
} }
closeAll() { closeAll() {
this.createOverlay.setVisible(false); this.createOverlay.setVisible(false);
this.cancel.setVisible(false);
this.okCancel.setVisible(false);
} }
} }
class MapHandler { class MapHandler {
@ -301,7 +395,7 @@ class MapHandler {
if (addPointBtn) { if (addPointBtn) {
addPointBtn.classList.remove("activeBtn"); addPointBtn.classList.remove("activeBtn");
} }
self.map.off("click", this.addMarker); self.map.off("click", MapHandler.addMarker);
} }
catch (_a) { } catch (_a) { }
try { try {
@ -309,33 +403,57 @@ class MapHandler {
if (addCircleBtn) { if (addCircleBtn) {
addCircleBtn.classList.remove("activeBtn"); addCircleBtn.classList.remove("activeBtn");
} }
self.map.off("click", this.addCircle); self.map.off("click", MapHandler.addCircle);
} }
catch (_b) { } catch (_b) { }
try {
const addPolygonBtn = document.getElementById("addPolygon-btn");
if (addPolygonBtn) {
addPolygonBtn.classList.remove("activeBtn");
}
self.map.off("click", MapHandler.polygonAddPoint);
}
catch (_c) { }
} }
} }
static addMarker(e) { static addMarker(e) {
const self = MapHandler.instance; const self = MapHandler.instance;
if (self) { if (self) {
self.modals.createOverlay.setVisible(true); self.modals.cancel.setVisible(false);
self.modals.createOverlay.setState(OverlayType.POINT, { self.modals.createOverlay.setState(OverlayType.POINT, {
latlng: e.latlng, latlng: e.latlng,
map: self.map, map: self.map,
overlays: self.overlays, overlays: self.overlays,
}); });
MapHandler.resetMapClick(); MapHandler.resetMapClick();
self.modals.createOverlay.setVisible(true);
} }
} }
static addCircle(e) { static addCircle(e) {
const self = MapHandler.instance; const self = MapHandler.instance;
if (self) { if (self) {
self.modals.createOverlay.setVisible(true); self.modals.cancel.setVisible(false);
self.modals.createOverlay.setState(OverlayType.CIRCLE, { self.modals.createOverlay.setState(OverlayType.CIRCLE, {
latlng: e.latlng, latlng: e.latlng,
map: self.map, map: self.map,
overlays: self.overlays, overlays: self.overlays,
}); });
MapHandler.resetMapClick(); MapHandler.resetMapClick();
self.modals.createOverlay.setVisible(true);
}
}
static addPolygon(e) {
const self = MapHandler.instance;
if (self) {
self.modals.okCancel.setVisible(false);
self.modals.createOverlay.setState(OverlayType.POLYGON, {
points: self.overlays.polyline.points,
map: self.map,
overlays: self.overlays,
});
MapHandler.resetMapClick();
self.overlays.polyline.clearPoints();
self.modals.createOverlay.setVisible(true);
} }
} }
static circleCollect(e) { static circleCollect(e) {
@ -345,6 +463,15 @@ class MapHandler {
MapHandler.resetMapClick(); MapHandler.resetMapClick();
e.target.classList.add("activeBtn"); e.target.classList.add("activeBtn");
self.map.on("click", MapHandler.addCircle); self.map.on("click", MapHandler.addCircle);
const cancelBtn = self.modals.cancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = () => {
self.modals.closeAll();
MapHandler.resetMapClick();
};
}
self.modals.cancel.setMsg("Placing circle");
self.modals.cancel.setVisible(true);
} }
} }
static markerCollect(e) { static markerCollect(e) {
@ -354,18 +481,105 @@ class MapHandler {
MapHandler.resetMapClick(); MapHandler.resetMapClick();
e.target.classList.add("activeBtn"); e.target.classList.add("activeBtn");
self.map.on("click", MapHandler.addMarker); self.map.on("click", MapHandler.addMarker);
const cancelBtn = self.modals.cancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = () => {
self.modals.closeAll();
MapHandler.resetMapClick();
};
}
self.modals.cancel.setMsg("Placing marker");
self.modals.cancel.setVisible(true);
}
}
static polygonCollect(e) {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
MapHandler.resetMapClick();
e.target.classList.add("activeBtn");
// show cancel -- on cancel, clear polyline and reset map handling
const cancelBtn = self.modals.cancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = MapHandler.polygonClearPoints;
}
self.modals.cancel.setMsg("Creating polygon");
self.modals.cancel.setVisible(true);
self.map.on("click", MapHandler.polygonAddPoint);
}
}
static polygonClearPoints(e) {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
self.overlays.polyline.clearPoints();
MapHandler.resetMapClick();
}
}
static polygonAddPoint(e) {
const self = MapHandler.instance;
if (self) {
self.overlays.polyline.insertPoint(e.latlng);
if (self.overlays.polyline.numPoints() >= 3) {
self.modals.cancel.setVisible(false);
const okBtn = self.modals.okCancel.okBtn();
if (okBtn) {
okBtn.onclick = MapHandler.addPolygon;
}
const cancelBtn = self.modals.okCancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = MapHandler.polygonClearPoints;
}
self.modals.okCancel.setMsg("Creating polygon");
self.modals.okCancel.setVisible(true);
}
} }
} }
static overlaySave(e) { static overlaySave(e) {
const self = MapHandler.instance; const self = MapHandler.instance;
if (self) { if (self) {
OverlayState.save(self.overlays); self.modals.closeAll();
MapHandler.resetMapClick();
e.target.classList.add("activeBtn");
self.modals.okCancel.setMsg("Save current map overlays?");
const okBtn = self.modals.okCancel.okBtn();
if (okBtn) {
okBtn.onclick = () => {
OverlayState.save(self.overlays);
self.modals.okCancel.setVisible(false);
// show info modal "Save complete"
};
}
const cancelBtn = self.modals.okCancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = () => {
self.modals.okCancel.setVisible(false);
};
}
self.modals.okCancel.setVisible(true);
} }
} }
static overlayClear(e) { static overlayClear(e) {
const self = MapHandler.instance; const self = MapHandler.instance;
if (self) { if (self) {
self.overlays = OverlayState.clear(self.overlays, self.map); self.modals.closeAll();
MapHandler.resetMapClick();
e.target.classList.add("activeBtn");
self.modals.okCancel.setMsg("Clear all map overlays (will not affect saved data)?");
const okBtn = self.modals.okCancel.okBtn();
if (okBtn) {
okBtn.onclick = () => {
self.overlays = OverlayState.clear(self.overlays, self.map);
self.modals.okCancel.setVisible(false);
};
}
const cancelBtn = self.modals.okCancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = () => {
self.modals.okCancel.setVisible(false);
};
}
self.modals.okCancel.setVisible(true);
} }
} }
static swapTiles(e) { static swapTiles(e) {
@ -397,11 +611,12 @@ function init() {
overlays.markers.forEach(m => m.add(map)); overlays.markers.forEach(m => m.add(map));
overlays.circles.forEach(m => m.add(map)); overlays.circles.forEach(m => m.add(map));
overlays.polygons.forEach(m => m.add(map)); overlays.polygons.forEach(m => m.add(map));
const createOverlayModal = new CreateOverlayModal(); overlays.polyline.add(map);
const modals = new ModalCollection(createOverlayModal); const modals = new ModalCollection(new CreateOverlayModal(), new CancelModal(), new OKCancelModal());
MapHandler.init(map, overlays, TileLayerWrapper.layers, modals); MapHandler.init(map, overlays, TileLayerWrapper.layers, modals);
MapHandler.setButtonClick("addPoint-btn", MapHandler.markerCollect); MapHandler.setButtonClick("addPoint-btn", MapHandler.markerCollect);
MapHandler.setButtonClick("addCircle-btn", MapHandler.circleCollect); MapHandler.setButtonClick("addCircle-btn", MapHandler.circleCollect);
MapHandler.setButtonClick("addPolygon-btn", MapHandler.polygonCollect);
MapHandler.setButtonClick("save-btn", MapHandler.overlaySave); MapHandler.setButtonClick("save-btn", MapHandler.overlaySave);
MapHandler.setButtonClick("clear-btn", MapHandler.overlayClear); MapHandler.setButtonClick("clear-btn", MapHandler.overlayClear);
MapHandler.setButtonClick("tiles-btn", MapHandler.swapTiles); MapHandler.setButtonClick("tiles-btn", MapHandler.swapTiles);

View file

@ -169,9 +169,9 @@ button.closeBtn:hover {
color: crimson; color: crimson;
} }
button#createOverlay-submitBtn { button#createOverlay-submitBtn, button.positive-btn, button.negative-btn {
font-size: 150%; font-size: 150%;
background: transparent;; background: transparent;
color: white; color: white;
border: solid 2px dimgray; border: solid 2px dimgray;
position: relative; position: relative;
@ -186,14 +186,42 @@ button#createOverlay-submitBtn:hover {
border: solid 2px white; border: solid 2px white;
} }
button.positive-btn, button.negative-btn {
font-size: 66.66%;
margin-top: 1em;
}
button.positive-btn {
border: solid 2px #1f9b92;
float: left;
}
button.positive-btn:hover {
color: black;
background: #1f9b92;
}
button.negative-btn {
float: right;
}
button.negative-btn:hover {
color: black;
background: crimson;
border: solid 2px crimson;
}
#cancel-container, #confirm-container, #info-container { #cancel-container, #confirm-container, #info-container {
position: fixed; position: fixed;
font-size: 200%; font-size: 250%;
bottom: 1.5em; bottom: 5em;
display: none; display: none;
left: 50%; left: 50%;
transform: translateY(-50%); transform: translateX(-50%);
background: black; background: black;
z-index: 10;
color: white;
padding: 0.5em;
} }
#import-export-container { #import-export-container {