4

I have a working python code that runs within the SPYDER IDE, but doesn't work when run from inside the Python console in QGIS. I have checked the QGIS installs and I can see both panda and shapely. The code opens a .csv (extension .mcsv by the creator) and creates a Polygon from it.

from PyQt5 import QtWidgets
import pandas as pd
from shapely.geometry import Polygon


import_file_path, _ = QtWidgets.QFileDialog.getOpenFileName(
    None, "Select File", "", "Line Files (*.mcsv)")
if import_file_path == '':
    msgBox = QtWidgets.QMessageBox()
    msgBox.setText("No file selected")
    msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok)
    msgBox.setIcon(QtWidgets.QMessageBox.Warning)
    msgBox.exec_()


data = pd.read_csv(import_file_path)

df = pd.DataFrame(data, columns=['Easting', 'Northing'])
df.drop(df.tail(1).index, inplace=True)  # drop -9999 row
df['Easting'] = df['Easting'].astype("string")
df['Northing'] = df['Northing'].astype("string")


p = Polygon(list(zip(df["Easting"], df["Northing"])))

print(str(p))

The .mcsv looks like this:

Map,Name,Easting,Northing
1,1,416213.873,6507344.904
1,1,424283.100,6509982.331
1,1,428632.580,6496675.102
1,1,418176.907,6493257.665
1,1,415338.984,6501940.281
1,1,416213.873,6507344.904
-9999,-9999,-9999,-9999

and the SPYDER generated output looks like:

POLYGON ((416213.873 6507344.904, 424283.1 6509982.331, 428632.58 6496675.102, 418176.907 6493257.665, 415338.984 6501940.281, 416213.873 6507344.904))

And this is the QGIS error message it get:

exec(Path('C:/Users/client/AppData/Local/Temp/tmpq5jtxh23.py').read_text())
Traceback (most recent call last):
  File "C:\PROGRA~1\QGIS32~1.2\apps\Python39\lib\code.py", line 90, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
  File "<string>", line 24, in <module>
  File "C:\PROGRA~1\QGIS32~1.2\apps\Python39\lib\site-packages\shapely\geometry\polygon.py", line 261, in __init__
    ret = geos_polygon_from_py(shell, holes)
  File "C:\PROGRA~1\QGIS32~1.2\apps\Python39\lib\site-packages\shapely\geometry\polygon.py", line 539, in geos_polygon_from_py
    ret = geos_linearring_from_py(shell)
  File "C:\PROGRA~1\QGIS32~1.2\apps\Python39\lib\site-packages\shapely\geometry\polygon.py", line 502, in geos_linearring_from_py
    lgeos.GEOSCoordSeq_setX(cs, i, coords[0])
ctypes.ArgumentError: argument 4: <class 'TypeError'>: wrong type

QGIS 3.24.2 - Tisler Python version 3.9.5

1 Answer 1

5

You are converting your coordinates to "string" type:

df['Easting'] = df['Easting'].astype("string")
df['Northing'] = df['Northing'].astype("string")

and then making a polygon:

p = Polygon(list(zip(df["Easting"], df["Northing"])))

A simple test in Python (outside QGIS) gives me this:

>>> df = pd.DataFrame(dict(Easting=[1,2,3,4],Northing=[4,5,6,7]))
>>> df['Easting'] = df['Easting'].astype("string")
>>> df['Northing'] = df['Northing'].astype("string")
>>> p = Polygon(list(zip(df["Easting"], df["Northing"])))
Traceback (most recent call last):
  File "shapely/speedups/_speedups.pyx", line 252, in shapely.speedups._speedups.geos_linearring_from_py
AttributeError: 'list' object has no attribute '__array_interface__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/rowlings/.local/lib/python3.8/site-packages/shapely/geometry/polygon.py", line 261, in __init__
    ret = geos_polygon_from_py(shell, holes)
  File "/home/rowlings/.local/lib/python3.8/site-packages/shapely/geometry/polygon.py", line 539, in geos_polygon_from_py
    ret = geos_linearring_from_py(shell)
  File "shapely/speedups/_speedups.pyx", line 373, in shapely.speedups._speedups.geos_linearring_from_py
TypeError: must be real number, not str

without the type conversion it works fine:

>>> df = pd.DataFrame(dict(Easting=[1,2,3,4],Northing=[4,5,6,7]))
>>> p = Polygon(list(zip(df["Easting"], df["Northing"])))
>>> 

I don't know why this works for you in Spyder, perhaps a different version of shapely that tolerates string inputs and does a conversion to numeric?

3
  • That solved it, seems SPYDER will work with or without the conversion.
    – WillH
    Commented Jun 2, 2023 at 8:05
  • It'll be the version of shapely that the python being run by Spyder or QGIS is using. You can see the version number with shapely.__version__. I was using 1.8.0 in my answer.
    – Spacedman
    Commented Jun 2, 2023 at 8:13
  • 1
    Looks like that is it. I had to install shapely into SPYDER which has given me 2.0.1, but my QGIS version is 1.8.0.
    – WillH
    Commented Jun 2, 2023 at 8:26

Your Answer

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

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