tools: bounds importer
This commit is contained in:
5
tools/import_bounds/.env.example
Normal file
5
tools/import_bounds/.env.example
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
DB_NAME=
|
||||||
|
DB_USER=
|
||||||
|
DB_PASSWORD=
|
||||||
|
DB_HOST=
|
||||||
|
DB_PORT=
|
5200
tools/import_bounds/city.sql
Normal file
5200
tools/import_bounds/city.sql
Normal file
File diff suppressed because one or more lines are too long
3440
tools/import_bounds/district.sql
Normal file
3440
tools/import_bounds/district.sql
Normal file
File diff suppressed because one or more lines are too long
BIN
tools/import_bounds/import_bounds.zip
Normal file
BIN
tools/import_bounds/import_bounds.zip
Normal file
Binary file not shown.
75
tools/import_bounds/init.py
Normal file
75
tools/import_bounds/init.py
Normal 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()
|
320
tools/import_bounds/region.sql
Normal file
320
tools/import_bounds/region.sql
Normal file
File diff suppressed because one or more lines are too long
55
tools/import_bounds/save_queries.py
Normal file
55
tools/import_bounds/save_queries.py
Normal 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()
|
Reference in New Issue
Block a user