Dataset Description
The dataset is a set of map tiles for the various states of the USA.
Dataset Sources
Dataset Structure
- Organized into folders by state
- Structure of graphml files:
- Top of files have a list of keys/ids that correspond to the properties of the segment:
maxspeed: speed limitoneway: if it is a one-way roadlit: if the road is litlanes: the number of lanes- Other tags can be found on OpenStreetMap.org's wiki page
- Uses nodes to describe points in the road
xandyattributes are for lat/lon.
- Top of files have a list of keys/ids that correspond to the properties of the segment:
- If a tile is not included, there was no map data for roads in that region.
Dataset Creation
Uses OSMium:
- Install with Homebrew:
brew install osmium- For MacOS (Recommended)
Generated with Python and OSMium to process maps
- Input directory: Change the directory in the script to match where you have the .osm.pbf files saved
- BBoxes JSON: You need a list of bboxes per region in the JSON format shown below
[{
"fips":"01",
"state":"Alabama",
"bounds":[
[-88.4745951503515,30.222501133601334],
[-84.89247974539745,35.008322669916694]
]
}]
This was used to generate the dataset (Using Python 3.13):
import os
import subprocess
import osmnx as ox
import tempfile
import json
# --- CONFIG ---
TILE_SIZE = 0.1 # degrees of lat/lon
UNPROCESSED_DIR = "/where/you/have/*.osm.pbf map files" # Change this: Input .osm.pbf map files
PREPROCESSED_DIR = "/where/you/want/output/folders" #Change this to where you want output map tiles
BBOX_JSON = "/your/bbox/file" # You need a list of bboxes per region.
# ----------------
# Load bounding boxes from JSON
with open(BBOX_JSON, "r") as f:
state_bbox_data = json.load(f)
# Convert to dict: state name → [minlon, minlat, maxlon, maxlat]
STATE_BBOX = {}
for item in state_bbox_data:
name = item["state"]
minlon, minlat = item["bounds"][0]
maxlon, maxlat = item["bounds"][1]
STATE_BBOX[name] = (minlon, minlat, maxlon, maxlat)
# Utility to generate ranges of floats
def frange(start, stop, step):
vals = []
while start < stop:
vals.append(round(start, 6))
start += step
return vals
# Process a single PBF file
def process_pbf(pbf_path):
base = os.path.basename(pbf_path)
state_raw = base.split("-")[0] # e.g., south-dakota
state_name = state_raw.replace("_", " ").title() # South Dakota
print(f"[MAP] Processing {base} → state: {state_name}")
if state_name not in STATE_BBOX:
print(f"[SKIP] No bounding box for {state_name}")
return
minlon, minlat, maxlon, maxlat = STATE_BBOX[state_name]
# Create output folder
out_dir = os.path.join(PREPROCESSED_DIR, state_name)
os.makedirs(out_dir, exist_ok=True)
lats = frange(minlat, maxlat, TILE_SIZE)
lons = frange(minlon, maxlon, TILE_SIZE)
for lat in lats:
for lon in lons:
tile_name = f"tile_{lat:.1f}_{lon:.1f}"
out_pbf = os.path.join(out_dir, tile_name + ".osm.pbf")
out_graphml = os.path.join(out_dir, tile_name + ".graphml")
if os.path.exists(out_graphml):
print(f"[SKIP] {out_graphml} already exists.")
continue
# --- Extract tile ---
bbox = f"{lon},{lat},{lon+TILE_SIZE},{lat+TILE_SIZE}"
print(f"[INFO] Extracting {tile_name} ...")
subprocess.run([
"osmium", "extract",
"-b", bbox,
"--overwrite",
"-o", out_pbf,
pbf_path
], check=False)
if not os.path.exists(out_pbf) or os.path.getsize(out_pbf) < 10000:
print(f"[SKIP] {tile_name} appears empty, skipping conversion.")
if os.path.exists(out_pbf):
os.remove(out_pbf)
continue
# --- Convert to GraphML ---
try:
print(f"[INFO] Converting {tile_name} to GraphML ...")
with tempfile.NamedTemporaryFile(suffix=".osm.xml") as tmpfile:
subprocess.run([
"osmium", "cat",
"-f", "osm",
"--overwrite",
"-o", tmpfile.name,
out_pbf
], check=False)
G = ox.graph_from_xml(tmpfile.name, simplify=True)
ox.save_graphml(G, out_graphml)
print(f"[OK] {tile_name} done ✅")
except Exception as e:
print(f"[ERROR] Failed on {tile_name}: {e}")
# Remove small .osm.pbf to save space
if os.path.exists(out_pbf):
os.remove(out_pbf)
# Main loop
def main():
for pbf_file in sorted(os.listdir(UNPROCESSED_DIR)):
if not pbf_file.endswith(".osm.pbf"):
continue
pbf_path = os.path.join(UNPROCESSED_DIR, pbf_file)
process_pbf(pbf_path)
if __name__ == "__main__":
main()
Limitations - Do NOT rely strongly on this map
- Maps may be inaccurate and are not guaranteed to be reliable
- Maps may be lacking certain information