Categories
All OSGEO QGIS

QGIS Multi Ring Buffer Plugin Version 1

After about 3 years of existing. I am releasing version 1 of the Multi Ring Buffer Plugin.

QGIS plugin repository.

With version 1 comes a few new features:

  • Ability to choose the layer to buffer after launching the plugin
  • Ability to supply buffer distances as comma separated text string
  • Ability to make non-doughnut buffers
  • Doughnut buffer:

    Non-doughnut buffer (regular):

    Works either in a sequential manner by buffering the resulting buffer and differencing the previous buffer, or a central manner by buffering the original feature with different distances. Also by default the buffer dissolves the features before buffering.

    Dissolving makes adjacent features behave in a better manner without overlapping buffers. The QGIS buffer feature has the logic behind this.

    Post:

    Buffering methodology

    Known issues:

    Help Guide

    Code:

    GitHub Code Base

    Issues and bug tracker:

    GitHub Issues

    Categories
    All OSGEO QGIS

    Updating A Plugin From QGIS 2 to QGIS 3

    I have two plugins in the QGIS plugin repository, and with the release of QGIS 3 looming it was time to upgrade them for QGIS 3.

    There is a short guide by the QGIS dev team that is a good starting point at:
    https://github.com/qgis/QGIS/wiki/Plugin-migration-to-QGIS-3

    But I had not done any development on these plugins for a while so a more step by step guide was useful, so hopefully, write the guide for the first plugin and follow it step by step for the second.

    I am working on Windows, with OSGeo4W.

    Before we start we will need to insure a couple of extras are installed through the OSGeo4w Installer:
    Desktop:
    qgis-dev
    Libs:
    python-future

    Assuming GitHUB is the repo.
    In git shell:

    git clone https://github.com/HeikkiVesanto/QGIS_Multi_Ring_Buffer.git

    There is a conversion script for QGIS plugins provided by the QGIS devs in the main repo.

    UPDATE:
    The qgis2to3 packages can be found on pip now:

    https://github.com/opengisch/qgis2to3/

    We can download just the scripts folder using the following link:
    https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/qgis/QGIS/tree/master/scripts

    Extract that into a location of your choice.

    Then we can run the 2to3 script from the OSGeo4W console (cd to the folder you extracted the script to):

    python 2to3 C:\path_to_plugin\QGIS_Multi_Ring_Buffer

    This will print out changes that need to be made to convert from QGIS2 to QGIS3.

    My first run resulted in many lines of:

    RefactoringTool: Line 31: could not convert: from PyQt4.QtCore import *
    RefactoringTool: Cannot handle star imports.

    So my plugins line of:

    from PyQt4.QtCore import *

    Was impossible to convert with the tool, since I was not 100% sure what I needed from the QtCore library (I was young when I wrote the plugin). I commented out the line for the plugin in QGIS 2.8, booted up QGIS 2.8 and tried running the plugin.

    So python errors:
    NameError: global name ‘QVariant’ is not defined
    NameError: global name ‘Qt’ is not defined
    Later. I ended up expanding my other import from QtCore to:

    from PyQt4.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, QVariant, Qt

    Running the 2to3 script again looked ok, with a number of changes required. These changes can be applied with –w flag:

    python 2to3 C:\path_to_plugin\QGIS_Multi_Ring_Buffer -w

    For the next step I booted up my favourite IDE PyCharm. I created a bat file that launched PyCharm with the QGIS dev environmental variables. So copying the “python-qgis-dev.bat” file from:

    I changed the final line of:

    "%PYTHONHOME%\python" %*

    To:

    start /d "C:\Program Files\JetBrains\PyCharm Community Edition 2017.2.1\bin\" pycharm64.exe

    Then from File> Settings> Project:> Project Interpreter> Set to “C:\OSGeo4W64\apps\Python36\python.exe”

    It takes a while to update the interpreter.

    I only had 2 errors, both for:
    QgsMapLayerRegistry.instance().addMapLayer(vl)

    There is a list of API breaks between QGIS 2 and QGIS 3 at:
    https://qgis.org/api/api_break.html

    Looks like QgsMapLayerRegistry was moved to QgsProject. So I edit it to:

    QgsProject.instance().addMapLayer(vl)

    Then we can edit the metadata.txt to QGIS 3:
    qgisMinimumVersion=3.0

    And increase the version number.

    Then we need to recompile the icon and ui for Python3 and QT5.

    I was struggling a bit with the environmental variables to get it working, and ended up using a great batch script form StackExchange:
    https://gis.stackexchange.com/questions/260743/how-to-compile-qtdesigner-user-interface-ui-and-resource-qrc-files-with-qg

    @ECHO OFF
    
    set OSGEO4W_ROOT=C:\OSGeo4W64
    
    set PATH=%OSGEO4W_ROOT%\bin;%PATH%
    set PATH=%PATH%;%OSGEO4W_ROOT%\apps\qgis\bin
    
    @echo off
    call "%OSGEO4W_ROOT%\bin\o4w_env.bat"
    call "%OSGEO4W_ROOT%\bin\qt5_env.bat"
    call "%OSGEO4W_ROOT%\bin\py3_env.bat"
    @echo off
    path %OSGEO4W_ROOT%\apps\qgis-dev\bin;%OSGEO4W_ROOT%\apps\grass\grass-7.2.2\lib;%OSGEO4W_ROOT%\apps\grass\grass-7.2.2\bin;%PATH%
    
    cd /d %~dp0
    
    @ECHO ON
    ::Ui Compilation
    call pyuic5 multi_ring_buffer_dialog_base.ui -o multi_ring_buffer_dialog_base.py          
    
    ::Resources
    call pyrcc5 resources.qrc -o resources_rc.py
    
    @ECHO OFF
    GOTO END
    
    :ERROR
       echo "Failed!"
       set ERRORLEVEL=%ERRORLEVEL%
       pause
    
    :END
    @ECHO ON

    So create the .bat file and run it in the folder of you plugin (editing where needed). Note: Your resources_rc may be called resource_rc or something slightly different.

    Move the plugin folder to:
    C:\\Users\\USERNAME\\AppData\\Roaming\\QGIS\\QGIS3\\profiles\\default\\python\\plugins\\

    Boot up QGIS2.99/3.

    I had a few more issues.

    It seems QGIS 3 deals with the icon slightly differently.

    icon_rc.py is no longer needed, and it seems was not used on my other plugin either.

    So I removed the reference to it in the main python script:
    from . import icon_rc

    I still had some errors.

    AttributeError: module ‘qgis.PyQt.QtGui’ has no attribute ‘QDialog’

    It seems QDialog has moved to PyQt.QtWidgets.

    So in my multi_ring_buffer_dialog.py file I needed to change some lines:

    Add:

    from qgis.PyQt.QtWidgets import QDialog, QDialogButtonBox

    Change:
    QtGui.QDialog
    to:
    QDialog
    In the two instances in that file.

    Working plugin!

    Commit the changes back to the repo. Cd to the directory in git shell.

    git add -A
    git commit –m “Updated for QGIS 3”
    git push

    Zip the plugin up.
    Upload to https://plugins.qgis.org/plugins/

    Second plugin:
    Same issue with import *
    1 error with QgsMapLayerRegistry
    My resources_rc file was called resource_rc so the batch script needed to be edited to:
    call pyrcc5 resources.qrc -o resource_rc.py
    Same issues with QtGui.QDialog

    Now time for some improvements.

    Categories
    All OSGEO QGIS

    UK Postcode Breakdown RegEX

    UK postcodes are broken down/divided into 4 levels: Areas, Districts, Sectors, and Units.

    For G12 8QH the breakdown is:
    Area – G
    District – G12
    Sector – G12 8
    Unit – G12 8QH

    See my previous post:
    UK Postcode Format Breakdown/

    This is just a note of the RegEX strings to extract these, which can be used in QGIS, or PostgreSQL. These are a bit complex for most datasets, but should work independent on whether spaces and how many were used between the in and out codes. Should also work for London postcodes.

    Area: G
    RegEX: ^[a-zA-Z][a-zA-Z]?
    PostgreSQL: substring(postcode, '^[a-zA-Z][a-zA-Z]?')
    QGIS: regexp_substr("postcode" , '(^[a-zA-Z][a-zA-Z]?)')

    UK Postcode Area UK Postcode Area

    District: G12
    This is actually pretty hard to do.

    UK Postcode District UK Postcode District

    Sector: G12 8
    RegEX: ^[a-zA-Z]+\d\d?[a-zA-Z]?\s*\d+
    PostgreSQL: substring(postcode, '^[a-zA-Z]+\d\d?[a-zA-Z]?\s*\d+')
    QGIS: regexp_substr("postcode" , '(^[a-zA-Z]+\\d\\d?[a-zA-Z]?\\s*\\d+)')

    UK Postcode Sector UK Postcode Sector

    Unit: G12 8QH
    postcode…

    I’ll let you figure this one out.

    Categories
    All Animations Featured OSGEO QGIS Tutorials

    Storm Harvey QGIS Geometry Generator

    Storm Harvey produced some extremely high levels of rainfall. Some areas of Texas received over 50 inches of rain over 9 days.

    The National Oceanic and Atmospheric Administration (NOAA) provided some really great real time datasets to map the progress of the storm.

    Among these were:
    Hourly Precipitation
    and
    Hurricane Path

    From these we can produce a GIF of hourly precipitation:

    Hourly precipitation.

    And total precipitation:
    Hurricane Harvey Total Precipitation

    Particularly the hurricane path was possible to create in QGIS using the Atlas Generator, and the excellent new:ish geometry generator. This can be found as an option for any layers symbology, as one of the renderers.

    For my map I had a non spatial table that drove my atlas. This was a log table of all of the hours of precipitation I had loaded into my database. So I looped through each entry and showed the corresponding points of hourly precipitation for the corresponding hour. I also had hurricane path data as points for every 6 hours. So I could use the geometry generator to interpolate points in between known points.

    While the query ended up being pretty long it is pretty straightforward.

    It only needs to be run when the hour being generated does not end with a 00, 06, 12, or 18, because those are the positions I already know.

    For the rest I need to generate two points. One for the previously known point, and one for the next known point.

    Then I would create a line between those two points, measure the line, and place a point on the line x times one sixth of the way for the start of the line depending on the hour from the last known point.

    Overall I am very impressed and happy with the result. With a bit of data defined rotation the storm progress looks great.

    line_interpolate_point(
    Make_line(
    geometry(
    case when right(to_string(attribute(@atlas_feature , 'id')),2) IN ('00', '06', '12', '18') then
        get_feature(  @layer_name , 'dtg', attribute(  @atlas_feature , 'id') )
    else
        get_feature(  @layer_name , 'dtg',  attribute(  @atlas_feature , 'id') - (attribute(  @atlas_feature , 'id') % 100 % 6  ))
    end)
    ,
    geometry(
    case
        when right(to_string(attribute(@atlas_feature , 'id')),2) IN ('00', '06', '12') then
            get_feature(  @layer_name , 'dtg', attribute(  @atlas_feature , 'id') + 6 )
        when right(to_string(attribute(@atlas_feature , 'id')),2) IN ('18') then
            get_feature(  @layer_name , 'dtg', attribute(  @atlas_feature , 'id') + 100 - 18 )
        when to_int(right(to_string(attribute(@atlas_feature , 'id')),2)) > 18 then
            get_feature(  @layer_name , 'dtg',  attribute(  @atlas_feature , 'id') - ((attribute(  @atlas_feature , 'id') % 100 % 6)  ) + 100 - 18)
        else
            get_feature(  @layer_name , 'dtg',  attribute(  @atlas_feature , 'id') - ((attribute(  @atlas_feature , 'id') % 100 % 6)  ) + 6)
    end)
    ),
    length(Make_line(geometry(
    case when right(to_string(attribute(@atlas_feature , 'id')),2) IN ('00', '06', '12', '18') then get_feature(  @layer_name , 'dtg', attribute(  @atlas_feature , 'id') )
    else get_feature(  @layer_name , 'dtg',  attribute(  @atlas_feature , 'id') - (attribute(  @atlas_feature , 'id') % 100 % 6  ))
    end
    )
    ,
    geometry(
    case
        when right(to_string(attribute(@atlas_feature , 'id')),2) IN ('00', '06', '12') then
            get_feature(  @layer_name , 'dtg', attribute(  @atlas_feature , 'id') + 6 )
        when right(to_string(attribute(@atlas_feature , 'id')),2) IN ('18') then
            get_feature(  @layer_name , 'dtg', attribute(  @atlas_feature , 'id') + 100 - 18 )
        when to_int(right(to_string(attribute(@atlas_feature , 'id')),2)) > 18 then
            get_feature(  @layer_name , 'dtg',  attribute(  @atlas_feature , 'id') - ((attribute(  @atlas_feature , 'id') % 100 % 6)  ) + 100 - 18)
        else
            get_feature(  @layer_name , 'dtg',  attribute(  @atlas_feature , 'id') - ((attribute(  @atlas_feature , 'id') % 100 % 6)  ) + 6)
    end)))
    *
    ((attribute(  @atlas_feature , 'id') % 100 % 6) * 0.16666666666666666))
    
    
    Categories
    All Maps OSGEO QGIS Scotland

    Every Person in Scotland on the Map

    Winner of the 2016 OS OpenData Award for Excellence in the use of OpenData from the British Cartographic Society.

    Full size.

    The mapping process creates a random point within a building shell inside of a postcode area, which is repeated for every person in a postcode. This is in contrast to a simpler process, which does not take into account buildings at all, working simply with postcode areas. This can be seen in my previous post: Population of Scotland Mapped

    Inspired by:
    The Guardian – Every person in England and Wales on a map by Chris Cross

    Based on the 2011 Scottish Census population data.

    Data from the National Records of Scotland.

    Combined with the Ordnance Survey, Open Map product.

    Rendered with: QGIS tile writer python script.

    Categories
    All OSGEO QGIS

    Highlighting Selections in QGIS

    I have been working a lot with points recently, and one thing with the default selection highlighting in QGIS is that selections do not really stand out. This is especially true with point layers.

    A bit of an extreme example, but there are 15 points selected in the middle of this image.

    hard_to_see

    However, we can remedy this with the Expression Plus plugin (by Nathan Woodrow) and a rule based symbology.

    plugin

    This plugin adds a great function: isselected()

    With this we can easily create rule to symbolise features that are selected.

    The rule for symbology is as follows:

    QGIS 2.12+:

    isselected( @layer_name )

    QGIS 2.8:

    isselected( 'ACTUAL_NAME_OF_LAYER' )

    So we can see that 2.12 has added a slightly more dynamic way of applying the symbology.

    symbology

    We can now slightly more easily see our selection.

    more_visible

    But one final setting. With symbol levels we can really make the selections pop.

    symbol_levels

    Symbol levels can be set from the bottom right of the styles tab, through rendering order. We simply want out selection to have a higher number than the other symbologies. Thus being rendered in a later pass and appearing on top.

    final_selection

    Much better.

    Categories
    All OSGEO QGIS Tutorials

    Mapping Google Location Data

    A cool python script has been created that allows you to easily convert your google location (Takeout) data into a shapefile.

    You can get your data from: Google Takeout
    And you only need the “Location History – JSON format”

    The conversion python script can be downloaded from: GitHub

    The python script requires GDAL and its python bindings, but can be easily run if you installed QGIS using the OSGeo4W installer. From the advanced installer, under the Lib section.

    instruct

    Then using the OSGeo4W Shell.
    shell

    Run the command:

    python "C:\FullPath_to_Python_Script\read_location_data.py" "C:\FullPath_to_Input_File\LocationHistory.json" "C:\output_path" output_file_name ESRI_Shapefile

    Example:

    python "C:\FilePath\Takeout\Location History\read_location_data.py" "C:\FilePath\Takeout\Location History\LocationHistory.json" "C:\FilePath\Takeout\Location History" output ESRI_Shapefile

    Then just style it in QGIS as desired.
    GoogleTakeOut

    Categories
    All OSGEO QGIS Tutorials

    GIS to CAD using ogr2ogr – Part 2 – GML to DXF with OS MasterMap

    GIS to CAD using ogr2ogr – Part 1 – Shp to DXF with Contour Data
    GIS to CAD using ogr2ogr – Part 3 – Point Annotation to Text in CAD

    For this example we are using Ordnance Survey MasterMap Topology Layer data.

    MasterMap Topo Sample Data:

    https://www.ordnancesurvey.co.uk/business-and-government/licensing/sample-data/discover-data.html

    Now we know that we can maintain an attribute through layers, as we saw in the shp to DXF example, the export of MasterMap should be straightforward.

    Let’s first see what the GML file contains.

    ogrinfo -so os-mastermap-topography-layer-sample-data.gml
    Had to open data source read-only.
    INFO: Open of 'os-mastermap-topography-layer-sample-data.gml'
    using driver 'GML' successful.
    1: TopographicArea (Polygon)
    2: CartographicText (Point)
    3: CartographicSymbol (Point)
    4: BoundaryLine (Line String)
    5: TopographicPoint (Point)
    6: TopographicLine (Line String)

    So we have 6 layers in total.

    For MasterMap in CAD we will be mainly interested in CartographicText, TopographicPoint, and TopographicLine.

    Lets start with TopographicLine.

    ogrinfo -so os-mastermap-topography-layer-sample-data.gml TopographicLine

    Nothing too useful.

    A bit more details:

    ogrinfo os-mastermap-topography-layer-sample-data.gml TopographicLine

    Sample:

    OGRFeature(TopographicLine):185
    fid (String) = osgb1000000347615024
    featureCode (Integer) = 10019
    version (Integer) = 5
    versionDate (String) = 2005-03-30
    theme (StringList) = (2:Buildings,Land)
    accuracyOfPosition (String) = 1.0m
    changeDate (StringList) = (4:1994-01-26,2003-11-10,2004-02-19,2005-01-05)
    reasonForChange (StringList) = (4:Modified,Attributes,Attributes,Attributes)
    descriptiveGroup (String) = Building
    physicalLevel (Integer) = 50
    physicalPresence (String) = Obstructing
    descriptiveTerm (String) = Outline
    make (String) = Manmade
    nonBoundingLine (String) = (null)
    LINESTRING (...)

    For this feature the “descriptiveGroup”” seems the most useful, and from reading the os-mastermap-topography-layer-user-guide.pdf the best would be either a combination of descriptiveGroup and descriptiveTerm or using the featureCode. Since this is a simple conversion we will just use a combo of descriptiveGroup and descriptiveTerm to create our DXF layers.

    I will be using || for concatenation, which works with the SQlite SQL dialect.

    ogr2ogr -f DXF TopographicLine.dxf os-mastermap-topography-layer-sample-data.gml TopographicLine -sql "select descriptiveGroup || ' - ' || descriptiveTerm as Layer from TopographicLine" -dialect SQlite

    Result:

    layer names ignored in combination with -sql.
    ERROR 1: No known way to write feature with geometry 'None'.
    ERROR 1: Unable to write feature 0 from layer SELECT.
    
    ERROR 1: Terminating translation prematurely after failed
    translation from sql statement.

    Not quite. Seems to be missing geometry, perhaps a SQL select issue.

    This can be tested with:

    ogrinfo os-mastermap-topography-layer-sample-data.gml TopographicLine -sql "select descriptiveGroup || ' - ' || descriptiveTerm as Layer from TopographicLine" -dialect SQLITE

    Result:

    OGRFeature(SELECT):14634
    Layer (String) = Building - Outline
    
    OGRFeature(SELECT):14635
    Layer (String) = Building - Outline

    So we do not have any geometry. Lets bring that in.

    ogr2ogr -f DXF TopographicLine.dxf os-mastermap-topography-layer-sample-data.gml TopographicLine -sql "select descriptiveGroup || ' - ' || descriptiveTerm as Layer, * from TopographicLine" -dialect SQLITE

    Geometry looks good:

    Screenshot[6]

    But if we check the attributes in QGIS:

    Screenshot[7]

    We can see that all of the attributes that are not 0 have both a descriptiveGroup and a descriptiveTerm, which was not what we can see in the ogrinfo summary. So our SQL statement is cutting some out.

    Try again:

    ogr2ogr -f DXF TopographicLine2.dxf os-mastermap-topography-layer-sample-data.gml TopographicLine -sql "select descriptiveGroup ||' - '|| coalesce(descriptiveTerm,'') as Layer, * from TopographicLine" -dialect SQLITE

    Looking better:

    Screenshot[8]

    But it won’t open in AutoCAD DWG TrueView. Lets try running it through a ShapeFile format first before the DXF conversion.

    ogr2ogr TopographicLine.shp os-mastermap-topography-layer-sample-data.gml TopographicLine -sql "select descriptiveGroup || ' - ' || coalesce(descriptiveTerm,'') as Layer, * from TopographicLine" -dialect SQLITE
    
    ogr2ogr -f DXF TopographicLine3.dxf TopographicLine.shp

    Success:

    Screenshot[9]

    No indication of why a direct GML to DXF conversion would hang TrueView, and your mileage with other CAD software may vary. But ShapeFile is a very simplified geometry format, so perhaps running through that helps with some more complex geometry in the GML. Hard to say with no errors from TrueView, just a stuck program.

    Repeat for point:

    ogr2ogr -f DXF TopographicPoint.dxf TopographicPoint.shp
    
    ogr2ogr TopographicPoint.shp os-mastermap-topography-layer-sample-data.gml TopographicPoint -sql "select descriptiveGroup || ' - ' || coalesce(descriptiveTerm,'') as Layer, * from TopographicPoint" -dialect SQLITE

    GIS to CAD using ogr2ogr – Part 1 – Shp to DXF with Contour Data
    GIS to CAD using ogr2ogr – Part 3 – Point Annotation to Text in CAD

    Categories
    All OSGEO QGIS Tutorials

    GIS to CAD using ogr2ogr – Part 1 – Shp to DXF with Contour Data

    GIS to CAD using ogr2ogr – Part 2 – GML to DXF with OS MasterMap
    GIS to CAD using ogr2ogr – Part 3 – Point Annotation to Text in CAD

    The power of GDAL, and specifically ogr2ogr is pretty impressive. This conversion is from shp to DXF, which is a somewhat universal CAD format so further conversion should be possible.

    This post will cover contour export while maintaining 3D elevation, in addition to contour values as layers in CAD. The data used is OS terrain 50.

    OS Terrain 50:

    https://www.ordnancesurvey.co.uk/opendatadownload/products.html

    In QGIS:

    Screenshot[1]

    Contours in 3D:

    ogr2ogr -f DXF contour_zfield.dxf SX99SW_line.shp -zfield PROP_VALUE

    With the -zfield creating the 3d elevation.

    Great result:

    Screenshot[3]

    The alternative is to just store the z-value as layers.

    ogr2ogr -f DXF contour_layer.dxf SX99SW_line.shp -sql "SELECT PROP_VALUE AS Layer FROM SX99SW_line"

    Layers work great:

    Screenshot[2]

    With the ogr2ogr DXF driver, if you have an input column called “Layer” then it will be used to group features as a layer in DXF. We use a SQL query to achive this. Prop_Value is the height field in my input data.

    And putting them all together:

    ogr2ogr -f DXF contour_zfield_layer.dxf SX99SW_line.shp -zfield PROP_VALUE -sql "SELECT PROP_VALUE AS Layer FROM SX99SW_line"

    Result not as expected, flat output:

    Screenshot[4]

    Adding our SQL select statement removes our zfield attribute as such ogr2ogr cannot access it. Lets resolve this:

    ogr2ogr -f DXF contour_zfield_2_layer.dxf SX99SW_line.shp -zfield PROP_VALUE -sql "SELECT PROP_VALUE AS Layer, * FROM SX99SW_line"

    Excellent:

    Screenshot[5]

    Layers and height.

    GIS to CAD using ogr2ogr – Part 2 – GML to DXF with OS MasterMap
    GIS to CAD using ogr2ogr – Part 3 – Point Annotation to Text in CAD

    Categories
    All OSGEO PostGIS QGIS Scotland

    Multi Ring Buffer – Buffer the Buffer or Incrementally Increasing Distance?

    Does it matter, and who cares?

    Multi-ring buffers can be useful for simple distance calculations as seen in:
    X Percent of the Population of Scotland Lives Within Y Miles of Glasgow
    And:
    X Percent of the Population of Scotland Lives Within Y Miles of Edinburgh

    For these I simply created multiple buffers using the QGIS buffer tool. This works for small samples, but was quite frustrating. I had initially hoped to do the whole analysis in SQLite, which worked pretty well initally, but struggled on the larger buffers. It took too long to run the queries, and did not allow for visualisation. I think using PostGIS would however be pretty feasible.

    But creating a multi-ring buffer plugin for QGIS also seemed like a good learning experience. Which got me thinking, does it matter if you create increasingly large buffers around the original feature, or if you buffered the resulting buffer sequentially. My hypothesis was that there would be pretty significant differences due to the rounding of corners.

    I asked on StackExchange but the conversation did not really take off:
    http://gis.stackexchange.com/questions/140413/multi-ring-buffer-methodology

    My question is not about the overlapping-ness of the buffers, since I think multi-ring buffers should be “doughnuts” anyway. But rather if smoothing will occur. The only answer was to try it myself.

    Buffer styles:
    Buffer the resulting buffer sequentially: Sequential
    Buffer the original feature with increasing buffer distance: Central
    [table caption=”Speed – In seconds”]
    Features, Rings,Central, Sequential
    1, 5, 0.59, 0.56
    55, 5, 8.06, 6.38
    1, 200, 60.83, 31.76
    3, 200, 62.89, 40.89
    55, 200, 628.38, 586.67
    1, 2000, 203.84, 67.00
    [/table]

    No matter how you do it the sequential style is quicker, but that may be down to my code.

    Rendering

    Interestingly, although understandably, the sequential style results in a lot more vertices in the outer rings. For comparison, for a 500 ring buffer the outermost ring had the following vertice counts:
    [table]
    Style, Vertices
    Central,488
    Sequential,30918
    [/table]

    We can see this with editing turned on.
    Central:
    Central_editing
    Sequential:
    Sequential_editing

    We can also see a smoother profile in the sequential buffer. However the difference is not major, and hard to discern with the naked eye.

    So we have at most about around a 10m discrepancy, with 500 50m rings, so around 25000m of distance from the original feature.
    Screenshot[34]
    This impacts rendering time dramatically, an example with our 500 rings:

    Central:

    Sequential:

    So quicker to create but slower to draw. So which one is better, quicker calculation, or quicker rendering? Or should we not do 200+ ring buffers?

    Hard to say. In version 0.2 of the Multi Ring Buffer Plugin. There is an option for either in the advanced tab.

    Plugin: https://plugins.qgis.org/plugins/Multi_Ring_Buffer/
    Please report any issues through GitHub: https://github.com/HeikkiVesanto/QGIS_Multi_Ring_Buffer/issues