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

R.K.
17.5k3 gold badges61 silver badges110 bronze badges
asked Nov 23, 2012 at 16:07
7
  • It seems you're still using non-unique gid in the layer datasource definition. 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. Commented Nov 23, 2012 at 17:02
  • @underdark: btw..thanks for pgRoutingLayer plugin. I'm learning a lot reading your code. 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++ 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. 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.

answered Dec 20, 2014 at 15:49
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.

answered Jul 1, 2013 at 9:18

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.