all repos — onyx @ 0bb6f69fa4cb96947bf308ebb3cedc5889891f00

minimal map annotation and location data sharing tool

cleanup a bit more after build
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEkFh6dA+k/6CXFXU4O3+8IhROY5gFAmL4jf8ACgkQO3+8IhRO
Y5jfgw//e3e0kVMLsWCzGVAhg+nM60QUaSmQHxpEVrZ7Uc/o8U/xZht74hvkDVSN
ubb903tGI7wd2DSroBDckvladJ/wmraAPaSLmjf/mJA/YgPHDPMGli7PvrTYiIVn
xTeFLt5N6BEkFrM/6iajMmPKAA0cSBHCC280+SydHl7LMK3OAVJMgSo3ELYajVk7
u1TOD6jA1E6xwdH87bRtdJvudFJGQcpC6khp7K0WdgflBDmyGaslhoosobpUc6gU
vO+LrhrKWqKi5oFuLQ39tB4Q/zywcH4uq7ByaaN9YnV/U01Zd2avsGQs3SN4pI9o
z5vt3u+i4AYF6Z9WYixIBng+TW/fHrhlIRJVBexItyGNp57JJC6aDJ/jP5yZZSUh
hiYh8Aawux6LGm6NlpW2YOQclVZ7GMw7+W2fx/AP8cdU8WH7ojpWe+onDKKuc8Ur
JTDeX6/bv89Lb8U4D7S5rGfpqmUaajgtzc/XG34SraVzSinOlPb2UkqX4q6E+KBW
qpwYAcAAIy+yuOeDWfZqBqZyXQZ0aVEROkDjrCFsoSZgek8uylEPMtXgVZElNg5Z
JZASE5S33APlncvz94/Be3hb5pMYk1QXkPeifnyHSBibrPbIYNWjQGKbO+h5gOJ4
xduhFyyakpcF/JnCT9jMtr/fkpzENj6SaUJwcv8kFTNHLnwcfgI=
=YRCc
-----END PGP SIGNATURE-----
commit

0bb6f69fa4cb96947bf308ebb3cedc5889891f00

parent

b1342fcc0f9234da1730d1de56c307ad11253052

3 files changed, 4 insertions(+), 462 deletions(-)

jump to
D src/.srcmap

@@ -1,6 +0,0 @@

-10-overlay.ts 147 -11-tilelayer.ts 37 -20-createOverlayModal.ts 98 -29-modalCollection.ts 10 -30-handlers.ts 118 -99-onyx-scry.ts 44
M src/build.shsrc/build.sh

@@ -36,5 +36,7 @@

# translate lines into original source with the source map and output to stdout ../buildtools/sourcemapper ${errorOut} -# delete the temporary file -rm ${errorOut}+# delete the temporary files +rm ${errorOut} +rm ${progname}.ts +rm .srcmap
D src/onyx-scry.ts

@@ -1,454 +0,0 @@

