Skip to content

Commit

Permalink
Merge pull request #25 from hotosm/refactor/remove-geopandas
Browse files Browse the repository at this point in the history
Refactor out geopandas in favour of shapely
  • Loading branch information
spwoodcock authored Mar 8, 2024
2 parents a471826 + 22aa1d6 commit 3f496f6
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 358 deletions.
44 changes: 13 additions & 31 deletions fmtm_splitter/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@
#
"""DB models for temporary tables in splitBySQL."""
import logging
import warnings
from typing import Union

import geopandas as gpd
import psycopg2
from psycopg2.extensions import register_adapter
from psycopg2.extras import Json, execute_values, register_uuid
from psycopg2.extras import Json, register_uuid
from shapely.geometry import Polygon

try:
import sqlalchemy
Expand Down Expand Up @@ -89,21 +88,18 @@ def create_tables(conn: psycopg2.extensions.connection):
create_cmd = """
CREATE TABLE project_aoi (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
geom GEOMETRY(GEOMETRY, 4326),
tags JSONB
geom GEOMETRY(GEOMETRY, 4326)
);
CREATE TABLE ways_poly (
id SERIAL PRIMARY KEY,
project_id VARCHAR,
osm_id VARCHAR,
geom GEOMETRY(GEOMETRY, 4326),
tags JSONB
);
CREATE TABLE ways_line (
id SERIAL PRIMARY KEY,
project_id VARCHAR,
osm_id VARCHAR,
geom GEOMETRY(GEOMETRY, 4326),
tags JSONB
Expand Down Expand Up @@ -137,42 +133,28 @@ def drop_tables(conn: psycopg2.extensions.connection):
cur.execute(drop_cmd)


def gdf_to_postgis(gdf: gpd.GeoDataFrame, conn: psycopg2.extensions.connection, table_name: str, geom_name: str = "geom") -> None:
def aoi_to_postgis(conn: psycopg2.extensions.connection, geom: Polygon) -> None:
"""Export a GeoDataFrame to the project_aoi table in PostGIS.
Built-in geopandas to_wkb uses shapely underneath.
Uses a new cursor on existing connection, but not committed directly.
Args:
gdf (gpd.GeoDataFrame): The GeoDataFrame to export.
geom (Polygon): The shapely geom to insert.
conn (psycopg2.extensions.connection): The PostgreSQL connection.
table_name (str): The name of the table to insert data into.
geom_name (str, optional): The name of the geometry column. Defaults to "geom".
Returns:
None
"""
# Only use dataframe copy, else the geom is transformed to WKBElement
gdf = gdf.copy()
log.debug("Adding AOI to project_aoi table")

# Rename existing geometry column if it doesn't match
if geom_name not in gdf.columns:
gdf = gdf.rename(columns={gdf.geometry.name: geom_name}).set_geometry(geom_name, crs=gdf.crs)

log.debug("Converting geodataframe geom to wkb hex string")
# Ignore warning 'Geometry column does not contain geometry'
warnings.filterwarnings("ignore", category=UserWarning, module="fmtm_splitter.db")
gdf[geom_name] = gdf[geom_name].to_wkb(hex=True, include_srid=True)
warnings.filterwarnings("default", category=UserWarning, module="fmtm_splitter.db")

# Build numpy array for db insert
tuples = [tuple(x) for x in gdf.to_numpy()]
cols = ",".join(list(gdf.columns))
query = "INSERT INTO %s(%s) VALUES %%s" % (table_name, cols)
sql = """
INSERT INTO project_aoi (geom)
VALUES (ST_SetSRID(CAST(%s AS GEOMETRY), 4326));
"""

cur = conn.cursor()
execute_values(cur, query, tuples)
cur.execute(sql, (geom.wkb_hex,))
cur.close()


def insert_geom(cur: psycopg2.extensions.cursor, table_name: str, **kwargs) -> None:
Expand All @@ -188,5 +170,5 @@ def insert_geom(cur: psycopg2.extensions.cursor, table_name: str, **kwargs) -> N
Returns:
None
"""
query = f"INSERT INTO {table_name}(project_id,geom,osm_id,tags) " "VALUES (%(project_id)s,%(geom)s,%(osm_id)s,%(tags)s)"
query = f"INSERT INTO {table_name}(geom,osm_id,tags) " "VALUES (%(geom)s,%(osm_id)s,%(tags)s)"
cur.execute(query, kwargs)
Loading

0 comments on commit 3f496f6

Please sign in to comment.