Re: [Qgis-developer] Cleanly create memory layer in Python?

2011-01-19 Thread Martin Dobias
Hi Chris

On Mon, Jan 17, 2011 at 10:00 PM, Chris Crook ccr...@linz.govt.nz wrote:
 I've added submitted a patch to implement this change at 
 http://trac.osgeo.org/qgis/ticket/3414.

 Changes made are:

 * QgsCoordinateReferenceSystem? string constructor has been generalised to 
 allow string formats
   epsg:1234
   postgis:1234
   internal:1234
   proj4:proj_4_string
   wkt:wkt_string
   wkt_string
 This is implemented by a createFromString function, similar to the 
 createFromId function

Looks good!


 * Changed QgsMemoryProvider URI format to:
   
 memory?geometry=Pointindex=yescrs=epsg:1234field=id:integerfield=name:string(25)

I would probably prefer to have uri point? instead of
memory?geometry=point... since the fact that we are using memory
provider is given as another parameter to the vector layer
constructor, so in future we would save some typing ;-)


 The URI can contain the following items:
   geometry=Point|LineString|Polygon|MultiPoint|MultiLineString|MultiPolygon
   index=yes  - creates a spatial index
   crs=...    - defines the CRS in one of the formats above
   field=definition - defines an attribute field.

 The field definition is a field name, optionally followed by 
 :type(length,precision), where type is one of integer, int, real, double, and 
 string (int/integer are synonyms, as are real/double).  Eg
   field=magnitude:real(16,2)
   field=owner:string(64)
   field=owner

 This uses Qurl for encoding and decoding the strings.  To provide backwards 
 compatibility, if there is no geometry query string field, then the path is 
 taken as the geometry type.  For example
   point
   point?crs=epsg:1234

Good.


 * Added an option crs= to the QgsDelimitedTextProvider URI, so that 
 plugin code can specify the CRS when creating a delimited text layer.  The 
 crs can be any of the formats listed above. Also updated the provider to use 
 Qurl for encoding and decoding the URI, to ensure consistent handling of 
 special characters.

 * Made a couple of small fixes to the QgsMemoryProviderPlugin UI component to 
 ensure that it correctly remembers the last choice of delimiter type (and to 
 encode the data source URI using Qurl)

Then it would be also great to have the possibility to set CRS in the GUI...


 One thing I haven't done is to modify the handling of datasourceUri in 
 QgsVectorLayer to ensure that it always uses the datasourceUri from the 
 provider, rather than storing its own version when the layer is created (or 
 the provider is reset).  I'm not sure how safe this would be - that is 
 whether all the data providers correctly handle the datasourceUri() function. 
  I think this would be the right thing to do though - I think that the 
 provider should be responsible for its own URI.  Any comments on the wisdom 
 of changing this would be welcome!

