Related Plugins and Tags

QGIS Planet

What are all these QGIS file types? Why do I need them

After I added the new QGIS Layer Definition feature in QGIS I have noticed some indirect feedback regarding its use. I thought I would do this post in order to clear things up regarding the new feature so that we are all on the same page.

Some of this feedback, or I could say confusion, was mainly "Why not use the qml format?" or "How is it different from a project file". I can understand this confusion because they do kind of look and act the same however they are a little different.

I'm going to work my way up from the bottom up in terms of file levels and their use.

The QML file (.qml)

It contains: Style information

The QML (.qml) file in QGIS is a style file. It contains an export of the style information, including labels, from a layer. The .qml file however has no reference to the layer. This means I can share a .qml file with you and you can apply it to your own data without needing the data I exported it from. QML files are handy if you have one, or more, layers but have a collection of different style that you want to apply to them.

Style files can only be only be applied to a layer once it is opened. The recent Ordance Survey release of styles is a prefect QML use case.

The Layer Definition file (.qlr)

It contains: Layer source pointer + Style information

This newest feature, also in plugin form for 2.0 and 2.2, is a Layer Definition file. This file contains the reference - or pointer - to the data source plus any style information. This is like a the ArcGIS .lyr file, although maybe not as fully feature rich just yet. The use case for this file is simple: To have a single file to can open a data source bringing in all the related style information. These files also allow you to mask the underlying datasource in a easy to open file.

One of my use cases is to open MS SQL layers. Rather then having to go to the MS SQL connection dialog, connect, select and load, then style. I can simply add a .qlr file that points to the correct MS SQL layer pre styled.

In the future a .qlr file may hold a reference to more then one layer. The Ordance Survey or Natural Earth stuff could also be done with a QLR in order too allow just opening a single file.

The Project file (.qgs)

It contains: Layer source pointer + Style information + Composers + a whole heap of other stuff

The Project file is the highest level file that QGIS has. This holds more then just a list of layers, it also holds order, groups, composers, marcos, etc. I don't really need to explain any of this because you already know.

Why not just extend QML (style file) or QGS (project file)?

In software development we have this thing called SRP (Single Responsibility Principle), and while it can be tricky to follow at times I think it can also apply in cases like this. Sometimes have a single file meaning many different things can be worse then having a many different files with one use case each.

Could I have extended QML to support datasource too? Sure. Easy. However I don't think it made any sense. The use case of the QML is to store only the style and to be applied after the layer is loaded. Who says I have the datasource you used in the first place? In this case the QML is the most portable format because it doesn't point to a data source. I could have just stored the layer reference and ignored it in the normal places we import QML, yes but now you start to muddy the water on what a QML is. If your answer to "What is a QML file?" is "Well sometimes it opens a layer, and sometimes it's just the style" that to me is a smell.

The project file stores a lot of different things and I could have used that as a base, but again I think it starts to muddy the waters. The project file also contains a lot of other things that we just don't need, composers, etc. I have started working on a Import from Project function, just like the plugin of the same function, however I don't think this process is a smooth as using something like a QLR file to bring in layers. Giving someone a full project just so then can import a single layer from it feels like giving someone a full toolbox when all they want is a screwdriver. Just give me the screwdriver, I don't care for the other stuff.

What are all these QGIS file types? Why do I need them

After I added the new QGIS Layer Definition feature in QGIS I have noticed some indirect feedback regarding its use. I thought I would do this post in order to clear things up regarding the new feature so that we are all on the same page.

Some of this feedback, or I could say confusion, was mainly "Why not use the qml format?" or "How is it different from a project file". I can understand this confusion because they do kind of look and act the same however they are a little different.

I'm going to work my way up from the bottom up in terms of file levels and their use.

The QML file (.qml)

It contains: Style information

The QML (.qml) file in QGIS is a style file. It contains an export of the style information, including labels, from a layer. The .qml file however has no reference to the layer. This means I can share a .qml file with you and you can apply it to your own data without needing the data I exported it from. QML files are handy if you have one, or more, layers but have a collection of different style that you want to apply to them.

Style files can only be only be applied to a layer once it is opened. The recent Ordance Survey release of styles is a prefect QML use case.

The Layer Definition file (.qlr)

It contains: Layer source pointer + Style information

This newest feature, also in plugin form for 2.0 and 2.2, is a Layer Definition file. This file contains the reference - or pointer - to the data source plus any style information. This is like a the ArcGIS .lyr file, although maybe not as fully feature rich just yet. The use case for this file is simple: To have a single file to can open a data source bringing in all the related style information. These files also allow you to mask the underlying datasource in a easy to open file.

One of my use cases is to open MS SQL layers. Rather then having to go to the MS SQL connection dialog, connect, select and load, then style. I can simply add a .qlr file that points to the correct MS SQL layer pre styled.

In the future a .qlr file may hold a reference to more then one layer. The Ordance Survey or Natural Earth stuff could also be done with a QLR in order too allow just opening a single file.

The Project file (.qgs)

It contains: Layer source pointer + Style information + Composers + a whole heap of other stuff

The Project file is the highest level file that QGIS has. This holds more then just a list of layers, it also holds order, groups, composers, marcos, etc. I don't really need to explain any of this because you already know.

Why not just extend QML (style file) or QGS (project file)?

In software development we have this thing called SRP (Single Responsibility Principle), and while it can be tricky to follow at times I think it can also apply in cases like this. Sometimes have a single file meaning many different things can be worse then having a many different files with one use case each.

Could I have extended QML to support datasource too? Sure. Easy. However I don't think it made any sense. The use case of the QML is to store only the style and to be applied after the layer is loaded. Who says I have the datasource you used in the first place? In this case the QML is the most portable format because it doesn't point to a data source. I could have just stored the layer reference and ignored it in the normal places we import QML, yes but now you start to muddy the water on what a QML is. If your answer to "What is a QML file?" is "Well sometimes it opens a layer, and sometimes it's just the style" that to me is a smell.

The project file stores a lot of different things and I could have used that as a base, but again I think it starts to muddy the waters. The project file also contains a lot of other things that we just don't need, composers, etc. I have started working on a Import from Project function, just like the plugin of the same function, however I don't think this process is a smooth as using something like a QLR file to bring in layers. Giving someone a full project just so then can import a single layer from it feels like giving someone a full toolbox when all they want is a screwdriver. Just give me the screwdriver, I don't care for the other stuff.

Waiting for QGIS 2.2: Highlighting current Atlas feature

A new feature coming up in QGIS 2.2 will be the ability to style the current active atlas feature with a different symbol. This also extends to styling other layers based on the current feature geometry. This post is a quick preview of the upcoming 2.2 feature.

When a layer has been enabled for Atlas in the composer two new variables will be created $atlasfeatureid and $atlasgeometry. This are static expression variables so once set they are available anywhere in QGIS. These two new static variables will now be set for each feature when printing using the Atlas feature. This also means we can access them in the rule and label expressions to do some pretty cool styled maps.

Once defined we can then create a rule using the rule based renderer to highlight the active layer. We do this by using the expression $id = $atlasfeatureid. Simply put "Does this feature ID match the current atlas one"

Alt Text

Alt Text

That's pretty cool. The current feature (ID 0) in this case is green and the rest is gray. You will also note another new feature in 2.2 which is the ELSE rule. This rule will run when none of the other rules on it's level have passed or evaluated to true. We can use this ELSE rule to just style everything else as gray.

