4

I'm trying to create a vectors grid from a single geometry, from PostGIS's table to another PostGIS's table; both tables are in the same DB. The input geometry is MultiPolygon and I've previously created with SQL the output table:

CREATE TABLE IF NOT EXISTS comuni_campania_copy (
    id SERIAL PRIMARY KEY,
    comune VARCHAR(255) NOT NULL,
    comune_id INTEGER NOT NULL
);
SELECT AddGeometryColumn('comuni_campania_copy', 'geom', 32633, 'MULTIPOLYGON', 2);

I'm be able to create with GeoPandas a vectors grid from a shapefile and save it as another shapefile. I've modified my script to use this functionality with PostGIS.

from shapely.geometry import MultiPolygon
from sqlalchemy import *
import geopandas as gpd
import numpy as np
import psycopg2

# Connection data
con_params = create_engine('postgresql://postgres:1234@localhost:5432/postgres', echo=False)

# SQL parameters
sql_params_in = "SELECT id as comune_id, geom, comune FROM comuni_campania WHERE id = 3"


def vector_grid_from_db(sql_params: str, con_params: psycopg2.extensions.connection, dx: int, dy: int) -> None:
    # Read vector
    vector_in = gpd.GeoDataFrame.from_postgis(
        sql=sql_params,
        con=con_params
    )

    # Read bounding box
    bbox = vector_in.bounds

    # Generate columns and rows
    cols = list(np.arange(bbox.minx[0], bbox.maxx[0], dx))
    rows = list(np.arange(bbox.miny[0] + dy, bbox.maxy[0] + dy, dy))

    # Create vector grid
    polygons = []
    for x in cols:
        for y in rows:
            polygons.append(MultiPolygon([(x, y), (x + dx, y), (x + dx, y - dy), (x, y - dy)]))

        grid = gpd.GeoDataFrame(geometry=polygons, crs=vector_in.crs)

    epsq_code = int(str(vector_in.crs)[5:])

    grid.to_postgis(
        'comuni_campania_copy',
        con_params,
        if_exists="append",
        index=False,
        dtype={
            "geometry": Geometry(
                "MULTIPOLYGON",
                srid=epsq_code
            )
        }
    )

vector_grid_from_db(sql_params_in, con_params, 300, 300)

Using my script I see this error:

Traceback (most recent call last): File "create_grid_to_db.py", line 71, in vector_grid_from_db(sql_params_in, con_params, 300, 300) File "create_grid_to_db.py", line 45, in vector_grid_from_db polygons.append(MultiPolygon([(x, y), (x + dx, y), (x + dx, y - dy), (x, y - dy)])) File "/home/maxdragonheart/DEV_FOLDER/MIO/GISPython/devenv/lib/python3.8/site-packages/shapely/geometry/multipolygon.py", line 62, in init self._geom, self._ndim = geos_multipolygon_from_polygons(polygons) File "/home/maxdragonheart/DEV_FOLDER/MIO/GISPython/devenv/lib/python3.8/site-packages/shapely/geometry/multipolygon.py", line 181, in geos_multipolygon_from_polygons N = len(exemplar[0][0]) IndexError: invalid index to scalar variable.

3

1 Answer 1

4

A MultiPolygon is a list of Polygons so use:

polygons = []
for x in cols:
    for y in rows:
        polygons.append(MultiPolygon([Polygon([(x, y), (x + dx, y), (x + dx, y - dy), (x, y - dy)])]))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.