Currently I don't really like this idea. It's not usual that data
source URI would change inside the provider, so I would be happy to
keep the current situation. Developers can be advised to use the new
syntax (after all it's less verbose) and we have no problems.

Regards
Martin
___
Qgis-developer mailing list
Qgis-developer@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/qgis-developer


RE: [Qgis-developer] Cleanly create memory layer in Python?

2011-01-19 Thread Chris Crook
Hi Martin

On the choice of memory?geometry=point... Vs point?.., at the moment both are 
supported.  

I guess I lean towards the memory?geometry=... because I think it better 
follows the natural understanding of a url, in that the path defines the 
location, and the query string defines attributes.  That said, memory is 
perhaps more properly the authority part of a URL (ie memory://?geometry=point)!

One other point in favour of encoding the geometry type in the query string is 
that (in principle) the path component of the Url could be tampered with by the 
code for handling absolute/relative paths when the project is saved/reloaded, 
whereas the query string should not be.

I'm not strongly attached to either alternative.

On using the provider datasourceUri() rather than caching this in 
QgsVectorLayer().  It seems to me more logical that the provider owns the Uri 
by which it can be recreated, and which it understands.  The QgsVectorLayer has 
no understanding of the Uri - it just passes it through to the provider, so why 
should it assume it will not change.

In terms of the memory layer URI, even if the layer was set up with the new Uri 
format, including fields etc, it will not include fields a user may have added 
or removed manually after creating the layer.   

On setting the delimited text CRS in the plugin user interface.  I chose not to 
mainly out of laziness/other priorities!  Of course the CRS can still be set 
through the interface, at least for the layer (rather than the provider).  It 
remains an option for future implementation :-) 

Cheers
Chris


-Original Message-
From: Martin Dobias [mailto:wonder...@gmail.com] 
Sent: Thursday, 20 January 2011 8:51 a.m.
To: Chris Crook
Cc: qgis-developer@lists.osgeo.org
Subject: Re: [Qgis-developer] Cleanly create memory layer in Python?

Hi Chris

On Mon, Jan 17, 2011 at 10:00 PM, Chris Crook ccr...@linz.govt.nz wrote:
 I've added submitted a patch to implement this change at 
 http://trac.osgeo.org/qgis/ticket/3414.

 Changes made are:

 * QgsCoordinateReferenceSystem? string constructor has been 
 generalised to allow string formats
   epsg:1234
   postgis:1234
   internal:1234
   proj4:proj_4_string
   wkt:wkt_string
   wkt_string
 This is implemented by a createFromString function, similar to the 
 createFromId function

Looks good!


 * Changed QgsMemoryProvider URI format to:
   
 memory?geometry=Pointindex=yescrs=epsg:1234field=id:integerfield=n
 ame:string(25)

I would probably prefer to have uri point? instead of 
memory?geometry=point... since the fact that we are using memory provider is 
given as another parameter to the vector layer constructor, so in future we 
would save some typing ;-)


 The URI can contain the following items:
   
 geometry=Point|LineString|Polygon|MultiPoint|MultiLineString|MultiPoly
 gon
   index=yes  - creates a spatial index
   crs=...    - defines the CRS in one of the formats above
   field=definition - defines an attribute field.

 The field definition is a field name, optionally followed by 
 :type(length,precision), where type is one of integer, int, real, 
 double, and string (int/integer are synonyms, as are real/double).  Eg
   field=magnitude:real(16,2)
   field=owner:string(64)
   field=owner

 This uses Qurl for encoding and decoding the strings.  To provide 
 backwards compatibility, if there is no geometry query string field, 
 then the path is taken as the geometry type.  For example
   point
   point?crs=epsg:1234

Good.


 * Added an option crs= to the QgsDelimitedTextProvider URI, so that 
 plugin code can specify the CRS when creating a delimited text layer.  The 
 crs can be any of the formats listed above. Also updated the provider to use 
 Qurl for encoding and decoding the URI, to ensure consistent handling of 
 special characters.

 * Made a couple of small fixes to the QgsMemoryProviderPlugin UI 
 component to ensure that it correctly remembers the last choice of 
 delimiter type (and to encode the data source URI using Qurl)

Then it would be also great to have the possibility to set CRS in the GUI...


 One thing I haven't done is to modify the handling of datasourceUri in 
 QgsVectorLayer to ensure that it always uses the datasourceUri from the 
 provider, rather than storing its own version when the layer is created (or 
 the provider is reset).  I'm not sure how safe this would be - that is 
 whether all the data providers correctly handle the datasourceUri() function. 
  I think this would be the right thing to do though - I think that the 
 provider should be responsible for its own URI.  Any comments on the wisdom 
 of changing this would be welcome!

Currently I don't really like this idea. It's not usual that data source URI 
would change inside the provider, so I would be happy to keep the current 
situation. Developers can be advised to use the new syntax (after all it's less 
verbose) and we have no problems.

Regards
Martin

RE: [Qgis-developer] Cleanly create memory layer in Python?

