From c4adc7740ebd75cfec4edab59c9ceef0948f911b Mon Sep 17 00:00:00 2001 From: jchanke Date: Tue, 12 Aug 2025 16:46:50 -0400 Subject: [PATCH 1/8] fix: when loading waypoints, clears existing waypoints first currently, waypoints are added by creating new nodes to the . however, any existing nodes and ways still remain. this commit removes them first, before loading data from waypoint data files. --- .../src/button-handlers/clearWaypoints.ts | 15 +++++++++++++++ .../src/button-handlers/loadWaypoints.ts | 14 ++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 waypoint-tagger/src/button-handlers/clearWaypoints.ts diff --git a/waypoint-tagger/src/button-handlers/clearWaypoints.ts b/waypoint-tagger/src/button-handlers/clearWaypoints.ts new file mode 100644 index 0000000..d3a03bc --- /dev/null +++ b/waypoint-tagger/src/button-handlers/clearWaypoints.ts @@ -0,0 +1,15 @@ +/** + * removes all nodes with way_point or waypoint_connection components from the + * screen. + * + * we'll call this before loading a new waypoint files, so they don't overlap. + */ + +const clearWaypoints = () => { + document.querySelectorAll("a-entity[way_point]").forEach((e) => e.remove()); + document + .querySelectorAll("a-entity[waypoint_connection]") + .forEach((e) => e.remove()); +}; + +export { clearWaypoints }; diff --git a/waypoint-tagger/src/button-handlers/loadWaypoints.ts b/waypoint-tagger/src/button-handlers/loadWaypoints.ts index 443b622..7111b0b 100644 --- a/waypoint-tagger/src/button-handlers/loadWaypoints.ts +++ b/waypoint-tagger/src/button-handlers/loadWaypoints.ts @@ -1,6 +1,8 @@ import type { Entity } from "aframe"; import { ElementArraySchema, type Element } from "../schema"; +import { clearWaypoints } from "./clearWaypoints"; +/* loads either from a CSV or JSON, depending on the extension */ function loadWaypointsFromFile(fileSelectEvent: Event): void { const input = fileSelectEvent.target; if ( @@ -12,17 +14,21 @@ function loadWaypointsFromFile(fileSelectEvent: Event): void { throw new Error("file select target is not defined"); const file = input.files![0]; - const [extension] = file.name.split(".").slice(-1); + const extension = file.name.split(".").slice(-1)[0].toLowerCase(); - switch (extension.toLowerCase()) { + if (!["csv", "json"].includes(extension)) + throw new Error(`unsupported file extension: .${extension}`); + + // clear existing waypoints before loading new ones + clearWaypoints(); + + switch (extension) { case "csv": loadWaypointsFromCSVFile(file); return; case "json": loadWaypointsFromJSONFile(file); return; - default: - throw new Error(`unsupported file extension: .${extension}`); } } From ca52eb93128ddb7e4cfb5da1cfbd558830399db0 Mon Sep 17 00:00:00 2001 From: jchanke Date: Tue, 12 Aug 2025 17:15:41 -0400 Subject: [PATCH 2/8] fmt: code style --- waypoint-tagger/src/button-handlers/loadWaypoints.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waypoint-tagger/src/button-handlers/loadWaypoints.ts b/waypoint-tagger/src/button-handlers/loadWaypoints.ts index 7111b0b..4d0577f 100644 --- a/waypoint-tagger/src/button-handlers/loadWaypoints.ts +++ b/waypoint-tagger/src/button-handlers/loadWaypoints.ts @@ -13,7 +13,7 @@ function loadWaypointsFromFile(fileSelectEvent: Event): void { ) throw new Error("file select target is not defined"); - const file = input.files![0]; + const [file] = input.files!; const extension = file.name.split(".").slice(-1)[0].toLowerCase(); if (!["csv", "json"].includes(extension)) From 51af8bc91d74d066f76a31d2eafdf8b89daf24b2 Mon Sep 17 00:00:00 2001 From: jchanke Date: Tue, 12 Aug 2025 17:23:33 -0400 Subject: [PATCH 3/8] add(sample_data): tags field to sample data --- sample_data/waypoints_graph.json | 107 ++++++++++++++++++++++++------- 1 file changed, 85 insertions(+), 22 deletions(-) diff --git a/sample_data/waypoints_graph.json b/sample_data/waypoints_graph.json index 69f2325..defcaaf 100644 --- a/sample_data/waypoints_graph.json +++ b/sample_data/waypoints_graph.json @@ -11,7 +11,10 @@ { "type": "way", "id": "ArenaLab-ArenaLabDoor", - "nodes": ["ArenaLab", "ArenaLabDoor"], + "nodes": [ + "ArenaLab", + "ArenaLabDoor" + ], "tags": {} }, { @@ -25,13 +28,19 @@ { "type": "way", "id": "ArenaLabDoor-ConferenceRoom", - "nodes": ["ArenaLabDoor", "ConferenceRoom"], + "nodes": [ + "ArenaLabDoor", + "ConferenceRoom" + ], "tags": {} }, { "type": "way", "id": "ArenaLabDoor-Lobby2300", - "nodes": ["ArenaLabDoor", "Lobby2300"], + "nodes": [ + "ArenaLabDoor", + "Lobby2300" + ], "tags": {} }, { @@ -45,7 +54,10 @@ { "type": "way", "id": "ConferenceRoom-Hallway", - "nodes": ["ConferenceRoom", "Hallway"], + "nodes": [ + "ConferenceRoom", + "Hallway" + ], "tags": {} }, { @@ -59,7 +71,10 @@ { "type": "way", "id": "Entrance2300-Lobby2300", - "nodes": ["Entrance2300", "Lobby2300"], + "nodes": [ + "Entrance2300", + "Lobby2300" + ], "tags": {} }, { @@ -73,43 +88,64 @@ { "type": "way", "id": "Hallway-StaffOffice", - "nodes": ["Hallway", "StaffOffice"], + "nodes": [ + "Hallway", + "StaffOffice" + ], "tags": {} }, { "type": "way", "id": "Hallway-StudentI", - "nodes": ["Hallway", "StudentI"], + "nodes": [ + "Hallway", + "StudentI" + ], "tags": {} }, { "type": "way", "id": "Hallway-StudentJ", - "nodes": ["Hallway", "StudentJ"], + "nodes": [ + "Hallway", + "StudentJ" + ], "tags": {} }, { "type": "way", "id": "Hallway-StudentN", - "nodes": ["Hallway", "StudentN"], + "nodes": [ + "Hallway", + "StudentN" + ], "tags": {} }, { "type": "way", "id": "Hallway-StudentM", - "nodes": ["Hallway", "StudentM"], + "nodes": [ + "Hallway", + "StudentM" + ], "tags": {} }, { "type": "way", "id": "Hallway-StudentL", - "nodes": ["Hallway", "StudentL"], + "nodes": [ + "Hallway", + "StudentL" + ], "tags": {} }, { "type": "way", "id": "Hallway-StudentK", - "nodes": ["Hallway", "StudentK"], + "nodes": [ + "Hallway", + "StudentK" + ], "tags": {} }, { @@ -131,55 +167,82 @@ { "type": "way", "id": "Professor-StudentA", - "nodes": ["Professor", "StudentA"], + "nodes": [ + "Professor", + "StudentA" + ], "tags": {} }, { "type": "way", "id": "Professor-StudentB", - "nodes": ["Professor", "StudentB"], + "nodes": [ + "Professor", + "StudentB" + ], "tags": {} }, { "type": "way", "id": "Professor-StudentC", - "nodes": ["Professor", "StudentC"], + "nodes": [ + "Professor", + "StudentC" + ], "tags": {} }, { "type": "way", "id": "Professor-StudentD", - "nodes": ["Professor", "StudentD"], + "nodes": [ + "Professor", + "StudentD" + ], "tags": {} }, { "type": "way", "id": "Professor-StudentE", - "nodes": ["Professor", "StudentE"], + "nodes": [ + "Professor", + "StudentE" + ], "tags": {} }, { "type": "way", "id": "Professor-StudentF", - "nodes": ["Professor", "StudentF"], + "nodes": [ + "Professor", + "StudentF" + ], "tags": {} }, { "type": "way", "id": "Professor-StudentG", - "nodes": ["Professor", "StudentG"], + "nodes": [ + "Professor", + "StudentG" + ], "tags": {} }, { "type": "way", "id": "Professor-StaffOffice", - "nodes": ["Professor", "StaffOffice"], + "nodes": [ + "Professor", + "StaffOffice" + ], "tags": {} }, { "type": "way", "id": "Professor-StudentH", - "nodes": ["Professor", "StudentH"], + "nodes": [ + "Professor", + "StudentH" + ], "tags": {} }, { @@ -303,4 +366,4 @@ "lon": 7.42173 } ] -} +} \ No newline at end of file From 246df1dbd2d66be632be44718ee6b5eef73896c0 Mon Sep 17 00:00:00 2001 From: jchanke Date: Tue, 12 Aug 2025 17:24:21 -0400 Subject: [PATCH 4/8] add: 'tag' field to schema (for nodes) --- waypoint-tagger/src/schema/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/waypoint-tagger/src/schema/index.ts b/waypoint-tagger/src/schema/index.ts index 54a7de4..feeea74 100644 --- a/waypoint-tagger/src/schema/index.ts +++ b/waypoint-tagger/src/schema/index.ts @@ -7,6 +7,7 @@ export const NodeSchema = z.object({ lat: z.number(), // x "ele:local": z.number(), // y lon: z.number(), // z + tags: z.object(), }); export type Node = z.infer; From 625604dc1706653788ffe533c1a77a5851ba3984 Mon Sep 17 00:00:00 2001 From: jchanke Date: Tue, 12 Aug 2025 17:30:37 -0400 Subject: [PATCH 5/8] actually add: 'tag' field to nodes in sample_data --- sample_data/waypoints_graph.json | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sample_data/waypoints_graph.json b/sample_data/waypoints_graph.json index defcaaf..30b6ec0 100644 --- a/sample_data/waypoints_graph.json +++ b/sample_data/waypoints_graph.json @@ -4,6 +4,7 @@ "type": "node", "id": "ArenaLab", "description": "", + "tags": {}, "lat": -4.25773, "ele:local": -1, "lon": 4.87359 @@ -21,6 +22,7 @@ "type": "node", "id": "ArenaLabDoor", "description": "", + "tags": {}, "lat": -4.84196, "ele:local": -0.92885, "lon": 1.73607 @@ -47,6 +49,7 @@ "type": "node", "id": "ConferenceRoom", "description": "", + "tags": {}, "lat": -3.40554, "ele:local": -1, "lon": 0.78139 @@ -64,6 +67,7 @@ "type": "node", "id": "Entrance2300", "description": "", + "tags": {}, "lat": -7.10102, "ele:local": -1, "lon": -4.61792 @@ -81,6 +85,7 @@ "type": "node", "id": "Hallway", "description": "", + "tags": {}, "lat": -0.56477, "ele:local": -1, "lon": 0.81094 @@ -152,6 +157,7 @@ "type": "node", "id": "Lobby2300", "description": "", + "tags": {}, "lat": -6.04847, "ele:local": -1, "lon": -2.36367 @@ -160,6 +166,7 @@ "type": "node", "id": "Professor", "description": "", + "tags": {}, "lat": 2.60499, "ele:local": -1, "lon": -5.28736 @@ -249,6 +256,7 @@ "type": "node", "id": "StaffOffice", "description": "", + "tags": {}, "lat": 2.61439, "ele:local": -1, "lon": 0.41135 @@ -257,6 +265,7 @@ "type": "node", "id": "StudentA", "description": "", + "tags": {}, "lat": -4.31889, "ele:local": -1, "lon": -6.55324 @@ -265,6 +274,7 @@ "type": "node", "id": "StudentB", "description": "", + "tags": {}, "lat": -2.68955, "ele:local": -1, "lon": -6.48687 @@ -273,6 +283,7 @@ "type": "node", "id": "StudentC", "description": "", + "tags": {}, "lat": -1.17725, "ele:local": -1, "lon": -6.3836 @@ -281,6 +292,7 @@ "type": "node", "id": "StudentD", "description": "", + "tags": {}, "lat": 0.43108, "ele:local": -1, "lon": -6.44152 @@ -289,6 +301,7 @@ "type": "node", "id": "StudentE", "description": "", + "tags": {}, "lat": -4.16253, "ele:local": -1, "lon": -5.2185 @@ -297,6 +310,7 @@ "type": "node", "id": "StudentF", "description": "", + "tags": {}, "lat": -2.81188, "ele:local": -1, "lon": -5.28351 @@ -305,6 +319,7 @@ "type": "node", "id": "StudentG", "description": "", + "tags": {}, "lat": -1.19974, "ele:local": -1, "lon": -5.21431 @@ -313,6 +328,7 @@ "type": "node", "id": "StudentH", "description": "", + "tags": {}, "lat": 0.50184, "ele:local": -1, "lon": -5.15294 @@ -321,6 +337,7 @@ "type": "node", "id": "StudentI", "description": "", + "tags": {}, "lat": -0.11917, "ele:local": -1, "lon": -2.35952 @@ -329,6 +346,7 @@ "type": "node", "id": "StudentJ", "description": "", + "tags": {}, "lat": -0.42932, "ele:local": -1, "lon": -0.68392 @@ -337,6 +355,7 @@ "type": "node", "id": "StudentK", "description": "", + "tags": {}, "lat": -0.34771, "ele:local": -1, "lon": 2.35552 @@ -345,6 +364,7 @@ "type": "node", "id": "StudentL", "description": "", + "tags": {}, "lat": -0.23317, "ele:local": -1, "lon": 4.03259 @@ -353,6 +373,7 @@ "type": "node", "id": "StudentM", "description": "", + "tags": {}, "lat": -0.29684, "ele:local": -1, "lon": 5.41319 @@ -361,6 +382,7 @@ "type": "node", "id": "StudentN", "description": "", + "tags": {}, "lat": -0.13389, "ele:local": -1, "lon": 7.42173 From 0aab860f7afabeab5c9ef13755dd0a8eed2643f5 Mon Sep 17 00:00:00 2001 From: jchanke Date: Tue, 12 Aug 2025 17:24:21 -0400 Subject: [PATCH 6/8] parse 'tag' field when loading waypoints... this now works with the updated sample_data! --- .../src/button-handlers/downloadWaypointsAsJSON.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/waypoint-tagger/src/button-handlers/downloadWaypointsAsJSON.ts b/waypoint-tagger/src/button-handlers/downloadWaypointsAsJSON.ts index 2460cbf..d9d4d89 100644 --- a/waypoint-tagger/src/button-handlers/downloadWaypointsAsJSON.ts +++ b/waypoint-tagger/src/button-handlers/downloadWaypointsAsJSON.ts @@ -48,15 +48,17 @@ function downloadWaypointsAsJSON() { y: number; z: number; description: string; + tags: object; neighbors: Array; // array of ids } >(); for (const wp of waypointEntities) { const id = wp.getAttribute("id"); // TODO: this should be numeric! const { x, y, z } = wp.object3D.position; - const description = wp.components.way_point.data.description; - const neighbors = wp.components.way_point.data.neighbors.split(","); - waypointEntitiesMap.set(id, { id, x, y, z, description, neighbors }); + const description = wp.components.way_point.data.description ?? ""; + const neighbors = wp.components.way_point.data.neighbors.split(",") ?? []; + const tags = wp.components.way_point.data.tags ?? {}; + waypointEntitiesMap.set(id, { id, x, y, z, description, tags, neighbors }); } // initialize the array of output elements @@ -65,13 +67,14 @@ function downloadWaypointsAsJSON() { // iterate through nodes in _increasing_ order of id for (const [ _, - { id, x, y, z, description, neighbors }, + { id, x, y, z, description, tags, neighbors }, ] of waypointEntitiesMap) { // add way_point as 'node' const waypointNode = { type: "node", id, description, + tags, lat: x, "ele:local": y, lon: z, From 40487aa7ced74b7a3975514df6048c38d81172db Mon Sep 17 00:00:00 2001 From: jchanke Date: Thu, 11 Sep 2025 16:17:33 -0400 Subject: [PATCH 7/8] add: tag attribute to waypoint component --- waypoint-tagger/src/button-handlers/loadWaypoints.ts | 5 +++-- waypoint-tagger/src/components/waypoint.ts | 5 +++++ waypoint-tagger/src/components/waypointConnection.ts | 4 +--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/waypoint-tagger/src/button-handlers/loadWaypoints.ts b/waypoint-tagger/src/button-handlers/loadWaypoints.ts index 4d0577f..d23db7b 100644 --- a/waypoint-tagger/src/button-handlers/loadWaypoints.ts +++ b/waypoint-tagger/src/button-handlers/loadWaypoints.ts @@ -103,6 +103,7 @@ function createWaypointEntitiesFromCSV( entity.setAttribute("way_point", { ID: row.id, description: row.description || "", // assuming description might be an empty string if not provided + tags: row.tags, }); entity.setAttribute("id", row.id); @@ -133,12 +134,12 @@ function createWaypointEntitiesFromJSON(elements: Element[]) { // first loop: create entities for nodes for (const e of elements) { if (e.type !== "node") continue; - const { lat: x, "ele:local": y, lon: z, id, description } = e; + const { lat: x, "ele:local": y, lon: z, id, description, tags } = e; const entity = document.createElement("a-entity"); entity.setAttribute("position", `${x} ${y} ${z}`); entity.setAttribute("id", id); - entity.setAttribute("way_point", { ID: id, description }); + entity.setAttribute("way_point", { ID: id, description, tags }); // set the gltf-model attribute to the waypoint model entity.setAttribute("gltf-model", "#waypoint_model"); diff --git a/waypoint-tagger/src/components/waypoint.ts b/waypoint-tagger/src/components/waypoint.ts index bee6c5c..a2640b0 100644 --- a/waypoint-tagger/src/components/waypoint.ts +++ b/waypoint-tagger/src/components/waypoint.ts @@ -4,6 +4,11 @@ AFRAME.registerComponent("way_point", { schema: { ID: { type: "string" }, description: { type: "string" }, + tags: { + default: {}, + stringify: (value: object) => + Object.entries(value).map(([key, value]) => `${key}=${value}`), + }, neighbors: { type: "string" }, }, diff --git a/waypoint-tagger/src/components/waypointConnection.ts b/waypoint-tagger/src/components/waypointConnection.ts index 2839df5..fa8c605 100644 --- a/waypoint-tagger/src/components/waypointConnection.ts +++ b/waypoint-tagger/src/components/waypointConnection.ts @@ -1,6 +1,4 @@ -import type { LineBasicMaterial } from "three"; -import type { BufferGeometry } from "three"; -import type { Line } from "three"; +import type { BufferGeometry, Line, LineBasicMaterial } from "three"; AFRAME.registerComponent("waypoint_connection", { schema: { From 6ec61146f6c69dcb4aca2ad538d69e2497c77963 Mon Sep 17 00:00:00 2001 From: jchanke Date: Thu, 25 Sep 2025 16:40:12 -0400 Subject: [PATCH 8/8] fix: npm command to rebuild inspector & copy; & update submodule --- aframe-inspector | 2 +- waypoint-tagger/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aframe-inspector b/aframe-inspector index c4141c9..8ffa439 160000 --- a/aframe-inspector +++ b/aframe-inspector @@ -1 +1 @@ -Subproject commit c4141c9df701751049494c030915ce562e8ddeb5 +Subproject commit 8ffa4392a72a97e3f04f7fd3af1d0e44599a4053 diff --git a/waypoint-tagger/package.json b/waypoint-tagger/package.json index cc83121..ccdd079 100644 --- a/waypoint-tagger/package.json +++ b/waypoint-tagger/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "dev": "vite", - "build:inspector": "cd ../aframe-inspector && npm run dist:min && cp dist/aframe-inspector.min.js ../waypoint-tagger/dist/dependencies", + "build:inspector": "npm --prefix ../aframe-inspector run dist:max; cp ../aframe-inspector/dist/aframe-inspector.js ./dist/dependencies/", "build": "tsc && vite build", "preview": "vite preview", "deploy": "tsc && vite build && gh-pages -d dist"