A tiny, self-contained browser tool for tracing real-estate site-plan lots (or building-elevation units) into clean JSON/SVG geometry. Load a master-plan image, draw a polygon over each lot, tag it with a number/status/area, and export — ready to drop into an interactive availability map on your site.
It exists because AI agents (and humans squinting at low-res renders) are bad at guessing lot boundaries, but great at consuming clean geometry. So the workflow splits the job: a human traces, the data exports, the site renders it. It also ships as a Claude Code skill so an agent can drive the whole flow.
- Single
index.html— vanilla JS, zero dependencies, works offline - Optional
server.py— stdlib-only Python helper that pre-loads an image and collects the result (used by the Claude skill flow) - Output is plain JSON with SVG-ready paths in the source image's pixel space
Just open index.html in any browser — no install, no server.
(Double-click the file, or host it anywhere static and bookmark the URL.)
- Load plan — drag an image onto the canvas or click Load plan.
- Draw (
N) — click each corner of a lot; click the first dot or pressEnterto close. It keeps drawing so you can trace lots back-to-back.Esccancels. - Edit (
V) — click a lot, drag its dots to refine. Double-click an edge to add a point,Alt-click a dot to remove one, drag inside a lot to move it.⌫deletes. - Tag — set each lot's number, status (available / reserved / sold), and optional area in the sidebar.
- Export JSON (or Copy) — hand it off / commit it. Import JSON to resume later.
Pan with Space-drag or middle-drag; zoom with the scroll wheel; F fits to screen.
Work auto-saves to the browser's localStorage, so an accidental tab close loses nothing.
Clone this repo into your Claude Code skills directory:
git clone https://github.com/martoast/lot-mapper.git ~/.claude/skills/lot-mapperThen, in any project, tell Claude something like "trace the lots", "map the lots", or "make this site plan interactive" and point it at your plan image. Claude will:
- Start
server.pyin the background with your image pre-loaded - Open the tracer in your browser at
http://localhost:8731 - Wait while you trace and tag the lots, then click "Done — send to Claude"
- Read the resulting JSON and build the interactive map (SVG overlay, hover/click → detail panel, colored by status, numbered at each centroid)
See SKILL.md for the exact instructions the agent follows.
python3 server.py \
--image /path/to/masterplan.png \ # required: the plan to trace
--out /path/to/output.json \ # required: where the result is written on Done
--port 8731 \
--name "Master plan" \ # image label shown in the tool
--title "My Project" \ # browser tab title
--start 0 \ # first lot number to auto-assign
--lots /path/to/existing.json # optional: preload previously-traced lots to view/editThe server prints SAVED: <path> when the user clicks Done. --lots makes revision
rounds cheap: reload an earlier export, tweak a boundary or a status, re-export.
Coordinates are in the source image's pixel space, so a consuming <svg> just needs
viewBox="0 0 W H" with the same plan image as its backdrop — paths line up 1:1.
{
"image": { "name": "masterplan.png", "width": 1036, "height": 964 },
"viewBox": "0 0 1036 964",
"lots": [
{
"n": "112",
"status": "available",
"area": "3,043 m²",
"points": [[x,y], [x,y], ...],
"d": "M x,y L x,y ... Z",
"cx": 0, "cy": 0
}
]
}d— ready-to-use SVG path for the parcel polygon.cx,cy— polygon centroid (handy for placing the lot-number label).points— raw vertices if you need them.
<div style="position:relative">
<img src="masterplan.png" style="width:100%">
<svg viewBox="0 0 1036 964" style="position:absolute;inset:0;width:100%">
<!-- one <path> per lot from the JSON, colored by status, with hover/click handlers -->
</svg>
</div>That's the whole trick: because the geometry is in image pixels, the overlay scales with
the image at any rendered size. Wire hover/click to a detail panel, color the paths by
status, and place each lot number at cx,cy.
Works just as well for building elevations — trace units instead of lots.
| Key | Action |
|---|---|
N |
Draw mode (new lot) |
V |
Select/edit mode |
Enter |
Close current polygon |
Esc |
Cancel current polygon |
⌫ / Delete |
Delete selected lot |
F |
Fit image to screen |
Space-drag / middle-drag |
Pan |
| Scroll | Zoom |
- Single file, vanilla JS, zero dependencies — keep it that way; it's meant to stay portable.
server.pyis Python 3 stdlib only. No pip installs, ever.