crs-l3-tokyo-jgd-crossings
Map (reference ← swipe → agent)
0:00
I'm rebuilding the road-safety dashboard for Tokyo's 23 special wards. For each ward I need to know how often the drivable road network crosses the ward boundary (please skip service roads), plus a 50 m buffer around every crossing for jurisdictional reporting. Pull the data from current OSM via Overpass. Run the engineering layers in the regional metric coordinate system so the distances and areas come out in real metres.
Save everything to a single `tokyo_crossings.gpkg` with five layers:
- `wards_jgd` (Polygon): the 23 ward boundaries.
- `crossing_points` (Point): one point at each place a road crosses a ward boundary.
- `crossing_buffers_50m` (Polygon): a 50 m buffer around each crossing point.
- `buffer_ward_intersection` (Polygon): each buffer clipped to the ward whose boundary it crossed.
- `ward_crossing_density_wgs84` (Polygon): one row per ward with `ward_id`, `crossing_count`, `ward_area_km2`, and `crossings_per_km2`. This is what the public dashboard reads, so it goes in WGS84 while the other four stay in the metric grid.
Use each ward's OSM relation id as `ward_id`, and carry the English and native ward names as `ward_name_en` and `ward_name` on every layer that's tied to a specific ward.
0:00
System info
{
"adapter": "openrouter",
"model": "google/gemma-4-26b-a4b-it",
"base_url": "https://openrouter.ai/api/v1"
}
0:01
Bash
pip install osmnx requests geopandas shapely pyproj
Defaulting to user installation because normal site-packages is not writeable Requirement already satisfied: osmnx in /usr/local/lib/python3.14/site-packages (2.1.0) Requirement already satisfied: requests in /usr/local/lib/python3.14/site-packages (2.34.2) Requirement already satisfied: geopandas in /usr/local/lib/python3.14/site-packages (1.1.3) Requirement already satisfied: shapely in /usr/local/lib/python3.14/site-packages (2.1.2) Requirement already satisfied: pyproj in /usr/local/lib/python3.14/site-packages (3.7.2) Requirement already satisfied: networkx>=2.5 in /usr/local/lib/python3.14/site-packages (from osmnx) (3.6.1) Requirement already satisfied: numpy>=1.24 in /usr/local/lib/python3.14/site-packages (from osmnx) (2.4.6) Requirement already satisfied: pandas>=1.5 in /usr/local/lib/python3.14/site-packages (from osmnx) (3.0.3) Requirement already satisfied: charset_normalizer<4,>=2 in /usr/local/lib/python3.14/site-packages (from requests) (3.4.7) Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.14/site-packages (from requests) (3.18) Requirement already satisfied: urllib3<3,>=1.26 in /usr/local/lib/python3.14/site-packages (from requests) (2.7.0) Requirement already satisfied: certifi>=2023.5.7 in /usr/local/lib/python3.14/site-packages (from requests) (2026.5.20) Requirement already satisfied: pyogrio>=0.7.2 in /usr/local/lib/python3.14/site-packages (from geopandas) (0.12.1) Requirement already satisfied: packaging in /usr/local/lib/python3.14/site-packages (from geopandas) (26.2) Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.14/site-packages (from pandas>=1.5->osmnx) (2.9.0.post0) Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.14/site-packages (from python-dateutil>=2.8.2->pandas>=1.5->osmnx) (1.17.0)
1:34
Write
content · 288 lines
import osmnx as ox
import geopandas as gpd
import pandas as pd
from shapely.geometry import Point, MultiPoint
import requests
def get_tokyo_wards():
print("Fetching Tokyo 23 wards from OSM...")
# We use 'Tokyo, Japan' but we need the 23 special wards.
# A more precise way is to search for the administrative boundaries of the 23 wards.
# OSMnx can download boundaries by name or by a list of names.
# Since there are exactly 23, let's try to get them via a query or by using the administrative level.
# Alternatively, we can use the relation for "Tokyo Special Wards".
# Let's try to get the boundaries of the 23 wards.
# The 23 wards are often part of a single relation or can be found by searching.
# Using osmnx to get the boundaries of 'Tokyo, Japan' might give us the prefecture.
# Let's try to find the 23 wards specifically.
# A list of the 23 wards is hardcoded or we search for them.
# Let's use a more robust approach: search for administrative boundaries in Tokyo with admin_level=8 (typical for wards).
# However, to be safe and efficient, let's try to download them by a query.
# For this task, I'll use a broad search and filter.
# Actually, the most reliable way is to use the OSM relation ID if we knew it,
# but we can search for "Tokyo Special Wards" or similar.
# Let's try fetching via osmnx using the city name 'Tokyo' and then filtering.
# But Tokyo is huge. We specifically want the 23 special wards.
# Let's use Overpass directly to get the 23 wards.
# The 23 special wards are often grouped in a relation.
# Query: [out:json][timeout:90];area["name"="Tokyo"]->.a;relation["admin_level"="8"]["boundary"="administrative"](area.a);out body;>;out skel qt;
overpass_url = "http://overpass-api.de/api/interpreter"
overpass_query = """
[out:json][timeout:90];
area["name"="Tokyo"]->.a;
(
relation["admin_level"="8"]["boundary"="administrative"](area.a);
);
out body;
>;
out skel qt;
"""
print("Querying Overpass for wards...")
response = requests.get(overpass_url, params={'data': overpass_query})
if response.status_code != 200:
raise Exception(f"Overpass query failed: {response.status_code}")
data = response.json()
# Convert OSM JSON to GeoDataFrame
# osmnx has a way to do this if we use its geocode, but for relations it's better to use osmnx's internal logic if possible.
# Actually, let's use ox.features_from_place which is more convenient.
# Let's try a simpler way:
# We want the 23 special wards.
# We'll use osmnx to get the features for the "Special Wards of Tokyo" if it exists,
# or just download all admin_level 8 in Tokyo and pick the ones that are wards.
return ox.features_from_place("Tokyo, Japan", tags={"admin_level": "8", "boundary": "administrative"})
def main():
# 1. Get Wards
try:
wards = get_tokyo_wards()
except Exception as e:
print(f"Error fetching wards: {e}")
return
# Filter to ensure we only have the 23 special wards (they usually have admin_level=8 and are in Tokyo)
# In OSM, the 23 wards are often distinguished by their relation.
# For this exercise, we'll assume the returned wards are the ones we need.
# We need to keep 'ward_id' (OSM relation id), 'ward_name_en' (name:en), 'ward_name' (name).
# Pre-process wards
wards = wards[wards.geometry.type.isin(['Polygon', 'MultiPolygon'])].copy()
# Standardize column names
# OSM names can be in different columns: 'name', 'name:en', 'name:ja'
# We'll map them to ward_name_en, ward_name, and ward_id
def get_val(row, col_list):
for col in col_list:
if col in row.index and pd.notnull(row[col]):
return row[col]
return None
wards['ward_id'] = wards.index.map(lambda x: x if isinstance(x, int) else None)
# Wait, index of ox.features_from_place is the OSM ID.
# If it's a relation, the index is the relation ID.
# Let's re-check the index.
wards['ward_id'] = wards.index
wards['ward_name_en'] = wards.apply(lambda r: get_val(r, ['name:en', 'name_en', 'en']), axis=1)
wards['ward_name'] = wards.apply(lambda r: get_val(r, ['name:ja', 'name_ja', 'ja', 'name']), axis=1)
# If name:en is missing, use name
wards.loc[wards['ward_name_en'].isna(), 'ward_name_en'] = wards['ward_name']
# We only want the 23 wards. Let's refine by checking if they are in Tokyo.
# For the purpose of this task, we assume the user wants the 23 wards.
# Let's filter to keep only those that have a ward-like name or are within the expected set.
# Actually, the query for admin_level 8 in Tokyo should be mostly wards.
# Let's just take all of them and proceed.
# 2. Setup Coordinate Systems
# JGD2011 / Japan Plane Rectangular CS (e.g., zone 10 for Tokyo is EPSG:6677)
# Or better, use a projection that is good for Tokyo. EPSG:6677 (JGD2011 / Japan Plane Rectangular CS IX) is common for Tokyo.
# Let's use EPSG:6677.
target_crs = "EPSG:6677"
wards_metric = wards.to_crs(target_crs)
# 3. Get Road Network
print("Fetching road network (this may take a while)...")
# We need drivable roads. osmox.graph_from_place returns a graph.
# We want the geometries.
# To avoid service roads, we can filter by highway tag.
# Service roads: highway=service.
# We want: highway=primary, secondary, tertiary, residential, unclassified, living_street, etc.
# Instead of graph, let's use features_from_place to get the lines directly.
# This is more direct for intersection analysis.
# We'll get roads in the bounding box of the wards.
bbox = wards.total_bounds # [minx, miny, maxx, maxy]
# To be efficient, let's use osmnx.features_from_bbox
# We exclude 'service' roads.
road_tags = {"highway": [True]} # Get all highways first
roads = ox.features_from_bbox(bbox[3], bbox[1], bbox[2], bbox[0], tags=road_tags)
# Filter out service roads and non-line geometries
roads = roads[roads.geometry.type.isin(['LineString', 'MultiLineString'])]
roads = roads[roads['highway'] != 'service']
# Convert roads to metric CRS
roads_metric = roads.to_crs(target_crs)
# 4. Find Crossings
print("Calculating crossings...")
# A crossing occurs where a road geometry intersects a ward boundary.
# We want the intersection points.
# We can iterate through wards and roads.
# For each ward, find the intersection of its boundary with the roads.
crossing_points_list = []
for idx, ward in wards_metric.iterrows():
ward_boundary = ward.geometry.boundary
# Intersect roads with ward boundary
# This returns geometries (Points or MultiPoints)
intersections = roads_metric.intersection(ward_boundary)
# intersections might contain LineStrings if a road is coincident with boundary,
# but for 'crossing' we usually want points.
# However, osmnx intersection might return LineStrings if they overlap.
# We want the points where they cross.
for _, inter_geom in intersections.items():
if inter_geom.is_empty:
continue
# If it's a Point or MultiPoint, we extract points
if inter_geom.geom_type == 'Point':
crossing_points_list.append({
'geometry': inter_geom,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
elif inter_geom.geom_type == 'MultiPoint':
for p in inter_geom.geoms:
crossing_points_list.append({
'geometry': p,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
# If it's a LineString (road follows boundary), we might want to skip or take endpoints.
# The prompt says "crosses the ward boundary".
# For a dashboard, usually we want the crossing points.
# Let's ignore LineStrings for now as they aren't "crossings" in the typical sense.
if not crossing_points_list:
print("No crossings found. Check road filtering or ward boundaries.")
return
crossing_points = gpd.GeoDataFrame(crossing_points_list, crs=target_crs)
# 5. Create Buffers
print("Creating buffers...")
crossing_buffers_50m = crossing_points.copy()
crossing_buffers_50m['geometry'] = crossing_points.geometry.buffer(50)
# 6. Clip Buffers to Wards
print("Clipping buffers to wards...")
# Each buffer should be clipped to the ward whose boundary it crossed.
# Since our crossing_points already has ward info, we can use a spatial join or loop.
buffer_ward_intersection_list = []
# We use the ward info already attached to the points.
for idx, buffer_row in crossing_buffers_50m.iterrows():
# Find the ward matching the ward_id
target_ward = wards_metric[wards_metric['ward_id'] == buffer_row['ward_id']]
if not target_ward.empty:
clipped_geom = buffer_row.geometry.intersection(target_ward.iloc[0].geometry)
if not clipped_geom.is_empty:
buffer_ward_intersection_list.append({
'geometry': clipped_geom,
'ward_id': buffer_row['ward_id'],
'ward_name_en': buffer_row['ward_name_en'],
'ward_name': buffer_row['ward_name']
})
buffer_ward_intersection = gpd.GeoDataFrame(buffer_ward_intersection_list, crs=target_crs)
# 7. Calculate Ward Crossing Density
print("Calculating density...")
# One row per ward
# ward_id, crossing_count, ward_area_km2, crossings_per_km2
# We need to make sure all wards are included even if they have 0 crossings.
density_data = []
for idx, ward in wards_metric.iterrows():
count = len(crossing_points[crossing_points['ward_id'] == ward['ward_id']])
area_m2 = ward.geometry.area
area_km2 = area_m2 / 1_000_000
density = count / area_km2 if area_km2 > 0 else 0
density_data.append({
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name'],
'crossing_count': count,
'ward_area_km2': area_km2,
'crossings_per_km2': density,
'geometry': ward.geometry
})
ward_crossing_density = gpd.GeoDataFrame(density_data, crs=target_crs)
# Convert to WGS84
ward_crossing_density_wgs84 = ward_crossing_density.to_crs("EPSG:4326")
# 8. Save to GPKG
print("Saving to tokyo_crossings.gpkg...")
# The layers in metric:
# wards_jgd
# crossing_points
# crossing_buffers_50m
# buffer_ward_intersection
# The layer in WGS84:
# ward_crossing_density_wgs84
# We need to write them to the same file.
# Note: geopandas.to_file with mode='a' appends layers.
# First, create the file with the first layer
wards_jgd = wards_metric.copy()
# Ensure we only have the columns requested for wards_jgd if any, but we'll keep ward_id, ward_name_en, ward_name
# The prompt says "Use each ward's OSM relation id as ward_id, and carry the English and native ward names as ward_name_en and ward_name on every layer that's tied to a specific ward."
# wards_jgd is tied to the ward.
# Keep only necessary columns for wards_jgd to be clean, or just keep all.
# Let's keep ward_id, ward_name_en, ward_name and geometry.
wards_jgd = wards_jgd[['ward_id', 'ward_name_en', 'ward_name', 'geometry']]
wards_jgd.to_file("tokyo_crossings.gpkg", layer='wards_jgd', driver="GPKG")
# Append other layers
crossing_points[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file("tokyo_crossings.gpkg", layer='crossing_points', driver="GPKG", mode='a')
crossing_buffers_50m[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file("tokyo_crossings.gpkg", layer='crossing_buffers_50m', driver="GPKG", mode='a')
buffer_ward_intersection[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file("tokyo_crossings.gpkg", layer='buffer_ward_intersection', driver="GPKG", mode='a')
# Final layer in WGS84
ward_crossing_density_wgs84[['ward_id', 'ward_name_en', 'ward_name', 'crossing_count', 'ward_area_km2', 'crossings_per_km2', 'geometry']].to_file("tokyo_crossings.gpkg", layer='ward_crossing_density_wgs84', driver="GPKG", mode='a')
print("Done!")
if __name__ == "__main__":
main()
missing or non-string argument: 'file_path'
2:26
Write
content · 223 lines
import osmnx as ox
import geopandas as gpd
import pandas as pd
from shapely.geometry import Point, MultiPoint
import requests
def get_tokyo_wards():
print("Fetching Tokyo 23 wards from OSM...")
# We'll use a specific query for the 23 special wards if possible,
# or get admin_level 8 in Tokyo.
# Let's try a query that targets the 23 wards specifically.
# In OSM, there is a relation for Tokyo's special wards.
overpass_url = "http://overpass-api.de/api/interpreter"
# We want the 23 wards. They are admin_level 8.
# To be sure we get the 23 wards and not other admin level 8s in Tokyo prefecture,
# we can look for the relation that contains them, but it's safer to just
# filter for name patterns or check the count.
# Let's try getting admin_level 8 in Tokyo.
overpass_query = """
[out:json][timeout:90];
area["name"="Tokyo"]["admin_level"="1"]->.a;
(
relation["admin_level"="8"]["boundary"="administrative"](area.a);
);
out body;
>;
out skel qt;
"""
print("Querying Overpass for wards...")
response = requests.get(overpass_url, params={'data': overpass_query})
if response.status_code != 200:
raise Exception(f"Overpass query failed: {response.status_code}")
data = response.json()
# Using osmnx to download the features from the results of the query is complex.
# Let's use osmnx's more direct approach.
# 'Tokyo, Japan' is a bit broad. 'Special Wards of Tokyo' might work.
# Let's try ox.features_from_place with a more specific name.
return ox.features_from_place("Special Wards of Tokyo", tags={"admin_level": "8"})
def main():
# 1. Get Wards
try:
wards = get_tokyo_wards()
except Exception as e:
print(f"Error fetching wards: {e}. Falling back to a broader search.")
try:
wards = ox.features_from_place("Tokyo, Japan", tags={"admin_level": "8"})
except Exception as e2:
print(f"Fallback failed: {e2}")
return
# Filter to ensure we have polygons/multipolygons
wards = wards[wards.geometry.type.isin(['Polygon', 'MultiPolygon'])].copy()
if wards.empty:
print("No wards found.")
return
# Standardize column names
# OSM names can be in different columns: 'name', 'name:en', 'name:ja'
def get_val(row, col_list):
for col in col_list:
if col in row.index and pd.notnull(row[col]):
return row[col]
return None
wards['ward_id'] = wards.index
wards['ward_name_en'] = wards.apply(lambda r: get_val(r, ['name:en', 'name_en', 'en']), axis=1)
wards['ward_name'] = wards.apply(lambda r: get_val(r, ['name:ja', 'name_ja', 'ja', 'name']), axis=1)
# If name:en is missing, use name
wards.loc[wards['ward_name_en'].isna(), 'ward_name_en'] = wards['ward_name']
# 2. Setup Coordinate Systems
# JGD2011 / Japan Plane Rectangular CS (EPSG:6677 is for zone IX - Tokyo)
target_crs = "EPSG:6677"
wards_metric = wards.to_crs(target_crs)
# 3. Get Road Network
print("Fetching road network (this may take a while)...")
bbox = wards.total_bounds # [minx, miny, maxx, maxy]
# Fetching all highways in the area.
# We use a slightly larger bbox to ensure we catch roads crossing boundaries.
road_tags = {"highway": True}
roads = ox.features_from_bbox(bbox[3], bbox[1], bbox[2], bbox[0], tags=road_tags)
# Filter out service roads and non-line geometries
roads = roads[roads.geometry.type.isin(['LineString', 'MultiLineString'])]
# Filter out 'service' roads. Some roads might have multiple tags or a single tag.
# We check if 'highway' is 'service'.
if 'highway' in roads.columns:
roads = roads[roads['highway'] != 'service']
# Convert roads to metric CRS
roads_metric = roads.to_crs(target_crs)
# 4. Find Crossings
print("Calculating crossings...")
crossing_points_list = []
# Optimization: iterate through wards, find intersections with roads
for idx, ward in wards_metric.iterrows():
ward_boundary = ward.geometry.boundary
# Use spatial index for faster intersection if needed, but for 23 wards, a loop is fine.
# intersections = roads_metric.intersection(ward_boundary)
# To handle potential LineStrings from intersection (when road is exactly on boundary),
# we specifically want the points of intersection.
# We can use the overlay method or simply iterate.
# Since we want points where the road crosses the boundary:
# The intersection of a LineString (road) and a LineString (boundary) is a Point or MultiPoint.
# For efficiency, we first filter roads that are near the ward boundary.
# But let's keep it simple first.
intersections = roads_metric.intersection(ward_boundary)
for _, inter_geom in intersections.items():
if inter_geom.is_empty:
continue
# If it's a Point or MultiPoint, we extract points
if inter_geom.geom_type == 'Point':
crossing_points_list.append({
'geometry': inter_geom,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
elif inter_geom.geom_type == 'MultiPoint':
for p in inter_geom.geoms:
crossing_points_list.append({
'geometry': p,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
# If it's a LineString (road follows boundary), we ignore it as it's not a 'crossing' point.
if not crossing_points_list:
print("No crossings found. Check road filtering or ward boundaries.")
# If no crossings, we'll still produce the wards and density (which will be 0)
crossing_points = gpd.GeoDataFrame(columns=['ward_id', 'ward_name_en', 'ward_name', 'geometry'], crs=target_crs)
else:
crossing_points = gpd.GeoDataFrame(crossing_points_list, crs=target_crs)
# 5. Create Buffers
print("Creating buffers...")
crossing_buffers_50m = crossing_points.copy()
if not crossing_buffers_50m.empty:
crossing_buffers_50m['geometry'] = crossing_buffers_50m.geometry.buffer(50)
# 6. Clip Buffers to Wards
print("Clipping buffers to wards...")
buffer_ward_intersection_list = []
if not crossing_buffers_50m.empty:
for idx, buffer_row in crossing_buffers_50m.iterrows():
# Find the ward matching the ward_id
target_ward = wards_metric[wards_metric['ward_id'] == buffer_row['ward_id']]
if not target_ward.empty:
# Clip the buffer to the ward
clipped_geom = buffer_row.geometry.intersection(target_ward.iloc[0].geometry)
if not clipped_geom.is_empty:
buffer_ward_intersection_list.append({
'geometry': clipped_geom,
'ward_id': buffer_row['ward_id'],
'ward_name_en': buffer_row['ward_name_en'],
'ward_name': buffer_row['ward_name']
})
buffer_ward_intersection = gpd.GeoDataFrame(buffer_ward_intersection_list, crs=target_crs)
# 7. Calculate Ward Crossing Density
print("Calculating density...")
density_data = []
for idx, ward in wards_metric.iterrows():
count = len(crossing_points[crossing_points['ward_id'] == ward['ward_id']])
area_m2 = ward.geometry.area
area_km2 = area_m2 / 1_000_000
density = count / area_km2 if area_km2 > 0 else 0
density_data.append({
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name'],
'crossing_count': count,
'ward_area_km2': area_km2,
'crossings_per_km2': density,
'geometry': ward.geometry
})
ward_crossing_density = gpd.GeoDataFrame(density_data, crs=target_crs)
# Convert to WGS84
ward_crossing_density_wgs84 = ward_crossing_density.to_crs("EPSG:4326")
# 8. Save to GPKG
print("Saving to tokyo_crossings.gpkg...")
output_file = "tokyo_crossings.gpkg"
# Create the file with the first layer
wards_jgd = wards_metric[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].copy()
wards_jgd.to_file(output_file, layer='wards_jgd', driver="GPKG")
# Append other layers
crossing_points[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='crossing_points', driver="GPKG", mode='a')
crossing_buffers_50m[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='crossing_buffers_50m', driver="GPKG", mode='a')
buffer_ward_intersection[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='buffer_ward_intersection', driver="GPKG", mode='a')
# Final layer in WGS84
ward_crossing_density_wgs84[['ward_id', 'ward_name_en', 'ward_name', 'crossing_count', 'ward_area_km2', 'crossings_per_km2', 'geometry']].to_file(output_file, layer='ward_crossing_density_wgs84', driver="GPKG", mode='a')
print(f"Done! File saved to {output_file}")
if __name__ == "__main__":
main()
missing or non-string argument: 'file_path'
2:57
Write
content · 177 lines
import osmnx as ox
import geopandas as gpd
import pandas as pd
from shapely.geometry import Point, MultiPoint
import requests
def get_tokyo_wards():
print("Fetching Tokyo 23 wards from OSM...")
# We'll try to get the 23 wards using a specific query.
# Tokyo's 23 wards are often identified by admin_level=8 within Tokyo.
# If we use osmnx.features_from_place("Special Wards of Tokyo", tags={"admin_level": "8"}),
# it might work if the place name is well-indexed.
try:
return ox.features_from_place("Special Wards of Tokyo", tags={"admin_level": "8"})
except:
# Fallback: fetch admin_level 8 in Tokyo prefecture
return ox.features_from_place("Tokyo, Japan", tags={"admin_level": "8"})
def main():
# 1. Get Wards
try:
wards = get_tokyo_wards()
except Exception as e:
print(f"Error fetching wards: {e}")
return
# Filter to ensure we only have Polygons/MultiPolygons
wards = wards[wards.geometry.type.isin(['Polygon', 'MultiPolygon'])].copy()
if wards.empty:
print("No wards found.")
return
# Standardize column names
def get_val(row, col_list):
for col in col_list:
if col in row.index and pd.notnull(row[col]):
return row[col]
return None
wards['ward_id'] = wards.index
wards['ward_name_en'] = wards.apply(lambda r: get_val(r, ['name:en', 'name_en', 'en']), axis=1)
wards['ward_name'] = wards.apply(lambda r: get_val(r, ['name:ja', 'name_ja', 'ja', 'name']), axis=1)
# If name:en is missing, use name
wards.loc[wards['ward_name_en'].isna(), 'ward_name_en'] = wards['ward_name']
# 2. Setup Coordinate Systems
# JGD2011 / Japan Plane Rectangular CS (EPSG:6677 is zone IX - Tokyo)
target_crs = "EPSG:6677"
wards_metric = wards.to_crs(target_crs)
# 3. Get Road Network
print("Fetching road network (this may take a while)...")
bbox = wards.total_bounds # [minx, miny, maxx, maxy]
# Use a slightly larger bbox to ensure we catch roads crossing boundaries.
# We fetch all highways in the bounding box.
road_tags = {"highway": True}
roads = ox.features_from_bbox(bbox[3], bbox[1], bbox[2], bbox[0], tags=road_tags)
# Filter out service roads and non-line geometries
roads = roads[roads.geometry.type.isin(['LineString', 'MultiLineString'])]
if 'highway' in roads.columns:
roads = roads[roads['highway'] != 'service']
# Convert roads to metric CRS
roads_metric = roads.to_crs(target_crs)
# 4. Find Crossings
print("Calculating crossings...")
crossing_points_list = []
for idx, ward in wards_metric.iterrows():
ward_boundary = ward.geometry.boundary
# Intersections of road (LineString) and boundary (LineString)
intersections = roads_metric.intersection(ward_boundary)
for _, inter_geom in intersections.items():
if inter_geom.is_empty:
continue
# We are looking for points where the road crosses the boundary.
if inter_geom.geom_type == 'Point':
crossing_points_list.append({
'geometry': inter_geom,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
elif inter_geom.geom_type == 'MultiPoint':
for p in inter_geom.geoms:
crossing_points_list.append({
'geometry': p,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
if not crossing_points_list:
print("No crossings found.")
crossing_points = gpd.GeoDataFrame(columns=['ward_id', 'ward_name_en', 'ward_name', 'geometry'], crs=target_crs)
else:
crossing_points = gpd.GeoDataFrame(crossing_points_list, crs=target_crs)
# 5. Create Buffers
print("Creating buffers...")
crossing_buffers_50m = crossing_points.copy()
if not crossing_buffers_50m.empty:
crossing_buffers_50m['geometry'] = crossing_buffers_50m.geometry.buffer(50)
# 6. Clip Buffers to Wards
print("Clipping buffers to wards...")
buffer_ward_intersection_list = []
if not crossing_buffers_50m.empty:
for idx, buffer_row in crossing_buffers_50m.iterrows():
target_ward = wards_metric[wards_metric['ward_id'] == buffer_row['ward_id']]
if not target_ward.empty:
clipped_geom = buffer_row.geometry.intersection(target_ward.iloc[0].geometry)
if not clipped_geom.is_empty:
buffer_ward_intersection_list.append({
'geometry': clipped_geom,
'ward_id': buffer_row['ward_id'],
'ward_name_en': buffer_row['ward_name_en'],
'ward_name': buffer_row['ward_name']
})
buffer_ward_intersection = gpd.GeoDataFrame(buffer_ward_intersection_list, crs=target_crs)
# 7. Calculate Ward Crossing Density
print("Calculating density...")
density_data = []
for idx, ward in wards_metric.iterrows():
count = len(crossing_points[crossing_points['ward_id'] == ward['ward_id']])
area_m2 = ward.geometry.area
area_km2 = area_m2 / 1_000_000
density = count / area_km2 if area_km2 > 0 else 0
density_data.append({
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name'],
'crossing_count': count,
'ward_area_km2': area_km2,
'crossings_per_km2': density,
'geometry': ward.geometry
})
ward_crossing_density = gpd.GeoDataFrame(density_data, crs=target_crs)
ward_crossing_density_wgs84 = ward_crossing_density.to_crs("EPSG:4326")
# 8. Save to GPKG
print("Saving to tokyo_crossings.gpkg...")
output_file = "tokyo_crossings.gpkg"
# Layer 1: wards_jgd
wards_jgd = wards_metric[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].copy()
wards_jgd.to_file(output_file, layer='wards_jgd', driver="GPKG")
# Layer 2: crossing_points
crossing_points[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='crossing_points', driver="GPKG", mode='a')
# Layer 3: crossing_buffers_50m
crossing_buffers_50m[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='crossing_buffers_50m', driver="GPKG", mode='a')
# Layer 4: buffer_ward_intersection
buffer_ward_intersection[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='buffer_ward_intersection', driver="GPKG", mode='a')
# Layer 5: ward_crossing_density_wgs84
ward_crossing_density_wgs84[['ward_id', 'ward_name_en', 'ward_name', 'crossing_count', 'ward_area_km2', 'crossings_per_km2', 'geometry']].to_file(output_file, layer='ward_crossing_density_wgs84', driver="GPKG", mode='a')
print(f"Done! File saved to {output_file}")
if __name__ == "__main__":
main()
missing or non-string argument: 'file_path'
3:37
Write
content · 175 lines
import osmnx as ox
import geopandas as gpd
import pandas as pd
from shapely.geometry import Point, MultiPoint
import requests
def get_tokyo_wards():
print("Fetching Tokyo 23 wards from OSM...")
# The 23 special wards are a unique administrative division.
# A very reliable way to get them is to query for admin_level 8 in Tokyo.
# To be even more precise, we'll use the Overpass API via osmnx logic.
# We use a search string that is commonly used for the 23 wards.
return ox.features_from_place("Tokyo, Japan", tags={"admin_level": "8"})
def main():
# 1. Get Wards
try:
wards = get_tokyo_wards()
except Exception as e:
print(f"Error fetching wards: {e}")
return
# Filter to ensure we only have Polygons/MultiPolygons
wards = wards[wards.geometry.type.isin(['Polygon', 'MultiPolygon'])].copy()
if wards.empty:
print("No wards found.")
return
# We want to identify the 23 wards. In OSM, the 23 wards are often
# part of the Tokyo prefecture but they are distinct.
# We'll assume the admin_level 8 in Tokyo returns the 23 wards.
# Standardize column names
def get_val(row, col_list):
for col in col_list:
if col in row.index and pd.notnull(row[col]):
return row[col]
return None
wards['ward_id'] = wards.index
wards['ward_name_en'] = wards.apply(lambda r: get_val(r, ['name:en', 'name_en', 'en']), axis=1)
wards['ward_name'] = wards.apply(lambda r: get_val(r, ['name:ja', 'name_ja', 'ja', 'name']), axis=1)
# If name:en is missing, use name
wards.loc[wards['ward_name_en'].isna(), 'ward_name_en'] = wards['ward_name']
# 2. Setup Coordinate Systems
# JGD2011 / Japan Plane Rectangular CS (EPSG:6677 is for zone IX - Tokyo)
target_crs = "EPSG:6677"
wards_metric = wards.to_crs(target_crs)
# 3. Get Road Network
print("Fetching road network (this may take a while)...")
bbox = wards.total_bounds # [minx, miny, maxx, maxy]
# Use a slightly larger bbox to ensure we catch roads crossing boundaries.
road_tags = {"highway": True}
roads = ox.features_from_bbox(bbox[3], bbox[1], bbox[2], bbox[0], tags=road_tags)
# Filter out service roads and non-line geometries
roads = roads[roads.geometry.type.isin(['LineString', 'MultiLineString'])]
if 'highway' in roads.columns:
roads = roads[roads['highway'] != 'service']
# Convert roads to metric CRS
roads_metric = roads.to_crs(target_crs)
# 4. Find Crossings
print("Calculating crossings...")
crossing_points_list = []
# Optimization: Iterate through wards, find intersections with roads
for idx, ward in wards_metric.iterrows():
ward_boundary = ward.geometry.boundary
intersections = roads_metric.intersection(ward_boundary)
for _, inter_geom in intersections.items():
if inter_geom.is_empty:
continue
if inter_geom.geom_type == 'Point':
crossing_points_list.append({
'geometry': inter_geom,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
elif inter_geom.geom_type == 'MultiPoint':
for p in inter_geom.geoms:
crossing_points_list.append({
'geometry': p,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
if not crossing_points_list:
print("No crossings found.")
crossing_points = gpd.GeoDataFrame(columns=['ward_id', 'ward_name_en', 'ward_name', 'geometry'], crs=target_crs)
else:
crossing_points = gpd.GeoDataFrame(crossing_points_list, crs=target_crs)
# 5. Create Buffers
print("Creating buffers...")
crossing_buffers_50m = crossing_points.copy()
if not crossing_buffers_50m.empty:
crossing_buffers_50m['geometry'] = crossing_buffers_50m.geometry.buffer(50)
# 6. Clip Buffers to Wards
print("Clipping buffers to wards...")
buffer_ward_intersection_list = []
if not crossing_buffers_50m.empty:
for idx, buffer_row in crossing_buffers_50m.iterrows():
target_ward = wards_metric[wards_metric['ward_id'] == buffer_row['ward_id']]
if not target_ward.empty:
clipped_geom = buffer_row.geometry.intersection(target_ward.iloc[0].geometry)
if not clipped_geom.is_empty:
buffer_ward_intersection_list.append({
'geometry': clipped_geom,
'ward_id': buffer_row['ward_id'],
'ward_name_en': buffer_row['ward_name_en'],
'ward_name': buffer_row['ward_name']
})
buffer_ward_intersection = gpd.GeoDataFrame(buffer_ward_intersection_list, crs=target_crs)
# 7. Calculate Ward Crossing Density
print("Calculating density...")
density_data = []
for idx, ward in wards_metric.iterrows():
count = len(crossing_points[crossing_points['ward_id'] == ward['ward_id']])
area_m2 = ward.geometry.area
area_km2 = area_m2 / 1_000_000
density = count / area_km2 if area_km2 > 0 else 0
density_data.append({
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name'],
'crossing_count': count,
'ward_area_km2': area_km2,
'crossings_per_km2': density,
'geometry': ward.geometry
})
ward_crossing_density = gpd.GeoDataFrame(density_data, crs=target_crs)
ward_crossing_density_wgs84 = ward_crossing_density.to_crs("EPSG:4326")
# 8. Save to GPKG
print("Saving to tokyo_crossings.gpkg...")
output_file = "tokyo_crossings.gpkg"
# Layer 1: wards_jgd
wards_jgd = wards_metric[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].copy()
wards_jgd.to_file(output_file, layer='wards_jgd', driver="GPKG")
# Layer 2: crossing_points
crossing_points[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='crossing_points', driver="GPKG", mode='a')
# Layer 3: crossing_buffers_50m
crossing_buffers_50m[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='crossing_buffers_50m', driver="GPKG", mode='a')
# Layer 4: buffer_ward_intersection
buffer_ward_intersection[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='buffer_ward_intersection', driver="GPKG", mode='a')
# Layer 5: ward_crossing_density_wgs84
ward_crossing_density_wgs84[['ward_id', 'ward_name_en', 'ward_name', 'crossing_count', 'ward_area_km2', 'crossings_per_km2', 'geometry']].to_file(output_file, layer='ward_crossing_density_wgs84', driver="GPKG", mode='a')
print(f"Done! File saved to {output_file}")
if __name__ == "__main__":
main()
missing or non-string argument: 'file_path'
3:53
Write
content · 170 lines
import osmnx as ox
import geopandas as gpd
import pandas as pd
from shapely.geometry import Point, MultiPoint
import requests
def get_tokyo_wards():
print("Fetching Tokyo 23 wards from OSM...")
# Using a query to get the 23 wards (admin_level 8) in Tokyo.
# To avoid fetching everything, we'll use osmnx features_from_place
# but we'll be careful about what it returns.
# The "23 Special Wards" is a specific area.
return ox.features_from_place("Tokyo, Japan", tags={"admin_level": "8"})
def main():
# 1. Get Wards
try:
wards = get_tokyo_wards()
except Exception as e:
print(f"Error fetching wards: {e}")
return
# Filter to ensure we only have Polygons/MultiPolygons
wards = wards[wards.geometry.type.isin(['Polygon', 'MultiPolygon'])].copy()
if wards.empty:
print("No wards found.")
return
# Standardize column names
def get_val(row, col_list):
for col in col_list:
if col in row.index and pd.notnull(row[col]):
return row[col]
return None
wards['ward_id'] = wards.index
wards['ward_name_en'] = wards.apply(lambda r: get_val(r, ['name:en', 'name_en', 'en']), axis=1)
wards['ward_name'] = wards.apply(lambda r: get_val(r, ['name:ja', 'name_ja', 'ja', 'name']), axis=1)
# If name:en is missing, use name
wards.loc[wards['ward_name_en'].isna(), 'ward_name_en'] = wards['ward_name']
# 2. Setup Coordinate Systems
# EPSG:6677 is JGD2011 / Japan Plane Rectangular CS IX, which is suitable for Tokyo.
target_crs = "EPSG:6677"
wards_metric = wards.to_crs(target_crs)
# 3. Get Road Network
print("Fetching road network (this may take a while)...")
bbox = wards.total_bounds # [minx, miny, maxx, maxy]
# Fetch all highways in the bounding box.
# We use a slightly larger bbox to ensure we catch roads crossing boundaries.
road_tags = {"highway": True}
roads = ox.features_from_bbox(bbox[3], bbox[1], bbox[2], bbox[0], tags=road_tags)
# Filter out service roads and non-line geometries
roads = roads[roads.geometry.type.isin(['LineString', 'MultiLineString'])]
if 'highway' in roads.columns:
roads = roads[roads['highway'] != 'service']
# Convert roads to metric CRS
roads_metric = roads.to_crs(target_crs)
# 4. Find Crossings
print("Calculating crossings...")
crossing_points_list = []
for idx, ward in wards_metric.iterrows():
ward_boundary = ward.geometry.boundary
intersections = roads_metric.intersection(ward_boundary)
for _, inter_geom in intersections.items():
if inter_geom.is_empty:
continue
if inter_geom.geom_type == 'Point':
crossing_points_list.append({
'geometry': inter_geom,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
elif inter_geom.geom_type == 'MultiPoint':
for p in inter_geom.geoms:
crossing_points_list.append({
'geometry': p,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
if not crossing_points_list:
print("No crossings found.")
crossing_points = gpd.GeoDataFrame(columns=['ward_id', 'ward_name_en', 'ward_name', 'geometry'], crs=target_crs)
else:
crossing_points = gpd.GeoDataFrame(crossing_points_list, crs=target_crs)
# 5. Create Buffers
print("Creating buffers...")
crossing_buffers_50m = crossing_points.copy()
if not crossing_buffers_50m.empty:
crossing_buffers_50m['geometry'] = crossing_buffers_50m.geometry.buffer(50)
# 6. Clip Buffers to Wards
print("Clipping buffers to wards...")
buffer_ward_intersection_list = []
if not crossing_buffers_50m.empty:
for idx, buffer_row in crossing_buffers_50m.iterrows():
target_ward = wards_metric[wards_metric['ward_id'] == buffer_row['ward_id']]
if not target_ward.empty:
clipped_geom = buffer_row.geometry.intersection(target_ward.iloc[0].geometry)
if not clipped_geom.is_empty:
buffer_ward_intersection_list.append({
'geometry': clipped_geom,
'ward_id': buffer_row['ward_id'],
'ward_name_en': buffer_row['ward_name_en'],
'ward_name': buffer_row['ward_name']
})
buffer_ward_intersection = gpd.GeoDataFrame(buffer_ward_intersection_list, crs=target_crs)
# 7. Calculate Ward Crossing Density
print("Calculating density...")
density_data = []
for idx, ward in wards_metric.iterrows():
count = len(crossing_points[crossing_points['ward_id'] == ward['ward_id']])
area_m2 = ward.geometry.area
area_km2 = area_m2 / 1_000_000
density = count / area_km2 if area_km2 > 0 else 0
density_data.append({
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name'],
'crossing_count': count,
'ward_area_km2': area_km2,
'crossings_per_km2': density,
'geometry': ward.geometry
})
ward_crossing_density = gpd.GeoDataFrame(density_data, crs=target_crs)
ward_crossing_density_wgs84 = ward_crossing_density.to_crs("EPSG:4326")
# 8. Save to GPKG
print("Saving to tokyo_crossings.gpkg...")
output_file = "tokyo_crossings.gpkg"
# Layer 1: wards_jgd
wards_jgd = wards_metric[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].copy()
wards_jgd.to_file(output_file, layer='wards_jgd', driver="GPKG")
# Layer 2: crossing_points
crossing_points[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='crossing_points', driver="GPKG", mode='a')
# Layer 3: crossing_buffers_50m
crossing_buffers_50m[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='crossing_buffers_50m', driver="GPKG", mode='a')
# Layer 4: buffer_ward_intersection
buffer_ward_intersection[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='buffer_ward_intersection', driver="GPKG", mode='a')
# Layer 5: ward_crossing_density_wgs84
ward_crossing_density_wgs84[['ward_id', 'ward_name_en', 'ward_name', 'crossing_count', 'ward_area_km2', 'crossings_per_km2', 'geometry']].to_file(output_file, layer='ward_crossing_density_wgs84', driver="GPKG", mode='a')
print(f"Done! File saved to {output_file}")
if __name__ == "__main__":
main()
missing or non-string argument: 'file_path'
4:16
Write
content · 176 lines
import osmnx as ox
import geopandas as gpd
import pandas as pd
from shapely.geometry import Point, MultiPoint
import requests
def get_tokyo_wards():
print("Fetching Tokyo 23 wards from OSM...")
# We want the 23 special wards.
# Let's use a query that specifically targets them.
# In OSM, the 23 wards are often admin_level 8.
# Using a place name that is specific to the 23 wards.
return ox.features_from_place("Special Wards, Tokyo, Japan", tags={"admin_level": "8"})
def main():
# 1. Get Wards
try:
wards = get_tokyo_wards()
except Exception as e:
print(f"Error fetching wards: {e}. Trying fallback...")
try:
# Fallback to a broader search
wards = ox.features_from_place("Tokyo, Japan", tags={"admin_level": "8"})
except Exception as e2:
print(f"Fallback failed: {e2}")
return
# Filter to ensure we only have Polygons/MultiPolygons
wards = wards[wards.geometry.type.isin(['Polygon', 'MultiPolygon'])].copy()
if wards.empty:
print("No wards found.")
return
# Standardize column names
def get_val(row, col_list):
for col in col_list:
if col in row.index and pd.notnull(row[col]):
return row[col]
return None
wards['ward_id'] = wards.index
wards['ward_name_en'] = wards.apply(lambda r: get_val(r, ['name:en', 'name_en', 'en']), axis=1)
wards['ward_name'] = wards.apply(lambda r: get_val(r, ['name:ja', 'name_ja', 'ja', 'name']), axis=1)
# If name:en is missing, use name
wards.loc[wards['ward_name_en'].isna(), 'ward_name_en'] = wards['ward_name']
# 2. Setup Coordinate Systems
# EPSG:6677 is JGD2011 / Japan Plane Rectangular CS IX (for Tokyo)
target_crs = "EPSG:6677"
wards_metric = wards.to_crs(target_crs)
# 3. Get Road Network
print("Fetching road network...")
bbox = wards.total_bounds # [minx, miny, maxx, maxy]
# We fetch roads in the bounding box of the wards.
# We'll use a slightly larger bbox to be safe.
road_tags = {"highway": True}
roads = ox.features_from_bbox(bbox[3], bbox[1], bbox[2], bbox[0], tags=road_tags)
# Filter out service roads and non-line geometries
roads = roads[roads.geometry.type.isin(['LineString', 'MultiLineString'])]
if 'highway' in roads.columns:
roads = roads[roads['highway'] != 'service']
# Convert roads to metric CRS
roads_metric = roads.to_crs(target_crs)
# 4. Find Crossings
print("Calculating crossings...")
crossing_points_list = []
# Iterating through wards and finding intersections with roads
for idx, ward in wards_metric.iterrows():
ward_boundary = ward.geometry.boundary
intersections = roads_metric.intersection(ward_boundary)
for _, inter_geom in intersections.items():
if inter_geom.is_empty:
continue
if inter_geom.geom_type == 'Point':
crossing_points_list.append({
'geometry': inter_geom,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
elif inter_geom.geom_type == 'MultiPoint':
for p in inter_geom.geoms:
crossing_points_list.append({
'geometry': p,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
if not crossing_points_list:
print("No crossings found.")
crossing_points = gpd.GeoDataFrame(columns=['ward_id', 'ward_name_en', 'ward_name', 'geometry'], crs=target_crs)
else:
crossing_points = gpd.GeoDataFrame(crossing_points_list, crs=target_crs)
# 5. Create Buffers
print("Creating 50m buffers...")
crossing_buffers_50m = crossing_points.copy()
if not crossing_buffers_50m.empty:
crossing_buffers_50m['geometry'] = crossing_buffers_50m.geometry.buffer(50)
# 6. Clip Buffers to Wards
print("Clipping buffers to wards...")
buffer_ward_intersection_list = []
if not crossing_buffers_50m.empty:
for idx, buffer_row in crossing_buffers_50m.iterrows():
target_ward = wards_metric[wards_metric['ward_id'] == buffer_row['ward_id']]
if not target_ward.empty:
clipped_geom = buffer_row.geometry.intersection(target_ward.iloc[0].geometry)
if not clipped_geom.is_empty:
buffer_ward_intersection_list.append({
'geometry': clipped_geom,
'ward_id': buffer_row['ward_id'],
'ward_name_en': buffer_row['ward_name_en'],
'ward_name': buffer_row['ward_name']
})
buffer_ward_intersection = gpd.GeoDataFrame(buffer_ward_intersection_list, crs=target_crs)
# 7. Calculate Ward Crossing Density
print("Calculating density...")
density_data = []
for idx, ward in wards_metric.iterrows():
count = len(crossing_points[crossing_points['ward_id'] == ward['ward_id']])
area_m2 = ward.geometry.area
area_km2 = area_m2 / 1_000_000
density = count / area_km2 if area_km2 > 0 else 0
density_data.append({
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name'],
'crossing_count': count,
'ward_area_km2': area_km2,
'crossings_per_km2': density,
'geometry': ward.geometry
})
ward_crossing_density = gpd.GeoDataFrame(density_data, crs=target_crs)
ward_crossing_density_wgs84 = ward_crossing_density.to_crs("EPSG:4326")
# 8. Save to GPKG
print("Saving to tokyo_crossings.gpkg...")
output_file = "tokyo_crossings.gpkg"
# Layer 1: wards_jgd
wards_jgd = wards_metric[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].copy()
wards_jgd.to_file(output_file, layer='wards_jgd', driver="GPKG")
# Layer 2: crossing_points
crossing_points[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='crossing_points', driver="GPKG", mode='a')
# Layer 3: crossing_buffers_50m
crossing_buffers_50m[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='crossing_buffers_50m', driver="GPKG", mode='a')
# Layer 4: buffer_ward_intersection
buffer_ward_intersection[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='buffer_ward_intersection', driver="GPKG", mode='a')
# Layer 5: ward_crossing_density_wgs84
ward_crossing_density_wgs84[['ward_id', 'ward_name_en', 'ward_name', 'crossing_count', 'ward_area_km2', 'crossings_per_km2', 'geometry']].to_file(output_file, layer='ward_crossing_density_wgs84', driver="GPKG", mode='a')
print(f"Done! File saved to {output_file}")
if __name__ == "__main__":
main()
missing or non-string argument: 'file_path'
4:34
Write
content · 166 lines
import osmnx as ox
import geopandas as gpd
import pandas as pd
from shapely.geometry import Point, MultiPoint
def get_tokyo_wards():
print("Fetching Tokyo 23 wards from OSM...")
# The 23 wards are special administrative units.
# Trying a specific place name.
return ox.features_from_place("Tokyo, Japan", tags={"admin_level": "8"})
def main():
# 1. Get Wards
try:
wards = get_tokyo_wards()
except Exception as e:
print(f"Error fetching wards: {e}")
return
# Filter to ensure we only have Polygons/MultiPolygons
wards = wards[wards.geometry.type.isin(['Polygon', 'MultiPolygon'])].copy()
if wards.empty:
print("No wards found.")
return
# Standardize column names
def get_val(row, col_list):
for col in col_list:
if col in row.index and pd.notnull(row[col]):
return row[col]
return None
wards['ward_id'] = wards.index
wards['ward_name_en'] = wards.apply(lambda r: get_val(r, ['name:en', 'name_en', 'en']), axis=1)
wards['ward_name'] = wards.apply(lambda r: get_val(r, ['name:ja', 'name_ja', 'ja', 'name']), axis=1)
# If name:en is missing, use name
wards.loc[wards['ward_name_en'].isna(), 'ward_name_en'] = wards['ward_name']
# 2. Setup Coordinate Systems
# EPSG:6677 is JGD2011 / Japan Plane Rectangular CS IX (for Tokyo)
target_crs = "EPSG:6677"
wards_metric = wards.to_crs(target_crs)
# 3. Get Road Network
print("Fetching road network...")
bbox = wards.total_bounds # [minx, miny, maxx, maxy]
# We'll use a slightly larger bbox to be safe.
road_tags = {"highway": True}
roads = ox.features_from_bbox(bbox[3], bbox[1], bbox[2], bbox[0], tags=road_tags)
# Filter out service roads and non-line geometries
roads = roads[roads.geometry.type.isin(['LineString', 'MultiLineString'])]
if 'highway' in roads.columns:
roads = roads[roads['highway'] != 'service']
# Convert roads to metric CRS
roads_metric = roads.to_crs(target_crs)
# 4. Find Crossings
print("Calculating crossings...")
crossing_points_list = []
for idx, ward in wards_metric.iterrows():
ward_boundary = ward.geometry.boundary
intersections = roads_metric.intersection(ward_boundary)
for _, inter_geom in intersections.items():
if inter_geom.is_empty:
continue
if inter_geom.geom_type == 'Point':
crossing_points_list.append({
'geometry': inter_geom,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
elif inter_geom.geom_type == 'MultiPoint':
for p in inter_geom.geoms:
crossing_points_list.append({
'geometry': p,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
if not crossing_points_list:
print("No crossings found.")
crossing_points = gpd.GeoDataFrame(columns=['ward_id', 'ward_name_en', 'ward_name', 'geometry'], crs=target_crs)
else:
crossing_points = gpd.GeoDataFrame(crossing_points_list, crs=target_crs)
# 5. Create Buffers
print("Creating 50m buffers...")
crossing_buffers_50m = crossing_points.copy()
if not crossing_buffers_50m.empty:
crossing_buffers_50m['geometry'] = crossing_buffers_50m.geometry.buffer(50)
# 6. Clip Buffers to Wards
print("Clipping buffers to wards...")
buffer_ward_intersection_list = []
if not crossing_buffers_50m.empty:
for idx, buffer_row in crossing_buffers_50m.iterrows():
target_ward = wards_metric[wards_metric['ward_id'] == buffer_row['ward_id']]
if not target_ward.empty:
clipped_geom = buffer_row.geometry.intersection(target_ward.iloc[0].geometry)
if not clipped_geom.is_empty:
buffer_ward_intersection_list.append({
'geometry': clipped_geom,
'ward_id': buffer_row['ward_id'],
'ward_name_en': buffer_row['ward_name_en'],
'ward_name': buffer_row['ward_name']
})
buffer_ward_intersection = gpd.GeoDataFrame(buffer_ward_intersection_list, crs=target_crs)
# 7. Calculate Ward Crossing Density
print("Calculating density...")
density_data = []
for idx, ward in wards_metric.iterrows():
count = len(crossing_points[crossing_points['ward_id'] == ward['ward_id']])
area_m2 = ward.geometry.area
area_km2 = area_m2 / 1_000_000
density = count / area_km2 if area_km2 > 0 else 0
density_data.append({
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name'],
'crossing_count': count,
'ward_area_km2': area_km2,
'crossings_per_km2': density,
'geometry': ward.geometry
})
ward_crossing_density = gpd.GeoDataFrame(density_data, crs=target_crs)
ward_crossing_density_wgs84 = ward_crossing_density.to_crs("EPSG:4326")
# 8. Save to GPKG
print("Saving to tokyo_crossings.gpkg...")
output_file = "tokyo_crossings.gpkg"
# Layer 1: wards_jgd
wards_jgd = wards_metric[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].copy()
wards_jgd.to_file(output_file, layer='wards_jgd', driver="GPKG")
# Layer 2: crossing_points
crossing_points[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='crossing_points', driver="GPKG", mode='a')
# Layer 3: crossing_buffers_50m
crossing_buffers_50m[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='crossing_buffers_50m', driver="GPKG", mode='a')
# Layer 4: buffer_ward_intersection
buffer_ward_intersection[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='buffer_ward_intersection', driver="GPKG", mode='a')
# Layer 5: ward_crossing_density_wgs84
ward_crossing_density_wgs84[['ward_id', 'ward_name_en', 'ward_name', 'crossing_count', 'ward_area_km2', 'crossings_per_km2', 'geometry']].to_file(output_file, layer='ward_crossing_density_wgs84', driver="GPKG", mode='a')
print(f"Done! File saved to {output_file}")
if __name__ == "__main__":
main()
missing or non-string argument: 'file_path'
4:37
(no output)
Bash
# I will use a simpler script to avoid issues with the Write tool.
# I will use a simpler script to avoid issues with the Write tool. # The problem is that I am using Write with a lot of content and it's failing. # I will write the script in smaller chunks or use a single Bash command to write it. # Actually, I'll just use a heredoc in Bash.
5:03
Bash
cat << 'EOF' > /work/solve.py
cat << 'EOF' > /work/solve.py
import osmnx as ox
import geopandas as gpd
import pandas as pd
from shapely.geometry import Point, MultiPoint
def get_tokyo_wards():
print("Fetching Tokyo 23 wards from OSM...")
# Using a search string that is common for the 23 wards.
# If "Special Wards of Tokyo" doesn't work, "Tokyo, Japan" with admin_level 8 is a good fallback.
try:
return ox.features_from_place("Special Wards of Tokyo, Japan", tags={"admin_level": "8"})
except:
return ox.features_from_place("Tokyo, Japan", tags={"admin_level": "8"})
def main():
# 1. Get Wards
try:
wards = get_tokyo_wards()
except Exception as e:
print(f"Error fetching wards: {e}")
return
# Filter to ensure we only have Polygons/MultiPolygons
wards = wards[wards.geometry.type.isin(['Polygon', 'MultiPolygon'])].copy()
if wards.empty:
print("No wards found.")
return
# Standardize column names
def get_val(row, col_list):
for col in col_list:
if col in row.index and pd.notnull(row[col]):
return row[col]
return None
wards['ward_id'] = wards.index
wards['ward_name_en'] = wards.apply(lambda r: get_val(r, ['name:en', 'name_en', 'en']), axis=1)
wards['ward_name'] = wards.apply(lambda r: get_val(r, ['name:ja', 'name_ja', 'ja', 'name']), axis=1)
# If name:en is missing, use name
wards.loc[wards['ward_name_en'].isna(), 'ward_name_en'] = wards['ward_name']
# 2. Setup Coordinate Systems
# EPSG:6677 is JGD2011 / Japan Plane Rectangular CS IX (for Tokyo)
target_crs = "EPSG:6677"
wards_metric = wards.to_crs(target_crs)
# 3. Get Road Network
print("Fetching road network (this might take a few minutes)...")
bbox = wards.total_bounds # [minx, miny, maxx, maxy]
# Fetch all highways in the bounding box.
road_tags = {"highway": True}
roads = ox.features_from_bbox(bbox[3], bbox[1], bbox[2], bbox[0], tags=road_tags)
# Filter out service roads and non-line geometries
roads = roads[roads.geometry.type.isin(['LineString', 'MultiLineString'])]
if 'highway' in roads.columns:
# Ensure we exclude 'service'
roads = roads[roads['highway'] != 'service']
# Convert roads to metric CRS
roads_metric = roads.to_crs(target_crs)
# 4. Find Crossings
print("Calculating crossings...")
crossing_points_list = []
for idx, ward in wards_metric.iterrows():
ward_boundary = ward.geometry.boundary
intersections = roads_metric.intersection(ward_boundary)
for _, inter_geom in intersections.items():
if inter_geom.is_empty:
continue
if inter_geom.geom_type == 'Point':
crossing_points_list.append({
'geometry': inter_geom,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
elif inter_geom.geom_type == 'MultiPoint':
for p in inter_geom.geoms:
crossing_points_list.append({
'geometry': p,
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name']
})
if not crossing_points_list:
print("No crossings found.")
crossing_points = gpd.GeoDataFrame(columns=['ward_id', 'ward_name_en', 'ward_name', 'geometry'], crs=target_crs)
else:
crossing_points = gpd.GeoDataFrame(crossing_points_list, crs=target_crs)
# 5. Create Buffers
print("Creating 50m buffers...")
crossing_buffers_50m = crossing_points.copy()
if not crossing_buffers_50m.empty:
crossing_buffers_50m['geometry'] = crossing_buffers_50m.geometry.buffer(50)
# 6. Clip Buffers to Wards
print("Clipping buffers to wards...")
buffer_ward_intersection_list = []
if not crossing_buffers_50m.empty:
for idx, buffer_row in crossing_buffers_50m.iterrows():
target_ward = wards_metric[wards_metric['ward_id'] == buffer_row['ward_id']]
if not target_ward.empty:
clipped_geom = buffer_row.geometry.intersection(target_ward.iloc[0].geometry)
if not clipped_geom.is_empty:
buffer_ward_intersection_list.append({
'geometry': clipped_geom,
'ward_id': buffer_row['ward_id'],
'ward_name_en': buffer_row['ward_name_en'],
'ward_name': buffer_row['ward_name']
})
buffer_ward_intersection = gpd.GeoDataFrame(buffer_ward_intersection_list, crs=target_crs)
# 7. Calculate Ward Crossing Density
print("Calculating density...")
density_data = []
for idx, ward in wards_metric.iterrows():
count = len(crossing_points[crossing_points['ward_id'] == ward['ward_id']])
area_m2 = ward.geometry.area
area_km2 = area_m2 / 1_000_000
density = count / area_km2 if area_km2 > 0 else 0
density_data.append({
'ward_id': ward['ward_id'],
'ward_name_en': ward['ward_name_en'],
'ward_name': ward['ward_name'],
'crossing_count': count,
'ward_area_km2': area_km2,
'crossings_per_km2': density,
'geometry': ward.geometry
})
ward_crossing_density = gpd.GeoDataFrame(density_data, crs=target_crs)
ward_crossing_density_wgs84 = ward_crossing_density.to_crs("EPSG:4326")
# 8. Save to GPKG
print("Saving to tokyo_crossings.gpkg...")
output_file = "tokyo_crossings.gpkg"
# Layer 1: wards_jgd
wards_jgd = wards_metric[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].copy()
wards_jgd.to_file(output_file, layer='wards_jgd', driver="GPKG")
# Layer 2: crossing_points
crossing_points[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='crossing_points', driver="GPKG", mode='a')
# Layer 3: crossing_buffers_50m
crossing_buffers_50m[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='crossing_buffers_50m', driver="GPKG", mode='a')
# Layer 4: buffer_ward_intersection
buffer_ward_intersection[['ward_id', 'ward_name_en', 'ward_name', 'geometry']].to_file(output_file, layer='buffer_ward_intersection', driver="GPKG", mode='a')
# Layer 5: ward_crossing_density_wgs84
ward_crossing_density_wgs84[['ward_id', 'ward_name_en', 'ward_name', 'crossing_count', 'ward_area_km2', 'crossings_per_km2', 'geometry']].to_file(output_file, layer='ward_crossing_density_wgs84', driver="GPKG", mode='a')
print(f"Done! File saved to {output_file}")
if __name__ == "__main__":
main()
EOF
python /work/solve.py
Fetching Tokyo 23 wards from OSM...
Error fetching wards: HTTPSConnectionPool(host='overpass-api.de', port=443): Max retries exceeded with url: /api/interpreter (Caused by NewConnectionError("HTTPSConnection(host='overpass-api.de', port=443): Failed to establish a new connection: [Errno 111] Connection refused"))
/usr/local/lib/python3.14/site-packages/osmnx/_overpass.py:271: UserWarning: This area is 650 times your configured Overpass max query area size. It will automatically be divided up into multiple sub-queries accordingly. This may take a long time. multi_poly_proj = utils_geo._consolidate_subdivide_geometry(poly_proj)
6:12
```thought
6:12
Bash
# The connection refused might be a temporary issue or a restriction.
# The connection refused might be a temporary issue or a restriction. # Let's try to run it again, maybe it's a transient network error. python /work/solve.py
Fetching Tokyo 23 wards from OSM...
Error fetching wards: HTTPSConnectionPool(host='overpass-api.de', port=443): Max retries exceeded with url: /api/interpreter (Caused by NewConnectionError("HTTPSConnection(host='overpass-api.de', port=443): Failed to establish a new connection: [Errno 111] Connection refused"))
/usr/local/lib/python3.14/site-packages/osmnx/_overpass.py:271: UserWarning: This area is 650 times your configured Overpass max query area size. It will automatically be divided up into multiple sub-queries accordingly. This may take a long time. multi_poly_proj = utils_geo._consolidate_subdivide_geometry(poly_proj)
7:22
```thought
7:22
Bash
# The Overpass API might be having issues or limiting requests.
# The Overpass API might be having issues or limiting requests.
# Let's try to use a different way to get the wards or check the network.
# Since the user wants to "Pull the data from current OSM via Overpass",
# I must try to make it work.
# Maybe the "Special Wards of Tokyo, Japan" is too large?
# Let's try a much smaller area to test connectivity.
cat << 'EOF' > /work/test_conn.py
import requests
try:
response = requests.get("http://overpass-api.de/api/interpreter", params={'data': '[out:json];node(35.6,139.6,35.7,139.8);out;'}, timeout=10)
print(f"Status: {response.status_code}")
except Exception as e:
print(f"Error: {e}")
EOF
python /work/test_conn.py
Error: HTTPConnectionPool(host='overpass-api.de', port=80): Max retries exceeded with url: /api/interpreter?data=%5Bout%3Ajson%5D%3Bnode%2835.6%2C139.6%2C35.7%2C139.8%29%3Bout%3B (Caused by NewConnectionError("HTTPConnection(host='overpass-api.de', port=80): Failed to establish a new connection: [Errno 101] Network is unreachable"))
8:12
$thought
8:12