Skip to content

KIzadi/Zonar

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Zonar

Find the perfect location for your business.

Three AI agents analyze foot traffic, demographics, competition, rent, and walkability to rank the best locations.

Zonar — AI Site Selection

The Problem

Opening a small business means picking a location based on gut feeling, expensive consultants, or driving around town. Commercial real estate data is fragmented, paywalled, and not designed for someone opening their first shop.

Zonar gives any entrepreneur the same site intelligence that big chains use internally:

  • Zone-level scoring across every Census block group in a city
  • Revenue and rent estimates calibrated to your business type
  • Demographic fit analysis — income, age distribution, population density
  • Competition mapping — how saturated is this area for your category?
  • AI-generated insights explaining why a zone scores well or poorly

How It Works

  1. Describe your business — "bubble tea shop targeting college students" or "pizza restaurant with a $200K budget"
  2. AI parses your concept — Gemini extracts business type, target demographics, search terms, and priorities
  3. Every neighborhood gets scored — 175 Census block groups scored in parallel using cached Census + OSM data
  4. Explore the heatmap — color-coded zones from red (poor fit) to green (strong fit), with a ranked sidebar
  5. Drill into any zone — see financials, demographics, competition count, and an AI narrative
  6. Adjust priorities — drag weight sliders to re-rank zones instantly (no API call, client-side rescoring)

Features

Zone Heatmap

  • Mapbox fill-layer heatmap colored by PlotScore (0–100)
  • 3D building extrusion toggle
  • Click any zone for detailed breakdown
  • Ranked sidebar with revenue estimates and population
  • Weight sliders for real-time rescoring (foot traffic, demographics, competition, rent, walkability)

AI Agents

Agent What it does AI?
Query Parser Natural language → structured business profile Gemini
Zone Scorer Scores all 175 block groups using financial + location heuristics No
Financial Modeler Revenue, rent, breakeven, and profit estimates per zone No
Location Scorer PlotScore from 5 weighted subscores No
Insight Explainer 3–4 sentence narrative per zone with specific numbers Gemini
Web Researcher Market intel via Google Search grounding (rent ranges, closures, developments) Gemini + Search

Scoring Breakdown

PlotScore (0–100) = weighted sum of 5 subscores:

Subscore What it measures
Foot Traffic POI density, population, transit access
Demographic Fit Age bracket alignment, income match
Competition Gap Fewer competitors = higher score
Rent Efficiency Revenue-to-rent ratio, breakeven speed
Walkability Inferred from nearby POI count

Weights shift based on user priorities (e.g. selecting "Low Competition" boosts the competition_gap weight).

Financial Estimates

Per zone, calibrated by business type:

Metric Source
Monthly Revenue Foot traffic × capture rate × avg ticket
Monthly Rent Census median rent × sqft estimate
Monthly Profit Revenue − rent − COGS
Startup Cost Industry benchmark × location factor
Breakeven Startup cost / monthly profit
Confidence Data completeness score (0–100%)

Benchmarks cover 18 business types (coffee shop, bubble tea, restaurant, gym, salon, retail, etc.).

Data Sources

Data Source How
Demographics U.S. Census ACS 5-Year Bulk fetch, cached in S3
POIs OpenStreetMap Overpass Citywide query, cached in S3
Block group boundaries Census TIGER/Line shapefiles Pre-processed GeoJSON
Market intel Google Search via Gemini On-demand per zone click

Tech Stack

Backend

  • Runtime: Python 3.11 on AWS Lambda (FastAPI + Mangum)
  • AI: Google Gemini 2.5 Flash Lite (query parsing, insights, web research with search grounding)
  • Data cache: S3 for bulk Census + citywide OSM (in-memory after cold start)
  • Auth: JWT + bcrypt, DynamoDB user table

Frontend

  • Framework: Next.js 16 + React 19 + TypeScript
  • Map: Mapbox GL JS (fill layers, 3D buildings)
  • Styling: Tailwind CSS v4
  • Animations: Framer Motion

Infrastructure

Component Service
API AWS Lambda Function URL (120s timeout)
Cache S3 — bulk Census demographics + citywide OSM POIs
Auth DynamoDB user table + JWT tokens
Frontend Next.js (Vercel or static)

Project Structure

Zonar/
├── backend/
│   ├── main.py                      # FastAPI app — /api/zones, /api/insight, /api/web-research
│   ├── agents/
│   │   ├── query_parser.py          # Gemini: natural language → structured query
│   │   ├── financial_modeler.py     # Revenue/rent/breakeven heuristics
│   │   ├── location_scorer.py       # PlotScore computation
│   │   ├── insight_explainer.py     # Gemini: per-zone AI narrative
│   │   └── web_researcher.py        # Gemini + Search: market intel
│   └── services/
│       ├── census.py                # Census ACS bulk S3 loader
│       ├── places.py                # OSM citywide S3 loader
│       └── zone_scorer.py           # Score all block groups (calls financial_modeler + location_scorer)
│
├── frontend/
│   ├── src/app/
│   │   ├── page.tsx                 # Single-page app — onboarding, map, zone heatmap
│   │   ├── layout.tsx               # Metadata + fonts
│   │   └── globals.css              # Theme + component styles
│   └── public/
│       └── providence_block_groups.geojson  # Pre-processed Census block group boundaries
│
└── scripts/
    ├── prepare_geojson.py           # One-time: TIGER shapefile → GeoJSON
    ├── refresh_census_cache.py      # Periodic: bulk Census ACS → S3
    └── refresh_osm_cache.py         # Periodic: citywide Overpass → S3

Quick Start

Prerequisites

  • Node.js 18+
  • Python 3.10+
  • AWS account with S3 + DynamoDB
  • Google AI API key (Gemini)
  • Mapbox access token

Frontend

cd frontend
npm install

Create .env.local:

NEXT_PUBLIC_MAPBOX_TOKEN=your_mapbox_token
NEXT_PUBLIC_API_URL=http://localhost:8000
npm run dev

Open http://localhost:3000

Backend (local)

cd backend
pip install -r requirements.txt

Create .env:

GEMINI_API_KEY=your_gemini_key
CENSUS_API_KEY=your_census_key
OSM_S3_BUCKET=your_bucket
OSM_S3_KEY=osm/providence.json
CENSUS_S3_BUCKET=your_bucket
CENSUS_S3_KEY=cache/bulk_census_44_007.json
DDB_DEMOGRAPHICS_TABLE=plotline-demographics
DDB_USERS_TABLE=plotline-users
JWT_SECRET=your_secret
uvicorn main:app --reload --port 8000

Data Preparation (one-time)

# Generate block group GeoJSON
pip install geopandas shapely requests
python scripts/prepare_geojson.py

# Populate S3 caches
CENSUS_API_KEY=xxx CENSUS_S3_BUCKET=xxx python scripts/refresh_census_cache.py
OSM_S3_BUCKET=xxx python scripts/refresh_osm_cache.py

Design Philosophy

Cache data, score per request. Census and OSM data change slowly. Cache them once in S3, score dynamically based on business type and priorities.

No black boxes. Every PlotScore decomposes into 5 subscores. Every financial estimate shows its inputs. Weight sliders let users express what matters to them.

AI where it helps, heuristics where it doesn't. Gemini parses queries and writes narratives. Scoring and financial modeling are deterministic — same inputs, same outputs.

License

MIT

About

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors