GSV Image

A modular Python pipeline for sampling road points and collecting Google Street View metadata + imagery.
Python · OSMnx · Folium

Sample any city's roads. Pull every available panorama.

Generate 100 m road sample points, probe the free Street View Metadata API per point, deduplicate panoramas, and bulk-download configurable JPEGs — with retries, caching, and full resume support.

Features

Metadata-first

Probe Google's free Metadata API before spending image-API quota. No wasted requests on points without coverage.

Concurrent & throttled

ThreadPoolExecutor fan-out plus a client-side token-bucket QPS limiter and urllib3 backoff for 429/5xx.

Resumable

On-disk JSON cache for metadata, skip-if-exists for images. Re-runs only fill in gaps.

Dedup panoramas

Same pano shared by multiple nearby points is downloaded once. Globally deduplicated index.

Maps included

Folium HTML maps for sample points and successful panoramas, plus per-segment coverage stats.

Production-ready

Rotating logs, retry policy, batching, configurable image size / headings / pitch / FOV.

Quick start

git clone https://github.com/anshulsinghrs/GSV_Image-.git
cd GSV_Image-
pip install -r requirements.txt

export GSV_API_KEY="YOUR_GOOGLE_API_KEY"

# 1. sample road points
python road_sampler.py --city "Delhi, India" --spacing 100 \
    --out data/road_points_delhi.csv

# 2. collect Street View metadata + imagery
python main.py \
    --input data/road_points_delhi.csv \
    --output output/ \
    --headings 0,90,180,270 \
    --fov 90 --pitch 0 \
    --image-size 640x640 \
    --batch-size 100 --max-workers 8 --qps 25

Repository layout

GSV_Image-/
├── gsv_points/             # GSV-points + metadata package
│   ├── config.py
│   ├── utils.py
│   ├── metadata.py         # Metadata API client
│   ├── downloader.py       # Static Image API downloader
│   ├── pipeline.py         # orchestration
│   └── visualization.py    # Folium maps + summary
├── main.py                 # CLI entry point
├── road_sampler.py         # OSMnx road sampler
├── docs/                   # this site
└── requirements.txt

Outputs

PathDescription
output/gsv_points/metadata.csvOne row per input point with status, pano_id, capture_date, lat/lon, image_path, heading, pitch, fov.
output/gsv_points/metadata.geojsonSame data as point features (EPSG:4326).
output/gsv_points/panorama_index.csvOne row per (point_id, pano_id, heading) — globally dedup'd.
output/gsv_points/summary.jsonCoverage stats; per-segment if input CSV has segment_id.
output/gsv_points/map_sample_points.htmlFolium map of all input points.
output/gsv_points/map_panoramas.htmlFolium map of successful panoramas.
output/gsv_images/{point_id}_{pano_id}_h{heading}.jpgDownloaded JPEG panoramas.

Configuration

All defaults live in gsv_points/config.PipelineConfig. Override via CLI flags or env vars.

KnobDefaultNotes
image_size640x640Static API free-tier max.
headings0, 90, 180, 270Compass headings per pano.
fov / pitch90 / 0Camera field of view and pitch.
radius_m50Metadata search radius.
sourceoutdoorExclude user-contributed indoor panos.
rate_limit_qps25Client-side throttle.
max_workers8Concurrent HTTP threads.
batch_size100Metadata batching unit.