Why don't we one up this a little and just label the current active one.

Alt Text

Alt Text

You could also use a CASE expression do the same thing CASE WHEN $id = $atlasfeatureid THEN "name" END. Take your pick on which one you like the most.

What if we wanted to just show other layers features that are within the area, maybe we want to style them different if they are within an area, or outside of that area. Lets take a look at styling a tree layer that is only within the current atlas geometry.

We have geometry functions in the expression engine so lets use those here on our street trees layer:

Alt Text

Alt Text

I have nested the rule so that we can style the trees differently based on status but only if they are within the active atlas feature.

Remember this is dynamic so there is going to be a performance hit if you try and run this type of expression on many features. The expressions will run once per feature per map redraw so just be aware of how expensive this can become.

When we render the output to files we get what was expected.

Alt Text

Waiting for QGIS 2.2: Highlighting current Atlas feature

A new feature coming up in QGIS 2.2 will be the ability to style the current active atlas feature with a different symbol. This also extends to styling other layers based on the current feature geometry. This post is a quick preview of the upcoming 2.2 feature.

When a layer has been enabled for Atlas in the composer two new variables will be created $atlasfeatureid and $atlasgeometry. This are static expression variables so once set they are available anywhere in QGIS. These two new static variables will now be set for each feature when printing using the Atlas feature. This also means we can access them in the rule and label expressions to do some pretty cool styled maps.

Once defined we can then create a rule using the rule based renderer to highlight the active layer. We do this by using the expression $id = $atlasfeatureid. Simply put "Does this feature ID match the current atlas one"

Alt Text

Alt Text

That's pretty cool. The current feature (ID 0) in this case is green and the rest is gray. You will also note another new feature in 2.2 which is the ELSE rule. This rule will run when none of the other rules on it's level have passed or evaluated to true. We can use this ELSE rule to just style everything else as gray.

Why don't we one up this a little and just label the current active one.

Alt Text

Alt Text

You could also use a CASE expression do the same thing CASE WHEN $id = $atlasfeatureid THEN "name" END. Take your pick on which one you like the most.

What if we wanted to just show other layers features that are within the area, maybe we want to style them different if they are within an area, or outside of that area. Lets take a look at styling a tree layer that is only within the current atlas geometry.

We have geometry functions in the expression engine so lets use those here on our street trees layer:

Alt Text

Alt Text

I have nested the rule so that we can style the trees differently based on status but only if they are within the active atlas feature.

Remember this is dynamic so there is going to be a performance hit if you try and run this type of expression on many features. The expressions will run once per feature per map redraw so just be aware of how expensive this can become.

When we render the output to files we get what was expected.

Alt Text

The death of your child

Today was Eloise's due date but she has already been and gone. Three weeks now. Sometimes it doesn't feel real - a bad dream that we can't escape from. There is no rewind in life, you can only push forward and try to make things better.

Eloise died at around 8:30am on the 16th of October, just 10 days after being born. Her heart stopped and she passed away in Stacey's arms while we both held her. We knew it was coming, it was just a matter of time. Stace and I had broken sleep that night listening for the alarms and watching her oxygen levels fall to the floor taking longer and longer to come back up. At one stage she was never going to come back and at 8:30am that is what happened. It was expected she would only last a few days and we stayed at the hospital, sleeping beside her, ever day until that morning.

It started about a month before Eloise was born. The ultrasound said she might have T21 (Downs), T18, or T13, and that she had a major heart defect. T21 was the biggest concern, the idea a bit scary, but the feeling of worry passed as we came to peace with the idea that having a Downs child would be fine. Each time Stace panicked I told her not to worry, T18 and T13 have other markers and the risk is so small it couldn't happen to us. Apart from her being small and the heart defect, Eloise looked fine. Surely this just means Downs. Surely it will be fine.

After Eloise was born the doctors told us there was some markers for T18. At this point you try to hide the fear but I'm sure people can see right though. I left Stace at the hospital to come back home for a shower and get some clothes. Once I got to the car the reality of what could happen had started to kick in. You try to be strong but any thoughts of what could happen just break you. I think the half and hour shower was the only good thing about the night, a time just to think without noise or anyone else around.

As the days passed we tired to find excuses for the "markers". Trying to reassure ourself that it's fine. They are just little quirks that she has. I'm sure those tests will come back negative. I'm sure they will. Of course they will.

Due to Eloise being born on a Sunday and the Monday being a public holiday the blood samples didn't get to the lab until late Tuesday. A test that normally only takes three days is now looking like a week return. One of the longest weeks we have ever done. Stace would express and I would run milk down to Eloise's room every three hours - nights not excluded. Doing a little check. Talking to the nurse about how Eloise is doing. Reassuring myself of the markers.

We came to the hospital on Saturday knowing the results would come in. It was D-Day and I had a feeling this wasn't going to end well. We had lunch trying to ignore the gravity of the situation. After lunch the doctor came into our room and closed the door, the tell tale sign that something is wrong. "The tests have come back. I'm sorry the news isn't good. Eloise has T18". Stace fell apart and there is only so long that you can watch your wife before it starts to cut into you and you soon follow. The doctor left us and we cried for about half and hour - or what felt like it. There is nothing else you can do. Your world just started to fall apart and you are powerless against it.

Eloise was put into palliative care. The heart medication was stopped. She was going to die and we just had to watch her. How can you just sit there an watch your child die? The nights were the hardest, they were long and uncomfortable. We didn't want to sleep but knew we had to in order to have the energy the next day. The option was given to switch off the monitors so no alarms would sound if she started to decline. The thought of not being able to hold Eloise as she passed was too much for Stace to bare so we left the alarms on, watching them for any drops. The alarms became more frequent as the days went on; the idea that she was going to die become more real with each time.

It finally came the morning of the 16th. Her heart started to slow and her oxygen dropped. It didn't show any signs of coming back up and we watched her go.

Why couldn't it have just been Downs!?

How do you cope? Well you do and you don't. There are days you are really good and can focus, and then there are days when your brain is just mush. It happens, I doubt it ever goes away maybe you just grow to live with it and push forward. The emotions on the day of the service in the faces of relatives and close friends who have also lost children shows it never really goes away, and as quickly as you forgot the pain it can all come back in an instant.


The most important thing I think in all this is support. Having people that could support us and our family. We are very lucky to have good friends and family who were able to support us though everything, some traveling a long way to attend the service. I am also very thankful to DMS who showed us great support with their thoughts and much much more, more then I could ever ask. To the folks on Twitter and Google+ for letting us know we are in their thoughts. It all helps, even just the small stuff.

We are very grateful for our son, who is too young to understand although I'm sure he knows something is missing. He helps to keep the hopes up on the shit days. The stupid noises, the stupid faces he pulls, all help to take your mind away from the pain and into a happy place. When no one else is around he helps to bind us.

<3 Mummy, Daddy, and big brother

Alt Text

The death of your child

Today was Eloise's due date but she has already been and gone. Three weeks now. Sometimes it doesn't feel real - a bad dream that we can't escape from. There is no rewind in life, you can only push forward and try to make things better.

Eloise died at around 8:30am on the 16th of October, just 10 days after being born. Her heart stopped and she passed away in Stacey's arms while we both held her. We knew it was coming, it was just a matter of time. Stace and I had broken sleep that night listening for the alarms and watching her oxygen levels fall to the floor taking longer and longer to come back up. At one stage she was never going to come back and at 8:30am that is what happened. It was expected she would only last a few days and we stayed at the hospital, sleeping beside her, ever day until that morning.