2011-01-17 Thread Chris Crook
I've added submitted a patch to implement this change at 
http://trac.osgeo.org/qgis/ticket/3414.

Changes made are:

* QgsCoordinateReferenceSystem? string constructor has been generalised to 
allow string formats
   epsg:1234
   postgis:1234
   internal:1234
   proj4:proj_4_string
   wkt:wkt_string
   wkt_string
This is implemented by a createFromString function, similar to the createFromId 
function

* Changed QgsMemoryProvider URI format to:
   
memory?geometry=Pointindex=yescrs=epsg:1234field=id:integerfield=name:string(25)

The URI can contain the following items:
   geometry=Point|LineString|Polygon|MultiPoint|MultiLineString|MultiPolygon
   index=yes  - creates a spatial index
   crs=...- defines the CRS in one of the formats above
   field=definition - defines an attribute field.

The field definition is a field name, optionally followed by 
:type(length,precision), where type is one of integer, int, real, double, and 
string (int/integer are synonyms, as are real/double).  Eg
   field=magnitude:real(16,2)
   field=owner:string(64)
   field=owner

This uses Qurl for encoding and decoding the strings.  To provide backwards 
compatibility, if there is no geometry query string field, then the path is 
taken as the geometry type.  For example
   point
   point?crs=epsg:1234

* Added an option crs= to the QgsDelimitedTextProvider URI, so that plugin 
code can specify the CRS when creating a delimited text layer.  The crs can be 
any of the formats listed above. Also updated the provider to use Qurl for 
encoding and decoding the URI, to ensure consistent handling of special 
characters.

* Made a couple of small fixes to the QgsMemoryProviderPlugin UI component to 
ensure that it correctly remembers the last choice of delimiter type (and to 
encode the data source URI using Qurl)


One thing I haven't done is to modify the handling of datasourceUri in 
QgsVectorLayer to ensure that it always uses the datasourceUri from the 
provider, rather than storing its own version when the layer is created (or the 
provider is reset).  I'm not sure how safe this would be - that is whether all 
the data providers correctly handle the datasourceUri() function.  I think this 
would be the right thing to do though - I think that the provider should be 
responsible for its own URI.  Any comments on the wisdom of changing this would 
be welcome!

Cheers
Chris

-Original Message-
From: Martin Dobias [mailto:wonder...@gmail.com] 
Sent: Saturday, 8 January 2011 7:06 a.m.
To: Chris Crook
Cc: qgis-developer@lists.osgeo.org
Subject: Re: [Qgis-developer] Cleanly create memory layer in Python?

