Cheeseman apps

MapHub

Zip code territory mapper fed by a spreadsheet of zips and categories

Platform
  • Mac
  • Web
Status
Shipping
Stack
Electron, Node, Express
Started

MapHub turns a spreadsheet of zip codes into a shaded territory map. Drop a CSV or Excel file on the window with the zip in column A and a category in column B, review the import summary, and each zip’s Census ZCTA boundary is drawn on a Leaflet map colored by category. It needs no account, no database, and no API key; the boundary data is built once from the Census shapefiles and served from local files.

Maps work in 5-digit, 3-digit prefix, or state mode, and switching converts the data in place: zips roll up to their prefix or state with the majority category winning, and switching back restores the original rows. Turn on All boundaries to see every outline in view, then hold Control or Command and click or drag across zips to add or remove them from the active category, so a territory can be built from a blank map. Legend rows recolor, hide, or delete a category, and dragging one row onto another merges them, with Undo on Cmd+Z.

Other things it does:

  • Radius zones: type an address, pick it from the autocomplete, and a shaded circle of the chosen radius appears with its name. One click converts the zone into the zips it covers. Geocoding tries Google when a key is present, then the Census geocoder, OpenStreetMap, and finally the zip’s own center, and warns when a match is approximate.
  • Basemaps: Standard, Light, Dark, Satellite, Hybrid, or Auto to follow the system appearance. Zip labels print each number where the polygon is wide enough to hold it.
  • Export: a CSV of zip and category that re-imports unchanged, or a single standalone HTML file with the viewer and every polygon inlined, which a recipient opens by double-clicking with no server or network path back.
  • My Maps: save, rename, duplicate, and delete named maps in a local library.

It runs as a signed Mac app with the Express server inside the Electron process, and the same code runs headless under pm2 for browser use on the network.