pymartheproject / pymarthe

1 stars 1 forks source link

Rtree error #31

Open ebus-brgm opened 1 month ago

ebus-brgm commented 1 month ago

I am running into an issue when creating a Marthe instance with a spatial index. This creation was working smoothly few weeks ago and I am wondering whether it is related to new security rules with our IT department. Is there a way to divert Rtree storage to a permissible location?

# load Marthe model 
rma_file = 'Model.rma'

# create Marthe instance
mm = MartheModel(os.path.join('.', rma_file), spatial_index=True)

rtree.exceptions.RTreeError: Error in "Index_CreateWithStream": Spatial Index Error: IllegalArgumentException: SpatialIndex::DiskStorageManager: Index/Data file cannot be read/written.

ebus-brgm commented 1 month ago

I found a workaround to solve this, by specifically naming the spatial_index file, as made possible by pymarthe:

# create Marthe instance
# mm = MartheModel(os.path.join(mldir, rma_file), spatial_index=True)
custom_si = {'name': 'Model_SI.si', 'only_active': True}
mm = MartheModel(rma_file, spatial_index=custom_si)

So it seems that my issue is on the default name provided in the build_spatial_index() function (marthe.py)

pmatran commented 1 month ago

Hi @ebus-brgm :wave:

Thank's for your issue.

I've already experienced similar issue, and the reason may be less obvious than it seems.
When creating a spatial index for a given model, 2 files are generated in the model folder: a binary file (.si) containing node idetifiers and a data file (.dat) storing node characteristics (row, column, ...). When a sampling operation is performed, the spatial query passes through the opening of these files, creating a certain form of connection without passing through RAM storage.
What I've noticed is that if this connection is not properly closed (if you brutally close your interpreter window for exemple), the binary file will be corrupted so it becomes impossible to reuse the spatial index again (reading problem). The most trivial solution I used to solve that issue was simply to delete the existing .si and .dat files from disk and simply rebuild the spatial index from scratch :innocent: :

# -- Set spatial index file names & remove them
SI_FILES = ['model.si', 'model.dat']
for si_file in SI_FILES:
    os.remove(si_file)
# -- Build fresh new default spatial index
mm = MartheModel('model.rma', spatial_index=True)

I understand that this approach isn't the sexiest, but it should (I hope) solve your problem!

By the way, using the custom version forces the creation of a new index with a name chosen by the user, which is why your reading problem no longer occurs because the pymarthe.Model object is pointing the new created .si file.

It might be a good idea to add a connection closure feature directly at the end of each spatial query, or to upgrade the library to more recent solutions offering greater efficiency, readability and support like shapely, geopandas, gdal, ... :facepunch: .

I hope this comment has been helpful,

See you :v:,

Pierre