On Thu, Jan 6, 2011 at 9:16 PM, Chris Crook ccr...@linz.govt.nz wrote:
 Hi All

 I'm wanting to create a memory provider in Python without invoking the CRS 
 selection dialog (even if the QGIS settings are set to Prompt for CRS when a 
 new layer is created.

 At the moment my code looks like:

        settings = QSettings()
        prjSetting = settings.value(/Projections/defaultBehaviour)
        settings.setValue(/Projections/defaultBehaviour, 
 QVariant())
        layer = QgsVectorLayer(point,name,memory)
        if prjSetting:
            
 settings.setValue(/Projections/defaultBehaviour,prjSetting)

 This does work, but it seems a bit cumbersome (at first glance it doesn't 
 even look like creating a vector layer!), so I'm wondering if there is a 
 cleaner approach..

Hi Chris

I agree this is cumbersome. A possible solution would be to extend the URI for 
memory provider - currently it accepts only a string with geometry type. New 
syntax could be introduced that would explicitly set layer CRS, e.g. 
geometry=pointcrs=4326. Any thoughts and patches are welcome.

Regards
Martin
__

This message contains information, which is confidential and may be subject to 
legal privilege. 
If you are not the intended recipient, you must not peruse, use, disseminate, 
distribute or copy this message.
If you have received this message in error, please notify us immediately (Phone 
0800 665 463 or i...@linz.govt.nz) and destroy the original message.
LINZ accepts no responsibility for changes to this email, or for any 
attachments, after its transmission from LINZ.

Thank you.
__
___
Qgis-developer mailing list
Qgis-developer@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/qgis-developer


RE: [Qgis-developer] Cleanly create memory layer in Python?

2011-01-09 Thread Chris Crook
Hi Martin and list readers

I'm experimenting with using a Url format very similar to what Martin 
suggested.  I'm thinking that this could include the Crs, the list of fields, 
and the creation of a spatial index. I'm thinking that a Url of the form:

memory?geometry=pointcrs=1234index=yesfield=integer:idfield=string:name ...

The crs can be a simple srid, epsg:id, or (possibly) a proj4 text string.

The path component of this is redundant of course - it could be anything.  To 
retain backward compatibility though if there is no geometry query field, then 
the query path will be used.  So the format could be 

point?crs=1234index=yes...

Including the index in the URI is useful for me (for the MemoryLayerSaver 
plugin), as it restores that when the layer is recreated when a project is 
reopened.

I'm not so sure about whether to include the field definitions.  And if I do, 
I'm not sure about the best way to encode them, and whether to include length 
and precision fields.  It would probably be more conventional to use something 
like name:type:length:precision for each field?  Any thoughts.

Finally, I'd like to override the dataSourceUri() function to return a 
definition reflecting the current state of the provider (ie index, fields, 
etc).  This is potentially breaking to plugin code if it uses this to determine 
the geometry type, not that there is any reason to do so.  

Cheers
Chris

-Original Message-
From: Martin Dobias [mailto:wonder...@gmail.com] 
Sent: Saturday, 8 January 2011 7:06 a.m.
To: Chris Crook
Cc: qgis-developer@lists.osgeo.org
Subject: Re: [Qgis-developer] Cleanly create memory layer in Python?

On Thu, Jan 6, 2011 at 9:16 PM, Chris Crook ccr...@linz.govt.nz wrote:
 Hi All

 I'm wanting to create a memory provider in Python without invoking the CRS 
 selection dialog (even if the QGIS settings are set to Prompt for CRS when a 
 new layer is created.

 At the moment my code looks like:

        settings = QSettings()
        prjSetting = settings.value(/Projections/defaultBehaviour)
        settings.setValue(/Projections/defaultBehaviour, 
 QVariant())
        layer = QgsVectorLayer(point,name,memory)
        if prjSetting:
            
 settings.setValue(/Projections/defaultBehaviour,prjSetting)

 This does work, but it seems a bit cumbersome (at first glance it doesn't 
 even look like creating a vector layer!), so I'm wondering if there is a 
 cleaner approach..

Hi Chris

I agree this is cumbersome. A possible solution would be to extend the URI for 
memory provider - currently it accepts only a string with geometry type. New 
syntax could be introduced that would explicitly set layer CRS, e.g. 
geometry=pointcrs=4326. Any thoughts and patches are welcome.

Regards
Martin
__

This message contains information, which is confidential and may be subject to 
legal privilege. 
If you are not the intended recipient, you must not peruse, use, disseminate, 
distribute or copy this message.
If you have received this message in error, please notify us immediately (Phone 
0800 665 463 or i...@linz.govt.nz) and destroy the original message.
LINZ accepts no responsibility for changes to this email, or for any 
attachments, after its transmission from LINZ.

Thank you.
__
___
Qgis-developer mailing list
Qgis-developer@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/qgis-developer


RE: [Qgis-developer] Cleanly create memory layer in Python?

2011-01-09 Thread Chris Crook
Looks like one of my ideas below won't work.  I was hoping that I could 
over-ride the QgsDataProvider.dataSourceUri() function to update the Uri as the 
provider was modified (such as adding an index).  

However I think that this function is only referenced when the provider is set 
up (ie QgsVectorLayer.setDataProvider() and QgsVectorLayer.setSubString()), 
which means any other provider initiated changes don't get reflected back to 
the QgsVectorLayer :-(

For some providers (osm, postgres) the dataSourceUri() function is used to 
reset the data source when the provider is first assigned to the layer, but not 
thereafter.

I'm wondering why the QgsDataProvider.dataSourceUri() function isn't used 
whenever the Uri is needed - as it seems to me it belongs very much to the 
provider and not to the layer?

Would it make sense to replace references to QgsMapLayer.mDataSource with calls 
to QgsMapLayer.dataSourceUri(), and to have that use the provider 
dataSourceUri() function unless the provider was not defined.

Cheers
Chris

-Original Message-
From: Chris Crook 
Sent: Monday, 10 January 2011 8:51 a.m.
To: 'Martin Dobias'
Cc: qgis-developer@lists.osgeo.org
Subject: RE: [Qgis-developer] Cleanly create memory layer in Python?

Hi Martin and list readers

I'm experimenting with using a Url format very similar to what Martin 
suggested.  I'm thinking that this could include the Crs, the list of fields, 
and the creation of a spatial index. I'm thinking that a Url of the form:

memory?geometry=pointcrs=1234index=yesfield=integer:idfield=string:name ...

The crs can be a simple srid, epsg:id, or (possibly) a proj4 text string.

The path component of this is redundant of course - it could be anything.  To 
retain backward compatibility though if there is no geometry query field, then 
the query path will be used.  So the format could be 

point?crs=1234index=yes...

Including the index in the URI is useful for me (for the MemoryLayerSaver 
plugin), as it restores that when the layer is recreated when a project is 
reopened.

I'm not so sure about whether to include the field definitions.  And if I do, 
I'm not sure about the best way to encode them, and whether to include length 
and precision fields.  It would probably be more conventional to use something 
like name:type:length:precision for each field?  Any thoughts.

Finally, I'd like to override the dataSourceUri() function to return a 
definition reflecting the current state of the provider (ie index, fields, 
etc).  This is potentially breaking to plugin code if it uses this to determine 
the geometry type, not that there is any reason to do so.  

Cheers
Chris

-Original Message-
From: Martin Dobias [mailto:wonder...@gmail.com]
Sent: Saturday, 8 January 2011 7:06 a.m.
To: Chris Crook
Cc: qgis-developer@lists.osgeo.org
Subject: Re: [Qgis-developer] Cleanly create memory layer in Python?

On Thu, Jan 6, 2011 at 9:16 PM, Chris Crook ccr...@linz.govt.nz wrote:
 Hi All

 I'm wanting to create a memory provider in Python without invoking the CRS 
 selection dialog (even if the QGIS settings are set to Prompt for CRS when a 
 new layer is created.

 At the moment my code looks like:

        settings = QSettings()
        prjSetting = settings.value(/Projections/defaultBehaviour)
        settings.setValue(/Projections/defaultBehaviour,
 QVariant())
        layer = QgsVectorLayer(point,name,memory)
        if prjSetting:
            
 settings.setValue(/Projections/defaultBehaviour,prjSetting)

 This does work, but it seems a bit cumbersome (at first glance it doesn't 
 even look like creating a vector layer!), so I'm wondering if there is a 
 cleaner approach..

Hi Chris

I agree this is cumbersome. A possible solution would be to extend the URI for 
memory provider - currently it accepts only a string with geometry type. New 
syntax could be introduced that would explicitly set layer CRS, e.g. 
geometry=pointcrs=4326. Any thoughts and patches are welcome.

Regards
Martin
__

This message contains information, which is confidential and may be subject to 
legal privilege. 
If you are not the intended recipient, you must not peruse, use, disseminate, 
distribute or copy this message.
If you have received this message in error, please notify us immediately (Phone 
0800 665 463 or i...@linz.govt.nz) and destroy the original message.
LINZ accepts no responsibility for changes to this email, or for any 
attachments, after its transmission from LINZ.

Thank you.
__
___
Qgis-developer mailing list
Qgis-developer@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/qgis-developer


Re: [Qgis-developer] Cleanly create memory layer in Python?

2011-01-07 Thread Martin Dobias
On Thu, Jan 6, 2011 at 9:16 PM, Chris Crook ccr...@linz.govt.nz wrote:
 Hi All

 I'm wanting to create a memory provider in Python without invoking the CRS 
 selection dialog (even if the QGIS settings are set to Prompt for CRS when a 
 new layer is created.

 At the moment my code looks like:

        settings = QSettings()
        prjSetting = settings.value(/Projections/defaultBehaviour)
        settings.setValue(/Projections/defaultBehaviour, QVariant())
        layer = QgsVectorLayer(point,name,memory)
        if prjSetting:
            settings.setValue(/Projections/defaultBehaviour,prjSetting)

 This does work, but it seems a bit cumbersome (at first glance it doesn't 
 even look like creating a vector layer!), so I'm wondering if there is a 
 cleaner approach..

Hi Chris

I agree this is cumbersome. A possible solution would be to extend the
URI for memory provider - currently it accepts only a string with
geometry type. New syntax could be introduced that would explicitly
set layer CRS, e.g. geometry=pointcrs=4326. Any thoughts and
patches are welcome.

Regards
Martin
___
Qgis-developer mailing list
Qgis-developer@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/qgis-developer


Re: [Qgis-developer] Cleanly create memory layer in Python?

2011-01-06 Thread Ricardo Filipe Soares Garcia da
Hi Chris

In the 'Profile from lines' plugin I'm using a similar approach:

# python code
projectionSettingKey = Projections/defaultBehaviour
oldProjectionSetting = self.qgisSettings.value(projectionSettingKey)
self.qgisSettings.setValue(projectionSettingKey, useGlobal)
self.qgisSettings.sync()
pointLayer = QgsVectorLayer(Point, temporary_points, memory)
pointLayer.setCrs(linesLayer.crs())
self.qgisSettings.setValue(projectionSettingKey, oldProjectionSetting)

This was discussed a while back at another thread in this mailing-list
(08/09/2010) and this was a suggestion from Martin Dobias. It seems at
the moment it is as clean as it gets (its still a bit unclean though
;))

I'd also be interested in knowing alternative ways to do this.


On Thu, Jan 6, 2011 at 8:16 PM, Chris Crook ccr...@linz.govt.nz wrote:
 Hi All

 I'm wanting to create a memory provider in Python without invoking the CRS 
 selection dialog (even if the QGIS settings are set to Prompt for CRS when a 
 new layer is created.

 At the moment my code looks like:

        settings = QSettings()
        prjSetting = settings.value(/Projections/defaultBehaviour)
        settings.setValue(/Projections/defaultBehaviour, QVariant())
        layer = QgsVectorLayer(point,name,memory)
        if prjSetting:
            settings.setValue(/Projections/defaultBehaviour,prjSetting)

 This does work, but it seems a bit cumbersome (at first glance it doesn't 
 even look like creating a vector layer!), so I'm wondering if there is a 
 cleaner approach..

 Cheers
 Chris
 __

 This message contains information, which is confidential and may be subject 
 to legal privilege.
 If you are not the intended recipient, you must not peruse, use, disseminate, 
 distribute or copy this message.
 If you have received this message in error, please notify us immediately 
 (Phone 0800 665 463 or i...@linz.govt.nz) and destroy the original message.
 LINZ accepts no responsibility for changes to this email, or for any 
 attachments, after its transmission from LINZ.

 Thank you.
 __
 ___
 Qgis-developer mailing list
 Qgis-developer@lists.osgeo.org
 http://lists.osgeo.org/mailman/listinfo/qgis-developer




-- 
___ ___ __
Ricardo Garcia Silva
___
Qgis-developer mailing list
Qgis-developer@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/qgis-developer