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.
Probe Google's free Metadata API before spending image-API quota. No wasted requests on points without coverage.
ThreadPoolExecutor fan-out plus a client-side token-bucket QPS limiter and urllib3 backoff for 429/5xx.
On-disk JSON cache for metadata, skip-if-exists for images. Re-runs only fill in gaps.
Same pano shared by multiple nearby points is downloaded once. Globally deduplicated index.
Folium HTML maps for sample points and successful panoramas, plus per-segment coverage stats.
Rotating logs, retry policy, batching, configurable image size / headings / pitch / FOV.
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
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
| Path | Description |
|---|---|
output/gsv_points/metadata.csv | One row per input point with status, pano_id, capture_date, lat/lon, image_path, heading, pitch, fov. |
output/gsv_points/metadata.geojson | Same data as point features (EPSG:4326). |
output/gsv_points/panorama_index.csv | One row per (point_id, pano_id, heading) — globally dedup'd. |
output/gsv_points/summary.json | Coverage stats; per-segment if input CSV has segment_id. |
output/gsv_points/map_sample_points.html | Folium map of all input points. |
output/gsv_points/map_panoramas.html | Folium map of successful panoramas. |
output/gsv_images/{point_id}_{pano_id}_h{heading}.jpg | Downloaded JPEG panoramas. |
All defaults live in gsv_points/config.PipelineConfig. Override via CLI flags or env vars.
| Knob | Default | Notes |
|---|---|---|
image_size | 640x640 | Static API free-tier max. |
headings | 0, 90, 180, 270 | Compass headings per pano. |
fov / pitch | 90 / 0 | Camera field of view and pitch. |
radius_m | 50 | Metadata search radius. |
source | outdoor | Exclude user-contributed indoor panos. |
rate_limit_qps | 25 | Client-side throttle. |
max_workers | 8 | Concurrent HTTP threads. |
batch_size | 100 | Metadata batching unit. |