11

How can I define the CRS for a memory layer from the QGIS project settings?

vpoi = QgsVectorLayer("Point", "vectpoi", "memory")
feature = QgsFeature()
feature.setGeometry(QgsGeometry.fromPoint(QgsPoint(10,10)))
provider = vpoly.dataProvider()
...

And how can I define the CRS from another loaded layer?

Taras
  • 32,823
  • 4
  • 66
  • 137
dassau
  • 387
  • 3
  • 11

3 Answers3

11

The QGIS API docs state

Memory data providerType (memory)

The memory data provider is used to construct in memory data, for example scratch data or data generated from spatial operations such as contouring. There is no inherent persistent storage of the data. The data source uri is constructed. The url specifies the geometry type ("point", "linestring", "polygon", "multipoint","multilinestring","multipolygon"), optionally followed by url parameters as follows:

crs=definition Defines the coordinate reference system to use for the layer. definition is any string accepted by QgsCoordinateReferenceSystem::createFromString()

index=yes Specifies that the layer will be constructed with a spatial index

field=name:type(length,precision) Defines an attribute of the layer. Multiple field parameters can be added to the data provider definition. type is one of "integer", "double", "string".

An example url is "Point?crs=epsg:4326&field=id:integer&field=name:string(20)&index=yes"

So I guess it's

crs = votherpoly.crs().toWkt() # could also use .authid() instead of .toWkt()
vpoi = QgsVectorLayer("Point?crs=" + crs, "vectpoi", "memory")
feature = QgsFeature()
feature.setGeometry(QgsGeometry.fromPoint(QgsPoint(10,10)))
provider = vpoly.dataProvider()
...
Taras
  • 32,823
  • 4
  • 66
  • 137
Matthias Kuhn
  • 27,780
  • 3
  • 88
  • 129
  • 1
    BTW. I also tested with QGIS 1.8 but that doesn't seem to work. e.g. vpoi = QgsVectorLayer("Point?crs=epsg:4326", "vectpoi", "memory") seems to be unrecognized. Although it is described here: http://www.qgis.org/pyqgis-cookbook/vector.html#memory-provider. – dassau Aug 30 '13 at 09:37
  • 1
    Passing the CRS as WKT may not be safe if the definition includes an ampersand (e.g. EPSG:32161). It's a fairly niche case, but for this reason I'd say it is preferable to pass the .authid() instead. However, the memory provider doesn't seem to recognise authids from user defined projections (i.e. those with a USER: prefix). – Snorfalorpagus Oct 31 '13 at 13:53
8

An alternate approach to that suggested by @MatthiasKuhn is to create the memory layer, then set the layer projection afterwards.

vpoi = QgsVectorLayer("Point?crs=EPSG:4326", "vectpoi", "memory") # create memory layer in WGS84
vpoi.setCrs(votherpoly.crs()) # change the coordinate reference system

If you don't specify any CRS initially (i.e. no "crs=") QGIS displays a warning to the user. This code creates a new memory layer using the WGS84 CRS, then changes the it to match the CRS from votherpoly. This avoids passing the CRS through the memory layer URI, which can have issues with some coordinate systems (such as those with an '&' in the name).

Taras
  • 32,823
  • 4
  • 66
  • 137
Snorfalorpagus
  • 4,934
  • 3
  • 34
  • 51
5

This works well for me:

vl = QgsVectorLayer()
crs = vl.crs()
crs.createFromId(4326)
vl.setCrs(crs)

crs() method of the Vector layer returns QgsCoordinateReferenceSystem (you can use alternatively class constructor. Like this:

QgsCoordinateReferenceSystem()

QgsCoordinateReferenceSystem has method to create crs from Id (alternatively you can use methods for create CRS from PostGIS database, or some definitions of crs like wkt, or proj4).

On last line I set created SRS to my layer.

Taras
  • 32,823
  • 4
  • 66
  • 137
Jelen
  • 191
  • 1
  • 3
  • Welcome to gis.stackexchange! Please note that a good question is expected to provide a bit more detail than just code lines. Please explain your approach. – underdark Dec 06 '15 at 17:30