7

I built a manual index on a shapefile, through the process "Create spatial index", which can be found in the process toolbox > general vector tools. This process creates a persistent spatial index, a .qix file.

I want to optimize the query: "How many polygons of a layer are contained within one or more larger polygons that I select" using PyQGIS.

Both layers are based on files in polygon shapefile format. The layer of the polygons that will be evaluated has more than 300.000 entities.

I can build and use a custom index with this code:

pry=QgsProject.instance()
parcelas=pry.mapLayersByName('parcelas')[0]
radios=pry.mapLayersByName('radios_censales')[0]

tiempo_inicial = time.time() index = QgsSpatialIndex() # Spatial index index = QgsSpatialIndex(parcelas.getFeatures()) duracionSI=time.time()-tiempo_inicial # 6.816403388977051 sec

csi=0 lisIds=[] tiempo_inicial = time.time() for i in radios.getSelectedFeatures(): bbx= i.geometry().boundingBox() listIds=index.intersects(bbx) for j in listIds: if i.geometry().contains(parcelas.getFeature(j).geometry()): csi=csi+1 duracionSI=time.time()-tiempo_inicial

But what I really want to do is leverage the existing .qix file directly, so I don't have to spend six seconds compiling the index every time. How can I do this from PyQGIS?

Note: I am aware that the spatial index file must be updated if geometries are modified, removed or added.

Matt
  • 16,843
  • 3
  • 21
  • 52
Luis Perez
  • 1,284
  • 4
  • 11
  • 2
    The capabilities of spatial indexes are dependent on the data source and the operation to be performed. Without any mention or dataset or operation, or code representing your attempt, it seems likely this question will be closed. – Vince Jan 13 '21 at 04:28
  • @Vince following your suggestion detail the consultation widely – Luis Perez Jan 13 '21 at 21:32
  • 1
    You didn't specify the data format associated with your parcels layer (in the body). And at this point, you don't seem to have a question being asked. – Vince Jan 13 '21 at 21:42
  • @Vince Sorry, but in the title I specified that I am working with shapefile. What other information should I provide? – Luis Perez Jan 14 '21 at 01:44
  • @Vince All right, edit the question again – Luis Perez Jan 14 '21 at 01:47
  • 1
    Your initial question didn't have the needed details; now you have too many, obscuring your issue. If you strip it down to "If I build a manual index on a shapefile {with example} I can optimize this query, but how can I access the .quix file directly, so I don't have to spend six seconds compiling the index every time?" your Question will be clearer. – Vince Jan 14 '21 at 01:52
  • @Vince I have just edited according to your suggestions, I hope that the question is clearer and more acceptable – Luis Perez Jan 14 '21 at 02:37
  • Thank you very much @Vince !! you can remove the condition of closed to the question?, I want to assign a bounty – Luis Perez Jan 14 '21 at 11:27
  • I do not have that ability. I have voted to reopen, but can do no more. – Vince Jan 14 '21 at 11:55
  • 2
    I would be surprised if QGIS does not automatically use an available index (e.g. an existing .qix file when you open the layer another time)! Are you sure that it is not used? – bugmenot123 Jan 15 '21 at 12:54
  • @bugmenot123 QGIS automatically recognizes the qix file when running a spatial search. But I don't see a way to do it through PyQGIS, I have checked the classes QgsVectorLayer, QgsVectorDataProvider and others, although they have methods to verify if the spatial index exists I haven't seen methods to capture it – Luis Perez Jan 15 '21 at 12:59
  • Have you tried to make heavy spatial queries with PyQGIS and with vs. without .qix file? – user30184 Jan 15 '21 at 16:11
  • I wonder what https://qgis.org/pyqgis/3.0/core/Vector/QgsVectorLayer.html does when option index=yes is used. – user30184 Jan 15 '21 at 16:25
  • @user30184 If I evaluated several options, perform the query with expressions, with PyQGIS in a sequential way, with PyQGIS filtering by the bounding box, with the spatial process query and with the spatial index. I put the code in my question, but it was edited and re-edited :) – Luis Perez Jan 16 '21 at 19:06
  • @user30184 I know how to create, use and update the spatial index, during the execution. But in a new session I don't know how to access the existing spatial index – Luis Perez Jan 16 '21 at 19:08
  • 1
    So you have also tried to open an existing shapefile that has .qix available by using the option index=yes? Without using index = QgsSpatialIndex() that obviously creates a new spatial index. Did index=yes also fire the same process of creating a new spatial index? I am not Python specialist and I apologize if my question does not make sense. – user30184 Jan 16 '21 at 20:46
  • 3
    It seems that QgsSpatialIndex is a temporary index and it is not the same than qix index https://gis.stackexchange.com/questions/234467/querying-indexed-vector-layer-finding-nearby-point. So if you want to use the qix index you will not use index.intersects. I guess that you should rather open the shapefile that has .qix index with the ogr provider and query as a.geometry().intersects(b.geometry()) and hope that the qix index is utilized transparently. See also https://gis.stackexchange.com/questions/168266/pyqgis-a-geometry-intersectsb-geometry-wouldnt-find-any-intersections – user30184 Jan 16 '21 at 21:44
  • @user30184 thank you!! this question is similar to mine gis.stackexchange.com/questions/234467/…. , but, I have doubts, the spatial index .qix is used by the process algorithms to improve the performance, a query without the hard .qix 1.333345651626587 and with the .qix only 0.06560158729553223 – Luis Perez Jan 17 '21 at 00:56
  • @user30184 Probably, it is, although not specified, that the .qix spatial index is only for QGIS use and not accessible by PyQGIS. If so, I would like you to place your comment as an answer and, eventually, assign the bounty. Eventually, to wait a little for other opinions – Luis Perez Jan 17 '21 at 00:59

0 Answers0