It started about a month before Eloise was born. The ultrasound said she might have T21 (Downs), T18, or T13, and that she had a major heart defect. T21 was the biggest concern, the idea a bit scary, but the feeling of worry passed as we came to peace with the idea that having a Downs child would be fine. Each time Stace panicked I told her not to worry, T18 and T13 have other markers and the risk is so small it couldn't happen to us. Apart from her being small and the heart defect, Eloise looked fine. Surely this just means Downs. Surely it will be fine.

After Eloise was born the doctors told us there was some markers for T18. At this point you try to hide the fear but I'm sure people can see right though. I left Stace at the hospital to come back home for a shower and get some clothes. Once I got to the car the reality of what could happen had started to kick in. You try to be strong but any thoughts of what could happen just break you. I think the half and hour shower was the only good thing about the night, a time just to think without noise or anyone else around.

As the days passed we tired to find excuses for the "markers". Trying to reassure ourself that it's fine. They are just little quirks that she has. I'm sure those tests will come back negative. I'm sure they will. Of course they will.

Due to Eloise being born on a Sunday and the Monday being a public holiday the blood samples didn't get to the lab until late Tuesday. A test that normally only takes three days is now looking like a week return. One of the longest weeks we have ever done. Stace would express and I would run milk down to Eloise's room every three hours - nights not excluded. Doing a little check. Talking to the nurse about how Eloise is doing. Reassuring myself of the markers.

We came to the hospital on Saturday knowing the results would come in. It was D-Day and I had a feeling this wasn't going to end well. We had lunch trying to ignore the gravity of the situation. After lunch the doctor came into our room and closed the door, the tell tale sign that something is wrong. "The tests have come back. I'm sorry the news isn't good. Eloise has T18". Stace fell apart and there is only so long that you can watch your wife before it starts to cut into you and you soon follow. The doctor left us and we cried for about half and hour - or what felt like it. There is nothing else you can do. Your world just started to fall apart and you are powerless against it.

Eloise was put into palliative care. The heart medication was stopped. She was going to die and we just had to watch her. How can you just sit there an watch your child die? The nights were the hardest, they were long and uncomfortable. We didn't want to sleep but knew we had to in order to have the energy the next day. The option was given to switch off the monitors so no alarms would sound if she started to decline. The thought of not being able to hold Eloise as she passed was too much for Stace to bare so we left the alarms on, watching them for any drops. The alarms became more frequent as the days went on; the idea that she was going to die become more real with each time.

It finally came the morning of the 16th. Her heart started to slow and her oxygen dropped. It didn't show any signs of coming back up and we watched her go.

Why couldn't it have just been Downs!?

How do you cope? Well you do and you don't. There are days you are really good and can focus, and then there are days when your brain is just mush. It happens, I doubt it ever goes away maybe you just grow to live with it and push forward. The emotions on the day of the service in the faces of relatives and close friends who have also lost children shows it never really goes away, and as quickly as you forgot the pain it can all come back in an instant.


The most important thing I think in all this is support. Having people that could support us and our family. We are very lucky to have good friends and family who were able to support us though everything, some traveling a long way to attend the service. I am also very thankful to DMS who showed us great support with their thoughts and much much more, more then I could ever ask. To the folks on Twitter and Google+ for letting us know we are in their thoughts. It all helps, even just the small stuff.

We are very grateful for our son, who is too young to understand although I'm sure he knows something is missing. He helps to keep the hopes up on the shit days. The stupid noises, the stupid faces he pulls, all help to take your mind away from the pain and into a happy place. When no one else is around he helps to bind us.

<3 Mummy, Daddy, and big brother

Alt Text

Hardest day of our life

Last Sunday, the 6th of October, Eloise Woodrow was born by emergency caesarean. We had run into a few speed bumps along the way during the pregnancy so we knew there might be some issues when she was born. They had found she was small for her gestational age and also had a VSD (heart defect), this kind of thing, we didn't find out till later, can be linked to chromosomal issues. The most common issue being Downs Syndrome. There are also two other chromosomal issues, T13 and T18, both which have grim outcomes. It was fine, we told ourselves, we can live with a child with Downs, we have known and been friends with plenty of Downs children it wasn't really a concern. In the end the chance of T13 and T18 is so rare that it isn't going to happen to us. Well it was nice to believe that.

Yesterday our worst fear come true. Eloise has T18. The survival rate for babies with T18 is extremely low, and most don't make it past age one. They don't do the heart operation because of the poor survival rate. This means she has no chance and will die. Maybe in a few days, or weeks, but not months.

As a parent this is not something that we have ever wanted to deal with. Not so soon. Not ever. It's hard enough losing a friend or a relative let alone your own child. Every parent knows they would throw themselves under a bus for their children. If you could take the pain yourself and free them you would. But you can't and that makes it harder.

To the dumb question "Why me?" the cosmos barely bothers to return the reply: why not?

Christopher Hitchens

Not being a believer in any gods, or devine power, sometimes bad things just happen to good people for no reason. Others have to deal with this kind of pain so why not us too. We will get though it. We will try again.

The only solace that I can take from it all is that it's a (mostly) random event that no one could predict or prevent. It's not anyone's fault. Just a bad thing that happened.

For now the only thing we can do is be with her, love her, and make sure she is comfortable.

Mummy, Daddy, and Harry love you baby girl

Alt Text

Hardest day of our life

Last Sunday, the 6th of October, Eloise Woodrow was born by emergency caesarean. We had run into a few speed bumps along the way during the pregnancy so we knew there might be some issues when she was born. They had found she was small for her gestational age and also had a VSD (heart defect), this kind of thing, we didn't find out till later, can be linked to chromosomal issues. The most common issue being Downs Syndrome. There are also two other chromosomal issues, T13 and T18, both which have grim outcomes. It was fine, we told ourselves, we can live with a child with Downs, we have known and been friends with plenty of Downs children it wasn't really a concern. In the end the chance of T13 and T18 is so rare that it isn't going to happen to us. Well it was nice to believe that.

Yesterday our worst fear come true. Eloise has T18. The survival rate for babies with T18 is extremely low, and most don't make it past age one. They don't do the heart operation because of the poor survival rate. This means she has no chance and will die. Maybe in a few days, or weeks, but not months.

As a parent this is not something that we have ever wanted to deal with. Not so soon. Not ever. It's hard enough losing a friend or a relative let alone your own child. Every parent knows they would throw themselves under a bus for their children. If you could take the pain yourself and free them you would. But you can't and that makes it harder.

To the dumb question "Why me?" the cosmos barely bothers to return the reply: why not?

Christopher Hitchens

Not being a believer in any gods, or devine power, sometimes bad things just happen to good people for no reason. Others have to deal with this kind of pain so why not us too. We will get though it. We will try again.

The only solace that I can take from it all is that it's a (mostly) random event that no one could predict or prevent. It's not anyone's fault. Just a bad thing that happened.

For now the only thing we can do is be with her, love her, and make sure she is comfortable.

Mummy, Daddy, and Harry love you baby girl

Alt Text

Death to the message box! Use the QGIS messagebar

The good ol' message box. So easy to use. Yet such as stab in the users user experience metaphorical heart. Nothing like working along and getting a nice dialog to tell you can't do something or that the operation has finished

Alt Text

Alt Text

