4

I'm trying to understand what goes wrong with a QGIS python plugin. Basically I'm trying to render a series of POINT.

The query works fine, at least giving it by hand from inside PostGIS DB:

"SELECT  gid, CAST (gid as text)|| '_' || (ST_DumpPoints(the_geom)).path[2] as key,  (ST_DumpPoints(the_geom)).geom as points FROM ways"

I concat gid and path[2] because after splitting the_geom (MULTILINE) field into several POINT, gid are duplicated and I think they are no longer usable as key (with this trick key should be unique, but it seems not solve my problem).

I tried to create the layer this way:

def createPointLayer(self):
    uri = self.db.getURI()
    query = "SELECT  gid, CAST (gid as text)|| '_' || (ST_DumpPoints(the_geom)).path[2] as key,  (ST_DumpPoints(the_geom)).geom as points FROM ways"

    uri.setDataSource("", "(" + query + ")", "points","","key")
    layerName = "NodeLayer"
    aLayer = self.iface.addVectorLayer(uri.uri(), layerName, self.db.getProviderName())

I think the query works fine (QGIS takes a long time before display the error. I guess something goes wrong after the query has been executed).

When the plugins run QGIS output the following error:

Layer is not valid:

The layer dbname='pgrouting' user='user' password='user' key='gid' table="(SELECT gid, CAST (gid as text)|| '_' || (ST_DumpPoints(the_geom)).path[2] as key, (ST_DumpPoints(the_geom)).geom as points FROM ways)" (points) sql= is not a valid layer and can not be added to the map

I already had to struggle against the Layer is not valid error, but I don't know how to debug it. So I have 2 questions:

  1. Could anyone tell me what's my mistake in this specific case?
  2. How can I debug 'Layer not valid error'? How can I get more information on which is the problem?

EDIT:

QGIS log console display the following message:

No key field for query given

7
  • It seems you're still using non-unique gid in the layer datasource definition.
    – underdark
    Commented Nov 23, 2012 at 16:50
  • @underdark: sorry, I pasted the wrong code. I edit it. Consider data source set this way: uri.setDataSource("", "(" + query + ")", "points","","key"). And I've just checked that key column has no duplicated value.
    – Heisenbug
    Commented Nov 23, 2012 at 17:02
  • @underdark: btw..thanks for pgRoutingLayer plugin. I'm learning a lot reading your code.
    – Heisenbug
    Commented Nov 23, 2012 at 17:08
  • Are you wrapping some of the API in your own code? I cannot find a reference to addVectorLayer in PyQGIS. It seems addVectorLayer is found in the QGIS API for C++
    – RomaH
    Commented Nov 23, 2012 at 17:24
  • @RomaH: iface is a reference to QGIS interface: qgis.org/pyqgis-cookbook/plugins.html#writing-a-plugin . Btw that method works as is. I didn't wrap anything. In other point of my code works fine.
    – Heisenbug
    Commented Nov 23, 2012 at 17:27

2 Answers 2

1

It seems your "key" field must have type integer and not text. I reproduced your problem with the following snippet:

uri = QgsDataSourceURI()
uri.setConnection("localhost", "5432", "mydb", "user", "pass")
query="SELECT  id, CAST (id as text)|| '_' || (ST_DumpPoints(geom)).path[2] as key, (ST_DumpPoints(geom)).geom as points FROM line"
uri.setDataSource("", "(" + query + ")", "points", "", "key")
vl = iface.addVectorLayer(uri.uri(), "QueryLayer", "postgres")

Only after I changed the "key" field type to "int", I could get the layer loaded into QGIS:

uri = QgsDataSourceURI()
uri.setConnection("localhost", "5432", "mydb", "user", "pass")
query="SELECT  id, CAST(CAST (id as text)|| (ST_DumpPoints(geom)).path[2] as int) as key, (ST_DumpPoints(geom)).geom as points FROM line"
uri.setDataSource("", "(" + query + ")", "points", "", "key")
vl = iface.addVectorLayer(uri.uri(), "QueryLayer", "postgres")

Note that I had to adjust your gid to id and your the_geom to geom, in order to work with my own data.

0

I had the same problem: "The layer ... is not a valid layer and can not be added to the map". It was just because my "id" was not unique (by default, the plugin used the first column as id (called "edge_id", so it took me a bit to figure out) which was not unique, instead of the "id" column, which was unique.

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.