Every August, a few thousand freshers walk into PSG College of Technology in Coimbatore and lose the same afternoon to the same problem. Your slip says "GH 305, 8:00 AM, Applied Chemistry." You have no idea what GH is. You ask a senior. They point vaguely at a building across the quadrangle and say "top floor, take the stairs on the far side." You are now late.
PSG has an official website, a printed prospectus, and, at the time I was there, exactly zero maps that would let you find a room from a room code. The buildings are labelled by acronyms that make sense to people who have been there for three years: A Block, B Block, GH, K Block, PSG Tech Auditorium, Hostel Blocks A through F. The room-numbering system is internally consistent but tribal. First-year me needed a map. So did every fresher after me. So in March 2023, my friend Navin Praanav and I sat down to build one.
What we actually shipped
The repo is public: PSG-College-of-Technolgy-Navigation-Map. Typo in the URL, intentional at this point, because we already had the Netflix deploy pointing at that name and neither of us wanted to break the link. It is a Create React App project, roughly 20 KB of JavaScript, 3.5 KB of CSS, and one JPG per building. Deployed at psgtech.netlify.app while we were both still students.
The thing on screen is a single image of K Block with hoverable regions. Move your cursor over a room and a floating card appears next to it with the room name and what it is: Chemistry Lab, Lecture Hall, Head of Department office, Server Room. Click and the box sticks. That is the entire user interaction.
Behind it is an HTML image map. Yes, the <map> and <area> tags from 1996. They are still in every browser. You define a polygon in pixel coordinates over an image and the browser fires mouse events when the pointer enters that polygon. React reads the event, sets some state, and renders a floating div with the room info. src/components/Image.js holds the handlers. src/static/data/k_block.json holds the coordinates and labels. Change the data file, the map updates. No code touched.
That was the whole design decision: keep the map data in JSON so we or any future junior could extend it without learning React. It worked. The bug list in the README is honest about what it did not solve: wrong coordinate order in the polygons made the highlight rectangle stutter, and we still had a login sidebar sitting in the code that nobody had wired up.
How we got the data
This is the part nobody asks about and where most of the actual work went.
The college does not publish floor plans. There is no GeoJSON of the campus on OpenStreetMap that goes below building outlines, and even the outlines were sparse in 2023. Buying access to a CAD floor plan was not a thing an undergrad could do. So the data-collection story was: I photographed the fire-exit map that hangs in the K Block stairwell.
The fire-exit map is a printed diagram with every room labelled, drawn approximately to scale, and screwed to a wall on the ground floor because the state fire code requires it. Every block has one. It is the closest thing to an authoritative floor plan a student can get. I took the photo on my phone, cropped it, cleaned it up a bit, and that image is the JPG the app renders. Every polygon in the JSON was traced against that image.
To trace the polygons I used image-map.net, a browser tool that lets you draw regions over an uploaded image and copy the coordinates out. I sat there for one evening clicking corners around each room and dumping the output into k_block.json. Navin did the same for a second block that we never fully wired into the app.
There is a demo MP4 of the image-map.net workflow in the README because I kept forgetting how to use it between sessions.
Tech choices, honestly
The stack is dumber than it needed to be, and I think that was right. Create React App, one dependency for a "made with love" footer, another for React Tooltip, plus react-papaparse and jQuery that snuck in and never got cleaned out. xlsx and csvtojson are in the package.json because at one point I thought I would import room data from a spreadsheet the college registrar might give us. That never happened, so those packages sit there unused. I flagged that in the README under Bugs and moved on.
The right tech for the actual problem is probably a static SVG with <a> tags around groups. No React, no state, no floating card, just links. But I wanted an excuse to write React in 2023, and this was the excuse. The image-map approach also had one real advantage: I could take a photograph of a printed diagram and turn it into a clickable map in a few hours. An SVG version would have needed me to redraw the whole floor plan by hand.
The floating-info-on-hover interaction is where React earns its place. Positioning a tooltip relative to the cursor, updating it on mousemove, sticking it on click, and dismissing it on outside-click is annoying in vanilla JavaScript and one component in React. Fine.
What a v2 would need
I never shipped v2. If I did, here is what I know it would need.
One building is a demo. To be useful on orientation day the app needs every block, and the state machine to jump between them. A dropdown at the top, or a small overview map of the campus where you click a block and land on its floor plan. K Block alone does not solve the GH 305 problem.
The photograph of a fire-exit map is a hack that runs out fast. It works because the print is legible and the campus is not that big, but the moment you want to show multiple floors you need real floor plans, one image per floor, and a floor switcher. Every block has three or four floors. That is 20-plus JPGs and 20-plus JSON files, and every one of them needs a person with a camera in the stairwell.
Search is the feature that would actually change the experience. Type "GH 305" and land on the highlighted polygon on the right floor of the right building. That is a flat index over the JSON files and a text input. It is a weekend of work I did not do because I graduated.
The mobile experience of an HTML image map is bad. Fingers are larger than the polygons I drew. A tap-friendly version means bigger regions, chunkier hit targets, and probably no image map at all: instead, an SVG with a <g> per room and CSS :hover and :focus states. I would rewrite the interaction layer if I picked this up again.
The last thing, and this is the one I keep thinking about: the whole app should be a PWA that a fresher installs from a QR code on the orientation-day slip. Offline, so the campus WiFi does not ruin it. That is the version that would have saved 18-year-old me from being late to Applied Chemistry.