Skip to content

Commit

Permalink
Merge pull request #1423 from colouring-cities/minor-tweaks-oct-24
Browse files Browse the repository at this point in the history
Code to generate SQL to import building footprints
  • Loading branch information
mdsimpson42 authored Oct 22, 2024
2 parents ae4a52a + 42fd71e commit 5c37503
Showing 1 changed file with 139 additions and 0 deletions.
139 changes: 139 additions & 0 deletions configuration/generate_footprint_import_sql.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
''' Generate an SQL Script to insert Colouring Cities building footprints from GEOJSON Data '''

import json

INPUT_DIRECTORY = "./"
INPUT_FILENAME = "sg_building_footprint.geojson"

OUTPUT_FILENAME = "generate_footprints.sql"

OUTPUT = []

print(f"Saving to file: '{OUTPUT_FILENAME}' ... ", end='')

OUTPUT.append("DROP TABLE IF EXISTS new_geometries;\n")
OUTPUT.append("""CREATE TABLE IF NOT EXISTS new_geometries (
source_id varchar(30),
geometry_geom geometry(GEOMETRY, 3857)
);\n""")

IDENTIFIER_COUNTER = 1

def file_location():
''' Docstring '''
return INPUT_DIRECTORY

def file_location_name():
''' Docstring '''
return INPUT_FILENAME

def location_code():
''' Docstring '''
# things like "inspire+localmap_intersect5201"
# lc - leicester
# nc - Newcastle
# lbx - area_around_loughborough
#return "lbx"
return "sgp"

# end of configuration

def fake_toid_prefix():
''' Docstring '''
return 'inspire+local_ntrsc_' + location_code()

def files_loaded():
''' Docstring '''
return [
file_location() + file_location_name()
]

def load_into_table(table, geojson_file):
''' Docstring '''
global IDENTIFIER_COUNTER

with open(geojson_file, 'r', encoding="utf8") as content_file:
content = content_file.read()
data = json.loads(content)
insert_prefix = "INSERT INTO " + table + "(source_id, geometry_geom) VALUES"

OUTPUT.append(insert_prefix) #no new line!

values = []

for entry in data["features"]:
geometry_type = entry["geometry"]["type"]

if geometry_type == 'MultiPolygon':
for ring in entry["geometry"]["coordinates"]:
for coord_list in ring:
for coord in coord_list:
lon = coord[0]
lat = coord[1]
if lon > 180:
raise Exception("out of bounds coordinate")
if lon < -180:
raise Exception("out of bounds coordinate")
if lat > 90:
raise Exception("out of bounds coordinate")
if lat <-90:
raise Exception("out of bounds coordinate")
elif geometry_type == 'Polygon':
for coord_list in entry["geometry"]["coordinates"]:
for coord in coord_list:
lon = coord[0]
lat = coord[1]
if lon > 180:
raise Exception("out of bounds coordinate")
if lon < -180:
raise Exception("out of bounds coordinate")
if lat > 90:
raise Exception("out of bounds coordinate")
if lat <-90:
raise Exception("out of bounds coordinate")
#else:
#print(entry["geometry"]["type"])
#print(entry["geometry"])
#print(entry)
#raise Exception("Unexpected type")

object_id = fake_toid_prefix() + str(IDENTIFIER_COUNTER)

if len(object_id) > 30:
print(object_id)
print(len(object_id))
raise Exception("Too long")

values.append("('" + object_id + "', ST_Transform(ST_GeomFromGeoJSON('" + json.dumps(entry["geometry"]) + "'), 3857))")

IDENTIFIER_COUNTER += 1
grouping = 50_000

if len(values) > grouping:
OUTPUT.append(", ".join(values[0:grouping]) + ";\n")
values = values[grouping:]
OUTPUT.append(insert_prefix) #no new line

OUTPUT.append(", ".join(values) + ";\n")

for file in files_loaded():
load_into_table("new_geometries", file)

OUTPUT.append("""INSERT INTO geometries ( source_id, geometry_geom )
SELECT source_id, geometry_geom
FROM new_geometries;\n""")
OUTPUT.append("""INSERT INTO buildings ( geometry_id, ref_toid )
SELECT geometry_id, source_id
FROM geometries AS g
WHERE EXISTS ( SELECT source_id
FROM new_geometries AS ng
WHERE g.source_id = ng.source_id);\n""")
OUTPUT.append("DROP TABLE IF EXISTS new_geometries;\n")
OUTPUT.append("REINDEX TABLE geometries;\n")
OUTPUT.append("REINDEX TABLE buildings;\n")

with open(OUTPUT_FILENAME, 'w', newline='', encoding="utf8") as f:
for row in OUTPUT:
f.write(row)

print("Done!")

0 comments on commit 5c37503

Please sign in to comment.