Mittwoch, 31. Oktober 2012

Basics: Setting a custom symbology for QGIS-layers

So you want to use a custom symbology for your layers and achieve that through Python.

Let me tell you first: The easy way is the WRONG way!
Because QGIS crashes with a "Win32RuntimeException" if you try the easy way.
So DON'T GO THERE and brace yourself for a detour!

Instead of creating a new Symbol, which contains all the fancy SymbologyLayers with your amazing Arrowheads for PolyLines and whatnot, you create just your beautiful SymbologyLayers and add it to the pre-existing Symbol.

This example shows a function which you can use to set a symbologystyle for a PolyLine-Layer with two styles to choose from: Awesome Arrowheads for your lines, or ugly dots.



 # adds a LineLayerStyle (Arrow, dotted)  
   def setLineLayerStyle(self, layer, style):  
     if(style == "arrow"):  
       sl = QgsSymbolLayerV2Registry.instance().symbolLayerMetadata("LineDecoration").createSymbolLayer({ 'width' : '0.26', 'color' : '0,0,0' })  
       symbollist = layer.rendererV2().symbols()  
       symbol = symbollist[0]  
       symbol.appendSymbolLayer(sl)  
     elif(style == "dotted"):  
       sl = QgsSymbolLayerV2Registry.instance().symbolLayerMetadata("MarkerLine").createSymbolLayer({ 'width' : '0.26', 'color' : '0,0,0' })  
       symbollist = layer.rendererV2().symbols()  
       symbol = symbollist[0]  
       symbol.appendSymbolLayer(sl)  
 self.canvas.refresh()  

Done.

What can i use instead of bloody arrows or dots you ask?! Read the pyqgis-cookbook or something.

or don't....because you wouldn't find it there in the first place.

Basics: Automatic use of a CRS for new layers

You are creating your own layers in QGIS through Python? Good job.

But everytime you do that QGIS punches you in the face with a prompt to select the coordinate-reference-system you want for the new layer.


To get rid of all that you need tell QGIS that you don't want that...easy right.

First you create a settings-variable. And because QGIS ist awesome you just use the PyQt4-Class QSettings. Then you set the value of "/Projections/defaultBehaviour" to whatever you need. There are three possibilities:
  • "useGlobal" (use a preset CRS everytime)
  • "useProject" (use the Project-CRS)
  • "prompt" (use the stupid prompt thingy)
 'set new Layers to use the Project-CRS'  
 def enableUseOfGlobalCrs(self):  
     self.s = QSettings()  
     self.oldValidation = self.s.value("/Projections/defaultBehaviour").toString()
     self.s.setValue( "/Projections/defaultBehaviour", "useProject" )  

 'enable old settings again' 
 def disableUseOfGlobalCrs(self):  
     self.s.setValue( "/Projections/defaultBehaviour", self.oldValidation )  

Done.

Basics: Creating a new layer in QGIS with Python

You want to create a new layer out of python programmatically...no worries.

Just create a new layerobject like this:

 from qgis.core import QgsVectorLayer, QgsField, QgsMapLayerRegistry  
 from PyQt4.QtCore import QVariant  

 'create Layer'  
 self.lineLayer = QgsVectorLayer("LineString", name, "memory")   

LineString is the type of layer you want to create. (e.g. Point, LineString or Polygon)
name is obviously the displayed name of the layer.
memory is the storagetype. it is just an unsaved memorylayer in this example.

After that you need to specifiy the layerattributes. (if you want to)
To do that you have to get the dataprovider of the layer and set it to "editable" to add the attributes you want the included features to have. To commit your changes to the attributetable use the commitChanges()-Function of the QgsVectorLayer.

 'set Attributes' 
 self.lineLayer.startEditing()  
 self.layerData = self.lineLayer.dataProvider() 
 self.layerData.addAttributes([ QgsField("ID", QVariant.String), QgsField("latStart", QVariant.String), QgsField("lonStart", QVariant.String), QgsField("latEnd", QVariant.String), QgsField("lonEnd", QVariant.String) ])#
 self.lineLayer.commitChanges()

Now the fresh layer needs to be added to the MapLayerRegistry within QGIS so it is out there for the world to see.

 'show Layer in QGIS'  
 QgsMapLayerRegistry.instance().addMapLayer(self.lineLayer)  

Done.