You might think. "Well there isn't really anything wrong with that. I needed to tell the user everything is done". Sure but what you didn't need to do was stop the user and make them acknowledge it. Consider if your car made you OK something you each time your speed changed.

Alt Text

Alt Text

Alt Text

Pretty annoying.

What is the alternative then?

Introducing the QGIS message bar

Alt Text

Alt Text

Alt Text

If you have been using QGIS 1.9 (the dev version for 2.0) you might have noticed it already. It's a great new way for us to let the user know about something without blocking their work or getting in the way. The best part is your can even access the message bar to post messages from your plugins.

iface.messageBar().pushMessage("Error", "I'm sorry Dave, I'm afraid I can't do that", level=QgsMessageBar.CRITICAL)

Alt Text

It even has timer to show a message for a limited time.

iface.messageBar().pushMessage("Error", "I'm sorry Dave, ..", level=QgsMessageBar.CRITICAL, duration=3)

Alt Text

or showing a button for more info

def showError():
    pass

widget = iface.messageBar().createMessage("Missing Layers", "Show Me")
button = QPushButton(widget)
button.setText("Show Me")
button.pressed.connect(showError)
widget.layout().addWidget(button)
iface.messageBar().pushWidget(widget, QgsMessageBar.WARNING)

Alt Text

In your own widgets

You can even use a message bar in your own dialog so you don't have to show a message box or if it doesn't make sense to show it in the main QGIS window.

class MyDialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.bar = QgsMessageBar()
        self.bar.setSizePolicy( QSizePolicy.Minimum, QSizePolicy.Fixed )
        self.setLayout(QGridLayout())
        self.layout().setContentsMargins(0,0,0,0)
        self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok)
        self.buttonbox.accepted.connect(self.run)
        self.layout().addWidget(self.buttonbox , 0,0,2,1)
        self.layout().addWidget(self.bar, 0,0,1,1)

    def run(self):
        self.bar.pushMessage("Hello", "World", level=QgsMessageBar.INFO)

Alt Text

Don't abuse it

Like anything the message bar can be abused if not careful. Avoid dumping debugging messages to it as this will annoy users rather then help. Use QgsMessageLog.logMessage() if you need to write debugging information. Also consider which messages you post there as posting too many messages will mean the user might just ignore it like they do with message boxes.

Death to the message box! Use the QGIS messagebar

The good ol' message box. So easy to use. Yet such as stab in the users user experience metaphorical heart. Nothing like working along and getting a nice dialog to tell you can't do something or that the operation has finished

Alt Text

Alt Text

You might think. "Well there isn't really anything wrong with that. I needed to tell the user everything is done". Sure but what you didn't need to do was stop the user and make them acknowledge it. Consider if your car made you OK something you each time your speed changed.

Alt Text

Alt Text

Alt Text

Pretty annoying.

What is the alternative then?

Introducing the QGIS message bar

Alt Text

Alt Text

Alt Text

If you have been using QGIS 1.9 (the dev version for 2.0) you might have noticed it already. It's a great new way for us to let the user know about something without blocking their work or getting in the way. The best part is your can even access the message bar to post messages from your plugins.

iface.messageBar().pushMessage("Error", "I'm sorry Dave, I'm afraid I can't do that", level=QgsMessageBar.CRITICAL)

Alt Text

It even has timer to show a message for a limited time.

iface.messageBar().pushMessage("Error", "I'm sorry Dave, ..", level=QgsMessageBar.CRITICAL, duration=3)

Alt Text

or showing a button for more info

def showError():
    pass

widget = iface.messageBar().createMessage("Missing Layers", "Show Me")
button = QPushButton(widget)
button.setText("Show Me")
button.pressed.connect(showError)
widget.layout().addWidget(button)
iface.messageBar().pushWidget(widget, QgsMessageBar.WARNING)

Alt Text

In your own widgets

You can even use a message bar in your own dialog so you don't have to show a message box or if it doesn't make sense to show it in the main QGIS window.

class MyDialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.bar = QgsMessageBar()
        self.bar.setSizePolicy( QSizePolicy.Minimum, QSizePolicy.Fixed )
        self.setLayout(QGridLayout())
        self.layout().setContentsMargins(0,0,0,0)
        self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok)
        self.buttonbox.accepted.connect(self.run)
        self.layout().addWidget(self.buttonbox , 0,0,2,1)
        self.layout().addWidget(self.bar, 0,0,1,1)

    def run(self):
        self.bar.pushMessage("Hello", "World", level=QgsMessageBar.INFO)

Alt Text

Don't abuse it

Like anything the message bar can be abused if not careful. Avoid dumping debugging messages to it as this will annoy users rather then help. Use QgsMessageLog.logMessage() if you need to write debugging information. Also consider which messages you post there as posting too many messages will mean the user might just ignore it like they do with message boxes.

Alpha by Value choropleth in QGIS

This post was inspired by a post written by Xaquín G.V, some extra credit must also go to Mathieu for helping me with the expression.

One of the new great features in the upcoming QGIS 2.0 is the ability to use data defined symbology and labelling. It might look like nothing on the surface but it can really open up the possibility of some great looking maps.

Lets start with the example Xaquín has used by classifying by the unemployment rate. I have even created a pre-joined dataset for you if you want to follow along, grab it here.

So first lets make a custom colour ramp just for this:

Alt Text

call it "usa" and classify the data

Alt Text

Alt Text

Ok not bad. But you will always have those hard edges on the colours. What if we could get the exact colour ramp value for a given value? Well you can.

We need to make a new column for the colour value for each feature. Open up the field calculator and add a new column with the following expression

ramp_color('usa', scale_linear( "unemployed_by_county_xgv_Rate",0,18,0,1 ))

What are the ramp_colur and scale_linear functions? ramp_colur is a new function that allows you to get a RGBA value for a position inside the ramp. So if you want the RGBA value at the 75% mark you can use ramp_color('usa', 0.75).

Cool but to make it dynamic we need to bring in the value from the "Rate" column, however that goes up higher then 1. How do we get in a range from 0..1? Well we can scale it back down using scale_linear.

scale_linear(<column>,<min in value>,<max in value>,<min out value>,<max out value>) 

Having said all that here is our result:

Alt Text

To use this new colour column we need to use data defined symbols

Alt Text

Note: I have selected Single Symbol

And the result

Alt Text

This isn't going to suit every map but when something is scale based this method works well.

Bumping it up a notch