-class Point implements L.LatLngLiteral { - lat: number = 0.00; - lng: number = 0.00; -} - -enum OverlayType { - POINT = 0, - CIRCLE = 1, - POLYGON = 2, -} - -interface Overlay { - name: string; - desc: string; - points: Point[]; - options: any; -} - -class OverlayData implements Overlay { - name: string; - desc: string; - points: Point[]; - options: any; - type: OverlayType; - - constructor(type: OverlayType, name: string, desc: string, points: Point[], options: any) { - this.type = type; - this.name = name; - this.desc = desc; - this.points = points; - this.options = options; - } -} - -abstract class OverlayBase implements Overlay { - name: string; - desc: string; - points: Point[]; - options: any; - protected self: any; - - constructor(name: string, desc: string, points: Point[], options: any) { - this.name = name; - this.desc = desc; - this.points = points; - this.options = options; - } - - add(map: L.Map): void { - this.self.addTo(map); - } - - remove(map: L.Map): void { - this.self.removeFrom(map); - } -} - - -class Marker extends OverlayBase { - - constructor(name: string, desc: string, point: Point, options: any) { - super(name, desc, [ point ], options); - this.self = L.marker(point); - this.self.bindPopup(`<h3>${name}</h3><p>${desc}</p>`); - } -} - -class Circle extends OverlayBase { - - constructor(name: string, desc: string, point: Point, options: any) { - super(name, desc, [ point ], options); - this.self = L.circle(point, options); - this.self.bindPopup(`<h3>${name}</h3><p>${desc}</p>`); - } -} - -class Polygon extends OverlayBase { - - constructor(name: string, desc: string, points: Point[], options: any) { - super(name, desc, points, options); - this.self = L.polygon(points, options); - } -} - -class OverlayState { - markers: Marker[]; - circles: Circle[]; - polygons: Polygon[]; - - constructor() { - this.markers = []; - this.circles = []; - this.polygons = []; - } - - static load(): OverlayState { - const store = localStorage.getItem("overlay_state"); - if (store) { - const model = JSON.parse(store); - return { - markers: model.markers.map((m: OverlayData) => OverlayState.fromData(m)), - circles: model.circles.map((c: OverlayData) => OverlayState.fromData(c)), - polygons: model.polygons.map((p: OverlayData) => OverlayState.fromData(p)), - } as OverlayState - } else { - return new OverlayState(); - } - } - - static save(overlayState: OverlayState): void { - localStorage.setItem("overlay_state", JSON.stringify({ - markers: overlayState.markers.map((m: OverlayBase) => OverlayState.toData(m)), - circles: overlayState.circles.map((c: OverlayBase) => OverlayState.toData(c)), - polygons: overlayState.polygons.map((p: OverlayBase) => OverlayState.toData(p)), - })); - } - - static clear(overlayState: OverlayState, map: L.Map): OverlayState { - overlayState.markers.forEach((m: Marker) => m.remove(map)); - overlayState.circles.forEach((c: Circle) => c.remove(map)); - overlayState.polygons.forEach((p: Polygon) => p.remove(map)); - - return new OverlayState(); - } - - private static toData(source: OverlayBase): OverlayData { - let 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); - } - - private static fromData(data: OverlayData): OverlayBase { - 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); - } - } - - -}class TileLayerWrapper { - self: L.TileLayer; - name: string; - visible: boolean = false; - - constructor(name: string, self: L.TileLayer) { - this.self = self; - this.name = name; - } - - static constructLayer(name: string, self: L.TileLayer): TileLayerWrapper { - const wrapper = new TileLayerWrapper(name, self); - TileLayerWrapper.layers.push(wrapper); - return wrapper; - } - - static getActiveLayer(): string | null { - for (const l of TileLayerWrapper.layers) { - if (l.visible == true) { - return l.name; - } - } - return null; - } - static layers: TileLayerWrapper[] = new Array<TileLayerWrapper>(); - static enableOnly(self: string, map: L.Map): void { - for (const l of TileLayerWrapper.layers) { - if (l.visible) { - l.self.removeFrom(map); - l.visible = false; - } - if (l.name == self) { - l.self.addTo(map); - l.visible = true; - } - } - } -}class CreateOverlayModal { - - constructor() { - const _this = this; - const closeBtn = document.getElementById("createOverlay-closeBtn"); - if (closeBtn) { - closeBtn.onclick = ()=>{_this.setVisible(false)}; - } - } - - self(): HTMLElement | null { - return document.getElementById("createOverlay-container"); - } - - title(): HTMLElement | null{ - return document.getElementById("createOverlay-title"); - } - - content(): HTMLElement | null { - return document.getElementById("createOverlay-content"); - } - - submitBtn(): HTMLElement | null { - return document.getElementById("createOverlay-submitBtn"); - } - - radiusContainer(): HTMLElement | null { - return document.getElementById("radius-container"); - } - - nameField(): string { - return (document.getElementById("createOverlay-name") as HTMLInputElement)?.value ?? ""; - } - - descField(): string { - return (document.getElementById("createOverlay-desc") as HTMLInputElement)?.value ?? ""; - } - - radiusField(): string { - return (document.getElementById("createOverlay-radius") as HTMLInputElement)?.value ?? ""; - } - - visible(): boolean { - return this.self()?.style.display != "none"; - } - - setVisible(v: boolean): void { - const modal = this.self(); - if (modal) { - modal.style.display = v ? "block" : "none"; - } - } - - 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(); - - if (radiusContainer) { - radiusContainer.style.display = state == OverlayType.CIRCLE ? "block" : "none"; - } - - switch (state) { - case OverlayType.POINT: - if (title) { - title.innerHTML = "Add Marker"; - } - - if (submitBtn) { - submitBtn.onclick = () => { - const 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: - if (title) { - title.innerHTML = "Add Circle"; - } - if (submitBtn) { - submitBtn.onclick = () => { - const circle = new Circle(name, desc, args.latlng, {radius: Number(radius) || 500}); - circle.add(args.map); - args.overlays.circles.push(circle); - _this.setVisible(false); - } - } - break; - case OverlayType.POLYGON: - break; - } - } -}class ModalCollection { - createOverlay: CreateOverlayModal; - - constructor(createOverlay: CreateOverlayModal) { - this.createOverlay = createOverlay; - } - - closeAll(): void { - this.createOverlay.setVisible(false); - } -}class MapHandler { - map: L.Map; - overlays: OverlayState; - layers: TileLayerWrapper[]; - modals: ModalCollection; - - static instance: MapHandler | null = null; - - private constructor(map: L.Map, overlays: OverlayState, layers: TileLayerWrapper[], modals: ModalCollection) { - this.map = map; - this.overlays = overlays; - this.layers = layers; - this.modals = modals; - } - - static init(map: L.Map, overlays: OverlayState, layers: TileLayerWrapper[], modals: ModalCollection): void { - if (!MapHandler.instance) { - MapHandler.instance = new MapHandler(map, overlays, layers, modals); - } - } - - static setButtonClick(btnId: string, handler: any): void { - const button = document.getElementById(btnId); - if (button) { - button.onclick = handler; - } - } - - static resetMapClick(): void { - const self = MapHandler.instance; - if (self) { - try { - const addPointBtn = document.getElementById("addPoint-btn"); - if (addPointBtn) { - addPointBtn.classList.remove("activeBtn"); - } - self.map.off("click", this.addMarker); - } catch {} - try { - const addCircleBtn = document.getElementById("addCircle-btn"); - if (addCircleBtn) { - addCircleBtn.classList.remove("activeBtn"); - } - self.map.off("click", this.addCircle); - } catch {} - } - } - - static addMarker(e: any): void { - const self = MapHandler.instance; - if (self) { - self.modals.createOverlay.setVisible(true); - self.modals.createOverlay.setState(OverlayType.POINT, { - latlng: e.latlng, - map: self.map, - overlays: self.overlays, - }); - MapHandler.resetMapClick(); - } - } - - static addCircle(e: any): void { - const self = MapHandler.instance; - if (self) { - self.modals.createOverlay.setVisible(true); - self.modals.createOverlay.setState(OverlayType.CIRCLE, { - latlng: e.latlng, - map: self.map, - overlays: self.overlays, - }); - MapHandler.resetMapClick(); - } - } - - static circleCollect(e: any): void { - const self = MapHandler.instance; - if (self) { - self.modals.closeAll(); - MapHandler.resetMapClick(); - (e.target as HTMLElement).classList.add("activeBtn"); - self.map.on("click", MapHandler.addCircle); - } - } - - static markerCollect(e: any): void { - const self = MapHandler.instance; - if (self) { - self.modals.closeAll(); - MapHandler.resetMapClick(); - (e.target as HTMLElement).classList.add("activeBtn"); - self.map.on("click", MapHandler.addMarker); - } - } - - static overlaySave(e: any): void { - const self = MapHandler.instance; - if (self) { - OverlayState.save(self.overlays); - } - } - - static overlayClear(e: any): void { - const self = MapHandler.instance; - if (self) { - OverlayState.clear(self.overlays, self.map); - } - } - - static swapTiles(e: any): void { - const self = MapHandler.instance; - if (self) { - if (TileLayerWrapper.getActiveLayer() == "satelliteLayer") { - TileLayerWrapper.enableOnly("streetLayer", self.map); - } else { - TileLayerWrapper.enableOnly("satelliteLayer", self.map); - } - } - } -} -function init(): void { - let overlays: OverlayState = OverlayState.load() ?? new OverlayState(); - const map = L.map('map').setView([35.6653, -105.9507], 13); - - const streetLayer = TileLayerWrapper.constructLayer( - "streetLayer", - L.tileLayer( - 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', - { - maxZoom: 19, - attribution: "street map tiles &copy; OpenStreetMap" - })); - - const satelliteLayer = TileLayerWrapper.constructLayer( - "satelliteLayer", - L.tileLayer( - 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', - { - maxZoom: 19, - attribution: "satellite tiles &copy; Esri" - })); - - TileLayerWrapper.enableOnly("streetLayer", map); - - overlays.markers.forEach(m=>m.add(map)); - overlays.circles.forEach(m=>m.add(map)); - overlays.polygons.forEach(m=>m.add(map)); - const createOverlayModal = new CreateOverlayModal(); - const modals = new ModalCollection( - createOverlayModal); - - MapHandler.init(map, overlays, TileLayerWrapper.layers, modals); - - MapHandler.setButtonClick("addPoint-btn", MapHandler.markerCollect); - MapHandler.setButtonClick("addCircle-btn", MapHandler.circleCollect); - - MapHandler.setButtonClick("save-btn", MapHandler.overlaySave); - MapHandler.setButtonClick("clear-btn", MapHandler.overlayClear); - - MapHandler.setButtonClick("tiles-btn", MapHandler.swapTiles); -} - -init();