tools: bounds importer

This commit is contained in:
2025-04-04 14:53:32 +09:00
parent 6015218d59
commit 1f9a3a8e03
7 changed files with 9095 additions and 0 deletions

View File

@ -0,0 +1,5 @@
DB_NAME=
DB_USER=
DB_PASSWORD=
DB_HOST=
DB_PORT=

5200
tools/import_bounds/city.sql Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1,75 @@
import os
import json
import psycopg2
from datetime import datetime
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
# Database connection parameters
DB_CONFIG = {
"dbname": os.getenv("DB_NAME"),
"user": os.getenv("DB_USER"),
"password": os.getenv("DB_PASSWORD"),
"host": os.getenv("DB_HOST"),
"port": int(os.getenv("DB_PORT", 5432)) # Default port to 5432 if not set
}
# Root directory where the folders are located
ROOT_DIR = "./"
def insert_bounds(entity_id, entity_type, geometry, conn):
"""Insert data into the bounds table."""
try:
with conn.cursor() as cur:
# Check if the GeoJSON is a GeometryCollection
if geometry.get('type') == 'GeometryCollection':
# Extract polygons from the GeometryCollection and convert them to MultiPolygon
geometry = {
"type": "MultiPolygon",
"coordinates": [
geom["coordinates"] for geom in geometry["geometries"] if geom["type"] == "Polygon"
]
}
# Insert into the bounds table
cur.execute(
"""
INSERT INTO bounds (entity_id, entity_type, geometry)
VALUES (%s, %s,
ST_Transform(
ST_Multi(
ST_GeomFromGeoJSON(%s::JSON)
),
3857)
);
""",
(entity_id, entity_type, json.dumps(geometry))
)
conn.commit()
except Exception as e:
print(f"Error inserting entity_id {entity_id} of type {entity_type}: {e}")
conn.rollback()
def process_geojson_files():
"""Process all GeoJSON files in the directory structure."""
try:
conn = psycopg2.connect(**DB_CONFIG)
for folder in os.listdir(ROOT_DIR):
folder_path = os.path.join(ROOT_DIR, folder)
if os.path.isdir(folder_path):
entity_type = folder # Folder name is the entity_type
for file in os.listdir(folder_path):
if file.endswith(".geojson"):
entity_id = int(os.path.splitext(file)[0]) # Extract ID from filename
file_path = os.path.join(folder_path, file)
with open(file_path, "r") as f:
geometry = json.load(f)
insert_bounds(entity_id, entity_type, geometry, conn)
conn.close()
except Exception as e:
print(f"Error processing files: {e}")
if __name__ == "__main__":
process_geojson_files()

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,55 @@
import os
import json
# Root directory where the folders are located
ROOT_DIR = "./"
OUTPUT_FILES = {}
def get_insert_query(entity_id, entity_type, geometry):
"""Generate SQL insert query for bounds."""
# If it's a GeometryCollection, extract and convert to MultiPolygon
if geometry.get('type') == 'GeometryCollection':
geometry = {
"type": "MultiPolygon",
"coordinates": [
geom["coordinates"] for geom in geometry["geometries"] if geom["type"] == "Polygon"
]
}
geojson_str = json.dumps(geometry).replace("'", "''") # Escape single quotes for SQL
query = f"""
INSERT INTO bounds (entity_id, entity_type, geometry)
VALUES ({entity_id}, '{entity_type}',
ST_Transform(
ST_Multi(
ST_GeomFromGeoJSON('{geojson_str}'::JSON)
),
3857)
);
"""
return query
def process_geojson_files():
"""Process all GeoJSON files and write SQL inserts to appropriate files."""
for folder in os.listdir(ROOT_DIR):
folder_path = os.path.join(ROOT_DIR, folder)
if os.path.isdir(folder_path):
entity_type = folder
sql_filename = f"{entity_type}.sql"
with open(sql_filename, "w", encoding="utf-8") as sql_file:
for file in os.listdir(folder_path):
if file.endswith(".geojson"):
try:
entity_id = int(os.path.splitext(file)[0])
file_path = os.path.join(folder_path, file)
with open(file_path, "r", encoding="utf-8") as f:
geometry = json.load(f)
query = get_insert_query(entity_id, entity_type, geometry)
sql_file.write(query + "\n")
except Exception as e:
print(f"Error processing {file}: {e}")
if __name__ == "__main__":
process_geojson_files()