Higher unemployment rates plus high lobor force really should get more weight. One way to handle this is by using Alpha-By-Value like Xaquín said in his post. Well to do that in QGIS we need to change the alpha value of what is returned from color_ramp. Time for a bit of regex (don't worry in 2.1 I will add a colour_ramp_rgb function with no aplha part)

First lets get just the aplha value part by scaling the lobor force coloum. Add a new column using the following expression

toint(scale_linear("unemployed_by_county_xgv_Labor_Force", 0, 100000, 0, 255))

Alt Text

Now make a new column that replaces the alpha part of the colour column

regexp_replace( "colour", ',[^,]*$' , format(',%1',"alpha" ))

Alt Text

Then we can use data defined symbols on that new column

Alt Text

Nifty!

Now you will have to play with the min and max values for the scaling functions and also the colours in the ramp but you get the idea.

Bonus

You can also use the same colour column on the labels to match the polygon and even increase the label size based on the rate column

Alt Text

So that is your Thursday lesson on how to create a Alpha by value map in the upcoming QGIS 2.0.

Extra stuff

If you want to avoid creating all those extra columns or even do it on the fly you can use this single expression

regexp_replace( ramp_color('usa', scale_linear( "unemployed_by_county_xgv_Rate",0,15,0,1)),',[^,]*$',','|| toint(scale_linear("unemployed_by_county_xgv_Labor_Force",0,100000,0,255)))

Using the single expression block can be handy if you want to get your upper and lower limits right.

Alpha by Value choropleth in QGIS

This post was inspired by a post written by Xaquín G.V, some extra credit must also go to Mathieu for helping me with the expression.

One of the new great features in the upcoming QGIS 2.0 is the ability to use data defined symbology and labelling. It might look like nothing on the surface but it can really open up the possibility of some great looking maps.

Lets start with the example Xaquín has used by classifying by the unemployment rate. I have even created a pre-joined dataset for you if you want to follow along, grab it here.

So first lets make a custom colour ramp just for this:

Alt Text

call it "usa" and classify the data

Alt Text

Alt Text

Ok not bad. But you will always have those hard edges on the colours. What if we could get the exact colour ramp value for a given value? Well you can.

We need to make a new column for the colour value for each feature. Open up the field calculator and add a new column with the following expression

ramp_color('usa', scale_linear( "unemployed_by_county_xgv_Rate",0,18,0,1 ))

What are the ramp_colur and scale_linear functions? ramp_colur is a new function that allows you to get a RGBA value for a position inside the ramp. So if you want the RGBA value at the 75% mark you can use ramp_color('usa', 0.75).

Cool but to make it dynamic we need to bring in the value from the "Rate" column, however that goes up higher then 1. How do we get in a range from 0..1? Well we can scale it back down using scale_linear.

scale_linear(<column>,<min in value>,<max in value>,<min out value>,<max out value>) 

Having said all that here is our result:

Alt Text

To use this new colour column we need to use data defined symbols

Alt Text

Note: I have selected Single Symbol

And the result

Alt Text

This isn't going to suit every map but when something is scale based this method works well.

Bumping it up a notch

Higher unemployment rates plus high lobor force really should get more weight. One way to handle this is by using Alpha-By-Value like Xaquín said in his post. Well to do that in QGIS we need to change the alpha value of what is returned from color_ramp. Time for a bit of regex (don't worry in 2.1 I will add a colour_ramp_rgb function with no aplha part)

First lets get just the aplha value part by scaling the lobor force coloum. Add a new column using the following expression

toint(scale_linear("unemployed_by_county_xgv_Labor_Force", 0, 100000, 0, 255))

Alt Text

Now make a new column that replaces the alpha part of the colour column

regexp_replace( "colour", ',[^,]*$' , format(',%1',"alpha" ))

Alt Text

Then we can use data defined symbols on that new column

Alt Text

Nifty!

Now you will have to play with the min and max values for the scaling functions and also the colours in the ramp but you get the idea.

Bonus

You can also use the same colour column on the labels to match the polygon and even increase the label size based on the rate column

Alt Text

So that is your Thursday lesson on how to create a Alpha by value map in the upcoming QGIS 2.0.

Extra stuff

If you want to avoid creating all those extra columns or even do it on the fly you can use this single expression

regexp_replace( ramp_color('usa', scale_linear( "unemployed_by_county_xgv_Rate",0,15,0,1)),',[^,]*$',','|| toint(scale_linear("unemployed_by_county_xgv_Labor_Force",0,100000,0,255)))

Using the single expression block can be handy if you want to get your upper and lower limits right.

Adding __geo_interface__ to QGIS geometry and feature

What is __geo_interface__ anyway? If you have never seen __geo_interface__ it was defined by Sean Gillies at https://gist.github.com/sgillies/2217756. A cool lightweight interface that describes a single spatial object using a GeoJSON like structure, in fact parts of it are just normal GeoJSON.

Since QGIS in feature freeze at the moment I can't add this to the main code base just yet. Awwww sad face :(

but wait!

Thanks to good ol' Python we can just monkey patch it right on.

def mapping_feature(feature):
    geom = feature.geometry()
    properties = {}
    fields = [field.name() for field in feature.fields()]
    properties = dict(zip(fields, feature.attributes()))
    return { 'type' : 'Feature',
             'properties' : properties,
             'geometry' : geom.__geo_interface__}

def mapping_geometry(geometry):
    geo = geometry.exportToGeoJSON()
    # We have to use eval because exportToGeoJSON() gives us
    # back a string that looks like a dictionary. 
    return eval(geo)

QgsFeature.__geo_interface__ = property(lambda self: mapping_feature(self))
QgsGeometry.__geo_interface__ = property(lambda self: mapping_geometry(self))

And that's that. Easy hey. Really got to love dynamic languages.

The __geo_interface__ property now exists on any instance of QgsGeometry or QgsFeature. Lets test that theory.

>>> import pprint
>>> layer = iface.activeLayer()
>>> feature = layer.selectedFeatures()[0]
>>> feature.__geo_interface__
>>> pprint.pprint(f.__geo_interface__)
{'geometry': {'coordinates': [[[385039.90567724, 6449154.61878853],
                               [385059.01135993, 6449154.80874077],
                               [385059.41538719, 6449114.58680192],
                               [385040.30145863, 6449114.38685169],
                               [385040.16953133, 6449127.46423076],
                               [385039.90567724, 6449154.61878853]]],
              'type': 'Polygon'},
 'properties': {u'address': u'HYNES WY',
                u'assessment': u'2204315',
                u'bool': u'F',
                u'dola_pin': 283678,
                u'field18': 2920,
                u'field19': 0.0,
                u'house_numb': u'3',
                u'location': None,
                u'lot': u'LOT 107',
                u'new': None,
                u'old': u'http://www.seabreeze.com.au|mylink',
                u'paid_in_fu': u'F',
                u'pin_string': u'283678',
                u'postcode': u'6163',
                u'reserve': None,
                u'sample_dat': u'2003-05-15',
                u'subdivided': None,
                u'suburb': u'HAMILTON HILL',
                u'suburb_wit': u'HAMILTON HILL',
                u'type': u'H',
                u'v_auto_dat': None,
                u'v_auto_use': None,
                u'v_boolean': None,
                u'v_datetime': None,
                u'v_decimal': None,
                u'v_int': None,
                u'v_numeric': None,
                u'v_varcha_1': None,
                u'v_varchar': None,
                u'v_varchar_': None},
 'type': 'Feature'}
>>> feature.geometry().__geo_interface__
{'type': 'Point', 'coordinates': [388197.74503284, 6450504.16670842]}

Excellent!

Adding __geo_interface__ to QGIS geometry and feature

What is __geo_interface__ anyway? If you have never seen __geo_interface__ it was defined by Sean Gillies at https://gist.github.com/sgillies/2217756. A cool lightweight interface that describes a single spatial object using a GeoJSON like structure, in fact parts of it are just normal GeoJSON.

Since QGIS in feature freeze at the moment I can't add this to the main code base just yet. Awwww sad face :(

but wait!

Thanks to good ol' Python we can just monkey patch it right on.

def mapping_feature(feature):
    geom = feature.geometry()
    properties = {}
    fields = [field.name() for field in feature.fields()]
    properties = dict(zip(fields, feature.attributes()))
    return { 'type' : 'Feature',
             'properties' : properties,
             'geometry' : geom.__geo_interface__}

def mapping_geometry(geometry):
    geo = geometry.exportToGeoJSON()
    # We have to use eval because exportToGeoJSON() gives us
    # back a string that looks like a dictionary. 
    return eval(geo)

QgsFeature.__geo_interface__ = property(lambda self: mapping_feature(self))
QgsGeometry.__geo_interface__ = property(lambda self: mapping_geometry(self))

And that's that. Easy hey. Really got to love dynamic languages.

The __geo_interface__ property now exists on any instance of QgsGeometry or QgsFeature. Lets test that theory.

>>> import pprint
>>> layer = iface.activeLayer()
>>> feature = layer.selectedFeatures()[0]
>>> feature.__geo_interface__
>>> pprint.pprint(f.__geo_interface__)
{'geometry': {'coordinates': [[[385039.90567724, 6449154.61878853],
                               [385059.01135993, 6449154.80874077],
                               [385059.41538719, 6449114.58680192],
                               [385040.30145863, 6449114.38685169],
                               [385040.16953133, 6449127.46423076],
                               [385039.90567724, 6449154.61878853]]],
              'type': 'Polygon'},
 'properties': {u'address': u'HYNES WY',
                u'assessment': u'2204315',
                u'bool': u'F',
                u'dola_pin': 283678,
                u'field18': 2920,
                u'field19': 0.0,
                u'house_numb': u'3',
                u'location': None,
                u'lot': u'LOT 107',
                u'new': None,
                u'old': u'http://www.seabreeze.com.au|mylink',
                u'paid_in_fu': u'F',
                u'pin_string': u'283678',
                u'postcode': u'6163',
                u'reserve': None,
                u'sample_dat': u'2003-05-15',
                u'subdivided': None,
                u'suburb': u'HAMILTON HILL',
                u'suburb_wit': u'HAMILTON HILL',
                u'type': u'H',
                u'v_auto_dat': None,
                u'v_auto_use': None,
                u'v_boolean': None,
                u'v_datetime': None,
                u'v_decimal': None,
                u'v_int': None,
                u'v_numeric': None,
                u'v_varcha_1': None,
                u'v_varchar': None,
                u'v_varchar_': None},
 'type': 'Feature'}
>>> feature.geometry().__geo_interface__
{'type': 'Point', 'coordinates': [388197.74503284, 6450504.16670842]}

Excellent!

New QGIS 2.0 API.

QGIS 2.0 has under gone some radical changes for its upcoming release. Some of these major changes relate to the API, both C++ and Python. Something that always comes up when trying to improve an API is the chance that you might have to remove the old way of doing something so that things are cleaner and improved for the future. These changes will always break existing working code and can be a burden for a little while until everything is adjusted. A little pain for a lot of gain is the way I like to think about it. I will also add that breaking API so radically isn't something that we, as developers, like to do or take lightly, but sometimes it has to be done.

This post is a summary of some of the new APIs, what has changed, and what it means to you as a user.

New Vector API (Iterator pattern)

We would like to introduce multithreaded rendering in the future and the old API for getting a set of features from the provider wasn't going to cut it in a multithreaded environment. In order to allow something that will be more threadable then the old select model we changed to a iterator pattern.

The old used to look like this:

layer.select()
for feature in layer:
    print feature

select() wouldn't return anything rather it would tell the provider of the layer to get ready to return some features when asked e.g the for loop. Want to thread that? Nope. Not going to happen.

The solution:

Create a method that returns an iterator that each thread can loop over on their own without changing the result of the other.

features = layer.getFeatures()
for feature in features:
    print feature

if you look at layer.getFeatures() you can see it returns a QgsFeatureIterator

>>> layer.getFeatures()
<qgis.core.QgsFeatureIterator object at 0x1A05F810>

QgsFeatureIterator has a next() method, just like a normal Python iterator, which you can call to get the next feature, it will just serve them up as you need them.

>>> features = layer.getFeatures()
>>> features.next()
<qgis.core.QgsFeature object at 0x1A062CD8>
>>> features.next()
<qgis.core.QgsFeature object at 0x1A062C48>
>>> features.next()
<qgis.core.QgsFeature object at 0x1A062C00>
>>> features.close()

So in the future (you can't do this yet due to some other restrictions):

>>> features = layer.getFeatures()
>>> features2 = layer.getFeatures()
>>> features.next().id()
1L
>>> features.next().id()
2L
>>> features2.next().id()
1L

Nifty!

New Vector API (Fields)

Something else that changed was how attributes are accessed.

This is the old style:

>>> index = layer.fieldNameIndex("yourcolumn")
>>> feature.attributeMap()[index].toString()
"Hello World"

That is a big pain in the butt just to get a value from a field.

The new method now uses a list of attributes on the feature itself.

>>> feature[5]
"Hello World"
>>> feature["yourcolumn"]
"Hello World"

You can even access them like attributes.

>>> feature.yourcolumn
"Hello World"

Be careful with accessing fields via the attribute magic. If you have a id field feature.id will return the feature id method not the field named id. In fact any method with the same name as any QgsFeature methods will return the method rather then the field value. I like this magic but use it wisely.

SIP API v2

This is the most recent change that has caused all of the 1.8 plugins to no longer work in 2.0. A bit of background: PyQt4 and pyqgis use sip to define their Python API. There are two versions of SIP V1 and V2. Using SIP V1 PyQt, and therefor pyqgis, will take and return QVariant and QString objects in Python.

So:

>>> feature["yourcolumn"]
<PyQt4.QtCore.QVariant object at 0x026AD5E0>

Well that is fine but to get a string value you had to do this:

>>> feature["yourcolumn"].toString()
"Hello World"

but that isn't a normal Python string. It's a QString. QStrings can't be used in normal Python methods so you have to do str(feature["yourcolumn"].toString()). Gross!

With the change to SIP V2 QVariant and QString are now auto converted to native Python types without any extra work.

>>> type(f["Name"])
<type 'unicode'>

Good stuff.

If you are looking for a conversion guide check out: http://hub.qgis.org/wiki/quantum-gis/Python_plugin_API_changes_from_18_to_20

The QGIS plugin repository can house both 1.8 and 2.0 plugins under the same plugin name, and the plugin installer will only download the version compatible with the QGIS version you are using.

The SIP version update was a hard one to make. On one hand we could just leave it the way it was with backwards compatibility and all the messy str(variant.toString()) stuff; OR we can make the switch now while everyone is migrating to the new vector API and have a cleaner API for the future. I picked the later. Once we switch to Python 3 at some stage in the future SIP v2 is the default so it would have broken all the plugins at that point anyway.

I can tell you that I did lose some sleep over if I should push the SIP update or not, wondering what impact it could have on plugin authors and the project in general. In the end I stand by our decision to make the update in QGIS 2.0.

Hopefully these API changes won't cause to much grief for plugin authors and the API is now better to work with.

Fine. But why I do care as a user?

All this means that when QGIS 2.0 comes out you may be missing some plugins that you used to have in 1.8 until all the plugins are migrated. If you have the skills to help updating a plugin please let the plugin author know so you can make their life easier. If you have the ability to fund a plugins update that would be excellent.

New QGIS 2.0 API.

QGIS 2.0 has under gone some radical changes for its upcoming release. Some of these major changes relate to the API, both C++ and Python. Something that always comes up when trying to improve an API is the chance that you might have to remove the old way of doing something so that things are cleaner and improved for the future. These changes will always break existing working code and can be a burden for a little while until everything is adjusted. A little pain for a lot of gain is the way I like to think about it. I will also add that breaking API so radically isn't something that we, as developers, like to do or take lightly, but sometimes it has to be done.

This post is a summary of some of the new APIs, what has changed, and what it means to you as a user.

New Vector API (Iterator pattern)

We would like to introduce multithreaded rendering in the future and the old API for getting a set of features from the provider wasn't going to cut it in a multithreaded environment. In order to allow something that will be more threadable then the old select model we changed to a iterator pattern.

The old used to look like this:

layer.select()
for feature in layer:
    print feature

select() wouldn't return anything rather it would tell the provider of the layer to get ready to return some features when asked e.g the for loop. Want to thread that? Nope. Not going to happen.

The solution:

Create a method that returns an iterator that each thread can loop over on their own without changing the result of the other.

features = layer.getFeatures()
for feature in features:
    print feature

if you look at layer.getFeatures() you can see it returns a QgsFeatureIterator

>>> layer.getFeatures()
<qgis.core.QgsFeatureIterator object at 0x1A05F810>

QgsFeatureIterator has a next() method, just like a normal Python iterator, which you can call to get the next feature, it will just serve them up as you need them.

>>> features = layer.getFeatures()
>>> features.next()
<qgis.core.QgsFeature object at 0x1A062CD8>
>>> features.next()
<qgis.core.QgsFeature object at 0x1A062C48>
>>> features.next()
<qgis.core.QgsFeature object at 0x1A062C00>
>>> features.close()

So in the future (you can't do this yet due to some other restrictions):

>>> features = layer.getFeatures()
>>> features2 = layer.getFeatures()
>>> features.next().id()
1L
>>> features.next().id()
2L
>>> features2.next().id()
1L

Nifty!

New Vector API (Fields)

Something else that changed was how attributes are accessed.

This is the old style:

>>> index = layer.fieldNameIndex("yourcolumn")
>>> feature.attributeMap()[index].toString()
"Hello World"

That is a big pain in the butt just to get a value from a field.

The new method now uses a list of attributes on the feature itself.

>>> feature[5]
"Hello World"
>>> feature["yourcolumn"]
"Hello World"

You can even access them like attributes.

>>> feature.yourcolumn
"Hello World"

Be careful with accessing fields via the attribute magic. If you have a id field feature.id will return the feature id method not the field named id. In fact any method with the same name as any QgsFeature methods will return the method rather then the field value. I like this magic but use it wisely.

SIP API v2

This is the most recent change that has caused all of the 1.8 plugins to no longer work in 2.0. A bit of background: PyQt4 and pyqgis use sip to define their Python API. There are two versions of SIP V1 and V2. Using SIP V1 PyQt, and therefor pyqgis, will take and return QVariant and QString objects in Python.

So:

>>> feature["yourcolumn"]
<PyQt4.QtCore.QVariant object at 0x026AD5E0>

Well that is fine but to get a string value you had to do this:

>>> feature["yourcolumn"].toString()
"Hello World"

but that isn't a normal Python string. It's a QString. QStrings can't be used in normal Python methods so you have to do str(feature["yourcolumn"].toString()). Gross!

With the change to SIP V2 QVariant and QString are now auto converted to native Python types without any extra work.

>>> type(f["Name"])
<type 'unicode'>

Good stuff.

If you are looking for a conversion guide check out: http://hub.qgis.org/wiki/quantum-gis/Python_plugin_API_changes_from_18_to_20

The QGIS plugin repository can house both 1.8 and 2.0 plugins under the same plugin name, and the plugin installer will only download the version compatible with the QGIS version you are using.

The SIP version update was a hard one to make. On one hand we could just leave it the way it was with backwards compatibility and all the messy str(variant.toString()) stuff; OR we can make the switch now while everyone is migrating to the new vector API and have a cleaner API for the future. I picked the later. Once we switch to Python 3 at some stage in the future SIP v2 is the default so it would have broken all the plugins at that point anyway.

I can tell you that I did lose some sleep over if I should push the SIP update or not, wondering what impact it could have on plugin authors and the project in general. In the end I stand by our decision to make the update in QGIS 2.0.

Hopefully these API changes won't cause to much grief for plugin authors and the API is now better to work with.

Fine. But why I do care as a user?

All this means that when QGIS 2.0 comes out you may be missing some plugins that you used to have in 1.8 until all the plugins are migrated. If you have the skills to help updating a plugin please let the plugin author know so you can make their life easier. If you have the ability to fund a plugins update that would be excellent.

SVG textures + blend modes = Cool QGIS Maps

Did you know you can use textures to fill a polyon in QGIS? No? Well you do now!

The cool thing is you can get results like this with a simple SVG and a texture.

Alt Text

So how do you do it? Lets give it a go.

First grab a texture you want from http://texturelib.com/

Install Inkscape, or any other tool that can create svgs with textures.

Drag and drop your texture into Inkscape and embed the texture into the SVG:

Alt Text

Twaek any settings you need in Inkscape and save it somewhere QGIS can find.

Tip: You can configure extra search paths for svg in Options -> System -> SVG Paths

Alt Text

Open QGIS and load a polygon layer

Change the symbol type for the style to SVG fill and selet your SVG

Alt Text

Hit apply.

Opps that's not right

Alt Text

Enter the handy blend modes added by Nyall.

Change the blend mode to Soft Light and move the layer to the top of the drawing list

Alt Text

SWEEEET!!!!

Now go and make some pirate maps.

SVG textures + blend modes = Cool QGIS Maps

Did you know you can use textures to fill a polyon in QGIS? No? Well you do now!

The cool thing is you can get results like this with a simple SVG and a texture.

Alt Text

So how do you do it? Lets give it a go.

First grab a texture you want from http://texturelib.com/

Install Inkscape, or any other tool that can create svgs with textures.

Drag and drop your texture into Inkscape and embed the texture into the SVG:

Alt Text

Twaek any settings you need in Inkscape and save it somewhere QGIS can find.

Tip: You can configure extra search paths for svg in Options -> System -> SVG Paths

Alt Text

Open QGIS and load a polygon layer

Change the symbol type for the style to SVG fill and selet your SVG

Alt Text

Hit apply.

Opps that's not right

Alt Text

Enter the handy blend modes added by Nyall.

Change the blend mode to Soft Light and move the layer to the top of the drawing list

Alt Text

SWEEEET!!!!

Now go and make some pirate maps.

My toolset

I am a big fan Scott Hanselman and this post was inspired by his 2011 Ultimate Developer and Power Users Tool List for Windows with some extra stuff thrown in. I have nowhere close to the amount of tools that Scott does but I thought it would be cool to share my setup anyway.

Editors\IDEs

  • Sublime Text 2\Notepad++ : These two text editors are the best of the bunch. Sublime Text 2 has a nice simple interface, good text editing features, and simple to configure. Sublime doesn't fill every need so Notepad++ fills any gaps.

  • Visual Studio 2010 : I'm mostly a C++ and Python guy now due to QGIS but every now and then I need to do some C#.

  • Qt Creator : If you are working with Qt and C++ this is the IDE for it. Built in Qt help files, form designer, good editor (good for someone who can't use vim). Qt Creator is like Visual Studio for Qt C++ but less...bloated.

  • Aptanta Studio 3 : Since starting Python I have tried a bunch of editors and have settled on Aptanta Studio 3 for now. I find it works constantly, has some nice IDE features, built in unit test runners, and is FREE. If I'm working on a single Python file I will normally use Sublime Text 2 but anything project based like QMap or a QGIS plugin will be done in here.

Dev Tools

  • git : Everyone uses git and if you don't you should.

  • svn : -_- Ok it was good at the time, but see above.

  • ConEmu : I bloody love this program. If you are still using cmd.exe to do anything just stop now! Go and download this. Tabs, better copy and paste, resize-able window, predefined tasks, and heaps more. Trust me you will be more productive. I found it though one of Scott's posts and haven't stopped using it since.

GIS

  • QGIS : Obviously

  • MapServer : The company I now work for uses MapServer as the base for their product, although that isn't the only reason that I like it of course.

  • GRASS\SAGA GIS : Great powerful tools for vector and raster progressing.

  • ILWIS : I first used this when I did a bushfire project ( the second round was done in QGIS ) however while I don't use it much anymore it still has some cool ideas.

  • PostGIS : Great relational spatial database

  • SQL Server 2008\2012 Express : It's not that bad. 2012 has better spatial support. QGIS supports 2008/2012.

Handy tools

  • Bins : This is a nifty little tool that I found tonight. Lets you group icons into "Bins" in the Windows taskbar so you don't end up with mess of icons. Handy! Not free but only $5

  • Fences : Another one from Scott's blog. Handy for sorting out your mess of a desktop.

  • Greenshot : Great for taking screens shots. Export to Paint, Dropbox, Imgur, file, clipboard, printer. Built-in image editor for annotations. And it's free.

  • Dropbox : It always pains me to hear people say "oh my computer crashed and I lost all my documents", and if it's your sister in law two days before an assignment is due then it's even worse. Use Dropbox, or SkyDrive, or something but keep more then one copy of important stuff.

  • Paint.NET\GIMP : Even as a developer one needs an editing program. These are the two best free ones you can get.

  • Expression Encoder 4 : I have plans to do some screencasting in the future so I am giving this a run to see how things work out. This has a ten minute limit on the free version, but you don't really want to hear me talking for more then ten minutes anyway.

  • Total Commander : This is one of the best tools you can get for working with your file system. No drag and drop here. Full keyboard control and speed. Can take a bit to getting used to however it will increase your productivity.

  • UtlraMon : I can't even work with one screen anymore and this tool helps you get the most out of your monitors. Multi screen taskbar, shortcuts for predefined window locations and more.

Chat

  • Skype : I don't really use Skype a lot but when I have it always works well. Anytime I have to be away from the family in the future I plan on calling using Skype.

  • Irssi : Good ol' IRC. I have played around with a whole bunch of IRC clients on Windows and Linux but never found one that I liked apart from Irssi. Sure it runs in a console window but IRC is just text anyway so who cares. I like to tweak things so Irssi scratches that itch for me. NathanW on #qgis.

Online

  • Trello : Another one in the bloody love list. A simple to use but powerful, well I don't really know how to describe it so you can just check it out. I use it for personal task management, work projects, software projects, event planning.

  • GitHub : I really like GitHub it really does add a nice social experience to development that most sites fail on.

  • gis.stackexchange.com : Personally I really think they hit the nail on the head when building this Q&A site. I try to spend as much time as I can on here answering QGIS questions.

If anyone has anything extra they can recommend feel free to leave a comment.

My toolset

I am a big fan Scott Hanselman and this post was inspired by his 2011 Ultimate Developer and Power Users Tool List for Windows with some extra stuff thrown in. I have nowhere close to the amount of tools that Scott does but I thought it would be cool to share my setup anyway.

Editors\IDEs

  • Sublime Text 2\Notepad++ : These two text editors are the best of the bunch. Sublime Text 2 has a nice simple interface, good text editing features, and simple to configure. Sublime doesn't fill every need so Notepad++ fills any gaps.

  • Visual Studio 2010 : I'm mostly a C++ and Python guy now due to QGIS but every now and then I need to do some C#.

  • Qt Creator : If you are working with Qt and C++ this is the IDE for it. Built in Qt help files, form designer, good editor (good for someone who can't use vim). Qt Creator is like Visual Studio for Qt C++ but less...bloated.

  • Aptanta Studio 3 : Since starting Python I have tried a bunch of editors and have settled on Aptanta Studio 3 for now. I find it works constantly, has some nice IDE features, built in unit test runners, and is FREE. If I'm working on a single Python file I will normally use Sublime Text 2 but anything project based like QMap or a QGIS plugin will be done in here.

Dev Tools

  • git : Everyone uses git and if you don't you should.

  • svn : -_- Ok it was good at the time, but see above.

  • ConEmu : I bloody love this program. If you are still using cmd.exe to do anything just stop now! Go and download this. Tabs, better copy and paste, resize-able window, predefined tasks, and heaps more. Trust me you will be more productive. I found it though one of Scott's posts and haven't stopped using it since.

GIS

  • QGIS : Obviously

  • MapServer : The company I now work for uses MapServer as the base for their product, although that isn't the only reason that I like it of course.

  • GRASS\SAGA GIS : Great powerful tools for vector and raster progressing.

  • ILWIS : I first used this when I did a bushfire project ( the second round was done in QGIS ) however while I don't use it much anymore it still has some cool ideas.

  • PostGIS : Great relational spatial database

  • SQL Server 2008\2012 Express : It's not that bad. 2012 has better spatial support. QGIS supports 2008/2012.

Handy tools

  • Bins : This is a nifty little tool that I found tonight. Lets you group icons into "Bins" in the Windows taskbar so you don't end up with mess of icons. Handy! Not free but only $5

  • Fences : Another one from Scott's blog. Handy for sorting out your mess of a desktop.

  • Greenshot : Great for taking screens shots. Export to Paint, Dropbox, Imgur, file, clipboard, printer. Built-in image editor for annotations. And it's free.

  • Dropbox : It always pains me to hear people say "oh my computer crashed and I lost all my documents", and if it's your sister in law two days before an assignment is due then it's even worse. Use Dropbox, or SkyDrive, or something but keep more then one copy of important stuff.

  • Paint.NET\GIMP : Even as a developer one needs an editing program. These are the two best free ones you can get.

  • Expression Encoder 4 : I have plans to do some screencasting in the future so I am giving this a run to see how things work out. This has a ten minute limit on the free version, but you don't really want to hear me talking for more then ten minutes anyway.

  • Total Commander : This is one of the best tools you can get for working with your file system. No drag and drop here. Full keyboard control and speed. Can take a bit to getting used to however it will increase your productivity.

  • UtlraMon : I can't even work with one screen anymore and this tool helps you get the most out of your monitors. Multi screen taskbar, shortcuts for predefined window locations and more.

Chat

  • Skype : I don't really use Skype a lot but when I have it always works well. Anytime I have to be away from the family in the future I plan on calling using Skype.

  • Irssi : Good ol' IRC. I have played around with a whole bunch of IRC clients on Windows and Linux but never found one that I liked apart from Irssi. Sure it runs in a console window but IRC is just text anyway so who cares. I like to tweak things so Irssi scratches that itch for me. NathanW on #qgis.

Online

  • Trello : Another one in the bloody love list. A simple to use but powerful, well I don't really know how to describe it so you can just check it out. I use it for personal task management, work projects, software projects, event planning.

  • GitHub : I really like GitHub it really does add a nice social experience to development that most sites fail on.

  • gis.stackexchange.com : Personally I really think they hit the nail on the head when building this Q&A site. I try to spend as much time as I can on here answering QGIS questions.

If anyone has anything extra they can recommend feel free to leave a comment.

Back to Top

Sustaining Members